minigit 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.
@@ -0,0 +1,20 @@
1
+ *~
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+ /.rbx
20
+ /log
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ bundler_args: --without development_workstation
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.2
6
+ - 1.9.3
7
+ # - jruby-18mode # JRuby in 1.8 mode
8
+ # - jruby-19mode # JRuby in 1.9 mode
9
+ - rbx-18mode
10
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in minigit.gemspec
4
+ gemspec
5
+
6
+ # Optional development environment
7
+ group :development_workstation do
8
+ gem "pry", :require => false
9
+ gem "minitest-ansi"
10
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Maciej Pasternacki
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,182 @@
1
+ # Minigit
2
+
3
+ Minigit is a minimal Ruby interface for Git. It is a simple proxy that
4
+ runs Git commands, and optionally captures output. It does not provide
5
+ any abstraction provided by Grit or Git gems. It is just a simple
6
+ wrapper over `system('git ...')` call. It also allows capturing output
7
+ of Git commands.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'minigit'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install minigit
22
+
23
+ ## Usage
24
+
25
+ To use the library in your code, simply require it.
26
+
27
+ ```ruby
28
+ require 'minigit'
29
+ ```
30
+
31
+ ### One-off Commands
32
+
33
+ You can run one-off commands simply by calling methods on the `MiniGit`
34
+ class:
35
+
36
+ ```ruby
37
+ MiniGit.branch # => nil (`git branch` output goes directly to terminal)
38
+ ```
39
+
40
+ To capture output, use `MiniGit::Capturing`:
41
+
42
+ ```ruby
43
+ MiniGit::Capturing.branch # => "* master\n"
44
+ ```
45
+
46
+ Methods are translated directly into Git commands. Arguments are
47
+ translated into command-line switches and arguments:
48
+
49
+ ```ruby
50
+ MiniGit.status # git status
51
+ MiniGit.status :s => true # git status -s
52
+ MiniGit.status :short => true # git status --short
53
+ MiniGit.log :n => 5 # git log -n 5
54
+ MiniGit.log({:n => 5}, 'path/' # git log -n 5 path/
55
+ MiniGit.ls_tree :HEAD # git ls-tree HEAD
56
+ MiniGit.something {:a => true}, 'foo', [1, {2 => 3}, 4], 'a_b', :c_d
57
+ # Not useful, but shows how arguments are composed and interpreted:
58
+ # git something -a foo 1 -2 3 4 a_b c-d
59
+ ```
60
+
61
+ For scripted access or to run a Git subcommand with underscore
62
+ character, use the `git` method:
63
+
64
+ ```ruby
65
+ MiniGit.git :foo_bar, :baz => true # git foo-bar --baz
66
+ MiniGit.git 'foo_bar', :baz => true # git foo_bar --baz
67
+ ```
68
+
69
+ The `MiniGit` class methods call out to Git without any particular
70
+ parameters, it behaves as if you just called git in your current
71
+ directory.
72
+
73
+ ### Instances
74
+
75
+ You can create instances of `MiniGit` and `MiniGit::Capturing`. If you
76
+ don't provide any arguments, the instance will behave as if the class
77
+ methods have been called - just run `git` in current directory. The
78
+ methods are also the same. If you call a `capturing` method, you get
79
+ instance of the `MiniGit::Capturing` class; if you call a `noncapturing`
80
+ method, you get instance of `MiniGit`.
81
+
82
+ ```ruby
83
+ git = MiniGit.new
84
+ git.branch # => nil (output shown to the terminal)
85
+ git.capturing.branch # => "* master\n"
86
+ ```
87
+
88
+ ```ruby
89
+ cgit = MiniGit::Capturing.new
90
+ git.branch # => "* master\n"
91
+ git.noncapturing.branch # => nil (output shown to the terminal)
92
+ ```
93
+
94
+ You can also provide a path specifying the Git repo. It can be:
95
+
96
+ * a working directory
97
+ * a file in or subdirectory of a working directory
98
+ * a bare repository
99
+ * a `.git` directory (which will be trated as a bare repository)
100
+
101
+ MiniGit will find the Git directory and work tree automagically by
102
+ calling out to `git rev-parse --git-dir --show-toplevel`, will set
103
+ `git_dir` and `git_work_tree` attributes, and add them as environment
104
+ variables when calling Git to have the calls work with a specified
105
+ repository. The `git_dir` and `git_work_tree` attributes are preserved
106
+ over `#capturing` and `#noncapturing` calls.
107
+
108
+ ```ruby
109
+ MiniGit.log :n => 1, :oneline => true # 47aac92 MiniGit.git method
110
+ MiniGit.new.log :n => 1, :oneline => true # 47aac92 MiniGit.git method
111
+ MiniGit.new('../vendorificator').log :n => 1, :oneline => true
112
+ # b485d32 Merge branch 'release/0.1.1' into develop
113
+ MiniGit.new('../vendorificator').capturing.log :n => 1, :oneline => true
114
+ # => "b485d32 Merge branch 'release/0.1.1' into develop\n"
115
+ ```
116
+
117
+ ### Git command
118
+
119
+ By default, MiniGit just calls `git`. You can override the Git command
120
+ on a couple levels:
121
+
122
+ * Instance level (when instantiating and as an attribute) will
123
+ override Git command for that instance, and instance it creates via
124
+ `#capturing` / `#noncapturing`:
125
+
126
+ ```ruby
127
+ MiniGit.new(nil, :git_command => '/path/to/git')
128
+ MiniGit.new('/path/to/repo', :git_command => '/path/to/git')
129
+ ```
130
+
131
+ ```ruby
132
+ git = MiniGit.new
133
+ git.git_command = '/path/to/git'
134
+ ```
135
+
136
+ * Class level - when set on subclass, will be used by this class
137
+ methods of this subclass, and as a default for instances of this
138
+ subclass.
139
+
140
+ ```ruby
141
+ class CustomGit < MiniGit
142
+ self.git_command = '/path/to/git'
143
+ end
144
+ CustomGit.git_command # => "/path/to/git"
145
+ CustomGit.new.git_command # => "/path/to/git"
146
+ CustomGit.new(nil, :git_command => '/other/git').git_command
147
+ # => "/other/git"
148
+ MiniGit.new.git_command # => "git"
149
+ MiniGit.git_command # => "git"
150
+ MiniGit::Capturing.git_command # => "git"
151
+ ```
152
+
153
+ * MiniGit level - Changing `MiniGit.git_command` will be used as a
154
+ default for MiniGit itself, and for all its subclasses and subclass
155
+ instances that don't override it.
156
+
157
+ ```ruby
158
+ MiniGit.git_command = '/yet/another/git' # => "/yet/another/git"
159
+ MiniGit.new.git_command # => "/yet/another/git"
160
+ MiniGit::Capturing.git_command # => "/yet/another/git"
161
+ CustomGit.git_command # => "/path/to/git"
162
+ CustomGit.new.git_command # => "/path/to/git"
163
+ ```
164
+
165
+ ## Issues
166
+
167
+ Non-capturing MiniGit doesn't always play well when Git is configured
168
+ to use pager. You can disable it by setting `GIT_PAGER` environment
169
+ variable to an empty string:
170
+
171
+ ```ruby
172
+ ENV['GIT_PAGER'] = ''
173
+ ```
174
+
175
+ ## Contributing
176
+
177
+ 1. Fork it
178
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
179
+ 3. Commit your changes (`git commit -am 'Add some feature'`), together
180
+ with specs for them
181
+ 4. Push to the branch (`git push origin my-new-feature`)
182
+ 5. Create new Pull Request
@@ -0,0 +1,15 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup
4
+
5
+ require "bundler/gem_tasks"
6
+ require 'rake/testtask'
7
+
8
+ desc "Run Minitest specs"
9
+ Rake::TestTask.new :spec do |task|
10
+ task.libs << 'spec'
11
+ task.test_files = FileList['spec/**/*_spec.rb']
12
+ end
13
+
14
+ task :default => [:spec]
15
+
@@ -0,0 +1,161 @@
1
+ require 'pathname'
2
+ require 'mixlib/shellout'
3
+
4
+ require "minigit/version"
5
+
6
+ class MiniGit
7
+ class << self
8
+ attr_writer :git_command
9
+
10
+ def git_command
11
+ @git_command || ( (self==::MiniGit) ? 'git' : ::MiniGit.git_command )
12
+ end
13
+
14
+ def method_missing(meth, *args, &block)
15
+ _myself.git(meth, *args)
16
+ end
17
+
18
+ def git(*args)
19
+ _myself.git(*args)
20
+ end
21
+
22
+ protected
23
+
24
+ def _myself
25
+ @myself ||= self.new
26
+ end
27
+ end
28
+
29
+ class GitError < RuntimeError
30
+ attr_reader :command, :status, :info
31
+ def initialize(command, status, info={})
32
+ @status = status.dup
33
+ @command = command
34
+ @info = info
35
+ super("Failed to run git #{command.join(' ')}: #{@status}")
36
+ end
37
+ end
38
+
39
+ attr_writer :git_command
40
+ attr_reader :git_dir, :git_work_tree
41
+
42
+ def git_command
43
+ @git_command || self.class.git_command
44
+ end
45
+
46
+ def find_git_dir(where)
47
+ path = Pathname.new(where)
48
+ raise ArgumentError, "#{where} does not seem to exist" unless path.exist?
49
+ path = path.dirname unless path.directory?
50
+ grp = Mixlib::ShellOut.new(
51
+ git_command, 'rev-parse', '--git-dir', '--show-toplevel',
52
+ :cwd => path.to_s)
53
+ grp.run_command
54
+ grp.error!
55
+ grp.stdout.lines.map { |ln| path.join(Pathname.new(ln.strip)).realpath.to_s }
56
+ rescue Mixlib::ShellOut::ShellCommandFailed
57
+ raise ArgumentError, "Invalid repository path #{where}; Git said: #{grp.stderr.inspect}"
58
+ end
59
+
60
+ def initialize(where=nil, opts={})
61
+ where, opts = nil, where if where.is_a?(Hash)
62
+ @git_command = opts[:git_command] if opts[:git_command]
63
+ if where
64
+ @git_dir, @git_work_tree = find_git_dir(where)
65
+ else
66
+ @git_dir = opts[:git_dir] if opts[:git_dir]
67
+ @git_work_tree = opts[:git_work_tree] if opts[:git_work_tree]
68
+ end
69
+ end
70
+
71
+ def git(*args)
72
+ argv = switches_for(*args)
73
+ system(
74
+ {'GIT_DIR' => git_dir, 'GIT_WORK_TREE' => git_work_tree},
75
+ git_command, *argv)
76
+ raise GitError.new(argv, $?) unless $?.success?
77
+ end
78
+
79
+ def method_missing(meth, *args, &block)
80
+ self.git(meth, *args)
81
+ end
82
+
83
+ def switches_for(*args)
84
+ rv = []
85
+ args.each do |arg|
86
+ case arg
87
+ when Hash
88
+ arg.keys.sort_by(&:to_s).each do |k|
89
+ short = (k.to_s.length == 1)
90
+ switch = short ? "-#{k}" : "--#{k}".gsub('_', '-')
91
+ Array(arg[k]).each do |value|
92
+ if value == true
93
+ rv << switch
94
+ elsif short
95
+ rv << switch
96
+ rv << value.to_s
97
+ else
98
+ rv << "#{switch}=#{value}"
99
+ end
100
+ end
101
+ end
102
+ when String
103
+ rv << arg
104
+ when Enumerable
105
+ rv += switches_for(*arg)
106
+ when Symbol
107
+ rv << arg.to_s.gsub('_', '-')
108
+ else
109
+ rv << arg.to_s
110
+ end
111
+ end
112
+ rv
113
+ end
114
+
115
+ def capturing
116
+ @capturing ||= Capturing.new(:git_command => @git_command,
117
+ :git_dir => @git_dir,
118
+ :git_work_tree => @git_work_tree)
119
+ end
120
+
121
+ def noncapturing
122
+ self
123
+ end
124
+
125
+ if RUBY_VERSION =~ /^1\.8\./
126
+ def system(*args)
127
+ return Kernel.system(*args) unless args.first.is_a?(Hash)
128
+ begin
129
+ env, oenv = args.shift, {}
130
+ env.keys.each { |k| oenv[k], ENV[k] = ENV[k], env[k] }
131
+ Kernel.system(*args)
132
+ ensure
133
+ oenv.each { |k,v| if v.nil? then ENV.delete(k) else ENV[k] = v end }
134
+ end
135
+ end
136
+ end
137
+
138
+ class Capturing < MiniGit
139
+ attr_reader :shellout
140
+
141
+ def git(*args)
142
+ argv = switches_for(*args)
143
+ argv << { :environment => { 'GIT_DIR' => git_dir, 'GIT_WORK_TREE' => git_work_tree } }
144
+ @shellout = Mixlib::ShellOut.new(git_command, *argv)
145
+ @shellout.run_command.error!
146
+ @shellout.stdout
147
+ rescue Mixlib::ShellOut::ShellCommandFailed
148
+ raise GitError.new(argv, @shellout.status, :shellout => @shellout)
149
+ end
150
+
151
+ def capturing
152
+ self
153
+ end
154
+
155
+ def noncapturing
156
+ @noncapturing ||= MiniGit.new(:git_command => @git_command,
157
+ :git_dir => @git_dir,
158
+ :git_work_tree => @git_work_tree)
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,3 @@
1
+ class MiniGit
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'minigit/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "minigit"
8
+ gem.version = MiniGit::VERSION
9
+ gem.authors = ["Maciej Pasternacki"]
10
+ gem.email = ["maciej@pasternacki.net"]
11
+ gem.description = 'A simple Ruby interface for Git'
12
+ gem.summary = 'A simple Ruby interface for Git'
13
+ gem.homepage = "https://github.com/3ofcoins/minigit"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'mixlib-shellout'
21
+
22
+ gem.add_development_dependency 'wrong', '>= 0.7.0'
23
+ gem.add_development_dependency 'rake'
24
+ gem.add_development_dependency 'minitest'
25
+ gem.add_development_dependency 'mocha'
26
+ gem.add_development_dependency 'simplecov'
27
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe MiniGit do
4
+ let(:work_tree) { tmp_path.join('wt') }
5
+ let(:git_dir) { work_tree.join('.git') }
6
+ let(:bare_git_dir) { tmp_path.join('bare.git') }
7
+ let(:file_in_work_tree) { work_tree.join('a_file') }
8
+
9
+ before :all do
10
+ git_dir.mkpath
11
+ bare_git_dir.mkpath
12
+ FileUtils.touch(file_in_work_tree.to_s)
13
+ end
14
+
15
+ describe '#find_git_dir' do
16
+ let(:git) { MiniGit.new }
17
+
18
+ before :each do
19
+ Mixlib::ShellOut.any_instance.stubs(:run_command)
20
+ Mixlib::ShellOut.any_instance.stubs(:error!)
21
+ end
22
+
23
+ it "Returns a pair of pathnames by running `git rev-parse`" do
24
+ Mixlib::ShellOut.any_instance.stubs(:stdout).returns("#{git_dir}\n#{work_tree}\n")
25
+ assert { git.find_git_dir('.') == [ git_dir.realpath.to_s, work_tree.realpath.to_s ] }
26
+ end
27
+
28
+ it "returns only a single pathname when only one pathname returned" do
29
+ Mixlib::ShellOut.any_instance.stubs(:stdout).returns("#{bare_git_dir}\n")
30
+ assert { git.find_git_dir('.') == [ bare_git_dir.realpath.to_s ] }
31
+ end
32
+
33
+ it 'works fine with relative pathnames' do
34
+ Mixlib::ShellOut.any_instance.stubs(:stdout).returns(".git\n")
35
+ assert { git.find_git_dir(work_tree.to_s) == [ git_dir.realpath.to_s ] }
36
+
37
+ Mixlib::ShellOut.any_instance.stubs(:stdout).returns(".git\n")
38
+ assert { git.find_git_dir(work_tree.relative_path_from(Pathname.getwd).to_s) == [ git_dir.realpath.to_s ] }
39
+ end
40
+
41
+ it 'works fine when given a file' do
42
+ Mixlib::ShellOut.any_instance.stubs(:stdout).returns(".git\n.\n")
43
+ assert { git.find_git_dir(file_in_work_tree.to_s) == [ git_dir.realpath.to_s, work_tree.realpath.to_s ] }
44
+ end
45
+
46
+ it "throws an error when given a nonexistent path" do
47
+ assert { ArgumentError === rescuing { git.find_git_dir('/does/not/exist') } }
48
+ end
49
+
50
+ it "throws an error when git returns error code" do
51
+ Mixlib::ShellOut.any_instance.stubs(:error!).raises(Mixlib::ShellOut::ShellCommandFailed)
52
+ assert { ArgumentError === rescuing { git.find_git_dir('.') } }
53
+ end
54
+ end
55
+
56
+ describe '#initialize' do
57
+ it "doesn't set @git_dir or @work_tree when not given arguments" do
58
+ MiniGit.any_instance.expects(:find_git_dir).never
59
+ git = MiniGit.new
60
+ assert { git.git_dir.nil? }
61
+ assert { git.git_work_tree.nil? }
62
+ end
63
+
64
+ it 'calls find_git_dir when given a path' do
65
+ MiniGit.any_instance.expects(:find_git_dir).once.returns( [ git_dir.realpath.to_s, work_tree.realpath.to_s ] )
66
+ git = MiniGit.new('.')
67
+ assert { git.git_dir == git_dir.realpath.to_s }
68
+ assert { git.git_work_tree == work_tree.realpath.to_s }
69
+ end
70
+
71
+ it "sets only git_dir when find_git_dir doesn't return work tree" do
72
+ MiniGit.any_instance.expects(:find_git_dir).once.returns( [ bare_git_dir.realpath.to_s ] )
73
+ git = MiniGit.new('.')
74
+ assert { git.git_dir == bare_git_dir.realpath.to_s }
75
+ assert { git.git_work_tree.nil? }
76
+ end
77
+ end
78
+
79
+ describe '#git' do
80
+ it 'Calls system() with GIT_DIR and GIT_WORK_TREE environment variables set' do
81
+ git = MiniGit.new
82
+ git.expects(:system).with({'GIT_DIR' => nil, 'GIT_WORK_TREE' => nil}, 'git', 'status')
83
+ git.status
84
+
85
+ MiniGit.any_instance.expects(:find_git_dir).once.returns( [ bare_git_dir.realpath.to_s ] )
86
+ git = MiniGit.new('.')
87
+ git.expects(:system).with({'GIT_DIR' => bare_git_dir.realpath.to_s, 'GIT_WORK_TREE' => nil}, 'git', 'status')
88
+ git.status
89
+
90
+ MiniGit.any_instance.expects(:find_git_dir).once.returns( [ git_dir.realpath.to_s, work_tree.realpath.to_s ] )
91
+ git = MiniGit.new('.')
92
+ git.expects(:system).with({'GIT_DIR' => git_dir.realpath.to_s, 'GIT_WORK_TREE' => work_tree.realpath.to_s}, 'git', 'status')
93
+ git.status
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+
3
+ describe MiniGit do
4
+ GIT_ENV = { 'GIT_DIR' => nil, 'GIT_WORK_TREE' => nil }
5
+ let(:git) { MiniGit.new }
6
+
7
+ describe '#git_command' do
8
+ it 'defaults to "git"' do
9
+ assert { git.git_command == 'git' }
10
+ end
11
+
12
+ it 'can be overriden per instance' do
13
+ git.git_command = 'other'
14
+ assert { git.git_command == 'other' }
15
+ end
16
+
17
+ it 'specifies how git is run' do
18
+ git.expects(:system).with(GIT_ENV, 'other', 'whatever', '--foo=bar')
19
+ git.git_command = 'other'
20
+ git.whatever :foo => 'bar'
21
+ end
22
+
23
+ it 'has precedence MiniGit -> class -> instance' do
24
+ gc = git.capturing
25
+
26
+ assert { git.git_command == 'git' }
27
+ assert { gc.git_command == 'git' }
28
+ assert { MiniGit.git_command == 'git' }
29
+ assert { MiniGit::Capturing.git_command == 'git' }
30
+
31
+ MiniGit.git_command = 'foo'
32
+ assert { git.git_command == 'foo' }
33
+ assert { gc.git_command == 'foo' }
34
+ assert { MiniGit.git_command == 'foo' }
35
+ assert { MiniGit::Capturing.git_command == 'foo' }
36
+
37
+ MiniGit::Capturing.git_command = 'bar'
38
+ assert { git.git_command == 'foo' }
39
+ assert { gc.git_command == 'bar' }
40
+ assert { MiniGit.git_command == 'foo' }
41
+ assert { MiniGit::Capturing.git_command == 'bar' }
42
+
43
+ git.git_command = 'baz'
44
+ assert { git.git_command == 'baz' }
45
+ assert { gc.git_command == 'bar' }
46
+ assert { MiniGit.git_command == 'foo' }
47
+ assert { MiniGit.new.git_command == 'foo' }
48
+ assert { MiniGit::Capturing.git_command == 'bar' }
49
+
50
+ gc.git_command = 'quux'
51
+ assert { git.git_command == 'baz' }
52
+ assert { gc.git_command == 'quux' }
53
+ assert { MiniGit.git_command == 'foo' }
54
+ assert { MiniGit.new.git_command == 'foo' }
55
+ assert { MiniGit::Capturing.git_command == 'bar' }
56
+ assert { MiniGit::Capturing.new.git_command == 'bar' }
57
+
58
+ MiniGit.git_command = nil
59
+ MiniGit::Capturing.git_command = nil
60
+ end
61
+ end
62
+
63
+ describe '#git' do
64
+ it 'calls git with given options' do
65
+ git.expects(:system).with(GIT_ENV, 'git', 'status')
66
+ git.git(:status)
67
+
68
+ git.expects(:system).with(GIT_ENV, 'git', 'log', '--oneline').once
69
+ git.git(:log, :oneline => true)
70
+ end
71
+
72
+ it 'raises an error if command fails' do
73
+ git.git_command = 'false'
74
+ assert { MiniGit::GitError === rescuing { git.git(:wrong) } }
75
+ system 'true' # to reset $? to a clean value
76
+ end
77
+ end
78
+
79
+ describe '#method_missing' do
80
+ it 'calls out to git' do
81
+ git.expects(:git).with(:rev_parse, :git_dir => true)
82
+ git.rev_parse :git_dir => true
83
+ end
84
+ end
85
+
86
+ describe '#capturing' do
87
+ it 'returns instance of MiniGit::Capturing' do
88
+ assert { MiniGit::Capturing === git.capturing }
89
+ end
90
+ end
91
+
92
+ describe '#noncapturing' do
93
+ it 'returns instance of MiniGit' do
94
+ assert { MiniGit === git.noncapturing }
95
+ deny { MiniGit::Capturing == git.noncapturing }
96
+ end
97
+ end
98
+
99
+ describe MiniGit::Capturing do
100
+ let(:git) { MiniGit::Capturing.new }
101
+
102
+ describe "#git" do
103
+ it "calls git and returns its output as a string" do
104
+ assert { git.git(:help) =~ /commit/ }
105
+ end
106
+
107
+ it 'raises an error if command fails' do
108
+ git.git_command = 'false'
109
+ assert { MiniGit::GitError === rescuing { git.git(:wrong) } }
110
+ end
111
+ end
112
+
113
+
114
+ describe '#capturing' do
115
+ it 'returns instance of MiniGit::Capturing' do
116
+ assert { MiniGit::Capturing === git.capturing }
117
+ end
118
+ end
119
+
120
+ describe '#noncapturing' do
121
+ it 'returns instance of MiniGit' do
122
+ assert { MiniGit === git.noncapturing }
123
+ deny { MiniGit::Capturing == git.noncapturing }
124
+ end
125
+ end
126
+ end
127
+
128
+ describe '.method_missing' do
129
+ it 'calls out to a hidden instance of self' do
130
+ MiniGit.any_instance.expects(:system).with(GIT_ENV, 'git', 'status')
131
+ MiniGit.status
132
+ end
133
+ end
134
+
135
+ describe '.git' do
136
+ it 'also calls out to a hidden instance of self' do
137
+ MiniGit.any_instance.expects(:system).with(GIT_ENV, 'git', 'status')
138
+ MiniGit.git :status
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+ require 'pathname'
3
+
4
+ describe MiniGit do
5
+ let(:git) { MiniGit::new }
6
+
7
+ describe '#switches_for' do
8
+ it 'passes regular arguments' do
9
+ assert { git.switches_for('foo') == %w'foo' }
10
+ assert { git.switches_for('foo', 'bar') == %w'foo bar' }
11
+ assert { git.switches_for('foo', 'bar', 'baz quux') == ['foo', 'bar', 'baz quux'] }
12
+ end
13
+
14
+ it 'converts hashes to switches' do
15
+ assert { git.switches_for(:foo => 'bar') == %w'--foo=bar' }
16
+ assert { git.switches_for(:f => 'bar') == %w'-f bar' }
17
+ assert { git.switches_for('foo', 'bar', :baz => 'quux') == %w'foo bar --baz=quux' }
18
+ assert { git.switches_for({ :foo => 'bar' }, 'baz', 'quux') == %w'--foo=bar baz quux' }
19
+ end
20
+
21
+ it 'sorts switch names in hash' do
22
+ assert { git.switches_for(:foo => 'bar', :baz => 'quux') == %w'--baz=quux --foo=bar' }
23
+ end
24
+
25
+ it 'converts underscores to dashes' do
26
+ assert { git.switches_for(:foo_bar_baz => 'quux') == %w'--foo-bar-baz=quux' }
27
+ end
28
+
29
+ it 'recursively flattens the arrays' do
30
+ assert { git.switches_for('foo', ['bar', 'baz'], 'quux') == %w'foo bar baz quux' }
31
+ assert { git.switches_for('foo', ['bar', ['baz']], 'quux') == %w'foo bar baz quux' }
32
+ assert { git.switches_for('foo', ['bar', {:baz => 'quux'}], 'xyzzy') == %w'foo bar --baz=quux xyzzy' }
33
+ end
34
+
35
+ it 'multiplies the switch if hash value is an array' do
36
+ assert { git.switches_for(:foo => ['bar', 'baz', 'quux']) == %w'--foo=bar --foo=baz --foo=quux' }
37
+ end
38
+
39
+ it 'converts positional aruments to strings' do
40
+ assert { git.switches_for(:foo, Pathname.new(__FILE__)) == ['foo', __FILE__] }
41
+ end
42
+
43
+ it 'interpretes true value as a boolean switch' do
44
+ assert { git.switches_for(:foo => true) == %w'--foo' }
45
+ assert { git.switches_for(:f => true) == %w'-f' }
46
+ end
47
+
48
+
49
+ it 'converts underscore to dash in a positional symbol' do
50
+ assert { git.switches_for(:foo_bar, 'baz_quux') == %w'foo-bar baz_quux' }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ Bundler.setup
4
+
5
+ require 'fileutils'
6
+ require 'pathname'
7
+
8
+ require 'simplecov'
9
+ SimpleCov.start
10
+
11
+ require 'minitest/spec'
12
+ require 'minitest/autorun'
13
+ require 'mocha/setup'
14
+ require 'wrong'
15
+ require 'wrong/adapters/minitest'
16
+
17
+ begin
18
+ require 'minitest/ansi'
19
+ rescue LoadError # that's fine, we'll live without it
20
+ else
21
+ MiniTest::ANSI.use! if STDOUT.tty?
22
+ end
23
+
24
+ require 'minigit'
25
+
26
+ # MiniTest pokes into these methods, and triggers errors from
27
+ # method_missing. Let's give it something to live with.
28
+ class MiniGit
29
+ def self.to_str ; to_s ; end
30
+ def self.to_ary ; to_a ; end
31
+ end
32
+
33
+ class MiniTest::Spec
34
+ attr_reader :tmp_path
35
+ before do
36
+ @tmp_path = Pathname.new(__FILE__).dirname.dirname.join('tmp').expand_path
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: minigit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Maciej Pasternacki
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mixlib-shellout
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: wrong
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 0.7.0
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: 0.7.0
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: mocha
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: simplecov
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: A simple Ruby interface for Git
111
+ email:
112
+ - maciej@pasternacki.net
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - .travis.yml
119
+ - Gemfile
120
+ - LICENSE.txt
121
+ - README.md
122
+ - Rakefile
123
+ - lib/minigit.rb
124
+ - lib/minigit/version.rb
125
+ - minigit.gemspec
126
+ - spec/minigit_git_dir_spec.rb
127
+ - spec/minigit_spec.rb
128
+ - spec/minigit_spec.rb~
129
+ - spec/minigit_switches_for_spec.rb
130
+ - spec/spec_helper.rb
131
+ - spec/spec_helper.rb~
132
+ homepage: https://github.com/3ofcoins/minigit
133
+ licenses: []
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ segments:
145
+ - 0
146
+ hash: 1654588845628700009
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ segments:
154
+ - 0
155
+ hash: 1654588845628700009
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 1.8.25
159
+ signing_key:
160
+ specification_version: 3
161
+ summary: A simple Ruby interface for Git
162
+ test_files:
163
+ - spec/minigit_git_dir_spec.rb
164
+ - spec/minigit_spec.rb
165
+ - spec/minigit_spec.rb~
166
+ - spec/minigit_switches_for_spec.rb
167
+ - spec/spec_helper.rb
168
+ - spec/spec_helper.rb~