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.
- data/.gitignore +20 -0
- data/.travis.yml +10 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +182 -0
- data/Rakefile +15 -0
- data/lib/minigit.rb +161 -0
- data/lib/minigit/version.rb +3 -0
- data/minigit.gemspec +27 -0
- data/spec/minigit_git_dir_spec.rb +97 -0
- data/spec/minigit_spec.rb +141 -0
- data/spec/minigit_switches_for_spec.rb +53 -0
- data/spec/spec_helper.rb +38 -0
- metadata +168 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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
|
+
|
data/lib/minigit.rb
ADDED
@@ -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
|
data/minigit.gemspec
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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~
|