git_wrapper 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.
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/git_wrapper.gemspec +21 -0
- data/lib/git_wrapper/commands/add.rb +21 -0
- data/lib/git_wrapper/commands/branch.rb +73 -0
- data/lib/git_wrapper/commands/checkout.rb +21 -0
- data/lib/git_wrapper/commands/commit.rb +21 -0
- data/lib/git_wrapper/commands/config.rb +26 -0
- data/lib/git_wrapper/commands/diff.rb +27 -0
- data/lib/git_wrapper/commands/fetch.rb +21 -0
- data/lib/git_wrapper/commands/git.rb +44 -0
- data/lib/git_wrapper/commands/init.rb +16 -0
- data/lib/git_wrapper/commands/log.rb +82 -0
- data/lib/git_wrapper/commands/merge.rb +16 -0
- data/lib/git_wrapper/commands/pull.rb +21 -0
- data/lib/git_wrapper/commands/push.rb +27 -0
- data/lib/git_wrapper/commands/remote.rb +49 -0
- data/lib/git_wrapper/commands/remove.rb +16 -0
- data/lib/git_wrapper/commands/reset.rb +36 -0
- data/lib/git_wrapper/commands/revert.rb +23 -0
- data/lib/git_wrapper/commands/shell.rb +67 -0
- data/lib/git_wrapper/commands/show.rb +40 -0
- data/lib/git_wrapper/commands/status.rb +17 -0
- data/lib/git_wrapper/commands/tag.rb +54 -0
- data/lib/git_wrapper/repository.rb +208 -0
- data/lib/git_wrapper/results/diff_name_status.rb +28 -0
- data/lib/git_wrapper/results/file_status.rb +21 -0
- data/lib/git_wrapper/results/log_info.rb +23 -0
- data/lib/git_wrapper/results/status_porcelain.rb +40 -0
- data/lib/git_wrapper/version.rb +3 -0
- data/lib/git_wrapper.rb +45 -0
- data/spec/repository_spec.rb +886 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/status_porcelain_parser_spec.rb +78 -0
- data/spec/support/helpers/file_helper.rb +37 -0
- data/spec/support/matchers/git_status_matchers.rb +40 -0
- metadata +105 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Commands
|
3
|
+
|
4
|
+
module Shell
|
5
|
+
|
6
|
+
def self.execute(command, options={})
|
7
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
|
8
|
+
jruby_execute(command, options)
|
9
|
+
else
|
10
|
+
ruby_execute(command, options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.ruby_execute(command, options={})
|
15
|
+
location_folder = options[:chdir] || '.'
|
16
|
+
result = nil
|
17
|
+
|
18
|
+
Open3.popen3(command, :chdir => location_folder) do |stdin, stdout, stderr, wait_thr|
|
19
|
+
output = stdout.readlines.join
|
20
|
+
error = stderr.readlines.join
|
21
|
+
status = wait_thr.value
|
22
|
+
|
23
|
+
if block_given?
|
24
|
+
result = status
|
25
|
+
yield(output, error, wait_thr.pid)
|
26
|
+
else
|
27
|
+
result = [output, error, status]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
return result
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.jruby_execute(command, options={})
|
35
|
+
location_folder = options[:chdir] || '.'
|
36
|
+
|
37
|
+
prev_stdout = $stdout
|
38
|
+
prev_stderr = $stderr
|
39
|
+
|
40
|
+
$stdout = StringIO.new
|
41
|
+
$stderr = StringIO.new
|
42
|
+
|
43
|
+
begin
|
44
|
+
Dir.chdir location_folder do
|
45
|
+
system(command)
|
46
|
+
end
|
47
|
+
status = $?
|
48
|
+
$stdout.rewind
|
49
|
+
$stderr.rewind
|
50
|
+
if block_given?
|
51
|
+
yield($stdout.readlines.join.force_encoding('UTF-8'), $stderr.readlines.join.force_encoding('UTF-8'), status.pid)
|
52
|
+
result = status
|
53
|
+
else
|
54
|
+
result = $stdout.readlines.join.force_encoding('UTF-8'), $stderr.readlines.join.force_encoding('UTF-8'), status
|
55
|
+
end
|
56
|
+
ensure
|
57
|
+
$stdout = prev_stdout
|
58
|
+
$stderr = prev_stderr
|
59
|
+
end
|
60
|
+
|
61
|
+
return result
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Commands
|
3
|
+
class Show < Git
|
4
|
+
|
5
|
+
def file(file_name)
|
6
|
+
@file = to_relative_path(file_name)
|
7
|
+
self
|
8
|
+
end
|
9
|
+
|
10
|
+
def commit(commit)
|
11
|
+
@version = "#{commit}:"
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def base
|
16
|
+
@version = ':1:'
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def mine
|
21
|
+
@version = ':2:'
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def theirs
|
26
|
+
@version = ':3:'
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def command
|
31
|
+
"show #{@version ? @version : 'HEAD:'}\"#{@file}\""
|
32
|
+
end
|
33
|
+
|
34
|
+
def result
|
35
|
+
output
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Commands
|
3
|
+
class Tag < Git
|
4
|
+
|
5
|
+
def create(name)
|
6
|
+
@mode = :create
|
7
|
+
@name = name
|
8
|
+
self
|
9
|
+
end
|
10
|
+
|
11
|
+
def from(commit)
|
12
|
+
@commit = commit
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def remove(name)
|
17
|
+
@mode = :remove
|
18
|
+
@name = name
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def list
|
23
|
+
@mode = :list
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
def command
|
28
|
+
command = 'tag '
|
29
|
+
|
30
|
+
if @mode == :create
|
31
|
+
command += "#{@name} #{@commit.nil? ? '' : @commit}"
|
32
|
+
elsif @mode == :remove
|
33
|
+
command += "-d #{@name}"
|
34
|
+
elsif @mode == :list
|
35
|
+
#Nothing to add
|
36
|
+
else
|
37
|
+
raise 'Unespecified tag mode'
|
38
|
+
end
|
39
|
+
|
40
|
+
command
|
41
|
+
end
|
42
|
+
|
43
|
+
def result
|
44
|
+
return result_list if @mode == :list
|
45
|
+
super
|
46
|
+
end
|
47
|
+
|
48
|
+
def result_list
|
49
|
+
output.split("\n")
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
class Repository
|
3
|
+
attr_reader :location
|
4
|
+
attr_reader :log_output
|
5
|
+
attr_reader :log_error
|
6
|
+
|
7
|
+
def initialize(location)
|
8
|
+
@location = location
|
9
|
+
@log_output = []
|
10
|
+
@log_error = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def init
|
14
|
+
FileUtils.mkpath(@location) unless Dir.exist?(@location)
|
15
|
+
execute(Commands::Init.new(@location))
|
16
|
+
end
|
17
|
+
|
18
|
+
def init_bare
|
19
|
+
FileUtils.mkpath(@location) unless Dir.exist?(@location)
|
20
|
+
execute(Commands::Init.new(@location).bare)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialized?
|
24
|
+
Dir.exist?("#{@location}/.git") || bare?
|
25
|
+
end
|
26
|
+
|
27
|
+
def bare?
|
28
|
+
Dir.exist?("#{@location}/hooks") &&
|
29
|
+
Dir.exist?("#{@location}/info") &&
|
30
|
+
Dir.exist?("#{@location}/objects") &&
|
31
|
+
Dir.exist?("#{@location}/refs")
|
32
|
+
end
|
33
|
+
|
34
|
+
def status
|
35
|
+
execute(Commands::Status.new(@location))
|
36
|
+
end
|
37
|
+
|
38
|
+
def add(file_name)
|
39
|
+
execute(Commands::Add.new(@location).file(file_name))
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_all
|
43
|
+
execute(Commands::Add.new(@location).all)
|
44
|
+
end
|
45
|
+
|
46
|
+
def commit(message, options={})
|
47
|
+
command = Commands::Commit.new(@location).message(message)
|
48
|
+
command.author(options[:author_name], options[:author_email]) if options[:author_name] && options[:author_email]
|
49
|
+
execute(command)
|
50
|
+
end
|
51
|
+
|
52
|
+
def remove(file_name)
|
53
|
+
execute(Commands::Remove.new(@location).file(file_name))
|
54
|
+
end
|
55
|
+
|
56
|
+
def remotes
|
57
|
+
execute(Commands::Remote.new(@location).list)
|
58
|
+
end
|
59
|
+
|
60
|
+
def add_remote(name, url)
|
61
|
+
execute(Commands::Remote.new(@location).name(name).add(url))
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_remote(name)
|
65
|
+
execute(Commands::Remote.new(@location).name(name).remove)
|
66
|
+
end
|
67
|
+
|
68
|
+
def pull(remote='origin', branch='master')
|
69
|
+
execute(Commands::Pull.new(@location).remote(remote).branch(branch))
|
70
|
+
end
|
71
|
+
|
72
|
+
def push(remote='origin', branch='master')
|
73
|
+
execute(Commands::Push.new(@location).remote(remote).branch(branch))
|
74
|
+
end
|
75
|
+
|
76
|
+
def push_tags(remote='origin')
|
77
|
+
execute(Commands::Push.new(@location).remote(remote).tags)
|
78
|
+
end
|
79
|
+
|
80
|
+
def show(file_name, commit=nil)
|
81
|
+
command = Commands::Show.new(@location).file(file_name)
|
82
|
+
command.commit(commit) unless commit.nil?
|
83
|
+
execute(command)
|
84
|
+
end
|
85
|
+
|
86
|
+
def show_base(file_name)
|
87
|
+
execute(Commands::Show.new(@location).file(file_name).base)
|
88
|
+
end
|
89
|
+
|
90
|
+
def show_mine(file_name)
|
91
|
+
execute(Commands::Show.new(@location).file(file_name).mine)
|
92
|
+
end
|
93
|
+
|
94
|
+
def show_theirs(file_name)
|
95
|
+
execute(Commands::Show.new(@location).file(file_name).theirs)
|
96
|
+
end
|
97
|
+
|
98
|
+
def log(options={})
|
99
|
+
if options[:file_name]
|
100
|
+
execute(Commands::Log.new(@location).file(options[:file_name]))
|
101
|
+
elsif options[:commit]
|
102
|
+
execute(Commands::Log.new(@location).commit(options[:commit]))
|
103
|
+
else
|
104
|
+
execute(Commands::Log.new(@location))
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def branches
|
109
|
+
execute(Commands::Branch.new(@location).list)
|
110
|
+
end
|
111
|
+
|
112
|
+
def current_branch
|
113
|
+
execute(Commands::Branch.new(@location).current)
|
114
|
+
end
|
115
|
+
|
116
|
+
def branch(name, commit=nil)
|
117
|
+
if commit.nil?
|
118
|
+
execute(Commands::Branch.new(@location).create(name))
|
119
|
+
else
|
120
|
+
execute(Commands::Branch.new(@location).create(name).from(commit))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def remove_branch(name, remote=nil)
|
125
|
+
if remote.nil?
|
126
|
+
execute(Commands::Branch.new(@location).remove(name))
|
127
|
+
else
|
128
|
+
execute(Commands::Branch.new(@location).remove(name).remote(remote))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def checkout(commit, new_branch=nil)
|
133
|
+
if commit.nil?
|
134
|
+
execute(Commands::Checkout.new(@location).commit(commit))
|
135
|
+
else
|
136
|
+
execute(Commands::Checkout.new(@location).commit(commit).into(new_branch))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def tags
|
141
|
+
execute(Commands::Tag.new(@location).list)
|
142
|
+
end
|
143
|
+
|
144
|
+
def tag(name, commit=nil)
|
145
|
+
if commit.nil?
|
146
|
+
execute(Commands::Tag.new(@location).create(name))
|
147
|
+
else
|
148
|
+
execute(Commands::Tag.new(@location).create(name).from(commit))
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def remove_tag(name)
|
153
|
+
execute(Commands::Tag.new(@location).remove(name))
|
154
|
+
end
|
155
|
+
|
156
|
+
def merge(commit)
|
157
|
+
execute(Commands::Merge.new(@location).commit(commit))
|
158
|
+
end
|
159
|
+
|
160
|
+
def fetch(remote=nil)
|
161
|
+
if remote.nil?
|
162
|
+
execute(Commands::Fetch.new(@location).all)
|
163
|
+
else
|
164
|
+
execute(Commands::Fetch.new(@location).remote(remote))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def diff(commit)
|
169
|
+
execute(Commands::Diff.new(@location).with(commit))
|
170
|
+
end
|
171
|
+
|
172
|
+
def diff_reverse(commit)
|
173
|
+
execute(Commands::Diff.new(@location).with(commit).reverse)
|
174
|
+
end
|
175
|
+
|
176
|
+
def revert(commit)
|
177
|
+
if log(:commit => commit).merge?
|
178
|
+
execute(Commands::Revert.new(@location).merge(commit))
|
179
|
+
else
|
180
|
+
execute(Commands::Revert.new(@location).commit(commit))
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def reset(options={})
|
185
|
+
command = Commands::Reset.new(@location)
|
186
|
+
command.commit(options[:commit]) if options[:commit]
|
187
|
+
command.send(options[:mode]) if options[:mode]
|
188
|
+
execute(command)
|
189
|
+
end
|
190
|
+
|
191
|
+
def config(key=nil, value=nil)
|
192
|
+
command = Commands::Config.new(@location)
|
193
|
+
command.key(key) if key
|
194
|
+
command.value(value) if value
|
195
|
+
execute(command)
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
def execute(command)
|
201
|
+
result = command.execute
|
202
|
+
@log_output << command.output
|
203
|
+
@log_error << command.error
|
204
|
+
result
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Results
|
3
|
+
class DiffNameStatus
|
4
|
+
attr_reader :file_name
|
5
|
+
attr_reader :status
|
6
|
+
|
7
|
+
def initialize(file_name, status)
|
8
|
+
@file_name = file_name
|
9
|
+
@status = status
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.parse(text)
|
13
|
+
DiffNameStatus.new parse_file_name(text), parse_status(text)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def self.parse_file_name(text)
|
19
|
+
text[1..text.length].strip
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.parse_status(text)
|
23
|
+
FileStatus.value_of text[0]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Results
|
3
|
+
module FileStatus
|
4
|
+
STATUSES = {
|
5
|
+
'A' => :new_file,
|
6
|
+
'M' => :modified,
|
7
|
+
'D' => :deleted,
|
8
|
+
'R' => :renamed,
|
9
|
+
'U' => :merge_conflict,
|
10
|
+
'C' => :copied,
|
11
|
+
'T' => :type_changed,
|
12
|
+
'X' => :unknown
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.value_of(char)
|
16
|
+
return :untracked unless STATUSES.key?(char)
|
17
|
+
STATUSES[char]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Results
|
3
|
+
class LogInfo
|
4
|
+
def initialize(attributes)
|
5
|
+
attributes.each do |name, value|
|
6
|
+
define_singleton_method name, lambda { value }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def parents
|
11
|
+
parent_hashes.split
|
12
|
+
end
|
13
|
+
|
14
|
+
def abbreviated_parents
|
15
|
+
abbreviated_parent_hashes.split
|
16
|
+
end
|
17
|
+
|
18
|
+
def merge?
|
19
|
+
parents.length == 2
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module GitWrapper
|
2
|
+
module Results
|
3
|
+
class StatusPorcelain
|
4
|
+
attr_reader :file_name
|
5
|
+
attr_reader :original_file_name
|
6
|
+
attr_reader :status
|
7
|
+
attr_reader :staged_for_commit
|
8
|
+
|
9
|
+
def initialize(file_name, original_file_name, status, staged_for_commit)
|
10
|
+
@file_name = file_name
|
11
|
+
@original_file_name = original_file_name
|
12
|
+
@status = status
|
13
|
+
@staged_for_commit = staged_for_commit
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.parse(text)
|
17
|
+
StatusPorcelain.new parse_file_name(text), parse_original_file_name(text), parse_status(text), parse_staged_for_commit(text)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def self.parse_file_name(text)
|
23
|
+
text[3..text.length].gsub("\"", "").split(' -> ').last
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.parse_original_file_name(text)
|
27
|
+
text[3..text.length].gsub("\"", "").split(' -> ').first
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.parse_status(text)
|
31
|
+
FileStatus.value_of text[0..2].strip[0]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.parse_staged_for_commit(text)
|
35
|
+
text[1..2].strip.empty?
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/git_wrapper.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
require 'git_wrapper/version'
|
5
|
+
|
6
|
+
require 'git_wrapper/repository'
|
7
|
+
|
8
|
+
require 'git_wrapper/commands/shell'
|
9
|
+
require 'git_wrapper/commands/git'
|
10
|
+
require 'git_wrapper/commands/init'
|
11
|
+
require 'git_wrapper/commands/status'
|
12
|
+
require 'git_wrapper/commands/add'
|
13
|
+
require 'git_wrapper/commands/commit'
|
14
|
+
require 'git_wrapper/commands/remove'
|
15
|
+
require 'git_wrapper/commands/remote'
|
16
|
+
require 'git_wrapper/commands/pull'
|
17
|
+
require 'git_wrapper/commands/push'
|
18
|
+
require 'git_wrapper/commands/show'
|
19
|
+
require 'git_wrapper/commands/log'
|
20
|
+
require 'git_wrapper/commands/branch'
|
21
|
+
require 'git_wrapper/commands/checkout'
|
22
|
+
require 'git_wrapper/commands/tag'
|
23
|
+
require 'git_wrapper/commands/merge'
|
24
|
+
require 'git_wrapper/commands/fetch'
|
25
|
+
require 'git_wrapper/commands/diff'
|
26
|
+
require 'git_wrapper/commands/revert'
|
27
|
+
require 'git_wrapper/commands/reset'
|
28
|
+
require 'git_wrapper/commands/config'
|
29
|
+
|
30
|
+
require 'git_wrapper/results/file_status'
|
31
|
+
require 'git_wrapper/results/status_porcelain'
|
32
|
+
require 'git_wrapper/results/log_info'
|
33
|
+
require 'git_wrapper/results/diff_name_status'
|
34
|
+
|
35
|
+
module GitWrapper
|
36
|
+
|
37
|
+
def self.logger
|
38
|
+
@@logger ||= Logger.new($stdout)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.logger=(logger)
|
42
|
+
@@logger = logger
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|