hipe-githelper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ coverage
3
+ wtfami
4
+ tmp.*
5
+ pkg
data/History.txt ADDED
@@ -0,0 +1,8 @@
1
+ == 0.0.1 / 2009-12-02
2
+ * now depends on gorilla-grammar gem, more robust parsing
3
+ * different, simplified syntax
4
+ * 100% C1 testing code coverage w/ rcov
5
+ * tried several differnent automated testing platforms. settled on bacon
6
+
7
+ == 0.0.0 / 2009-11-??
8
+ * standalone version, no dependencies. hackish parser
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Mark Meves
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ = hipe-githelper
2
+
3
+ little convenience methods for git
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally. -- Use rcov if you can!
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Thank You's
16
+ * to rue for being the yoda to my luke, teaching me the force of metaprogramming by letting me find it.
17
+
18
+ == Copyright
19
+
20
+ Copyright (c) 2009 Mark Meves. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,68 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rcov/rcovtask'
4
+
5
+ Rcov::RcovTask.new do |t|
6
+ t.test_files = FileList['test/*_test.rb']
7
+ t.verbose = true # uncomment to see the executed command
8
+ t.rcov_opts = ['--exclude', 'test,/Library/Ruby/Gems/1.8/gems']
9
+ end
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gem|
14
+ gem.name = "hipe-githelper"
15
+ gem.summary = %Q{little convenience methods for git}
16
+ gem.description = %Q{command-line convenience methods for git}
17
+ gem.email = "mark dot meves at gmail dot com"
18
+ gem.homepage = "http://github.com/hipe/hipe-githelper"
19
+ gem.authors = ["Mark Meves"]
20
+ gem.add_development_dependency "bacon", ">= 1.1.0"
21
+ gem.add_dependency "hipe-gorillagrammar", ">= 0.0.1"
22
+ #gem.add_development_dependency "rspec", ">= 1.2.9"
23
+ # gem.add_development_dependency "yard", ">= 0"
24
+ # gem.add_development_dependency "cucumber", ">= 0"
25
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
26
+ end
27
+ Jeweler::GemcutterTasks.new
28
+ rescue LoadError
29
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
30
+ end
31
+
32
+ require 'spec/rake/spectask'
33
+ Spec::Rake::SpecTask.new(:spec) do |spec|
34
+ spec.libs << 'lib' << 'spec'
35
+ spec.spec_files = FileList['spec/**/*_spec.rb']
36
+ end
37
+
38
+ #Spec::Rake::SpecTask.new(:rcov) do |spec|
39
+ # spec.libs << 'lib' << 'spec'
40
+ # spec.pattern = 'spec/**/*_spec.rb'
41
+ # spec.rcov = true
42
+ #end
43
+ #
44
+ task :spec => :check_dependencies
45
+
46
+ begin
47
+ require 'cucumber/rake/task'
48
+ Cucumber::Rake::Task.new(:features)
49
+
50
+ task :features => :check_dependencies
51
+ rescue LoadError
52
+ task :features do
53
+ abort "Cucumber is not available. In order to run features, you must: sudo gem install cucumber"
54
+ end
55
+ end
56
+
57
+ task :default => :spec
58
+
59
+ begin
60
+ require 'yard'
61
+ YARD::Rake::YardocTask.new
62
+ rescue LoadError
63
+ task :yardoc do
64
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
65
+ end
66
+ end
67
+
68
+ Dir['tasks/*.rake'].each{|f| import(f) }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/githelper ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ begin
3
+ require 'hipe-githelper'
4
+ rescue LoadError
5
+ require 'rubygems'
6
+ require 'hipe-githelper'
7
+ end
8
+ Hipe::GitHelper.new.run
@@ -0,0 +1 @@
1
+ this is a bad git status string for the purpose of testing
@@ -0,0 +1,69 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{hipe-githelper}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Mark Meves"]
12
+ s.date = %q{2009-12-02}
13
+ s.default_executable = %q{githelper}
14
+ s.description = %q{command-line convenience methods for git}
15
+ s.email = %q{mark dot meves at gmail dot com}
16
+ s.executables = ["githelper"]
17
+ s.extra_rdoc_files = [
18
+ "LICENSE",
19
+ "README.rdoc"
20
+ ]
21
+ s.files = [
22
+ ".gitignore",
23
+ "History.txt",
24
+ "LICENSE",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "bin/githelper",
29
+ "example1.git.status",
30
+ "hipe-githelper.gemspec",
31
+ "lib/hipe-githelper.rb",
32
+ "tasks/bacon.rake_",
33
+ "test/argv.rb",
34
+ "test/bacon_test.rb",
35
+ "test/example1.git.status",
36
+ "test/other_testing_frameworks/coulda.all_test_.rb",
37
+ "test/other_testing_frameworks/riot.all_test_.rb",
38
+ "test/other_testing_frameworks/teststrap.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/hipe/hipe-githelper}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.5}
44
+ s.summary = %q{little convenience methods for git}
45
+ s.test_files = [
46
+ "test/argv.rb",
47
+ "test/bacon_test.rb",
48
+ "test/other_testing_frameworks/coulda.all_test_.rb",
49
+ "test/other_testing_frameworks/riot.all_test_.rb",
50
+ "test/other_testing_frameworks/teststrap.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ s.add_development_dependency(%q<bacon>, [">= 1.1.0"])
59
+ s.add_runtime_dependency(%q<hipe-gorillagrammar>, [">= 0.0.1"])
60
+ else
61
+ s.add_dependency(%q<bacon>, [">= 1.1.0"])
62
+ s.add_dependency(%q<hipe-gorillagrammar>, [">= 0.0.1"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<bacon>, [">= 1.1.0"])
66
+ s.add_dependency(%q<hipe-gorillagrammar>, [">= 0.0.1"])
67
+ end
68
+ end
69
+
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'hipe-gorillagrammar'
4
+ require 'hipe-gorillagrammar/extensions/syntax'
5
+
6
+
7
+ # This puppy is intended to be a standalone command line script written in ruby
8
+ # with useful features that are not out-of-the-box available for git -- Features like
9
+ # "add all files that haven't been added yet" or "add all files that have been modified"
10
+ # or "do an equivalent of svn-info.". If you use this a lot, it is recommended that you do something like
11
+ # "alias gh='githelper' in your ~/.bash_profile"
12
+ #
13
+ # For example:
14
+ # githelper info
15
+ # githelper add modified and add untracked and delete deleted as dry run
16
+ # githelper add both and delete deleted as dry run
17
+ # githelper help
18
+ #
19
+ # Just for fun, the syntax of this command line tool is kind of strange in two ways:
20
+ #
21
+ # 1) instead of --options-like="this" or options like -abc, we just type them inline with the commands
22
+ # so for example, we don't say "githelper add modified --dry-run" ,
23
+ # we say "githelper add modified as dry run"
24
+ #
25
+ # 2) the options can appear before or after the "verb phrase", so in addition to the above we could also say
26
+ # "githelper as dry run add modified"
27
+ #
28
+ #
29
+ # Wishlist: required verb modifiers. utilize ruby 1.9 stuff
30
+
31
+
32
+ module Hipe
33
+
34
+ class GitHelper
35
+
36
+ class BufferString < String # there was StringIO but i couldn't figure out how to use it
37
+ def read
38
+ output = self.dup
39
+ self.replace('')
40
+ output
41
+ end
42
+ def puts mixed
43
+ if mixed.kind_of? Array
44
+ mixed.each{|x| puts x}
45
+ else
46
+ self << mixed
47
+ self << "\n" if (mixed.kind_of? String and mixed.length > 0 and mixed[mixed.size-1] != "\n"[0])
48
+ end
49
+ end
50
+ public :puts
51
+ end
52
+
53
+ class Command
54
+ def initialize name, desc, ast
55
+ @name, @desc, @ast = name, desc, ast
56
+ end
57
+ def syntax; @symbol.syntax; end
58
+ def help_short opts
59
+ buffer = opts[:buffer] || ''
60
+ col1width,col2width = opts[:col1width], opts[:col2width]
61
+ syntax = sprintf(%{ %-#{col1width-3}s },@ast.syntax)
62
+ buffer << syntax
63
+ (buffer << ("\n" + ' ' * col1width )) if syntax.length > (col1width)
64
+ buffer << self.class.wordwrap(@desc,col2width).gsub(/$\n/,"\n"+' '*col1width)
65
+ buffer
66
+ end
67
+ def self.wordwrap text, line_width # thansks rails
68
+ text.split("\n").collect do |line|
69
+ line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
70
+ end * "\n"
71
+ end
72
+ end
73
+
74
+ class GitHelperException < Exception; end
75
+
76
+ @screen = {:col1width=>26, :col2width=>46}
77
+ VERSION = '0.0.1beta'
78
+ REGGIE =
79
+ %r<
80
+ (?:^\#\sOn\sbranch.*$\n)
81
+ (?:^\#\sYour\sbranch\sis\sahead[^\n]+\n\#\n)?
82
+ (?:^\#\s^\#\sInitial\sCommit\n\#\s)?
83
+ (?:
84
+ (?:^\#\sChanges\sto\sbe\scommitted:$\n)
85
+ (?:^\#\s+[[:print:]]+$\n)+
86
+ (?:^\#$\n)
87
+ ((?:^\#\s+(?:new\sfile|modified|deleted|renamed|copied|[a-z ]+):\s+.+$\n)+)
88
+ (?:^\#$\n)
89
+ )?
90
+ (?:
91
+ (?:^\#\sChanged\sbut\snot\supdated:$\n)
92
+ (?:^\#\s+[[:print:]]+$\n)+
93
+ (?:^\#$\n)
94
+ ((?:^\#\s+(?:modified|deleted):\s+.+$\n)+)
95
+ (?:^\#$\n)
96
+ )?
97
+ (?:
98
+ (?:^\#\sUntracked\sfiles:$\n)
99
+ (?:^\#\s+[[:print:]]+$\n)+
100
+ (?:^\#$\n)
101
+ ((?:^\#\s+.+$\n)+)
102
+ )?
103
+ >ix
104
+ @grammar = Hipe.GorillaGrammar {
105
+ :help_command =~ 'help'
106
+ :info_command =~ 'info'
107
+ :version_command =~ 'version'
108
+ :delete_command =~ ['delete',zero_or_one('deleted')]
109
+ :add_command =~ ['add',one('untracked','modified','both')]
110
+ :command =~ :add_command | :delete_command | :help_command |
111
+ :version_command | :info_command
112
+ :dry =~ zero_or_one([zero_or_one('as'),'dry',zero_or_one('run')])
113
+ :argv =~ [:command,zero_or_more(['and',:command]),:dry]
114
+ }
115
+
116
+ class << self
117
+ attr_accessor :commands, :grammar, :screen
118
+ end
119
+
120
+ @commands = []
121
+ def self.command name, *other, &block
122
+ @commands << Command.new(name, other[0], @grammar[(name.to_s+'_command'.to_s).to_sym])
123
+ end
124
+
125
+ def initialize(opts={})
126
+ opts = {:output_buffer => $stdout }.merge opts
127
+ @out = opts[:output_buffer]
128
+ end
129
+
130
+ def program_name; File.basename($PROGRAM_NAME) end
131
+
132
+ def run
133
+ self << ARGV
134
+ end
135
+
136
+ def << (argv)
137
+ tree = parse_command argv
138
+ execute_command tree
139
+ @out
140
+ end
141
+
142
+ def read
143
+ @out.read # will fail unless the user passed in something that responds to this.
144
+ end
145
+
146
+ def parse_command argv
147
+ if (0==argv.size || ['--help','-h'].include?(argv[0])) then argv[0] = 'help'
148
+ elsif (['-v','--version'].include?(argv[0])) then argv[0] = 'version'
149
+ end
150
+ tree = self.class.grammar.parse argv
151
+ tree
152
+ end
153
+
154
+ def execute_command tree
155
+ if tree.is_error?
156
+ @out.puts tree.message
157
+ @out.puts "Please try 'help' for syntax and usage."
158
+ else
159
+ commands = tree.recurse {|x| (x.name.to_s =~ /_command$/) ? [x] : [] }
160
+ dry = tree.recurse {|x| (x.name.to_s =~ /dry/) ? [x] : [] }
161
+ commands.each do |x|
162
+ send(x.name.to_s.match(/^(.+)_command$/).captures[0],[x,dry])
163
+ end
164
+ end
165
+ @out
166
+ end
167
+
168
+ command :help, "show this screen"
169
+ def help args
170
+ argv = self.class.grammar[:argv].fork_for_parse # make a deep copy,
171
+ dry = argv.instance_variable_get('@group').pop.dereference # explain dry separately
172
+ argv_syntax = %{#{argv.syntax} #{dry.syntax}}
173
+ @out << <<-END.gsub(/^ {6}/, '')
174
+ Helpful little shortcuts for git.
175
+ usage: #{program_name} #{argv_syntax}
176
+
177
+ available commands:
178
+ END
179
+ @out << self.class.commands.map{ |x| x.help_short(self.class.screen) }.join("\n")
180
+ @out << "\n\n"
181
+ @out << "available options:\n"+Command.new(:dry,
182
+ "Don't actually do anything, just show a preview of what you would do (where applicable.)", dry).
183
+ help_short(self.class.screen)
184
+ @out << "\n"
185
+ end
186
+
187
+ command :version, "show version number of this script"
188
+ def version args
189
+ @out.puts %{#{program_name} version #{VERSION}}
190
+ end
191
+
192
+ command :add, "add all files of that kind"
193
+ def add tree
194
+ is_dry = tree[1].size > 0 && tree[1][0].name == :dry
195
+ do_untracked = ['both','untracked'].include? tree[0][1][0]
196
+ do_modified = ['both','modified'].include? tree[0][1][0]
197
+ tree = git_status_parse_tree
198
+ raise GitHelperException("failed to parse command") unless do_untracked || do_modified
199
+ list = {}
200
+ list[:modified] = do_modified ? tree[:changed]['modified'] : [] # names are strings!
201
+ list[:untracked] = do_untracked ? tree[:untracked] : []
202
+ [:modified,:untracked].each do |which|
203
+ count = ( list[which] && list[which].size ) ? list[which].size : 0
204
+ @out << %{# adding #{count} #{which.to_s} file(s)#{(is_dry&&count>0)? ' (dry run -- not actually doing it)' : '' }\n}
205
+ next if count == 0
206
+ list[which].each do |filename|
207
+ cmd = %{git add #{filename}}
208
+ @out.puts cmd
209
+ unless is_dry
210
+ if (res = shell!(cmd)).length > 0
211
+ raise GitHelperException.new(%{I wasn't expecting any response from this. Got: "#{res}"})
212
+ end
213
+ end
214
+ end
215
+ end
216
+ @out.puts '# done.'
217
+ end
218
+
219
+ def shell! cmd
220
+ %x{#{cmd}}
221
+ end
222
+
223
+ def git_status_string
224
+ shell! 'git status'
225
+ end
226
+
227
+ def try_to_write_git_status_to_file(str)
228
+ i = 0
229
+ head = File.expand_path(FileUtils.pwd)+'/example'
230
+ tail = '.git.status'
231
+ begin
232
+ filename = %{#{head}#{i+=1}#{tail}}
233
+ end while File.exist?(filename)
234
+ e = nil
235
+ File.open(filename, 'w'){|fh| fh.write(str)} rescue e
236
+ e ? e.message : %{Wrote git status to "#{filename}".}
237
+ end
238
+
239
+ def git_status_parse_tree
240
+ str = self.git_status_string
241
+ unless (matches = REGGIE.match str)
242
+ response = try_to_write_git_status_to_file(str)
243
+ raise GitHelperException.new(%{Sorry, failed to parse the git status string. Please make a note }+
244
+ %{of the git status for a bug report. #{response}})
245
+ end
246
+ caps = matches.captures
247
+ ret = {
248
+ :pending => _to_hash(caps[0]),
249
+ :changed => _to_hash(caps[1]),
250
+ :untracked => caps[2] ? caps[2].scan(/^\#\t(.*)$\n/).flatten : []
251
+ }
252
+ ret
253
+ end
254
+
255
+ def _to_hash(mixed)
256
+ mixed ||= ''
257
+ hash = Hash.new{|x,y|x[y] = []}
258
+ x = mixed.scan(/^\#\t([^:]+): +(.*)$\n/)
259
+ x.each{|pair| hash[pair[0]] << pair[1] }
260
+ hash
261
+ end
262
+
263
+ command :info, "Similar to svn info (Thanks Duane Johnson!)"
264
+ # This is a port of Duane Johnson's shell script (duane D0T johnson AT gmail D0T com, License: MIT):
265
+ # http://blog.inquirylabs.com/2008/06/12/git-info-kinda-like-svn-info/
266
+ # Based on discussion at http://kerneltrap.org/mailarchive/git/2007/11/12/406496
267
+ def info args
268
+ # Find base of git directory
269
+ until Dir.glob('.git').length > 0 do
270
+ if '/'==Dir.pwd
271
+ @out.puts "can't find .git directory this or any parent folder!"
272
+ return
273
+ end
274
+ Dir.chdir('..')
275
+ end
276
+
277
+ @out.puts "(in "+Dir.pwd+')'
278
+
279
+ # Show various information about this git directory
280
+ @out.puts "== Remote URL: "
281
+ @out.puts `git remote -v`
282
+
283
+ @out.puts "== Remote Branches: "
284
+ @out.puts `git branch -r`
285
+
286
+ @out.puts "== Local Branches:"
287
+ @out.puts `git branch`
288
+ @out.puts "\n"
289
+
290
+ @out.puts "== Configuration (.git/config)"
291
+ File.open('.git/config'){|fh| @out.puts fh.read }
292
+ @out.puts "\n"
293
+
294
+ @out.puts "== Most Recent Commit"
295
+ @out.puts `git log --max-count=1`
296
+ @out.puts "\n"
297
+
298
+ @out.puts "Type 'git log' for more commits, or 'git show' for full commit details."
299
+
300
+ end
301
+
302
+ end # class GitHelper
303
+
304
+ end # module Hipe
305
+
306
+ # pz.to_enum.with_index.select{|e,i| e > 5 }.map{|e,i| i } from manveru sunday 18:08
307
+ # we considered using Diff::LCS.LCS for this but -- we need contiguous matches
data/tasks/bacon.rake_ ADDED
@@ -0,0 +1,77 @@
1
+ desc 'Run all bacon specs with pretty output'
2
+ task :bacon do
3
+ require 'open3'
4
+ require 'scanf'
5
+ require 'matrix'
6
+
7
+ PROJECT_SPECS = FileList[
8
+ 'test/*_test.rb'
9
+ ]
10
+
11
+ specs = PROJECT_SPECS
12
+
13
+ some_failed = false
14
+ specs_size = specs.size
15
+ require 'ruby-debug'
16
+ len = specs.map{|s| s.size }.sort.last
17
+ total_tests = total_assertions = total_failures = total_errors = 0
18
+ totals = Vector[0, 0, 0, 0]
19
+
20
+ red, yellow, green = "\e[31m%s\e[0m", "\e[33m%s\e[0m", "\e[32m%s\e[0m"
21
+ left_format = "%4d/%d: %-#{len + 11}s"
22
+ spec_format = "%d specifications (%d requirements), %d failures, %d errors"
23
+
24
+ load_path = File.expand_path('../../lib', __FILE__)
25
+
26
+ specs.each_with_index do |spec, idx|
27
+ print(left_format % [idx + 1, specs_size, spec])
28
+
29
+ Open3.popen3(RUBY, '-I', load_path, spec) do |sin, sout, serr|
30
+ out = sout.read.strip
31
+ err = serr.read.strip
32
+
33
+ # this is conventional
34
+ if out =~ /^Bacon::Error: (needed .*)/
35
+ puts(yellow % ("%6s %s" % ['', $1]))
36
+ elsif out =~ /^Spec (precondition: "[^"]*" failed)/
37
+ puts(yellow % ("%6s %s" % ['', $1]))
38
+ elsif out =~ /^Spec require: "require" failed: "(no such file to load -- [^"]*)"/
39
+ puts(yellow % ("%6s %s" % ['', $1]))
40
+ else
41
+ total = nil
42
+
43
+ out.each_line do |line|
44
+ scanned = line.scanf(spec_format)
45
+
46
+ next unless scanned.size == 4
47
+
48
+ total = Vector[*scanned]
49
+ break
50
+ end
51
+
52
+ if total
53
+ totals += total
54
+ tests, assertions, failures, errors = total_array = total.to_a
55
+
56
+ if tests > 0 && failures + errors == 0
57
+ puts((green % "%6d passed") % tests)
58
+ else
59
+ some_failed = true
60
+ puts(red % " failed")
61
+ puts out unless out.empty?
62
+ puts err unless err.empty?
63
+ end
64
+ else
65
+ some_failed = true
66
+ puts(red % " failed")
67
+ puts out unless out.empty?
68
+ puts err unless err.empty?
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ total_color = some_failed ? red : green
75
+ puts(total_color % (spec_format % totals.to_a))
76
+ exit 1 if some_failed
77
+ end
data/test/argv.rb ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ # this is for debugging with how the shell parses strings into tokens
3
+ puts Marshal.dump(ARGV)
@@ -0,0 +1,155 @@
1
+ # bacon test/bacon_test.rb
2
+ # WARNING! currently this uses the shell to see exactly how the shell will parse a string
3
+ # and turn it into an array. These tests will likely fail on windows. @FIXME
4
+
5
+
6
+ require 'rubygems'
7
+ require 'hipe-githelper'
8
+ require 'bacon'
9
+
10
+ ##################################
11
+ module TestHelper
12
+ # dangerous! -- we pass anything to shell and execute it to see how the shell parses it
13
+ @argv_filename = %{#{File.expand_path(File.dirname(__FILE__))}/argv.rb}
14
+ class << self
15
+ attr_accessor :argv_filename
16
+ end
17
+ def shell! str
18
+ response = %x{ruby #{TestHelper.argv_filename} #{str}}
19
+ Marshal.load response
20
+ end
21
+ end
22
+ include TestHelper
23
+ #################################
24
+
25
+ include TestHelper
26
+
27
+ describe "Parsing user input in General context" do
28
+
29
+ before do
30
+ @g = Hipe::GitHelper.new(:output_buffer=>(@s = Hipe::GitHelper::BufferString.new))
31
+ end
32
+
33
+ it "should help on no input (b1)" do
34
+ @g << shell!('')
35
+ @g.read.should.match( /usage[^\n]+(\n[^\n]*){5}/ )
36
+ end
37
+
38
+ it "should complain on bad input (b2)" do
39
+ @g << shell!('bling blang blong')
40
+ @g.read.should.match( /don't know what you mean by .*bling.*expecting.*help/)
41
+ end
42
+
43
+ it "should do version command (b3)" do
44
+ @g << shell!('version')
45
+ @g.read.should.match( /version.*\d+\.\d+\.\d/)
46
+ end
47
+ end
48
+
49
+ describe Hipe::GitHelper::BufferString,"in General context" do
50
+ it "puts should work with arrays" do
51
+ s = Hipe::GitHelper::BufferString.new
52
+ s.puts(['alpha','beta'])
53
+ s.read.should.equal "alpha\nbeta\n"
54
+ end
55
+ end
56
+
57
+
58
+ describe 'Actual script in real environment, in General context' do
59
+ before do
60
+ @g = Hipe::GitHelper.new(:output_buffer=>(@s = Hipe::GitHelper::BufferString.new))
61
+ end
62
+
63
+ it "should report in actual status (Fragile test--needs actual git repository) (r1)" do # was p3
64
+ @g << shell!('info');
65
+ @g.read.should.match(
66
+ /Remote URL.*== Remote Branches.*== Local Branches.*== Configuration.*== Most Recent Commit.*/m
67
+ )
68
+ end
69
+
70
+ it "should do add as dry run (Fragile test--needs actual git repository)(r2)" do
71
+ @g << shell!('add modified as dry run')
72
+ s = @g.read
73
+ s.should.match(/^# adding /)
74
+ end
75
+
76
+ it "should actually run from the command line (r3)" do
77
+ fullpath = File.expand_path(File.dirname(__FILE__))+'/../bin/githelper'
78
+ %x{#{fullpath} version}.should.match(/version.*\d+\.\d+\.\d+/i)
79
+ end
80
+
81
+
82
+ it "should complain about missing git, or that ...blah blah(p6)" do
83
+ # "YOU'RE GOING TO FEEL REALLY DUMB WHEN THIS FAILS"
84
+ @app = Hipe::GitHelper.new
85
+ class << @app; self end.send(:define_method,'shell!'){'dummy response for testing'} # metaprogramming just for fun\
86
+ def @app.git_status_string # @todo fixme -- this needs actual stubbing or mocking or whatever
87
+ File.open(File.dirname(__FILE__)+'/example1.git.status','r'){|f| f.read}
88
+ end
89
+ fn = 'erase-me-now-'+Time.now.strftime('%Y-%m-%d--%H:%I:%S')
90
+ FileUtils.touch fn
91
+ lambda{ @app << shell!('add untracked') }.should.raise(Hipe::GitHelper::GitHelperException).
92
+ message.should.match(/^I wasn't expecting any response from this\. Got: "dummy response for testing"$/)
93
+ FileUtils.rm fn
94
+ end
95
+
96
+ end
97
+
98
+ describe 'Parsing the git status in General context' do
99
+ before do
100
+ @app = Hipe::GitHelper.new :output_buffer=>Hipe::GitHelper::BufferString.new
101
+ def @app.git_status_string # @todo fixme -- this needs actual stubbing or mocking or whatever
102
+ File.open(File.dirname(__FILE__)+'/example1.git.status','r'){|f| f.read}
103
+ end
104
+ end
105
+
106
+ it "parses the git file into a pretty tree (p1)" do
107
+ @app.git_status_parse_tree.should.equal({
108
+ :pending=>
109
+ {"modified"=>["lib/hipe-gorillagrammar.rb", "spec/parsing_spec.rb"],
110
+ "deleted"=>["spec/unparse_spec.rb"]},
111
+ :changed=>
112
+ {"modified"=>
113
+ ["History.txt",
114
+ "README.txt",
115
+ "lib/hipe-gorillagrammar.rb",
116
+ "spec/parsing_spec.rb",
117
+ "spec/sequence_spec.rb",
118
+ "spec/shorthand_spec.rb"]},
119
+ :untracked=>
120
+ ["lame",
121
+ "oh.rb",
122
+ "spec/FOCUS",
123
+ "spec/parse_tree_spec.rb",
124
+ "spec/symbol_reference_spec.rb"]
125
+ })
126
+ end
127
+
128
+ it "should do add as dry run (p2)" do
129
+ @app << shell!('add modified as dry run')
130
+ s = @app.read
131
+ s.should.match(/add.*History.*README.txt\n(.*\n){3}/m)
132
+ end
133
+
134
+ it "should complain when not in git dir (p4)" do
135
+ name = '/tmp/this_is_a_temporary_folder_for_tests'
136
+ pwd = Dir.pwd
137
+ FileUtils.mkdir name unless File.exist?(name)
138
+ FileUtils.cd name
139
+ @app << shell!('info')
140
+ FileUtils.cd pwd
141
+ @app.read.should.match(/can't find \.git directory this or any parent folder!/)
142
+ end
143
+
144
+ it "should write that file thing.(p5)" do
145
+ str = "this is a bad git status string for the purpose of testing"
146
+ class << @app; self end.send(:define_method,:git_status_string){str} # thanks rue
147
+ begin
148
+ @app.git_status_parse_tree
149
+ rescue Hipe::GitHelper::GitHelperException => e
150
+ md = /Wrote git status to "([^"]+)"/.match(e)
151
+ md.should.be.kind_of MatchData
152
+ str.should.equal File.open(md[1],'r'){|fh| fh.read } # ridiculous test
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,27 @@
1
+ # On branch master
2
+ # Changes to be committed:
3
+ # (use "git reset HEAD <file>..." to unstage)
4
+ #
5
+ # modified: lib/hipe-gorillagrammar.rb
6
+ # modified: spec/parsing_spec.rb
7
+ # deleted: spec/unparse_spec.rb
8
+ #
9
+ # Changed but not updated:
10
+ # (use "git add <file>..." to update what will be committed)
11
+ # (use "git checkout -- <file>..." to discard changes in working directory)
12
+ #
13
+ # modified: History.txt
14
+ # modified: README.txt
15
+ # modified: lib/hipe-gorillagrammar.rb
16
+ # modified: spec/parsing_spec.rb
17
+ # modified: spec/sequence_spec.rb
18
+ # modified: spec/shorthand_spec.rb
19
+ #
20
+ # Untracked files:
21
+ # (use "git add <file>..." to include in what will be committed)
22
+ #
23
+ # lame
24
+ # oh.rb
25
+ # spec/FOCUS
26
+ # spec/parse_tree_spec.rb
27
+ # spec/symbol_reference_spec.rb
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'coulda'
3
+ require 'hipe-githelper'
4
+ include Coulda
5
+
6
+ module Helper
7
+ def get_app
8
+ Githelper.new(:output_buffer=>'')
9
+ end
10
+
11
+ def shell_argv! string
12
+ Marshal.load %x{ruby #{File.dirname(__FILE__).'/argv.rb'}}
13
+ end
14
+
15
+ end
16
+
17
+ Feature "Parse user commands" do
18
+ include helper
19
+ in_order_to "understand user requests"
20
+ as_a "pieces of software"
21
+ i_want_to "use an LA parser generator to understand commands"
22
+
23
+ Scenario "the user enters nothing" do
24
+ Given "the user inputs this" do
25
+ @app = get_app
26
+ @argv = shell_argv! ''
27
+ end
28
+ When "i parse it" do
29
+ @app << @argv
30
+ end
31
+ Then "it should make a pretty tree" do
32
+ assert_match /usage.*\n.*\n.*\n/i, @app->flush
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ # ruby test/all_test.rb
2
+ require 'rubygems'
3
+ require 'ruby-debug'
4
+ require File.dirname(__FILE__)+'/teststrap'
5
+
6
+
7
+ # dangerous -- we pass anything to shell and execute it to see how the shell parses it
8
+ def shell! str
9
+ Marshal.load %x{ruby #{File.dirname(__FILE__)}/argv #{str}}
10
+ end
11
+
12
+ class BufferString < String; def flush; t = s.dup; s.replace(''); t end end
13
+
14
+ context "parsing input" do
15
+ #setup do
16
+ # @s = BufferString.new
17
+ # Githelper.new(:output_buffer=>@s)
18
+ #end
19
+ #
20
+ #asserts("displays help when given empty input") do
21
+ #
22
+ #end
23
+ #
24
+ #
25
+ #end
26
+
27
+ end
28
+
29
+
30
+
31
+ Hipe::GitHelper.new(:output_buffer=>@s).git_status_parse_tree
32
+
33
+ context "parsing git status" do
34
+ setup do
35
+
36
+ debugger
37
+ #@s = BufferString.new
38
+ #@g = Hipe::GitHelper.new(:output_buffer=>@s)
39
+ #def @g.git_statuz_string
40
+ # File.open(File.dirname(__FILE__)+'/example1.git.status','r'){|f| f.read}
41
+ #end
42
+ #
43
+ end
44
+
45
+ asserts("parses the git file into a pretty tree"){
46
+ debugger
47
+ @g.git_status_parse_tree
48
+
49
+
50
+ }
51
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'riot'
3
+ require 'hipe-githelper'
4
+
5
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hipe-githelper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mark Meves
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-02 00:00:00 -05:00
13
+ default_executable: githelper
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bacon
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.1.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: hipe-gorillagrammar
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.1
34
+ version:
35
+ description: command-line convenience methods for git
36
+ email: mark dot meves at gmail dot com
37
+ executables:
38
+ - githelper
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .gitignore
46
+ - History.txt
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - bin/githelper
52
+ - example1.git.status
53
+ - hipe-githelper.gemspec
54
+ - lib/hipe-githelper.rb
55
+ - tasks/bacon.rake_
56
+ - test/argv.rb
57
+ - test/bacon_test.rb
58
+ - test/example1.git.status
59
+ - test/other_testing_frameworks/coulda.all_test_.rb
60
+ - test/other_testing_frameworks/riot.all_test_.rb
61
+ - test/other_testing_frameworks/teststrap.rb
62
+ has_rdoc: true
63
+ homepage: http://github.com/hipe/hipe-githelper
64
+ licenses: []
65
+
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --charset=UTF-8
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "0"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project:
86
+ rubygems_version: 1.3.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: little convenience methods for git
90
+ test_files:
91
+ - test/argv.rb
92
+ - test/bacon_test.rb
93
+ - test/other_testing_frameworks/coulda.all_test_.rb
94
+ - test/other_testing_frameworks/riot.all_test_.rb
95
+ - test/other_testing_frameworks/teststrap.rb