hipe-githelper 0.0.1

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,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