tmp-repo 1.0.0

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,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
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ group :development, :test do
6
+ gem 'pry-nav'
7
+ gem 'rake'
8
+ end
9
+
10
+ group :test do
11
+ gem 'rspec'
12
+ gem 'rr'
13
+ end
@@ -0,0 +1,3 @@
1
+ == 1.0.0
2
+
3
+ * Birthday!
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
1
+ # encoding: UTF-8
2
+
3
+ class TmpRepo
4
+ VERSION = '1.0.0'
5
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'rspec'
4
+ require 'tmp-repo'
5
+ require 'pry-nav'
6
+
7
+ RSpec.configure do |config|
8
+ config.mock_with :rr
9
+ end
@@ -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
@@ -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
+