stg 0.1.3 → 0.1.5
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.
- checksums.yaml +4 -4
- data/lib/{actions.rb → stg/actions.rb} +239 -55
- data/lib/{differencing.rb → stg/differencing.rb} +6 -5
- data/lib/{help.rb → stg/help.rb} +3 -3
- data/lib/{utils.rb → stg/utils.rb} +14 -0
- data/lib/stg/version.rb +3 -0
- data/lib/stg.rb +34 -4
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0f993bbd2bd4575637beb24485c54a88a2679551000551df0f1b1a552249922f
|
|
4
|
+
data.tar.gz: cca41c04c1ab146a16055debbf6364081993d4afb647222865a219d88d9a40bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 745cc975c54fc9e1449a514c711ca2a3ab98df951deb554b6e37de8f5e01ddbacf4e2001a20d0cd512d4ed5411291b4a213e0293928878b805ee5395acbd02c7
|
|
7
|
+
data.tar.gz: 9afe52e540571bd3330743229d8e267150d243a9e28a815a503841199979c1a156434ad07b4a4d828a3f5db042710a3a5756999c8bf525a10aafa17f3dd0ff26
|
|
@@ -9,6 +9,22 @@ module Actions
|
|
|
9
9
|
include DiffCalc
|
|
10
10
|
|
|
11
11
|
def p_initialize
|
|
12
|
+
begin
|
|
13
|
+
OptionParser.new do |opts|
|
|
14
|
+
opts.banner = 'Usage: stg init'
|
|
15
|
+
|
|
16
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
17
|
+
puts opts
|
|
18
|
+
exit
|
|
19
|
+
end
|
|
20
|
+
end.parse!
|
|
21
|
+
rescue OptionParser::ParseError => e
|
|
22
|
+
puts e.message
|
|
23
|
+
puts 'Usage: stg init'
|
|
24
|
+
puts ' -h, --help Show this help'
|
|
25
|
+
exit 1
|
|
26
|
+
end
|
|
27
|
+
|
|
12
28
|
# Check if already initialized
|
|
13
29
|
if File.exist?('.stolen-git')
|
|
14
30
|
if confirm?('An instance of stolen-git is already up here do you want to replace it')
|
|
@@ -41,6 +57,7 @@ module Actions
|
|
|
41
57
|
|
|
42
58
|
# main files
|
|
43
59
|
File.write('.stolen-git/project_info.json', {})
|
|
60
|
+
File.write('.stg-ignore', JSON.pretty_generate(['.*/']))
|
|
44
61
|
File.write('.stolen-git/commits.json', JSON.pretty_generate({ commits: [] }))
|
|
45
62
|
File.write('.stolen-git/index.json', {})
|
|
46
63
|
|
|
@@ -54,16 +71,36 @@ module Actions
|
|
|
54
71
|
end
|
|
55
72
|
|
|
56
73
|
def stage
|
|
74
|
+
begin
|
|
75
|
+
OptionParser.new do |opts|
|
|
76
|
+
opts.banner = 'Usage: stg stage <file> [files...]'
|
|
77
|
+
|
|
78
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
79
|
+
puts opts
|
|
80
|
+
exit
|
|
81
|
+
end
|
|
82
|
+
end.parse!
|
|
83
|
+
rescue OptionParser::ParseError => e
|
|
84
|
+
puts e.message
|
|
85
|
+
puts 'Usage: stg stage <file> [files...]'
|
|
86
|
+
puts ' -h, --help Show this help'
|
|
87
|
+
exit 1
|
|
88
|
+
end
|
|
89
|
+
|
|
57
90
|
inp = ARGV
|
|
58
91
|
|
|
59
92
|
if inp.empty?
|
|
60
|
-
puts 'Usage: stg stage <
|
|
93
|
+
puts 'Usage: stg stage <file> [files...]'
|
|
61
94
|
return
|
|
62
95
|
end
|
|
63
96
|
|
|
64
|
-
index =
|
|
65
|
-
|
|
97
|
+
index = read_json('.stolen-git/index.json')
|
|
98
|
+
ignore = read_json('.stg-ignore')
|
|
66
99
|
stage_file = lambda do |file_path|
|
|
100
|
+
ignore&.each do |ignore_pattern|
|
|
101
|
+
return if File.fnmatch(ignore_pattern, file_path)
|
|
102
|
+
end
|
|
103
|
+
file_path = clean_path(file_path)
|
|
67
104
|
file_hash = get_file_hash(file_path)
|
|
68
105
|
file_content = File.read(file_path)
|
|
69
106
|
|
|
@@ -79,7 +116,10 @@ module Actions
|
|
|
79
116
|
end
|
|
80
117
|
|
|
81
118
|
stage_directory = lambda do |dir_path|
|
|
119
|
+
dir_path = clean_path(dir_path)
|
|
82
120
|
Dir.children(dir_path).each do |entry|
|
|
121
|
+
next if entry == '.stolen-git'
|
|
122
|
+
|
|
83
123
|
path = File.join(dir_path, entry)
|
|
84
124
|
if File.file?(path)
|
|
85
125
|
stage_file.call(path)
|
|
@@ -90,6 +130,7 @@ module Actions
|
|
|
90
130
|
end
|
|
91
131
|
|
|
92
132
|
inp.each do |inp_path|
|
|
133
|
+
inp_path = clean_path(inp_path)
|
|
93
134
|
unless File.exist? inp_path
|
|
94
135
|
puts "#{inp_path} doesn't exist"
|
|
95
136
|
next
|
|
@@ -111,17 +152,31 @@ module Actions
|
|
|
111
152
|
options = { name: '', description: '' }
|
|
112
153
|
|
|
113
154
|
# Getting commit name & description
|
|
114
|
-
|
|
115
|
-
|
|
155
|
+
begin
|
|
156
|
+
OptionParser.new do |opts|
|
|
157
|
+
opts.banner = 'Usage: stg commit [options]'
|
|
116
158
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
159
|
+
opts.on('-n', '--name NAME', 'Add a commit name') do |name|
|
|
160
|
+
options[:name] = name
|
|
161
|
+
end
|
|
120
162
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
163
|
+
opts.on('-d', '--description DESCRIPTION', 'Add a commit description') do |description|
|
|
164
|
+
options[:description] = description
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
168
|
+
puts opts
|
|
169
|
+
exit
|
|
170
|
+
end
|
|
171
|
+
end.parse!
|
|
172
|
+
rescue OptionParser::ParseError => e
|
|
173
|
+
puts e.message
|
|
174
|
+
puts 'Usage: stg commit [options]'
|
|
175
|
+
puts ' -n, --name NAME Add a commit name'
|
|
176
|
+
puts ' -d, --description DESCRIPTION Add a commit description'
|
|
177
|
+
puts ' -h, --help Show this help'
|
|
178
|
+
exit 1
|
|
179
|
+
end
|
|
125
180
|
|
|
126
181
|
options[:name] = ask('Add a commit name: ') if options[:name].empty?
|
|
127
182
|
|
|
@@ -139,35 +194,57 @@ module Actions
|
|
|
139
194
|
parent_commit = branch_content['commit_pointer']
|
|
140
195
|
|
|
141
196
|
# Getting differences to last commit
|
|
142
|
-
|
|
143
197
|
no_insertions = 0
|
|
144
198
|
no_deletions = 0
|
|
145
199
|
no_file_changed = 0
|
|
200
|
+
|
|
146
201
|
commit_diff = {}
|
|
147
202
|
|
|
148
203
|
getting_diff = lambda do |entries|
|
|
149
|
-
|
|
204
|
+
if entries.nil?
|
|
205
|
+
index.each do |key, value|
|
|
206
|
+
key = clean_path(key)
|
|
207
|
+
new_entry_content = File.read(".stolen-git/storage/blobs/#{value['hash']}").lines.to_a
|
|
208
|
+
compute_diff([], new_entry_content)
|
|
209
|
+
diff = build_sequences
|
|
210
|
+
no_insertions += diff[:insertions]
|
|
211
|
+
no_deletions += diff[:deletions]
|
|
212
|
+
no_file_changed += 1
|
|
213
|
+
commit_diff[key] = diff
|
|
214
|
+
end
|
|
215
|
+
else
|
|
216
|
+
parent_map = entries.to_h { |e| [e['path'], e['hash']] }
|
|
150
217
|
|
|
151
|
-
|
|
152
|
-
|
|
218
|
+
index.each do |key, value|
|
|
219
|
+
key = clean_path(key)
|
|
153
220
|
new_hash = value['hash']
|
|
154
|
-
old_hash =
|
|
155
|
-
|
|
156
|
-
|
|
221
|
+
old_hash = parent_map[key]
|
|
222
|
+
|
|
223
|
+
if old_hash
|
|
224
|
+
next if old_hash == new_hash
|
|
225
|
+
|
|
226
|
+
entry_content = File.read(".stolen-git/storage/blobs/#{old_hash}").lines.to_a
|
|
227
|
+
new_entry_content = File.read(".stolen-git/storage/blobs/#{new_hash}").lines.to_a
|
|
228
|
+
compute_diff(entry_content, new_entry_content)
|
|
229
|
+
else
|
|
230
|
+
new_entry_content = File.read(".stolen-git/storage/blobs/#{new_hash}").lines.to_a
|
|
231
|
+
compute_diff([], new_entry_content)
|
|
232
|
+
end
|
|
157
233
|
|
|
158
|
-
entry_content = File.read(".stolen-git/storage/blobs/#{old_hash}").lines.to_a
|
|
159
|
-
new_entry_content = File.read(".stolen-git/storage/blobs/#{new_hash}").lines.to_a
|
|
160
|
-
compute_diff(entry_content, new_entry_content)
|
|
161
234
|
diff = build_sequences
|
|
162
235
|
no_insertions += diff[:insertions]
|
|
163
236
|
no_deletions += diff[:deletions]
|
|
164
237
|
no_file_changed += 1
|
|
165
238
|
commit_diff[key] = diff
|
|
166
|
-
|
|
167
|
-
new_entry_content = File.read(".stolen-git/storage/blobs/#{value['hash']}").lines.to_a
|
|
168
|
-
compute_diff('', new_entry_content)
|
|
169
|
-
diff = build_sequences
|
|
239
|
+
end
|
|
170
240
|
|
|
241
|
+
parent_map.each do |key, old_hash|
|
|
242
|
+
key = clean_path(key)
|
|
243
|
+
next if index.key?(key)
|
|
244
|
+
|
|
245
|
+
entry_content = File.read(".stolen-git/storage/blobs/#{old_hash}").lines.to_a
|
|
246
|
+
compute_diff(entry_content, [])
|
|
247
|
+
diff = build_sequences
|
|
171
248
|
no_insertions += diff[:insertions]
|
|
172
249
|
no_deletions += diff[:deletions]
|
|
173
250
|
no_file_changed += 1
|
|
@@ -193,6 +270,7 @@ module Actions
|
|
|
193
270
|
|
|
194
271
|
# Making the tree
|
|
195
272
|
index.each do |key, value|
|
|
273
|
+
key = clean_path(key)
|
|
196
274
|
tree_content[:entries].push({
|
|
197
275
|
path: key,
|
|
198
276
|
type: 'blob',
|
|
@@ -243,6 +321,22 @@ module Actions
|
|
|
243
321
|
end
|
|
244
322
|
|
|
245
323
|
def reset
|
|
324
|
+
begin
|
|
325
|
+
OptionParser.new do |opts|
|
|
326
|
+
opts.banner = 'Usage: stg reset [commit_id]'
|
|
327
|
+
|
|
328
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
329
|
+
puts opts
|
|
330
|
+
exit
|
|
331
|
+
end
|
|
332
|
+
end.parse!
|
|
333
|
+
rescue OptionParser::ParseError => e
|
|
334
|
+
puts e.message
|
|
335
|
+
puts 'Usage: stg reset [commit_id]'
|
|
336
|
+
puts ' -h, --help Show this help'
|
|
337
|
+
exit 1
|
|
338
|
+
end
|
|
339
|
+
|
|
246
340
|
commit_id = ARGV.first
|
|
247
341
|
commit_history = read_json('.stolen-git/commits.json')
|
|
248
342
|
pointer = read_json('.stolen-git/pointer.json')
|
|
@@ -272,13 +366,27 @@ module Actions
|
|
|
272
366
|
options = { commit: false }
|
|
273
367
|
|
|
274
368
|
# Getting commit name & description
|
|
275
|
-
|
|
276
|
-
|
|
369
|
+
begin
|
|
370
|
+
OptionParser.new do |opts|
|
|
371
|
+
opts.banner = 'Usage: stg checkout [options]'
|
|
372
|
+
|
|
373
|
+
opts.on('-c', '--commit', 'Add a commit id instead') do
|
|
374
|
+
options[:commit] = true
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
378
|
+
puts opts
|
|
379
|
+
exit
|
|
380
|
+
end
|
|
381
|
+
end.parse!
|
|
382
|
+
rescue OptionParser::ParseError => e
|
|
383
|
+
puts e.message
|
|
384
|
+
puts 'Usage: stg checkout [options]'
|
|
385
|
+
puts ' -c, --commit Add a commit id instead'
|
|
386
|
+
puts ' -h, --help Show this help'
|
|
387
|
+
exit 1
|
|
388
|
+
end
|
|
277
389
|
|
|
278
|
-
opts.on('-c', '--commit', 'Add a commit id instead') do
|
|
279
|
-
options[:commit] = true
|
|
280
|
-
end
|
|
281
|
-
end.parse!
|
|
282
390
|
inp = ARGV.last
|
|
283
391
|
if !inp
|
|
284
392
|
puts 'Please Enter the name of a branch or commit_id'
|
|
@@ -287,7 +395,7 @@ module Actions
|
|
|
287
395
|
current_commit_hash = commit_history['commits'].find { |x| x['id'] == inp }['hash']
|
|
288
396
|
revert_to_commit(current_commit_hash)
|
|
289
397
|
else
|
|
290
|
-
# TODO: Handle if user enters branch_id instead
|
|
398
|
+
# TODO: Handle if user enters branch_id instead of name
|
|
291
399
|
branch_content = {}
|
|
292
400
|
branch_id = ''
|
|
293
401
|
Dir.children('.stolen-git/branches').each do |entry|
|
|
@@ -302,28 +410,47 @@ module Actions
|
|
|
302
410
|
nil
|
|
303
411
|
end
|
|
304
412
|
commit_hash = branch_content['commit_pointer']
|
|
305
|
-
revert_to_commit(commit_hash)
|
|
413
|
+
revert_to_commit(commit_hash) if commit_hash&.length&.positive?
|
|
306
414
|
pointer = read_json('.stolen-git/pointer.json')
|
|
307
415
|
pointer['point_to'] = branch_id
|
|
308
416
|
pointer['type'] = 'branch'
|
|
309
417
|
File.write('.stolen-git/pointer.json', JSON.pretty_generate(pointer))
|
|
418
|
+
|
|
310
419
|
end
|
|
311
420
|
end
|
|
312
421
|
|
|
313
422
|
def branch
|
|
314
|
-
|
|
423
|
+
begin
|
|
424
|
+
OptionParser.new do |opts|
|
|
425
|
+
opts.banner = 'Usage: stg branch [name]'
|
|
426
|
+
|
|
427
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
428
|
+
puts opts
|
|
429
|
+
exit
|
|
430
|
+
end
|
|
431
|
+
end.parse!
|
|
432
|
+
rescue OptionParser::ParseError => e
|
|
433
|
+
puts e.message
|
|
434
|
+
puts 'Usage: stg branch [name]'
|
|
435
|
+
puts ' -h, --help Show this help'
|
|
436
|
+
exit 1
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
names = ARGV
|
|
315
440
|
pointer = read_json('.stolen-git/pointer.json')
|
|
316
441
|
pointed_branch = pointer['type'] == 'branch' ? pointer['point_to'] : ''
|
|
317
|
-
if
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
442
|
+
if names && names.length.positive?
|
|
443
|
+
names.each do |name|
|
|
444
|
+
first_commit = pointer['type'] == 'branch' ? read_json(".stolen-git/branches/#{pointed_branch}.json")['commit_pointer'] : pointer['point_to']
|
|
445
|
+
id = SecureRandom.uuid
|
|
446
|
+
File.write(".stolen-git/branches/#{id}.json", JSON.pretty_generate({
|
|
447
|
+
name: name,
|
|
448
|
+
created_at: Time.now,
|
|
449
|
+
commit_pointer: first_commit
|
|
450
|
+
}))
|
|
451
|
+
puts "branch #{name} created"
|
|
452
|
+
end
|
|
325
453
|
return
|
|
326
|
-
puts "branch #{name} created"
|
|
327
454
|
end
|
|
328
455
|
Dir.children('.stolen-git/branches').each do |entry|
|
|
329
456
|
branch_content = read_json(".stolen-git/branches/#{entry}")
|
|
@@ -338,8 +465,25 @@ module Actions
|
|
|
338
465
|
end
|
|
339
466
|
|
|
340
467
|
def diff
|
|
468
|
+
begin
|
|
469
|
+
OptionParser.new do |opts|
|
|
470
|
+
opts.banner = 'Usage: stg diff'
|
|
471
|
+
|
|
472
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
473
|
+
puts opts
|
|
474
|
+
exit
|
|
475
|
+
end
|
|
476
|
+
end.parse!
|
|
477
|
+
rescue OptionParser::ParseError => e
|
|
478
|
+
puts e.message
|
|
479
|
+
puts 'Usage: stg diff'
|
|
480
|
+
puts ' -h, --help Show this help'
|
|
481
|
+
exit 1
|
|
482
|
+
end
|
|
483
|
+
|
|
341
484
|
index = read_json('.stolen-git/index.json')
|
|
342
485
|
index.each do |key, value|
|
|
486
|
+
key = clean_path(key)
|
|
343
487
|
new_file_content = File.exist?(key) ? File.read(key) : nil
|
|
344
488
|
file_name = File.basename(key)
|
|
345
489
|
if new_file_content.nil?
|
|
@@ -357,25 +501,65 @@ module Actions
|
|
|
357
501
|
end
|
|
358
502
|
|
|
359
503
|
def log
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
504
|
+
# Handle if the user wants to -[num]
|
|
505
|
+
ARGV.map! do |arg|
|
|
506
|
+
if arg =~ /^-(\d+)$/
|
|
507
|
+
['-l', ::Regexp.last_match(1)]
|
|
508
|
+
else
|
|
509
|
+
arg
|
|
510
|
+
end
|
|
511
|
+
end.flatten!
|
|
363
512
|
|
|
364
|
-
|
|
365
|
-
|
|
513
|
+
options = { limit: 0 }
|
|
514
|
+
begin
|
|
515
|
+
OptionParser.new do |opts|
|
|
516
|
+
opts.banner = 'Usage: stg log [limit]'
|
|
366
517
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
518
|
+
opts.on('-l', '--limit LIMIT', 'limit showed logs') do |num|
|
|
519
|
+
options[:limit] = num.to_i
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
opts.on_tail('-h', '--help', 'Show this help') do
|
|
523
|
+
puts opts
|
|
524
|
+
exit
|
|
525
|
+
end
|
|
526
|
+
end.parse!
|
|
527
|
+
rescue OptionParser::ParseError => e
|
|
528
|
+
puts e.message
|
|
529
|
+
puts 'Usage: stg log [limit]'
|
|
530
|
+
puts ' -[num], --limit limit showed logs i.e. stg log -5'
|
|
531
|
+
puts ' -l, --limit limit showed logs'
|
|
532
|
+
puts ' -h, --help Show this help'
|
|
533
|
+
exit 1
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
is_limited = options[:limit] > 0
|
|
537
|
+
pointer = read_json('.stolen-git/pointer.json')
|
|
538
|
+
last_commit = pointer['type'] == 'commit' ? pointer['point_to'] : read_json(".stolen-git/branches/#{pointer['point_to']}.json")['commit_pointer']
|
|
539
|
+
unless last_commit
|
|
540
|
+
puts "Couldn't find last commits. The setup might have been corrupted. If that's the case run 'stg init'"
|
|
541
|
+
end
|
|
542
|
+
i = 0
|
|
543
|
+
|
|
544
|
+
print_commit = lambda do |commit_hash, commit_content|
|
|
372
545
|
puts
|
|
373
546
|
puts "commit #{commit_content['id']}".green
|
|
547
|
+
puts "hash: #{commit_hash[0..5]}...#{commit_hash[-5..]}".green
|
|
374
548
|
puts "Author #{commit_content['author_profile']['username']} <#{commit_content['author_profile']['email']}>"
|
|
375
549
|
puts "Date: #{commit_content['created_at']}"
|
|
376
550
|
puts
|
|
377
551
|
puts " #{commit_content['name']}"
|
|
378
|
-
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
while (is_limited && i < options[:limit] || !is_limited) && last_commit && last_commit.length.positive?
|
|
555
|
+
last_commit_content = read_json(".stolen-git/commits/#{last_commit}.json")
|
|
556
|
+
print_commit.call(last_commit, last_commit_content)
|
|
557
|
+
last_commit = last_commit_content['parent_commit']
|
|
558
|
+
i += 1
|
|
559
|
+
if !is_limited && i >= 5
|
|
560
|
+
q = ask(':')
|
|
561
|
+
break if q == 'q'
|
|
562
|
+
end
|
|
379
563
|
end
|
|
380
564
|
end
|
|
381
565
|
end
|
|
@@ -27,14 +27,12 @@ module DiffCalc
|
|
|
27
27
|
if i1 >= @old_s.length
|
|
28
28
|
result = { diff_cnt: @new_s.length - i2, insertions: @new_s.length - i2, deletions: 0, action: :insert }
|
|
29
29
|
@mem[[i1, i2]] = result
|
|
30
|
-
differencing(i1, i2 + 1) if i2 < @new_s.length
|
|
31
30
|
return result
|
|
32
31
|
end
|
|
33
32
|
|
|
34
33
|
if i2 >= @new_s.length
|
|
35
34
|
result = { diff_cnt: @old_s.length - i1, insertions: 0, deletions: @old_s.length - i1, action: :delete }
|
|
36
35
|
@mem[[i1, i2]] = result
|
|
37
|
-
differencing(i1 + 1, i2) if i1 < @old_s.length
|
|
38
36
|
return result
|
|
39
37
|
end
|
|
40
38
|
|
|
@@ -69,7 +67,10 @@ module DiffCalc
|
|
|
69
67
|
deletion_seq = {}
|
|
70
68
|
|
|
71
69
|
while i1 < @old_s.length || i2 < @new_s.length
|
|
72
|
-
|
|
70
|
+
entry = @mem[[i1, i2]]
|
|
71
|
+
break unless entry
|
|
72
|
+
|
|
73
|
+
action = entry[:action]
|
|
73
74
|
|
|
74
75
|
case action
|
|
75
76
|
when :done
|
|
@@ -82,12 +83,12 @@ module DiffCalc
|
|
|
82
83
|
deletion_seq[i2].push({ old_index: i1, ma_type: 'bs' })
|
|
83
84
|
i1 += 1
|
|
84
85
|
when :insert
|
|
85
|
-
insertion_seq[i2] = { value: @new_s[i2], old_index: i1 }
|
|
86
|
+
insertion_seq[i2] = { value: @new_s[i2].encode('UTF-8', invalid: :replace, undef: :replace, replace: ''), old_index: i1 }
|
|
86
87
|
i2 += 1
|
|
87
88
|
end
|
|
88
89
|
end
|
|
89
90
|
|
|
90
|
-
result = @mem[[0, 0]]
|
|
91
|
+
result = @mem[[0, 0]] || { insertions: 0, deletions: 0, diff_cnt: 0 }
|
|
91
92
|
{
|
|
92
93
|
insertion_seq: insertion_seq,
|
|
93
94
|
deletion_seq: deletion_seq,
|
data/lib/{help.rb → stg/help.rb}
RENAMED
|
@@ -8,11 +8,11 @@ module Help
|
|
|
8
8
|
stage: 'add a file or directory to be tracked ',
|
|
9
9
|
commit: 'Save the current tracked state ',
|
|
10
10
|
diff: 'get the difference between working directory and the last commit ',
|
|
11
|
-
log: 'print out commit history
|
|
11
|
+
log: 'print out commit history',
|
|
12
12
|
reset: 'Revert to commit',
|
|
13
13
|
checkout: 'check a commit or a branch without loss in data',
|
|
14
|
-
branch: 'List all branches.
|
|
15
|
-
|
|
14
|
+
branch: 'List all branches.',
|
|
15
|
+
help: 'show this list'
|
|
16
16
|
}
|
|
17
17
|
max_len = 0
|
|
18
18
|
commands_docs.each_key do |command|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'fileutils'
|
|
2
2
|
require 'optparse'
|
|
3
3
|
require 'digest'
|
|
4
|
+
require 'pathname'
|
|
4
5
|
module Utils
|
|
5
6
|
def confirm?(prompt)
|
|
6
7
|
loop do
|
|
@@ -28,6 +29,8 @@ module Utils
|
|
|
28
29
|
|
|
29
30
|
def read_json(path)
|
|
30
31
|
JSON.parse(File.read(path))
|
|
32
|
+
rescue StandardError
|
|
33
|
+
nil
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def get_file_hash(path)
|
|
@@ -58,6 +61,17 @@ module Utils
|
|
|
58
61
|
|
|
59
62
|
File.write('.stolen-git/index.json', JSON.pretty_generate(index))
|
|
60
63
|
end
|
|
64
|
+
|
|
65
|
+
def clean_path(path)
|
|
66
|
+
Pathname.new(path).cleanpath.to_s
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def check_program_exists
|
|
70
|
+
return true if File.exist? '.stolen-git'
|
|
71
|
+
|
|
72
|
+
puts "There is no instance of stolen-git found. Please run 'stg init' first."
|
|
73
|
+
false
|
|
74
|
+
end
|
|
61
75
|
end
|
|
62
76
|
|
|
63
77
|
include Utils
|
data/lib/stg/version.rb
ADDED
data/lib/stg.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
require_relative '
|
|
1
|
+
require 'optparse'
|
|
2
|
+
require_relative 'stg/help'
|
|
3
|
+
require_relative 'stg/actions'
|
|
4
|
+
require_relative 'stg/version'
|
|
3
5
|
|
|
4
6
|
module Stg
|
|
5
7
|
class CLI
|
|
@@ -7,10 +9,36 @@ module Stg
|
|
|
7
9
|
extend Help
|
|
8
10
|
|
|
9
11
|
def self.start
|
|
12
|
+
begin
|
|
13
|
+
OptionParser.new do |opts|
|
|
14
|
+
opts.banner = 'Usage: stg <command> [options]'
|
|
15
|
+
|
|
16
|
+
opts.on('-v', '--version', 'Show version') do
|
|
17
|
+
puts "stg version #{VERSION}"
|
|
18
|
+
exit
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
opts.on('-h', '--help', 'Show this help') do
|
|
22
|
+
puts print_usage
|
|
23
|
+
exit
|
|
24
|
+
end
|
|
25
|
+
end.order!
|
|
26
|
+
rescue OptionParser::ParseError
|
|
27
|
+
# Ignore unknown options, let command handlers deal with them
|
|
28
|
+
end
|
|
29
|
+
|
|
10
30
|
command = ARGV.shift
|
|
11
|
-
|
|
12
|
-
|
|
31
|
+
if !command || command.empty?
|
|
32
|
+
puts print_usage
|
|
33
|
+
return
|
|
34
|
+
elsif command == 'init'
|
|
13
35
|
p_initialize
|
|
36
|
+
return
|
|
37
|
+
else
|
|
38
|
+
return unless check_program_exists
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
case command
|
|
14
42
|
when 'commit'
|
|
15
43
|
commit
|
|
16
44
|
when 'diff'
|
|
@@ -42,3 +70,5 @@ module Stg
|
|
|
42
70
|
end
|
|
43
71
|
end
|
|
44
72
|
end
|
|
73
|
+
|
|
74
|
+
Stg::CLI.start if __FILE__ == $PROGRAM_NAME
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: stg
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Amr ElTaweel
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: colorize
|
|
@@ -35,11 +35,12 @@ extra_rdoc_files: []
|
|
|
35
35
|
files:
|
|
36
36
|
- README.md
|
|
37
37
|
- bin/stg
|
|
38
|
-
- lib/actions.rb
|
|
39
|
-
- lib/differencing.rb
|
|
40
|
-
- lib/help.rb
|
|
41
38
|
- lib/stg.rb
|
|
42
|
-
- lib/
|
|
39
|
+
- lib/stg/actions.rb
|
|
40
|
+
- lib/stg/differencing.rb
|
|
41
|
+
- lib/stg/help.rb
|
|
42
|
+
- lib/stg/utils.rb
|
|
43
|
+
- lib/stg/version.rb
|
|
43
44
|
homepage: https://github.com/amrbassem218/stolen-git
|
|
44
45
|
licenses:
|
|
45
46
|
- MIT
|