git-duet 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -0
- data/.simplecov +1 -0
- data/.travis.yml +4 -6
- data/Gemfile +1 -0
- data/LICENSE +1 -1
- data/README.md +1 -0
- data/Rakefile +7 -1
- data/bin/git-duet +2 -1
- data/bin/git-duet-commit +2 -1
- data/bin/git-duet-install-hook +2 -1
- data/bin/git-duet-pre-commit +2 -1
- data/bin/git-solo +2 -1
- data/git-duet.gemspec +5 -7
- data/lib/git-duet.rb +1 -0
- data/lib/git/duet.rb +4 -4
- data/lib/git/duet/author_mapper.rb +14 -10
- data/lib/git/duet/cli.rb +22 -26
- data/lib/git/duet/command_methods.rb +44 -12
- data/lib/git/duet/commit_command.rb +20 -15
- data/lib/git/duet/config.rb +11 -0
- data/lib/git/duet/duet_command.rb +11 -5
- data/lib/git/duet/install_hook_command.rb +14 -10
- data/lib/git/duet/pre_commit_command.rb +11 -8
- data/lib/git/duet/script_die_error.rb +2 -0
- data/lib/git/duet/solo_command.rb +21 -7
- data/lib/git/duet/version.rb +3 -1
- data/spec/integration/end_to_end_spec.rb +74 -54
- data/spec/lib/git/duet/author_mapper_spec.rb +45 -42
- data/spec/lib/git/duet/cli_spec.rb +20 -19
- data/spec/lib/git/duet/command_methods_spec.rb +21 -11
- data/spec/lib/git/duet/duet_command_spec.rb +75 -51
- data/spec/lib/git/duet/pre_commit_command_spec.rb +19 -14
- data/spec/lib/git/duet/solo_command_spec.rb +118 -73
- data/spec/spec_helper.rb +3 -16
- data/spec/support/author_mapper_helper.rb +22 -18
- metadata +25 -41
- data/.rbenv-version +0 -1
- data/bin/git-duet-pre-commit-tk +0 -3
- data/lib/git/duet/key_error.rb +0 -3
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 46323bd5392d627ae8bed46e4cd89f2bf8803885
|
4
|
+
data.tar.gz: b78bc212d1b95a47e28c8337b19cd5b3ebb38072
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 28d686c6d459b9104b5c9279e98cc49b6119461bf6b19cf88b41c71b053465fc8c2bb8e66cc856571fc909206a6e4ea7946d2b0f090ae29c38ce50761635d5ba
|
7
|
+
data.tar.gz: ec5038f060832c4f7ed5ad35243ba9ef43498a07eff2722ac2d65e2846c10460d2c5fe879e1750dc1e913d624ebfdb3ce43732345534a3f86b5ce22b1003f03c
|
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p247
|
data/.simplecov
CHANGED
data/.travis.yml
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
---
|
1
2
|
language: ruby
|
2
3
|
env:
|
3
4
|
global:
|
@@ -6,12 +7,9 @@ matrix:
|
|
6
7
|
allow_failures:
|
7
8
|
- rvm: jruby-19mode
|
8
9
|
rvm:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
- ree
|
13
|
-
script:
|
14
|
-
- bundle exec rake spec --trace
|
10
|
+
- 1.9.3
|
11
|
+
- 2.0.0
|
12
|
+
- jruby-19mode
|
15
13
|
notifications:
|
16
14
|
email:
|
17
15
|
recipients:
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
|
+
# vim:fileencoding=utf-8
|
2
3
|
require "bundler/gem_tasks"
|
3
4
|
|
4
5
|
require 'rspec/core/rake_task'
|
5
6
|
|
7
|
+
desc 'Run rubocop'
|
8
|
+
task :rubocop do
|
9
|
+
sh('rubocop --format simple') { |r, _| r || abort }
|
10
|
+
end
|
11
|
+
|
6
12
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
7
13
|
t.rspec_opts = '--format documentation'
|
8
14
|
end
|
9
15
|
|
10
|
-
task :default => :spec
|
16
|
+
task :default => [:rubocop, :spec]
|
data/bin/git-duet
CHANGED
data/bin/git-duet-commit
CHANGED
data/bin/git-duet-install-hook
CHANGED
data/bin/git-duet-pre-commit
CHANGED
data/bin/git-solo
CHANGED
data/git-duet.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.summary = "Pair harmoniously! Decide who's driving. " <<
|
19
19
|
"Commit along the way. Don't make a mess of " <<
|
20
20
|
"the repository history."
|
21
|
-
gem.homepage = ''
|
21
|
+
gem.homepage = 'https://github.com/modcloth/git-duet'
|
22
22
|
gem.license = 'MIT'
|
23
23
|
|
24
24
|
gem.files = `git ls-files`.split($\)
|
@@ -27,14 +27,12 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.name = 'git-duet'
|
28
28
|
gem.require_paths = %w(lib)
|
29
29
|
gem.version = Git::Duet::VERSION
|
30
|
-
gem.required_ruby_version = '>= 1.
|
30
|
+
gem.required_ruby_version = '>= 1.9.3'
|
31
31
|
|
32
|
-
gem.add_development_dependency 'nyan-cat-formatter'
|
33
32
|
gem.add_development_dependency 'rake'
|
34
33
|
gem.add_development_dependency 'rspec'
|
34
|
+
gem.add_development_dependency 'rubocop'
|
35
35
|
|
36
|
-
unless RUBY_PLATFORM == 'java'
|
37
|
-
|
38
|
-
gem.add_development_dependency 'simplecov'
|
39
|
-
end
|
36
|
+
gem.add_development_dependency 'pry' unless RUBY_PLATFORM == 'java'
|
37
|
+
gem.add_development_dependency 'simplecov' unless RUBY_PLATFORM == 'java'
|
40
38
|
end
|
data/lib/git-duet.rb
CHANGED
data/lib/git/duet.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
1
2
|
module Git
|
2
3
|
module Duet
|
4
|
+
autoload :VERSION, 'git/duet/version'
|
5
|
+
autoload :Cli, 'git/duet/cli'
|
6
|
+
autoload :Config, 'git/duet/config'
|
3
7
|
end
|
4
8
|
end
|
5
|
-
|
6
|
-
require 'git/duet/version'
|
7
|
-
require 'git/duet/cli'
|
8
|
-
require 'git/duet/key_error'
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
1
2
|
require 'yaml'
|
2
3
|
require 'erb'
|
3
4
|
require 'git/duet'
|
@@ -22,27 +23,30 @@ class Git::Duet::AuthorMapper
|
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
26
|
+
|
25
27
|
def author_info(initials)
|
26
28
|
author, username = author_map.fetch(initials).split(/;/).map(&:strip)
|
27
29
|
{
|
28
|
-
:
|
29
|
-
:
|
30
|
+
name: author,
|
31
|
+
email: lookup_author_email(initials, author, username)
|
30
32
|
}
|
31
33
|
end
|
32
34
|
|
33
35
|
def lookup_author_email(initials, author, username)
|
34
|
-
|
35
|
-
|
36
|
-
return author_email if !author_email.empty?
|
37
|
-
end
|
38
|
-
|
36
|
+
author_email = email_from_lookup(initials, author, username)
|
37
|
+
return author_email unless author_email.empty?
|
39
38
|
return email_addresses[initials] if email_addresses[initials]
|
40
39
|
return email_from_template(initials, author, username) if email_template
|
41
40
|
return "#{username}@#{email_domain}" if username
|
42
41
|
|
43
42
|
author_name_parts = author.split
|
44
|
-
|
45
|
-
|
43
|
+
"#{author_name_parts.first[0, 1].downcase}." <<
|
44
|
+
"#{author_name_parts.last.downcase}@#{email_domain}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def email_from_lookup(initials, author, username)
|
48
|
+
return '' unless @email_lookup
|
49
|
+
`#{@email_lookup} '#{initials}' '#{author}' '#{username}'`.strip
|
46
50
|
end
|
47
51
|
|
48
52
|
def email_from_template(initials, author, username)
|
@@ -69,7 +73,7 @@ class Git::Duet::AuthorMapper
|
|
69
73
|
end
|
70
74
|
|
71
75
|
def cfg
|
72
|
-
@cfg ||= YAML.load(IO.read(
|
76
|
+
@cfg ||= YAML.load(IO.read(authors_file))
|
73
77
|
rescue StandardError => e
|
74
78
|
$stderr.puts("git-duet: Missing or corrupt authors file: #{e.message}")
|
75
79
|
raise Git::Duet::ScriptDieError.new(3)
|
data/lib/git/duet/cli.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
1
2
|
require 'optparse'
|
2
3
|
require 'git/duet'
|
3
4
|
require 'git/duet/script_die_error'
|
@@ -5,30 +6,27 @@ require 'git/duet/script_die_error'
|
|
5
6
|
class Git::Duet::Cli
|
6
7
|
class << self
|
7
8
|
def run(prog, argv)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
return 0
|
15
|
-
when /pre-commit$/
|
16
|
-
pre_commit(parse_generic_options(argv.clone))
|
17
|
-
return 0
|
18
|
-
when /install-hook$/
|
19
|
-
install_hook(parse_generic_options(argv.clone))
|
20
|
-
return 0
|
21
|
-
when /commit$/
|
22
|
-
commit(parse_commit_options(argv.clone))
|
23
|
-
return 0
|
24
|
-
else
|
25
|
-
raise ScriptError.new('How did you get here???')
|
26
|
-
end
|
9
|
+
method_name = File.basename(prog)
|
10
|
+
.sub(/^git-duet-/, '').sub(/^git-/, '').tr('-', '_')
|
11
|
+
send(method_name, parse_options(method_name, argv.clone))
|
12
|
+
0
|
13
|
+
rescue NoMethodError
|
14
|
+
raise ScriptError.new('How did you get here???')
|
27
15
|
rescue Git::Duet::ScriptDieError => e
|
28
|
-
|
16
|
+
e.exit_code
|
29
17
|
end
|
30
18
|
|
31
19
|
private
|
20
|
+
|
21
|
+
def parse_options(method_name, argv)
|
22
|
+
case method_name
|
23
|
+
when 'pre_commit', 'install_hook'
|
24
|
+
parse_generic_options(argv)
|
25
|
+
else
|
26
|
+
send("parse_#{method_name}_options", argv)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
32
30
|
def with_common_opts(argv, banner)
|
33
31
|
options = {}
|
34
32
|
leftover_argv = OptionParser.new do |opts|
|
@@ -36,17 +34,15 @@ class Git::Duet::Cli
|
|
36
34
|
opts.on('-q', 'Silence output') do |q|
|
37
35
|
options[:quiet] = true
|
38
36
|
end
|
39
|
-
if block_given?
|
40
|
-
yield opts, options
|
41
|
-
end
|
37
|
+
yield opts, options if block_given?
|
42
38
|
end.parse!(argv)
|
43
|
-
|
39
|
+
[leftover_argv, options]
|
44
40
|
end
|
45
41
|
|
46
42
|
def parse_solo_options(argv)
|
47
43
|
leftover_argv, options = with_common_opts(
|
48
44
|
argv, 'Usage: __PROG__ [options] <soloist-initials>'
|
49
|
-
) do |opts,options_hash|
|
45
|
+
) do |opts, options_hash|
|
50
46
|
opts.on('-g', '--global', 'Change global git config') do |g|
|
51
47
|
options_hash[:global] = true
|
52
48
|
end
|
@@ -58,7 +54,7 @@ class Git::Duet::Cli
|
|
58
54
|
def parse_duet_options(argv)
|
59
55
|
leftover_argv, options = with_common_opts(
|
60
56
|
argv, 'Usage: __PROG__ [options] <alpha-initials> <omega-initials>'
|
61
|
-
) do |opts,options_hash|
|
57
|
+
) do |opts, options_hash|
|
62
58
|
opts.on('-g', '--global', 'Change global git config') do |g|
|
63
59
|
options_hash[:global] = true
|
64
60
|
end
|
@@ -1,40 +1,68 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
2
|
+
require 'English'
|
1
3
|
require 'git/duet'
|
2
4
|
require 'git/duet/script_die_error'
|
3
5
|
|
4
6
|
module Git::Duet::CommandMethods
|
7
|
+
|
5
8
|
private
|
9
|
+
|
6
10
|
def report_env_vars
|
7
|
-
var_map.each do |key,value|
|
11
|
+
var_map.each do |key, value|
|
8
12
|
info("#{key}='#{value}'")
|
9
13
|
end
|
10
14
|
end
|
11
15
|
|
12
16
|
def write_env_vars
|
13
17
|
in_repo_root do
|
14
|
-
var_map.each do |key,value|
|
15
|
-
exec_check(
|
18
|
+
var_map.each do |key, value|
|
19
|
+
exec_check(
|
20
|
+
"#{git_config} #{Git::Duet::Config.namespace}." <<
|
21
|
+
"#{key.downcase.gsub(/_/, '-')} '#{value}'"
|
22
|
+
)
|
16
23
|
end
|
17
|
-
exec_check("
|
24
|
+
exec_check("#{git_config} #{Git::Duet::Config
|
25
|
+
.namespace}.mtime #{Time.now.to_i}")
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
29
|
+
def git_config
|
30
|
+
"git config#{@global ? ' --global' : ''}"
|
31
|
+
end
|
32
|
+
|
21
33
|
def author_env_vars_set?
|
22
|
-
|
23
|
-
|
34
|
+
%x(#{get_author_name} && #{get_author_email})
|
35
|
+
$CHILD_STATUS == 0
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_author_name
|
39
|
+
"git config --get #{Git::Duet::Config.namespace}.git-author-name"
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_author_email
|
43
|
+
"git config --get #{Git::Duet::Config.namespace}.git-author-email"
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_current_config
|
47
|
+
"git config --get-regexp #{Git::Duet::Config.namespace}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def show_current_config
|
51
|
+
info(exec_check(get_current_config))
|
24
52
|
end
|
25
53
|
|
26
54
|
def dump_env_vars
|
27
|
-
extract_env_vars_from_git_config.each do |k,v|
|
55
|
+
extract_env_vars_from_git_config.each do |k, v|
|
28
56
|
puts "#{k}='#{v}'"
|
29
57
|
end
|
30
58
|
end
|
31
59
|
|
32
60
|
def extract_env_vars_from_git_config
|
33
61
|
dest = {}
|
34
|
-
env_vars.each do |env_var,config_key|
|
62
|
+
env_vars.each do |env_var, config_key|
|
35
63
|
begin
|
36
|
-
value =
|
37
|
-
dest[env_var] = value
|
64
|
+
value = check_env_var_config_key(config_key)
|
65
|
+
dest[env_var] = value unless value.empty?
|
38
66
|
rescue StandardError => e
|
39
67
|
error("#{e.message}")
|
40
68
|
end
|
@@ -42,6 +70,10 @@ module Git::Duet::CommandMethods
|
|
42
70
|
dest
|
43
71
|
end
|
44
72
|
|
73
|
+
def check_env_var_config_key(config_key)
|
74
|
+
exec_check("git config #{Git::Duet::Config.namespace}.#{config_key}").chomp
|
75
|
+
end
|
76
|
+
|
45
77
|
def exec_git_commit
|
46
78
|
if author_env_vars_set?
|
47
79
|
exec 'git commit ' << signoff_arg << quoted_passthrough_args
|
@@ -58,8 +90,8 @@ module Git::Duet::CommandMethods
|
|
58
90
|
|
59
91
|
def exec_check(command, okay_statuses = [0].freeze)
|
60
92
|
output = `#{command}`
|
61
|
-
|
62
|
-
error("Command #{command.inspect} exited with #{
|
93
|
+
unless okay_statuses.include?($CHILD_STATUS.exitstatus)
|
94
|
+
error("Command #{command.inspect} exited with #{$CHILD_STATUS.to_i}")
|
63
95
|
raise Git::Duet::ScriptDieError.new(1)
|
64
96
|
end
|
65
97
|
output
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# vim:fileencoding=utf-8
|
1
2
|
require 'git/duet'
|
2
3
|
require 'git/duet/command_methods'
|
3
4
|
|
@@ -17,8 +18,9 @@ class Git::Duet::CommitCommand
|
|
17
18
|
end
|
18
19
|
|
19
20
|
private
|
21
|
+
|
20
22
|
def add_env_vars_to_env
|
21
|
-
extract_env_vars_from_git_config.each do |k,v|
|
23
|
+
extract_env_vars_from_git_config.each do |k, v|
|
22
24
|
ENV[k] = v
|
23
25
|
end
|
24
26
|
end
|
@@ -43,26 +45,29 @@ class Git::Duet::CommitCommand
|
|
43
45
|
soloing? ? '' : '--signoff '
|
44
46
|
end
|
45
47
|
|
48
|
+
SOLO_ENV_VARS = %w(
|
49
|
+
GIT_AUTHOR_NAME
|
50
|
+
GIT_AUTHOR_EMAIL
|
51
|
+
)
|
52
|
+
|
53
|
+
DUET_ENV_VARS = %w(
|
54
|
+
GIT_AUTHOR_NAME
|
55
|
+
GIT_AUTHOR_EMAIL
|
56
|
+
GIT_COMMITTER_NAME
|
57
|
+
GIT_COMMITTER_EMAIL
|
58
|
+
)
|
59
|
+
|
46
60
|
def env_var_names
|
47
|
-
if soloing?
|
48
|
-
|
49
|
-
GIT_AUTHOR_NAME
|
50
|
-
GIT_AUTHOR_EMAIL
|
51
|
-
)
|
52
|
-
else
|
53
|
-
%w(
|
54
|
-
GIT_AUTHOR_NAME
|
55
|
-
GIT_AUTHOR_EMAIL
|
56
|
-
GIT_COMMITTER_NAME
|
57
|
-
GIT_COMMITTER_EMAIL
|
58
|
-
)
|
59
|
-
end
|
61
|
+
return SOLO_ENV_VARS if soloing?
|
62
|
+
DUET_ENV_VARS
|
60
63
|
end
|
61
64
|
|
62
65
|
def soloing?
|
63
66
|
@soloing ||= begin
|
64
67
|
with_output_quieted do
|
65
|
-
exec_check(
|
68
|
+
exec_check(
|
69
|
+
"git config #{Git::Duet::Config.namespace}.git-committer-name"
|
70
|
+
).chomp
|
66
71
|
end
|
67
72
|
false
|
68
73
|
rescue StandardError
|