git-duo 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.autotest +5 -0
- data/.gitignore +17 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +98 -0
- data/Rakefile +19 -0
- data/bin/git-duo +5 -0
- data/bin/git-solo +6 -0
- data/git-duo.gemspec +26 -0
- data/lib/git/duo/author.rb +32 -0
- data/lib/git/duo/author_collection.rb +22 -0
- data/lib/git/duo/cli.rb +63 -0
- data/lib/git/duo/exceptions.rb +5 -0
- data/lib/git/duo/pair.rb +57 -0
- data/lib/git/duo/repo.rb +85 -0
- data/lib/git/duo/version.rb +5 -0
- data/lib/git/duo/wrapper.rb +15 -0
- data/lib/git/duo.rb +6 -0
- data/test/git/duo/author_collection_test.rb +28 -0
- data/test/git/duo/author_test.rb +43 -0
- data/test/git/duo/pair_test.rb +75 -0
- data/test/git/duo/repo_test.rb +91 -0
- data/test/test_helper.rb +44 -0
- metadata +146 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZDNjMWI5YWM3YzYwOGE4OGNhMmE0NWIwZWMzYmU2ODE2MDYwNmEwZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NDBmZTMwYTExNGY1ZjQyYWZhNGMxNzNkODNmZDI2MjYwZjhlNTExNA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
OGU4MGViMzIzM2NlOWI3ZGFjZGJlYWViZDhmZmE5MmZhZDJiZmQ2ZWRlMWQy
|
10
|
+
NzRlYWMyYzcyODc4YWYyOWJiYjc0ZjQzMDg5MjFhMGUzNjM5MDgxNDYwZTlj
|
11
|
+
ZDRlNTRmNDZmMGRhNGRiNmZjMjEwYzJiZmU3NDdlNzlmZjc5YjU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDBkMWZjNGJlM2I0MjQ0MDA4NDQ3MTgzZTMzOTllZjM3ODhmMThlYmYxMjQy
|
14
|
+
Nzk5YWZmY2VjNDEwY2VmNTM1NTdhODAzMjc4Mzg0YjI5OWYwOTk2MGVhNzhi
|
15
|
+
NDE1MGRhOTRmMmVhNTM0YmQ4NWI0MjU5NWEwMzJhMzE5ZmQyYmU=
|
data/.autotest
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Teo Ljungberg
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Git Duo
|
2
|
+
|
3
|
+
- [home](https://github.com/teoljungberg/git-duo)
|
4
|
+
- [code](https://github.com/teoljungberg/git-duo)
|
5
|
+
- [bugs](https://github.com/teoljungberg/git-duo/issues)
|
6
|
+
|
7
|
+
# Description
|
8
|
+
|
9
|
+
A git porcelain for duo programming. Changes git-config's user.name and
|
10
|
+
user.email settings so you can commit as more than one author.
|
11
|
+
|
12
|
+
# Features/problems:
|
13
|
+
|
14
|
+
* Keep pairs per repository
|
15
|
+
* Import pairs between repositories
|
16
|
+
* Pairing made easy(-ier)
|
17
|
+
|
18
|
+
# Synopsis
|
19
|
+
```bash
|
20
|
+
$ git duo --email "board+%names@gotham.travel"
|
21
|
+
```
|
22
|
+
|
23
|
+
```bash
|
24
|
+
$ git duo --add "bruce Bruce Wayne <bruce@gotham.travel>"
|
25
|
+
$ git duo --add "alfred Alfred Pennyworth <alfred@gotham.travel>"
|
26
|
+
```
|
27
|
+
|
28
|
+
```bash
|
29
|
+
$ git duo alfred bruce
|
30
|
+
Alfred Pennyworth + Bruce Wayne <board+alfred+bruce@gotham.travel>
|
31
|
+
```
|
32
|
+
|
33
|
+
```bash
|
34
|
+
$ git duo --add "jim Jim Gordon <jim@gotham.travel>"
|
35
|
+
$ git duo alfred bruce jim
|
36
|
+
Alfred Pennyworth + Bruce Wayne + Jim Gordon <dev+alfred+bruce+jim@gotham.travel>
|
37
|
+
```
|
38
|
+
|
39
|
+
```bash
|
40
|
+
$ git duo --list
|
41
|
+
Bruce Wayne <bruce@gotham.travel>
|
42
|
+
Alfred Pennyworth <alfred@gotham.travel>
|
43
|
+
Jim Gordon <jim@gotham.travel>
|
44
|
+
```
|
45
|
+
|
46
|
+
```bash
|
47
|
+
$ git duo --email "law+%names@gotham.travel"
|
48
|
+
Alfred Pennyworth + Bruce Wayne <law+alfred+bruce@gotham.travel>
|
49
|
+
```
|
50
|
+
|
51
|
+
```bash
|
52
|
+
$ cd ../new-project
|
53
|
+
$ git duo --import ../old-project
|
54
|
+
# this will import the authors and email from the `old-project` project
|
55
|
+
# into `new-project`
|
56
|
+
```
|
57
|
+
|
58
|
+
```bash
|
59
|
+
$ git solo
|
60
|
+
Teo Ljungberg <teo.ljungberg@gmail.com>
|
61
|
+
```
|
62
|
+
|
63
|
+
# Requirements
|
64
|
+
|
65
|
+
* Ruby 1.9 and above
|
66
|
+
* Rake
|
67
|
+
|
68
|
+
# Install
|
69
|
+
|
70
|
+
* Clone down this repository
|
71
|
+
* Run `rake install`
|
72
|
+
* Good to go
|
73
|
+
|
74
|
+
# Developers
|
75
|
+
|
76
|
+
After checking out the source, run:
|
77
|
+
|
78
|
+
```bash
|
79
|
+
$ rake newb
|
80
|
+
```
|
81
|
+
|
82
|
+
This task will install any missing dependencies, the gem itself and
|
83
|
+
run the tests
|
84
|
+
|
85
|
+
## Autotest
|
86
|
+
* Install autotest (as a part of [ZenTest][zentest])
|
87
|
+
* Install [autotest-suffix][autotest-suffix] (since I prefer `foo_test.rb` to `test_foo.rb`)
|
88
|
+
|
89
|
+
## Contributing
|
90
|
+
|
91
|
+
1. Fork it
|
92
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
93
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
94
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
95
|
+
5. Create new Pull Request
|
96
|
+
|
97
|
+
[zentest]: https://github.com/seattlerb/ZenTest
|
98
|
+
[autotest-suffix]: https://github.com/blowmage/autotest-suffix/
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.pattern = "test/**/*_test.rb"
|
7
|
+
end
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
desc 'Setup a new dev computer'
|
11
|
+
task newb: [:install_deps, :install, :test] do
|
12
|
+
puts
|
13
|
+
puts 'Happy hacking'
|
14
|
+
end
|
15
|
+
|
16
|
+
task :install_deps do
|
17
|
+
puts '--- installing dependencies'
|
18
|
+
system 'bundle install'
|
19
|
+
end
|
data/bin/git-duo
ADDED
data/bin/git-solo
ADDED
data/git-duo.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'git/duo/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "git-duo"
|
8
|
+
spec.version = Git::Duo::VERSION
|
9
|
+
spec.authors = ["Teo Ljungberg"]
|
10
|
+
spec.email = ["teo.ljungberg@gmail.com"]
|
11
|
+
spec.description = %q{A git porcelain for duo programming. Changes git-config's user.name and user.email settings so you can commit as more than one author.}
|
12
|
+
spec.summary = %q{Git pairing made easy}
|
13
|
+
spec.homepage = "https://github.com/teoljungberg/git-duo"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "minitest"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
spec.add_development_dependency "mocha"
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Git
|
2
|
+
module Duo
|
3
|
+
class Author
|
4
|
+
EMAIL_REGEXP = /(?:<?(.+@[^>]+)>?)/
|
5
|
+
|
6
|
+
def self.import(new_author)
|
7
|
+
key, *author = new_author.split(?\s)
|
8
|
+
first, last, email = author
|
9
|
+
|
10
|
+
new({ key: key,
|
11
|
+
name: "#{first} #{last}",
|
12
|
+
email: email.match(EMAIL_REGEXP)[1] })
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :key, :name, :email
|
16
|
+
|
17
|
+
def initialize(opts = {})
|
18
|
+
@key = opts[:key]
|
19
|
+
@name = opts[:name]
|
20
|
+
@email = opts[:email]
|
21
|
+
end
|
22
|
+
|
23
|
+
def valid?
|
24
|
+
key && name && email
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_s
|
28
|
+
"#{name} <#{email}>"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Git
|
2
|
+
module Duo
|
3
|
+
class AuthorCollection
|
4
|
+
attr_reader :authors
|
5
|
+
|
6
|
+
def initialize authors
|
7
|
+
@authors = authors
|
8
|
+
end
|
9
|
+
|
10
|
+
def where opts = {}
|
11
|
+
result = []
|
12
|
+
result += opts.
|
13
|
+
select {|k, _| authors.sample.respond_to? k }.
|
14
|
+
map do |k, v|
|
15
|
+
authors.select {|o| o.send(k) =~ /#{v}/i }
|
16
|
+
end.flatten
|
17
|
+
rescue NoMethodError
|
18
|
+
result
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/git/duo/cli.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'git/duo'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module Git
|
5
|
+
module Duo
|
6
|
+
class CLI
|
7
|
+
def self.start
|
8
|
+
parser = OptionParser.new do |opts|
|
9
|
+
puts current_repo.committer if ARGV.empty?
|
10
|
+
|
11
|
+
opts.on '--add AUTHOR', 'Add an author. Format: "Key Author Name <author@example.com>"' do |string|
|
12
|
+
current_repo.authors = Author.import string
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on '--list', 'Lists the authors in the repository' do
|
16
|
+
puts current_repo.authors
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on '--email EMAIL', 'Set email format. Format: dev@example.com' do |email|
|
20
|
+
current_repo.email = email
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on '--import=PATH/TO/REPO', 'Import pairs from another repo' do |path|
|
24
|
+
import_repo = Repo.new path
|
25
|
+
current_repo.email = import_repo.email
|
26
|
+
current_repo.authors = import_repo.authors
|
27
|
+
end
|
28
|
+
|
29
|
+
opts.on '-h', 'Show this message' do
|
30
|
+
puts opts
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
parser.parse!
|
36
|
+
|
37
|
+
unless ARGV.empty?
|
38
|
+
authors = ARGV.sort.map do |key|
|
39
|
+
author = AuthorCollection.new(current_repo.authors).
|
40
|
+
where(key: key).first
|
41
|
+
abort "`#{key}` can't be found, see -h on how to add new authors" unless author
|
42
|
+
Author.new(key: key, name: author.name, email: author.email)
|
43
|
+
end
|
44
|
+
pair = Pair.new authors
|
45
|
+
pair.save
|
46
|
+
puts pair.to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
current_repo.save
|
50
|
+
rescue OptionParser::MissingArgument
|
51
|
+
abort "missing required argument\n\n #{parser.help}"
|
52
|
+
rescue Git::Duo::EmailNotImplementedError
|
53
|
+
abort "`Email format isn't set, see -h on how to set the email format"
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def self.current_repo
|
59
|
+
@current_repo ||= Repo.current
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/git/duo/pair.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'git/duo/wrapper'
|
2
|
+
require 'git/duo/exceptions'
|
3
|
+
|
4
|
+
module Git
|
5
|
+
module Duo
|
6
|
+
class Pair
|
7
|
+
attr_reader :authors, :wrapper
|
8
|
+
|
9
|
+
def initialize authors, opts = {}
|
10
|
+
@authors = authors.sort_by {|author| author.key }
|
11
|
+
@wrapper = opts.fetch(:wrapper) { Git::Duo::Wrapper.new File.join(Dir.pwd, '.git') }
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
authors.map(&:name).join ' + '
|
16
|
+
end
|
17
|
+
|
18
|
+
def email
|
19
|
+
base_email.gsub "%names", authors.map(&:key).join(?+)
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
"#{name} <#{email}>"
|
24
|
+
end
|
25
|
+
alias_method :inspect, :to_s
|
26
|
+
|
27
|
+
def save
|
28
|
+
save_pair_name
|
29
|
+
save_pair_email
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def base_email
|
35
|
+
wrapper.config("git-duo.email").first ||
|
36
|
+
guess_base_email_from_authors ||
|
37
|
+
raise(Git::Duo::EmailNotImplemented)
|
38
|
+
end
|
39
|
+
|
40
|
+
def guess_base_email_from_authors
|
41
|
+
domains = authors.map do |author|
|
42
|
+
author.email.split(?@).last
|
43
|
+
end.uniq
|
44
|
+
|
45
|
+
"dev+%names@#{domains.first}" if domains.size == 1
|
46
|
+
end
|
47
|
+
|
48
|
+
def save_pair_name
|
49
|
+
wrapper.config "user.name '#{name}'"
|
50
|
+
end
|
51
|
+
|
52
|
+
def save_pair_email
|
53
|
+
wrapper.config "user.email '#{email}'"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/git/duo/repo.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'git/duo/wrapper'
|
2
|
+
require 'git/duo/author'
|
3
|
+
|
4
|
+
module Git
|
5
|
+
module Duo
|
6
|
+
class Repo
|
7
|
+
def self.current
|
8
|
+
new Dir.pwd
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :directory, :wrapper
|
12
|
+
|
13
|
+
def initialize(directory, opts = {})
|
14
|
+
@directory = File.expand_path(directory)
|
15
|
+
@wrapper = opts.fetch(:wrapper) { Git::Duo::Wrapper.new(git_directory) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def authors
|
19
|
+
return @authors if defined? @authors
|
20
|
+
config.
|
21
|
+
reject {|key| non_git_author? key }.
|
22
|
+
map {|a| Git::Duo::Author.import(a) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def authors=(new_authors)
|
26
|
+
@authors = new_authors
|
27
|
+
end
|
28
|
+
|
29
|
+
def committer
|
30
|
+
name = wrapper.config("user.name").shift
|
31
|
+
email = wrapper.config("user.email").shift
|
32
|
+
|
33
|
+
Author.new(name: name, email: email).to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
def email
|
37
|
+
return @email if defined? @email
|
38
|
+
config.
|
39
|
+
select {|key| non_git_author? key }.
|
40
|
+
map {|key| key.gsub(/^email\s/, '') }.
|
41
|
+
first
|
42
|
+
end
|
43
|
+
|
44
|
+
def email=(new_email)
|
45
|
+
@email = new_email
|
46
|
+
end
|
47
|
+
|
48
|
+
def solo!
|
49
|
+
wrapper.config '--remove-section user'
|
50
|
+
end
|
51
|
+
|
52
|
+
def save
|
53
|
+
save_email if email
|
54
|
+
save_authors if authors
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def non_git_author?(key)
|
60
|
+
key =~ /email/
|
61
|
+
end
|
62
|
+
|
63
|
+
def save_authors
|
64
|
+
authors.each do |author|
|
65
|
+
wrapper.config "git-duo.#{author.key} '#{author}'"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def save_email
|
70
|
+
wrapper.config "git-duo.email '#{email}'"
|
71
|
+
end
|
72
|
+
|
73
|
+
def config
|
74
|
+
wrapper.
|
75
|
+
config('--get-regexp git-duo').
|
76
|
+
select {|key| key.start_with? 'git-duo' }.
|
77
|
+
map {|config| config.gsub('git-duo.', '') }
|
78
|
+
end
|
79
|
+
|
80
|
+
def git_directory
|
81
|
+
File.join(directory, '.git')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Git
|
2
|
+
module Duo
|
3
|
+
class Wrapper
|
4
|
+
PIPE_STDOUT_TO_STDERR = '2>&1'
|
5
|
+
|
6
|
+
def initialize(directory)
|
7
|
+
@directory = directory
|
8
|
+
end
|
9
|
+
|
10
|
+
def config(args)
|
11
|
+
`git --git-dir=#{@directory} config #{args} #{PIPE_STDOUT_TO_STDERR}`.split("\n")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/git/duo.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
require 'git/duo/author_collection'
|
3
|
+
|
4
|
+
module Git::Duo
|
5
|
+
class AuthorCollectionTest < Minitest::Test
|
6
|
+
def setup
|
7
|
+
@collection = AuthorCollection.new alfred_and_bruce
|
8
|
+
end
|
9
|
+
attr_reader :collection
|
10
|
+
|
11
|
+
def test_where_with_existing_keys
|
12
|
+
assert_instance_of Author, collection.where(key: 'alfred').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_where_with_nonexisting_keys_returns_empty_array
|
16
|
+
assert_empty collection.where(omg: 0)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_where_returns_the_result_of_the_valid_query
|
20
|
+
refute_empty collection.where(key: 'alfred', omg: 0)
|
21
|
+
refute_empty collection.where(omg: 0, key: 'alfred')
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_where_returns_empty_array_with_an_empty_search
|
25
|
+
assert_empty collection.where
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
module Git::Duo
|
4
|
+
class AuthorTest < MiniTest::Test
|
5
|
+
def setup
|
6
|
+
@author = Author.new(author_options)
|
7
|
+
end
|
8
|
+
attr_reader :author
|
9
|
+
|
10
|
+
def author_options
|
11
|
+
{
|
12
|
+
key: 'alfred',
|
13
|
+
name: 'Alfred Pennyworth',
|
14
|
+
email: 'alfred@gotham.travel'
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_author_requires_name
|
19
|
+
author = Author.new author_options.merge(name: nil)
|
20
|
+
refute author.valid?
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_author_requires_email
|
24
|
+
author = Author.new author_options.merge(email: nil)
|
25
|
+
refute author.valid?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_author_requires_key
|
29
|
+
author = Author.new author_options.merge(key: nil)
|
30
|
+
refute author.valid?
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_import
|
34
|
+
author = Author.import("bruce Bruce Wayne <bruce@gotham.travel>")
|
35
|
+
assert author.valid?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_to_s
|
39
|
+
expected = "Alfred Pennyworth <alfred@gotham.travel>"
|
40
|
+
assert_equal expected, author.to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
module Git::Duo
|
4
|
+
class PairTest < MiniTest::Test
|
5
|
+
def setup
|
6
|
+
@wrapper = DummyWrapper.new(:path_to_hell)
|
7
|
+
@pair = Pair.new alfred_and_bruce, wrapper: wrapper
|
8
|
+
end
|
9
|
+
attr_reader :pair, :wrapper
|
10
|
+
|
11
|
+
def test_pair_supports_multiple_authors
|
12
|
+
wrapper.expects(:config).with("git-duo.email").
|
13
|
+
returns(["board+%names@gotham.travel"]).at_least_once
|
14
|
+
|
15
|
+
pair = Pair.new alfred_and_bruce_rachel, wrapper: wrapper
|
16
|
+
expected_name = "Alfred Pennyworth + Bruce Wayne + Rachel Dawes"
|
17
|
+
expected_email = "board+alfred+bruce+rachel@gotham.travel"
|
18
|
+
|
19
|
+
assert_equal expected_name, pair.name
|
20
|
+
assert_equal expected_email, pair.email
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_name
|
24
|
+
expected = 'Alfred Pennyworth + Bruce Wayne'
|
25
|
+
assert_equal expected, pair.name
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_email
|
29
|
+
wrapper.expects(:config).with("git-duo.email").
|
30
|
+
returns(["board+%names@gotham.travel"]).at_least_once
|
31
|
+
|
32
|
+
expected = 'board+alfred+bruce@gotham.travel'
|
33
|
+
assert_equal expected, pair.email
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_email_guesses_the_email_domain_from_authors
|
37
|
+
wrapper.expects(:config).with("git-duo.email").
|
38
|
+
returns([]).at_least_once
|
39
|
+
|
40
|
+
expected = "dev+alfred+bruce@gotham.travel"
|
41
|
+
assert_equal expected, pair.email
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_email_raises_error_if_domain_could_not_be_guessed
|
45
|
+
wrapper.expects(:config).with("git-duo.email").
|
46
|
+
returns([]).at_least_once
|
47
|
+
|
48
|
+
assert_raises Git::Duo::EmailNotImplemented do
|
49
|
+
Pair.new(bruce_and_edward, wrapper: wrapper).email
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_to_s
|
54
|
+
wrapper.expects(:config).with("git-duo.email").
|
55
|
+
returns(["board+%names@gotham.travel"]).at_least_once
|
56
|
+
|
57
|
+
expected = 'Alfred Pennyworth + Bruce Wayne <board+alfred+bruce@gotham.travel>'
|
58
|
+
assert_equal expected, pair.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_inspect_is_to_s
|
62
|
+
assert_equal pair.to_s, pair.inspect
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_save
|
66
|
+
wrapper.expects(:config).with("git-duo.email").
|
67
|
+
returns(["board+%names@gotham.travel"]).at_least_once
|
68
|
+
|
69
|
+
wrapper.expects(:config).with("user.email 'board+alfred+bruce@gotham.travel'")
|
70
|
+
wrapper.expects(:config).with("user.name 'Alfred Pennyworth + Bruce Wayne'")
|
71
|
+
|
72
|
+
pair.save
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative '../../test_helper'
|
2
|
+
|
3
|
+
module Git::Duo
|
4
|
+
class RepoTest < MiniTest::Test
|
5
|
+
def setup
|
6
|
+
@wrapper = DummyWrapper.new(:path_to_hell)
|
7
|
+
@repo = Repo.new '~/code/mynewsdesk', wrapper: wrapper
|
8
|
+
end
|
9
|
+
attr_reader :repo, :wrapper
|
10
|
+
|
11
|
+
def test_current_inits_repo_with_current_dir
|
12
|
+
repo = Repo.current
|
13
|
+
expected = Dir.pwd
|
14
|
+
|
15
|
+
assert_equal expected, repo.directory
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_initialize_expands_directory_path
|
19
|
+
expected = repo.directory
|
20
|
+
assert_equal expected, File.join(ENV['HOME'], 'code', 'mynewsdesk')
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_authors_returns_author_objects
|
24
|
+
assert_instance_of Author, repo.authors.sample
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_importing_authors
|
28
|
+
wrapper.expects(:config).with('--get-regexp git-duo').returns(git_config).at_least_once
|
29
|
+
wrapper.expects(:config).with("git-duo.email 'board+%names@gotham.travel'")
|
30
|
+
wrapper.expects(:config).with("git-duo.jim 'Jim Gordon <jim@gotham.travel>'")
|
31
|
+
wrapper.expects(:config).with("git-duo.harvey 'Harvey Dent <harvey@gotham.travel>'")
|
32
|
+
|
33
|
+
repo.authors = jim_and_harvey
|
34
|
+
repo.save
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_committer
|
38
|
+
wrapper.expects(:config).with('user.name').returns ["Bruce Wayne"]
|
39
|
+
wrapper.expects(:config).with('user.email').returns ["bruce@gotham.travel"]
|
40
|
+
|
41
|
+
expected = "Bruce Wayne <bruce@gotham.travel>"
|
42
|
+
assert_equal expected, repo.committer
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_importing_email
|
46
|
+
wrapper.expects(:config).with('--get-regexp git-duo').returns(git_config).at_least_once
|
47
|
+
wrapper.expects(:config).with("git-duo.email 'law+%names@gotham.travel'")
|
48
|
+
wrapper.expects(:config).with("git-duo.alfred 'Alfred Pennyworth <alfred@gotham.travel>'")
|
49
|
+
wrapper.expects(:config).with("git-duo.bruce 'Bruce Wayne <bruce@gotham.travel>'")
|
50
|
+
|
51
|
+
repo.email = "law+%names@gotham.travel"
|
52
|
+
repo.save
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_email_returns_set_group_email
|
56
|
+
assert_equal "board+%names@gotham.travel", repo.email
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_solo_bang_resets_the_pair
|
60
|
+
wrapper.expects(:config).with('--remove-section user')
|
61
|
+
|
62
|
+
repo.solo!
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_save
|
66
|
+
wrapper.expects(:config).with('--get-regexp git-duo').returns(git_config).at_least_once
|
67
|
+
wrapper.expects(:config).with("git-duo.email 'board+%names@gotham.travel'")
|
68
|
+
wrapper.expects(:config).with("git-duo.alfred 'Alfred Pennyworth <alfred@gotham.travel>'")
|
69
|
+
wrapper.expects(:config).with("git-duo.bruce 'Bruce Wayne <bruce@gotham.travel>'")
|
70
|
+
|
71
|
+
repo.save
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_save_doesnt_save_email_if_nil
|
75
|
+
wrapper.expects(:config).with('--get-regexp git-duo').returns(git_config).at_least_once
|
76
|
+
wrapper.expects(:config).with("git-duo.alfred 'Alfred Pennyworth <alfred@gotham.travel>'")
|
77
|
+
wrapper.expects(:config).with("git-duo.bruce 'Bruce Wayne <bruce@gotham.travel>'")
|
78
|
+
|
79
|
+
repo.email = nil
|
80
|
+
repo.save
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_save_doesnt_save_authors_if_empty
|
84
|
+
wrapper.expects(:config).with('--get-regexp git-duo').returns(git_config).at_least_once
|
85
|
+
wrapper.expects(:config).with("git-duo.email 'board+%names@gotham.travel'")
|
86
|
+
|
87
|
+
repo.authors = []
|
88
|
+
repo.save
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require "mocha/setup"
|
3
|
+
|
4
|
+
$:<< File.dirname(__FILE__) + "/../lib"
|
5
|
+
require 'git/duo'
|
6
|
+
|
7
|
+
def alfred_and_bruce
|
8
|
+
[
|
9
|
+
Git::Duo::Author.import('bruce Bruce Wayne <bruce@gotham.travel>'),
|
10
|
+
Git::Duo::Author.import('alfred Alfred Pennyworth <alfred@gotham.travel>')
|
11
|
+
]
|
12
|
+
end
|
13
|
+
|
14
|
+
def alfred_and_bruce_rachel
|
15
|
+
alfred_and_bruce << Git::Duo::Author.import('rachel Rachel Dawes <rachel@gotham.travel>')
|
16
|
+
end
|
17
|
+
|
18
|
+
def bruce_and_edward
|
19
|
+
[
|
20
|
+
Git::Duo::Author.import('bruce Bruce Wayne <bruce@gotham.travel>'),
|
21
|
+
Git::Duo::Author.import('riddler Edward Nigma <riddler@guess.com>')
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
def jim_and_harvey
|
26
|
+
[
|
27
|
+
Git::Duo::Author.import('jim Jim Gordon <jim@gotham.travel>'),
|
28
|
+
Git::Duo::Author.import('harvey Harvey Dent <harvey@gotham.travel>')
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
class DummyWrapper < Struct.new(:directory)
|
33
|
+
def config(*)
|
34
|
+
git_config
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def git_config
|
39
|
+
[
|
40
|
+
'git-duo.bruce Bruce Wayne <bruce@gotham.travel>',
|
41
|
+
'git-duo.alfred Alfred Pennyworth <alfred@gotham.travel>',
|
42
|
+
'git-duo.email board+%names@gotham.travel'
|
43
|
+
]
|
44
|
+
end
|
metadata
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: git-duo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Teo Ljungberg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-01-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mocha
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ! '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: A git porcelain for duo programming. Changes git-config's user.name and
|
84
|
+
user.email settings so you can commit as more than one author.
|
85
|
+
email:
|
86
|
+
- teo.ljungberg@gmail.com
|
87
|
+
executables:
|
88
|
+
- git-duo
|
89
|
+
- git-solo
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- .autotest
|
94
|
+
- .gitignore
|
95
|
+
- .travis.yml
|
96
|
+
- Gemfile
|
97
|
+
- LICENSE.txt
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- bin/git-duo
|
101
|
+
- bin/git-solo
|
102
|
+
- git-duo.gemspec
|
103
|
+
- lib/git/duo.rb
|
104
|
+
- lib/git/duo/author.rb
|
105
|
+
- lib/git/duo/author_collection.rb
|
106
|
+
- lib/git/duo/cli.rb
|
107
|
+
- lib/git/duo/exceptions.rb
|
108
|
+
- lib/git/duo/pair.rb
|
109
|
+
- lib/git/duo/repo.rb
|
110
|
+
- lib/git/duo/version.rb
|
111
|
+
- lib/git/duo/wrapper.rb
|
112
|
+
- test/git/duo/author_collection_test.rb
|
113
|
+
- test/git/duo/author_test.rb
|
114
|
+
- test/git/duo/pair_test.rb
|
115
|
+
- test/git/duo/repo_test.rb
|
116
|
+
- test/test_helper.rb
|
117
|
+
homepage: https://github.com/teoljungberg/git-duo
|
118
|
+
licenses:
|
119
|
+
- MIT
|
120
|
+
metadata: {}
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - ! '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 2.1.11
|
138
|
+
signing_key:
|
139
|
+
specification_version: 4
|
140
|
+
summary: Git pairing made easy
|
141
|
+
test_files:
|
142
|
+
- test/git/duo/author_collection_test.rb
|
143
|
+
- test/git/duo/author_test.rb
|
144
|
+
- test/git/duo/pair_test.rb
|
145
|
+
- test/git/duo/repo_test.rb
|
146
|
+
- test/test_helper.rb
|