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.
Files changed (39) hide show
  1. data/.gitignore +5 -0
  2. data/Gemfile +4 -0
  3. data/README.md +74 -0
  4. data/Rakefile +1 -0
  5. data/git_wrapper.gemspec +21 -0
  6. data/lib/git_wrapper/commands/add.rb +21 -0
  7. data/lib/git_wrapper/commands/branch.rb +73 -0
  8. data/lib/git_wrapper/commands/checkout.rb +21 -0
  9. data/lib/git_wrapper/commands/commit.rb +21 -0
  10. data/lib/git_wrapper/commands/config.rb +26 -0
  11. data/lib/git_wrapper/commands/diff.rb +27 -0
  12. data/lib/git_wrapper/commands/fetch.rb +21 -0
  13. data/lib/git_wrapper/commands/git.rb +44 -0
  14. data/lib/git_wrapper/commands/init.rb +16 -0
  15. data/lib/git_wrapper/commands/log.rb +82 -0
  16. data/lib/git_wrapper/commands/merge.rb +16 -0
  17. data/lib/git_wrapper/commands/pull.rb +21 -0
  18. data/lib/git_wrapper/commands/push.rb +27 -0
  19. data/lib/git_wrapper/commands/remote.rb +49 -0
  20. data/lib/git_wrapper/commands/remove.rb +16 -0
  21. data/lib/git_wrapper/commands/reset.rb +36 -0
  22. data/lib/git_wrapper/commands/revert.rb +23 -0
  23. data/lib/git_wrapper/commands/shell.rb +67 -0
  24. data/lib/git_wrapper/commands/show.rb +40 -0
  25. data/lib/git_wrapper/commands/status.rb +17 -0
  26. data/lib/git_wrapper/commands/tag.rb +54 -0
  27. data/lib/git_wrapper/repository.rb +208 -0
  28. data/lib/git_wrapper/results/diff_name_status.rb +28 -0
  29. data/lib/git_wrapper/results/file_status.rb +21 -0
  30. data/lib/git_wrapper/results/log_info.rb +23 -0
  31. data/lib/git_wrapper/results/status_porcelain.rb +40 -0
  32. data/lib/git_wrapper/version.rb +3 -0
  33. data/lib/git_wrapper.rb +45 -0
  34. data/spec/repository_spec.rb +886 -0
  35. data/spec/spec_helper.rb +10 -0
  36. data/spec/status_porcelain_parser_spec.rb +78 -0
  37. data/spec/support/helpers/file_helper.rb +37 -0
  38. data/spec/support/matchers/git_status_matchers.rb +40 -0
  39. 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,17 @@
1
+ module GitWrapper
2
+ module Commands
3
+ class Status < Git
4
+
5
+ def command
6
+ 'status --porcelain'
7
+ end
8
+
9
+ def result
10
+ output.split(/\n/).map do |line|
11
+ Results::StatusPorcelain.parse(line)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ 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
@@ -0,0 +1,3 @@
1
+ module GitWrapper
2
+ VERSION = '1.0.0'
3
+ end
@@ -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