tmp-repo 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +13 -0
- data/History.txt +3 -0
- data/README.md +120 -0
- data/Rakefile +18 -0
- data/lib/tmp-repo.rb +117 -0
- data/lib/tmp-repo/version.rb +5 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/tmp-repo_spec.rb +183 -0
- data/tmp-repo.gemspec +18 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 750d50105e4fe0fd086ed4c10c8bf3f4648b17c6
|
4
|
+
data.tar.gz: ebacae5e6fd5562a16c78ee84f1f262d45546620
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d57090af6e6155920bea50f1d8fd2513bcae60ec2030c9eb5bead81e0c2f9ff740e5165c27b244edf097a130ddf8ca1bd178f0c68e37dfbd93138a72a82ef943
|
7
|
+
data.tar.gz: ab3f893e67603d9a024f8bf18c44a042e82b2bd56a68771684daa7c793efb50233c7ed527524ac53906796c91d08b097e2c1b84ef818fd001f36e355bac60833
|
data/Gemfile
ADDED
data/History.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
tmp-repo
|
2
|
+
========
|
3
|
+
|
4
|
+
[![Build Status](https://travis-ci.org/camertron/tmp-repo.svg?branch=master)](http://travis-ci.org/camertron/tmp-repo)
|
5
|
+
|
6
|
+
Creates and manages git repositories in the operating system's temporary directory. It does this by providing a thin wrapper around the git binary that's pointed at a randomly generated temporary folder.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
`gem install tmp-repo`
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
require 'tmp-repo'
|
16
|
+
```
|
17
|
+
|
18
|
+
### Basics
|
19
|
+
|
20
|
+
Creating a new `TmpRepo` will automatically create a randomly named folder in your system's temp directory and initialize a git repository in it:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
repo = TmpRepo.new
|
24
|
+
repo.working_dir # => #<Pathname:/var/folders/3x/n10r69b16bq_rlcqr3fy0rwc0000gn/T/b068487773901ffe23e66a8259711fa1>
|
25
|
+
```
|
26
|
+
|
27
|
+
Once created, you can ask your `TmpRepo` questions and perform operations on it. Don't forget to clean up after yourself when you're finished:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
repo.unlink
|
31
|
+
```
|
32
|
+
|
33
|
+
### Creating Files
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
repo.create_file('foo.txt') do |f|
|
37
|
+
f.write("I'm a new file!")
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
OR
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
file = repo.create_file('foo.txt')
|
45
|
+
file.write("I'm a new file!")
|
46
|
+
file.close
|
47
|
+
```
|
48
|
+
|
49
|
+
### Branching
|
50
|
+
|
51
|
+
To create a new branch:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
repo.create_branch('my_new_branch')
|
55
|
+
```
|
56
|
+
|
57
|
+
To check out a branch:
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
repo.checkout('my_other_branch')
|
61
|
+
```
|
62
|
+
|
63
|
+
To get the current branch:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
repo.current_branch # => 'master'
|
67
|
+
```
|
68
|
+
|
69
|
+
### Staging and Committing
|
70
|
+
|
71
|
+
To add all files to the git stage:
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
repo.add_all
|
75
|
+
```
|
76
|
+
|
77
|
+
To commit staged files:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
repo.commit('Commit message')
|
81
|
+
```
|
82
|
+
|
83
|
+
### Repo Status
|
84
|
+
|
85
|
+
`TmpRepo` instances provide a convenient way to retrieve the status of the repository via the `status` method. `status` return values are a simple hash of arrays:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
status = repo.status
|
89
|
+
status[:new_file] # => ['file1.txt', 'file2.txt']
|
90
|
+
status[:deleted] # => ['file3.txt']
|
91
|
+
status[:modified] # => ['file4.txt']
|
92
|
+
```
|
93
|
+
|
94
|
+
### Custom Commands
|
95
|
+
|
96
|
+
This library only provides wrapper methods around the most common git commands. To run additional git commands, use the `git` method:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
repo.git('rebase master')
|
100
|
+
```
|
101
|
+
|
102
|
+
In addition, the lower-level `in_repo` method wraps the given block in a `Dir.chdir`, meaning the block is executed in the context of the repo's working directory:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
repo.in_repo do
|
106
|
+
`ls` # list files in the repo's working directory
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
## Requirements
|
111
|
+
|
112
|
+
No external requirements.
|
113
|
+
|
114
|
+
## Running Tests
|
115
|
+
|
116
|
+
`bundle exec rake` should do the trick.
|
117
|
+
|
118
|
+
## Authors
|
119
|
+
|
120
|
+
* Cameron C. Dutro: http://github.com/camertron
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
4
|
+
|
5
|
+
require 'bundler'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'rubygems/package_task'
|
8
|
+
|
9
|
+
require './lib/tmp-repo'
|
10
|
+
|
11
|
+
Bundler::GemHelper.install_tasks
|
12
|
+
|
13
|
+
task :default => :spec
|
14
|
+
|
15
|
+
desc 'Run specs'
|
16
|
+
RSpec::Core::RakeTask.new do |t|
|
17
|
+
t.pattern = './spec/**/*_spec.rb'
|
18
|
+
end
|
data/lib/tmp-repo.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'pathname'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'securerandom'
|
7
|
+
|
8
|
+
class TmpRepo
|
9
|
+
class GitError < StandardError; end
|
10
|
+
|
11
|
+
attr_reader :working_dir
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@working_dir = Pathname(
|
15
|
+
File.join(Dir.tmpdir, SecureRandom.hex(16))
|
16
|
+
)
|
17
|
+
|
18
|
+
FileUtils.mkdir_p(working_dir)
|
19
|
+
git('init')
|
20
|
+
end
|
21
|
+
|
22
|
+
def unlink
|
23
|
+
FileUtils.rm_rf(working_dir.to_s)
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_file(new_file)
|
28
|
+
new_path = working_dir.join(new_file).to_s
|
29
|
+
handle = File.open(new_path, 'w+')
|
30
|
+
|
31
|
+
if block_given?
|
32
|
+
yield handle
|
33
|
+
handle.close
|
34
|
+
else
|
35
|
+
handle
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_all
|
40
|
+
git('add -A')
|
41
|
+
end
|
42
|
+
|
43
|
+
def commit(message)
|
44
|
+
git("commit -m '#{message.gsub("'", "\\\\'")}'")
|
45
|
+
end
|
46
|
+
|
47
|
+
def checkout(ref)
|
48
|
+
git("checkout #{ref}")
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_branch(branch_name)
|
52
|
+
git("checkout -b #{branch_name}")
|
53
|
+
end
|
54
|
+
|
55
|
+
def current_branch
|
56
|
+
git('rev-parse --abbrev-ref HEAD').strip
|
57
|
+
end
|
58
|
+
|
59
|
+
def status
|
60
|
+
parse_status(git('status'))
|
61
|
+
end
|
62
|
+
|
63
|
+
def git(command)
|
64
|
+
in_repo do
|
65
|
+
output = `git #{command}`
|
66
|
+
|
67
|
+
if $?.exitstatus != 0
|
68
|
+
raise GitError, output
|
69
|
+
end
|
70
|
+
|
71
|
+
output
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def in_repo
|
76
|
+
Dir.chdir(working_dir.to_s) do
|
77
|
+
yield
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def parse_status(status_text)
|
84
|
+
lines = status_text.split("\n")
|
85
|
+
status_hash = create_status_hash
|
86
|
+
statuses = possible_statuses_from(status_hash)
|
87
|
+
|
88
|
+
lines.each do |line|
|
89
|
+
index = -1
|
90
|
+
|
91
|
+
status = statuses.find do |status|
|
92
|
+
index = line =~ /#{Regexp.escape(status)}: /
|
93
|
+
end
|
94
|
+
|
95
|
+
if status
|
96
|
+
status = status_to_hash_key(status)
|
97
|
+
status_hash[status] << line[(index + status.size + 2)..-1].strip
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
status_hash
|
102
|
+
end
|
103
|
+
|
104
|
+
def status_to_hash_key(status)
|
105
|
+
status.gsub(' ', '_').to_sym
|
106
|
+
end
|
107
|
+
|
108
|
+
def possible_statuses_from(status_hash)
|
109
|
+
status_hash.keys.map do |status|
|
110
|
+
status.to_s.gsub('_', ' ').downcase
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def create_status_hash
|
115
|
+
{ modified: [], deleted: [], new_file: [] }
|
116
|
+
end
|
117
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe TmpRepo do
|
6
|
+
let(:repo) do
|
7
|
+
TmpRepo.new
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:each) do
|
11
|
+
repo.git('config user.email tester@tester.com')
|
12
|
+
repo.git('config user.name Tester McTesterson')
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
repo.unlink
|
17
|
+
end
|
18
|
+
|
19
|
+
def in_repo
|
20
|
+
Dir.chdir(repo.working_dir.to_s) do
|
21
|
+
yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#initialize' do
|
26
|
+
it 'should initialize the repository' do
|
27
|
+
expect(repo.working_dir.join('.git')).to exist
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#unlink' do
|
32
|
+
it 'should delete the temp directory' do
|
33
|
+
repo.unlink
|
34
|
+
expect(repo.working_dir).to_not exist
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#create_file' do
|
39
|
+
it 'yields a file handle if given a block' do
|
40
|
+
repo.create_file('foo.txt') do |f|
|
41
|
+
expect(f).to be_a(IO)
|
42
|
+
f.write('foobar')
|
43
|
+
end
|
44
|
+
|
45
|
+
contents = File.read(repo.working_dir.join('foo.txt').to_s)
|
46
|
+
expect(contents).to eq('foobar')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'returns a file handle if not given a block' do
|
50
|
+
handle = repo.create_file('foo.txt')
|
51
|
+
expect(handle).to be_a(IO)
|
52
|
+
handle.write('foobarbaz')
|
53
|
+
handle.close
|
54
|
+
|
55
|
+
contents = File.read(repo.working_dir.join('foo.txt').to_s)
|
56
|
+
expect(contents).to eq('foobarbaz')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#add_all' do
|
61
|
+
it 'stages all files' do
|
62
|
+
repo.create_file('foo.txt') { |f| f.write('foobar') }
|
63
|
+
repo.add_all
|
64
|
+
|
65
|
+
in_repo do
|
66
|
+
expect(`git status`).to match(/new file:[\s]+foo\.txt/)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#commit' do
|
72
|
+
it 'commits the stage' do
|
73
|
+
repo.create_file('foo.txt') { |f| f.write('foobar') }
|
74
|
+
repo.add_all
|
75
|
+
repo.commit('Committing foobar')
|
76
|
+
|
77
|
+
in_repo do
|
78
|
+
expect(`git log`).to match(/Committing foobar/)
|
79
|
+
expect(`git show --name-only HEAD`).to include('foo.txt')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'with a single commit' do
|
85
|
+
before(:each) do
|
86
|
+
repo.create_file('foo.txt') do |f|
|
87
|
+
f.write('foobar')
|
88
|
+
end
|
89
|
+
|
90
|
+
repo.add_all
|
91
|
+
repo.commit('Foobar committed')
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '#checkout' do
|
95
|
+
it 'checks out the given branch' do
|
96
|
+
in_repo do
|
97
|
+
`git checkout -b my_branch && git checkout master`
|
98
|
+
expect(`git rev-parse --abbrev-ref HEAD`.strip).to eq('master')
|
99
|
+
end
|
100
|
+
|
101
|
+
repo.checkout('my_branch')
|
102
|
+
|
103
|
+
in_repo do
|
104
|
+
expect(`git rev-parse --abbrev-ref HEAD`.strip).to eq('my_branch')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#create_branch' do
|
110
|
+
it 'creates a new branch' do
|
111
|
+
repo.create_branch('new_branch')
|
112
|
+
|
113
|
+
in_repo do
|
114
|
+
expect(`git branch`).to include('new_branch')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe '#current_branch' do
|
120
|
+
it 'returns the current branch name' do
|
121
|
+
in_repo { `git checkout -b cool_branch` }
|
122
|
+
expect(repo.current_branch).to eq('cool_branch')
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#status' do
|
127
|
+
it 'returns no results when there are no uncommitted changes' do
|
128
|
+
repo.status.tap do |status|
|
129
|
+
expect(status[:new_file]).to be_empty
|
130
|
+
expect(status[:modified]).to be_empty
|
131
|
+
expect(status[:deleted]).to be_empty
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'shows new files' do
|
136
|
+
repo.create_file('hello.txt') do |f|
|
137
|
+
f.write('blarg blegh')
|
138
|
+
end
|
139
|
+
|
140
|
+
repo.add_all
|
141
|
+
|
142
|
+
repo.status.tap do |status|
|
143
|
+
expect(status[:new_file]).to include('hello.txt')
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'shows modified files' do
|
148
|
+
in_repo do
|
149
|
+
File.open('foo.txt', 'w+') do |f|
|
150
|
+
f.write("\nI'm a change!")
|
151
|
+
end
|
152
|
+
|
153
|
+
repo.add_all
|
154
|
+
|
155
|
+
repo.status.tap do |status|
|
156
|
+
expect(status[:modified]).to include('foo.txt')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'shows deleted files' do
|
162
|
+
in_repo do
|
163
|
+
File.unlink('foo.txt')
|
164
|
+
repo.add_all
|
165
|
+
|
166
|
+
repo.status.tap do |status|
|
167
|
+
expect(status[:deleted]).to include('foo.txt')
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe '#git' do
|
174
|
+
it 'facilitates executing custom git commands and returning their output' do
|
175
|
+
expect(repo.git('branch')).to include('master')
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'raises an error if the command fails' do
|
179
|
+
expect(lambda { repo.git('') }).to raise_error(TmpRepo::GitError)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
data/tmp-repo.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
require 'tmp-repo/version'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "tmp-repo"
|
6
|
+
s.version = ::TmpRepo::VERSION
|
7
|
+
s.authors = ["Cameron Dutro"]
|
8
|
+
s.email = ["camertron@gmail.com"]
|
9
|
+
s.homepage = "http://github.com/camertron"
|
10
|
+
|
11
|
+
s.description = s.summary = "Creates and manages a git repository in the operating system's temporary directory. Useful for running git operations in tests."
|
12
|
+
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.has_rdoc = true
|
15
|
+
|
16
|
+
s.require_path = 'lib'
|
17
|
+
s.files = Dir["{lib,spec}/**/*", "Gemfile", "History.txt", "README.md", "Rakefile", "tmp-repo.gemspec"]
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tmp-repo
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cameron Dutro
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2014-08-21 00:00:00 Z
|
13
|
+
dependencies: []
|
14
|
+
|
15
|
+
description: Creates and manages a git repository in the operating system's temporary directory. Useful for running git operations in tests.
|
16
|
+
email:
|
17
|
+
- camertron@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- Gemfile
|
26
|
+
- History.txt
|
27
|
+
- README.md
|
28
|
+
- Rakefile
|
29
|
+
- lib/tmp-repo.rb
|
30
|
+
- lib/tmp-repo/version.rb
|
31
|
+
- spec/spec_helper.rb
|
32
|
+
- spec/tmp-repo_spec.rb
|
33
|
+
- tmp-repo.gemspec
|
34
|
+
homepage: http://github.com/camertron
|
35
|
+
licenses: []
|
36
|
+
|
37
|
+
metadata: {}
|
38
|
+
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- &id001
|
47
|
+
- ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- *id001
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 2.2.2
|
57
|
+
signing_key:
|
58
|
+
specification_version: 4
|
59
|
+
summary: Creates and manages a git repository in the operating system's temporary directory. Useful for running git operations in tests.
|
60
|
+
test_files: []
|
61
|
+
|