lib/vendorificator/cli.rb in vendorificator-0.5.git.v0.4.0.17.g26d50d8 vs lib/vendorificator/cli.rb in vendorificator-0.5.git.v0.4.0.60.g9c35209

- old
+ new

@@ -12,47 +12,44 @@ require 'thor' require 'vendorificator' module Vendorificator class CLI < Thor + VERBOSITY_LEVELS = {1 => :quiet, 2 => :default, 3 => :chatty, 9 => :debug} attr_reader :environment check_unknown_options! :except => [:git, :diff, :log] stop_on_unknown_option! :git, :diff, :log default_task :help - class_option :file, :aliases => '-f', :type => :string, - :banner => 'PATH' - class_option :debug, :aliases => '-d', :type => :boolean, :default => false - class_option :quiet, :aliases => '-q', :type => :boolean, :default => false + class_option :file, :aliases => '-f', :type => :string, :banner => 'PATH' class_option :modules, :aliases => '-m', :type => :string, :default => '', :banner => 'mod1,mod2,...,modN', :desc => 'Run only for specified modules (name or path, comma separated)' class_option :version, :type => :boolean - class_option :help, :aliases => '-h', :type => :boolean + class_option :verbose, :aliases => '-v', :type => :numeric - def initialize(args=[], options={}, config={}) + def initialize(args = [], options = {}, config = {}) super + parse_options if self.options[:debug] MiniGit.debug = true end if self.options[:version] say "Vendorificator #{Vendorificator::VERSION}" exit end - if self.options[:help] && config[:current_task].name != 'help' - invoke :help, [ config[:current_task].name ] - exit - end + @environment = Vendorificator::Environment.new( + shell, + VERBOSITY_LEVELS[self.options[:verbose]] || :default, + self.options[:file] + ) - @environment = Vendorificator::Environment.new(self.options[:file]) - environment.shell = shell - class << shell # Make say_status always say it. def quiet? false end @@ -60,20 +57,41 @@ end desc :sync, "Download new or updated vendor files" method_option :update, :type => :boolean, :default => false def sync + say_status 'DEPRECATED', 'Using vendor sync is deprecated and will be removed in future versions. Use vendor install or vendor update instead.', :yellow environment.sync options.merge(:modules => modules) rescue DirtyRepoError fail! 'Repository is not clean.' + rescue MissingVendorfileError + fail! "Vendorfile not found. Vendorificator needs to run in the directory containing Vendorfile or config/vendor.rb." end + desc :install, "Download and install new or updated vendor files" + def install(*modules) + environment.sync options.merge(:modules => modules) + rescue DirtyRepoError + fail! 'Repository is not clean.' + end + + desc :update, "Update installed vendor files" + def update(*modules) + environment.sync options.merge(:modules => modules, :update => true) + rescue DirtyRepoError + fail! 'Repository is not clean.' + end + desc "status", "List known vendor modules and their status" method_option :update, :type => :boolean, :default => false def status - say_status 'WARNING', 'Git repository is not clean', :red unless environment.clean? environment.config[:use_upstream_version] = options[:update] + environment.load_vendorfile + + say_status 'DEPRECATED', 'Using vendor status is deprecated and will be removed in future versions', :yellow + say_status 'WARNING', 'Git repository is not clean', :red unless environment.clean? + environment.each_vendor_instance(*modules) do |mod| status_line = mod.to_s updatable = mod.updatable? if updatable @@ -85,76 +103,97 @@ end say_status( mod.status.to_s.gsub('_', ' '), status_line, ( mod.status == :up_to_date ? :green : :yellow ) ) end + rescue MissingVendorfileError + fail! "Vendorfile not found. Vendorificator needs to run in the directory containing Vendorfile or config/vendor.rb." end desc 'info MODULE', "Show module information" def info(mod_name) environment.info mod_name, options + rescue MissingVendorfileError + fail! "Vendorfile not found. Vendorificator needs to run in the directory containing Vendorfile or config/vendor.rb." end + desc :list, 'List all currently installed modules' + def list + environment.list + end + + desc :outdated, 'List all currently installed modules' + def outdated + environment.outdated + end + desc :pull, "Pull upstream branches from a remote repository" method_option :remote, :aliases => ['-r'], :default => nil method_option :dry_run, :aliases => ['-n'], :default => false, :type => :boolean def pull environment.pull_all options rescue DirtyRepoError fail! 'Repository is not clean.' + rescue MissingVendorfileError + fail! "Vendorfile not found. Vendorificator needs to run in the directory containing Vendorfile or config/vendor.rb." end desc :push, "Push local changes back to the remote repository" method_option :remote, :aliases => ['-r'], :default => nil def push environment.push options rescue DirtyRepoError fail! 'Repository is not clean.' + rescue MissingVendorfileError + fail! "Vendorfile not found. Vendorificator needs to run in the directory containing Vendorfile or config/vendor.rb." end - desc "git GIT_COMMAND [GIT_ARGS [...]]", - "Run a git command for specified modules" + desc "git GIT_COMMAND [MODULE [MODULE ...]] [-- GIT_OPTIONS]", + "Run a git command for specified module(s)" long_desc <<EOF Run a git command for specified modules. Within GIT_ARGS arguments, you can use @MERGED@ and @PATH@ tags, which will be substituted with module's most recently merged revision and full path of its work directory. The 'diff' and 'log' commands are simple aliases for 'git' command. Examples: - vendor git log @MERGED@..HEAD -- @PATH@ # basic 'vendor log' - vendor git diff --stat @MERGED@ -- @PATH@ # 'vendor diff', as diffstat + vendor git log my_module -- @MERGED@..HEAD -- @PATH@ # basic 'vendor log' + vendor git diff module1 module2 -- --stat @MERGED@ -- @PATH@ # 'vendor diff', as diffstat EOF def git(command, *args) + modules, git_options = split_git_options(args) environment.each_vendor_instance(*modules) do |mod| unless mod.merged - say_status 'unmerged', mod.to_s, :red unless options[:only_changed] + say_status 'unmerged', mod.to_s, :red next end - actual_args = args.dup.map do |arg| + actual_args = git_options.dup.map do |arg| arg. gsub('@MERGED@', mod.merged). gsub('@PATH@', mod.work_dir) end say_status command, mod.to_s output = environment.git.git(command, *actual_args) end end - desc "diff [OPTIONS] [GIT OPTIONS]", + desc "diff [MODULE [MODULE ...]] [-- GIT_OPTIONS]", "Show differences between work tree and upstream module(s)" def diff(*args) - invoke :git, %w'diff' + args + %w'@MERGED@ -- @PATH@' + modules, git_options = split_git_options(args) + invoke :git, %w'diff' + modules + %w'--' + git_options + %w'@MERGED@ -- @PATH@' end - desc "log [OPTIONS] [GIT OPTIONS]", + desc "log [MODULE [MODULE ...]] [-- GIT_OPTIONS]", "Show git log of commits added to upstream module(s)" def log(*args) - invoke :git, %w'log' + args + %w'@MERGED@..HEAD -- @PATH@' + modules, git_options = split_git_options(args) + invoke :git, %w'log' + modules + %w'--' + git_options + %w'@MERGED@..HEAD -- @PATH@' end desc :pry, 'Pry into the binding', :hide => true def pry require 'pry' @@ -182,24 +221,39 @@ end end private + # Private: Parses general vendorificator options. + # + # Returns nothing. + def parse_options + if options[:version] + say "Vendorificator #{Vendorificator::VERSION}" + exit + end + + if options[:verbose] && (!VERBOSITY_LEVELS.keys.include? options[:verbose]) + fail! "Unknown verbosity level: #{options[:verbose].inspect}" + end + end + def split_git_options(args) - case i = args.index('--git-options') - when nil then [ args, [] ] - when 0 then [ [], args[1..-1] ] - else [ args[0..(i-1)], args[(i+1)..-1] ] + case i = args.index('--') + when nil then [args, []] + when 0 then [[], args[1..-1]] + else [args[0..(i - 1)], args[(i + 1)..-1]] end end def modules + say_status 'DEPRECATED', 'Using --modules option is deprecated and will be removed in future versions.', :yellow unless options[:modules].empty? options[:modules].split(',').map(&:strip) end - def fail!(message, exception_message='I give up.') + def fail!(message, exception_message = 'I give up.') say_status('FATAL', message, :red) - raise Thor::Error, 'I give up.' + raise Thor::Error, exception_message end end end