web_git 0.0.4 → 0.1.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/lib/web_git/diff.rb CHANGED
@@ -1,233 +1,234 @@
1
- module WebGit
2
- class Diff
3
- def self.get_diff
4
- Dir.chdir(Rails.root) do
5
- `git diff`
6
- end
7
- end
8
1
 
9
- def self.get_each_left(diff)
10
- filenames = get_file_names("")
11
- files = file_diffs(diff)
12
- lefts = {}
13
- files.each_with_index do |file, i|
14
- file_content = ""
15
- lines = file.split("\n").drop(4)
16
- start_line = 0
17
- current_line_index = 0
18
- line_number = start_line + current_line_index
19
- lines.each do |line|
20
- if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
21
- if line.first != "+"
22
- file_content += "#{line_number}| " + line + "\n"
23
- line_number += 1
24
- end
25
- else
26
- current_line_index = 0
27
- # The line numbers in the output of a git diff match this regex
28
- numbers = line.scan(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/).map(&:join)
29
- # If left, starting line number is the first one in a split Array
30
- start_line = numbers.first.split(" ").first.
31
- split(",").first.to_i.abs
32
- line_number = start_line + current_line_index
33
- file_content += "\n"
2
+ require "diffy"
3
+ require "git"
4
+ class Diff
5
+
6
+ def self.get_diff
7
+ # Dir.chdir(Rails.root) do
8
+ `git diff`
9
+ # end
10
+ end
11
+
12
+ def self.get_each_left(diff)
13
+ filenames = get_file_names("")
14
+ files = file_diffs(diff)
15
+ lefts = {}
16
+ files.each_with_index do |file, i|
17
+ file_content = ""
18
+ lines = file.split("\n").drop(4)
19
+ start_line = 0
20
+ current_line_index = 0
21
+ line_number = start_line + current_line_index
22
+ lines.each do |line|
23
+ if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
24
+ if line[0] != "+"
25
+ file_content += "#{line_number}| " + line + "\n"
26
+ line_number += 1
34
27
  end
35
- end
36
- lefts[filenames[i]] = file_content.chomp "\n"
37
- end
38
- lefts
39
- end
40
-
41
- def self.get_each_right(diff)
42
- filenames = get_file_names("")
43
- files = file_diffs(diff)
44
- rights = {}
45
- files.each_with_index do |file, i|
46
- file_content = ""
47
- lines = file.split("\n").drop(4)
48
- start_line = 0
49
- current_line_index = 0
50
- line_number = start_line + current_line_index
51
- lines.each do |line|
28
+ else
29
+ current_line_index = 0
52
30
  # The line numbers in the output of a git diff match this regex
53
- # @@ -61,18 +61,15 @@
54
- if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
55
- if line.first != "-"
56
- file_content += "#{line_number}| " + line + "\n"
57
- line_number += 1
58
- end
59
- else
60
- current_line_index = 0
61
- numbers = line.scan(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/).map(&:join)
62
- # If right, start line is the second in a split Array
63
- start_line = numbers.first.split(" ").second.
64
- split(",").first.to_i.abs
65
- line_number = start_line + current_line_index
66
- file_content += "\n"
67
- end
31
+ numbers = line.scan(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/).map(&:join)
32
+ # If left, starting line number is the first one in a split Array
33
+ start_line = numbers[0].split(" ")[0].
34
+ split(",")[0].to_i.abs
35
+ line_number = start_line + current_line_index
36
+ file_content += "\n"
68
37
  end
69
- rights[filenames[i]] = file_content.chomp "\n"
70
38
  end
71
- rights
39
+ lefts[filenames[i]] = file_content.chomp "\n"
72
40
  end
