From 8f621c9e064afe1465728143d71f0658053d55ad Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Fri, 8 Feb 2013 16:47:24 +0400 Subject: [PATCH 01/19] Enumerize gem added --- Gemfile | 3 +++ Gemfile.lock | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index 0eba7eb2f65..46ad7e80599 100644 --- a/Gemfile +++ b/Gemfile @@ -45,6 +45,9 @@ gem "grape", "~> 0.2.1" # based on human-friendly examples gem "stamp" +# Enumeration fields +gem 'enumerize' + # Pagination gem "kaminari", "~> 0.14.1" diff --git a/Gemfile.lock b/Gemfile.lock index 3ca39aeae28..311e757cd7c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -144,6 +144,8 @@ GEM email_spec (1.4.0) launchy (~> 2.1) mail (~> 2.2) + enumerize (0.5.1) + activesupport (>= 3.2) erubis (2.7.0) escape_utils (0.2.4) eventmachine (1.0.0) @@ -469,6 +471,7 @@ DEPENDENCIES devise (~> 2.1.0) draper (~> 0.18.0) email_spec + enumerize factory_girl_rails ffaker font-awesome-sass-rails (~> 3.0.0) From e6d2e5696186cc81b7d9a12af25e00528ca2cc30 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Wed, 23 Jan 2013 18:13:28 +0400 Subject: [PATCH 02/19] Issue tracker field added to projects --- app/helpers/issues_helper.rb | 27 ++ app/models/project.rb | 6 +- app/views/projects/_form.html.haml | 4 + config/gitlab.yml.example | 6 + ...123114545_add_issues_tracker_to_project.rb | 5 + db/schema.rb | 312 ------------------ lib/gitlab/markdown.rb | 7 +- spec/helpers/gitlab_markdown_helper_spec.rb | 1 + spec/lib/issues_tracker_spec.rb | 16 + 9 files changed, 69 insertions(+), 315 deletions(-) create mode 100644 db/migrate/20130123114545_add_issues_tracker_to_project.rb delete mode 100644 db/schema.rb create mode 100644 spec/lib/issues_tracker_spec.rb diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index ed7e3e869c0..030f9af3697 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -40,4 +40,31 @@ module IssuesHelper def issues_active_milestones @project.milestones.active.order("id desc").all end + + def url_for_issue(issue_id) + if @project.issues_tracker == Project.issues_tracker.default_value + url = project_issue_url project_id: @project, id: issue_id + else + url = Settings[:issues_tracker][@project.issues_tracker]["issues_url"] + url.gsub(':id', issue_id.to_s).gsub(':project_id', @project.id.to_s) + end + end + + def title_for_issue(issue_id) + if issue = @project.issues.where(id: issue_id).first + issue.title + else + "" + end + end + + def issue_exists?(issue_id) + return false if @project.nil? + + if @project.issues_tracker == Project.issues_tracker.default_value + @project.issues.where(id: issue_id).first.present? + else + true + end + end end diff --git a/app/models/project.rb b/app/models/project.rb index 6ff2a3698df..9ba3080cb14 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -11,6 +11,7 @@ # creator_id :integer # default_branch :string(255) # issues_enabled :boolean default(TRUE), not null +# issues_tracker :string not null # wall_enabled :boolean default(TRUE), not null # merge_requests_enabled :boolean default(TRUE), not null # wiki_enabled :boolean default(TRUE), not null @@ -22,10 +23,11 @@ require "grit" class Project < ActiveRecord::Base include Gitolited + extend Enumerize class TransferError < StandardError; end - attr_accessible :name, :path, :description, :default_branch, + attr_accessible :name, :path, :description, :default_branch, :issues_tracker, :issues_enabled, :wall_enabled, :merge_requests_enabled, :wiki_enabled, :public, :import_url, as: [:default, :admin] @@ -93,6 +95,8 @@ class Project < ActiveRecord::Base scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } scope :public_only, -> { where(public: true) } + enumerize :issues_tracker, :in => (Settings[:issues_tracker].keys).append(:gitlab), :default => :gitlab + class << self def abandoned project_ids = Event.select('max(created_at) as latest_date, project_id'). diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 0336654dc69..7072d78d3ef 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -24,6 +24,10 @@ = f.check_box :issues_enabled %span.descr Lightweight issue tracking system for this project + .control-group + = f.label :issues_tracker, "Issues tracker", class: 'control-label' + .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) + .control-group = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' .controls diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 62761c80cbb..0d1d5818b2e 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -7,6 +7,7 @@ # 2. Replace gitlab -> host with your domain # 3. Replace gitlab -> email_from +<<<<<<< HEAD production: &base # # 1. GitLab app settings @@ -37,6 +38,11 @@ production: &base # signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled. # username_changing_enabled: false # default: true - User can change her username/namespace + ## Available issues trackers + issues_tracker: + redmine: + issues_url: "http://redmine.sample/issues/:id" + ## Gravatar gravatar: enabled: true # Use user avatar images from Gravatar.com (default: true) diff --git a/db/migrate/20130123114545_add_issues_tracker_to_project.rb b/db/migrate/20130123114545_add_issues_tracker_to_project.rb new file mode 100644 index 00000000000..288d0f07c9a --- /dev/null +++ b/db/migrate/20130123114545_add_issues_tracker_to_project.rb @@ -0,0 +1,5 @@ +class AddIssuesTrackerToProject < ActiveRecord::Migration + def change + add_column :projects, :issues_tracker, :string, default: :gitlab, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb deleted file mode 100644 index 74d5f9a360c..00000000000 --- a/db/schema.rb +++ /dev/null @@ -1,312 +0,0 @@ -# encoding: UTF-8 -# This file is auto-generated from the current state of the database. Instead -# of editing this file, please use the migrations feature of Active Record to -# incrementally modify your database, and then regenerate this schema definition. -# -# Note that this schema.rb definition is the authoritative source for your -# database schema. If you need to create the application database on another -# system, you should be using db:schema:load, not running all the migrations -# from scratch. The latter is a flawed and unsustainable approach (the more migrations -# you'll amass, the slower it'll run and the greater likelihood for issues). -# -# It's strongly recommended to check this file into your version control system. - -ActiveRecord::Schema.define(:version => 20130220133245) do - - create_table "events", :force => true do |t| - t.string "target_type" - t.integer "target_id" - t.string "title" - t.text "data" - t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "action" - t.integer "author_id" - end - - add_index "events", ["action"], :name => "index_events_on_action" - add_index "events", ["author_id"], :name => "index_events_on_author_id" - add_index "events", ["created_at"], :name => "index_events_on_created_at" - add_index "events", ["project_id"], :name => "index_events_on_project_id" - add_index "events", ["target_id"], :name => "index_events_on_target_id" - add_index "events", ["target_type"], :name => "index_events_on_target_type" - - create_table "issues", :force => true do |t| - t.string "title" - t.integer "assignee_id" - t.integer "author_id" - t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "position", :default => 0 - t.string "branch_name" - t.text "description" - t.integer "milestone_id" - t.string "state" - end - - add_index "issues", ["assignee_id"], :name => "index_issues_on_assignee_id" - add_index "issues", ["author_id"], :name => "index_issues_on_author_id" - add_index "issues", ["created_at"], :name => "index_issues_on_created_at" - add_index "issues", ["milestone_id"], :name => "index_issues_on_milestone_id" - add_index "issues", ["project_id"], :name => "index_issues_on_project_id" - add_index "issues", ["title"], :name => "index_issues_on_title" - - create_table "keys", :force => true do |t| - t.integer "user_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.text "key" - t.string "title" - t.string "identifier" - t.integer "project_id" - end - - add_index "keys", ["identifier"], :name => "index_keys_on_identifier" - add_index "keys", ["project_id"], :name => "index_keys_on_project_id" - add_index "keys", ["user_id"], :name => "index_keys_on_user_id" - - create_table "merge_requests", :force => true do |t| - t.string "target_branch", :null => false - t.string "source_branch", :null => false - t.integer "project_id", :null => false - t.integer "author_id" - t.integer "assignee_id" - t.string "title" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.text "st_commits", :limit => 2147483647 - t.text "st_diffs", :limit => 2147483647 - t.integer "milestone_id" - t.string "state" - t.string "merge_status" - end - - add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id" - add_index "merge_requests", ["author_id"], :name => "index_merge_requests_on_author_id" - add_index "merge_requests", ["created_at"], :name => "index_merge_requests_on_created_at" - add_index "merge_requests", ["milestone_id"], :name => "index_merge_requests_on_milestone_id" - add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" - add_index "merge_requests", ["source_branch"], :name => "index_merge_requests_on_source_branch" - add_index "merge_requests", ["target_branch"], :name => "index_merge_requests_on_target_branch" - add_index "merge_requests", ["title"], :name => "index_merge_requests_on_title" - - create_table "milestones", :force => true do |t| - t.string "title", :null => false - t.integer "project_id", :null => false - t.text "description" - t.date "due_date" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "state" - end - - add_index "milestones", ["due_date"], :name => "index_milestones_on_due_date" - add_index "milestones", ["project_id"], :name => "index_milestones_on_project_id" - - create_table "namespaces", :force => true do |t| - t.string "name", :null => false - t.string "path", :null => false - t.integer "owner_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "type" - end - - add_index "namespaces", ["name"], :name => "index_namespaces_on_name" - add_index "namespaces", ["owner_id"], :name => "index_namespaces_on_owner_id" - add_index "namespaces", ["path"], :name => "index_namespaces_on_path" - add_index "namespaces", ["type"], :name => "index_namespaces_on_type" - - create_table "notes", :force => true do |t| - t.text "note" - t.string "noteable_type" - t.integer "author_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "project_id" - t.string "attachment" - t.string "line_code" - t.string "commit_id" - t.integer "noteable_id" - end - - add_index "notes", ["commit_id"], :name => "index_notes_on_commit_id" - add_index "notes", ["created_at"], :name => "index_notes_on_created_at" - add_index "notes", ["noteable_type"], :name => "index_notes_on_noteable_type" - add_index "notes", ["project_id", "noteable_type"], :name => "index_notes_on_project_id_and_noteable_type" - add_index "notes", ["project_id"], :name => "index_notes_on_project_id" - - create_table "projects", :force => true do |t| - t.string "name" - t.string "path" - t.text "description" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "creator_id" - t.string "default_branch" - t.boolean "issues_enabled", :default => true, :null => false - t.boolean "wall_enabled", :default => true, :null => false - t.boolean "merge_requests_enabled", :default => true, :null => false - t.boolean "wiki_enabled", :default => true, :null => false - t.integer "namespace_id" - t.boolean "public", :default => false, :null => false - end - - add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id" - add_index "projects", ["namespace_id"], :name => "index_projects_on_namespace_id" - - create_table "protected_branches", :force => true do |t| - t.integer "project_id", :null => false - t.string "name", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "services", :force => true do |t| - t.string "type" - t.string "title" - t.string "token" - t.integer "project_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.boolean "active", :default => false, :null => false - t.string "project_url" - end - - add_index "services", ["project_id"], :name => "index_services_on_project_id" - - create_table "snippets", :force => true do |t| - t.string "title" - t.text "content" - t.integer "author_id", :null => false - t.integer "project_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "file_name" - t.datetime "expires_at" - end - - add_index "snippets", ["created_at"], :name => "index_snippets_on_created_at" - add_index "snippets", ["expires_at"], :name => "index_snippets_on_expires_at" - add_index "snippets", ["project_id"], :name => "index_snippets_on_project_id" - - create_table "taggings", :force => true do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context" - t.datetime "created_at" - end - - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" - add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" - - create_table "tags", :force => true do |t| - t.string "name" - end - - create_table "user_team_project_relationships", :force => true do |t| - t.integer "project_id" - t.integer "user_team_id" - t.integer "greatest_access" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "user_team_user_relationships", :force => true do |t| - t.integer "user_id" - t.integer "user_team_id" - t.boolean "group_admin" - t.integer "permission" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "user_teams", :force => true do |t| - t.string "name" - t.string "path" - t.integer "owner_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - end - - create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :default => "", :null => false - t.string "reset_password_token" - t.datetime "reset_password_sent_at" - t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 - t.datetime "current_sign_in_at" - t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "name" - t.boolean "admin", :default => false, :null => false - t.integer "projects_limit", :default => 10 - t.string "skype", :default => "", :null => false - t.string "linkedin", :default => "", :null => false - t.string "twitter", :default => "", :null => false - t.string "authentication_token" - t.boolean "dark_scheme", :default => false, :null => false - t.integer "theme_id", :default => 1, :null => false - t.string "bio" - t.boolean "blocked", :default => false, :null => false - t.integer "failed_attempts", :default => 0 - t.datetime "locked_at" - t.string "extern_uid" - t.string "provider" - t.string "username" - t.boolean "can_create_group", :default => true, :null => false - t.boolean "can_create_team", :default => true, :null => false - end - - add_index "users", ["admin"], :name => "index_users_on_admin" - add_index "users", ["blocked"], :name => "index_users_on_blocked" - add_index "users", ["email"], :name => "index_users_on_email", :unique => true - add_index "users", ["extern_uid", "provider"], :name => "index_users_on_extern_uid_and_provider", :unique => true - add_index "users", ["name"], :name => "index_users_on_name" - add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true - add_index "users", ["username"], :name => "index_users_on_username" - - create_table "users_projects", :force => true do |t| - t.integer "user_id", :null => false - t.integer "project_id", :null => false - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.integer "project_access", :default => 0, :null => false - end - - add_index "users_projects", ["project_access"], :name => "index_users_projects_on_project_access" - add_index "users_projects", ["project_id"], :name => "index_users_projects_on_project_id" - add_index "users_projects", ["user_id"], :name => "index_users_projects_on_user_id" - - create_table "web_hooks", :force => true do |t| - t.string "url" - t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "type", :default => "ProjectHook" - t.integer "service_id" - end - - create_table "wikis", :force => true do |t| - t.string "title" - t.text "content" - t.integer "project_id" - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false - t.string "slug" - t.integer "user_id" - end - - add_index "wikis", ["project_id"], :name => "index_wikis_on_project_id" - add_index "wikis", ["slug"], :name => "index_wikis_on_slug" - -end diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index e7d6e3e6bd9..befac462707 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -163,8 +163,11 @@ module Gitlab end def reference_issue(identifier) - if issue = @project.issues.where(id: identifier).first - link_to("##{identifier}", project_issue_url(@project, issue), html_options.merge(title: "Issue: #{issue.title}", class: "gfm gfm-issue #{html_options[:class]}")) + if issue_exists? identifier + url = url_for_issue(identifier) + title = title_for_issue(identifier) + + link_to("##{identifier}", url, html_options.merge(title: "Issue: #{title}", class: "gfm gfm-issue #{html_options[:class]}")) end end diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb index 1b067972c81..1f5fabfbb8e 100644 --- a/spec/helpers/gitlab_markdown_helper_spec.rb +++ b/spec/helpers/gitlab_markdown_helper_spec.rb @@ -2,6 +2,7 @@ require "spec_helper" describe GitlabMarkdownHelper do include ApplicationHelper + include IssuesHelper let!(:project) { create(:project) } diff --git a/spec/lib/issues_tracker_spec.rb b/spec/lib/issues_tracker_spec.rb new file mode 100644 index 00000000000..f0bbd8839ad --- /dev/null +++ b/spec/lib/issues_tracker_spec.rb @@ -0,0 +1,16 @@ +require 'spec_helper' + +describe IssuesTracker do + let(:project) { double('project') } + + before do + @project = project + project.stub(repository: stub(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0'])) + project.stub(path_with_namespace: 'gitlab/gitlab-ci') + end + + it 'returns url for issue' do + ololo + end +end + From 999fc2391b012a9de66ad089a3c3eafe8c8b02d8 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Fri, 8 Feb 2013 17:55:02 +0400 Subject: [PATCH 03/19] Issue tracker added to edit project form in admin area --- app/views/admin/projects/_form.html.haml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml index ebf69924a25..657a66f98ec 100644 --- a/app/views/admin/projects/_form.html.haml +++ b/app/views/admin/projects/_form.html.haml @@ -31,6 +31,10 @@ = f.label :issues_enabled, "Issues" .input= f.check_box :issues_enabled + .clearfix + = f.label :issues_tracker, "Issues tracker", class: 'control-label' + .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) + .clearfix = f.label :merge_requests_enabled, "Merge Requests" .input= f.check_box :merge_requests_enabled From 68a7ecdaaf0959d5087d08ef3c94bb201e6dd166 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 11 Feb 2013 15:41:12 +0400 Subject: [PATCH 04/19] Project issue tracker functions refactored --- app/helpers/issues_helper.rb | 14 ++------------ app/models/project.rb | 12 ++++++++++++ lib/gitlab/markdown.rb | 2 +- spec/factories.rb | 4 ++++ spec/lib/issues_tracker_spec.rb | 16 ---------------- spec/models/project_spec.rb | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 52 insertions(+), 29 deletions(-) delete mode 100644 spec/lib/issues_tracker_spec.rb diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 030f9af3697..0d1301d0627 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -42,7 +42,7 @@ module IssuesHelper end def url_for_issue(issue_id) - if @project.issues_tracker == Project.issues_tracker.default_value + if @project.used_default_issues_tracker? url = project_issue_url project_id: @project, id: issue_id else url = Settings[:issues_tracker][@project.issues_tracker]["issues_url"] @@ -51,20 +51,10 @@ module IssuesHelper end def title_for_issue(issue_id) - if issue = @project.issues.where(id: issue_id).first + if @project.used_default_issues_tracker? && issue = @project.issues.where(id: issue_id).first issue.title else "" end end - - def issue_exists?(issue_id) - return false if @project.nil? - - if @project.issues_tracker == Project.issues_tracker.default_value - @project.issues.where(id: issue_id).first.present? - else - true - end - end end diff --git a/app/models/project.rb b/app/models/project.rb index 9ba3080cb14..612a318c968 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -205,6 +205,18 @@ class Project < ActiveRecord::Base issues.tag_counts_on(:labels) end + def issue_exists?(issue_id) + if used_default_issues_tracker? + self.issues.where(id: issue_id).first.present? + else + true + end + end + + def used_default_issues_tracker? + self.issues_tracker == Project.issues_tracker.default_value + end + def services [gitlab_ci_service].compact end diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index befac462707..4e78d881185 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -163,7 +163,7 @@ module Gitlab end def reference_issue(identifier) - if issue_exists? identifier + if @project.issue_exists? identifier url = url_for_issue(identifier) title = title_for_issue(identifier) diff --git a/spec/factories.rb b/spec/factories.rb index b81984b5d53..b846f0a4325 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -29,6 +29,10 @@ FactoryGirl.define do creator end + factory :redmine_project, parent: :project do + issues_tracker { "redmine" } + end + factory :group do sequence(:name) { |n| "group#{n}" } path { name.downcase.gsub(/\s/, '_') } diff --git a/spec/lib/issues_tracker_spec.rb b/spec/lib/issues_tracker_spec.rb deleted file mode 100644 index f0bbd8839ad..00000000000 --- a/spec/lib/issues_tracker_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe IssuesTracker do - let(:project) { double('project') } - - before do - @project = project - project.stub(repository: stub(ref_names: ['master', 'foo/bar/baz', 'v1.0.0', 'v2.0.0'])) - project.stub(path_with_namespace: 'gitlab/gitlab-ci') - end - - it 'returns url for issue' do - ololo - end -end - diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 48432eac147..c5603f52f6a 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -190,4 +190,37 @@ describe Project do Project.new(path: "empty").repository.should be_nil end end + + describe :issue_exists? do + let(:project) { create(:project) } + let(:existed_issue) { create(:issue, project: project) } + let(:not_existed_issue) { create(:issue) } + let(:ext_project) { create(:redmine_project) } + + it "should be true or if used internal tracker and issue exists" do + project.issue_exists?(existed_issue.id).should be_true + end + + it "should be false or if used internal tracker and issue not exists" do + project.issue_exists?(not_existed_issue.id).should be_false + end + + it "should always be true if used other tracker" do + ext_project.issue_exists?(rand(100)).should be_true + end + end + + describe :used_default_issues_tracker? do + let(:project) { create(:project) } + let(:ext_project) { create(:redmine_project) } + + it "should be true if used internal tracker" do + project.used_default_issues_tracker?.should be_true + end + + it "should be false if used other tracker" do + ext_project.used_default_issues_tracker?.should be_false + end + end + end From 62de22c142d0ad9d956e7f6dae2eef4559d38436 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 11 Feb 2013 17:15:10 +0400 Subject: [PATCH 05/19] External issue tracker params added to config --- config/gitlab.yml.example | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 0d1d5818b2e..93824e86853 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -7,6 +7,7 @@ # 2. Replace gitlab -> host with your domain # 3. Replace gitlab -> email_from +<<<<<<< HEAD <<<<<<< HEAD production: &base # @@ -38,9 +39,17 @@ production: &base # signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled. # username_changing_enabled: false # default: true - User can change her username/namespace - ## Available issues trackers + + ## External issues trackers issues_tracker: redmine: + ## If not nil Issues link in project page will be replaced to this + url: "http://redmine.sample" + ## If not nil links from /#\d/ entities from commit messages will replaced to this + ## Use placeholders: + ## :project_id - Gitlab project identifier + ## :issues_tracker_id - Project Name or Id in external issue tracker + ## :id - Issue id (from commit messages) issues_url: "http://redmine.sample/issues/:id" ## Gravatar From 0afdf39dbcc50eb5889be08e5b1aaefe162e456c Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 11 Feb 2013 18:17:43 +0400 Subject: [PATCH 06/19] New field added --- app/models/project.rb | 7 ++++++- app/views/admin/projects/_form.html.haml | 4 ++++ app/views/projects/_form.html.haml | 4 ++++ config/gitlab.yml.example | 6 +----- spec/factories.rb | 1 + spec/models/project_spec.rb | 21 +++++++++++++++++++++ 6 files changed, 37 insertions(+), 6 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 612a318c968..e47e2a094f2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -28,7 +28,7 @@ class Project < ActiveRecord::Base class TransferError < StandardError; end attr_accessible :name, :path, :description, :default_branch, :issues_tracker, - :issues_enabled, :wall_enabled, :merge_requests_enabled, + :issues_enabled, :wall_enabled, :merge_requests_enabled, :issues_tracker_id, :wiki_enabled, :public, :import_url, as: [:default, :admin] attr_accessible :namespace_id, :creator_id, as: :admin @@ -74,6 +74,7 @@ class Project < ActiveRecord::Base message: "only letters, digits & '_' '-' '.' allowed. Letter should be first" } validates :issues_enabled, :wall_enabled, :merge_requests_enabled, :wiki_enabled, inclusion: { in: [true, false] } + validates :issues_tracker_id, length: { within: 0..255 } validates_uniqueness_of :name, scope: :namespace_id validates_uniqueness_of :path, scope: :namespace_id @@ -217,6 +218,10 @@ class Project < ActiveRecord::Base self.issues_tracker == Project.issues_tracker.default_value end + def can_have_issues_tracker_id? + self.issues_enabled && !self.used_default_issues_tracker? + end + def services [gitlab_ci_service].compact end diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml index 657a66f98ec..9049dcd6791 100644 --- a/app/views/admin/projects/_form.html.haml +++ b/app/views/admin/projects/_form.html.haml @@ -35,6 +35,10 @@ = f.label :issues_tracker, "Issues tracker", class: 'control-label' .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) + .clearfix + = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' + .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? + .clearfix = f.label :merge_requests_enabled, "Merge Requests" .input= f.check_box :merge_requests_enabled diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index 7072d78d3ef..c9d623182e3 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -28,6 +28,10 @@ = f.label :issues_tracker, "Issues tracker", class: 'control-label' .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) + .clearfix + = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' + .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? + .control-group = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' .controls diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 93824e86853..cc38b3a45ce 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -7,8 +7,6 @@ # 2. Replace gitlab -> host with your domain # 3. Replace gitlab -> email_from -<<<<<<< HEAD -<<<<<<< HEAD production: &base # # 1. GitLab app settings @@ -43,9 +41,7 @@ production: &base ## External issues trackers issues_tracker: redmine: - ## If not nil Issues link in project page will be replaced to this - url: "http://redmine.sample" - ## If not nil links from /#\d/ entities from commit messages will replaced to this + ## If not nil, links from /#\d/ entities from commit messages will replaced to this ## Use placeholders: ## :project_id - Gitlab project identifier ## :issues_tracker_id - Project Name or Id in external issue tracker diff --git a/spec/factories.rb b/spec/factories.rb index b846f0a4325..41766859468 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -31,6 +31,7 @@ FactoryGirl.define do factory :redmine_project, parent: :project do issues_tracker { "redmine" } + issues_tracker_id { "project_name_in_redmine" } end factory :group do diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index c5603f52f6a..44f4cd4a737 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -60,6 +60,7 @@ describe Project do it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) } it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) } it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) } + it { should ensure_length_of(:issues_tracker_id).is_within(0..255) } it "should not allow new projects beyond user limits" do project.stub(:creator).and_return(double(can_create_project?: false, projects_limit: 1)) @@ -223,4 +224,24 @@ describe Project do end end + describe :can_have_issues_tracker_id? do + let(:project) { create(:project) } + let(:ext_project) { create(:redmine_project) } + + it "should be true for projects with external issues tracker if issues enabled" do + ext_project.can_have_issues_tracker_id?.should be_true + end + + it "should be false for projects with internal issue tracker if issues enabled" do + project.can_have_issues_tracker_id?.should be_false + end + + it "should be always false if issues disbled" do + project.issues_enabled = false + ext_project.issues_enabled = false + + project.can_have_issues_tracker_id?.should be_false + ext_project.can_have_issues_tracker_id?.should be_false + end + end end From f13600845d2ccec816337234eb5f1dccd40777f7 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 11 Feb 2013 18:21:04 +0400 Subject: [PATCH 07/19] Migration added --- .../20130211085435_add_issues_tracker_id_to_project.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/20130211085435_add_issues_tracker_id_to_project.rb diff --git a/db/migrate/20130211085435_add_issues_tracker_id_to_project.rb b/db/migrate/20130211085435_add_issues_tracker_id_to_project.rb new file mode 100644 index 00000000000..71763d18aee --- /dev/null +++ b/db/migrate/20130211085435_add_issues_tracker_id_to_project.rb @@ -0,0 +1,5 @@ +class AddIssuesTrackerIdToProject < ActiveRecord::Migration + def change + add_column :projects, :issues_tracker_id, :string + end +end From 16c720fd966ccb70a7642c59b81b23f74f00c122 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Mon, 11 Feb 2013 17:32:29 +0400 Subject: [PATCH 08/19] Issues helper improved --- app/helpers/issues_helper.rb | 8 ++++- spec/helpers/issues_helper_spec.rb | 54 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 spec/helpers/issues_helper_spec.rb diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 0d1301d0627..3f802727560 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -42,15 +42,21 @@ module IssuesHelper end def url_for_issue(issue_id) + return "" if @project.nil? + if @project.used_default_issues_tracker? url = project_issue_url project_id: @project, id: issue_id else url = Settings[:issues_tracker][@project.issues_tracker]["issues_url"] - url.gsub(':id', issue_id.to_s).gsub(':project_id', @project.id.to_s) + url.gsub(':id', issue_id.to_s) + .gsub(':project_id', @project.id.to_s) + .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s) end end def title_for_issue(issue_id) + return "" if @project.nil? + if @project.used_default_issues_tracker? && issue = @project.issues.where(id: issue_id).first issue.title else diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb new file mode 100644 index 00000000000..7d2ac8c7d84 --- /dev/null +++ b/spec/helpers/issues_helper_spec.rb @@ -0,0 +1,54 @@ +require "spec_helper" + +describe IssuesHelper do + let(:project) { create(:project) } + let(:issue) { create(:issue, project: project) } + let(:ext_project) { create(:redmine_project) } + + describe :title_for_issue do + it "should return issue title if used internal tracker" do + @project = project + title_for_issue(issue.id).should eq issue.title + end + + it "should always return empty string if used external tracker" do + @project = ext_project + title_for_issue(rand(100)).should eq "" + end + + it "should always return empty string if project nil" do + @project = nil + + title_for_issue(rand(100)).should eq "" + end + end + + describe :url_for_issue do + let(:issue_id) { 3 } + let(:issues_url) { "http://redmine/:project_id/:issues_tracker_id/:id" } + let(:ext_expected) do + issues_url.gsub(':id', issue_id.to_s) + .gsub(':project_id', ext_project.id.to_s) + .gsub(':issues_tracker_id', ext_project.issues_tracker_id.to_s) + end + let(:int_expected) { polymorphic_path([project, issue]) } + + it "should return internal path if used internal tracker" do + @project = project + url_for_issue(issue.id).should match(int_expected) + end + + it "should return path to external tracker" do + @project = ext_project + Settings[:issues_tracker][ext_project.issues_tracker]["issues_url"] = issues_url + + url_for_issue(issue_id).should match(ext_expected) + end + + it "should return empty string if project nil" do + @project = nil + + url_for_issue(issue.id).should eq "" + end + end +end From 9e8a818696f3b3538b93a306d6e8d3ce5973ece0 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 12 Feb 2013 15:37:33 +0400 Subject: [PATCH 09/19] Issues helper included to markdown helper --- lib/gitlab/markdown.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb index 4e78d881185..280f9f9730a 100644 --- a/lib/gitlab/markdown.rb +++ b/lib/gitlab/markdown.rb @@ -25,6 +25,8 @@ module Gitlab # >> gfm(":trollface:") # => "\":trollface:\" module Markdown + include IssuesHelper + attr_reader :html_options # Public: Parse the provided text with GitLab-Flavored Markdown From 9b606ede000666bc5f5330f43fa0ea0c7ff9815c Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Thu, 14 Feb 2013 18:25:56 +0400 Subject: [PATCH 10/19] Wrong default section in config. Fixed. --- config/gitlab.yml.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index cc38b3a45ce..c7bb66ae6e7 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -140,10 +140,10 @@ production: &base timeout: 10 development: - <<: *base + <<: *defaults test: <<: *base staging: - <<: *base + <<: *defaults From c643b50dbd726b6a3396ea459d14378e1c52b48b Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Thu, 14 Feb 2013 18:26:50 +0400 Subject: [PATCH 11/19] Default value for issues_tracker setting added --- app/models/project.rb | 2 +- config/gitlab.yml.example | 5 ++++- config/initializers/1_settings.rb | 2 ++ spec/helpers/issues_helper_spec.rb | 3 +-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index e47e2a094f2..12f7e45496b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -96,7 +96,7 @@ class Project < ActiveRecord::Base scope :joined, ->(user) { where("namespace_id != ?", user.namespace_id) } scope :public_only, -> { where(public: true) } - enumerize :issues_tracker, :in => (Settings[:issues_tracker].keys).append(:gitlab), :default => :gitlab + enumerize :issues_tracker, :in => (Gitlab.config.issues_tracker.keys).append(:gitlab), :default => :gitlab class << self def abandoned diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index c7bb66ae6e7..895ae797b6b 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -143,7 +143,10 @@ development: <<: *defaults test: - <<: *base + <<: *defaults + issues_tracker: + redmine: + issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" staging: <<: *defaults diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index f7d18e67148..a656b02171f 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -42,6 +42,8 @@ Settings['omniauth'] ||= Settingslogic.new({}) Settings.omniauth['enabled'] = false if Settings.omniauth['enabled'].nil? Settings.omniauth['providers'] ||= [] +Settings['issues_tracker'] ||= {} + # # GitLab # diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 7d2ac8c7d84..013dab71d69 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -25,7 +25,7 @@ describe IssuesHelper do describe :url_for_issue do let(:issue_id) { 3 } - let(:issues_url) { "http://redmine/:project_id/:issues_tracker_id/:id" } + let(:issues_url) { Gitlab.config.issues_tracker.redmine.issues_url} let(:ext_expected) do issues_url.gsub(':id', issue_id.to_s) .gsub(':project_id', ext_project.id.to_s) @@ -40,7 +40,6 @@ describe IssuesHelper do it "should return path to external tracker" do @project = ext_project - Settings[:issues_tracker][ext_project.issues_tracker]["issues_url"] = issues_url url_for_issue(issue_id).should match(ext_expected) end From c6385e41355a622ef1be2d72d0fd20eef2897707 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Thu, 14 Feb 2013 18:43:06 +0400 Subject: [PATCH 12/19] Section name returned back to base --- config/gitlab.yml.example | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index 895ae797b6b..b7b2296fee2 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -140,13 +140,13 @@ production: &base timeout: 10 development: - <<: *defaults + <<: *base test: - <<: *defaults + <<: *base issues_tracker: redmine: issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" staging: - <<: *defaults + <<: *base From cf3cf3750e53439cfaa8df786fd71308e4ef4867 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 19 Feb 2013 16:30:37 +0400 Subject: [PATCH 13/19] Gem gon added. It produces server-side variable values in javascript --- Gemfile | 1 + Gemfile.lock | 4 ++++ app/views/layouts/_head.html.haml | 1 + 3 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index 46ad7e80599..9c8467b1733 100644 --- a/Gemfile +++ b/Gemfile @@ -115,6 +115,7 @@ group :assets do gem 'bootstrap-sass', "2.2.1.1" gem "font-awesome-sass-rails", "~> 3.0.0" gem "gemoji", "~> 1.2.1", require: 'emoji/railtie' + gem "gon" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 311e757cd7c..65fd6f363fb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -184,6 +184,9 @@ GEM pyu-ruby-sasl (~> 0.0.3.1) rubyntlm (~> 0.1.1) gitlab_yaml_db (1.0.0) + gon (4.0.2) + actionpack (>= 2.3.0) + json grape (0.2.2) activesupport hashie (~> 1.2) @@ -483,6 +486,7 @@ DEPENDENCIES gitlab_meta (= 5.0) gitlab_omniauth-ldap (= 1.0.2) gitlab_yaml_db (= 1.0.0) + gon grack! grape (~> 0.2.1) grit! diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml index 4b4f5da3324..eb83fd2fd45 100644 --- a/app/views/layouts/_head.html.haml +++ b/app/views/layouts/_head.html.haml @@ -7,6 +7,7 @@ = stylesheet_link_tag "application" = javascript_include_tag "application" = csrf_meta_tags + = include_gon -# Atom feed - if current_user From bca72eac747acbec42e4b93fecb4f6100e3ba257 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 19 Feb 2013 16:37:43 +0400 Subject: [PATCH 14/19] Default issue tracker name added to gon variables --- app/controllers/application_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1f211bac9c2..5b886227bc9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,6 +5,7 @@ class ApplicationController < ActionController::Base before_filter :add_abilities before_filter :dev_tools if Rails.env == 'development' before_filter :default_headers + before_filter :add_gon_variables protect_from_forgery @@ -148,4 +149,8 @@ class ApplicationController < ActionController::Base headers['X-Frame-Options'] = 'DENY' headers['X-XSS-Protection'] = '1; mode=block' end + + def add_gon_variables + gon.default_issues_tracker = Project.issues_tracker.default_value + end end From ab98db73a35172d723adf474d9dc50b5d613a9bf Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 19 Feb 2013 16:43:24 +0400 Subject: [PATCH 15/19] Issues tracker settings enableds/disableds without page reloading now --- app/assets/javascripts/projects.js.coffee | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/assets/javascripts/projects.js.coffee b/app/assets/javascripts/projects.js.coffee index d03a487c453..24106c61b75 100644 --- a/app/assets/javascripts/projects.js.coffee +++ b/app/assets/javascripts/projects.js.coffee @@ -18,3 +18,18 @@ $ -> # Ref switcher $('.project-refs-select').on 'change', -> $(@).parents('form').submit() + + $('#project_issues_enabled').change -> + if ($(this).is(':checked') == true) + $('#project_issues_tracker').removeAttr('disabled') + else + $('#project_issues_tracker').attr('disabled', 'disabled') + + $('#project_issues_tracker').change() + + $('#project_issues_tracker').change -> + if ($(this).val() == gon.default_issues_tracker || $(this).is(':disabled')) + $('#project_issues_tracker_id').attr('disabled', 'disabled') + else + $('#project_issues_tracker_id').removeAttr('disabled') + From b6d0f2852d1f2518ca8987667beb7df2b8223611 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 19 Feb 2013 17:06:40 +0400 Subject: [PATCH 16/19] Issues link from project page follows on remote bug tracker if it selected now --- app/helpers/issues_helper.rb | 12 ++++++++++++ app/views/layouts/project_resource.html.haml | 7 ++++--- config/gitlab.yml.example | 6 ++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 3f802727560..83215180492 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -41,6 +41,18 @@ module IssuesHelper @project.milestones.active.order("id desc").all end + def url_for_project_issues + return "" if @project.nil? + + if @project.used_default_issues_tracker? + project_issues_filter_path(@project) + else + url = Settings[:issues_tracker][@project.issues_tracker]["project_url"] + url.gsub(':project_id', @project.id.to_s) + .gsub(':issues_tracker_id', @project.issues_tracker_id.to_s) + end + end + def url_for_issue(issue_id) return "" if @project.nil? diff --git a/app/views/layouts/project_resource.html.haml b/app/views/layouts/project_resource.html.haml index 13fb8637bf6..55abe8ab5f1 100644 --- a/app/views/layouts/project_resource.html.haml +++ b/app/views/layouts/project_resource.html.haml @@ -22,11 +22,12 @@ = nav_link(controller: %w(graph)) do = link_to "Network", project_graph_path(@project, @ref || @repository.root_ref) - - if @project.issues_enabled + - if @project.issues_enabled = nav_link(controller: %w(issues milestones labels)) do - = link_to project_issues_filter_path(@project) do + = link_to url_for_project_issues do Issues - %span.count.issue_counter= @project.issues.opened.count + - if @project.used_default_issues_tracker? + %span.count.issue_counter= @project.issues.opened.count - if @project.repo_exists? && @project.merge_requests_enabled = nav_link(controller: :merge_requests) do diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index b7b2296fee2..07e97ae5414 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -41,6 +41,11 @@ production: &base ## External issues trackers issues_tracker: redmine: + ## If not nil, link 'Issues' on project page will be replaced tp this + ## Use placeholders: + ## :project_id - Gitlab project identifier + ## :issues_tracker_id - Project Name or Id in external issue tracker + project_url: "http://redmine.sample/projects/:issues_tracker_id" ## If not nil, links from /#\d/ entities from commit messages will replaced to this ## Use placeholders: ## :project_id - Gitlab project identifier @@ -146,6 +151,7 @@ test: <<: *base issues_tracker: redmine: + project_url: "http://redmine/projects/:issues_tracker_id" issues_url: "http://redmine/:project_id/:issues_tracker_id/:id" staging: From 8caccae45457940b54174a3516a1a56915016c22 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 19 Feb 2013 17:21:59 +0400 Subject: [PATCH 17/19] Issue helper tests improved --- spec/helpers/issues_helper_spec.rb | 32 +++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb index 013dab71d69..c9eb6591561 100644 --- a/spec/helpers/issues_helper_spec.rb +++ b/spec/helpers/issues_helper_spec.rb @@ -1,9 +1,9 @@ require "spec_helper" describe IssuesHelper do - let(:project) { create(:project) } - let(:issue) { create(:issue, project: project) } - let(:ext_project) { create(:redmine_project) } + let(:project) { create :project } + let(:issue) { create :issue, project: project } + let(:ext_project) { create :redmine_project } describe :title_for_issue do it "should return issue title if used internal tracker" do @@ -23,6 +23,32 @@ describe IssuesHelper do end end + describe :url_for_project_issues do + let(:project_url) { Gitlab.config.issues_tracker.redmine.project_url} + let(:ext_expected) do + project_url.gsub(':project_id', ext_project.id.to_s) + .gsub(':issues_tracker_id', ext_project.issues_tracker_id.to_s) + end + let(:int_expected) { polymorphic_path([project]) } + + it "should return internal path if used internal tracker" do + @project = project + url_for_project_issues.should match(int_expected) + end + + it "should return path to external tracker" do + @project = ext_project + + url_for_project_issues.should match(ext_expected) + end + + it "should return empty string if project nil" do + @project = nil + + url_for_project_issues.should eq "" + end + end + describe :url_for_issue do let(:issue_id) { 3 } let(:issues_url) { Gitlab.config.issues_tracker.redmine.issues_url} From cff845784eb76aeaff7b4242e0aaa2469a530a59 Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Tue, 19 Feb 2013 17:31:45 +0400 Subject: [PATCH 18/19] Show Issues tracker select only if one or more remote issue trackers available --- app/views/admin/projects/_form.html.haml | 13 +++++++------ app/views/projects/_form.html.haml | 13 +++++++------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/app/views/admin/projects/_form.html.haml b/app/views/admin/projects/_form.html.haml index 9049dcd6791..29b90bdd4cb 100644 --- a/app/views/admin/projects/_form.html.haml +++ b/app/views/admin/projects/_form.html.haml @@ -31,13 +31,14 @@ = f.label :issues_enabled, "Issues" .input= f.check_box :issues_enabled - .clearfix - = f.label :issues_tracker, "Issues tracker", class: 'control-label' - .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) + - if Project.issues_tracker.values.count > 1 + .clearfix + = f.label :issues_tracker, "Issues tracker", class: 'control-label' + .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) - .clearfix - = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' - .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? + .clearfix + = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' + .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? .clearfix = f.label :merge_requests_enabled, "Merge Requests" diff --git a/app/views/projects/_form.html.haml b/app/views/projects/_form.html.haml index c9d623182e3..b78c70be18a 100644 --- a/app/views/projects/_form.html.haml +++ b/app/views/projects/_form.html.haml @@ -24,13 +24,14 @@ = f.check_box :issues_enabled %span.descr Lightweight issue tracking system for this project - .control-group - = f.label :issues_tracker, "Issues tracker", class: 'control-label' - .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) + - if Project.issues_tracker.values.count > 1 + .control-group + = f.label :issues_tracker, "Issues tracker", class: 'control-label' + .input= f.select(:issues_tracker, Project.issues_tracker.values, {}, { disabled: !@project.issues_enabled }) - .clearfix - = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' - .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? + .clearfix + = f.label :issues_tracker_id, "Project name or id in issues tracker", class: 'control-label' + .input= f.text_field :issues_tracker_id, class: "xxlarge", disabled: !@project.can_have_issues_tracker_id? .control-group = f.label :merge_requests_enabled, "Merge Requests", class: 'control-label' From 1dab19d0d7b25cb5af27b8d10c8b615b2d38c2cf Mon Sep 17 00:00:00 2001 From: Andrew8xx8 Date: Thu, 28 Feb 2013 16:30:47 +0400 Subject: [PATCH 19/19] DB schema updated --- db/schema.rb | 314 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 db/schema.rb diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 00000000000..e9d428e5ef5 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,314 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20130220133245) do + + create_table "events", :force => true do |t| + t.string "target_type" + t.integer "target_id" + t.string "title" + t.text "data" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "action" + t.integer "author_id" + end + + add_index "events", ["action"], :name => "index_events_on_action" + add_index "events", ["author_id"], :name => "index_events_on_author_id" + add_index "events", ["created_at"], :name => "index_events_on_created_at" + add_index "events", ["project_id"], :name => "index_events_on_project_id" + add_index "events", ["target_id"], :name => "index_events_on_target_id" + add_index "events", ["target_type"], :name => "index_events_on_target_type" + + create_table "issues", :force => true do |t| + t.string "title" + t.integer "assignee_id" + t.integer "author_id" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "position", :default => 0 + t.string "branch_name" + t.text "description" + t.integer "milestone_id" + t.string "state" + end + + add_index "issues", ["assignee_id"], :name => "index_issues_on_assignee_id" + add_index "issues", ["author_id"], :name => "index_issues_on_author_id" + add_index "issues", ["created_at"], :name => "index_issues_on_created_at" + add_index "issues", ["milestone_id"], :name => "index_issues_on_milestone_id" + add_index "issues", ["project_id"], :name => "index_issues_on_project_id" + add_index "issues", ["title"], :name => "index_issues_on_title" + + create_table "keys", :force => true do |t| + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "key" + t.string "title" + t.string "identifier" + t.integer "project_id" + end + + add_index "keys", ["identifier"], :name => "index_keys_on_identifier" + add_index "keys", ["project_id"], :name => "index_keys_on_project_id" + add_index "keys", ["user_id"], :name => "index_keys_on_user_id" + + create_table "merge_requests", :force => true do |t| + t.string "target_branch", :null => false + t.string "source_branch", :null => false + t.integer "project_id", :null => false + t.integer "author_id" + t.integer "assignee_id" + t.string "title" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "st_commits", :limit => 2147483647 + t.text "st_diffs", :limit => 2147483647 + t.integer "milestone_id" + t.string "state" + t.string "merge_status" + end + + add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id" + add_index "merge_requests", ["author_id"], :name => "index_merge_requests_on_author_id" + add_index "merge_requests", ["created_at"], :name => "index_merge_requests_on_created_at" + add_index "merge_requests", ["milestone_id"], :name => "index_merge_requests_on_milestone_id" + add_index "merge_requests", ["project_id"], :name => "index_merge_requests_on_project_id" + add_index "merge_requests", ["source_branch"], :name => "index_merge_requests_on_source_branch" + add_index "merge_requests", ["target_branch"], :name => "index_merge_requests_on_target_branch" + add_index "merge_requests", ["title"], :name => "index_merge_requests_on_title" + + create_table "milestones", :force => true do |t| + t.string "title", :null => false + t.integer "project_id", :null => false + t.text "description" + t.date "due_date" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "state" + end + + add_index "milestones", ["due_date"], :name => "index_milestones_on_due_date" + add_index "milestones", ["project_id"], :name => "index_milestones_on_project_id" + + create_table "namespaces", :force => true do |t| + t.string "name", :null => false + t.string "path", :null => false + t.integer "owner_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "type" + end + + add_index "namespaces", ["name"], :name => "index_namespaces_on_name" + add_index "namespaces", ["owner_id"], :name => "index_namespaces_on_owner_id" + add_index "namespaces", ["path"], :name => "index_namespaces_on_path" + add_index "namespaces", ["type"], :name => "index_namespaces_on_type" + + create_table "notes", :force => true do |t| + t.text "note" + t.string "noteable_type" + t.integer "author_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "project_id" + t.string "attachment" + t.string "line_code" + t.string "commit_id" + t.integer "noteable_id" + end + + add_index "notes", ["commit_id"], :name => "index_notes_on_commit_id" + add_index "notes", ["created_at"], :name => "index_notes_on_created_at" + add_index "notes", ["noteable_type"], :name => "index_notes_on_noteable_type" + add_index "notes", ["project_id", "noteable_type"], :name => "index_notes_on_project_id_and_noteable_type" + add_index "notes", ["project_id"], :name => "index_notes_on_project_id" + + create_table "projects", :force => true do |t| + t.string "name" + t.string "path" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "creator_id" + t.string "default_branch" + t.boolean "issues_enabled", :default => true, :null => false + t.boolean "wall_enabled", :default => true, :null => false + t.boolean "merge_requests_enabled", :default => true, :null => false + t.boolean "wiki_enabled", :default => true, :null => false + t.integer "namespace_id" + t.boolean "public", :default => false, :null => false + t.string "issues_tracker", :default => "gitlab", :null => false + t.string "issues_tracker_id" + end + + add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id" + add_index "projects", ["namespace_id"], :name => "index_projects_on_namespace_id" + + create_table "protected_branches", :force => true do |t| + t.integer "project_id", :null => false + t.string "name", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "services", :force => true do |t| + t.string "type" + t.string "title" + t.string "token" + t.integer "project_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "active", :default => false, :null => false + t.string "project_url" + end + + add_index "services", ["project_id"], :name => "index_services_on_project_id" + + create_table "snippets", :force => true do |t| + t.string "title" + t.text "content" + t.integer "author_id", :null => false + t.integer "project_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "file_name" + t.datetime "expires_at" + end + + add_index "snippets", ["created_at"], :name => "index_snippets_on_created_at" + add_index "snippets", ["expires_at"], :name => "index_snippets_on_expires_at" + add_index "snippets", ["project_id"], :name => "index_snippets_on_project_id" + + create_table "taggings", :force => true do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context" + t.datetime "created_at" + end + + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + + create_table "tags", :force => true do |t| + t.string "name" + end + + create_table "user_team_project_relationships", :force => true do |t| + t.integer "project_id" + t.integer "user_team_id" + t.integer "greatest_access" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_team_user_relationships", :force => true do |t| + t.integer "user_id" + t.integer "user_team_id" + t.boolean "group_admin" + t.integer "permission" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_teams", :force => true do |t| + t.string "name" + t.string "path" + t.integer "owner_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "users", :force => true do |t| + t.string "email", :default => "", :null => false + t.string "encrypted_password", :default => "", :null => false + t.string "reset_password_token" + t.datetime "reset_password_sent_at" + t.datetime "remember_created_at" + t.integer "sign_in_count", :default => 0 + t.datetime "current_sign_in_at" + t.datetime "last_sign_in_at" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "name" + t.boolean "admin", :default => false, :null => false + t.integer "projects_limit", :default => 10 + t.string "skype", :default => "", :null => false + t.string "linkedin", :default => "", :null => false + t.string "twitter", :default => "", :null => false + t.string "authentication_token" + t.boolean "dark_scheme", :default => false, :null => false + t.integer "theme_id", :default => 1, :null => false + t.string "bio" + t.boolean "blocked", :default => false, :null => false + t.integer "failed_attempts", :default => 0 + t.datetime "locked_at" + t.string "extern_uid" + t.string "provider" + t.string "username" + t.boolean "can_create_group", :default => true, :null => false + t.boolean "can_create_team", :default => true, :null => false + end + + add_index "users", ["admin"], :name => "index_users_on_admin" + add_index "users", ["blocked"], :name => "index_users_on_blocked" + add_index "users", ["email"], :name => "index_users_on_email", :unique => true + add_index "users", ["extern_uid", "provider"], :name => "index_users_on_extern_uid_and_provider", :unique => true + add_index "users", ["name"], :name => "index_users_on_name" + add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true + add_index "users", ["username"], :name => "index_users_on_username" + + create_table "users_projects", :force => true do |t| + t.integer "user_id", :null => false + t.integer "project_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "project_access", :default => 0, :null => false + end + + add_index "users_projects", ["project_access"], :name => "index_users_projects_on_project_access" + add_index "users_projects", ["project_id"], :name => "index_users_projects_on_project_id" + add_index "users_projects", ["user_id"], :name => "index_users_projects_on_user_id" + + create_table "web_hooks", :force => true do |t| + t.string "url" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "type", :default => "ProjectHook" + t.integer "service_id" + end + + create_table "wikis", :force => true do |t| + t.string "title" + t.text "content" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "slug" + t.integer "user_id" + end + + add_index "wikis", ["project_id"], :name => "index_wikis_on_project_id" + add_index "wikis", ["slug"], :name => "index_wikis_on_slug" + +end