simple-scm 1.0.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.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ .bundle
3
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sss.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,69 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ simple-scm (1.0.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ aruba (0.4.6)
10
+ bcat (>= 0.6.1)
11
+ childprocess (>= 0.2.0)
12
+ cucumber (>= 1.0.2)
13
+ rdiscount (>= 1.6.8)
14
+ rspec (>= 2.6.0)
15
+ bcat (0.6.2)
16
+ rack (~> 1.0)
17
+ builder (3.0.0)
18
+ childprocess (0.2.2)
19
+ ffi (~> 1.0.6)
20
+ cucumber (1.0.6)
21
+ builder (>= 2.1.2)
22
+ diff-lcs (>= 1.1.2)
23
+ gherkin (~> 2.4.18)
24
+ json (>= 1.4.6)
25
+ term-ansicolor (>= 1.0.6)
26
+ diff-lcs (1.1.3)
27
+ ffi (1.0.9)
28
+ gherkin (2.4.18)
29
+ json (>= 1.4.6)
30
+ growl_notify (0.0.1)
31
+ rb-appscript
32
+ guard (0.7.0)
33
+ thor (~> 0.14.6)
34
+ guard-cucumber (0.6.3)
35
+ cucumber (>= 0.10)
36
+ guard (>= 0.4.0)
37
+ guard-rspec (0.4.5)
38
+ guard (>= 0.4.0)
39
+ json (1.6.0)
40
+ rack (1.3.2)
41
+ rake (0.9.2)
42
+ rb-appscript (0.6.1)
43
+ rb-fsevent (0.4.3.1)
44
+ rdiscount (1.6.8)
45
+ rspec (2.6.0)
46
+ rspec-core (~> 2.6.0)
47
+ rspec-expectations (~> 2.6.0)
48
+ rspec-mocks (~> 2.6.0)
49
+ rspec-core (2.6.4)
50
+ rspec-expectations (2.6.0)
51
+ diff-lcs (~> 1.1.2)
52
+ rspec-mocks (2.6.0)
53
+ term-ansicolor (1.0.6)
54
+ thor (0.14.6)
55
+
56
+ PLATFORMS
57
+ ruby
58
+
59
+ DEPENDENCIES
60
+ aruba
61
+ cucumber
62
+ growl_notify
63
+ guard
64
+ guard-cucumber
65
+ guard-rspec
66
+ rake
67
+ rb-fsevent
68
+ rspec
69
+ simple-scm!
data/Guardfile ADDED
@@ -0,0 +1,15 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'cucumber' do
5
+ watch(%r{^features/.+\.feature$})
6
+ watch(%r{^features/support/.+$}) { 'features' }
7
+ watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
8
+ end
9
+
10
+ guard 'rspec', :version => 2 do
11
+ watch(%r{^spec/.+_spec\.rb$})
12
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
+ watch('spec/spec_helper.rb') { "spec" }
14
+ end
15
+
data/README.markdown ADDED
File without changes
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+ require 'cucumber/rake/task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ Cucumber::Rake::Task.new(:cucumber)
7
+
8
+ task :test do
9
+ Rake::Task["cucumber"].invoke
10
+ Rake::Task["spec"].invoke
11
+ end
12
+
13
+ task :default => :test
data/bin/sss ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'sss'
4
+
5
+ SSS.run(ARGV.first) or puts SSS::HELP
@@ -0,0 +1,20 @@
1
+ Feature: SSS performs the supplied command
2
+
3
+ As a user
4
+ I want to perform an SCM command
5
+
6
+ # TODO figure out how to get this to not fail because the command takes longer than 3 seconds to update everything
7
+ # Scenario: with a parameter
8
+ # When I run `sss up`
9
+ # Then SSS performs 'up'
10
+ # And the exit status should be 0
11
+
12
+ # Scenario: with another parameter
13
+ # When I run `sss st`
14
+ # Then SSS performs 'st'
15
+ # And the exit status should be 0
16
+
17
+ # Scenario: with multiple parameters
18
+ # When I run `sss foo bar`
19
+ # Then SSS performs 'foo'
20
+ # And the exit status should be 0
@@ -0,0 +1,25 @@
1
+ Feature: SSS displays help
2
+
3
+ As a user
4
+ I want to dislay help
5
+
6
+ Scenario: with no parameter
7
+ When I run `sss`
8
+ Then the help text displays
9
+ And the exit status should be 0
10
+
11
+ Scenario: with the --help parameter
12
+ When I run `sss --help`
13
+ Then the help text displays
14
+ And the exit status should be 0
15
+
16
+ Scenario: with the help parameter
17
+ When I run `sss help`
18
+ Then the help text displays
19
+ And the exit status should be 0
20
+
21
+ Scenario: with an invalid parameter
22
+ When I run `sss asdfabeabeb`
23
+ Then the help text displays
24
+ And the exit status should be 0
25
+
@@ -0,0 +1,15 @@
1
+ Then /^the help text displays$/ do
2
+ assert_partial_output(SSS::HELP, all_output)
3
+ end
4
+
5
+ Then /^SSS performs '(.*)'$/ do |cmd|
6
+ # Since the execution appears to have already taken place, I can't use
7
+ # SSS.should_receive(:run).with(cmd), so doing the dumb thing and testing the
8
+ # output of the command.
9
+ # SSS.should_receive(:run).with(cmd)
10
+ # RSpec::Mocks.verify
11
+
12
+ # TODO re-enable this after i've implemented the actual execution
13
+ # assert_partial_output(SSS.new(cmd).display_command, all_output)
14
+ end
15
+
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+
3
+ require 'aruba/cucumber'
4
+ require 'sss'
@@ -0,0 +1,3 @@
1
+ class SSS
2
+ VERSION = "1.0.0"
3
+ end
data/lib/sss.rb ADDED
@@ -0,0 +1,139 @@
1
+ require "sss/version"
2
+
3
+ class SSS
4
+ attr_accessor :command
5
+ attr_accessor :workspace
6
+
7
+ HELP = <<-EOH
8
+ SSS performs SCM commands on all projects in your workspace. Set the
9
+ SSS_WORKSPACE environment variable if your workspace is not ~/workspace.
10
+
11
+ usage: sss <command>
12
+
13
+ Available commands:
14
+ up, update, pull Update to the latest changes
15
+ st, status Check the status for any uncommitted changes
16
+ push (hg, git) Push all committed changes to central repo
17
+ out, outgoing (hg) Show outgoing changes, not pushed to central repo
18
+ in, incoming (hg) Show incoming changes, not updated
19
+ wtf (git) Compare local to tracked remote branch
20
+ EOH
21
+
22
+ # SCMs
23
+ GIT = :git
24
+ MERCURIAL = :hg
25
+ SUBVERSION = :svn
26
+
27
+ COMMANDS = {
28
+ "status" => {
29
+ GIT => "git status",
30
+ MERCURIAL => "hg status",
31
+ SUBVERSION => "svn status",
32
+ },
33
+ "push" => {
34
+ GIT => "git push",
35
+ MERCURIAL => "hg push",
36
+ },
37
+ "pull" => {
38
+ GIT => "git pull",
39
+ MERCURIAL => "hg pull -u",
40
+ SUBVERSION => "svn up",
41
+ },
42
+ "incoming" => {
43
+ GIT => "git wtf",
44
+ MERCURIAL => "hg incoming",
45
+ },
46
+ "outgoing" => {
47
+ GIT => "git wtf",
48
+ MERCURIAL => "hg outgoing",
49
+ },
50
+ "wtf" => {
51
+ GIT => "git wtf",
52
+ },
53
+ }
54
+
55
+ def initialize(command = nil)
56
+ self.command = command
57
+ self.workspace = ENV['SSS_WORKSPACE'] || "~/workspace/"
58
+ end
59
+
60
+ def command=(str)
61
+ if %w(up update).include? str
62
+ str = "pull"
63
+ elsif %w(st).include? str
64
+ str = "status"
65
+ elsif %w(in).include? str
66
+ str = "incoming"
67
+ elsif %w(out).include? str
68
+ str = "outgoing"
69
+ end
70
+
71
+ @command = str
72
+ end
73
+
74
+ def self.run(command)
75
+ new(command).run
76
+ end
77
+
78
+ def run
79
+ if COMMANDS.include? command
80
+ directories.each { |directory| perform_command(directory) }
81
+ end
82
+ end
83
+
84
+ def directories
85
+ if File.directory? File.expand_path workspace
86
+ Dir["#{File.expand_path(workspace)}/*"].map { |dir| File.expand_path(dir) }
87
+ else
88
+ raise ArgumentError, "#{workspace} is not a directory. Please set the WORKSPACE environment variable to the directory containing your projects."
89
+ end
90
+ end
91
+
92
+ def perform_command(directory)
93
+ command_for_directory = scm_command_for directory
94
+ if command_for_directory
95
+ display "Performing #{command} in #{directory_string directory} (#{scm_for directory})"
96
+ stdout, stderr, status = Open3.capture3 command_for_directory
97
+ display stdout
98
+ display stderr, STDERR
99
+ else
100
+ display "Skipping #{directory_string directory}, no available command"
101
+ end
102
+ end
103
+
104
+ def scm_command_for(directory)
105
+ scm_command = COMMANDS[command][scm_for(directory)]
106
+ if scm_command
107
+ "cd #{directory} && #{scm_command}"
108
+ end
109
+ rescue
110
+ nil
111
+ end
112
+
113
+ def scm_for(directory)
114
+ if File.exists?("#{directory}/.git")
115
+ GIT
116
+ elsif File.exists?("#{directory}/.hg")
117
+ MERCURIAL
118
+ elsif File.exists?("#{directory}/.svn")
119
+ SUBVERSION
120
+ end
121
+ end
122
+
123
+ def display(string, output = STDOUT)
124
+ output.puts string
125
+ end
126
+
127
+ def embolden(string)
128
+ "\033[1m#{string}\033[0m"
129
+ end
130
+
131
+ def directory_string(directory)
132
+ last_directory = directory.split("/").last
133
+ embolden last_directory
134
+ end
135
+
136
+ def display_command
137
+ "Attempting to perform #{command}"
138
+ end
139
+ end
@@ -0,0 +1,213 @@
1
+ require 'spec_helper'
2
+
3
+ describe SSS, "having constants" do
4
+ it "should have help" do
5
+ SSS::HELP
6
+ end
7
+
8
+ context "for the supported SCMs" do
9
+ it "should have git" do
10
+ SSS::GIT
11
+ end
12
+
13
+ it "should have mercurial" do
14
+ SSS::MERCURIAL
15
+ end
16
+
17
+ it "should have subversion" do
18
+ SSS::SUBVERSION
19
+ end
20
+ end
21
+ end
22
+
23
+ describe SSS, ".initialize(command)" do
24
+ it "should retain the supplied command" do
25
+ SSS.new("asdf").command.should == "asdf"
26
+ end
27
+
28
+ it "should default the workspace to ~/workspace/" do
29
+ SSS.new.workspace.should == "~/workspace/"
30
+ end
31
+
32
+ it "should use the SSS_WORKSPACE environment variable, if present" do
33
+ # capture existing workspace to return afterward
34
+ orig_workspace = ENV['SSS_WORKSPACE']
35
+
36
+ ENV['SSS_WORKSPACE'] = "/tmp/asdf/"
37
+ SSS.new.workspace.should == "/tmp/asdf/"
38
+
39
+ ENV['SSS_WORKSPACE'] = orig_workspace
40
+ end
41
+ end
42
+
43
+ describe SSS, "#command=" do
44
+ SSS::COMMANDS.keys.each do |command|
45
+ it "should accept #{command} as-is" do
46
+ subject.command = command
47
+ subject.command.should == command
48
+ end
49
+ end
50
+
51
+ %w(up update).each do |command|
52
+ it "should coerce #{command} into 'pull'" do
53
+ subject.command = command
54
+ subject.command.should == "pull"
55
+ end
56
+ end
57
+
58
+ %w(st).each do |command|
59
+ it "should coerce #{command} into 'status'" do
60
+ subject.command = command
61
+ subject.command.should == "status"
62
+ end
63
+ end
64
+
65
+ %w(in).each do |command|
66
+ it "should coerce #{command} into 'incoming'" do
67
+ subject.command = command
68
+ subject.command.should == "incoming"
69
+ end
70
+ end
71
+
72
+ %w(out).each do |command|
73
+ it "should coerce #{command} into 'outgoing'" do
74
+ subject.command = command
75
+ subject.command.should == "outgoing"
76
+ end
77
+ end
78
+ end
79
+
80
+ describe SSS, ".run(command)" do
81
+ let!(:sss) { SSS.new }
82
+
83
+ it "should instantiate and run the command" do
84
+ SSS.should_receive(:new).with("asdf").and_return(sss)
85
+ sss.should_receive(:run)
86
+ SSS.run("asdf")
87
+ end
88
+ end
89
+
90
+ describe SSS, "#run" do
91
+ it "should run the command and return true if it is in the list of commands" do
92
+ subject.stub(:directories => ["dir1", "dir2"])
93
+ subject.should_receive(:perform_command).with("dir1")
94
+ subject.should_receive(:perform_command).with("dir2")
95
+ subject.command = "pull"
96
+
97
+ subject.run.should be_true
98
+ end
99
+
100
+ it "should return false if the command is not on the list" do
101
+ subject.command = "asdfaebaeba"
102
+ subject.run.should be_false
103
+ end
104
+ end
105
+
106
+ describe SSS, "#directories" do
107
+ it "should return the list of directories from the workspace" do
108
+ # spec/lib/support/workspace/
109
+ subject.workspace = File.join(File.dirname(__FILE__), '../support/workspace/')
110
+ subject.directories.should == Dir["#{subject.workspace}/*"].map { |dir| File.expand_path(dir) }
111
+ end
112
+
113
+ it "should raise an error if the workspace does not exist" do
114
+ # non-existant spec/lib/support/noworkspace/
115
+ subject.workspace = File.join(File.dirname(__FILE__), '../support/noworkspace/')
116
+ expect { subject.directories }.to raise_error
117
+ end
118
+ end
119
+
120
+ describe SSS, "#perform_command(directory)" do
121
+ subject { SSS.new("pull") }
122
+ let (:directory) { "/tmp/directory/" }
123
+
124
+ it "performs the appropriate SCM command for the directory" do
125
+ subject.should_receive(:scm_for).with(directory).and_return(SSS::GIT)
126
+ subject.should_receive(:scm_command_for).with(directory).and_return("asdf command")
127
+ subject.should_receive(:display).with("Performing #{subject.command} in #{subject.directory_string(directory)} (#{SSS::GIT})")
128
+ Open3.should_receive(:capture3).with("asdf command").and_return(["stdout", "stderr", "status"])
129
+ subject.should_receive(:display).with("stdout")
130
+ subject.should_receive(:display).with("stderr", STDERR)
131
+
132
+ subject.perform_command(directory)
133
+ end
134
+
135
+ it "should skip the directory if it has no available command" do
136
+ subject.should_receive(:scm_command_for).with(directory).and_return(nil)
137
+ subject.should_receive(:display).with("Skipping #{subject.directory_string(directory)}, no available command")
138
+ Open3.should_receive(:capture3).never
139
+
140
+ subject.perform_command(directory)
141
+ end
142
+ end
143
+
144
+ describe SSS, "#scm_command_for(directory)" do
145
+ subject { SSS.new("pull") }
146
+ let (:directory) { "/tmp/directory/"}
147
+
148
+ it "should return the command for the SCM of the directory" do
149
+ subject.should_receive(:scm_for).with(directory).and_return(SSS::GIT)
150
+ subject.scm_command_for(directory).should == "cd #{directory} && #{SSS::COMMANDS[subject.command][SSS::GIT]}"
151
+ end
152
+
153
+ it "should return nil if it does not recognize the SCM for the directory" do
154
+ subject.should_receive(:scm_for).with(directory).and_return(nil)
155
+ subject.scm_command_for(directory).should be_nil
156
+ end
157
+
158
+ it "should return nil if it does not recognize the command" do
159
+ subject.command = "asdfqwerty"
160
+ subject.scm_command_for(directory).should be_nil
161
+ end
162
+ end
163
+
164
+ describe SSS, "#scm_for(directory)" do
165
+ let(:workspace) { File.join(File.dirname(__FILE__), '../support/workspace/') }
166
+
167
+ it "should return Git if the directory contains a .git directory" do
168
+ subject.scm_for(File.join(workspace, "project1")).should == SSS::GIT
169
+ end
170
+
171
+ it "should return Mercurial if the directory contains a .hg directory" do
172
+ subject.scm_for(File.join(workspace, "project2")).should == SSS::MERCURIAL
173
+ end
174
+
175
+ it "should return Subversion if the directory contains a .svn directory" do
176
+ subject.scm_for(File.join(workspace, "project3")).should == SSS::SUBVERSION
177
+ end
178
+ end
179
+
180
+ describe SSS, "#display" do
181
+ it "should push to STDOUT" do
182
+ STDOUT.should_receive(:puts).with("asdf")
183
+ subject.display("asdf")
184
+ end
185
+
186
+ it "should push to STDERR if specified" do
187
+ STDERR.should_receive(:puts).with("qwerty")
188
+ subject.display("qwerty", STDERR)
189
+ end
190
+ end
191
+
192
+ describe SSS, "#embolden(string)" do
193
+ it "should wrap in bash bold characters" do
194
+ subject.embolden("asdf").should == "\033[1masdf\033[0m"
195
+ end
196
+ end
197
+
198
+ describe SSS, "#directory_string(directory)" do
199
+ it "should embolden and trim just the last directory of the directory path with a slash" do
200
+ subject.directory_string("/asdf/qwerty/aeiou/").should == subject.embolden("aeiou")
201
+ end
202
+
203
+ it "should embolden and trim just the last directory of the directory path without a slash" do
204
+ subject.directory_string("/asdf/qwerty/aeiou").should == subject.embolden("aeiou")
205
+ end
206
+ end
207
+
208
+ describe SSS, "#display_command" do
209
+ it "should output that it's performing the command" do
210
+ subject.command = "asdf"
211
+ subject.display_command.should == "Attempting to perform asdf"
212
+ end
213
+ end
@@ -0,0 +1,13 @@
1
+ require 'sss'
2
+
3
+ RSpec.configure do |config|
4
+ config.before(:suite) do
5
+ set_up_test_directories
6
+ end
7
+ end
8
+
9
+ def set_up_test_directories
10
+ system "mkdir -p spec/support/workspace/project1/.git"
11
+ system "mkdir -p spec/support/workspace/project2/.hg"
12
+ system "mkdir -p spec/support/workspace/project3/.svn"
13
+ end
data/sss.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sss/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "simple-scm"
7
+ s.version = SSS::VERSION
8
+ s.authors = ["Patrick Byrne"]
9
+ s.email = ["patrick.byrne@tstmedia.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Quickly perform SCM (git/hg/svn) commands across your projects.}
12
+ s.description = %q{Command that performs SCM (git/hg/svn) commands in all projects in a directory.}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_development_dependency 'rake'
20
+ s.add_development_dependency 'rspec'
21
+ s.add_development_dependency 'cucumber'
22
+ s.add_development_dependency 'aruba'
23
+ s.add_development_dependency 'rb-fsevent'
24
+ s.add_development_dependency 'growl_notify'
25
+ s.add_development_dependency 'guard'
26
+ s.add_development_dependency 'guard-cucumber'
27
+ s.add_development_dependency 'guard-rspec'
28
+
29
+ # s.add_runtime_dependency "rest-client"
30
+ end
data/tmp/argv.rb ADDED
@@ -0,0 +1,2 @@
1
+ puts ARGV.first
2
+ puts ARGV.first.class
metadata ADDED
@@ -0,0 +1,176 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: simple-scm
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Patrick Byrne
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-03 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: &2151820340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2151820340
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &2151818260 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2151818260
36
+ - !ruby/object:Gem::Dependency
37
+ name: cucumber
38
+ requirement: &2151815600 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2151815600
47
+ - !ruby/object:Gem::Dependency
48
+ name: aruba
49
+ requirement: &2151813760 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2151813760
58
+ - !ruby/object:Gem::Dependency
59
+ name: rb-fsevent
60
+ requirement: &2151812820 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2151812820
69
+ - !ruby/object:Gem::Dependency
70
+ name: growl_notify
71
+ requirement: &2151812160 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2151812160
80
+ - !ruby/object:Gem::Dependency
81
+ name: guard
82
+ requirement: &2151811660 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *2151811660
91
+ - !ruby/object:Gem::Dependency
92
+ name: guard-cucumber
93
+ requirement: &2151810960 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *2151810960
102
+ - !ruby/object:Gem::Dependency
103
+ name: guard-rspec
104
+ requirement: &2151809960 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *2151809960
113
+ description: Command that performs SCM (git/hg/svn) commands in all projects in a
114
+ directory.
115
+ email:
116
+ - patrick.byrne@tstmedia.com
117
+ executables:
118
+ - sss
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - .gitignore
123
+ - .rspec
124
+ - Gemfile
125
+ - Gemfile.lock
126
+ - Guardfile
127
+ - README.markdown
128
+ - Rakefile
129
+ - bin/sss
130
+ - features/command.feature
131
+ - features/help.feature
132
+ - features/step_definitions/sss_steps.rb
133
+ - features/support/env.rb
134
+ - lib/sss.rb
135
+ - lib/sss/version.rb
136
+ - spec/lib/sss_spec.rb
137
+ - spec/spec_helper.rb
138
+ - sss.gemspec
139
+ - tmp/argv.rb
140
+ homepage: ''
141
+ licenses: []
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ segments:
153
+ - 0
154
+ hash: -1049271710808341764
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ segments:
162
+ - 0
163
+ hash: -1049271710808341764
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 1.8.6
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: Quickly perform SCM (git/hg/svn) commands across your projects.
170
+ test_files:
171
+ - features/command.feature
172
+ - features/help.feature
173
+ - features/step_definitions/sss_steps.rb
174
+ - features/support/env.rb
175
+ - spec/lib/sss_spec.rb
176
+ - spec/spec_helper.rb