minigit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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~