diff --git a/README.md b/README.md index 5740f3f3f8..14fa657678 100644 --- a/README.md +++ b/README.md @@ -18,27 +18,31 @@ __Requires ruby 1.9+__ ./bin/install -### Check +### Check ./bin/check ### Repos: - + Add repo ./bin/gitlab-projects add-project gitlab/gitlab-ci.git -Remove repo +Add repo from template + + ./bin/gitlab-projects add-init-project gitlab/gitlab-ci.git /home/git/gitlab-templates/1/template-name template-name "Administrator" "admin@local.host" + +Remove repo ./bin/gitlab-projects rm-project gitlab/gitlab-ci.git -Import repo +Import repo + + # Default timeout is 2 minutes + ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git - # Default timeout is 2 minutes - ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git - # Override timeout in seconds ./bin/gitlab-projects import-project randx/six.git https://github.com/randx/six.git 90 @@ -60,14 +64,14 @@ Remove branch Create tag - ./bin/gitlab-projects create-tag gitlab/gitlab-ci.git v3.0.0 3-0-stable + ./bin/gitlab-projects create-tag gitlab/gitlab-ci.git v3.0.0 3-0-stable Remove tag ./bin/gitlab-projects rm-tag gitlab/gitlab-ci.git v3.0.0 -### Keys: +### Keys: Add key diff --git a/bin/gitlab-projects b/bin/gitlab-projects index 01de20b9ef..9cde5d1a2d 100755 --- a/bin/gitlab-projects +++ b/bin/gitlab-projects @@ -9,6 +9,8 @@ require_relative '../lib/gitlab_init' # Ex. # /bin/gitlab-projects add-project gitlab/gitlab-ci.git # +# ./bin/gitlab-projects add-init-project gitlab/gitlab-ci.git /home/git/gitlab-templates/1/template-name template-name "Administrator" "admin@local.host" +# # /bin/gitlab-projects rm-project gitlab/gitlab-ci.git # # /bin/gitlab-projects mv-project gitlab/gitlab-ci.git randx/fork.git diff --git a/lib/gitlab_config.rb b/lib/gitlab_config.rb index ad15247976..898a95bb64 100644 --- a/lib/gitlab_config.rb +++ b/lib/gitlab_config.rb @@ -15,6 +15,10 @@ def auth_file @config['auth_file'] ||= "/home/git/.ssh/authorized_keys" end + def tmp_init_path + @config['tmp_init_path'] ||= "home/git/gitlab-templates/tmp" + end + def gitlab_url @config['gitlab_url'] ||= "http://localhost/" end diff --git a/lib/gitlab_projects.rb b/lib/gitlab_projects.rb index 4067d1346d..4eb63e4eed 100644 --- a/lib/gitlab_projects.rb +++ b/lib/gitlab_projects.rb @@ -1,10 +1,13 @@ require 'fileutils' require 'timeout' +require 'pathname' require_relative 'gitlab_config' require_relative 'gitlab_logger' class GitlabProjects + attr_reader :gitlab_config + # Project name is a directory name for repository with .git at the end # It may be namespaced or not. Like repo.git or gitlab/repo.git attr_reader :project_name @@ -24,9 +27,10 @@ def self.create_hooks(path) end def initialize + @gitlab_config = GitlabConfig.new @command = ARGV.shift @project_name = ARGV.shift - @repos_path = GitlabConfig.new.repos_path + @repos_path = @gitlab_config.repos_path @full_path = File.join(@repos_path, @project_name) end @@ -37,6 +41,7 @@ def exec when 'create-tag'; create_tag when 'rm-tag'; rm_tag when 'add-project'; add_project + when 'add-init-project'; add_init_project when 'rm-project'; rm_project when 'mv-project'; mv_project when 'import-project'; import_project @@ -84,6 +89,58 @@ def add_project system(*cmd) && self.class.create_hooks(full_path) end + def add_init_project + project_name_tmp = @project_name.gsub('.git', '') + project_template_path = ARGV.shift + project_template_name = ARGV.shift + current_user_name = ARGV.shift + current_user_email = ARGV.shift + project_template_tmp_path = File.join(@gitlab_config.tmp_init_path,project_name_tmp) + + #set git user and email + cmd = %W(git config --global user.name '#{current_user_name}') + system(*cmd) + cmd = %W(git config --global user.email '#{current_user_email}') + system(*cmd) + + # create directory + $logger.info "Adding project #{@project_name} at <#{full_path}> and init it with template path #{project_template_path}" + FileUtils.mkdir_p(full_path, mode: 0770) + + # init the repo with bare option + cmd = %W(git --git-dir=#{full_path} init --bare) + system(*cmd) + + # create tmp directories + FileUtils.mkdir_p(gitlab_config.tmp_init_path, mode: 0700) + FileUtils.mkdir_p(project_template_tmp_path, mode: 0700) + + # copy all files from project-template into the tmp directory + FileUtils.cd(project_template_tmp_path) do + cmd = %W(git init) + system(*cmd) + + FileUtils.cp_r(Dir.glob("#{project_template_path}/*"), "./") + + cmd = %W(git add .) + system(*cmd) + + cmd = "git commit -m 'initial commit by GitLabHQ from template \"#{project_template_name}\"'" + system(*cmd) + + cmd = %W(git remote add origin #{full_path}) + system(*cmd) + + cmd = %W(git push -u origin master) + system(*cmd) + + cmd = %W(rm -rf #{project_template_tmp_path}) + system(*cmd) + end + + self.class.create_hooks(full_path) + end + def rm_project $logger.info "Removing project #{@project_name} from <#{full_path}>." FileUtils.rm_rf(full_path) diff --git a/spec/gitlab_projects_spec.rb b/spec/gitlab_projects_spec.rb index 64cb63e9e7..c4d7b46779 100644 --- a/spec/gitlab_projects_spec.rb +++ b/spec/gitlab_projects_spec.rb @@ -4,11 +4,14 @@ describe GitlabProjects do before do FileUtils.mkdir_p(tmp_repos_path) + FileUtils.mkdir_p(tmp_repos_templates_path) + FileUtils.touch(File.join(tmp_repos_templates_path, 'REAMDE.md')) $logger = double('logger').as_null_object end after do FileUtils.rm_rf(tmp_repos_path) + FileUtils.rm_rf(tmp_repos_templates_path) end describe :initialize do @@ -113,6 +116,54 @@ end end + describe :add_init_project do + let(:gl_projects) { build_gitlab_projects('add-init-project', repo_name_from_template, tmp_repos_templates_path, 'rspec test template', 'Administrator', 'admin@local.host') } + + it "should create a directory" do + gl_projects.stub(system: true) + GitlabProjects.stub(create_hooks: true) + gl_projects.exec + File.exists?(tmp_repo_path_from_template).should be_true + end + + it "should receive valid cmds" do + valid_cmd_user_name = ["git", "config", "--global", "user.name", "'Administrator'"] + gl_projects.should_receive(:system).with(*valid_cmd_user_name).and_return(true) + + valid_cmd_user_mail = ["git", "config", "--global", "user.email", "'admin@local.host'"] + gl_projects.should_receive(:system).with(*valid_cmd_user_mail).and_return(true) + + valid_init_bare_cmd = ["git", "--git-dir=#{tmp_repo_path_from_template}", "init", "--bare"] + gl_projects.should_receive(:system).with(*valid_init_bare_cmd).and_return(true) + + valid_init_cmd = ["git", "init"] + gl_projects.should_receive(:system).with(*valid_init_cmd).and_return(true) + + valid_add_cmd = ["git", "add", "."] + gl_projects.should_receive(:system).with(*valid_add_cmd).and_return(true) + + valid_commit_cmd = ["git commit -m 'initial commit by GitLabHQ from template \"rspec test template\"'"] + gl_projects.should_receive(:system).with(*valid_commit_cmd).and_return(true) + + valid_add_origin_cmd = ["git", "remote", "add", "origin", "#{tmp_repo_path_from_template}"] + gl_projects.should_receive(:system).with(*valid_add_origin_cmd).and_return(true) + + valid_push_cmd = ["git", "push", "-u", "origin", "master"] + gl_projects.should_receive(:system).with(*valid_push_cmd).and_return(true) + + valid_clean_up_cmd = ["rm", "-rf", "#{tmp_init_path}"] + gl_projects.should_receive(:system).with(*valid_clean_up_cmd).and_return(true) + + GitlabProjects.should_receive(:create_hooks).with(tmp_repo_path_from_template) + gl_projects.exec + end + + it "should log an add-init-project event" do + $logger.should_receive(:info).with("Adding project #{repo_name_from_template} at <#{tmp_repo_path_from_template}> and init it with template path #{tmp_repos_templates_path}") + gl_projects.exec + end + end + describe :mv_project do let(:gl_projects) { build_gitlab_projects('mv-project', repo_name, 'repo.git') } let(:new_repo_path) { File.join(tmp_repos_path, 'repo.git') } @@ -323,14 +374,30 @@ def tmp_repos_path File.join(ROOT_PATH, 'tmp', 'repositories') end + def tmp_repos_templates_path + File.join(ROOT_PATH, 'tmp', 'templates') + end + def tmp_repo_path File.join(tmp_repos_path, repo_name) end + def tmp_repo_path_from_template + File.join(tmp_repos_path, repo_name_from_template) + end + def repo_name 'gitlab-ci.git' end + def repo_name_from_template + 'gitlab-ci-from-template.git' + end + + def tmp_init_path + File.join(GitlabConfig.new.tmp_init_path, repo_name_from_template.gsub('.git', '')) + end + def capture_in_tmp_repo(cmd) IO.popen([*cmd, {chdir: tmp_repo_path}]).read.strip end