Commit 37383966 authored by Steven Thonus's avatar Steven Thonus

Archiving old projects; archived projects aren't shown on dashboard

features for archive projects
abilities for archived project
other abilities for archive projects

only limit commits and merges for archived projects

ability changed to prohibited actions on archived projects

added spec and feature tests for archive projects

changed search bar not to include archived projects
parent 99490159
......@@ -73,6 +73,6 @@ class DashboardController < ApplicationController
protected
def load_projects
@projects = current_user.authorized_projects.sorted_by_activity
@projects = current_user.authorized_projects.sorted_by_activity.non_archived
end
end
......@@ -5,7 +5,7 @@ class ProjectsController < ApplicationController
# Authorize
before_filter :authorize_read_project!, except: [:index, :new, :create]
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer]
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
before_filter :require_non_empty_project, only: [:blob, :tree, :graph]
layout 'navless', only: [:new, :create, :fork]
......@@ -116,6 +116,24 @@ class ProjectsController < ApplicationController
end
end
def archive
return access_denied! unless can?(current_user, :archive_project, project)
project.archive!
respond_to do |format|
format.html { redirect_to @project }
end
end
def unarchive
return access_denied! unless can?(current_user, :archive_project, project)
project.unarchive!
respond_to do |format|
format.html { redirect_to @project }
end
end
private
def set_title
......
......@@ -73,14 +73,14 @@ module SearchHelper
# Autocomplete results for the current user's projects
def projects_autocomplete
current_user.authorized_projects.map do |p|
current_user.authorized_projects.non_archived.map do |p|
{ label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) }
end
end
# Autocomplete results for the current user's projects
def public_projects_autocomplete
Project.public_or_internal_only(current_user).map do |p|
Project.public_or_internal_only(current_user).non_archived.map do |p|
{ label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) }
end
end
......
......@@ -59,31 +59,35 @@ class Ability
# Rules based on role in project
if team.masters.include?(user)
rules << project_master_rules
rules += project_master_rules
elsif team.developers.include?(user)
rules << project_dev_rules
rules += project_dev_rules
elsif team.reporters.include?(user)
rules << project_report_rules
rules += project_report_rules
elsif team.guests.include?(user)
rules << project_guest_rules
rules += project_guest_rules
end
if project.public? || project.internal?
rules << public_project_rules
rules += public_project_rules
end
if project.owner == user || user.admin?
rules << project_admin_rules
rules += project_admin_rules
end
if project.group && project.group.has_owner?(user)
rules << project_admin_rules
rules += project_admin_rules
end
rules.flatten
if project.archived?
rules -= project_archived_rules
end
rules
end
def public_project_rules
......@@ -125,6 +129,16 @@ class Ability
]
end
def project_archived_rules
[
:write_merge_request,
:push_code,
:push_code_to_protected_branches,
:modify_merge_request,
:admin_merge_request
]
end
def project_master_rules
project_dev_rules + [
:push_code_to_protected_branches,
......@@ -147,7 +161,8 @@ class Ability
:change_namespace,
:change_visibility_level,
:rename_project,
:remove_project
:remove_project,
:archive_project
]
end
......@@ -160,7 +175,7 @@ class Ability
# Only group owner and administrators can manage group
if group.has_owner?(user) || user.admin?
rules << [
rules += [
:manage_group,
:manage_namespace
]
......@@ -174,7 +189,7 @@ class Ability
# Only namespace owner and administrators can manage it
if namespace.owner == user || user.admin?
rules << [
rules += [
:manage_namespace
]
end
......
......@@ -116,6 +116,8 @@ class Project < ActiveRecord::Base
scope :public_only, -> { where(visibility_level: PUBLIC) }
scope :public_or_internal_only, ->(user) { where("visibility_level IN (:levels)", levels: user ? [ INTERNAL, PUBLIC ] : [ PUBLIC ]) }
scope :non_archived, -> { where(archived: false) }
enumerize :issues_tracker, in: (Gitlab.config.issues_tracker.keys).append(:gitlab), default: :gitlab
class << self
......@@ -132,7 +134,7 @@ class Project < ActiveRecord::Base
end
def search query
joins(:namespace).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%")
joins(:namespace).where("projects.archived = ?", false).where("projects.name LIKE :query OR projects.path LIKE :query OR namespaces.name LIKE :query OR projects.description LIKE :query", query: "%#{query}%")
end
def find_with_namespace(id)
......@@ -472,4 +474,12 @@ class Project < ActiveRecord::Base
def visibility_level_field
visibility_level
end
def archive!
update_attribute(:archived, true)
end
def unarchive!
update_attribute(:archived, false)
end
end
......@@ -82,6 +82,10 @@
= link_to project.forked_from_project.name_with_namespace, project_path(project.forked_from_project)
.project-info
.pull-right
- if project.archived?
%span.label
%i.icon-book
Archived
- project.labels.each do |label|
%span.label.label-info
%i.icon-tag
......
......@@ -7,6 +7,10 @@
%span.visibility-level-label
= visibility_level_icon(@project.visibility_level)
= visibility_level_label(@project.visibility_level)
- if @project.archived?
%span.visibility-level-label
%i.icon-book
Archived
.span7
- unless empty_repo
......
......@@ -98,6 +98,33 @@
%i.icon-chevron-down
.js-toggle-visibility-container.hide
- if can? current_user, :archive_project, @project
.ui-box.ui-box-danger
.title
- if @project.archived?
Unarchive project
- else
Archive project
.ui-box-body
- if @project.archived?
%p
Unarchiving the project will mark its repository as active.
%br
The project can be committed to.
%br
%strong Once active this project shows up in the search and on the dashboard.
= link_to 'Unarchive', unarchive_project_path(@project), confirm: "Are you sure that you want to unarchive this project?\nWhen this project is unarchived it is active and can be comitted to again.", method: :post, class: "btn btn-remove"
- else
%p
Archiving the project will mark its repository as read-only.
%br
It is hidden from the dashboard and doesn't show up in searches.
%br
%strong Archived projects cannot be committed to!
= link_to 'Archive', archive_project_path(@project), confirm: "Are you sure that you want to archive this project?\nAn archived project cannot be committed to.", method: :post, class: "btn btn-remove"
- else
%p.nothing_here_message Only the project owner can archive a project
- if can?(current_user, :change_namespace, @project)
.ui-box.ui-box-danger
.title Transfer project
......
......@@ -170,6 +170,8 @@ Gitlab::Application.routes.draw do
member do
put :transfer
post :fork
post :archive
post :unarchive
get :autocomplete_sources
end
......
class AddArchivedToProjects < ActiveRecord::Migration
def change
add_column :projects, :archived, :boolean, default: false, null: false
end
end
......@@ -192,6 +192,7 @@ ActiveRecord::Schema.define(version: 20131214224427) do
t.boolean "imported", default: false, null: false
t.string "import_url"
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
end
add_index "projects", ["creator_id"], name: "index_projects_on_owner_id", using: :btree
......
Feature: Dashboard with archived projects
Background:
Given I sign in as a user
And I own project "Shop"
And I own project "Forum"
And project "Forum" is archived
And I visit dashboard page
Scenario: I should see non-archived projects on dashboard
Then I should see "Shop" project link
And I should not see "Forum" project link
Scenario: I should see all projects on projects page
And I visit dashboard projects page
Then I should see "Shop" project link
And I should see "Forum" project link
Feature: Project Archived
Background:
Given I sign in as a user
And I own project "Shop"
And I own project "Forum"
Scenario: I should not see archived on project page of not-archive project
And project "Forum" is archived
And I visit project "Shop" page
Then I should not see "Archived"
Scenario: I should see archived on project page of archive project
And project "Forum" is archived
And I visit project "Forum" page
Then I should see "Archived"
Scenario: I should not see archived on projects page with no archived projects
And I visit dashboard projects page
Then I should not see "Archived"
Scenario: I should see archived on projects page with archived projects
And project "Forum" is archived
And I visit dashboard projects page
Then I should see "Archived"
Scenario: I archive project
When project "Shop" has push event
And I visit project "Shop" page
And I visit edit project "Shop" page
And I set project archived
Then I should see "Archived"
Scenario: I unarchive project
When project "Shop" has push event
And project "Shop" is archived
And I visit project "Shop" page
And I visit edit project "Shop" page
And I set project unarchived
Then I should not see "Archived"
class DashboardWithArchivedProjects < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
include SharedProject
When 'project "Forum" is archived' do
project = Project.find_by_name "Forum"
project.update_attribute(:archived, true)
end
Then 'I should see "Shop" project link' do
page.should have_link "Shop"
end
Then 'I should not see "Forum" project link' do
page.should_not have_link "Forum"
end
Then 'I should see "Forum" project link' do
page.should have_link "Forum"
end
end
class ProjectArchived < Spinach::FeatureSteps
include SharedAuthentication
include SharedProject
include SharedPaths
When 'project "Forum" is archived' do
project = Project.find_by_name "Forum"
project.update_attribute(:archived, true)
end
When 'project "Shop" is archived' do
project = Project.find_by_name "Shop"
project.update_attribute(:archived, true)
end
When 'I visit project "Forum" page' do
project = Project.find_by_name "Forum"
visit project_path(project)
end
Then 'I should not see "Archived"' do
page.should_not have_content "Archived"
end
Then 'I should see "Archived"' do
page.should have_content "Archived"
end
When 'I set project archived' do
click_link "Archive"
end
When 'I set project unarchived' do
click_link "Unarchive"
end
end
\ No newline at end of file
......@@ -14,6 +14,13 @@ module SharedProject
@project.team << [@user, :master]
end
# Create another specific project called "Forum"
And 'I own project "Forum"' do
@project = Project.find_by_name "Forum"
@project ||= create(:project_with_code, name: "Forum", namespace: @user.namespace, path: 'forum_project')
@project.team << [@user, :master]
end
And 'project "Shop" has push event' do
@project = Project.find_by_name("Shop")
......
......@@ -21,6 +21,7 @@
# imported :boolean default(FALSE), not null
# import_url :string(255)
# visibility_level :integer default(0), not null
# archived :boolean default(FALSE), not null
#
require 'spec_helper'
......
......@@ -103,6 +103,33 @@ describe API::API do
end
end
context "archived project" do
let(:personal_project) { create(:project, namespace: user.namespace) }
before do
project.team << [user, :developer]
project.archive!
end
context "git pull" do
it do
pull(key, project)
response.status.should == 200
response.body.should == 'true'
end
end
context "git push" do
it do
push(key, project)
response.status.should == 200
response.body.should == 'false'
end
end
end
context "deploy key" do
let(:key) { create(:deploy_key) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment