gitsu 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.licenseignore +2 -0
  3. data/.simplecov +16 -0
  4. data/.travis.yml +19 -2
  5. data/Gemfile +17 -1
  6. data/README.md +36 -7
  7. data/Rakefile +37 -3
  8. data/TODO +4 -2
  9. data/bin/git-su +15 -0
  10. data/bin/git-whoami +15 -0
  11. data/features/add_user.feature +16 -0
  12. data/features/change_user_in_different_scopes.feature +16 -0
  13. data/features/clear_user.feature +16 -0
  14. data/features/configure_default_scope.feature +22 -2
  15. data/features/edit_config.feature +16 -0
  16. data/features/list_users.feature +16 -0
  17. data/features/print_current_user.feature +16 -0
  18. data/features/print_options.feature +16 -0
  19. data/features/step_definitions/gitsu_steps.rb +33 -12
  20. data/features/support/env.rb +16 -0
  21. data/features/switch_to_fully_qualified_user.feature +21 -0
  22. data/features/switch_to_multiple_users.feature +64 -0
  23. data/features/switch_to_stored_user.feature +16 -0
  24. data/gitsu.gemspec +20 -3
  25. data/lib/gitsu.rb +17 -0
  26. data/lib/gitsu/array.rb +31 -0
  27. data/lib/gitsu/config_repository.rb +49 -0
  28. data/lib/gitsu/factory.rb +26 -3
  29. data/lib/gitsu/git.rb +44 -35
  30. data/lib/gitsu/gitsu.rb +27 -3
  31. data/lib/gitsu/runner.rb +16 -0
  32. data/lib/gitsu/shell.rb +17 -2
  33. data/lib/gitsu/switcher.rb +68 -30
  34. data/lib/gitsu/user.rb +80 -11
  35. data/lib/gitsu/user_file.rb +18 -2
  36. data/lib/gitsu/user_list.rb +68 -12
  37. data/lib/gitsu/version.rb +17 -1
  38. data/man/git-su.1.ronn +36 -4
  39. data/spec/gitsu/array_spec.rb +71 -0
  40. data/spec/gitsu/bin_spec.rb +16 -0
  41. data/spec/gitsu/config_repository_spec.rb +67 -0
  42. data/spec/gitsu/git_spec.rb +36 -15
  43. data/spec/gitsu/gitsu_spec.rb +41 -18
  44. data/spec/gitsu/runner_spec.rb +16 -0
  45. data/spec/gitsu/shell_spec.rb +55 -0
  46. data/spec/gitsu/switcher_spec.rb +53 -13
  47. data/spec/gitsu/user_file_spec.rb +91 -0
  48. data/spec/gitsu/user_list_spec.rb +112 -41
  49. data/spec/gitsu/user_spec.rb +97 -0
  50. data/spec/gitsu/version_spec.rb +16 -0
  51. data/spec/spec_helper.rb +16 -0
  52. metadata +45 -28
@@ -1,3 +1,19 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  Given /^no user is selected$/ do
2
18
  step "no user is selected in any scope"
3
19
  end
@@ -27,21 +43,17 @@ Given /^user list is$/ do |user_list|
27
43
  end
28
44
 
29
45
  Then /^user list should be$/ do |user_list|
30
- read_user_list.should eq user_list
46
+ read_user_list.strip.should eq user_list
31
47
  end
32
48
 
33
49
  And /^user list contains user "(.*?)" with email "(.*?)"$/ do |name, email|
34
50
  user_list.add GitSu::User.new(name, email)
35
51
  end
36
52
 
37
- def split_args_with_shell(arg_line)
38
- `for arg in #{arg_line}; do echo $arg; done`.strip.split("\n")
39
- end
40
-
41
53
  When /^I type "(.*?)"$/ do |command_line|
42
54
  arg_line = command_line.gsub(/^git su/, "")
43
55
  args = split_args_with_shell(arg_line)
44
- gitsu.go args
56
+ runner.run { gitsu.go args }
45
57
  end
46
58
 
47
59
  Then /^I should see$/ do |expected_output|
@@ -79,6 +91,10 @@ Then /^the config file should be open in an editor$/ do
79
91
  git.editing?.should be true
80
92
  end
81
93
 
94
+ def split_args_with_shell(arg_line)
95
+ `for arg in #{arg_line}; do echo $arg; done`.strip.split("\n")
96
+ end
97
+
82
98
  class Output
83
99
  def messages
84
100
  @messages ||= []
@@ -89,8 +105,13 @@ class Output
89
105
  end
90
106
  end
91
107
 
92
- class StubGit < GitSu::Git
108
+ class StubFactory < GitSu::Factory
109
+ def git
110
+ @git ||= StubGit.new
111
+ end
112
+ end
93
113
 
114
+ class StubGit < GitSu::Git
94
115
  attr_accessor :users
95
116
 
96
117
  def initialize
@@ -166,16 +187,16 @@ def gitsu
166
187
  factory.gitsu
167
188
  end
168
189
 
190
+ def runner
191
+ factory.runner
192
+ end
193
+
169
194
  def user_list
170
195
  factory.user_list
171
196
  end
172
197
 
173
198
  def factory
174
- if @factory.nil?
175
- @factory = GitSu::Factory.new(output, user_list_file)
176
- @factory.git = StubGit.new
177
- end
178
- @factory
199
+ @factory ||= StubFactory.new(output, user_list_file)
179
200
  end
180
201
 
181
202
  def user_list_file
@@ -1,3 +1,19 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  require 'simplecov'
2
18
 
3
19
  lib_path = File.expand_path('../../../lib', __FILE__)
@@ -1,3 +1,19 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  Feature: Switch to fully qualified user
2
18
  As a new user
3
19
  I want to switch to my Git user
@@ -5,6 +21,11 @@ Feature: Switch to fully qualified user
5
21
 
6
22
  Scenario: Switch to fully qualified user
7
23
  Given no user is selected
24
+ And user list is empty
8
25
  When I type "git su 'John Galt <jg@example.com>'"
9
26
  Then I should see "Switched local user to John Galt <jg@example.com>"
10
27
  And user "John Galt <jg@example.com>" should be selected in "local" scope
28
+ And user list should be
29
+ """
30
+ jg@example.com : John Galt
31
+ """
@@ -0,0 +1,64 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ Feature: Switch to multiple users
18
+ As a pairer
19
+ I want to select multiple Git users at once
20
+ So that I can commit code that I created with my pair
21
+
22
+ Scenario: Switch to fully qualified users
23
+ Given no user is selected
24
+ When I type "git su 'John Galt <jg@example.com>' 'Joseph Porter <jp@example.com>'"
25
+ Then I should see "Switched local user to John Galt and Joseph Porter <dev+jg+jp@example.com>"
26
+ And user "John Galt and Joseph Porter <dev+jg+jp@example.com>" should be selected in "local" scope
27
+
28
+ Scenario: Switch to stored users
29
+ Given no user is selected
30
+ Given user list is
31
+ """
32
+ a@example.com: Johnny Z
33
+ c@example.com: Johnny X
34
+ b@example.com: Johnny Y
35
+ """
36
+ When I type "git su jy jx jz"
37
+ Then I should see "Switched local user to Johnny Z, Johnny Y and Johnny X <dev+a+b+c@example.com>"
38
+ And user "Johnny Z, Johnny Y and Johnny X <dev+a+b+c@example.com>" should be selected in "local" scope
39
+
40
+ Scenario: User not found
41
+ Given user list is
42
+ """
43
+ porter@example.com: Joseph Porter
44
+ """
45
+ When I type "git su frances joseph"
46
+ Then I should see "No user found matching 'frances'"
47
+ And no user should be selected in "local" scope
48
+
49
+ Scenario: User already matched
50
+ Given user list is
51
+ """
52
+ a@example.com: Johnny A
53
+ b@example.com: Johnny B
54
+ """
55
+ When I type "git su ja jb ja"
56
+ Then I should see "Couldn't find a combination of unique users matching 'ja', 'jb' and 'ja'"
57
+
58
+ Scenario: No group email configured
59
+ Given the Git configuration has "gitsu.groupEmailAddress" set to ""
60
+
61
+ Scenario: Group email configured
62
+ Given the Git configuration has "gitsu.groupEmailAddress" set to "pairs@example.org"
63
+ When I type "git su 'John Galt <jg@example.com>' 'Joseph Porter <jp@example.com>'"
64
+ And user "John Galt and Joseph Porter <pairs+jg+jp@example.org>" should be selected in "local" scope
@@ -1,3 +1,19 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  Feature: Switch to stored user
2
18
  As an user
3
19
  I want to quickly switch to my user
@@ -1,4 +1,20 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # Gitsu
3
+ # Copyright (C) 2013 drrb
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
2
18
  lib = File.expand_path('../lib', __FILE__)
3
19
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
20
  require 'gitsu/version'
@@ -7,14 +23,14 @@ Gem::Specification.new do |gem|
7
23
  gem.name = "gitsu"
8
24
  gem.version = GitSu::VERSION
9
25
  gem.authors = ["drrb"]
10
- gem.email = ["drrb@github.com"]
26
+ gem.email = ["drrrrrrrrrrrb@gmail.com"]
11
27
  gem.license = "GPL-3"
12
28
  gem.description = %q{Manage your Git users}
13
29
  gem.summary = <<-EOF
14
30
  Gitsu allows you to quickly configure and switch between Git users, for
15
- different projects and contexts
31
+ different projects and contexts, and pair programming.
16
32
  EOF
17
- gem.homepage = "http://drrb.github.com/gitsu"
33
+ gem.homepage = "http://drrb.github.io/gitsu"
18
34
 
19
35
  gem.files = `git ls-files`.split($/)
20
36
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -23,6 +39,7 @@ Gem::Specification.new do |gem|
23
39
 
24
40
  # Dependencies
25
41
  gem.add_development_dependency('coveralls', '>= 0.6.3')
42
+ gem.add_development_dependency('json') # Coveralls needs it
26
43
  gem.add_development_dependency('rake')
27
44
  gem.add_development_dependency('rspec')
28
45
  gem.add_development_dependency('cucumber')
@@ -1,4 +1,21 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  require 'gitsu/factory'
18
+ require 'gitsu/config_repository'
2
19
  require 'gitsu/git'
3
20
  require 'gitsu/gitsu'
4
21
  require 'gitsu/runner'
@@ -0,0 +1,31 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ class Array
18
+ def to_sentence
19
+ if empty?
20
+ ""
21
+ elsif size == 1
22
+ last.to_s
23
+ else
24
+ "#{self[0..-2].map{|e| e.to_s}.join(", ")} and #{last.to_s}"
25
+ end
26
+ end
27
+
28
+ def pluralize(word)
29
+ size > 1 ? word + "s" : word
30
+ end
31
+ end
@@ -0,0 +1,49 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module GitSu
18
+ class ConfigRepository
19
+ class InvalidConfigError < RuntimeError
20
+ end
21
+
22
+ def initialize(git)
23
+ @git = git
24
+ end
25
+
26
+ def get(key)
27
+ @git.get_config(:derived, key)
28
+ end
29
+
30
+ def default_select_scope
31
+ scope_string = get_gitsu_config "defaultSelectScope", "local"
32
+ if scope_string =~ /^(local|global|system)$/
33
+ scope_string.to_sym
34
+ else
35
+ raise InvalidConfigError, "Invalid configuration value found for gitsu.defaultSelectScope: '#{scope_string}'. Expected one of 'local', 'global', or 'system'."
36
+ end
37
+ end
38
+
39
+ def group_email_address
40
+ get_gitsu_config "groupEmailAddress", "dev@example.com"
41
+ end
42
+
43
+ private
44
+ def get_gitsu_config(key, default)
45
+ value = get "gitsu.#{key}"
46
+ value.empty? ? default : value
47
+ end
48
+ end
49
+ end
@@ -1,6 +1,21 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  module GitSu
2
18
  class Factory
3
- attr_accessor :git
4
19
  def initialize(output, user_list_file)
5
20
  @output, @user_list_file = output, File.expand_path(user_list_file)
6
21
  end