73
-
74
- def self.get_last_commit_hash
75
- Dir.chdir(Rails.root) do
76
- log = `git log -1 --oneline`
77
- log.split.first
78
- end
79
- end
80
-
81
- def self.file_diffs(diff)
82
- diff.scan(/diff --git.*?(?=diff --git|\z)/m)
83
- end
84
-
85
- def self.match_other_files(line, file, filenames)
86
- filenames.each do |other_file|
87
- if file != other_file
88
- # It looks like:
89
- # --- a/<path-to-file>
90
- # +++ b/<path-to-file>
91
- if line.include?('diff --git a/' + other_file + ' b/' + other_file)
92
- return true
41
+ lefts
42
+ end
43
+
44
+ def self.get_each_right(diff)
45
+ filenames = get_file_names("")
46
+ files = file_diffs(diff)
47
+ rights = {}
48
+ files.each_with_index do |file, i|
49
+ file_content = ""
50
+ lines = file.split("\n").drop(4)
51
+ start_line = 0
52
+ current_line_index = 0
53
+ line_number = start_line + current_line_index
54
+ lines.each do |line|
55
+ # The line numbers in the output of a git diff match this regex
56
+ # @@ -61,18 +61,15 @@
57
+ if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
58
+ if line[0] != "-"
59
+ file_content += "#{line_number}| " + line + "\n"
60
+ line_number += 1
93
61
  end
62
+ else
63
+ current_line_index = 0
64
+ numbers = line.scan(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/).map(&:join)
65
+ # If right, start line is the second in a split Array
66
+ start_line = numbers[0].split(" ")[1].
67
+ split(",")[0].to_i.abs
68
+ line_number = start_line + current_line_index
69
+ file_content += "\n"
94
70
  end
95
71
  end
96
- false
72
+ rights[filenames[i]] = file_content.chomp "\n"
97
73
  end
98
-
99
- def self.get_file_names(commit)
100
- Dir.chdir(Rails.root) do
101
- if commit.blank?
102
- filenames = `git diff --name-only`
103
- else
104
- filenames = `git diff-tree --no-commit-id --name-only -r #{commit}`
74
+ rights
75
+ end
76
+
77
+ def self.get_last_commit_hash
78
+ working_dir = Dir.pwd
79
+ git = Git.open(working_dir)
80
+ git.log.first.sha.slice(0, 7)
81
+ end
82
+
83
+ def self.file_diffs(diff)
84
+ diff.scan(/diff --git.*?(?=diff --git|\z)/m)
85
+ end
86
+
87
+ def self.match_other_files(line, file, filenames)
88
+ filenames.each do |other_file|
89
+ if file != other_file
90
+ # It looks like:
91
+ # --- a/<path-to-file>
92
+ # +++ b/<path-to-file>
93
+ if line.include?('diff --git a/' + other_file + ' b/' + other_file)
94
+ return true
105
95
  end
106
- filenames.split("\n")
107
96
  end
108
97
  end
109
-
110
- def self.get_last_diff
111
- Dir.chdir(Rails.root) do
112
- `git diff -M HEAD~1`
113
- end
98
+ false
99
+ end
100
+
101
+ def self.get_file_names(commit)
102
+ git = Git.open(Dir.pwd)
103
+ if commit.empty?
104
+ filenames = git.status.changed.keys
105
+ else
106
+ filenames = git.diff(commit, "HEAD").map(&:path)
114
107
  end
115
-
116
- def self.get_last_left(diff)
117
- filenames = get_file_names(get_last_commit_hash)
118
- files = file_diffs(diff)
119
- ones = {}
120
- files.each_with_index do |file, i|
121
- file_content = ""
122
- lines = file.split("\n").drop(4)
123
- lines.each do |line|
124
- # The line numbers in the output of a git diff match this regex
125
- # @@ -61,18 +61,15 @@
126
- if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
127
- if line.first != "+"
128
- line.slice!(0)
129
- file_content += line + "\n"
130
- end
131
- else
132
- file_content += "\n"
108
+ filenames
109
+ end
110
+
111
+ def self.get_last_diff
112
+ # Dir.chdir(Rails.root) do
113
+ `git diff -M HEAD~1`
114
+ # end
115
+ end
116
+
117
+ def self.get_last_left(diff)
118
+ filenames = get_file_names("HEAD~1")
119
+ files = file_diffs(diff)
120
+ ones = {}
121
+ files.each_with_index do |file, i|
122
+ file_content = ""
123
+ lines = file.split("\n").drop(4)
124
+ lines.each do |line|
125
+ # The line numbers in the output of a git diff match this regex
126
+ # @@ -61,18 +61,15 @@
127
+ if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
128
+ if line[0] != "+"
129
+ line.slice!(0)
130
+ file_content += line + "\n"
133
131
  end
