提交 26d9c920 编写于 作者: M Mislav Marohnić

preserve global flags to git such as `--bare` and `--git-dir=/some/path`

Supply these global flags to subcommands. Closes #69
上级 35303130
......@@ -54,7 +54,7 @@ module Hub
# Array of `executable` followed by all args suitable as arguments
# for `exec` or `system` calls.
def to_exec(args = self)
[*executable].concat args
Array(executable) + args
end
# All the words (as opposed to flags) contained in this argument
......@@ -80,6 +80,11 @@ module Hub
chained? or self != @original_args
end
def has_flag?(*flags)
pattern = flags.flatten.map { |f| Regexp.escape(f) }.join('|')
!grep(/^#{pattern}(?:=|$)/).empty?
end
private
def normalize_callback(cmd_or_args, args, block)
......
......@@ -42,8 +42,10 @@ module Hub
API_CREATE = 'http://github.com/api/v2/yaml/repos/create'
def run(args)
slurp_global_flags(args)
# Hack to emulate git-style
args.unshift 'help' if args.grep(/^[^-]|version|exec-path$|html-path/).empty?
args.unshift 'help' if args.empty?
cmd = args[0]
expanded_args = expand_alias(cmd)
......@@ -493,13 +495,13 @@ module Hub
# $ hub help
# (print improved help text)
def help(args)
command = args.grep(/^[^-]/)[1]
command = args.words[1]
if command == 'hub'
puts hub_manpage
exit
elsif command.nil? && args.grep(/^--?a/).empty?
ENV['GIT_PAGER'] = '' if args.grep(/^-{1,2}p/).empty? # Use `cat`.
elsif command.nil? && !args.has_flag?('-a', '--all')
ENV['GIT_PAGER'] = '' unless args.has_flag?('-p', '--paginate') # Use `cat`.
puts improved_help_text
exit
end
......@@ -556,6 +558,50 @@ help
# from the command line.
#
# Extract global flags from the front of the arguments list.
# Makes sure important ones are supplied for calls to subcommands.
#
# Known flags are:
# --version --exec-path=<path> --html-path
# -p|--paginate|--no-pager --no-replace-objects
# --bare --git-dir=<path> --work-tree=<path>
# -c name=value --help
#
# Special: `--version`, `--help` are replaced with "version" and "help".
# Ignored: `--exec-path`, `--html-path` are kept in args list untouched.
def slurp_global_flags(args)
flags = %w[ -c -p --paginate --no-pager --no-replace-objects --bare --version --help ]
flags2 = %w[ --exec-path= --git-dir= --work-tree= ]
# flags that should be present in subcommands, too
globals = []
# flags that apply only to main command
locals = []
while args[0] && (flags.include?(args[0]) || flags2.any? {|f| args[0].index(f) == 0 })
flag = args.shift
case flag
when '--version', '--help'
args.unshift flag.sub('--', '')
when '-c'
# slurp one additional argument
config_pair = args.shift
# add configuration to our local cache
key, value = config_pair.split('=', 2)
Context::GIT_CONFIG["config #{key}"] = value.to_s
globals << flag << config_pair
when '-p', '--paginate', '--no-pager'
locals << flag
else
globals << flag
end
end
Context::GIT_CONFIG.executable = Array(Context::GIT_CONFIG.executable).concat(globals)
args.executable = Array(args.executable).concat(globals).concat(locals)
end
# Handles common functionality of browser commands like `browse`
# and `compare`. Yields a block that returns params for `github_url`.
def browse_command(args)
......
require 'shellwords'
module Hub
# Provides methods for inspecting the environment, such as GitHub user/token
# settings, repository info, and similar.
module Context
private
class ShellOutCache < Hash
attr_accessor :executable
def initialize(executable = nil, &block)
super(&block)
@executable = executable
end
def to_exec(args)
args = args.shellsplit if args.respond_to? :shellsplit
Array(executable) + Array(args)
end
end
# Caches output when shelling out to git
GIT_CONFIG = Hash.new do |cache, cmd|
result = %x{git #{cmd}}.chomp
GIT_CONFIG = ShellOutCache.new(ENV['GIT'] || 'git') do |cache, cmd|
result = %x{#{cache.to_exec(cmd).shelljoin}}.chomp
cache[cmd] = $?.success? && !result.empty? ? result : nil
end
......
#!/bin/sh
if [ "$1" = "--version" ]; then
if [ "$1" = "--version" ] || [ "$1" = "version" ]; then
echo "git version 1.7.0.4"
elif [ "$1" = "--exec-path" ]; then
echo "/usr/lib/git-core"
......
......@@ -30,6 +30,8 @@ class HubTest < Test::Unit::TestCase
Hub::Context::DIRNAME.replace 'hub'
Hub::Context::REMOTES.clear
Hub::Context::GIT_CONFIG.executable = 'git'
@git = Hub::Context::GIT_CONFIG.replace(Hash.new { |h, k|
unless k.index('config alias.') == 0
raise ArgumentError, "`git #{k}` not stubbed"
......@@ -557,7 +559,7 @@ class HubTest < Test::Unit::TestCase
def test_exec_path_arg
out = hub('--exec-path=/home/wombat/share/my-l33t-git-core')
assert_equal Hub::Commands.improved_help_text, hub("")
assert_equal Hub::Commands.improved_help_text, out
end
def test_html_path
......@@ -760,6 +762,12 @@ config
assert_command "browse", "open https://github.com/my/repo"
end
def test_global_flags_preserved
cmd = '--no-pager --bare -c core.awesome=true -c name=value --git-dir=/srv/www perform'
assert_command cmd, 'git --bare -c core.awesome=true -c name=value --git-dir=/srv/www --no-pager perform'
assert_equal %w[git --bare -c core.awesome=true -c name=value --git-dir=/srv/www], @git.executable
end
protected
def stub_github_user(name)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册