From 7cdc5b9e0438c35c83fce739a764cb146d20c004 Mon Sep 17 00:00:00 2001 From: randx Date: Wed, 29 Aug 2012 00:04:06 +0300 Subject: [PATCH] Use similar interface to access gitolite Simplified gitolite handle logic Stubn over monkeypatch Stub only specific methods in Gitlab:Gitolite Moved grach auth to lib added specs for keys observer removes SshKey role --- app/models/key.rb | 5 +- app/models/protected_branch.rb | 4 +- app/models/users_project.rb | 6 +-- app/observers/key_observer.rb | 7 ++- app/roles/git_host.rb | 5 ++ app/roles/git_merge.rb | 2 - app/roles/repository.rb | 8 ++-- app/roles/ssh_key.rb | 18 ------- config/environment.rb | 2 - config/initializers/5_backend.rb | 5 ++ features/support/env.rb | 8 ++++ lib/gitlab/{ => backend}/gitolite.rb | 48 +++++++++++++++++-- .../gitlab/backend}/grack_auth.rb | 0 lib/gitlab/git_host.rb | 17 ------- lib/tasks/gitlab/enable_automerge.rake | 4 +- lib/tasks/gitlab/gitolite_rebuild.rake | 2 +- spec/observers/key_observer_spec.rb | 34 +++++++++++++ spec/spec_helper.rb | 3 ++ spec/support/gitolite_stub.rb | 35 ++++++++++++++ spec/support/monkeypatch.rb | 30 ------------ 20 files changed, 155 insertions(+), 88 deletions(-) create mode 100644 app/roles/git_host.rb delete mode 100644 app/roles/git_merge.rb delete mode 100644 app/roles/ssh_key.rb create mode 100644 config/initializers/5_backend.rb rename lib/gitlab/{ => backend}/gitolite.rb (79%) rename {config/initializers => lib/gitlab/backend}/grack_auth.rb (100%) delete mode 100644 lib/gitlab/git_host.rb create mode 100644 spec/observers/key_observer_spec.rb create mode 100644 spec/support/gitolite_stub.rb diff --git a/app/models/key.rb b/app/models/key.rb index cfcb1f63..8b61675a 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -1,7 +1,6 @@ require 'digest/md5' class Key < ActiveRecord::Base - include SshKey belongs_to :user belongs_to :project @@ -50,6 +49,10 @@ class Key < ActiveRecord::Base user.projects end end + + def last_deploy? + Key.where(identifier: identifier).count == 0 + end end # == Schema Information # diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index 4da1432c..7c30f7a0 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -1,4 +1,6 @@ class ProtectedBranch < ActiveRecord::Base + include GitHost + belongs_to :project validates_presence_of :project_id validates_presence_of :name @@ -7,7 +9,7 @@ class ProtectedBranch < ActiveRecord::Base after_destroy :update_repository def update_repository - Gitlab::GitHost.system.update_project(project.path, project) + git_host.update_repository(project) end def commit diff --git a/app/models/users_project.rb b/app/models/users_project.rb index 36e6d904..7d172934 100644 --- a/app/models/users_project.rb +++ b/app/models/users_project.rb @@ -1,4 +1,6 @@ class UsersProject < ActiveRecord::Base + include GitHost + GUEST = 10 REPORTER = 20 DEVELOPER = 30 @@ -58,9 +60,7 @@ class UsersProject < ActiveRecord::Base end def update_repository - Gitlab::GitHost.system.new.configure do |c| - c.update_project(project.path, project) - end + git_host.update_repository(project) end def project_access_human diff --git a/app/observers/key_observer.rb b/app/observers/key_observer.rb index fac53a67..a3f17bde 100644 --- a/app/observers/key_observer.rb +++ b/app/observers/key_observer.rb @@ -1,9 +1,12 @@ class KeyObserver < ActiveRecord::Observer + include GitHost + def after_save(key) - key.update_repository + git_host.set_key(key.identifier, key.key, key.projects) end def after_destroy(key) - key.repository_delete_key + return if key.is_deploy_key && !key.last_deploy? + git_host.remove_key(key.identifier, key.projects) end end diff --git a/app/roles/git_host.rb b/app/roles/git_host.rb new file mode 100644 index 00000000..aa620f77 --- /dev/null +++ b/app/roles/git_host.rb @@ -0,0 +1,5 @@ +module GitHost + def git_host + Gitlab::Gitolite.new + end +end diff --git a/app/roles/git_merge.rb b/app/roles/git_merge.rb deleted file mode 100644 index 95e5942f..00000000 --- a/app/roles/git_merge.rb +++ /dev/null @@ -1,2 +0,0 @@ -module GitMerge -end diff --git a/app/roles/repository.rb b/app/roles/repository.rb index 17f52499..5fa950db 100644 --- a/app/roles/repository.rb +++ b/app/roles/repository.rb @@ -1,4 +1,6 @@ module Repository + include GitHost + def valid_repo? repo rescue @@ -48,7 +50,7 @@ module Repository end def url_to_repo - Gitlab::GitHost.url_to_repo(path) + git_host.url_to_repo(path) end def path_to_repo @@ -56,11 +58,11 @@ module Repository end def update_repository - Gitlab::GitHost.system.update_project(path, self) + git_host.update_repository(self) end def destroy_repository - Gitlab::GitHost.system.destroy_project(self) + git_host.remove_repository(self) end def repo_exists? diff --git a/app/roles/ssh_key.rb b/app/roles/ssh_key.rb deleted file mode 100644 index 5e1d2c23..00000000 --- a/app/roles/ssh_key.rb +++ /dev/null @@ -1,18 +0,0 @@ -module SshKey - def update_repository - Gitlab::GitHost.system.new.configure do |c| - c.update_keys(identifier, key) - c.update_projects(projects) - end - end - - def repository_delete_key - Gitlab::GitHost.system.new.configure do |c| - #delete key file is there is no identically deploy keys - if !is_deploy_key || Key.where(identifier: identifier).count() == 0 - c.delete_key(identifier) - end - c.update_projects(projects) - end - end -end diff --git a/config/environment.rb b/config/environment.rb index c880a7ad..3b186a9d 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -3,5 +3,3 @@ require File.expand_path('../application', __FILE__) # Initialize the rails application Gitlab::Application.initialize! - -require File.join(Rails.root, "lib", "gitlab", "git_host") diff --git a/config/initializers/5_backend.rb b/config/initializers/5_backend.rb new file mode 100644 index 00000000..85f747ac --- /dev/null +++ b/config/initializers/5_backend.rb @@ -0,0 +1,5 @@ +# GIT over HTTP +require Rails.root.join("lib", "gitlab", "backend", "grack_auth") + +# GITOLITE backend +require Rails.root.join("lib", "gitlab", "backend", "gitolite") diff --git a/features/support/env.rb b/features/support/env.rb index 80a465b4..0d9a9ed4 100644 --- a/features/support/env.rb +++ b/features/support/env.rb @@ -5,10 +5,12 @@ end require 'cucumber/rails' require 'webmock/cucumber' + WebMock.allow_net_connect! require Rails.root.join 'spec/factories' require Rails.root.join 'spec/support/monkeypatch' +require Rails.root.join 'spec/support/gitolite_stub' require Rails.root.join 'spec/support/login_helpers' require Rails.root.join 'spec/support/valid_commit' @@ -48,3 +50,9 @@ headless = Headless.new headless.start require 'cucumber/rspec/doubles' + +include GitoliteStub + +Before do + stub_gitolite! +end diff --git a/lib/gitlab/gitolite.rb b/lib/gitlab/backend/gitolite.rb similarity index 79% rename from lib/gitlab/gitolite.rb rename to lib/gitlab/backend/gitolite.rb index a3f34061..4d0a0cf0 100644 --- a/lib/gitlab/gitolite.rb +++ b/lib/gitlab/backend/gitolite.rb @@ -2,24 +2,62 @@ require 'gitolite' require 'timeout' require 'fileutils' +# TODO: refactor & cleanup module Gitlab class Gitolite class AccessDenied < StandardError; end - def self.update_project(path, project) - self.new.configure { |git| git.update_project(path, project) } + def set_key key_id, key_content, projects + self.configure do |c| + c.update_keys(key_id, key_content) + c.update_project(project.path, projects) + end end - def self.destroy_project(project) - self.new.configure { |git| git.destroy_project(project) } + def remove_key key_id, projects + self.configure do |c| + c.delete_key(key_id) + c.update_project(project.path, projects) + end end + def update_repository project + self.configure do |c| + c.update_project(project.path, project) + end + end + + alias_method :create_repository, :update_repository + + def remove_repository project + self.configure do |c| + c.destroy_project(project) + end + end + + def url_to_repo path + Gitlab.config.ssh_path + "#{path}.git" + end + + def initialize + # create tmp dir + @local_dir = File.join(Rails.root, 'tmp',"gitlabhq-gitolite-#{Time.now.to_i}") + end + + def enable_automerge + self.configure do |git| + git.admin_all_repo + end + end + + private + def pull # create tmp dir @local_dir = File.join(Rails.root, 'tmp',"gitlabhq-gitolite-#{Time.now.to_i}") Dir.mkdir @local_dir - `git clone #{GitHost.admin_uri} #{@local_dir}/gitolite` + `git clone #{self.class.admin_uri} #{@local_dir}/gitolite` end def push diff --git a/config/initializers/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb similarity index 100% rename from config/initializers/grack_auth.rb rename to lib/gitlab/backend/grack_auth.rb diff --git a/lib/gitlab/git_host.rb b/lib/gitlab/git_host.rb deleted file mode 100644 index 76b2c7b1..00000000 --- a/lib/gitlab/git_host.rb +++ /dev/null @@ -1,17 +0,0 @@ -require File.join(Rails.root, "lib", "gitlab", "gitolite") - -module Gitlab - class GitHost - def self.system - Gitlab::Gitolite - end - - def self.admin_uri - Gitlab.config.git_host.admin_uri - end - - def self.url_to_repo(path) - Gitlab.config.ssh_path + "#{path}.git" - end - end -end diff --git a/lib/tasks/gitlab/enable_automerge.rake b/lib/tasks/gitlab/enable_automerge.rake index 07f80586..0a1a0fa7 100644 --- a/lib/tasks/gitlab/enable_automerge.rake +++ b/lib/tasks/gitlab/enable_automerge.rake @@ -2,9 +2,7 @@ namespace :gitlab do namespace :app do desc "GITLAB | Enable auto merge" task :enable_automerge => :environment do - Gitlab::GitHost.system.new.configure do |git| - git.admin_all_repo - end + Gitlab::Gitolite.new.enable_automerge Project.find_each do |project| if project.repo_exists? && !project.satellite.exists? diff --git a/lib/tasks/gitlab/gitolite_rebuild.rake b/lib/tasks/gitlab/gitolite_rebuild.rake index 5ab17606..534aa315 100644 --- a/lib/tasks/gitlab/gitolite_rebuild.rake +++ b/lib/tasks/gitlab/gitolite_rebuild.rake @@ -16,7 +16,7 @@ namespace :gitlab do task :update_keys => :environment do puts "Starting Key" Key.find_each(:batch_size => 100) do |key| - key.update_repository + Gitlab::Gitolite.new.set_key(key.identifier, key.key, key.projects) print '.' end puts "Done with keys" diff --git a/spec/observers/key_observer_spec.rb b/spec/observers/key_observer_spec.rb new file mode 100644 index 00000000..7f2a76a3 --- /dev/null +++ b/spec/observers/key_observer_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe KeyObserver do + before do + @key = double('Key', + identifier: 'admin_654654', + key: '== a vaild ssh key', + projects: [], + is_deploy_key: false + ) + + @gitolite = double('Gitlab::Gitolite', + set_key: true, + remove_key: true + ) + + @observer = KeyObserver.instance + @observer.stub(:git_host => @gitolite) + end + + context :after_save do + it do + @gitolite.should_receive(:set_key).with(@key.identifier, @key.key, @key.projects) + @observer.after_save(@key) + end + end + + context :after_destroy do + it do + @gitolite.should_receive(:remove_key).with(@key.identifier, @key.projects) + @observer.after_destroy(@key) + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9fb0ad7e..06909f39 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -27,6 +27,7 @@ RSpec.configure do |config| config.mock_with :rspec config.include LoginHelpers, type: :request + config.include GitoliteStub # 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 @@ -39,6 +40,8 @@ RSpec.configure do |config| end config.before do + stub_gitolite! + # !!! Observers disabled by default in tests ActiveRecord::Base.observers.disable(:all) # ActiveRecord::Base.observers.enable(:all) diff --git a/spec/support/gitolite_stub.rb b/spec/support/gitolite_stub.rb new file mode 100644 index 00000000..2a907f99 --- /dev/null +++ b/spec/support/gitolite_stub.rb @@ -0,0 +1,35 @@ +module GitoliteStub + def stub_gitolite! + stub_gitlab_gitolite + stub_gitolite_admin + end + + def stub_gitolite_admin + gitolite_repo = mock( + clean_permissions: true, + add_permission: true + ) + + gitolite_config = mock( + add_repo: true, + get_repo: gitolite_repo, + has_repo?: true + ) + + gitolite_admin = double( + 'Gitolite::GitoliteAdmin', + config: gitolite_config, + save: true, + ) + + Gitolite::GitoliteAdmin.stub(new: gitolite_admin) + + end + + def stub_gitlab_gitolite + gitlab_gitolite = Gitlab::Gitolite.new + Gitlab::Gitolite.stub(new: gitlab_gitolite) + gitlab_gitolite.stub(configure: ->() { yield(self) }) + gitlab_gitolite.stub(update_keys: true) + end +end diff --git a/spec/support/monkeypatch.rb b/spec/support/monkeypatch.rb index 855a31f0..04bbb6fb 100644 --- a/spec/support/monkeypatch.rb +++ b/spec/support/monkeypatch.rb @@ -1,14 +1,6 @@ # Stubbing Project <-> git host path # create project using Factory only class Project - def update_repository - true - end - - def destroy_repository - true - end - def path_to_repo File.join(Rails.root, "tmp", "tests", path) end @@ -18,22 +10,6 @@ class Project end end -class Key - def update_repository - true - end - - def repository_delete_key - true - end -end - -class UsersProject - def update_repository - true - end -end - class FakeSatellite def exists? true @@ -43,9 +19,3 @@ class FakeSatellite true end end - -class ProtectedBranch - def update_repository - true - end -end