132
+ else
133
+ file_content += "\n"
134
134
  end
135
- ones[filenames[i]] = file_content.chomp "\n"
136
135
  end
137
- ones
136
+ ones[filenames[i]] = file_content.chomp "\n"
138
137
  end
139
-
140
- def self.get_last_right(diff)
141
- filenames = get_file_names(get_last_commit_hash)
142
- files = file_diffs(diff)
143
- ones = {}
144
- files.each_with_index do |file, i|
145
- file_content = ""
146
- lines = file.split("\n").drop(4)
147
- lines.each do |line|
148
- if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
149
- if line.first != "+"
150
- elsif line.first == "+"
151
- line.slice!(0)
152
- file_content += line + "\n"
153
- end
154
- else
155
- file_content += "\n"
138
+ ones
139
+ end
140
+
141
+ def self.get_last_right(diff)
142
+ filenames = get_file_names("HEAD~1")
143
+ files = file_diffs(diff)
144
+ ones = {}
145
+ files.each_with_index do |file, i|
146
+ file_content = ""
147
+ lines = file.split("\n").drop(4)
148
+ lines.each do |line|
149
+ if !line.match?(/@@ ([-]\d+,\d+\s[+]\d+,\d+) @@/)
150
+ if line[0] != "+"
151
+ elsif line[0] == "+"
152
+ line.slice!(0)
153
+ file_content += line + "\n"
156
154
  end
155
+ else
156
+ file_content += "\n"
157
157
  end
158
- ones[filenames[i]] = file_content.chomp "\n"
159
158
  end
160
- ones
159
+ ones[filenames[i]] = file_content.chomp "\n"
161
160
  end
162
-
163
- def self.last_to_html(diff)
164
- left_hash = get_last_left(diff)
165
- right_hash = get_last_right(diff)
166
-
167
- html_output = '<link rel="stylesheet"' +
168
- 'href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/' +
169
- 'bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/' +
170
- '1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">'
171
- html_output += '<style>'
172
- html_output += Diffy::CSS
173
- html_output += '</style>'
174
- html_output += '<div class="card">'
175
- left_hash.keys.each do |file|
176
- html_output += '<div class="file mb-4 p-3">'
177
- html_output += '<h4>' + file + '</h4>'
178
- html_output += Diffy::Diff.new(
179
- left_hash[file],
180
- right_hash[file],
181
- :include_plus_and_minus_in_html => true
182
- ).to_s(:html)
183
- html_output += '</div>'
184
- end
161
+ ones
162
+ end
163
+
164
+ def self.last_to_html(diff)
165
+ left_hash = get_last_left(diff)
166
+ right_hash = get_last_right(diff)
167
+
168
+ html_output = '<link rel="stylesheet"' +
169
+ 'href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/' +
170
+ 'bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/' +
171
+ '1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">'
172
+ html_output += '<style>'
173
+ html_output += Diffy::CSS
174
+ html_output += '</style>'
175
+ html_output += '<div class="card" style="overflow-y: scroll;max-height:400px">'
176
+ left_hash.keys.each do |file|
177
+ html_output += '<div class="file mb-4 p-1">'
178
+ html_output += '<h4>' + file + '</h4>'
179
+ html_output += Diffy::Diff.new(
180
+ left_hash[file],
181
+ right_hash[file],
182
+ :include_plus_and_minus_in_html => true,
183
+ :allow_empty_diff => false
184
+ ).to_s(:html)
185
185
  html_output += '</div>'
186
- html_output
187
186
  end
