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
This commit is contained in:
Steven Thonus 2013-11-29 17:10:59 +01:00
parent 99490159e5
commit 37383966ef
18 changed files with 251 additions and 16 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -170,6 +170,8 @@ Gitlab::Application.routes.draw do
member do
put :transfer
post :fork
post :archive
post :unarchive
get :autocomplete_sources
end

View file

@ -0,0 +1,5 @@
class AddArchivedToProjects < ActiveRecord::Migration
def change
add_column :projects, :archived, :boolean, default: false, null: false
end
end

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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

View 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")

View file

@ -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'

View file

@ -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) }