lib/modulesync/cli.rb in modulesync-2.2.0 vs lib/modulesync/cli.rb in modulesync-2.3.0
- old
+ new
@@ -5,43 +5,46 @@
require 'modulesync/constants'
require 'modulesync/util'
module ModuleSync
module CLI
+ def self.prepare_options(cli_options, **more_options)
+ options = CLI.defaults
+ options.merge! Util.symbolize_keys(cli_options)
+ options.merge! more_options
+
+ Util.symbolize_keys options
+ end
+
def self.defaults
@defaults ||= Util.symbolize_keys(Util.parse_config(Constants::MODULESYNC_CONF_FILE))
end
class Hook < Thor
- class_option :project_root,
- :aliases => '-c',
- :desc => 'Path used by git to clone modules into. Defaults to "modules"',
- :default => CLI.defaults[:project_root] || 'modules'
- class_option :hook_args,
- :aliases => '-a',
- :desc => 'Arguments to pass to msync in the git hook'
-
+ option :hook_args,
+ :aliases => '-a',
+ :desc => 'Arguments to pass to msync in the git hook'
+ option :branch,
+ :aliases => '-b',
+ :desc => 'Branch name to pass to msync in the git hook',
+ :default => CLI.defaults[:branch]
desc 'activate', 'Activate the git hook.'
def activate
- config = { :command => 'hook' }.merge(options)
- config[:hook] = 'activate'
- ModuleSync.hook(config)
+ ModuleSync.hook CLI.prepare_options(options, hook: 'activate')
end
desc 'deactivate', 'Deactivate the git hook.'
def deactivate
- config = { :command => 'hook' }.merge(options)
- config[:hook] = 'deactivate'
- ModuleSync.hook(config)
+ ModuleSync.hook CLI.prepare_options(options, hook: 'deactivate')
end
end
class Base < Thor
class_option :project_root,
:aliases => '-c',
:desc => 'Path used by git to clone modules into.',
- :default => CLI.defaults[:project_root] || 'modules'
+ :default => CLI.defaults[:project_root]
class_option :git_base,
:desc => 'Specify the base part of a git URL to pull from',
:default => CLI.defaults[:git_base] || 'git@github.com:'
class_option :namespace,
:aliases => '-n',
@@ -51,25 +54,25 @@
:aliases => '-f',
:desc => 'A regular expression to select repositories to update.'
class_option :negative_filter,
:aliases => '-x',
:desc => 'A regular expression to skip repositories.'
- class_option :branch,
- :aliases => '-b',
- :desc => 'Branch name to make the changes in.' \
- ' Defaults to the default branch of the upstream repository, but falls back to "master".',
- :default => CLI.defaults[:branch]
+ class_option :verbose,
+ :aliases => '-v',
+ :desc => 'Verbose mode',
+ :type => :boolean,
+ :default => false
desc 'update', 'Update the modules in managed_modules.yml'
option :message,
:aliases => '-m',
:desc => 'Commit message to apply to updated modules. Required unless running in noop mode.',
:default => CLI.defaults[:message]
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.'
+ ' 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 :remote_branch,
:aliases => '-r',
:desc => 'Remote branch name to push the changes to. Defaults to the branch name.',
@@ -102,11 +105,11 @@
:type => :array,
:desc => 'Labels to add to the pull/merge request',
:default => CLI.defaults[:pr_labels] || []
option :pr_target_branch,
:desc => 'Target branch for the pull/merge request',
- :default => CLI.defaults[:pr_target_branch] || 'master'
+ :default => CLI.defaults[:pr_target_branch]
option :offline,
:type => :boolean,
:desc => 'Do not run any Git commands. Allows the user to manage Git outside of ModuleSync.',
:default => false
option :bump,
@@ -128,20 +131,111 @@
:default => CLI.defaults[:pre_commit_script]
option :fail_on_warnings,
:type => :boolean,
:aliases => '-F',
:desc => 'Produce a failure exit code when there are warnings' \
- ' (only has effect when --skip_broken is enabled)',
+ ' (only has effect when --skip_broken is enabled)',
:default => false
-
+ option :branch,
+ :aliases => '-b',
+ :desc => 'Branch name to make the changes in.' \
+ ' Defaults to the default branch of the upstream repository, but falls back to "master".',
+ :default => CLI.defaults[:branch]
def update
- config = { :command => 'update' }.merge(options)
- config = Util.symbolize_keys(config)
+ config = CLI.prepare_options(options)
raise Thor::Error, 'No value provided for required option "--message"' unless config[:noop] \
|| config[:message] \
|| config[:offline]
- config[:git_opts] = { 'amend' => config[:amend], 'force' => config[:force] }
- ModuleSync.update(config)
+
+ ModuleSync.update config
+ end
+
+ desc 'execute [OPTIONS] -- COMMAND..', 'Execute the command in each managed modules'
+ long_desc <<~DESC
+ Execute the command in each managed modules.
+
+ COMMAND can be an absolute or a relative path.
+
+ To ease running local commands, a relative path is expanded with the current user directory but only if the target file exists.
+
+ Example: `msync exec custom-scripts/true` will run "$PWD/custom-scripts/true" in each repository.
+
+ As side effect, you can shadow system binary if a local file is present:
+ \x5 `msync exec true` will run "$PWD/true", not `/bin/true` if "$PWD/true" exists.
+ DESC
+
+ 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 make the changes in.',
+ :default => CLI.defaults[:branch]
+ option :fail_fast,
+ :type => :boolean,
+ :desc => 'Abort the run after a command execution failure',
+ :default => CLI.defaults[:fail_fast].nil? ? true : CLI.defaults[:fail_fast]
+ def execute(*command_args)
+ raise Thor::Error, 'COMMAND is a required argument' if command_args.empty?
+
+ ModuleSync.execute CLI.prepare_options(options, command_args: command_args)
+ end
+
+ desc 'reset', 'Reset local repositories to a well-known state'
+ long_desc <<~DESC
+ Reset local repository to a well-known state:
+ \x5 * Switch local repositories to specified branch
+ \x5 * Fetch and prune repositories unless running with `--offline` option
+ \x5 * Hard-reset any changes to specified source branch, technically any git refs, e.g. `main`, `origin/wip`
+ \x5 * Clean all extra local files
+
+ Note: If a repository is not already cloned, it will operate the following to reach to well-known state:
+ \x5 * Clone the repository
+ \x5 * Switch to specified branch
+ DESC
+ 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 make the changes in.',
+ :default => CLI.defaults[:branch]
+ option :offline,
+ :type => :boolean,
+ :desc => 'Only proceed local operations',
+ :default => false
+ option :source_branch,
+ :desc => 'Branch to reset from (e.g. origin/wip)'
+ def reset
+ ModuleSync.reset CLI.prepare_options(options)
+ 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
+ ModuleSync.push CLI.prepare_options(options)
+ end
+
+ desc 'clone', 'Clone repositories that need to'
+ def clone
+ ModuleSync.clone CLI.prepare_options(options)
end
desc 'hook', 'Activate or deactivate a git hook.'
subcommand 'hook', ModuleSync::CLI::Hook
end