188
-
189
- def self.diff_to_html(diff)
190
- left_hash = get_each_left(diff)
191
- right_hash = get_each_right(diff)
192
- html_output = '<div style="overflow-y: scroll;height:400px">'
193
- html_output += '<style>'
194
- html_output += Diffy::CSS
195
- html_output += '</style>'
196
- html_output += '<div class="row mb-3">'
197
- html_output += '<div class="col-md-12 offset" style="overflow-y: scroll;">'
198
-
199
- left_hash.keys.each do |file|
200
- html_output += '<div class="row text-center">
201
- <div class="col-12">
202
- <h4>'
203
- html_output+= file.to_s
204
- html_output += '</h4>
205
- </div>
187
+ html_output += '</div>'
188
+ html_output
189
+ end
190
+
191
+ def self.diff_to_html(diff)
192
+ left_hash = get_each_left(diff)
193
+ right_hash = get_each_right(diff)
194
+ html_output = '<div style="overflow-y: scroll;height:400px">'
195
+ html_output += '<style>'
196
+ html_output += Diffy::CSS
197
+ html_output += '</style>'
198
+ html_output += '<div class="row mb-3">'
199
+ html_output += '<div class="col-md-12 offset" style="overflow-y: scroll;">'
200
+
201
+ left_hash.keys.each do |file|
202
+ html_output += '<div class="row text-center">
203
+ <div class="col-12">
204
+ <h4>'
205
+ html_output+= file.to_s
206
+ html_output += '</h4>
206
207
  </div>
207
- <div class="row mb-4">
208
- <div class="col-6">'
209
- html_output += Diffy::SplitDiff.new(
210
- left_hash[file],
211
- right_hash[file],
212
- :format => :html
213
- ).left
214
-
215
- html_output +=
216
- '</div>
217
- <div class="col-6">'
218
- html_output += Diffy::SplitDiff.new(
219
- left_hash[file],
220
- right_hash[file],
221
- :format => :html
222
- ).right
223
-
224
- html_output += '</div></div>'
225
- end
226
- html_output += "</div>"
227
- html_output += "</div>"
228
- html_output += "</div>"
229
- html_output
230
-
208
+ </div>
209
+ <div class="row mb-4">
210
+ <div class="col-6">'
211
+ html_output += Diffy::SplitDiff.new(
212
+ left_hash[file],
213
+ right_hash[file],
214
+ :format => :html
215
+ ).left
216
+
217
+ html_output +=
218
+ '</div>
219
+ <div class="col-6">'
220
+ html_output += Diffy::SplitDiff.new(
221
+ left_hash[file],
222
+ right_hash[file],
223
+ :format => :html
224
+ ).right
225
+
226
+ html_output += '</div></div>'
231
227
  end
228
+ html_output += "</div>"
229
+ html_output += "</div>"
230
+ html_output += "</div>"
231
+ html_output
232
+
233
+ end
232
234
  end
