Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Thonus <steven@ln2.nl>2013-11-29 20:10:59 +0400
committerSteven Thonus <steven@ln2.nl>2013-12-16 17:39:14 +0400
commit37383966ef3fada865d3d21a8ce7a3c640bbd11e (patch)
treec7fe9015cd5d3b336e868498bb478fd523de0a86
parent99490159e5f9d6ff4b45f78b977d01caa1e3c4fc (diff)
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
-rw-r--r--app/controllers/dashboard_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb20
-rw-r--r--app/helpers/search_helper.rb4
-rw-r--r--app/models/ability.rb37
-rw-r--r--app/models/project.rb12
-rw-r--r--app/views/dashboard/projects.html.haml4
-rw-r--r--app/views/projects/_home_panel.html.haml4
-rw-r--r--app/views/projects/edit.html.haml27
-rw-r--r--config/routes.rb2
-rw-r--r--db/migrate/20131129154016_add_archived_to_projects.rb5
-rw-r--r--db/schema.rb1
-rw-r--r--features/dashboard/archived_projects.feature16
-rw-r--r--features/project/archived_projects.feature39
-rw-r--r--features/steps/dashboard/dashboard_with_archived_projects.rb22
-rw-r--r--features/steps/project/project_archived.rb37
-rw-r--r--features/steps/shared/project.rb7
-rw-r--r--spec/models/project_spec.rb1
-rw-r--r--spec/requests/api/internal_spec.rb27
18 files changed, 251 insertions, 16 deletions
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index 045e5805bd0..aaab4b40c4c 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -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
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 1835671fe98..e1c55e7d913 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -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
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index 109acfd192b..f24156e4d85 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -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
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 6df56eed5b8..cf925141f2d 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -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
diff --git a/app/models/project.rb b/app/models/project.rb
index 506f34ca6b6..d389579b3a1 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -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
diff --git a/app/views/dashboard/projects.html.haml b/app/views/dashboard/projects.html.haml
index b42bbf58dc4..23d78720881 100644
--- a/app/views/dashboard/projects.html.haml
+++ b/app/views/dashboard/projects.html.haml
@@ -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
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 19c150b54fb..ae5deb0b6de 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -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
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index 57936cff10f..c56919e792c 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -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
diff --git a/config/routes.rb b/config/routes.rb
index 188d2099997..8322d6a9d4e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -170,6 +170,8 @@ Gitlab::Application.routes.draw do
member do
put :transfer
post :fork
+ post :archive
+ post :unarchive
get :autocomplete_sources
end
diff --git a/db/migrate/20131129154016_add_archived_to_projects.rb b/db/migrate/20131129154016_add_archived_to_projects.rb
new file mode 100644
index 00000000000..917e690ba47
--- /dev/null
+++ b/db/migrate/20131129154016_add_archived_to_projects.rb
@@ -0,0 +1,5 @@
+class AddArchivedToProjects < ActiveRecord::Migration
+ def change
+ add_column :projects, :archived, :boolean, default: false, null: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index e7b3bf09d2d..77d245913e2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -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
diff --git a/features/dashboard/archived_projects.feature b/features/dashboard/archived_projects.feature
new file mode 100644
index 00000000000..399c9b53d81
--- /dev/null
+++ b/features/dashboard/archived_projects.feature
@@ -0,0 +1,16 @@
+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
diff --git a/features/project/archived_projects.feature b/features/project/archived_projects.feature
new file mode 100644
index 00000000000..9aac29384ba
--- /dev/null
+++ b/features/project/archived_projects.feature
@@ -0,0 +1,39 @@
+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"
diff --git a/features/steps/dashboard/dashboard_with_archived_projects.rb b/features/steps/dashboard/dashboard_with_archived_projects.rb
new file mode 100644
index 00000000000..700f4b426c3
--- /dev/null
+++ b/features/steps/dashboard/dashboard_with_archived_projects.rb
@@ -0,0 +1,22 @@
+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
diff --git a/features/steps/project/project_archived.rb b/features/steps/project/project_archived.rb
new file mode 100644
index 00000000000..149d293cd08
--- /dev/null
+++ b/features/steps/project/project_archived.rb
@@ -0,0 +1,37 @@
+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
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index cef66b038db..3dc4932a09a 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -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")
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 1e05d188234..8aa4c7fed1a 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -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'
diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb
index e8870f4d5d8..5f6dff92c0a 100644
--- a/spec/requests/api/internal_spec.rb
+++ b/spec/requests/api/internal_spec.rb
@@ -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) }