diff --git a/features/push.feature b/features/push.feature new file mode 100644 index 00000000..0861a19f --- /dev/null +++ b/features/push.feature @@ -0,0 +1,47 @@ +Feature: push + Push commits to remote + + Scenario: Push available commits to remote + Given a mocked git configuration + And a puppet module "puppet-test" from "awesome" + And a file named "managed_modules.yml" with: + """ + --- + puppet-test: + namespace: awesome + """ + And a file named "modulesync.yml" with: + """ + --- + branch: modulesync + """ + And a git_base option appended to "modulesync.yml" for local tests + And I successfully run `msync reset` + And I cd to "modules/awesome/puppet-test" + And I run `touch hello` + And I run `git add hello` + And I run `git commit -m'Hello!'` + And I cd to "~" + Then the puppet module "puppet-test" from "awesome" should have no commits made by "Aruba" + When I successfully run `msync push --verbose` + Then the puppet module "puppet-test" from "awesome" should have 1 commit made by "Aruba" in branch "modulesync" + + @announce-output + Scenario: Push command without a branch sets + Given a basic setup with a puppet module "puppet-test" from "awesome" + When I run `msync push --verbose` + Then the exit status should be 1 + And the stderr should contain: + """ + Error: 'branch' option is missing, please set it in configuration or in command line. + """ + + Scenario: Report the need to clone repositories if sourcecode was not cloned before + Given a basic setup with a puppet module "puppet-test" from "awesome" + And the global option "branch" sets to "modulesync" + When I run `msync push --verbose` + Then the exit status should be 1 + And the stderr should contain: + """ + puppet-test: Repository must be locally available before trying to push + """ diff --git a/lib/modulesync.rb b/lib/modulesync.rb index 8b8906f7..33e2e417 100644 --- a/lib/modulesync.rb +++ b/lib/modulesync.rb @@ -217,4 +217,17 @@ def self.reset(cli_options) ) end end + + def self.push(cli_options) + @options = config_defaults.merge(cli_options) + + raise Thor::Error, "Error: 'branch' option is missing, please set it in configuration or in command line." if @options[:branch].nil? + puts "XXX: #{@options[:branch]}" + + managed_modules.each do |puppet_module| + puppet_module.repository.push branch: @options[:branch], remote_branch: @options[:remote_branch] + rescue ModuleSync::Error => e + raise Thor::Error, "#{puppet_module.given_name}: #{e.message}" + end + end end diff --git a/lib/modulesync/cli.rb b/lib/modulesync/cli.rb index 35d1d1c3..7ac62625 100644 --- a/lib/modulesync/cli.rb +++ b/lib/modulesync/cli.rb @@ -195,6 +195,28 @@ def reset ModuleSync.reset(config) end + desc 'push', 'Push all available commits from branch to remote' + option :configs, + :aliases => '-c', + :desc => 'The local directory or remote repository to define the list of managed modules,' \ + ' the file templates, and the default values for template variables.' + option :managed_modules_conf, + :desc => 'The file name to define the list of managed modules' + option :branch, + :aliases => '-b', + :desc => 'Branch name to push', + :default => CLI.defaults[:branch] + option :remote_branch, + :desc => 'Remote branch to push to (e.g. maintenance)' + + def push + config = { + :command => 'push', + }.merge(options) + config = Util.symbolize_keys(config) + ModuleSync.push(config) + end + desc 'hook', 'Activate or deactivate a git hook.' subcommand 'hook', ModuleSync::CLI::Hook end diff --git a/lib/modulesync/repository.rb b/lib/modulesync/repository.rb index 899a5274..b5813281 100644 --- a/lib/modulesync/repository.rb +++ b/lib/modulesync/repository.rb @@ -162,6 +162,17 @@ def submit_changes(files, options) true end + def push(branch:, remote_branch:) + raise ModuleSync::Error, "Repository must be locally available before trying to push" unless cloned? + + remote = 'origin' + remote_url = git.remote(remote).url + remote_branch ||= branch + puts "Push branch '#{branch}' to '#{remote_url}' (#{remote}/#{remote_branch})" + + git.push(remote, "#{branch}:#{remote_branch}", force: true) + end + # Needed because of a bug in the git gem that lists ignored files as # untracked under some circumstances # https://github.com/schacon/ruby-git/issues/130