diff options
-rw-r--r-- | .travis.yml | 1 | ||||
-rw-r--r-- | README.md | 9 | ||||
-rwxr-xr-x | bin/gitlab-projects | 2 | ||||
-rwxr-xr-x | bin/install | 2 | ||||
-rw-r--r-- | config.yml.example | 9 | ||||
-rw-r--r-- | lib/gitlab_config.rb | 4 | ||||
-rw-r--r-- | lib/gitlab_projects.rb | 35 | ||||
-rw-r--r-- | lib/gitlab_update.rb | 17 | ||||
-rw-r--r-- | spec/gitlab_projects_spec.rb | 33 |
9 files changed, 101 insertions, 11 deletions
diff --git a/.travis.yml b/.travis.yml index 6307280..0b677af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ branches: - 'master' rvm: - 1.9.3-p327 + - 2.0.0 before_script: - "cp config.yml.example config.yml" script: "bundle exec rspec spec" @@ -2,10 +2,9 @@ #### Code status -* [](http://ci.gitlab.org/projects/4?ref=master) - +* [](http://ci.gitlab.org/projects/4?ref=master) +* [](https://travis-ci.org/gitlabhq/gitlab-shell) * [](https://codeclimate.com/github/gitlabhq/gitlab-shell) - * [](https://coveralls.io/r/gitlabhq/gitlab-shell) @@ -34,6 +33,10 @@ Import repo ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git +Fork repo + + ./bin/gitlab-projects fork-project gitlab/gitlab-ci.git randx + ### Keys: diff --git a/bin/gitlab-projects b/bin/gitlab-projects index 95d0475..8803931 100755 --- a/bin/gitlab-projects +++ b/bin/gitlab-projects @@ -13,6 +13,8 @@ require_relative '../lib/gitlab_init' # # /bin/gitlab-projects mv-project gitlab/gitlab-ci.git randx/fork.git # +# /bin/gitlab-projects fork-project gitlab/gitlab-ci.git randx +# # /bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git # require File.join(ROOT_PATH, 'lib', 'gitlab_projects') diff --git a/bin/install b/bin/install index 6b23df8..f8c12f8 100755 --- a/bin/install +++ b/bin/install @@ -12,7 +12,9 @@ key_dir = File.dirname("#{config.auth_file}") commands = [ "mkdir -p #{config.repos_path}", "mkdir -p #{key_dir}", + "chmod 700 #{key_dir}", "touch #{config.auth_file}", + "chmod 600 #{config.auth_file}", "chmod -R ug+rwX,o-rwx #{config.repos_path}", "find #{config.repos_path} -type d -print0 | xargs -0 chmod g+s" ] diff --git a/config.yml.example b/config.yml.example index 6b0dbeb..26aa28c 100644 --- a/config.yml.example +++ b/config.yml.example @@ -14,3 +14,12 @@ repos_path: "/home/git/repositories" # File used as authorized_keys for gitlab user auth_file: "/home/git/.ssh/authorized_keys" + +# Redis settings used for pushing commit notices to gitlab +redis: + bin: /usr/bin/redis-cli + host: 127.0.0.1 + port: 6379 + # socket: /tmp/redis.socket # Only define this if you want to use sockets + namespace: resque:gitlab + diff --git a/lib/gitlab_config.rb b/lib/gitlab_config.rb index 6cfee5d..ac6cc19 100644 --- a/lib/gitlab_config.rb +++ b/lib/gitlab_config.rb @@ -22,4 +22,8 @@ class GitlabConfig def http_settings @config['http_settings'] ||= {} end + + def redis + @config['redis'] ||= {} + end end diff --git a/lib/gitlab_projects.rb b/lib/gitlab_projects.rb index aef343e..0b9bb8c 100644 --- a/lib/gitlab_projects.rb +++ b/lib/gitlab_projects.rb @@ -29,6 +29,7 @@ class GitlabProjects when 'rm-project'; rm_project when 'mv-project'; mv_project when 'import-project'; import_project + when 'fork-project'; fork_project else puts 'not allowed' false @@ -44,10 +45,7 @@ class GitlabProjects end def create_hooks_cmd - pr_hook_path = File.join(ROOT_PATH, 'hooks', 'post-receive') - up_hook_path = File.join(ROOT_PATH, 'hooks', 'update') - - "ln -s #{pr_hook_path} #{full_path}/hooks/post-receive && ln -s #{up_hook_path} #{full_path}/hooks/update" + create_hooks_to(full_path) end def rm_project @@ -84,4 +82,33 @@ class GitlabProjects FileUtils.mv(full_path, new_full_path) end + + def fork_project + new_namespace = ARGV.shift + + # destination namespace must be provided + return false unless new_namespace + + #destination namespace must exist + namespaced_path = File.join(repos_path, new_namespace) + return false unless File.exists?(namespaced_path) + + #a project of the same name cannot already be within the destination namespace + full_destination_path = File.join(namespaced_path, project_name.split('/')[-1]) + return false if File.exists?(full_destination_path) + + cmd = "cd #{namespaced_path} && git clone --bare #{full_path} && #{create_hooks_to(full_destination_path)}" + system(cmd) + end + + private + + def create_hooks_to(dest_path) + pr_hook_path = File.join(ROOT_PATH, 'hooks', 'post-receive') + up_hook_path = File.join(ROOT_PATH, 'hooks', 'update') + + "ln -s #{pr_hook_path} #{dest_path}/hooks/post-receive && ln -s #{up_hook_path} #{dest_path}/hooks/update" + + end + end diff --git a/lib/gitlab_update.rb b/lib/gitlab_update.rb index 8282897..a486ecc 100644 --- a/lib/gitlab_update.rb +++ b/lib/gitlab_update.rb @@ -3,9 +3,11 @@ require_relative 'gitlab_net' class GitlabUpdate def initialize(repo_path, key_id, refname) + config = GitlabConfig.new + @repo_path = repo_path.strip @repo_name = repo_path - @repo_name.gsub!(GitlabConfig.new.repos_path.to_s, "") + @repo_name.gsub!(config.repos_path.to_s, "") @repo_name.gsub!(/\.git$/, "") @repo_name.gsub!(/^\//, "") @@ -15,6 +17,8 @@ class GitlabUpdate @oldrev = ARGV[1] @newrev = ARGV[2] + + @redis = config.redis end def exec @@ -49,7 +53,16 @@ class GitlabUpdate end def update_redis - command = "env -i redis-cli rpush 'resque:gitlab:queue:post_receive' '{\"class\":\"PostReceive\",\"args\":[\"#{@repo_path}\",\"#{@oldrev}\",\"#{@newrev}\",\"#{@refname}\",\"#{@key_id}\"]}' > /dev/null 2>&1" + if !@redis.empty? && !@redis.has_key?("socket") + redis_command = "#{@redis['bin']} -h #{@redis['host']} -p #{@redis['port']}" + elsif !@redis.empty? && @redis.has_key?("socket") + redis_command = "#{@redis['bin']} -s #{@redis['socket']}" + else + # Default to old method of connecting to redis for users that haven't updated their configuration + redis_command = "env -i redis-cli" + end + + command = "#{redis_command} rpush '#{@redis['namespace']}:queue:post_receive' '{\"class\":\"PostReceive\",\"args\":[\"#{@repo_path}\",\"#{@oldrev}\",\"#{@newrev}\",\"#{@refname}\",\"#{@key_id}\"]}' > /dev/null 2>&1" system(command) end end diff --git a/spec/gitlab_projects_spec.rb b/spec/gitlab_projects_spec.rb index cbe1ab2..d0d6764 100644 --- a/spec/gitlab_projects_spec.rb +++ b/spec/gitlab_projects_spec.rb @@ -18,7 +18,7 @@ describe GitlabProjects do it { @gl_projects.project_name.should == repo_name } it { @gl_projects.instance_variable_get(:@command).should == 'add-project' } - it { @gl_projects.instance_variable_get(:@full_path).should == '/home/git/repositories/gitlab-ci.git' } + it { @gl_projects.instance_variable_get(:@full_path).should == "#{GitlabConfig.new.repos_path}/gitlab-ci.git" } end describe :add_project do @@ -77,6 +77,35 @@ describe GitlabProjects do end end + describe :fork_project do + let(:source_repo_name) { File.join('source-namespace', repo_name) } + let(:dest_repo) { File.join(tmp_repos_path, 'forked-to-namespace', repo_name) } + let(:gl_projects_fork) { build_gitlab_projects('fork-project', source_repo_name, 'forked-to-namespace') } + let(:gl_projects_import) { build_gitlab_projects('import-project', source_repo_name, 'https://github.com/randx/six.git') } + + before do + gl_projects_import.exec + end + + it "should not fork into a namespace that doesn't exist" do + gl_projects_fork.exec.should be_false + end + + it "should fork the repo" do + # create destination namespace + FileUtils.mkdir_p(File.join(tmp_repos_path, 'forked-to-namespace')) + gl_projects_fork.exec.should be_true + File.exists?(dest_repo).should be_true + File.exists?(File.join(dest_repo, '/hooks/update')).should be_true + File.exists?(File.join(dest_repo, '/hooks/post-receive')).should be_true + end + + it "should not fork if a project of the same name already exists" do + #trying to fork again should fail as the repo already exists + gl_projects_fork.exec.should be_false + end + end + describe :exec do it 'should puts message if unknown command arg' do gitlab_projects = build_gitlab_projects('edit-project', repo_name) @@ -89,7 +118,7 @@ describe GitlabProjects do argv(*args) gl_projects = GitlabProjects.new gl_projects.stub(repos_path: tmp_repos_path) - gl_projects.stub(full_path: tmp_repo_path) + gl_projects.stub(full_path: File.join(tmp_repos_path, gl_projects.project_name)) gl_projects end |