233
- end
@@ -0,0 +1,3 @@
1
+ module WebGit
2
+ class AuthenticationError < StandardError; end
3
+ end
@@ -0,0 +1,114 @@
1
+ module WebGit
2
+ require "git"
3
+ require "ansispan"
4
+
5
+ class Graph
6
+ require "action_view"
7
+ require "action_view/helpers"
8
+ include ActionView::Helpers::DateHelper
9
+ attr_accessor :heads
10
+
11
+ def initialize(git)
12
+ @git = git
13
+ @full_list = []
14
+ @heads = {}
15
+ end
16
+
17
+ def to_hash
18
+
19
+ has_changes = has_untracked_changes?
20
+ if has_changes
21
+ temporarily_stash_changes
22
+ end
23
+
24
+ draw_graph
25
+
26
+ if has_changes
27
+ stash_pop
28
+ end
29
+ @full_list
30
+ end
31
+
32
+ def self.project_root
33
+ if defined?(Rails) && Rails.respond_to?("root")
34
+ return Rails.root
35
+ end
36
+
37
+ if defined?(Bundler)
38
+ return Bundler.root
39
+ end
40
+
41
+ Dir.pwd
42
+ end
43
+
44
+ def cli_graph
45
+ Dir.chdir(Graph.project_root) do
46
+ @cli_graph = `git log --oneline --decorate --graph --all --color`
47
+ all_commits = `git log --all --format=format:%H`.split("\n").map{|a| a.slice(0,7)}
48
+
49
+ @cli_graph = Ansispan.convert(@cli_graph)
50
+ all_commits.each do |sha|
51
+ sha_button = "<span class=\"commit\"><button class=\"btn btn-link sha\">#{sha}</button></span>"
52
+ @cli_graph.gsub!(sha, sha_button)
53
+ end
54
+ end
55
+ @cli_graph
56
+ end
57
+
58
+ def has_untracked_changes?
59
+ @git.diff.size > 0
60
+ end
61
+
62
+ def temporarily_stash_changes
63
+ @git.add(all: true)
64
+ stash_count = Git::Stashes.new(@git).count
65
+ Git::Stash.new(@git, "Temporary Stash #{stash_count}")
66
+ end
67
+
68
+ def stash_pop
69
+ stashes = Git::Stashes.new(@git)
70
+ stashes.apply(0)
71
+ end
72
+
73
+ def draw_graph
74
+ starting_branch = @git.current_branch
75
+ branches = @git.branches.local.map(&:name)
76
+ branches.each do |branch_name|
77
+ branch = { branch: branch_name }
78
+ @git.checkout(branch_name)
79
+ log_commits = build_array_of_commit_hashes
80
+ branch[:log] = log_commits
81
+ branch[:head] = log_commits.last[:sha]
82
+ @full_list.push branch
83
+ end
84
+ @git.checkout(starting_branch)
85
+
86
+ @full_list.each do |branch_hash|
87
+ head_sha = branch_hash[:head]
88
+ branch_name = branch_hash[:branch]
89
+
90
+ if @heads[head_sha].nil?
91
+ @heads[head_sha] = [branch_name]
92
+ else
93
+ @heads[head_sha].push branch_name
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ def build_array_of_commit_hashes
100
+ log_commits = []
101
+ @git.log.sort_by(&:date).each do |git_commit_object|
102
+ commit = {}
103
+ commit[:sha] = git_commit_object.sha.slice(0..7)
104
+ commit[:date] = git_commit_object.date
105
+ commit[:formatted_date] = time_ago_in_words(git_commit_object.date)
106
+ commit[:message] = git_commit_object.message
107
+ commit[:author] = git_commit_object.author.name
108
+ commit[:heads] = []
109
+ log_commits.push commit
110
+ end
111
+ log_commits
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,34 @@
1
+ require 'timeout'
2
+ require 'web_git/exceptions'
3
+
4
+ module WebGit
5
+ class Heroku
6
+ def self.authenticate(email, password)
7
+ raise ArgumentError.new("Email and password cannot be blank.") if email.blank? || password.blank?
8
+ script = File.join( File.dirname(__FILE__), '/../scripts/heroku_login.exp')
9
+
10
+ command = "#{script} #{email} #{password}"
11
+ rout, wout = IO.pipe
12
+ pid = Process.spawn(command, :out => wout)
13
+
14
+ begin
15
+ status = Timeout.timeout(30) do
16
+ _, status = Process.wait2(pid)
17
+ wout.close
18
+ end
19
+ stdout = rout.readlines.join("\n")
20
+ rout.close
21
+ message = stdout.match(/Error.*\./).to_s
22
+ raise WebGit::AuthenticationError.new(message) if stdout.include?("Error")
23
+
24
+ rescue Timeout::Error
25
+ Process.kill('TERM', script_pid)
26
+ raise Timeout::Error.new("Sign in took longer than 30 seconds.")
27
+ end
28
+ end
29
+
30
+ def self.whoami
31
+ `heroku whoami`.chomp
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,8 @@
1
+ # required for git
2
+ class String
3
+ def strip_heredoc
4
+ indent = scan(/^[ \t]*(?=\S)/).min.size || 0
5
+ gsub(/^[ \t]{#{indent}}/, '')
6
+ end
7
+ end
8
+