diff --git a/Gemfile b/Gemfile
index 71eafaba..8e2bdb9c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -57,7 +57,7 @@ gem "seed-fu"
# Markdown to HTML
gem "redcarpet", "~> 2.1.1"
-gem "github-markup", "~> 0.7.4"
+gem "github-markup", "~> 0.7.4", require: 'github/markup'
# Servers
gem "thin"
diff --git a/app/assets/stylesheets/sections/nav.scss b/app/assets/stylesheets/sections/nav.scss
index 2d902918..98bc7275 100644
--- a/app/assets/stylesheets/sections/nav.scss
+++ b/app/assets/stylesheets/sections/nav.scss
@@ -53,7 +53,7 @@ ul.main_menu {
border-left: 0;
}
- &.current {
+ &.active {
background-color:#D5D5D5;
border-right: 1px solid #BBB;
border-left: 1px solid #BBB;
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 5ac5c639..334135c8 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,7 +2,6 @@ class ApplicationController < ActionController::Base
before_filter :authenticate_user!
before_filter :reject_blocked!
before_filter :set_current_user_for_mailer
- before_filter :check_token_auth
before_filter :set_current_user_for_observers
before_filter :dev_tools if Rails.env == 'development'
@@ -26,13 +25,6 @@ class ApplicationController < ActionController::Base
protected
- def check_token_auth
- # Redirect to login page if not atom feed
- if params[:private_token].present? && params[:format] != 'atom'
- redirect_to new_user_session_path
- end
- end
-
def reject_blocked!
if current_user && current_user.blocked
sign_out current_user
@@ -113,7 +105,7 @@ class ApplicationController < ActionController::Base
end
def render_404
- render file: File.join(Rails.root, "public", "404"), layout: false, status: "404"
+ render file: Rails.root.join("public", "404"), layout: false, status: "404"
end
def require_non_empty_project
@@ -126,10 +118,6 @@ class ApplicationController < ActionController::Base
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
- def render_full_content
- @full_content = true
- end
-
def dev_tools
Rack::MiniProfiler.authorize_request
end
diff --git a/app/controllers/blame_controller.rb b/app/controllers/blame_controller.rb
new file mode 100644
index 00000000..dd0837ea
--- /dev/null
+++ b/app/controllers/blame_controller.rb
@@ -0,0 +1,21 @@
+# Controller for viewing a file's blame
+class BlameController < ApplicationController
+ include ExtractsPath
+
+ layout "project"
+
+ before_filter :project
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
+ before_filter :require_non_empty_project
+
+ before_filter :assign_ref_vars
+
+ def show
+ @repo = @project.repo
+ @blame = Grit::Blob.blame(@repo, @commit.id, @path)
+ end
+end
diff --git a/app/controllers/blob_controller.rb b/app/controllers/blob_controller.rb
new file mode 100644
index 00000000..33387842
--- /dev/null
+++ b/app/controllers/blob_controller.rb
@@ -0,0 +1,37 @@
+# Controller for viewing a file's blame
+class BlobController < ApplicationController
+ include ExtractsPath
+ include Gitlab::Encode
+
+ layout "project"
+
+ before_filter :project
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
+ before_filter :require_non_empty_project
+
+ before_filter :assign_ref_vars
+
+ def show
+ if @tree.is_blob?
+ if @tree.text?
+ encoding = detect_encoding(@tree.data)
+ mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
+ else
+ mime_type = @tree.mime_type
+ end
+
+ send_data(
+ @tree.data,
+ type: mime_type,
+ disposition: 'inline',
+ filename: @tree.name
+ )
+ else
+ not_found!
+ end
+ end
+end
diff --git a/app/controllers/commit_controller.rb b/app/controllers/commit_controller.rb
new file mode 100644
index 00000000..de0d5b2e
--- /dev/null
+++ b/app/controllers/commit_controller.rb
@@ -0,0 +1,36 @@
+# Controller for a specific Commit
+#
+# Not to be confused with CommitsController, plural.
+class CommitController < ApplicationController
+ before_filter :project
+ layout "project"
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
+ before_filter :require_non_empty_project
+
+ def show
+ result = CommitLoad.new(project, current_user, params).execute
+
+ @commit = result[:commit]
+ git_not_found! unless @commit
+
+ @suppress_diff = result[:suppress_diff]
+ @note = result[:note]
+ @line_notes = result[:line_notes]
+ @notes_count = result[:notes_count]
+ @comments_allowed = true
+
+ respond_to do |format|
+ format.html do
+ if result[:status] == :huge_commit
+ render "huge_commit" and return
+ end
+ end
+
+ format.patch
+ end
+ end
+end
diff --git a/app/controllers/commits_controller.rb b/app/controllers/commits_controller.rb
index 1e7aec00..bd67ee88 100644
--- a/app/controllers/commits_controller.rb
+++ b/app/controllers/commits_controller.rb
@@ -4,19 +4,19 @@ class CommitsController < ApplicationController
before_filter :project
layout "project"
+ include ExtractsPath
+
# Authorize
before_filter :add_project_abilities
before_filter :authorize_read_project!
before_filter :authorize_code_access!
before_filter :require_non_empty_project
- before_filter :load_refs, only: :index # load @branch, @tag & @ref
- before_filter :render_full_content
- def index
- @repo = project.repo
+ def show
+ @repo = @project.repo
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
- @commits = @project.commits(@ref, params[:path], @limit, @offset)
+ @commits = @project.commits(@ref, @path, @limit, @offset)
@commits = CommitDecorator.decorate(@commits)
respond_to do |format|
@@ -25,54 +25,4 @@ class CommitsController < ApplicationController
format.atom { render layout: false }
end
end
-
- def show
- result = CommitLoad.new(project, current_user, params).execute
-
- @commit = result[:commit]
-
- if @commit
- @suppress_diff = result[:suppress_diff]
- @note = result[:note]
- @line_notes = result[:line_notes]
- @notes_count = result[:notes_count]
- @comments_allowed = true
- else
- return git_not_found!
- end
-
- if result[:status] == :huge_commit
- render "huge_commit" and return
- end
- end
-
- def compare
- result = Commit.compare(project, params[:from], params[:to])
-
- @commits = result[:commits]
- @commit = result[:commit]
- @diffs = result[:diffs]
- @refs_are_same = result[:same]
- @line_notes = []
-
- @commits = CommitDecorator.decorate(@commits)
- end
-
- def patch
- @commit = project.commit(params[:id])
-
- send_data(
- @commit.to_patch,
- type: "text/plain",
- disposition: 'attachment',
- filename: "#{@commit.id}.patch"
- )
- end
-
- protected
-
- def load_refs
- @ref ||= params[:ref].presence || params[:branch].presence || params[:tag].presence
- @ref ||= @ref || @project.try(:default_branch) || 'master'
- end
end
diff --git a/app/controllers/compare_controller.rb b/app/controllers/compare_controller.rb
new file mode 100644
index 00000000..62f968fd
--- /dev/null
+++ b/app/controllers/compare_controller.rb
@@ -0,0 +1,29 @@
+class CompareController < ApplicationController
+ before_filter :project
+ layout "project"
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
+ before_filter :require_non_empty_project
+
+ def index
+ end
+
+ def show
+ result = Commit.compare(project, params[:from], params[:to])
+
+ @commits = result[:commits]
+ @commit = result[:commit]
+ @diffs = result[:diffs]
+ @refs_are_same = result[:same]
+ @line_notes = []
+
+ @commits = CommitDecorator.decorate(@commits)
+ end
+
+ def create
+ redirect_to project_compare_path(@project, params[:from], params[:to])
+ end
+end
diff --git a/app/controllers/protected_branches_controller.rb b/app/controllers/protected_branches_controller.rb
index 78c9c9ef..2556f095 100644
--- a/app/controllers/protected_branches_controller.rb
+++ b/app/controllers/protected_branches_controller.rb
@@ -7,7 +7,6 @@ class ProtectedBranchesController < ApplicationController
before_filter :require_non_empty_project
before_filter :authorize_admin_project!, only: [:destroy, :create]
- before_filter :render_full_content
layout "project"
diff --git a/app/controllers/refs_controller.rb b/app/controllers/refs_controller.rb
index 90361437..e92f4527 100644
--- a/app/controllers/refs_controller.rb
+++ b/app/controllers/refs_controller.rb
@@ -1,5 +1,3 @@
-require 'github/markup'
-
class RefsController < ApplicationController
include Gitlab::Encode
before_filter :project
@@ -11,23 +9,22 @@ class RefsController < ApplicationController
before_filter :require_non_empty_project
before_filter :ref
- before_filter :define_tree_vars, only: [:tree, :blob, :blame, :logs_tree]
- before_filter :render_full_content
+ before_filter :define_tree_vars, only: [:blob, :logs_tree]
layout "project"
- def switch
- respond_to do |format|
- format.html do
+ def switch
+ respond_to do |format|
+ format.html do
new_path = if params[:destination] == "tree"
- tree_project_ref_path(@project, params[:ref])
+ project_tree_path(@project, @ref)
else
- project_commits_path(@project, ref: params[:ref])
+ project_commits_path(@project, @ref)
end
- redirect_to new_path
+ redirect_to new_path
end
- format.js do
+ format.js do
@ref = params[:ref]
define_tree_vars
render "tree"
@@ -35,19 +32,6 @@ class RefsController < ApplicationController
end
end
- #
- # Repository preview
- #
- def tree
- respond_to do |format|
- format.html
- format.js do
- # disable cache to allow back button works
- no_cache_headers
- end
- end
- end
-
def logs_tree
contents = @tree.contents
@logs = contents.map do |content|
@@ -55,36 +39,12 @@ class RefsController < ApplicationController
last_commit = @project.commits(@commit.id, file, 1).last
last_commit = CommitDecorator.decorate(last_commit)
{
- file_name: content.name,
+ file_name: content.name,
commit: last_commit
}
end
end
- def blob
- if @tree.is_blob?
- if @tree.text?
- encoding = detect_encoding(@tree.data)
- mime_type = encoding ? "text/plain; charset=#{encoding}" : "text/plain"
- else
- mime_type = @tree.mime_type
- end
-
- send_data(
- @tree.data,
- type: mime_type,
- disposition: 'inline',
- filename: @tree.name
- )
- else
- head(404)
- end
- end
-
- def blame
- @blame = Grit::Blob.blame(@repo, @commit.id, params[:path])
- end
-
protected
def define_tree_vars
@@ -95,20 +55,20 @@ class RefsController < ApplicationController
@commit = CommitDecorator.decorate(@commit)
@tree = Tree.new(@commit.tree, project, @ref, params[:path])
@tree = TreeDecorator.new(@tree)
- @hex_path = Digest::SHA1.hexdigest(params[:path] || "/")
+ @hex_path = Digest::SHA1.hexdigest(params[:path] || "")
if params[:path]
- @history_path = tree_file_project_ref_path(@project, @ref, params[:path])
- @logs_path = logs_file_project_ref_path(@project, @ref, params[:path])
+ @history_path = project_tree_path(@project, File.join(@ref, params[:path]))
+ @logs_path = logs_file_project_ref_path(@project, @ref, params[:path])
else
- @history_path = tree_project_ref_path(@project, @ref)
- @logs_path = logs_tree_project_ref_path(@project, @ref)
+ @history_path = project_tree_path(@project, @ref)
+ @logs_path = logs_tree_project_ref_path(@project, @ref)
end
rescue
return render_404
end
-
+
def ref
- @ref = params[:id]
+ @ref = params[:id] || params[:ref]
end
end
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index cd20677e..614582fa 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -6,7 +6,6 @@ class RepositoriesController < ApplicationController
before_filter :authorize_read_project!
before_filter :authorize_code_access!
before_filter :require_non_empty_project
- before_filter :render_full_content
layout "project"
@@ -15,11 +14,11 @@ class RepositoriesController < ApplicationController
end
def branches
- @branches = @project.repo.heads.sort_by(&:name)
+ @branches = @project.branches
end
def tags
- @tags = @project.repo.tags.sort_by(&:name).reverse
+ @tags = @project.tags
end
def archive
diff --git a/app/controllers/snippets_controller.rb b/app/controllers/snippets_controller.rb
index b00c9283..a38fd52f 100644
--- a/app/controllers/snippets_controller.rb
+++ b/app/controllers/snippets_controller.rb
@@ -55,7 +55,6 @@ class SnippetsController < ApplicationController
def show
@note = @project.notes.new(noteable: @snippet)
- render_full_content
end
def destroy
diff --git a/app/controllers/tree_controller.rb b/app/controllers/tree_controller.rb
new file mode 100644
index 00000000..e6313783
--- /dev/null
+++ b/app/controllers/tree_controller.rb
@@ -0,0 +1,29 @@
+# Controller for viewing a repository's file structure
+class TreeController < ApplicationController
+ include ExtractsPath
+
+ layout "project"
+
+ before_filter :project
+
+ # Authorize
+ before_filter :add_project_abilities
+ before_filter :authorize_read_project!
+ before_filter :authorize_code_access!
+ before_filter :require_non_empty_project
+
+ before_filter :assign_ref_vars
+
+ def show
+ @hex_path = Digest::SHA1.hexdigest(@path)
+
+ @history_path = project_tree_path(@project, @id)
+ @logs_path = logs_file_project_ref_path(@project, @ref, @path)
+
+ respond_to do |format|
+ format.html
+ # Disable cache so browser history works
+ format.js { no_cache_headers }
+ end
+ end
+end
diff --git a/app/decorators/event_decorator.rb b/app/decorators/event_decorator.rb
index ce0aaa03..312ac651 100644
--- a/app/decorators/event_decorator.rb
+++ b/app/decorators/event_decorator.rb
@@ -21,7 +21,7 @@ class EventDecorator < ApplicationDecorator
elsif self.merge_request?
h.project_merge_request_url(self.project, self.merge_request)
elsif self.push?
- h.project_commits_url(self.project, ref: self.ref_name)
+ h.project_commits_url(self.project, self.ref_name)
end
end
end
diff --git a/app/decorators/tree_decorator.rb b/app/decorators/tree_decorator.rb
index 80c48da7..38236c2c 100644
--- a/app/decorators/tree_decorator.rb
+++ b/app/decorators/tree_decorator.rb
@@ -6,7 +6,7 @@ class TreeDecorator < ApplicationDecorator
part_path = ""
parts = path.split("\/")
- #parts = parts[0...-1] if is_blob?
+ #parts = parts[0...-1] if is_blob?
yield(h.link_to("..", "#", remote: :true)) if parts.count > max_links
@@ -15,29 +15,29 @@ class TreeDecorator < ApplicationDecorator
part_path = part if part_path.empty?
next unless parts.last(2).include?(part) if parts.count > max_links
- yield(h.link_to(h.truncate(part, length: 40), h.tree_file_project_ref_path(project, ref, path: part_path), remote: :true))
+ yield(h.link_to(h.truncate(part, length: 40), h.project_tree_path(project, h.tree_join(ref, part_path)), remote: :true))
end
end
end
def up_dir?
- !!path
+ path.present?
end
def up_dir_path
file = File.join(path, "..")
- h.tree_file_project_ref_path(project, ref, file)
+ h.project_tree_path(project, h.tree_join(ref, file))
end
def history_path
- h.project_commits_path(project, path: path, ref: ref)
+ h.project_commits_path(project, h.tree_join(ref, path))
end
def mb_size
size = (tree.size / 1024)
if size < 1024
- "#{size} KB"
- else
+ "#{size} KB"
+ else
"#{size/1024} MB"
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 0938dc23..911b46c9 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1,6 +1,35 @@
require 'digest/md5'
+
module ApplicationHelper
+ # Check if a particular controller is the current one
+ #
+ # args - One or more controller names to check
+ #
+ # Examples
+ #
+ # # On TreeController
+ # current_controller?(:tree) # => true
+ # current_controller?(:commits) # => false
+ # current_controller?(:commits, :tree) # => true
+ def current_controller?(*args)
+ args.any? { |v| v.to_s.downcase == controller.controller_name }
+ end
+
+ # Check if a partcular action is the current one
+ #
+ # args - One or more action names to check
+ #
+ # Examples
+ #
+ # # On Projects#new
+ # current_action?(:new) # => true
+ # current_action?(:create) # => false
+ # current_action?(:new, :create) # => true
+ def current_action?(*args)
+ args.any? { |v| v.to_s.downcase == action_name }
+ end
+
def gravatar_icon(user_email = '', size = 40)
if Gitlab.config.disable_gravatar? || user_email.blank?
'no_avatar.png'
@@ -31,8 +60,8 @@ module ApplicationHelper
def grouped_options_refs(destination = :tree)
options = [
- ["Branch", @project.repo.heads.map(&:name) ],
- [ "Tag", @project.tags ]
+ ["Branch", @project.branch_names ],
+ [ "Tag", @project.tag_names ]
]
# If reference is commit id -
@@ -58,11 +87,11 @@ module ApplicationHelper
if @project && !@project.new_record?
project_nav = [
- { label: "#{@project.name} / Issues", url: project_issues_path(@project) },
- { label: "#{@project.name} / Wall", url: wall_project_path(@project) },
- { label: "#{@project.name} / Tree", url: tree_project_ref_path(@project, @project.root_ref) },
- { label: "#{@project.name} / Commits", url: project_commits_path(@project) },
- { label: "#{@project.name} / Team", url: project_team_index_path(@project) }
+ { label: "#{@project.name} / Issues", url: project_issues_path(@project) },
+ { label: "#{@project.name} / Wall", url: wall_project_path(@project) },
+ { label: "#{@project.name} / Tree", url: project_tree_path(@project, @ref || @project.root_ref) },
+ { label: "#{@project.name} / Commits", url: project_commits_path(@project, @ref || @project.root_ref) },
+ { label: "#{@project.name} / Team", url: project_team_index_path(@project) }
]
end
@@ -85,45 +114,6 @@ module ApplicationHelper
event.project.merge_requests_enabled
end
- def tab_class(tab_key)
- active = case tab_key
-
- # Project Area
- when :wall; wall_tab?
- when :wiki; controller.controller_name == "wikis"
- when :issues; issues_tab?
- when :network; current_page?(controller: "projects", action: "graph", id: @project)
- when :merge_requests; controller.controller_name == "merge_requests"
-
- # Dashboard Area
- when :help; controller.controller_name == "help"
- when :search; current_page?(search_path)
- when :dash_issues; current_page?(dashboard_issues_path)
- when :dash_mr; current_page?(dashboard_merge_requests_path)
- when :root; current_page?(dashboard_path) || current_page?(root_path)
-
- # Profile Area
- when :profile; current_page?(controller: "profile", action: :show)
- when :history; current_page?(controller: "profile", action: :history)
- when :account; current_page?(controller: "profile", action: :account)
- when :token; current_page?(controller: "profile", action: :token)
- when :design; current_page?(controller: "profile", action: :design)
- when :ssh_keys; controller.controller_name == "keys"
-
- # Admin Area
- when :admin_root; controller.controller_name == "dashboard"
- when :admin_users; controller.controller_name == 'users'
- when :admin_projects; controller.controller_name == "projects"
- when :admin_hooks; controller.controller_name == 'hooks'
- when :admin_resque; controller.controller_name == 'resque'
- when :admin_logs; controller.controller_name == 'logs'
-
- else
- false
- end
- active ? "current" : nil
- end
-
def hexdigest(string)
Digest::SHA1.hexdigest string
end
diff --git a/app/helpers/tab_helper.rb b/app/helpers/tab_helper.rb
index b5d7ccb7..c76c1b6f 100644
--- a/app/helpers/tab_helper.rb
+++ b/app/helpers/tab_helper.rb
@@ -1,35 +1,85 @@
module TabHelper
- def issues_tab?
- controller.controller_name == "issues" || controller.controller_name == "milestones"
- end
+ # Navigation link helper
+ #
+ # Returns an `li` element with an 'active' class if the supplied
+ # controller(s) and/or action(s) currently active. The contents of the
+ # element is the value passed to the block.
+ #
+ # options - The options hash used to determine if the element is "active" (default: {})
+ # :controller - One or more controller names to check (optional).
+ # :action - One or more action names to check (optional).
+ # :path - A shorthand path, such as 'dashboard#index', to check (optional).
+ # :html_options - Extra options to be passed to the list element (optional).
+ # block - An optional block that will become the contents of the returned
+ # `li` element.
+ #
+ # When both :controller and :action are specified, BOTH must match in order
+ # to be marked as active. When only one is given, either can match.
+ #
+ # Examples
+ #
+ # # Assuming we're on TreeController#show
+ #
+ # # Controller matches, but action doesn't
+ # nav_link(controller: [:tree, :refs], action: :edit) { "Hello" }
+ # # => '
Hello'
+ #
+ # # Controller matches
+ # nav_link(controller: [:tree, :refs]) { "Hello" }
+ # # => 'Hello'
+ #
+ # # Shorthand path
+ # nav_link(path: 'tree#show') { "Hello" }
+ # # => 'Hello'
+ #
+ # # Supplying custom options for the list element
+ # nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" }
+ # # => 'Hello'
+ #
+ # Returns a list item element String
+ def nav_link(options = {}, &block)
+ if path = options.delete(:path)
+ c, a, _ = path.split('#')
+ else
+ c = options.delete(:controller)
+ a = options.delete(:action)
+ end
- def wall_tab?
- current_page?(controller: "projects", action: "wall", id: @project)
+ if c && a
+ # When given both options, make sure BOTH are active
+ klass = current_controller?(*c) && current_action?(*a) ? 'active' : ''
+ else
+ # Otherwise check EITHER option
+ klass = current_controller?(*c) || current_action?(*a) ? 'active' : ''
+ end
+
+ # Add our custom class into the html_options, which may or may not exist
+ # and which may or may not already have a :class key
+ o = options.delete(:html_options) || {}
+ o[:class] ||= ''
+ o[:class] += ' ' + klass
+ o[:class].strip!
+
+ if block_given?
+ content_tag(:li, capture(&block), o)
+ else
+ content_tag(:li, nil, o)
+ end
end
def project_tab_class
[:show, :files, :edit, :update].each do |action|
- return "current" if current_page?(controller: "projects", action: action, id: @project)
+ return "active" if current_page?(controller: "projects", action: action, id: @project)
end
if ['snippets', 'hooks', 'deploy_keys', 'team_members'].include? controller.controller_name
- "current"
- end
- end
-
- def tree_tab_class
- controller.controller_name == "refs" ? "current" : nil
- end
-
- def commit_tab_class
- if ['commits', 'repositories', 'protected_branches'].include? controller.controller_name
- "current"
+ "active"
end
end
def branches_tab_class
if current_page?(branches_project_repository_path(@project)) ||
- controller.controller_name == "protected_branches" ||
+ current_controller?(:protected_branches) ||
current_page?(project_repository_path(@project))
'active'
end
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 2b7265ca..81a16989 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -39,4 +39,9 @@ module TreeHelper
def gitlab_markdown?(filename)
filename.end_with?(*%w(.mdown .md .markdown))
end
+
+ # Simple shortcut to File.join
+ def tree_join(*args)
+ File.join(*args)
+ end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index bb7b53fa..717fe296 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1,4 +1,4 @@
-require File.join(Rails.root, "app/models/commit")
+require Rails.root.join("app/models/commit")
class MergeRequest < ActiveRecord::Base
include IssueCommonality
diff --git a/app/models/tree.rb b/app/models/tree.rb
index d65e50ab..88e8f2f4 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -1,5 +1,5 @@
class Tree
- include Linguist::BlobHelper
+ include Linguist::BlobHelper
attr_accessor :path, :tree, :project, :ref
delegate :contents,
@@ -14,8 +14,8 @@ class Tree
to: :tree
def initialize(raw_tree, project, ref = nil, path = nil)
- @project, @ref, @path = project, ref, path,
- @tree = if path
+ @project, @ref, @path = project, ref, path
+ @tree = if path.present?
raw_tree / path.dup.force_encoding('ascii-8bit')
else
raw_tree
@@ -26,6 +26,10 @@ class Tree
tree.is_a?(Grit::Blob)
end
+ def invalid?
+ tree.nil?
+ end
+
def empty?
data.blank?
end
diff --git a/app/roles/repository.rb b/app/roles/repository.rb
index 01156ac1..35093a2f 100644
--- a/app/roles/repository.rb
+++ b/app/roles/repository.rb
@@ -45,8 +45,29 @@ module Repository
File.exists?(hook_file)
end
+ # Returns an Array of branch names
+ def branch_names
+ repo.branches.collect(&:name).sort
+ end
+
+ # Returns an Array of Branches
+ def branches
+ repo.branches.sort_by(&:name)
+ end
+
+ # Returns an Array of tag names
+ def tag_names
+ repo.tags.collect(&:name).sort.reverse
+ end
+
+ # Returns an Array of Tags
def tags
- repo.tags.map(&:name).sort.reverse
+ repo.tags.sort_by(&:name).reverse
+ end
+
+ # Returns an Array of branch and tag names
+ def ref_names
+ [branch_names + tag_names].flatten
end
def repo
@@ -79,14 +100,6 @@ module Repository
@heads ||= repo.heads
end
- def branches_names
- heads.map(&:name)
- end
-
- def ref_names
- [branches_names + tags].flatten
- end
-
def tree(fcommit, path = nil)
fcommit = commit if fcommit == :head
tree = fcommit.tree
@@ -109,14 +122,12 @@ module Repository
# - If two or more branches are present, returns the one that has a name
# matching root_ref (default_branch or 'master' if default_branch is nil)
def discover_default_branch
- branches = heads.collect(&:name)
-
- if branches.length == 0
+ if branch_names.length == 0
nil
- elsif branches.length == 1
- branches.first
+ elsif branch_names.length == 1
+ branch_names.first
else
- branches.select { |v| v == root_ref }.first
+ branch_names.select { |v| v == root_ref }.first
end
end
@@ -144,7 +155,7 @@ module Repository
# Build file path
file_name = self.code + "-" + commit.id.to_s + ".tar.gz"
- storage_path = File.join(Rails.root, "tmp", "repositories", self.code)
+ storage_path = Rails.root.join("tmp", "repositories", self.code)
file_path = File.join(storage_path, file_name)
# Put files into a directory before archiving
diff --git a/app/roles/static_model.rb b/app/roles/static_model.rb
index d26c8f47..d67af243 100644
--- a/app/roles/static_model.rb
+++ b/app/roles/static_model.rb
@@ -25,6 +25,10 @@ module StaticModel
id
end
+ def new_record?
+ false
+ end
+
def persisted?
false
end
diff --git a/app/views/refs/_head.html.haml b/app/views/blame/_head.html.haml
similarity index 75%
rename from app/views/refs/_head.html.haml
rename to app/views/blame/_head.html.haml
index 3592f573..3b027bda 100644
--- a/app/views/refs/_head.html.haml
+++ b/app/views/blame/_head.html.haml
@@ -1,9 +1,8 @@
%ul.nav.nav-tabs
%li
= render partial: 'shared/ref_switcher', locals: {destination: 'tree', path: params[:path]}
- %li{class: "#{'active' if (controller.controller_name == "refs") }"}
- = link_to tree_project_ref_path(@project, @ref) do
- Source
+ = nav_link(controller: :refs) do
+ = link_to 'Source', project_tree_path(@project, @ref)
%li.right
.input-prepend.project_clone_holder
%button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH
diff --git a/app/views/refs/blame.html.haml b/app/views/blame/show.html.haml
similarity index 62%
rename from app/views/refs/blame.html.haml
rename to app/views/blame/show.html.haml
index eb66f597..8f82b00f 100644
--- a/app/views/refs/blame.html.haml
+++ b/app/views/blame/show.html.haml
@@ -4,7 +4,7 @@
%ul.breadcrumb
%li
%span.arrow
- = link_to tree_project_ref_path(@project, @ref, path: nil) do
+ = link_to project_tree_path(@project, @ref) do
= @project.name
- @tree.breadcrumbs(6) do |link|
\/
@@ -18,9 +18,9 @@
= @tree.name
%small blame
%span.options
- = link_to "raw", blob_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small", target: "_blank"
- = link_to "history", project_commits_path(@project, path: params[:path], ref: @ref), class: "btn very_small"
- = link_to "source", tree_file_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small"
+ = link_to "raw", project_blob_path(@project, @id), class: "btn very_small", target: "_blank"
+ = link_to "history", project_commits_path(@project, @id), class: "btn very_small"
+ = link_to "source", project_tree_path(@project, @id), class: "btn very_small"
.file_content.blame
%table
- @blame.each do |commit, lines|
@@ -32,8 +32,8 @@
= commit.author_name
%td.blame_commit
- %code= link_to commit.short_id, project_commit_path(@project, id: commit.id)
- = link_to_gfm truncate(commit.title, length: 30), project_commit_path(@project, id: commit.id), class: "row_title" rescue "--broken encoding"
+ %code= link_to commit.short_id, project_commit_path(@project, commit)
+ = link_to_gfm truncate(commit.title, length: 30), project_commit_path(@project, commit), class: "row_title" rescue "--broken encoding"
%td.lines
= preserve do
%pre
diff --git a/app/views/commit/show.html.haml b/app/views/commit/show.html.haml
new file mode 100644
index 00000000..d12fff96
--- /dev/null
+++ b/app/views/commit/show.html.haml
@@ -0,0 +1,10 @@
+= render "commits/commit_box"
+= render "commits/diffs", diffs: @commit.diffs
+= render "notes/notes_with_form", tid: @commit.id, tt: "commit"
+= render "notes/per_line_form"
+
+
+:javascript
+ $(function(){
+ PerLineNotes.init();
+ });
diff --git a/app/views/commit/show.patch.erb b/app/views/commit/show.patch.erb
new file mode 100644
index 00000000..ce1c3d02
--- /dev/null
+++ b/app/views/commit/show.patch.erb
@@ -0,0 +1 @@
+<%= @commit.to_patch %>
diff --git a/app/views/commits/_commit.html.haml b/app/views/commits/_commit.html.haml
index 61371d14..259e8e26 100644
--- a/app/views/commits/_commit.html.haml
+++ b/app/views/commits/_commit.html.haml
@@ -1,16 +1,15 @@
%li.commit
.browse_code_link_holder
%p
- %strong= link_to "Browse Code »", tree_project_ref_path(@project, commit.id), class: "right"
+ %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right"
%p
- = link_to commit.short_id(8), project_commit_path(@project, id: commit.id), class: "commit_short_id"
+ = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
%strong.commit-author-name= commit.author_name
%span.dash –
= image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
- = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, id: commit.id), class: "row_title"
+ = link_to_gfm truncate(commit.title, length: 50), project_commit_path(@project, commit.id), class: "row_title"
%span.committed_ago
= time_ago_in_words(commit.committed_date)
ago
-
diff --git a/app/views/commits/_commit_box.html.haml b/app/views/commits/_commit_box.html.haml
index 572337de..b8151b56 100644
--- a/app/views/commits/_commit_box.html.haml
+++ b/app/views/commits/_commit_box.html.haml
@@ -5,10 +5,10 @@
%span.btn.disabled.grouped
%i.icon-comment
= @notes_count
- = link_to patch_project_commit_path(@project, @commit.id), class: "btn small grouped" do
+ = link_to project_commit_path(@project, @commit, format: :patch), class: "btn small grouped" do
%i.icon-download-alt
Get Patch
- = link_to tree_project_ref_path(@project, @commit.id), class: "browse-button primary grouped" do
+ = link_to project_tree_path(@project, @commit), class: "browse-button primary grouped" do
%strong Browse Code »
%h3.commit-title.page_title
= gfm escape_once(@commit.title)
diff --git a/app/views/commits/_diffs.html.haml b/app/views/commits/_diffs.html.haml
index b590d64c..026fe27e 100644
--- a/app/views/commits/_diffs.html.haml
+++ b/app/views/commits/_diffs.html.haml
@@ -5,7 +5,7 @@
%p To prevent performance issue we rejected diff information.
%p
But if you still want to see diff
- = link_to "click this link", project_commit_path(@project, @commit.id, force_show_diff: true), class: "dark"
+ = link_to "click this link", project_commit_path(@project, @commit, force_show_diff: true), class: "dark"
%p.cgray
Showing #{pluralize(diffs.count, "changed file")}
@@ -24,7 +24,7 @@
%i.icon-file
%span{id: "#{diff.old_path}"}= diff.old_path
- else
- = link_to tree_file_project_ref_path(@project, @commit.id, diff.new_path) do
+ = link_to project_tree_path(@project, tree_join(@commit.id, diff.new_path)) do
%i.icon-file
%span{id: "#{diff.new_path}"}= diff.new_path
%br/
diff --git a/app/views/commits/_head.html.haml b/app/views/commits/_head.html.haml
index a8111a72..26ae32ed 100644
--- a/app/views/commits/_head.html.haml
+++ b/app/views/commits/_head.html.haml
@@ -1,23 +1,23 @@
%ul.nav.nav-tabs
%li= render partial: 'shared/ref_switcher', locals: {destination: 'commits'}
- %li{class: "#{'active' if current_page?(project_commits_path(@project)) }"}
- = link_to project_commits_path(@project) do
- Commits
- %li{class: "#{'active' if current_page?(compare_project_commits_path(@project)) }"}
- = link_to compare_project_commits_path(@project) do
- Compare
- %li{class: "#{branches_tab_class}"}
+
+ = nav_link(controller: [:commit, :commits]) do
+ = link_to 'Commits', project_commits_path(@project, @project.root_ref)
+ = nav_link(controller: :compare) do
+ = link_to 'Compare', project_compare_index_path(@project)
+
+ = nav_link(html_options: {class: branches_tab_class}) do
= link_to project_repository_path(@project) do
Branches
%span.badge= @project.repo.branch_count
- %li{class: "#{'active' if current_page?(tags_project_repository_path(@project)) }"}
+ = nav_link(controller: :repositories, action: :tags) do
= link_to tags_project_repository_path(@project) do
Tags
%span.badge= @project.repo.tag_count
- - if current_page?(project_commits_path(@project)) && current_user.private_token
+ - if current_controller?(:commits) && current_user.private_token
%li.right
%span.rss-icon
- = link_to project_commits_path(@project, :atom, { private_token: current_user.private_token, ref: @ref }), title: "Feed" do
+ = link_to project_commits_path(@project, @ref, {format: :atom, private_token: current_user.private_token}), title: "Feed" do
= image_tag "rss_ui.png", title: "feed"
diff --git a/app/views/commits/index.html.haml b/app/views/commits/index.html.haml
deleted file mode 100644
index 11ffdb6a..00000000
--- a/app/views/commits/index.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-= render "head"
-
-- if params[:path]
- %ul.breadcrumb
- %li
- %span.arrow
- = link_to project_commits_path(@project) do
- = @project.name
- %span.divider
- \/
- %li
- %a{href: "#"}= params[:path].split("/").join(" / ")
-
-%div{id: dom_id(@project)}
- #commits_list= render "commits"
-.clear
-.loading{ style: "display:none;"}
-
-- if @commits.count == @limit
- :javascript
- $(function(){
- CommitsList.init("#{@ref}", #{@limit});
- });
-
diff --git a/app/views/commits/index.atom.builder b/app/views/commits/show.atom.builder
similarity index 80%
rename from app/views/commits/index.atom.builder
rename to app/views/commits/show.atom.builder
index cca70456..46f9838e 100644
--- a/app/views/commits/index.atom.builder
+++ b/app/views/commits/show.atom.builder
@@ -1,8 +1,8 @@
xml.instruct!
xml.feed "xmlns" => "http://www.w3.org/2005/Atom", "xmlns:media" => "http://search.yahoo.com/mrss/" do
xml.title "Recent commits to #{@project.name}:#{@ref}"
- xml.link :href => project_commits_url(@project, :atom, :ref => @ref), :rel => "self", :type => "application/atom+xml"
- xml.link :href => project_commits_url(@project), :rel => "alternate", :type => "text/html"
+ xml.link :href => project_commits_url(@project, @ref, format: :atom), :rel => "self", :type => "application/atom+xml"
+ xml.link :href => project_commits_url(@project, @ref), :rel => "alternate", :type => "text/html"
xml.id project_commits_url(@project)
xml.updated @commits.first.committed_date.strftime("%Y-%m-%dT%H:%M:%SZ") if @commits.any?
diff --git a/app/views/commits/show.html.haml b/app/views/commits/show.html.haml
index d12fff96..a4f16465 100644
--- a/app/views/commits/show.html.haml
+++ b/app/views/commits/show.html.haml
@@ -1,10 +1,24 @@
-= render "commits/commit_box"
-= render "commits/diffs", diffs: @commit.diffs
-= render "notes/notes_with_form", tid: @commit.id, tt: "commit"
-= render "notes/per_line_form"
+= render "head"
+- if @path
+ %ul.breadcrumb
+ %li
+ %span.arrow
+ = link_to project_commits_path(@project) do
+ = @project.name
+ %span.divider
+ \/
+ %li
+ %a{href: "#"}= @path.split("/").join(" / ")
+
+%div{id: dom_id(@project)}
+ #commits_list= render "commits"
+.clear
+.loading{ style: "display:none;"}
+
+- if @commits.count == @limit
+ :javascript
+ $(function(){
+ CommitsList.init("#{@ref}", #{@limit});
+ });
-:javascript
- $(function(){
- PerLineNotes.init();
- });
diff --git a/app/views/commits/index.js.haml b/app/views/commits/show.js.haml
similarity index 100%
rename from app/views/commits/index.js.haml
rename to app/views/commits/show.js.haml
diff --git a/app/views/commits/compare.html.haml b/app/views/compare/_form.html.haml
similarity index 64%
rename from app/views/commits/compare.html.haml
rename to app/views/compare/_form.html.haml
index db15ba53..07f1c818 100644
--- a/app/views/commits/compare.html.haml
+++ b/app/views/compare/_form.html.haml
@@ -1,9 +1,3 @@
-= render "head"
-
-%h3.page_title
- Compare View
-%hr
-
%div
%p.slead
Fill input field with commit id like
@@ -14,7 +8,7 @@
%br
- = form_tag compare_project_commits_path(@project), method: :get do
+ = form_tag project_compare_index_path(@project), method: :post do
.clearfix
= text_field_tag :from, params[:from], placeholder: "master", class: "xlarge"
= "..."
@@ -25,29 +19,14 @@
.actions
= submit_tag "Compare", class: "btn primary wide commits-compare-btn"
-- if @commits.present?
- %div.ui-box
- %h5.small Commits (#{@commits.count})
- %ul.unstyled= render @commits
-
- - unless @diffs.empty?
- %h4 Diff
- = render "commits/diffs", diffs: @diffs
-
:javascript
$(function() {
var availableTags = #{@project.ref_names.to_json};
- $("#from").autocomplete({
- source: availableTags,
- minLength: 1
- });
-
- $("#to").autocomplete({
+ $("#from, #to").autocomplete({
source: availableTags,
minLength: 1
});
disableButtonIfEmptyField('#to', '.commits-compare-btn');
});
-
diff --git a/app/views/compare/index.html.haml b/app/views/compare/index.html.haml
new file mode 100644
index 00000000..6c9a5fd8
--- /dev/null
+++ b/app/views/compare/index.html.haml
@@ -0,0 +1,7 @@
+= render "commits/head"
+
+%h3.page_title
+ Compare View
+%hr
+
+= render "form"
diff --git a/app/views/compare/show.html.haml b/app/views/compare/show.html.haml
new file mode 100644
index 00000000..528c8b44
--- /dev/null
+++ b/app/views/compare/show.html.haml
@@ -0,0 +1,16 @@
+= render "commits/head"
+
+%h3.page_title
+ Compare View
+%hr
+
+= render "form"
+
+- if @commits.present?
+ %div.ui-box
+ %h5.small Commits (#{@commits.count})
+ %ul.unstyled= render @commits
+
+ - unless @diffs.empty?
+ %h4 Diff
+ = render "commits/diffs", diffs: @diffs
diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml
index ed4f33c0..ea417aa9 100644
--- a/app/views/events/_commit.html.haml
+++ b/app/views/events/_commit.html.haml
@@ -1,7 +1,7 @@
- commit = CommitDecorator.decorate(commit)
%li.commit
%p
- = link_to commit.short_id(8), project_commit_path(project, id: commit.id), class: "commit_short_id"
+ = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id"
%span= commit.author_name
–
= image_tag gravatar_icon(commit.author_email), class: "avatar", width: 16
diff --git a/app/views/events/_event_last_push.html.haml b/app/views/events/_event_last_push.html.haml
index 81b9994c..d70be70c 100644
--- a/app/views/events/_event_last_push.html.haml
+++ b/app/views/events/_event_last_push.html.haml
@@ -4,7 +4,7 @@
= image_tag gravatar_icon(event.author_email), class: "avatar"
%span You pushed to
= event.ref_type
- = link_to project_commits_path(event.project, ref: event.ref_name) do
+ = link_to project_commits_path(event.project, event.ref_name) do
%strong= truncate(event.ref_name, length: 28)
at
%strong= link_to event.project.name, event.project
diff --git a/app/views/events/_event_push.html.haml b/app/views/events/_event_push.html.haml
index c0be9cf5..9b7f10d9 100644
--- a/app/views/events/_event_push.html.haml
+++ b/app/views/events/_event_push.html.haml
@@ -5,7 +5,7 @@
.event-title
%strong.author_name #{event.author_name}
%span.event_label.pushed #{event.push_action_name} #{event.ref_type}
- = link_to project_commits_path(event.project, ref: event.ref_name) do
+ = link_to project_commits_path(event.project, event.ref_name) do
%strong= event.ref_name
at
%strong= link_to event.project.name, event.project
@@ -21,6 +21,6 @@
%li.commits-stat
- if event.commits_count > 2
%span ... and #{event.commits_count - 2} more commits.
- = link_to compare_project_commits_path(event.project, from: event.parent_commit.id, to: event.last_commit.id) do
+ = link_to project_compare_path(event.project, from: event.parent_commit.id, to: event.last_commit.id) do
%strong Compare → #{event.parent_commit.id[0..7]}...#{event.last_commit.id[0..7]}
.clearfix
diff --git a/app/views/issues/_head.html.haml b/app/views/issues/_head.html.haml
index 8ebe3e05..4294503c 100644
--- a/app/views/issues/_head.html.haml
+++ b/app/views/issues/_head.html.haml
@@ -1,13 +1,10 @@
%ul.nav.nav-tabs
- %li{class: "#{'active' if current_page?(project_issues_path(@project))}"}
- = link_to project_issues_path(@project), class: "tab" do
- Browse Issues
- %li{class: "#{'active' if current_page?(project_milestones_path(@project))}"}
- = link_to project_milestones_path(@project), class: "tab" do
- Milestones
- %li{class: "#{'active' if current_page?(project_labels_path(@project))}"}
- = link_to project_labels_path(@project), class: "tab" do
- Labels
+ = nav_link(controller: :issues) do
+ = link_to 'Browse Issues', project_issues_path(@project), class: "tab"
+ = nav_link(controller: :milestones) do
+ = link_to 'Milestones', project_milestones_path(@project), class: "tab"
+ = nav_link(controller: :labels) do
+ = link_to 'Labels', project_labels_path(@project), class: "tab"
%li.right
%span.rss-icon
= link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }) do
diff --git a/app/views/layouts/_app_menu.html.haml b/app/views/layouts/_app_menu.html.haml
deleted file mode 100644
index 02531489..00000000
--- a/app/views/layouts/_app_menu.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-%ul.main_menu
- %li.home{class: tab_class(:root)}
- = link_to "Home", root_path, title: "Home"
-
- %li{class: tab_class(:dash_issues)}
- = link_to dashboard_issues_path do
- Issues
- %span.count= current_user.assigned_issues.opened.count
-
- %li{class: tab_class(:dash_mr)}
- = link_to dashboard_merge_requests_path do
- Merge Requests
- %span.count= current_user.cared_merge_requests.count
-
- %li{class: tab_class(:search)}
- = link_to "Search", search_path
-
- %li{class: tab_class(:help)}
- = link_to "Help", help_path
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index c076a3a1..25fe9d80 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -10,8 +10,8 @@
- if controller_name == 'projects' && action_name == 'index'
= auto_discovery_link_tag :atom, projects_url(:atom, private_token: current_user.private_token), title: "Dashboard feed"
- if @project && !@project.new_record?
- - if current_page?(tree_project_ref_path(@project, @project.root_ref)) || current_page?(project_commits_path(@project))
- = auto_discovery_link_tag(:atom, project_commits_url(@project, :atom, ref: @ref, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")
- - if request.path == project_issues_path(@project)
+ - if current_controller?(:tree, :commits)
+ = auto_discovery_link_tag(:atom, project_commits_url(@project, @ref, format: :atom, private_token: current_user.private_token), title: "Recent commits to #{@project.name}:#{@ref}")
+ - if current_controller?(:issues)
= auto_discovery_link_tag(:atom, project_issues_url(@project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
= csrf_meta_tags
diff --git a/app/views/layouts/_project_menu.html.haml b/app/views/layouts/_project_menu.html.haml
deleted file mode 100644
index 04eaec5a..00000000
--- a/app/views/layouts/_project_menu.html.haml
+++ /dev/null
@@ -1,37 +0,0 @@
-%ul.main_menu
- %li.home{class: project_tab_class}
- = link_to @project.code, project_path(@project), title: "Project"
-
- - if @project.repo_exists?
- - if can? current_user, :download_code, @project
- %li{class: tree_tab_class}
- = link_to tree_project_ref_path(@project, @project.root_ref) do
- Files
- %li{class: commit_tab_class}
- = link_to "Commits", project_commits_path(@project)
-
- %li{class: tab_class(:network)}
- = link_to "Network", graph_project_path(@project)
-
- - if @project.issues_enabled
- %li{class: tab_class(:issues)}
- = link_to project_issues_filter_path(@project) do
- Issues
- %span.count.issue_counter= @project.issues.opened.count
-
- - if @project.repo_exists?
- - if @project.merge_requests_enabled
- %li{class: tab_class(:merge_requests)}
- = link_to project_merge_requests_path(@project) do
- Merge Requests
- %span.count.merge_counter= @project.merge_requests.opened.count
-
- - if @project.wall_enabled
- %li{class: tab_class(:wall)}
- = link_to wall_project_path(@project) do
- Wall
-
- - if @project.wiki_enabled
- %li{class: tab_class(:wiki)}
- = link_to project_wiki_path(@project, :index) do
- Wiki
diff --git a/app/views/layouts/admin.html.haml b/app/views/layouts/admin.html.haml
index 6af0f641..dbb6939d 100644
--- a/app/views/layouts/admin.html.haml
+++ b/app/views/layouts/admin.html.haml
@@ -6,17 +6,17 @@
= render "layouts/head_panel", title: "Admin area"
.container
%ul.main_menu
- %li.home{class: tab_class(:admin_root)}
+ = nav_link(controller: :dashboard, html_options: {class: 'home'}) do
= link_to "Stats", admin_root_path
- %li{class: tab_class(:admin_projects)}
+ = nav_link(controller: :projects) do
= link_to "Projects", admin_projects_path
- %li{class: tab_class(:admin_users)}
+ = nav_link(controller: :users) do
= link_to "Users", admin_users_path
- %li{class: tab_class(:admin_logs)}
+ = nav_link(controller: :logs) do
= link_to "Logs", admin_logs_path
- %li{class: tab_class(:admin_hooks)}
+ = nav_link(controller: :hooks) do
= link_to "Hooks", admin_hooks_path
- %li{class: tab_class(:admin_resque)}
+ = nav_link(controller: :resque) do
= link_to "Resque", admin_resque_path
.content= yield
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index dda10d5d..40f4f88c 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -5,6 +5,20 @@
= render "layouts/flash"
= render "layouts/head_panel", title: "Dashboard"
.container
- = render partial: "layouts/app_menu"
- .content
- = yield
+ %ul.main_menu
+ = nav_link(path: 'dashboard#index', html_options: {class: 'home'}) do
+ = link_to "Home", root_path, title: "Home"
+ = nav_link(path: 'dashboard#issues') do
+ = link_to dashboard_issues_path do
+ Issues
+ %span.count= current_user.assigned_issues.opened.count
+ = nav_link(path: 'dashboard#merge_requests') do
+ = link_to dashboard_merge_requests_path do
+ Merge Requests
+ %span.count= current_user.cared_merge_requests.count
+ = nav_link(path: 'search#show') do
+ = link_to "Search", search_path
+ = nav_link(path: 'help#index') do
+ = link_to "Help", help_path
+
+ .content= yield
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index 62c8db5b..7a54bb7c 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -6,23 +6,17 @@
= render "layouts/head_panel", title: "Profile"
.container
%ul.main_menu
- %li.home{class: tab_class(:profile)}
+ = nav_link(path: 'profile#show', html_options: {class: 'home'}) do
= link_to "Profile", profile_path
-
- %li{class: tab_class(:account)}
+ = nav_link(path: 'profile#account') do
= link_to "Account", profile_account_path
-
- %li{class: tab_class(:ssh_keys)}
+ = nav_link(controller: :keys) do
= link_to keys_path do
SSH Keys
%span.count= current_user.keys.count
-
- %li{class: tab_class(:design)}
+ = nav_link(path: 'profile#design') do
= link_to "Design", profile_design_path
-
- %li{class: tab_class(:history)}
+ = nav_link(path: 'profile#history') do
= link_to "History", profile_history_path
-
- .content
- = yield
+ .content= yield
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index 56a947d2..b1dbe41c 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -5,7 +5,37 @@
= render "layouts/flash"
= render "layouts/head_panel", title: @project.name
.container
- = render partial: "layouts/project_menu"
- .content
- = yield
+ %ul.main_menu
+ = nav_link(html_options: {class: "home #{project_tab_class}"}) do
+ = link_to @project.code, project_path(@project), title: "Project"
+ - if @project.repo_exists?
+ - if can? current_user, :download_code, @project
+ = nav_link(controller: %w(tree blob blame)) do
+ = link_to 'Files', project_tree_path(@project, @ref || @project.root_ref)
+ = nav_link(controller: %w(commit commits compare repositories protected_branches)) do
+ = link_to "Commits", project_commits_path(@project, @ref || @project.root_ref)
+ = nav_link(path: 'projects#graph') do
+ = link_to "Network", graph_project_path(@project)
+
+ - if @project.issues_enabled
+ = nav_link(controller: %w(issues milestones labels)) do
+ = link_to project_issues_filter_path(@project) do
+ Issues
+ %span.count.issue_counter= @project.issues.opened.count
+
+ - if @project.repo_exists? && @project.merge_requests_enabled
+ = nav_link(controller: :merge_requests) do
+ = link_to project_merge_requests_path(@project) do
+ Merge Requests
+ %span.count.merge_counter= @project.merge_requests.opened.count
+
+ - if @project.wall_enabled
+ = nav_link(path: 'projects#wall') do
+ = link_to 'Wall', wall_project_path(@project)
+
+ - if @project.wiki_enabled
+ = nav_link(controller: :wikis) do
+ = link_to 'Wiki', project_wiki_path(@project, :index)
+
+ .content= yield
diff --git a/app/views/projects/_project_head.html.haml b/app/views/projects/_project_head.html.haml
index 4f38bef8..47a79073 100644
--- a/app/views/projects/_project_head.html.haml
+++ b/app/views/projects/_project_head.html.haml
@@ -1,29 +1,27 @@
%ul.nav.nav-tabs
- %li{ class: "#{'active' if current_page?(project_path(@project)) }" }
+ = nav_link(path: 'projects#show') do
= link_to project_path(@project), class: "activities-tab tab" do
%i.icon-home
Show
- %li{ class: " #{'active' if (controller.controller_name == "team_members") || current_page?(project_team_index_path(@project)) }" }
+ = nav_link(controller: :team_members) do
= link_to project_team_index_path(@project), class: "team-tab tab" do
%i.icon-user
Team
- %li{ class: "#{'active' if current_page?(files_project_path(@project)) }" }
- = link_to files_project_path(@project), class: "files-tab tab " do
- Attachments
- %li{ class: " #{'active' if (controller.controller_name == "snippets") }" }
- = link_to project_snippets_path(@project), class: "snippets-tab tab" do
- Snippets
+ = nav_link(path: 'projects#files') do
+ = link_to 'Attachments', files_project_path(@project), class: "files-tab tab"
+ = nav_link(controller: :snippets) do
+ = link_to 'Snippets', project_snippets_path(@project), class: "snippets-tab tab"
- if can? current_user, :admin_project, @project
- %li.right{class: "#{'active' if controller.controller_name == "deploy_keys"}"}
+ = nav_link(controller: :deploy_keys, html_options: {class: 'right'}) do
= link_to project_deploy_keys_path(@project) do
%span
Deploy Keys
- %li.right{class: "#{'active' if controller.controller_name == "hooks" }"}
+ = nav_link(controller: :hooks, html_options: {class: 'right'}) do
= link_to project_hooks_path(@project) do
%span
Hooks
- %li.right{ class: "#{'active' if current_page?(edit_project_path(@project)) }" }
+ = nav_link(path: 'projects#edit', html_options: {class: 'right'}) do
= link_to edit_project_path(@project), class: "stat-tab tab " do
%i.icon-edit
Edit
diff --git a/app/views/protected_branches/index.html.haml b/app/views/protected_branches/index.html.haml
index 43884de1..50a81712 100644
--- a/app/views/protected_branches/index.html.haml
+++ b/app/views/protected_branches/index.html.haml
@@ -34,7 +34,7 @@
- @branches.each do |branch|
%tr
%td
- = link_to project_commits_path(@project, ref: branch.name) do
+ = link_to project_commits_path(@project, branch.name) do
%strong= branch.name
- if branch.name == @project.root_ref
%span.label default
diff --git a/app/views/refs/logs_tree.js.haml b/app/views/refs/logs_tree.js.haml
index 61ccbaee..b0ac0c4b 100644
--- a/app/views/refs/logs_tree.js.haml
+++ b/app/views/refs/logs_tree.js.haml
@@ -6,4 +6,4 @@
:plain
var row = $("table.table_#{@hex_path} tr.file_#{hexdigest(file_name)}");
row.find("td.tree_time_ago").html('#{escape_javascript(time_ago_in_words(content_commit.committed_date))} ago');
- row.find("td.tree_commit").html('#{escape_javascript(render("tree_commit", tm: tm, content_commit: content_commit))}');
+ row.find("td.tree_commit").html('#{escape_javascript(render("tree/tree_commit", tm: tm, content_commit: content_commit))}');
diff --git a/app/views/refs/tree.html.haml b/app/views/refs/tree.html.haml
deleted file mode 100644
index 181be642..00000000
--- a/app/views/refs/tree.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-= render "head"
-#tree-holder= render partial: "tree", locals: {repo: @repo, commit: @commit, tree: @tree}
-
-:javascript
- $(function() {
- Tree.init();
- });
diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml
index 64a633be..3c1fe47c 100644
--- a/app/views/repositories/_branch.html.haml
+++ b/app/views/repositories/_branch.html.haml
@@ -2,12 +2,12 @@
- commit = CommitDecorator.decorate(commit)
%tr
%td
- = link_to project_commits_path(@project, ref: branch.name) do
+ = link_to project_commits_path(@project, branch.name) do
%strong= truncate(branch.name, length: 60)
- if branch.name == @project.root_ref
%span.label default
%td
- = link_to project_commit_path(@project, id: commit.id) do
+ = link_to project_commit_path(@project, commit) do
%code= commit.short_id
= image_tag gravatar_icon(commit.author_email), class: "", width: 16
diff --git a/app/views/repositories/_branches_head.html.haml b/app/views/repositories/_branches_head.html.haml
index 6afff627..25a988cf 100644
--- a/app/views/repositories/_branches_head.html.haml
+++ b/app/views/repositories/_branches_head.html.haml
@@ -1,11 +1,8 @@
= render "commits/head"
%ul.nav.nav-pills
- %li{class: ("active" if current_page?(project_repository_path(@project)))}
- = link_to project_repository_path(@project) do
- Recent
- %li{class: ("active" if current_page?(project_protected_branches_path(@project)))}
- = link_to project_protected_branches_path(@project) do
- Protected
- %li{class: ("active" if current_page?(branches_project_repository_path(@project)))}
- = link_to branches_project_repository_path(@project) do
- All
+ = nav_link(path: 'repositories#show') do
+ = link_to 'Recent', project_repository_path(@project)
+ = nav_link(path: 'protected_branches#index') do
+ = link_to 'Protected', project_protected_branches_path(@project)
+ = nav_link(path: 'repositories#branches') do
+ = link_to 'All', branches_project_repository_path(@project)
diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml
index 0c13551d..496328ba 100644
--- a/app/views/repositories/_feed.html.haml
+++ b/app/views/repositories/_feed.html.haml
@@ -2,7 +2,7 @@
- commit = CommitDecorator.new(commit)
%tr
%td
- = link_to project_commits_path(@project, ref: commit.head.name) do
+ = link_to project_commits_path(@project, commit.head.name) do
%strong
= commit.head.name
- if commit.head.name == @project.root_ref
diff --git a/app/views/repositories/tags.html.haml b/app/views/repositories/tags.html.haml
index a4114586..38cc3aca 100644
--- a/app/views/repositories/tags.html.haml
+++ b/app/views/repositories/tags.html.haml
@@ -12,7 +12,7 @@
- commit = CommitDecorator.decorate(commit)
%tr
%td
- %strong= link_to tag.name, project_commits_path(@project, ref: tag.name), class: ""
+ %strong= link_to tag.name, project_commits_path(@project, tag.name), class: ""
%td
= link_to project_commit_path(@project, commit.id) do
%code= commit.short_id
diff --git a/app/views/shared/_ref_switcher.html.haml b/app/views/shared/_ref_switcher.html.haml
index e0c89522..8b44cf19 100644
--- a/app/views/shared/_ref_switcher.html.haml
+++ b/app/views/shared/_ref_switcher.html.haml
@@ -1,5 +1,5 @@
= form_tag switch_project_refs_path(@project), method: :get, class: "project-refs-form" do
= select_tag "ref", grouped_options_refs, class: "project-refs-select chosen"
= hidden_field_tag :destination, destination
- - if respond_to?(:path)
+ - if defined?(path)
= hidden_field_tag :path, path
diff --git a/app/views/tree/_head.html.haml b/app/views/tree/_head.html.haml
new file mode 100644
index 00000000..f1b3f63f
--- /dev/null
+++ b/app/views/tree/_head.html.haml
@@ -0,0 +1,10 @@
+%ul.nav.nav-tabs
+ %li
+ = render partial: 'shared/ref_switcher', locals: {destination: 'tree', path: @path}
+ = nav_link(controller: :tree) do
+ = link_to 'Source', project_tree_path(@project, @ref)
+ %li.right
+ .input-prepend.project_clone_holder
+ %button{class: "btn small active", :"data-clone" => @project.ssh_url_to_repo} SSH
+ %button{class: "btn small", :"data-clone" => @project.http_url_to_repo} HTTP
+ = text_field_tag :project_clone, @project.url_to_repo, class: "one_click_select span5"
diff --git a/app/views/refs/_submodule_item.html.haml b/app/views/tree/_submodule_item.html.haml
similarity index 100%
rename from app/views/refs/_submodule_item.html.haml
rename to app/views/tree/_submodule_item.html.haml
diff --git a/app/views/refs/_tree.html.haml b/app/views/tree/_tree.html.haml
similarity index 85%
rename from app/views/refs/_tree.html.haml
rename to app/views/tree/_tree.html.haml
index 55078718..439b4ec2 100644
--- a/app/views/refs/_tree.html.haml
+++ b/app/views/tree/_tree.html.haml
@@ -1,7 +1,7 @@
%ul.breadcrumb
%li
%span.arrow
- = link_to tree_project_ref_path(@project, @ref, path: nil), remote: true do
+ = link_to project_tree_path(@project, @ref), remote: true do
= @project.name
- tree.breadcrumbs(6) do |link|
\/
@@ -10,7 +10,7 @@
%div.tree_progress
#tree-content-holder
- if tree.is_blob?
- = render partial: "refs/tree_file", locals: { name: tree.name, content: tree.data, file: tree }
+ = render partial: "tree/tree_file", locals: { name: tree.name, content: tree.data, file: tree }
- else
- contents = tree.contents
%table#tree-slider{class: "table_#{@hex_path}" }
@@ -31,11 +31,11 @@
- index = 0
- contents.select{ |i| i.is_a?(Grit::Tree)}.each do |content|
- = render partial: "refs/tree_item", locals: { content: content, index: (index += 1) }
+ = render partial: "tree/tree_item", locals: { content: content, index: (index += 1) }
- contents.select{ |i| i.is_a?(Grit::Blob)}.each do |content|
- = render partial: "refs/tree_item", locals: { content: content, index: (index += 1) }
+ = render partial: "tree/tree_item", locals: { content: content, index: (index += 1) }
- contents.select{ |i| i.is_a?(Grit::Submodule)}.each do |content|
- = render partial: "refs/submodule_item", locals: { content: content, index: (index += 1) }
+ = render partial: "tree/submodule_item", locals: { content: content, index: (index += 1) }
- if content = contents.select{ |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }.first
.file_holder#README
diff --git a/app/views/refs/_tree_commit.html.haml b/app/views/tree/_tree_commit.html.haml
similarity index 100%
rename from app/views/refs/_tree_commit.html.haml
rename to app/views/tree/_tree_commit.html.haml
diff --git a/app/views/refs/_tree_file.html.haml b/app/views/tree/_tree_file.html.haml
similarity index 69%
rename from app/views/refs/_tree_file.html.haml
rename to app/views/tree/_tree_file.html.haml
index 76173e24..93f7be28 100644
--- a/app/views/refs/_tree_file.html.haml
+++ b/app/views/tree/_tree_file.html.haml
@@ -5,9 +5,9 @@
= name.force_encoding('utf-8')
%small #{file.mode}
%span.options
- = link_to "raw", blob_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small", target: "_blank"
- = link_to "history", project_commits_path(@project, path: params[:path], ref: @ref), class: "btn very_small"
- = link_to "blame", blame_file_project_ref_path(@project, @ref, path: params[:path]), class: "btn very_small"
+ = link_to "raw", project_blob_path(@project, @id), class: "btn very_small", target: "_blank"
+ = link_to "history", project_commits_path(@project, @id), class: "btn very_small"
+ = link_to "blame", project_blame_path(@project, @id), class: "btn very_small"
- if file.text?
- if gitlab_markdown?(name)
.file_content.wiki
@@ -32,7 +32,7 @@
- else
.file_content.blob_file
%center
- = link_to blob_project_ref_path(@project, @ref, path: params[:path]) do
+ = link_to project_blob_path(@project, @id) do
%div.padded
%br
= image_tag "download.png", width: 64
diff --git a/app/views/refs/_tree_item.html.haml b/app/views/tree/_tree_item.html.haml
similarity index 51%
rename from app/views/refs/_tree_item.html.haml
rename to app/views/tree/_tree_item.html.haml
index d4c4ee8d..226c380f 100644
--- a/app/views/refs/_tree_item.html.haml
+++ b/app/views/tree/_tree_item.html.haml
@@ -1,8 +1,8 @@
- file = tree_full_path(content)
-%tr{ class: "tree-item #{tree_hex_class(content)}", url: tree_file_project_ref_path(@project, @ref, file) }
+%tr{ class: "tree-item #{tree_hex_class(content)}", url: project_tree_path(@project, tree_join(@id, file)) }
%td.tree-item-file-name
= tree_icon(content)
- %strong= link_to truncate(content.name, length: 40), tree_file_project_ref_path(@project, @ref || @commit.id, file), remote: :true
+ %strong= link_to truncate(content.name, length: 40), project_tree_path(@project, tree_join(@id || @commit.id, file)), remote: :true
%td.tree_time_ago.cgray
- if index == 1
%span.log_loading
diff --git a/app/views/tree/show.html.haml b/app/views/tree/show.html.haml
new file mode 100644
index 00000000..d95f90e0
--- /dev/null
+++ b/app/views/tree/show.html.haml
@@ -0,0 +1,7 @@
+= render "head"
+#tree-holder= render partial: "tree", locals: {commit: @commit, tree: @tree}
+
+:javascript
+ $(function() {
+ Tree.init();
+ });
diff --git a/app/views/refs/tree.js.haml b/app/views/tree/show.js.haml
similarity index 71%
rename from app/views/refs/tree.js.haml
rename to app/views/tree/show.js.haml
index 92e90579..174e3e03 100644
--- a/app/views/refs/tree.js.haml
+++ b/app/views/tree/show.js.haml
@@ -1,8 +1,8 @@
:plain
// Load Files list
- $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {repo: @repo, commit: @commit, tree: @tree}))}");
+ $("#tree-holder").html("#{escape_javascript(render(partial: "tree", locals: {commit: @commit, tree: @tree}))}");
$("#tree-content-holder").show("slide", { direction: "right" }, 150);
- $('.project-refs-form #path').val("#{params[:path]}");
+ $('.project-refs-form #path').val("#{@path}");
// Load last commit log for each file in tree
$('#tree-slider').waitForImages(function() {
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 7a7ca43f..276707a7 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -112,7 +112,7 @@ class Settings < Settingslogic
def backup_path
t = app['backup_path'] || "backups/"
- t = /^\//.match(t) ? t : File.join(Rails.root + t)
+ t = /^\//.match(t) ? t : Rails.root .join(t)
t
end
diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb
index 9e8b0131..5d46ece1 100644
--- a/config/initializers/inflections.rb
+++ b/config/initializers/inflections.rb
@@ -8,3 +8,24 @@
# inflect.irregular 'person', 'people'
# inflect.uncountable %w( fish sheep )
# end
+
+# Mark "commits" as uncountable.
+#
+# Without this change, the routes
+#
+# resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
+# resources :commits, only: [:show], constraints: {id: /.+/}
+#
+# would generate identical route helper methods (`project_commit_path`), resulting
+# in one of them not getting a helper method at all.
+#
+# After this change, the helper methods are:
+#
+# project_commit_path(@project, @project.commit)
+# # => "/gitlabhq/commit/bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a
+#
+# project_commits_path(@project, 'stable/README.md')
+# # => "/gitlabhq/commits/stable/README.md"
+ActiveSupport::Inflector.inflections do |inflect|
+ inflect.uncountable %w(commits)
+end
diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb
index 72aca7e4..3549b836 100644
--- a/config/initializers/mime_types.rb
+++ b/config/initializers/mime_types.rb
@@ -3,3 +3,5 @@
# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register_alias "text/html", :iphone
+
+Mime::Type.register_alias 'text/plain', :patch
diff --git a/config/routes.rb b/config/routes.rb
index cfb9bdb9..21521a97 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -122,38 +122,14 @@ Gitlab::Application.routes.draw do
end
member do
- get "tree", constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }
+ # tree viewer logs
get "logs_tree", constraints: { id: /[a-zA-Z.\/0-9_\-]+/ }
-
- get "blob",
- constraints: {
- id: /[a-zA-Z.0-9\/_\-]+/,
- path: /.*/
- }
-
- # tree viewer
- get "tree/:path" => "refs#tree",
- as: :tree_file,
- constraints: {
- id: /[a-zA-Z.0-9\/_\-]+/,
- path: /.*/
- }
-
- # tree viewer
get "logs_tree/:path" => "refs#logs_tree",
as: :logs_file,
constraints: {
id: /[a-zA-Z.0-9\/_\-]+/,
path: /.*/
}
-
- # blame
- get "blame/:path" => "refs#blame",
- as: :blame_file,
- constraints: {
- id: /[a-zA-Z.0-9\/_\-]+/,
- path: /.*/
- }
end
end
@@ -182,27 +158,27 @@ Gitlab::Application.routes.draw do
get :test
end
end
- resources :commits do
- collection do
- get :compare
- end
- member do
- get :patch
- end
- end
+ resources :commit, only: [:show], constraints: {id: /[[:alnum:]]{6,40}/}
+ resources :commits, only: [:show], constraints: {id: /.+/}
+ resources :compare, only: [:index, :create]
+ resources :blame, only: [:show], constraints: {id: /.+/}
+ resources :blob, only: [:show], constraints: {id: /.+/}
+ resources :tree, only: [:show], constraints: {id: /.+/}
+ match "/compare/:from...:to" => "compare#show", as: "compare", constraints: {from: /.+/, to: /.+/}
+
resources :team, controller: 'team_members', only: [:index]
resources :team_members
resources :milestones
resources :labels, only: [:index]
resources :issues do
-
collection do
post :sort
post :bulk_update
get :search
end
end
+
resources :notes, only: [:index, :create, :destroy] do
collection do
post :preview
diff --git a/db/fixtures/test/001_repo.rb b/db/fixtures/test/001_repo.rb
index 67d4e7bf..18fc37cd 100644
--- a/db/fixtures/test/001_repo.rb
+++ b/db/fixtures/test/001_repo.rb
@@ -3,13 +3,13 @@ require 'fileutils'
print "Unpacking seed repository..."
SEED_REPO = 'seed_project.tar.gz'
-REPO_PATH = File.join(Rails.root, 'tmp', 'repositories')
+REPO_PATH = Rails.root.join('tmp', 'repositories')
# Make whatever directories we need to make
FileUtils.mkdir_p(REPO_PATH)
# Copy the archive to the repo path
-FileUtils.cp(File.join(Rails.root, 'spec', SEED_REPO), REPO_PATH)
+FileUtils.cp(Rails.root.join('spec', SEED_REPO), REPO_PATH)
# chdir to the repo path
FileUtils.cd(REPO_PATH) do
diff --git a/features/admin/active_tab.feature b/features/admin/active_tab.feature
new file mode 100644
index 00000000..fce85ce9
--- /dev/null
+++ b/features/admin/active_tab.feature
@@ -0,0 +1,33 @@
+Feature: Admin active tab
+ Background:
+ Given I sign in as an admin
+
+ Scenario: On Admin Home
+ Given I visit admin page
+ Then the active main tab should be Home
+ And no other main tabs should be active
+
+ Scenario: On Admin Projects
+ Given I visit admin projects page
+ Then the active main tab should be Projects
+ And no other main tabs should be active
+
+ Scenario: On Admin Users
+ Given I visit admin users page
+ Then the active main tab should be Users
+ And no other main tabs should be active
+
+ Scenario: On Admin Logs
+ Given I visit admin logs page
+ Then the active main tab should be Logs
+ And no other main tabs should be active
+
+ Scenario: On Admin Hooks
+ Given I visit admin hooks page
+ Then the active main tab should be Hooks
+ And no other main tabs should be active
+
+ Scenario: On Admin Resque
+ Given I visit admin Resque page
+ Then the active main tab should be Resque
+ And no other main tabs should be active
diff --git a/features/dashboard/active_tab.feature b/features/dashboard/active_tab.feature
new file mode 100644
index 00000000..6715ea26
--- /dev/null
+++ b/features/dashboard/active_tab.feature
@@ -0,0 +1,28 @@
+Feature: Dashboard active tab
+ Background:
+ Given I sign in as a user
+
+ Scenario: On Dashboard Home
+ Given I visit dashboard page
+ Then the active main tab should be Home
+ And no other main tabs should be active
+
+ Scenario: On Dashboard Issues
+ Given I visit dashboard issues page
+ Then the active main tab should be Issues
+ And no other main tabs should be active
+
+ Scenario: On Dashboard Merge Requests
+ Given I visit dashboard merge requests page
+ Then the active main tab should be Merge Requests
+ And no other main tabs should be active
+
+ Scenario: On Dashboard Search
+ Given I visit dashboard search page
+ Then the active main tab should be Search
+ And no other main tabs should be active
+
+ Scenario: On Dashboard Help
+ Given I visit dashboard help page
+ Then the active main tab should be Help
+ And no other main tabs should be active
diff --git a/features/profile/active_tab.feature b/features/profile/active_tab.feature
new file mode 100644
index 00000000..475641a3
--- /dev/null
+++ b/features/profile/active_tab.feature
@@ -0,0 +1,28 @@
+Feature: Profile active tab
+ Background:
+ Given I sign in as a user
+
+ Scenario: On Profile Home
+ Given I visit profile page
+ Then the active main tab should be Home
+ And no other main tabs should be active
+
+ Scenario: On Profile Account
+ Given I visit profile account page
+ Then the active main tab should be Account
+ And no other main tabs should be active
+
+ Scenario: On Profile SSH Keys
+ Given I visit profile SSH keys page
+ Then the active main tab should be SSH Keys
+ And no other main tabs should be active
+
+ Scenario: On Profile Design
+ Given I visit profile design page
+ Then the active main tab should be Design
+ And no other main tabs should be active
+
+ Scenario: On Profile History
+ Given I visit profile history page
+ Then the active main tab should be History
+ And no other main tabs should be active
diff --git a/features/project/active_tab.feature b/features/project/active_tab.feature
new file mode 100644
index 00000000..2d3e41d3
--- /dev/null
+++ b/features/project/active_tab.feature
@@ -0,0 +1,147 @@
+Feature: Project active tab
+ Background:
+ Given I sign in as a user
+ And I own a project
+
+ # Main Tabs
+
+ Scenario: On Project Home
+ Given I visit my project's home page
+ Then the active main tab should be Home
+ And no other main tabs should be active
+
+ Scenario: On Project Files
+ Given I visit my project's files page
+ Then the active main tab should be Files
+ And no other main tabs should be active
+
+ Scenario: On Project Commits
+ Given I visit my project's commits page
+ Then the active main tab should be Commits
+ And no other main tabs should be active
+
+ Scenario: On Project Network
+ Given I visit my project's network page
+ Then the active main tab should be Network
+ And no other main tabs should be active
+
+ Scenario: On Project Issues
+ Given I visit my project's issues page
+ Then the active main tab should be Issues
+ And no other main tabs should be active
+
+ Scenario: On Project Merge Requests
+ Given I visit my project's merge requests page
+ Then the active main tab should be Merge Requests
+ And no other main tabs should be active
+
+ Scenario: On Project Wall
+ Given I visit my project's wall page
+ Then the active main tab should be Wall
+ And no other main tabs should be active
+
+ Scenario: On Project Wiki
+ Given I visit my project's wiki page
+ Then the active main tab should be Wiki
+ And no other main tabs should be active
+
+ # Sub Tabs: Home
+
+ Scenario: On Project Home/Show
+ Given I visit my project's home page
+ Then the active sub tab should be Show
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ Scenario: On Project Home/Team
+ Given I visit my project's home page
+ And I click the "Team" tab
+ Then the active sub tab should be Team
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ Scenario: On Project Home/Attachments
+ Given I visit my project's home page
+ And I click the "Attachments" tab
+ Then the active sub tab should be Attachments
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ Scenario: On Project Home/Snippets
+ Given I visit my project's home page
+ And I click the "Snippets" tab
+ Then the active sub tab should be Snippets
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ Scenario: On Project Home/Edit
+ Given I visit my project's home page
+ And I click the "Edit" tab
+ Then the active sub tab should be Edit
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ Scenario: On Project Home/Hooks
+ Given I visit my project's home page
+ And I click the "Hooks" tab
+ Then the active sub tab should be Hooks
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ Scenario: On Project Home/Deploy Keys
+ Given I visit my project's home page
+ And I click the "Deploy Keys" tab
+ Then the active sub tab should be Deploy Keys
+ And no other sub tabs should be active
+ And the active main tab should be Home
+
+ # Sub Tabs: Commits
+
+ Scenario: On Project Commits/Commits
+ Given I visit my project's commits page
+ Then the active sub tab should be Commits
+ And no other sub tabs should be active
+ And the active main tab should be Commits
+
+ Scenario: On Project Commits/Compare
+ Given I visit my project's commits page
+ And I click the "Compare" tab
+ Then the active sub tab should be Compare
+ And no other sub tabs should be active
+ And the active main tab should be Commits
+
+ Scenario: On Project Commits/Branches
+ Given I visit my project's commits page
+ And I click the "Branches" tab
+ Then the active sub tab should be Branches
+ And no other sub tabs should be active
+ And the active main tab should be Commits
+
+ Scenario: On Project Commits/Tags
+ Given I visit my project's commits page
+ And I click the "Tags" tab
+ Then the active sub tab should be Tags
+ And no other sub tabs should be active
+ And the active main tab should be Commits
+
+ # Sub Tabs: Issues
+
+ Scenario: On Project Issues/Browse
+ Given I visit my project's issues page
+ Then the active sub tab should be Browse Issues
+ And no other sub tabs should be active
+ And the active main tab should be Issues
+
+ Scenario: On Project Issues/Milestones
+ Given I visit my project's issues page
+ And I click the "Milestones" tab
+ Then the active sub tab should be Milestones
+ And no other sub tabs should be active
+ And the active main tab should be Issues
+
+ Scenario: On Project Issues/Labels
+ Given I visit my project's issues page
+ And I click the "Labels" tab
+ Then the active sub tab should be Labels
+ And no other sub tabs should be active
+ And the active main tab should be Issues
diff --git a/features/project/commits/commits.feature b/features/project/commits/commits.feature
index 53de6e6a..df795ef7 100644
--- a/features/project/commits/commits.feature
+++ b/features/project/commits/commits.feature
@@ -1,8 +1,8 @@
Feature: Project Browse commits
Background:
Given I sign in as a user
- And I own project "Shop"
- Given I visit project commits page
+ And I own a project
+ And I visit my project's commits page
Scenario: I browse commits list for master branch
Then I see project commits
@@ -18,4 +18,4 @@ Feature: Project Browse commits
Scenario: I compare refs
Given I visit compare refs page
And I fill compare fields with refs
- And I see compared refs
+ Then I see compared refs
diff --git a/features/steps/admin/admin_active_tab.rb b/features/steps/admin/admin_active_tab.rb
new file mode 100644
index 00000000..29290892
--- /dev/null
+++ b/features/steps/admin/admin_active_tab.rb
@@ -0,0 +1,29 @@
+class AdminActiveTab < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedActiveTab
+
+ Then 'the active main tab should be Home' do
+ ensure_active_main_tab('Stats')
+ end
+
+ Then 'the active main tab should be Projects' do
+ ensure_active_main_tab('Projects')
+ end
+
+ Then 'the active main tab should be Users' do
+ ensure_active_main_tab('Users')
+ end
+
+ Then 'the active main tab should be Logs' do
+ ensure_active_main_tab('Logs')
+ end
+
+ Then 'the active main tab should be Hooks' do
+ ensure_active_main_tab('Hooks')
+ end
+
+ Then 'the active main tab should be Resque' do
+ ensure_active_main_tab('Resque')
+ end
+end
diff --git a/features/steps/dashboard/dashboard_active_tab.rb b/features/steps/dashboard/dashboard_active_tab.rb
new file mode 100644
index 00000000..41ecc48c
--- /dev/null
+++ b/features/steps/dashboard/dashboard_active_tab.rb
@@ -0,0 +1,25 @@
+class DashboardActiveTab < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedActiveTab
+
+ Then 'the active main tab should be Home' do
+ ensure_active_main_tab('Home')
+ end
+
+ Then 'the active main tab should be Issues' do
+ ensure_active_main_tab('Issues')
+ end
+
+ Then 'the active main tab should be Merge Requests' do
+ ensure_active_main_tab('Merge Requests')
+ end
+
+ Then 'the active main tab should be Search' do
+ ensure_active_main_tab('Search')
+ end
+
+ Then 'the active main tab should be Help' do
+ ensure_active_main_tab('Help')
+ end
+end
diff --git a/features/steps/profile/profile_active_tab.rb b/features/steps/profile/profile_active_tab.rb
new file mode 100644
index 00000000..1924a6fa
--- /dev/null
+++ b/features/steps/profile/profile_active_tab.rb
@@ -0,0 +1,25 @@
+class ProfileActiveTab < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedActiveTab
+
+ Then 'the active main tab should be Home' do
+ ensure_active_main_tab('Profile')
+ end
+
+ Then 'the active main tab should be Account' do
+ ensure_active_main_tab('Account')
+ end
+
+ Then 'the active main tab should be SSH Keys' do
+ ensure_active_main_tab('SSH Keys')
+ end
+
+ Then 'the active main tab should be Design' do
+ ensure_active_main_tab('Design')
+ end
+
+ Then 'the active main tab should be History' do
+ ensure_active_main_tab('History')
+ end
+end
diff --git a/features/steps/project/project_active_tab.rb b/features/steps/project/project_active_tab.rb
new file mode 100644
index 00000000..a5c80353
--- /dev/null
+++ b/features/steps/project/project_active_tab.rb
@@ -0,0 +1,146 @@
+class ProjectActiveTab < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedProject
+ include SharedActiveTab
+
+ # Main Tabs
+
+ Then 'the active main tab should be Home' do
+ ensure_active_main_tab(@project.name)
+ end
+
+ Then 'the active main tab should be Files' do
+ ensure_active_main_tab('Files')
+ end
+
+ Then 'the active main tab should be Commits' do
+ ensure_active_main_tab('Commits')
+ end
+
+ Then 'the active main tab should be Network' do
+ ensure_active_main_tab('Network')
+ end
+
+ Then 'the active main tab should be Issues' do
+ ensure_active_main_tab('Issues')
+ end
+
+ Then 'the active main tab should be Merge Requests' do
+ ensure_active_main_tab('Merge Requests')
+ end
+
+ Then 'the active main tab should be Wall' do
+ ensure_active_main_tab('Wall')
+ end
+
+ Then 'the active main tab should be Wiki' do
+ ensure_active_main_tab('Wiki')
+ end
+
+ # Sub Tabs: Home
+
+ Given 'I click the "Team" tab' do
+ click_link('Team')
+ end
+
+ Given 'I click the "Attachments" tab' do
+ click_link('Attachments')
+ end
+
+ Given 'I click the "Snippets" tab' do
+ click_link('Snippets')
+ end
+
+ Given 'I click the "Edit" tab' do
+ click_link('Edit')
+ end
+
+ Given 'I click the "Hooks" tab' do
+ click_link('Hooks')
+ end
+
+ Given 'I click the "Deploy Keys" tab' do
+ click_link('Deploy Keys')
+ end
+
+ Then 'the active sub tab should be Show' do
+ ensure_active_sub_tab('Show')
+ end
+
+ Then 'the active sub tab should be Team' do
+ ensure_active_sub_tab('Team')
+ end
+
+ Then 'the active sub tab should be Attachments' do
+ ensure_active_sub_tab('Attachments')
+ end
+
+ Then 'the active sub tab should be Snippets' do
+ ensure_active_sub_tab('Snippets')
+ end
+
+ Then 'the active sub tab should be Edit' do
+ ensure_active_sub_tab('Edit')
+ end
+
+ Then 'the active sub tab should be Hooks' do
+ ensure_active_sub_tab('Hooks')
+ end
+
+ Then 'the active sub tab should be Deploy Keys' do
+ ensure_active_sub_tab('Deploy Keys')
+ end
+
+ # Sub Tabs: Commits
+
+ Given 'I click the "Compare" tab' do
+ click_link('Compare')
+ end
+
+ Given 'I click the "Branches" tab' do
+ click_link('Branches')
+ end
+
+ Given 'I click the "Tags" tab' do
+ click_link('Tags')
+ end
+
+ Then 'the active sub tab should be Commits' do
+ ensure_active_sub_tab('Commits')
+ end
+
+ Then 'the active sub tab should be Compare' do
+ ensure_active_sub_tab('Compare')
+ end
+
+ Then 'the active sub tab should be Branches' do
+ ensure_active_sub_tab('Branches')
+ end
+
+ Then 'the active sub tab should be Tags' do
+ ensure_active_sub_tab('Tags')
+ end
+
+ # Sub Tabs: Issues
+
+ Given 'I click the "Milestones" tab' do
+ click_link('Milestones')
+ end
+
+ Given 'I click the "Labels" tab' do
+ click_link('Labels')
+ end
+
+ Then 'the active sub tab should be Browse Issues' do
+ ensure_active_sub_tab('Browse Issues')
+ end
+
+ Then 'the active sub tab should be Milestones' do
+ ensure_active_sub_tab('Milestones')
+ end
+
+ Then 'the active sub tab should be Labels' do
+ ensure_active_sub_tab('Labels')
+ end
+end
diff --git a/features/steps/project/project_browse_commits.rb b/features/steps/project/project_browse_commits.rb
index 01479987..cb5cabe9 100644
--- a/features/steps/project/project_browse_commits.rb
+++ b/features/steps/project/project_browse_commits.rb
@@ -4,8 +4,6 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
include SharedPaths
Then 'I see project commits' do
- current_path.should == project_commits_path(@project)
-
commit = @project.commit
page.should have_content(@project.name)
page.should have_content(commit.message)
@@ -34,14 +32,14 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
end
And 'I fill compare fields with refs' do
- fill_in "from", :with => "master"
- fill_in "to", :with => "stable"
+ fill_in "from", with: "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
+ fill_in "to", with: "8716fc78f3c65bbf7bcf7b574febd583bc5d2812"
click_button "Compare"
end
- And 'I see compared refs' do
- page.should have_content "Commits (27)"
+ Then 'I see compared refs' do
page.should have_content "Compare View"
- page.should have_content "Showing 73 changed files"
+ page.should have_content "Commits (1)"
+ page.should have_content "Showing 2 changed files"
end
end
diff --git a/features/steps/project/project_browse_files.rb b/features/steps/project/project_browse_files.rb
index 67c553ce..652daba0 100644
--- a/features/steps/project/project_browse_files.rb
+++ b/features/steps/project/project_browse_files.rb
@@ -10,7 +10,7 @@ class ProjectBrowseFiles < Spinach::FeatureSteps
end
Then 'I should see files from repository for "8470d70"' do
- current_path.should == tree_project_ref_path(@project, "8470d70")
+ current_path.should == project_tree_path(@project, "8470d70")
page.should have_content "app"
page.should have_content "History"
page.should have_content "Gemfile"
diff --git a/features/steps/shared/active_tab.rb b/features/steps/shared/active_tab.rb
new file mode 100644
index 00000000..884f2d5f
--- /dev/null
+++ b/features/steps/shared/active_tab.rb
@@ -0,0 +1,19 @@
+module SharedActiveTab
+ include Spinach::DSL
+
+ def ensure_active_main_tab(content)
+ page.find('ul.main_menu li.active').should have_content(content)
+ end
+
+ def ensure_active_sub_tab(content)
+ page.find('div.content ul.nav-tabs li.active').should have_content(content)
+ end
+
+ And 'no other main tabs should be active' do
+ page.should have_selector('ul.main_menu li.active', count: 1)
+ end
+
+ And 'no other sub tabs should be active' do
+ page.should have_selector('div.content ul.nav-tabs li.active', count: 1)
+ end
+end
diff --git a/features/steps/shared/authentication.rb b/features/steps/shared/authentication.rb
index 77d9839f..2add9161 100644
--- a/features/steps/shared/authentication.rb
+++ b/features/steps/shared/authentication.rb
@@ -7,4 +7,8 @@ module SharedAuthentication
Given 'I sign in as a user' do
login_as :user
end
+
+ Given 'I sign in as an admin' do
+ login_as :admin
+ end
end
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index 93ad0219..8efedfa1 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -1,22 +1,38 @@
module SharedPaths
include Spinach::DSL
- And 'I visit dashboard search page' do
- visit search_path
+ When 'I visit new project page' do
+ visit new_project_path
end
- And 'I visit dashboard merge requests page' do
- visit dashboard_merge_requests_path
+ # ----------------------------------------
+ # Dashboard
+ # ----------------------------------------
+
+ Given 'I visit dashboard page' do
+ visit dashboard_path
end
- And 'I visit dashboard issues page' do
+ Given 'I visit dashboard issues page' do
visit dashboard_issues_path
end
- When 'I visit dashboard page' do
- visit dashboard_path
+ Given 'I visit dashboard merge requests page' do
+ visit dashboard_merge_requests_path
end
+ Given 'I visit dashboard search page' do
+ visit search_path
+ end
+
+ Given 'I visit dashboard help page' do
+ visit help_path
+ end
+
+ # ----------------------------------------
+ # Profile
+ # ----------------------------------------
+
Given 'I visit profile page' do
visit profile_path
end
@@ -25,14 +41,94 @@ module SharedPaths
visit profile_account_path
end
+ Given 'I visit profile SSH keys page' do
+ visit keys_path
+ end
+
+ Given 'I visit profile design page' do
+ visit profile_design_path
+ end
+
+ Given 'I visit profile history page' do
+ visit profile_history_path
+ end
+
Given 'I visit profile token page' do
visit profile_token_path
end
- When 'I visit new project page' do
- visit new_project_path
+ # ----------------------------------------
+ # Admin
+ # ----------------------------------------
+
+ Given 'I visit admin page' do
+ visit admin_root_path
end
+ Given 'I visit admin projects page' do
+ visit admin_projects_path
+ end
+
+ Given 'I visit admin users page' do
+ visit admin_users_path
+ end
+
+ Given 'I visit admin logs page' do
+ visit admin_logs_path
+ end
+
+ Given 'I visit admin hooks page' do
+ visit admin_hooks_path
+ end
+
+ Given 'I visit admin Resque page' do
+ visit admin_resque_path
+ end
+
+ # ----------------------------------------
+ # Generic Project
+ # ----------------------------------------
+
+ Given "I visit my project's home page" do
+ visit project_path(@project)
+ end
+
+ Given "I visit my project's files page" do
+ visit project_tree_path(@project, @project.root_ref)
+ end
+
+ Given "I visit my project's commits page" do
+ visit project_commits_path(@project, @project.root_ref, {limit: 5})
+ end
+
+ Given "I visit my project's network page" do
+ # Stub out find_all to speed this up (10 commits vs. 650)
+ commits = Grit::Commit.find_all(@project.repo, nil, {max_count: 10})
+ Grit::Commit.stub(:find_all).and_return(commits)
+
+ visit graph_project_path(@project)
+ end
+
+ Given "I visit my project's issues page" do
+ visit project_issues_path(@project)
+ end
+
+ Given "I visit my project's merge requests page" do
+ visit project_merge_requests_path(@project)
+ end
+
+ Given "I visit my project's wall page" do
+ visit wall_project_path(@project)
+ end
+
+ Given "I visit my project's wiki page" do
+ visit project_wiki_path(@project, :index)
+ end
+
+ # ----------------------------------------
+ # "Shop" Project
+ # ----------------------------------------
+
And 'I visit project "Shop" page' do
project = Project.find_by_name("Shop")
visit project_path(project)
@@ -43,23 +139,27 @@ module SharedPaths
end
Given 'I visit compare refs page' do
- visit compare_project_commits_path(@project)
+ visit project_compare_index_path(@project)
end
Given 'I visit project commits page' do
- visit project_commits_path(@project)
+ visit project_commits_path(@project, @project.root_ref, {limit: 5})
+ end
+
+ Given 'I visit project commits page for stable branch' do
+ visit project_commits_path(@project, 'stable', {limit: 5})
end
Given 'I visit project source page' do
- visit tree_project_ref_path(@project, @project.root_ref)
+ visit project_tree_path(@project, @project.root_ref)
end
Given 'I visit blob file from repo' do
- visit tree_project_ref_path(@project, ValidCommit::ID, :path => ValidCommit::BLOB_FILE_PATH)
+ visit project_tree_path(@project, File.join(ValidCommit::ID, ValidCommit::BLOB_FILE_PATH))
end
Given 'I visit project source page for "8470d70"' do
- visit tree_project_ref_path(@project, "8470d70")
+ visit project_tree_path(@project, "8470d70")
end
Given 'I visit project tags page' do
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index 9b64ca59..0f93d675 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -1,6 +1,13 @@
module SharedProject
include Spinach::DSL
+ # Create a project without caring about what it's called
+ And "I own a project" do
+ @project = create(:project)
+ @project.add_access(@user, :admin)
+ end
+
+ # Create a specific project called "Shop"
And 'I own project "Shop"' do
@project = Factory :project, :name => "Shop"
@project.add_access(@user, :admin)
diff --git a/features/support/env.rb b/features/support/env.rb
index 9c6cef07..6d49c25a 100644
--- a/features/support/env.rb
+++ b/features/support/env.rb
@@ -23,5 +23,7 @@ Spinach.hooks.after_scenario { DatabaseCleaner.clean }
Spinach.hooks.before_run do
RSpec::Mocks::setup self
+ include FactoryGirl::Syntax::Methods
+
stub_gitolite!
end
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
new file mode 100644
index 00000000..f36dae52
--- /dev/null
+++ b/lib/extracts_path.rb
@@ -0,0 +1,114 @@
+# Module providing methods for dealing with separating a tree-ish string and a
+# file path string when combined in a request parameter
+module ExtractsPath
+ extend ActiveSupport::Concern
+
+ # Raised when given an invalid file path
+ class InvalidPathError < StandardError; end
+
+ included do
+ if respond_to?(:before_filter)
+ before_filter :assign_ref_vars, only: [:show]
+ end
+ end
+
+ # Given a string containing both a Git tree-ish, such as a branch or tag, and
+ # a filesystem path joined by forward slashes, attempts to separate the two.
+ #
+ # Expects a @project instance variable to contain the active project. This is
+ # used to check the input against a list of valid repository refs.
+ #
+ # Examples
+ #
+ # # No @project available
+ # extract_ref('master')
+ # # => ['', '']
+ #
+ # extract_ref('master')
+ # # => ['master', '']
+ #
+ # extract_ref("f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG")
+ # # => ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
+ #
+ # extract_ref("v2.0.0/README.md")
+ # # => ['v2.0.0', 'README.md']
+ #
+ # extract_ref('issues/1234/app/models/project.rb')
+ # # => ['issues/1234', 'app/models/project.rb']
+ #
+ # # Given an invalid branch, we fall back to just splitting on the first slash
+ # extract_ref('non/existent/branch/README.md')
+ # # => ['non', 'existent/branch/README.md']
+ #
+ # Returns an Array where the first value is the tree-ish and the second is the
+ # path
+ def extract_ref(input)
+ pair = ['', '']
+
+ return pair unless @project
+
+ if input.match(/^([[:alnum:]]{40})(.+)/)
+ # If the ref appears to be a SHA, we're done, just split the string
+ pair = $~.captures
+ else
+ # Otherwise, attempt to detect the ref using a list of the project's
+ # branches and tags
+
+ # Append a trailing slash if we only get a ref and no file path
+ id = input
+ id += '/' unless id.include?('/')
+
+ valid_refs = @project.branches + @project.tags
+ valid_refs.select! { |v| id.start_with?("#{v}/") }
+
+ if valid_refs.length != 1
+ # No exact ref match, so just try our best
+ pair = id.match(/([^\/]+)(.*)/).captures
+ else
+ # Partition the string into the ref and the path, ignoring the empty first value
+ pair = id.partition(valid_refs.first)[1..-1]
+ end
+ end
+
+ # Remove leading slash from path
+ pair[1].gsub!(/^\//, '')
+
+ pair
+ end
+
+ # Assigns common instance variables for views working with Git tree-ish objects
+ #
+ # Assignments are:
+ #
+ # - @id - A string representing the joined ref and path
+ # - @ref - A string representing the ref (e.g., the branch, tag, or commit SHA)
+ # - @path - A string representing the filesystem path
+ # - @commit - A CommitDecorator representing the commit from the given ref
+ # - @tree - A TreeDecorator representing the tree at the given ref/path
+ #
+ # If the :id parameter appears to be requesting a specific response format,
+ # that will be handled as well.
+ #
+ # Automatically renders `not_found!` if a valid tree path could not be
+ # resolved (e.g., when a user inserts an invalid path or ref).
+ def assign_ref_vars
+ # Handle formats embedded in the id
+ if params[:id].ends_with?('.atom')
+ params[:id].gsub!(/\.atom$/, '')
+ request.format = :atom
+ end
+
+ @ref, @path = extract_ref(params[:id])
+
+ @id = File.join(@ref, @path)
+
+ @commit = CommitDecorator.decorate(@project.commit(@ref))
+
+ @tree = Tree.new(@commit.tree, @project, @ref, @path)
+ @tree = TreeDecorator.new(@tree)
+
+ raise InvalidPathError if @tree.invalid?
+ rescue NoMethodError, InvalidPathError
+ not_found!
+ end
+end
diff --git a/lib/gitlab/backend/gitolite_config.rb b/lib/gitlab/backend/gitolite_config.rb
index f51e8efc..ffe15fb1 100644
--- a/lib/gitlab/backend/gitolite_config.rb
+++ b/lib/gitlab/backend/gitolite_config.rb
@@ -10,7 +10,7 @@ module Gitlab
attr_reader :config_tmp_dir, :ga_repo, :conf
def config_tmp_dir
- @config_tmp_dir ||= File.join(Rails.root, 'tmp',"gitlabhq-gitolite-#{Time.now.to_i}")
+ @config_tmp_dir ||= Rails.root.join('tmp',"gitlabhq-gitolite-#{Time.now.to_i}")
end
def ga_repo
@@ -19,7 +19,7 @@ module Gitlab
def apply
Timeout::timeout(30) do
- File.open(File.join(Rails.root, 'tmp', "gitlabhq-gitolite.lock"), "w+") do |f|
+ File.open(Rails.root.join('tmp', "gitlabhq-gitolite.lock"), "w+") do |f|
begin
# Set exclusive lock
# to prevent race condition
diff --git a/lib/gitlab/logger.rb b/lib/gitlab/logger.rb
index 9405163d..cf9a4c4a 100644
--- a/lib/gitlab/logger.rb
+++ b/lib/gitlab/logger.rb
@@ -15,7 +15,7 @@ module Gitlab
end
def self.build
- new(File.join(Rails.root, "log", file_name))
+ new(Rails.root.join("log", file_name))
end
end
end
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index 9201003e..9eb35b84 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -174,7 +174,7 @@ module Gitlab
def reference_commit(identifier)
if commit = @project.commit(identifier)
- link_to(identifier, project_commit_path(@project, id: commit.id), html_options.merge(title: CommitDecorator.new(commit).link_title, class: "gfm gfm-commit #{html_options[:class]}"))
+ link_to(identifier, project_commit_path(@project, commit), html_options.merge(title: CommitDecorator.new(commit).link_title, class: "gfm gfm-commit #{html_options[:class]}"))
end
end
end
diff --git a/lib/gitlab/merge.rb b/lib/gitlab/merge.rb
index 18013574..de8e737a 100644
--- a/lib/gitlab/merge.rb
+++ b/lib/gitlab/merge.rb
@@ -28,7 +28,7 @@ module Gitlab
def process
Grit::Git.with_timeout(30.seconds) do
- lock_file = File.join(Rails.root, "tmp", "merge_repo_#{project.path}.lock")
+ lock_file = Rails.root.join("tmp", "merge_repo_#{project.path}.lock")
File.open(lock_file, "w+") do |f|
f.flock(File::LOCK_EX)
@@ -36,7 +36,7 @@ module Gitlab
unless project.satellite.exists?
raise "You should run: rake gitlab:app:enable_automerge"
end
-
+
project.satellite.clear
Dir.chdir(project.satellite.path) do
diff --git a/lib/gitlab/satellite.rb b/lib/gitlab/satellite.rb
index 4bcbfe8d..9d8dfb8e 100644
--- a/lib/gitlab/satellite.rb
+++ b/lib/gitlab/satellite.rb
@@ -1,6 +1,6 @@
module Gitlab
class Satellite
-
+
PARKING_BRANCH = "__parking_branch"
attr_accessor :project
@@ -14,7 +14,7 @@ module Gitlab
end
def path
- File.join(Rails.root, "tmp", "repo_satellites", project.path)
+ Rails.root.join("tmp", "repo_satellites", project.path)
end
def exists?
@@ -36,6 +36,6 @@ module Gitlab
end
end
end
-
+
end
end
diff --git a/spec/controllers/commits_controller_spec.rb b/spec/controllers/commits_controller_spec.rb
new file mode 100644
index 00000000..bf335634
--- /dev/null
+++ b/spec/controllers/commits_controller_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe CommitsController do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ project.add_access(user, :read, :admin)
+ end
+
+ describe "GET show" do
+ context "as atom feed" do
+ it "should render as atom" do
+ get :show, project_id: project.code, id: "master.atom"
+ response.should be_success
+ response.content_type.should == 'application/atom+xml'
+ end
+ end
+ end
+end
diff --git a/spec/controllers/tree_controller_spec.rb b/spec/controllers/tree_controller_spec.rb
new file mode 100644
index 00000000..b9295537
--- /dev/null
+++ b/spec/controllers/tree_controller_spec.rb
@@ -0,0 +1,43 @@
+require 'spec_helper'
+
+describe TreeController do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+
+ project.add_access(user, :read, :admin)
+
+ project.stub(:branches).and_return(['master', 'foo/bar/baz'])
+ project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
+ controller.instance_variable_set(:@project, project)
+ end
+
+ describe "GET show" do
+ # Make sure any errors accessing the tree in our views bubble up to this spec
+ render_views
+
+ before { get :show, project_id: project.code, id: id }
+
+ context "valid branch, no path" do
+ let(:id) { 'master' }
+ it { should respond_with(:success) }
+ end
+
+ context "valid branch, valid path" do
+ let(:id) { 'master/README.md' }
+ it { should respond_with(:success) }
+ end
+
+ context "valid branch, invalid path" do
+ let(:id) { 'master/invalid-path.rb' }
+ it { should respond_with(:not_found) }
+ end
+
+ context "invalid branch, valid path" do
+ let(:id) { 'invalid-branch/README.md' }
+ it { should respond_with(:not_found) }
+ end
+ end
+end
diff --git a/spec/factories.rb b/spec/factories.rb
index 92790a3f..e11e6d07 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -42,8 +42,8 @@ FactoryGirl.define do
factory :project do
sequence(:name) { |n| "project#{n}" }
- path { name }
- code { name }
+ path { name.downcase.gsub(/\s/, '_') }
+ code { name.downcase.gsub(/\s/, '_') }
owner
end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 9a2df314..a94d5505 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -1,6 +1,44 @@
require 'spec_helper'
describe ApplicationHelper do
+ describe 'current_controller?' do
+ before do
+ controller.stub!(:controller_name).and_return('foo')
+ end
+
+ it "returns true when controller matches argument" do
+ current_controller?(:foo).should be_true
+ end
+
+ it "returns false when controller does not match argument" do
+ current_controller?(:bar).should_not be_true
+ end
+
+ it "should take any number of arguments" do
+ current_controller?(:baz, :bar).should_not be_true
+ current_controller?(:baz, :bar, :foo).should be_true
+ end
+ end
+
+ describe 'current_action?' do
+ before do
+ stub!(:action_name).and_return('foo')
+ end
+
+ it "returns true when action matches argument" do
+ current_action?(:foo).should be_true
+ end
+
+ it "returns false when action does not match argument" do
+ current_action?(:bar).should_not be_true
+ end
+
+ it "should take any number of arguments" do
+ current_action?(:baz, :bar).should_not be_true
+ current_action?(:baz, :bar, :foo).should be_true
+ end
+ end
+
describe "gravatar_icon" do
let(:user_email) { 'user@email.com' }
diff --git a/spec/helpers/tab_helper_spec.rb b/spec/helpers/tab_helper_spec.rb
new file mode 100644
index 00000000..ef8e4cf6
--- /dev/null
+++ b/spec/helpers/tab_helper_spec.rb
@@ -0,0 +1,44 @@
+require 'spec_helper'
+
+describe TabHelper do
+ include ApplicationHelper
+
+ describe 'nav_link' do
+ before do
+ controller.stub!(:controller_name).and_return('foo')
+ stub!(:action_name).and_return('foo')
+ end
+
+ it "captures block output" do
+ nav_link { "Testing Blocks" }.should match(/Testing Blocks/)
+ end
+
+ it "performs checks on the current controller" do
+ nav_link(controller: :foo).should match(//)
+ nav_link(controller: :bar).should_not match(/active/)
+ nav_link(controller: [:foo, :bar]).should match(/active/)
+ end
+
+ it "performs checks on the current action" do
+ nav_link(action: :foo).should match(//)
+ nav_link(action: :bar).should_not match(/active/)
+ nav_link(action: [:foo, :bar]).should match(/active/)
+ end
+
+ it "performs checks on both controller and action when both are present" do
+ nav_link(controller: :bar, action: :foo).should_not match(/active/)
+ nav_link(controller: :foo, action: :bar).should_not match(/active/)
+ nav_link(controller: :foo, action: :foo).should match(/active/)
+ end
+
+ it "accepts a path shorthand" do
+ nav_link(path: 'foo#bar').should_not match(/active/)
+ nav_link(path: 'foo#foo').should match(/active/)
+ end
+
+ it "passes extra html options to the list element" do
+ nav_link(action: :foo, html_options: {class: 'home'}).should match(//)
+ nav_link(html_options: {class: 'active'}).should match(//)
+ end
+ end
+end
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
new file mode 100644
index 00000000..8876373d
--- /dev/null
+++ b/spec/lib/extracts_path_spec.rb
@@ -0,0 +1,58 @@
+require 'spec_helper'
+
+describe ExtractsPath do
+ include ExtractsPath
+
+ let(:project) { double('project') }
+
+ before do
+ @project = project
+ project.stub(:branches).and_return(['master', 'foo/bar/baz'])
+ project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
+ end
+
+ describe '#extract_ref' do
+ it "returns an empty pair when no @project is set" do
+ @project = nil
+ extract_ref('master/CHANGELOG').should == ['', '']
+ end
+
+ context "without a path" do
+ it "extracts a valid branch" do
+ extract_ref('master').should == ['master', '']
+ end
+
+ it "extracts a valid tag" do
+ extract_ref('v2.0.0').should == ['v2.0.0', '']
+ end
+
+ it "extracts a valid commit ref without a path" do
+ extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062').should ==
+ ['f4b14494ef6abf3d144c28e4af0c20143383e062', '']
+ end
+
+ it "falls back to a primitive split for an invalid ref" do
+ extract_ref('stable').should == ['stable', '']
+ end
+ end
+
+ context "with a path" do
+ it "extracts a valid branch" do
+ extract_ref('foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', 'CHANGELOG']
+ end
+
+ it "extracts a valid tag" do
+ extract_ref('v2.0.0/CHANGELOG').should == ['v2.0.0', 'CHANGELOG']
+ end
+
+ it "extracts a valid commit SHA" do
+ extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should ==
+ ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
+ end
+
+ it "falls back to a primitive split for an invalid ref" do
+ extract_ref('stable/CHANGELOG').should == ['stable', 'CHANGELOG']
+ end
+ end
+ end
+end
diff --git a/spec/lib/ref_extractor_spec.rb b/spec/lib/ref_extractor_spec.rb
new file mode 100644
index 00000000..8876373d
--- /dev/null
+++ b/spec/lib/ref_extractor_spec.rb
@@ -0,0 +1,58 @@
+require 'spec_helper'
+
+describe ExtractsPath do
+ include ExtractsPath
+
+ let(:project) { double('project') }
+
+ before do
+ @project = project
+ project.stub(:branches).and_return(['master', 'foo/bar/baz'])
+ project.stub(:tags).and_return(['v1.0.0', 'v2.0.0'])
+ end
+
+ describe '#extract_ref' do
+ it "returns an empty pair when no @project is set" do
+ @project = nil
+ extract_ref('master/CHANGELOG').should == ['', '']
+ end
+
+ context "without a path" do
+ it "extracts a valid branch" do
+ extract_ref('master').should == ['master', '']
+ end
+
+ it "extracts a valid tag" do
+ extract_ref('v2.0.0').should == ['v2.0.0', '']
+ end
+
+ it "extracts a valid commit ref without a path" do
+ extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062').should ==
+ ['f4b14494ef6abf3d144c28e4af0c20143383e062', '']
+ end
+
+ it "falls back to a primitive split for an invalid ref" do
+ extract_ref('stable').should == ['stable', '']
+ end
+ end
+
+ context "with a path" do
+ it "extracts a valid branch" do
+ extract_ref('foo/bar/baz/CHANGELOG').should == ['foo/bar/baz', 'CHANGELOG']
+ end
+
+ it "extracts a valid tag" do
+ extract_ref('v2.0.0/CHANGELOG').should == ['v2.0.0', 'CHANGELOG']
+ end
+
+ it "extracts a valid commit SHA" do
+ extract_ref('f4b14494ef6abf3d144c28e4af0c20143383e062/CHANGELOG').should ==
+ ['f4b14494ef6abf3d144c28e4af0c20143383e062', 'CHANGELOG']
+ end
+
+ it "falls back to a primitive split for an invalid ref" do
+ extract_ref('stable/CHANGELOG').should == ['stable', 'CHANGELOG']
+ end
+ end
+ end
+end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index c313b58e..bb975a93 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -125,7 +125,7 @@ describe Project do
it "should return path to repo" do
project = Project.new(path: "somewhere")
- project.path_to_repo.should == File.join(Rails.root, "tmp", "repositories", "somewhere")
+ project.path_to_repo.should == Rails.root.join("tmp", "repositories", "somewhere")
end
it "returns the full web URL for this repo" do
diff --git a/spec/requests/atom/dashboard_spec.rb b/spec/requests/atom/dashboard_spec.rb
index 9459dd01..c160d24a 100644
--- a/spec/requests/atom/dashboard_spec.rb
+++ b/spec/requests/atom/dashboard_spec.rb
@@ -10,12 +10,5 @@ describe "Dashboard Feed" do
page.body.should have_selector("feed title")
end
end
-
- context "projects page via private token" do
- it "should redirect to login page" do
- visit dashboard_path(private_token: user.private_token)
- current_path.should == new_user_session_path
- end
- end
end
end
diff --git a/spec/requests/gitlab_flavored_markdown_spec.rb b/spec/requests/gitlab_flavored_markdown_spec.rb
index 68d354b7..106f6451 100644
--- a/spec/requests/gitlab_flavored_markdown_spec.rb
+++ b/spec/requests/gitlab_flavored_markdown_spec.rb
@@ -40,28 +40,27 @@ describe "Gitlab Flavored Markdown" do
project.add_access(@user, :read, :write)
end
-
describe "for commits" do
it "should render title in commits#index" do
- visit project_commits_path(project, ref: @branch_name)
+ visit project_commits_path(project, @branch_name, limit: 1)
page.should have_link("##{issue.id}")
end
it "should render title in commits#show" do
- visit project_commit_path(project, id: commit.id)
+ visit project_commit_path(project, commit)
page.should have_link("##{issue.id}")
end
it "should render description in commits#show" do
- visit project_commit_path(project, id: commit.id)
+ visit project_commit_path(project, commit)
page.should have_link("@#{fred.name}")
end
it "should render title in refs#tree", js: true do
- visit tree_project_ref_path(project, id: @branch_name)
+ visit project_tree_path(project, @branch_name)
within(".tree_commit") do
page.should have_link("##{issue.id}")
@@ -69,7 +68,7 @@ describe "Gitlab Flavored Markdown" do
end
it "should render title in refs#blame" do
- visit blame_file_project_ref_path(project, id: @branch_name, path: @test_file)
+ visit project_blame_path(project, File.join(@branch_name, @test_file))
within(".blame_commit") do
page.should have_link("##{issue.id}")
@@ -89,7 +88,6 @@ describe "Gitlab Flavored Markdown" do
end
end
-
describe "for issues" do
before do
@other_issue = Factory :issue,
@@ -175,7 +173,7 @@ describe "Gitlab Flavored Markdown" do
describe "for notes" do
it "should render in commits#show", js: true do
- visit project_commit_path(project, id: commit.id)
+ visit project_commit_path(project, commit)
fill_in "note_note", with: "see ##{issue.id}"
click_button "Add Comment"
diff --git a/spec/requests/security/project_access_spec.rb b/spec/requests/security/project_access_spec.rb
index af0d5fcd..060a276b 100644
--- a/spec/requests/security/project_access_spec.rb
+++ b/spec/requests/security/project_access_spec.rb
@@ -14,204 +14,228 @@ describe "Application access" do
end
describe "Project" do
+ let(:project) { create(:project) }
+
+ let(:master) { create(:user) }
+ let(:guest) { create(:user) }
+ let(:reporter) { create(:user) }
+
before do
- @project = Factory :project
- @u1 = Factory :user
- @u2 = Factory :user
- @u3 = Factory :user
# full access
- @project.users_projects.create(user: @u1, project_access: UsersProject::MASTER)
+ project.users_projects.create(user: master, project_access: UsersProject::MASTER)
+
# readonly
- @project.users_projects.create(user: @u3, project_access: UsersProject::REPORTER)
+ project.users_projects.create(user: reporter, project_access: UsersProject::REPORTER)
end
describe "GET /project_code" do
- subject { project_path(@project) }
+ subject { project_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
- describe "GET /project_code/master/tree" do
- subject { tree_project_ref_path(@project, @project.root_ref) }
+ describe "GET /project_code/tree/master" do
+ subject { project_tree_path(project, project.root_ref) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
- describe "GET /project_code/commits" do
- subject { project_commits_path(@project) }
+ describe "GET /project_code/commits/master" do
+ subject { project_commits_path(project, project.root_ref, limit: 1) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
- describe "GET /project_code/commit" do
- subject { project_commit_path(@project, @project.commit.id) }
+ describe "GET /project_code/commit/:sha" do
+ subject { project_commit_path(project, project.commit) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
+ it { should be_denied_for :user }
+ it { should be_denied_for :visitor }
+ end
+
+ describe "GET /project_code/compare" do
+ subject { project_compare_index_path(project) }
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
+ it { should be_denied_for :admin }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/team" do
- subject { project_team_index_path(@project) }
+ subject { project_team_index_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/wall" do
- subject { wall_project_path(@project) }
+ subject { wall_project_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/blob" do
before do
- commit = @project.commit
+ commit = project.commit
path = commit.tree.contents.select { |i| i.is_a?(Grit::Blob)}.first.name
- @blob_path = blob_project_ref_path(@project, commit.id, path: path)
+ @blob_path = project_blob_path(project, File.join(commit.id, path))
end
- it { @blob_path.should be_allowed_for @u1 }
- it { @blob_path.should be_allowed_for @u3 }
+ it { @blob_path.should be_allowed_for master }
+ it { @blob_path.should be_allowed_for reporter }
it { @blob_path.should be_denied_for :admin }
- it { @blob_path.should be_denied_for @u2 }
+ it { @blob_path.should be_denied_for guest }
it { @blob_path.should be_denied_for :user }
it { @blob_path.should be_denied_for :visitor }
end
describe "GET /project_code/edit" do
- subject { edit_project_path(@project) }
+ subject { edit_project_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_denied_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/deploy_keys" do
- subject { project_deploy_keys_path(@project) }
+ subject { project_deploy_keys_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_denied_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_denied_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/issues" do
- subject { project_issues_path(@project) }
+ subject { project_issues_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/snippets" do
- subject { project_snippets_path(@project) }
+ subject { project_snippets_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/merge_requests" do
- subject { project_merge_requests_path(@project) }
+ subject { project_merge_requests_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/repository" do
- subject { project_repository_path(@project) }
+ subject { project_repository_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/repository/branches" do
- subject { branches_project_repository_path(@project) }
+ subject { branches_project_repository_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ before do
+ # Speed increase
+ Project.any_instance.stub(:branches).and_return([])
+ end
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/repository/tags" do
- subject { tags_project_repository_path(@project) }
+ subject { tags_project_repository_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ before do
+ # Speed increase
+ Project.any_instance.stub(:tags).and_return([])
+ end
+
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/hooks" do
- subject { project_hooks_path(@project) }
+ subject { project_hooks_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
describe "GET /project_code/files" do
- subject { files_project_path(@project) }
+ subject { files_project_path(project) }
- it { should be_allowed_for @u1 }
- it { should be_allowed_for @u3 }
+ it { should be_allowed_for master }
+ it { should be_allowed_for reporter }
it { should be_denied_for :admin }
- it { should be_denied_for @u2 }
+ it { should be_denied_for guest }
it { should be_denied_for :user }
it { should be_denied_for :visitor }
end
diff --git a/spec/roles/repository_spec.rb b/spec/roles/repository_spec.rb
index 0fda57a3..3507585a 100644
--- a/spec/roles/repository_spec.rb
+++ b/spec/roles/repository_spec.rb
@@ -21,27 +21,27 @@ describe Project, "Repository" do
end
describe "#discover_default_branch" do
- let(:master) { double(name: 'master') }
- let(:stable) { double(name: 'stable') }
+ let(:master) { 'master' }
+ let(:stable) { 'stable' }
it "returns 'master' when master exists" do
- project.should_receive(:heads).and_return([stable, master])
+ project.should_receive(:branch_names).at_least(:once).and_return([stable, master])
project.discover_default_branch.should == 'master'
end
it "returns non-master when master exists but default branch is set to something else" do
project.default_branch = 'stable'
- project.should_receive(:heads).and_return([stable, master])
+ project.should_receive(:branch_names).at_least(:once).and_return([stable, master])
project.discover_default_branch.should == 'stable'
end
it "returns a non-master branch when only one exists" do
- project.should_receive(:heads).and_return([stable])
+ project.should_receive(:branch_names).at_least(:once).and_return([stable])
project.discover_default_branch.should == 'stable'
end
it "returns nil when no branch exists" do
- project.should_receive(:heads).and_return([])
+ project.should_receive(:branch_names).at_least(:once).and_return([])
project.discover_default_branch.should be_nil
end
end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index b3f9db01..dc687d2a 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -192,34 +192,17 @@ describe ProtectedBranchesController, "routing" do
end
# switch_project_refs GET /:project_id/switch(.:format) refs#switch
-# tree_project_ref GET /:project_id/:id/tree(.:format) refs#tree
# logs_tree_project_ref GET /:project_id/:id/logs_tree(.:format) refs#logs_tree
-# blob_project_ref GET /:project_id/:id/blob(.:format) refs#blob
-# tree_file_project_ref GET /:project_id/:id/tree/:path(.:format) refs#tree
# logs_file_project_ref GET /:project_id/:id/logs_tree/:path(.:format) refs#logs_tree
-# blame_file_project_ref GET /:project_id/:id/blame/:path(.:format) refs#blame
describe RefsController, "routing" do
it "to #switch" do
get("/gitlabhq/switch").should route_to('refs#switch', project_id: 'gitlabhq')
end
- it "to #tree" do
- get("/gitlabhq/stable/tree").should route_to('refs#tree', project_id: 'gitlabhq', id: 'stable')
- get("/gitlabhq/stable/tree/foo/bar/baz").should route_to('refs#tree', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz')
- end
-
it "to #logs_tree" do
get("/gitlabhq/stable/logs_tree").should route_to('refs#logs_tree', project_id: 'gitlabhq', id: 'stable')
get("/gitlabhq/stable/logs_tree/foo/bar/baz").should route_to('refs#logs_tree', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz')
end
-
- it "to #blob" do
- get("/gitlabhq/stable/blob").should route_to('refs#blob', project_id: 'gitlabhq', id: 'stable')
- end
-
- it "to #blame" do
- get("/gitlabhq/stable/blame/foo/bar/baz").should route_to('refs#blame', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz')
- end
end
# diffs_project_merge_request GET /:project_id/merge_requests/:id/diffs(.:format) merge_requests#diffs
@@ -298,25 +281,22 @@ describe HooksController, "routing" do
end
end
-# compare_project_commits GET /:project_id/commits/compare(.:format) commits#compare
+# project_commit GET /:project_id/commit/:id(.:format) commit#show {:id=>/[[:alnum:]]{6,40}/, :project_id=>/[^\/]+/}
+describe CommitController, "routing" do
+ it "to #show" do
+ get("/gitlabhq/commit/4246fb").should route_to('commit#show', project_id: 'gitlabhq', id: '4246fb')
+ get("/gitlabhq/commit/4246fb.patch").should route_to('commit#show', project_id: 'gitlabhq', id: '4246fb', format: 'patch')
+ get("/gitlabhq/commit/4246fbd13872934f72a8fd0d6fb1317b47b59cb5").should route_to('commit#show', project_id: 'gitlabhq', id: '4246fbd13872934f72a8fd0d6fb1317b47b59cb5')
+ end
+end
+
# patch_project_commit GET /:project_id/commits/:id/patch(.:format) commits#patch
# project_commits GET /:project_id/commits(.:format) commits#index
# POST /:project_id/commits(.:format) commits#create
-# new_project_commit GET /:project_id/commits/new(.:format) commits#new
-# edit_project_commit GET /:project_id/commits/:id/edit(.:format) commits#edit
# project_commit GET /:project_id/commits/:id(.:format) commits#show
-# PUT /:project_id/commits/:id(.:format) commits#update
-# DELETE /:project_id/commits/:id(.:format) commits#destroy
describe CommitsController, "routing" do
- it "to #compare" do
- get("/gitlabhq/commits/compare").should route_to('commits#compare', project_id: 'gitlabhq')
- end
-
- it "to #patch" do
- get("/gitlabhq/commits/1/patch").should route_to('commits#patch', project_id: 'gitlabhq', id: '1')
- end
-
it_behaves_like "RESTful project resources" do
+ let(:actions) { [:show] }
let(:controller) { 'commits' }
end
end
@@ -396,3 +376,42 @@ describe NotesController, "routing" do
let(:controller) { 'notes' }
end
end
+
+# project_blame GET /:project_id/blame/:id(.:format) blame#show {:id=>/.+/, :project_id=>/[^\/]+/}
+describe BlameController, "routing" do
+ it "to #show" do
+ get("/gitlabhq/blame/master/app/models/project.rb").should route_to('blame#show', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
+ end
+end
+
+# project_blob GET /:project_id/blob/:id(.:format) blob#show {:id=>/.+/, :project_id=>/[^\/]+/}
+describe BlobController, "routing" do
+ it "to #show" do
+ get("/gitlabhq/blob/master/app/models/project.rb").should route_to('blob#show', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
+ end
+end
+
+# project_tree GET /:project_id/tree/:id(.:format) tree#show {:id=>/.+/, :project_id=>/[^\/]+/}
+describe TreeController, "routing" do
+ it "to #show" do
+ get("/gitlabhq/tree/master/app/models/project.rb").should route_to('tree#show', project_id: 'gitlabhq', id: 'master/app/models/project.rb')
+ end
+end
+
+# project_compare_index GET /:project_id/compare(.:format) compare#index {:id=>/[^\/]+/, :project_id=>/[^\/]+/}
+# POST /:project_id/compare(.:format) compare#create {:id=>/[^\/]+/, :project_id=>/[^\/]+/}
+# project_compare /:project_id/compare/:from...:to(.:format) compare#show {:from=>/.+/, :to=>/.+/, :id=>/[^\/]+/, :project_id=>/[^\/]+/}
+describe CompareController, "routing" do
+ it "to #index" do
+ get("/gitlabhq/compare").should route_to('compare#index', project_id: 'gitlabhq')
+ end
+
+ it "to #compare" do
+ post("/gitlabhq/compare").should route_to('compare#create', project_id: 'gitlabhq')
+ end
+
+ it "to #show" do
+ get("/gitlabhq/compare/master...stable").should route_to('compare#show', project_id: 'gitlabhq', from: 'master', to: 'stable')
+ get("/gitlabhq/compare/issue/1234...stable").should route_to('compare#show', project_id: 'gitlabhq', from: 'issue/1234', to: 'stable')
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index d381b3f1..4700c3fe 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -28,6 +28,7 @@ RSpec.configure do |config|
config.include LoginHelpers, type: :request
config.include GitoliteStub
config.include FactoryGirl::Syntax::Methods
+ config.include Devise::TestHelpers, type: :controller
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
diff --git a/spec/support/stubbed_repository.rb b/spec/support/stubbed_repository.rb
index 90491e43..5bf3ea46 100644
--- a/spec/support/stubbed_repository.rb
+++ b/spec/support/stubbed_repository.rb
@@ -5,11 +5,11 @@ module StubbedRepository
if new_record? || path == 'newproject'
# There are a couple Project specs and features that expect the Project's
# path to be in the returned path, so let's patronize them.
- File.join(Rails.root, 'tmp', 'repositories', path)
+ Rails.root.join('tmp', 'repositories', path)
else
# For everything else, just give it the path to one of our real seeded
# repos.
- File.join(Rails.root, 'tmp', 'repositories', 'gitlabhq')
+ Rails.root.join('tmp', 'repositories', 'gitlabhq')
end
end