@@ -9,12 +24,20 @@ module GitSu
9
24
  @git ||= CachingGit.new(Shell.new)
10
25
  end
11
26
 
27
+ def config_repository
28
+ @config_repository ||= ConfigRepository.new(git)
29
+ end
30
+
12
31
  def user_list
13
- @user_list ||= UserList.new(@user_list_file)
32
+ @user_list ||= UserList.new(user_file)
33
+ end
34
+
35
+ def user_file
36
+ UserFile.new(@user_list_file)
14
37
  end
15
38
 
16
39
  def switcher
17
- @switcher ||= Switcher.new(git, user_list, @output)
40
+ @switcher ||= Switcher.new(config_repository, git, user_list, @output)
18
41
  end
19
42
 
20
43
  def gitsu
@@ -1,8 +1,21 @@
1
+ # Gitsu
2
+ # Copyright (C) 2013 drrb
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
1
17
  module GitSu
2
18
  class Git
3
- class InvalidConfigError < RuntimeError
4
- end
5
-
6
19
  class ConfigSettingError < RuntimeError
7
20
  end
8
21
 
@@ -10,22 +23,6 @@ module GitSu
10
23
  @shell = shell
11
24
  end
12
25
 
13
- def config_command(scope, suffix)
14
- command = "git config "
15
- unless scope == :derived
16
- command << "--#{scope} "
17
- end
18
- command << suffix
19
- end
20
-
21
- def execute_config_command(scope, command)
22
- @shell.execute config_command(scope, command)
23
- end
24
-
25
- def capture_config_command(scope, command)
26
- @shell.capture config_command(scope, command)
27
- end
28
-
29
26
  def get_config(scope, key)
30
27
  capture_config_command(scope, key)
31
28
  end
@@ -83,17 +80,6 @@ module GitSu
83
80
  execute_config_command(:derived, "--get-colorbool color.ui")
84
81
  end
85
82
 
86
- def default_select_scope
87
- scope_string = get_config(:derived, "git-su.defaultSelectScope")
88
- if scope_string.empty?
89
- :local
90
- elsif scope_string =~ /^(local|global|system)$/
91
- scope_string.to_sym
92
- else
93
- raise InvalidConfigError, "Invalid configuration value found for git-su.defaultSelectScope: '#{scope_string}'. Expected one of 'local', 'global', or 'system'."
94
- end
95
- end
96
-
97
83
  def render(user)
98
84
  if color_output?
99
85
  user_color = get_color "blue"
@@ -112,6 +98,28 @@ module GitSu
112
98
  def commit(file, message)
113
99
  @shell.execute("git commit #{file} --message='#{message}'")
114
100
  end
101
+
102
+ def list_files(*options)
103
+ flags = options.map {|o| "--#{o}"}.join " "
104
+ @shell.capture("git ls-files #{flags}").split "\n"
105
+ end
106
+
107
+ private
108
+ def config_command(scope, suffix)
109
+ command = "git config "
110
+ unless scope == :derived
111
+ command << "--#{scope} "
112
+ end
113
+ command << suffix
114
+ end
115
+
116
+ def execute_config_command(scope, command)
117
+ @shell.execute config_command(scope, command)
118
+ end
119
+
120
+ def capture_config_command(scope, command)
121
+ @shell.capture config_command(scope, command)
122
+ end
115
123
  end
116
124
 
117
125
  class CachingGit < Git
@@ -121,6 +129,12 @@ module GitSu
121
129
  @colors[color_name] ||= super
122
130
  end
123
131
 
132
+ def get_config(scope, key)
133
+ @config ||= {}
134
+ @config[scope] ||= {}
135
+ @config[scope][key] ||= super
136
+ end
137
+
124
138
  def color_output?
125
139
  @color_output.nil? ? @color_output = super : @color_output
126
140
  end
@@ -129,10 +143,5 @@ module GitSu
129
143
  # Git complains if you try to clear the user when the config file is missing
130
144
  super unless selected_user(scope).none?
131
145
  end
132
-
133
- def selected_user(scope)
134
- @selected_users ||= {}
135
- @selected_users[scope] ||= super
136
- end
137
146
  end
138
147
  end