copernicium 0.0.3 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cn +0 -1
- data/lib/RevLog.rb +23 -6
- data/lib/banners.rb +24 -10
- data/lib/pushpull.rb +63 -41
- data/lib/repos.rb +119 -89
- data/lib/required.rb +6 -6
- data/lib/ui.rb +165 -105
- data/lib/workspace.rb +123 -152
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2f146d401e84291f4f694ae9beef84ad4ea96616
|
4
|
+
data.tar.gz: 4771750c664405faebaab54e82fba71988b22c98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 11a03dc13faefeebc2e6070b2fd08da6d83ef658b5e543c1fb5340e02da2f4fca8d54651686ee1e309d83c8234a7c7c9c4fbd9cf86a346e51681e457f7c11e44
|
7
|
+
data.tar.gz: dffba98e39a8189a75f4cfde1ae9fd998d209dd61e87f8c6af7bb94735b95ff60a82094551fec411b1991140b17fb4933dbd09ca16428bb5fc3b148e9d718ffa
|
data/bin/cn
CHANGED
data/lib/RevLog.rb
CHANGED
@@ -26,12 +26,29 @@
|
|
26
26
|
|
27
27
|
module Copernicium
|
28
28
|
module RevLog
|
29
|
+
# called when including RevLog
|
30
|
+
# dont make any new folders
|
29
31
|
def RevLog.setup(root = Dir.pwd)
|
30
|
-
@@
|
31
|
-
@@cop_path = File.join(@@root, '.cn')
|
32
|
+
@@cop_path = File.join(root, '.cn')
|
32
33
|
@@rev_path = File.join(@@cop_path, 'revs')
|
33
|
-
@@log_path = File.join(@@cop_path, 'logmap
|
34
|
-
@@hash_path = File.join(@@cop_path, 'hashmap
|
34
|
+
@@log_path = File.join(@@cop_path, 'logmap')
|
35
|
+
@@hash_path = File.join(@@cop_path, 'hashmap')
|
36
|
+
if File.exist?(@@log_path) && File.exist?(@@hash_path)
|
37
|
+
@@logmap = hash_array.merge(YAML.load_file(@@log_path))
|
38
|
+
@@hashmap = hash_array.merge(YAML.load_file(@@hash_path))
|
39
|
+
else
|
40
|
+
@@logmap = hash_array
|
41
|
+
@@hashmap = hash_array
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# called when running the unit tests
|
46
|
+
# create a new folder for testing
|
47
|
+
def RevLog.setup_tester(root = Dir.pwd)
|
48
|
+
@@cop_path = File.join(root, '.cn')
|
49
|
+
@@rev_path = File.join(@@cop_path, 'revs')
|
50
|
+
@@log_path = File.join(@@cop_path, 'logmap')
|
51
|
+
@@hash_path = File.join(@@cop_path, 'hashmap')
|
35
52
|
Dir.mkdir(@@cop_path) unless Dir.exist?(@@cop_path)
|
36
53
|
Dir.mkdir(@@rev_path) unless Dir.exist?(@@rev_path)
|
37
54
|
if File.exist?(@@log_path) && File.exist?(@@hash_path)
|
@@ -74,11 +91,11 @@ module Copernicium
|
|
74
91
|
|
75
92
|
|
76
93
|
def RevLog.get_file(id)
|
77
|
-
file_path = File.join(@@rev_path, id)
|
94
|
+
file_path = File.join(@@rev_path, id.to_s)
|
78
95
|
if File.exist? file_path
|
79
96
|
File.open(file_path, 'r') { |f| return f.read }
|
80
97
|
else
|
81
|
-
raise Exception, '
|
98
|
+
raise Exception, 'RevLog: invalid file revision id!'.red
|
82
99
|
end
|
83
100
|
end
|
84
101
|
|
data/lib/banners.rb
CHANGED
@@ -7,6 +7,7 @@ class String
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def reset() colorize(0,0) end
|
10
|
+
def ugn() colorize(32,4) end
|
10
11
|
def blu() colorize(34,0) end
|
11
12
|
def yel() colorize(33,0) end
|
12
13
|
def grn() colorize(32,0) end
|
@@ -15,32 +16,35 @@ end
|
|
15
16
|
|
16
17
|
# create large constant strings
|
17
18
|
|
19
|
+
TOP_BANNER = 'Copernicium (cn) - simple DVCS'.ugn
|
20
|
+
|
18
21
|
HELP_BANNER = <<-EOS
|
19
|
-
|
22
|
+
#{TOP_BANNER}
|
20
23
|
|
21
|
-
Starting out:
|
24
|
+
#{'Starting out:'.grn}
|
22
25
|
init - create a new repository
|
23
26
|
status - check repo status
|
27
|
+
history - show repo commits
|
24
28
|
help - show more commands
|
25
29
|
EOS
|
26
30
|
|
27
31
|
|
28
32
|
COMMAND_BANNER = <<-EOS
|
29
33
|
#{HELP_BANNER}
|
30
|
-
Commands
|
31
|
-
clean [files]
|
34
|
+
#{'Commands'.grn}
|
35
|
+
clean [files] [commit/branch]
|
32
36
|
commit [files] -m <message>
|
33
|
-
checkout
|
34
|
-
branch [opt] [
|
37
|
+
checkout <commit id> [files]
|
38
|
+
branch [opt] [branch]
|
35
39
|
-r | rename current branch
|
36
40
|
-c | create a new branch
|
37
41
|
-d | delete a branch
|
38
42
|
merge <branch name>
|
39
43
|
clone <remote url>
|
40
|
-
push
|
41
|
-
pull
|
44
|
+
push <remote user>
|
45
|
+
pull <remote user>
|
42
46
|
|
43
|
-
Options
|
47
|
+
#{'Options'.grn}
|
44
48
|
-v: print version
|
45
49
|
-h: show help
|
46
50
|
|
@@ -48,6 +52,16 @@ Note: [optional] <required>
|
|
48
52
|
|
49
53
|
EOS
|
50
54
|
|
51
|
-
|
55
|
+
|
56
|
+
IN_REPO_WARNING = <<-EOS
|
57
|
+
You are currently in a Copernicium repo... `cn init` is not valid here!
|
58
|
+
EOS
|
59
|
+
|
60
|
+
NO_REPO_WARNING = <<-EOS
|
52
61
|
You are not currently in a Copernicium repo... run `cn init` to create one!
|
53
62
|
EOS
|
63
|
+
|
64
|
+
AUTHOR_BANNER = <<-EOS
|
65
|
+
todo
|
66
|
+
EOS
|
67
|
+
|
data/lib/pushpull.rb
CHANGED
@@ -2,47 +2,56 @@
|
|
2
2
|
# CSC 253
|
3
3
|
# PushPull Module
|
4
4
|
# November 6, 2015
|
5
|
-
require 'net/ssh'
|
6
|
-
require 'net/scp'
|
7
5
|
|
8
6
|
|
9
7
|
module Copernicium
|
10
|
-
|
8
|
+
# How to use for Push, Pull and Clone:
|
9
|
+
# Push - cn push <user> <repo.host:/dir/of/repo> <branch-name>
|
10
|
+
# Pull - cn pull <user> <repo.host:/dir/of/repo> <branch-name>
|
11
|
+
# Clone - cn clone <user> <repo.host:/dir/of/repo>
|
12
|
+
class UIComm
|
13
|
+
end
|
11
14
|
|
15
|
+
module PushPull
|
16
|
+
include Repos # needed for calling their methods
|
12
17
|
# Chris's edit
|
13
18
|
# Takes in Ethan's UICommandCommunicator object and calls
|
14
19
|
# a method based on the command
|
15
|
-
|
20
|
+
#
|
21
|
+
# Fields in UIComm and what they are for me:
|
22
|
+
# @opts - user
|
23
|
+
# @repo - repo.host:/path/to/repo
|
24
|
+
# @rev - branch name
|
25
|
+
def PushPull.UICommandParser(ui_comm)
|
16
26
|
case ui_comm.command
|
17
27
|
when "clone"
|
18
|
-
|
19
|
-
when "merge"
|
20
|
-
# do merge stuff
|
28
|
+
clone(ui_comm.repo, ui_comm.opts.first)
|
21
29
|
when "push"
|
22
|
-
|
30
|
+
push(ui_comm.repo, ui_comm.rev, ui_comm.opts.first)
|
23
31
|
when "pull"
|
24
|
-
|
32
|
+
pull(ui_comm.repo, ui_comm.rev, ui_comm.opts.first)
|
25
33
|
else
|
26
|
-
|
27
|
-
return nil
|
34
|
+
raise "Error: Invalid command supplied to PushPull".red
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
31
38
|
# Function: connect()
|
32
39
|
#
|
33
40
|
# Description:
|
34
|
-
# a net/ssh wrapper, if given a block will execute block on server,
|
41
|
+
# a net/ssh wrapper, if given a block will execute block on server,
|
42
|
+
# otherwise tests connection.
|
35
43
|
#
|
36
44
|
# remote: the remote server, formatted "my.server"
|
37
45
|
# user: the user to connect as
|
38
|
-
def connect(remote, user, &block)
|
46
|
+
def PushPull.connect(remote, user, &block)
|
39
47
|
exit_code = false
|
48
|
+
puts 'inside PushPull connect'.blu
|
40
49
|
if(block.nil?)
|
41
50
|
begin
|
51
|
+
puts 'inside PushPull connect nil block path'.grn
|
42
52
|
Net::SSH.start(remote, user) do |ssh|
|
43
|
-
|
44
|
-
|
45
|
-
exit_code = true;
|
53
|
+
puts ssh.exec!("echo Successful Connection!")
|
54
|
+
exit_code = true
|
46
55
|
end
|
47
56
|
rescue
|
48
57
|
begin
|
@@ -54,12 +63,11 @@ module Copernicium
|
|
54
63
|
puts
|
55
64
|
|
56
65
|
Net::SSH.start(remote, user, :password => passwd) do |ssh|
|
57
|
-
|
58
|
-
|
59
|
-
exit_code = true;
|
66
|
+
puts ssh.exec!("echo Successful Connection!")
|
67
|
+
exit_code = true
|
60
68
|
end
|
61
69
|
rescue
|
62
|
-
|
70
|
+
raise "Unsuccessful Connection".red
|
63
71
|
end
|
64
72
|
end
|
65
73
|
else
|
@@ -67,7 +75,7 @@ module Copernicium
|
|
67
75
|
Net::SSH.start(remote, user) do |ssh|
|
68
76
|
yield ssh
|
69
77
|
end
|
70
|
-
exit_code = true
|
78
|
+
exit_code = true
|
71
79
|
rescue
|
72
80
|
begin
|
73
81
|
print "Username for remote repo: "
|
@@ -80,9 +88,9 @@ module Copernicium
|
|
80
88
|
Net::SSH.start(remote, user, :password => passwd) do |ssh|
|
81
89
|
yield ssh
|
82
90
|
end
|
83
|
-
exit_code = true
|
91
|
+
exit_code = true
|
84
92
|
rescue
|
85
|
-
|
93
|
+
raise "Unable to execute command!".red
|
86
94
|
end
|
87
95
|
end
|
88
96
|
end
|
@@ -94,9 +102,9 @@ module Copernicium
|
|
94
102
|
# Description:
|
95
103
|
# a net/scp wrapper to copy to server
|
96
104
|
#
|
97
|
-
# remote: the remote server and directory to pull from, formatted "my.server
|
105
|
+
# remote: the remote server and directory to pull from, formatted "my.server"
|
98
106
|
# user: the user to connect as
|
99
|
-
def transfer(remote, user, &block)
|
107
|
+
def PushPull.transfer(remote, user, &block)
|
100
108
|
exit_code = false
|
101
109
|
begin
|
102
110
|
Net::SCP.start(remote, user) do |scp|
|
@@ -117,7 +125,7 @@ module Copernicium
|
|
117
125
|
end
|
118
126
|
exit_code = true
|
119
127
|
rescue
|
120
|
-
|
128
|
+
raise "Unable to upload file!".red
|
121
129
|
end
|
122
130
|
end
|
123
131
|
end
|
@@ -131,7 +139,7 @@ module Copernicium
|
|
131
139
|
# dest: what we want of the branch, not needed for blocked calls
|
132
140
|
# local: where we want to put the file, not needed for blocked calls
|
133
141
|
# user: the user to connect as
|
134
|
-
def fetch(remote, dest, local, user, &block)
|
142
|
+
def PushPull.fetch(remote, dest, local, user, &block)
|
135
143
|
exit_code = false
|
136
144
|
if(block.nil?)
|
137
145
|
begin
|
@@ -153,7 +161,7 @@ module Copernicium
|
|
153
161
|
end
|
154
162
|
exit_code = true
|
155
163
|
rescue
|
156
|
-
|
164
|
+
raise "Unable to fetch file(s)!".red
|
157
165
|
end
|
158
166
|
end
|
159
167
|
else
|
@@ -176,7 +184,7 @@ module Copernicium
|
|
176
184
|
end
|
177
185
|
exit_code = true
|
178
186
|
rescue
|
179
|
-
|
187
|
+
raise "Unable to fetch file(s)!".red
|
180
188
|
end
|
181
189
|
end
|
182
190
|
end
|
@@ -191,9 +199,12 @@ module Copernicium
|
|
191
199
|
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
192
200
|
# branch: the branch that we are pushing to
|
193
201
|
# user: the user to connect as
|
194
|
-
def push(remote, branch, user)
|
202
|
+
def PushPull.push(remote, branch, user)
|
195
203
|
# check contents of folder for .cn, fail if not present and remove otherwise
|
196
|
-
dest = remote.split(':')
|
204
|
+
dest = remote.split(':')
|
205
|
+
if(dest.length != 2)
|
206
|
+
dest = dest.insert(0, "cycle3.csug.rochester.edu")
|
207
|
+
end
|
197
208
|
contents = Dir.entries(Dir.pwd)
|
198
209
|
if(!content.include? '.cn')
|
199
210
|
puts 'failed to push to remote, not an initialized Copernicium repo'
|
@@ -202,6 +213,10 @@ module Copernicium
|
|
202
213
|
contents = contents.delete_if{|x| (x.eql? '.cn') || (x.eql? '.') || (x.eql? '..')}
|
203
214
|
end
|
204
215
|
|
216
|
+
# todo - check if branch exists on the remote server
|
217
|
+
# if so, dump contents and save a new commit saying pushed from user
|
218
|
+
# else, create branch and dump files, then make a new commit saying
|
219
|
+
# created branch
|
205
220
|
connect(dest[0], user) do |session|
|
206
221
|
session.exec!("cd #{dest[1]}")
|
207
222
|
result = session.exec!('ls .cn')
|
@@ -222,9 +237,9 @@ module Copernicium
|
|
222
237
|
# Commit the files and merge the branches
|
223
238
|
session.exec!('cn add .')
|
224
239
|
session.exec!('cn commit -m \'Temp commit for push\'')
|
225
|
-
session.exec!(
|
240
|
+
session.exec!("cn checkout #{branch}")
|
226
241
|
session.exec!("cn merge .temp_push_#{user}")
|
227
|
-
session.exec!("cn branch -
|
242
|
+
session.exec!("cn branch -d .temp_push_#{user}")
|
228
243
|
end
|
229
244
|
|
230
245
|
puts "Successfully pushed to #{remote}"
|
@@ -238,10 +253,13 @@ module Copernicium
|
|
238
253
|
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
239
254
|
# branch: the branch that we are pushing to
|
240
255
|
# user: the user to connect as
|
241
|
-
def pull(remote, branch, user)
|
256
|
+
def PushPull.pull(remote, branch, user)
|
242
257
|
# check contents of folder for .cn, fail if not present and remove otherwise
|
243
258
|
crbr = Repos.new.current_branch() # assumed function
|
244
|
-
dest = remote.split(':')
|
259
|
+
dest = remote.split(':')
|
260
|
+
if(dest.length != 2)
|
261
|
+
dest = dest.insert(0, "cycle3.csug.rochester.edu")
|
262
|
+
end
|
245
263
|
contents = Dir.entries(Dir.pwd)
|
246
264
|
if(!content.include? '.cn')
|
247
265
|
puts 'failed to pull from remote, not an initialized Copernicium repo'
|
@@ -262,6 +280,7 @@ module Copernicium
|
|
262
280
|
session.exec!("cn checkout #{branch}")
|
263
281
|
collection = session.exec!("ls | cat")
|
264
282
|
end
|
283
|
+
|
265
284
|
collection = collection.split('\n')
|
266
285
|
if(!collection.include? '.cn')
|
267
286
|
puts 'failed to pull from remote, remote folder not an initialized Copernicium repo'
|
@@ -280,7 +299,7 @@ module Copernicium
|
|
280
299
|
system "cn commit -m \'Temp commit for pull\'"
|
281
300
|
system "cn checkout #{crbr}"
|
282
301
|
system "cn merge .temp_pull_#{user}"
|
283
|
-
system "cn branch -
|
302
|
+
system "cn branch -d .temp_pull_#{user}"
|
284
303
|
puts "Successfully pulled from #{remote}"
|
285
304
|
end
|
286
305
|
|
@@ -291,18 +310,21 @@ module Copernicium
|
|
291
310
|
#
|
292
311
|
# remote: the remote server and directory to push to, formatted "my.server:/the/location/we/want"
|
293
312
|
# user: the user to connect as
|
294
|
-
def clone(remote, user = nil)
|
313
|
+
def PushPull.clone(remote, user = nil)
|
295
314
|
exit_code = false
|
296
315
|
dest = remote.split(':')
|
316
|
+
if(dest.length != 2)
|
317
|
+
dest = dest.insert(0, "cycle3.csug.rochester.edu")
|
318
|
+
end
|
297
319
|
begin
|
298
|
-
fetch(dest[0], dest[1], Dir.pwd, user)
|
299
|
-
exit_code = true
|
320
|
+
fetch(dest[0], dest[1], Dir.pwd, user)
|
321
|
+
exit_code = true
|
300
322
|
rescue
|
301
|
-
puts "Failed to clone the remote branch!"
|
323
|
+
puts "Failed to clone the remote branch!".red
|
302
324
|
end
|
303
325
|
|
304
326
|
return exit_code
|
305
327
|
end
|
306
|
-
|
307
328
|
end
|
308
329
|
end
|
330
|
+
|
data/lib/repos.rb
CHANGED
@@ -28,104 +28,115 @@
|
|
28
28
|
# delete_branch: delete a branch
|
29
29
|
# in - branch name
|
30
30
|
# out - exit status code
|
31
|
+
# note: @@history is a hash array of snapshot ids, which is saved as
|
32
|
+
# .cn/history to persist between calls to the copernicium tool
|
31
33
|
|
32
34
|
module Copernicium
|
33
35
|
class Snapshot
|
34
|
-
attr_accessor :id, :files
|
35
|
-
#
|
36
|
-
def initialize(files = [])
|
37
|
-
|
38
|
-
|
36
|
+
attr_accessor :id, :files, :msg, :date
|
37
|
+
# todo - doesnt support merging. consider adding parents field
|
38
|
+
def initialize(files = [], msg = 'null', date = nil)
|
39
|
+
@date = (date.nil?? DateTime.now : date)
|
40
|
+
@files = files
|
41
|
+
@msg = msg
|
42
|
+
|
43
|
+
# hash self and assign as the id value
|
44
|
+
@id = Digest::SHA256.hexdigest Marshal.dump(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
def time
|
48
|
+
@date.strftime("%m/%d/%Y %I:%M%p")
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
42
52
|
module Repos
|
43
53
|
include RevLog # needs diffing and merging
|
54
|
+
# read in file of snapshot ids (.cn/history)
|
44
55
|
# check the current branch (.cn/branch)
|
45
|
-
|
46
|
-
|
47
|
-
@@
|
48
|
-
@@
|
49
|
-
@@
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
# check if files exist, read them
|
56
|
-
if File.exist?(@@spath) && File.exist?(@@bpath)
|
57
|
-
@@branches = Marshal.load readFile(@@spath)
|
58
|
-
@@branch = readFile(@@bpath)
|
59
|
-
else # use defaults
|
60
|
-
@@branches = {branch => []}
|
61
|
-
@@branch = branch
|
62
|
-
end
|
63
|
-
|
64
|
-
# check if files exist, read them
|
65
|
-
if File.exist?(@@spath) && File.exist?(@@bpath)
|
66
|
-
@@branches = Marshal.load readFile(@@spath)
|
67
|
-
@@branch = readFile(@@bpath)
|
68
|
-
else # use defaults
|
69
|
-
@@branches = {branch => []}
|
70
|
-
@@branch = branch
|
71
|
-
end
|
56
|
+
def Repos.setup(root = Dir.pwd)
|
57
|
+
@@copn = File.join(root, '.cn')
|
58
|
+
@@snap = File.join(@@copn, 'snap')
|
59
|
+
@@head = File.join(@@copn, 'branch')
|
60
|
+
@@hist = File.join(@@copn, 'history')
|
61
|
+
|
62
|
+
# read history from disk
|
63
|
+
@@branch = File.read(@@head)
|
64
|
+
@@history = YAML.load File.read(@@hist)
|
65
|
+
@@brsnaps = Repos.get_branch @@branch
|
72
66
|
end
|
73
67
|
|
74
|
-
#
|
75
|
-
def
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
68
|
+
# unit testing version - create folders for this code
|
69
|
+
def Repos.setup_tester(root = Dir.pwd, branch = 'master')
|
70
|
+
@@copn = File.join(root, '.cn')
|
71
|
+
@@snap = File.join(@@copn, 'snap')
|
72
|
+
@@revs = File.join(@@copn, 'revs')
|
73
|
+
@@head = File.join(@@copn, 'branch')
|
74
|
+
@@hist = File.join(@@copn, 'history')
|
75
|
+
|
76
|
+
# create folders for testing this module
|
77
|
+
Dir.mkdir(@@copn) unless Dir.exist?(@@copn)
|
78
|
+
Dir.mkdir(@@snap) unless Dir.exist?(@@snap)
|
79
|
+
Dir.mkdir(@@revs) unless Dir.exist?(@@revs)
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
f.close
|
86
|
-
txt
|
81
|
+
# default new
|
82
|
+
@@branch = branch
|
83
|
+
@@history = {branch => []}
|
84
|
+
RevLog.setup
|
87
85
|
end
|
88
86
|
|
89
|
-
# check
|
90
|
-
def Repos.
|
91
|
-
|
87
|
+
# check whether a specific branch exists
|
88
|
+
def Repos.has_branch?(branch)
|
89
|
+
Repos.branches.include? branch
|
92
90
|
end
|
93
91
|
|
94
|
-
|
95
|
-
|
92
|
+
# check if any snapshots exist for the current branch
|
93
|
+
def Repos.has_snapshots?
|
94
|
+
not Repos.history(@@branch).empty?
|
96
95
|
end
|
97
96
|
|
98
|
-
#
|
97
|
+
# Return hash of an object
|
99
98
|
def Repos.hasher(obj)
|
100
99
|
Digest::SHA256.hexdigest Marshal.dump(obj)
|
101
100
|
end
|
102
101
|
|
103
|
-
#
|
104
|
-
def Repos.
|
105
|
-
@@
|
102
|
+
# helper to add snap to history
|
103
|
+
def Repos.update_history
|
104
|
+
File.write @@hist, YAML.dump(@@history) # write history
|
105
|
+
end
|
106
|
+
|
107
|
+
# Return array of snapshot IDs
|
108
|
+
def Repos.history(branch = nil)
|
109
|
+
if branch.nil? # return a list of unique all commits
|
110
|
+
(@@history.inject([]) { |o, x| o + x.last }).uniq
|
111
|
+
elsif Repos.has_branch? branch # just return the stored history
|
112
|
+
@@history[branch]
|
113
|
+
else # no commits yet
|
114
|
+
[]
|
115
|
+
end
|
106
116
|
end
|
107
117
|
|
108
|
-
# Create and return snapshot
|
109
|
-
def Repos.make_snapshot(files = [])
|
110
|
-
snap = Snapshot.new(files)
|
111
|
-
snap.id
|
112
|
-
@@branches[@@branch] << snap
|
118
|
+
# Create and return snapshot id
|
119
|
+
def Repos.make_snapshot(files = [], msg = 'nil')
|
120
|
+
snap = Snapshot.new(files, msg)
|
121
|
+
@@history[@@branch] << snap.id
|
113
122
|
|
114
123
|
# Update snaps file
|
115
|
-
update_snap
|
124
|
+
update_snap snap
|
125
|
+
update_history
|
116
126
|
snap.id
|
117
127
|
end
|
118
128
|
|
119
129
|
# helper to write a snapshot, saving a new commit
|
120
|
-
|
121
|
-
|
130
|
+
# marshal serializes the class instance to a string
|
131
|
+
def Repos.update_snap(snap)
|
132
|
+
File.write File.join(@@snap, snap.id), YAML.dump(snap)
|
122
133
|
end
|
123
134
|
|
124
|
-
# todo - Check to make sure id is from a different branch
|
125
135
|
# Merge the target snapshot into HEAD snapshot of the current branch
|
136
|
+
# todo - Check to make sure id is from a different branch
|
126
137
|
def Repos.merge_snapshot(id)
|
127
138
|
# run diff to get conflicts
|
128
|
-
current = @@
|
139
|
+
current = @@history[@@branch].last
|
129
140
|
difference = diff_snapshots(current.id, id)
|
130
141
|
conflicts = difference[1]
|
131
142
|
|
@@ -139,30 +150,20 @@ module Copernicium
|
|
139
150
|
|
140
151
|
# Find snapshot and return snapshot from id
|
141
152
|
def Repos.get_snapshot(id)
|
142
|
-
@@
|
143
|
-
|
144
|
-
return
|
153
|
+
@@history.each do |branch, snapids|
|
154
|
+
snapids.each do |snapid|
|
155
|
+
return YAML.load_file(File.join(@@snap, id)) if snapid == id
|
145
156
|
end
|
146
157
|
end
|
147
158
|
|
148
|
-
raise "
|
149
|
-
end
|
150
|
-
|
151
|
-
# Return array of snapshot IDs
|
152
|
-
def Repos.history(branch = nil)
|
153
|
-
snapids = []
|
154
|
-
if branch.nil?
|
155
|
-
@@branches[@@branch].each { |x| snapids << x.id }
|
156
|
-
elsif
|
157
|
-
@@branches[branch].each { |x| snapids << x.id }
|
158
|
-
end
|
159
|
-
snapids
|
159
|
+
raise "Repos: snapshot #{id} not found in this repo.".red
|
160
160
|
end
|
161
161
|
|
162
162
|
# Find snapshot, delete from snaps/memory
|
163
163
|
def Repos.delete_snapshot(id)
|
164
|
-
@@
|
165
|
-
|
164
|
+
@@history[@@branch].delete_if { |x| x == id }
|
165
|
+
File.delete File.join(@@snap, id)
|
166
|
+
update_history
|
166
167
|
end
|
167
168
|
|
168
169
|
#diff_snapshots needs to catch both files in snap1 that aren’t and snap2 and
|
@@ -190,8 +191,8 @@ module Copernicium
|
|
190
191
|
id2 = files2[f2_index].last
|
191
192
|
|
192
193
|
# get file contents
|
193
|
-
content1 = get_file(id1)
|
194
|
-
content2 = get_file(id2)
|
194
|
+
content1 = RevLog.get_file(id1)
|
195
|
+
content2 = RevLog.get_file(id2)
|
195
196
|
|
196
197
|
# check if the file content for each path is the same
|
197
198
|
if content1 == content2
|
@@ -214,23 +215,52 @@ module Copernicium
|
|
214
215
|
array1.select { |x| !array2.any? { |y| x == y } }
|
215
216
|
end
|
216
217
|
|
217
|
-
# BRANCHING
|
218
|
-
def current() @@branches end
|
219
218
|
|
220
|
-
#
|
219
|
+
# ADDITIONAL MODULE ACCESS INTERFACES
|
220
|
+
#
|
221
|
+
# return the current branch we are on now (string name)
|
222
|
+
def current() @@branch end
|
223
|
+
|
224
|
+
# return the snap id of branch head
|
225
|
+
def current_head() @@history[@@branch].last end
|
226
|
+
|
227
|
+
# return the array of our branches snapshots
|
228
|
+
def current_snaps() @@brsnaps end
|
229
|
+
|
230
|
+
# return the files in the latest snapshot
|
231
|
+
def current_files() Repos.has_snapshots?? @@brsnaps.last.files : [] end
|
232
|
+
|
233
|
+
# Return string array of what branches we have
|
234
|
+
def branches() @@history.keys end
|
235
|
+
|
236
|
+
|
237
|
+
# BRANCHING FUNCTIONALITY
|
238
|
+
#
|
239
|
+
# Create and return hash ID of new branch
|
221
240
|
def Repos.make_branch(branch)
|
222
|
-
@@
|
241
|
+
@@history[branch] = @@history[@@branch].inject([]) { |n, o| n << o }
|
223
242
|
@@branch = branch
|
224
|
-
|
243
|
+
update_history
|
244
|
+
hasher @@history[branch]
|
225
245
|
end
|
226
246
|
|
227
247
|
def Repos.update_branch(branch)
|
228
|
-
|
248
|
+
File.write(@@head, branch)
|
229
249
|
@@branch = branch
|
230
250
|
end
|
231
251
|
|
252
|
+
# From the branch names, get the history, ant build the array of snapshots
|
253
|
+
# This is different than the history branch which just contains ids
|
254
|
+
def Repos.get_branch(branch)
|
255
|
+
Repos.history(branch).inject([]) do |hist, snapid|
|
256
|
+
hist << Repos.get_snapshot(snapid)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# todo - also delete snapshots unique to this branch
|
232
261
|
def Repos.delete_branch(branch)
|
233
|
-
@@
|
262
|
+
@@history.delete(branch)
|
263
|
+
update_history
|
234
264
|
end
|
235
265
|
end # Repos
|
236
266
|
end # Copernicium
|