copernicium 0.0.3 → 0.1
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/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
data/lib/required.rb
CHANGED
@@ -12,10 +12,10 @@ require 'net/scp' # Needed for file transfer between servers
|
|
12
12
|
|
13
13
|
# coperncicium files
|
14
14
|
|
15
|
-
require_relative
|
16
|
-
require_relative
|
17
|
-
require_relative
|
18
|
-
require_relative
|
19
|
-
require_relative
|
20
|
-
require_relative
|
15
|
+
require_relative 'banners'
|
16
|
+
require_relative 'RevLog'
|
17
|
+
require_relative 'repos'
|
18
|
+
require_relative 'pushpull'
|
19
|
+
require_relative 'workspace'
|
20
|
+
require_relative 'ui'
|
21
21
|
|
data/lib/ui.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# user interface module - parse and execute commands
|
2
2
|
# integrates all modules, central module
|
3
3
|
|
4
|
-
VERSION = "0.
|
4
|
+
VERSION = "0.1"
|
5
5
|
|
6
6
|
module Copernicium
|
7
7
|
# Communication object that will pass commands to backend modules
|
@@ -9,7 +9,7 @@ module Copernicium
|
|
9
9
|
# rev - revision indicator (commit #, branch name, HEAD, etc.)
|
10
10
|
# repo - URL/path to a remote repository
|
11
11
|
class UIComm
|
12
|
-
|
12
|
+
attr_accessor :command, :files, :rev, :cmt_msg, :repo, :opts
|
13
13
|
def initialize(command: nil, files: nil, rev: nil,
|
14
14
|
cmt_msg: nil, repo: nil, opts: nil)
|
15
15
|
@cmt_msg = cmt_msg
|
@@ -21,16 +21,11 @@ module Copernicium
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
# todo - consider refactoring some UIComm usage
|
24
25
|
# main driver for the command line user interface
|
25
26
|
module Driver
|
26
27
|
include Repos # needed to get branch and history info
|
27
28
|
include Workspace # needed for most high level commands
|
28
|
-
def setup
|
29
|
-
Repos.setup
|
30
|
-
RevLog.setup
|
31
|
-
Workspace.setup
|
32
|
-
end
|
33
|
-
|
34
29
|
# Executes the required action for a given user command.
|
35
30
|
#
|
36
31
|
# Parameters:
|
@@ -55,36 +50,42 @@ module Copernicium
|
|
55
50
|
# if no arguments given show help information
|
56
51
|
pexit COMMAND_BANNER, 0 if (cmd == '-h' || cmd == 'help')
|
57
52
|
|
58
|
-
#
|
59
|
-
|
60
|
-
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
53
|
+
# create the cn project, else already in one
|
54
|
+
if cmd == 'init'
|
55
|
+
noroot?? init(args) : puts(IN_REPO_WARNING.yel, getroot)
|
56
|
+
elsif noroot? # if not in a repo, warn them, tell how to create
|
57
|
+
puts NO_REPO_WARNING.yel
|
58
|
+
else # now, assume we are in a copernicum project
|
59
|
+
Workspace.setup
|
60
|
+
|
61
|
+
# Handle all other commands
|
62
|
+
case cmd
|
63
|
+
when 'status'
|
64
|
+
status args
|
65
|
+
when 'history'
|
66
|
+
history args
|
67
|
+
when 'branch'
|
68
|
+
branch args
|
69
|
+
when 'clean'
|
70
|
+
clean args
|
71
|
+
when 'clone'
|
72
|
+
clone args
|
73
|
+
when 'commit'
|
74
|
+
commit args
|
75
|
+
when 'checkout'
|
76
|
+
checkout args
|
77
|
+
when 'merge'
|
78
|
+
merge args
|
79
|
+
when 'push'
|
80
|
+
push args
|
81
|
+
when 'pull'
|
82
|
+
pull args
|
83
|
+
when 'init'
|
84
|
+
# fall through - init handled above, before case statement
|
85
|
+
else # handle an unrecognized argument, show help and exit
|
86
|
+
pexit "Unrecognized command #{cmd}\n" + COMMAND_BANNER, 1
|
87
|
+
end
|
88
|
+
end # case
|
88
89
|
end # run
|
89
90
|
|
90
91
|
# Print and exit with a specific code
|
@@ -95,114 +96,152 @@ module Copernicium
|
|
95
96
|
|
96
97
|
# Get some info from the user when they dont specify it
|
97
98
|
def get(info)
|
98
|
-
puts "Note: #{info} not specified. Enter #{info} to continue."
|
99
|
+
puts "Note: #{info} not specified. Enter #{info} to continue.".yel
|
99
100
|
gets.chomp # read a line from user, and return it
|
100
101
|
end
|
101
102
|
|
102
103
|
# create a new copernicium repository
|
103
104
|
def init(args)
|
104
105
|
if args.empty?
|
105
|
-
Workspace.create_project
|
106
|
+
root = Workspace.create_project
|
106
107
|
else # init into a folder
|
107
|
-
Workspace.create_project args.first
|
108
|
+
root = Workspace.create_project args.first
|
108
109
|
end
|
109
|
-
puts "Created Copernicium repo
|
110
|
+
puts "Created Copernicium repo: ".grn + root
|
110
111
|
UIComm.new(command: 'init', opts: args)
|
111
112
|
end
|
112
113
|
|
113
114
|
# show the current repos status
|
114
115
|
def status(args)
|
115
|
-
ui = UIComm.new(command: 'status', opts: args)
|
116
116
|
st = Workspace.status
|
117
|
-
st
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
117
|
+
if st.all?(&:empty?)
|
118
|
+
puts "No changes since last commit | ".grn +
|
119
|
+
(Repos.current_snaps.last.time + ' | ').yel +
|
120
|
+
Repos.current_snaps.last.msg
|
121
|
+
else
|
122
|
+
st[0].each { |f| puts "Added: ".grn + f }
|
123
|
+
st[1].each { |f| puts "Edited: ".yel + f }
|
124
|
+
st[2].each { |f| puts "Removed: ".red + f }
|
125
|
+
end
|
126
126
|
end
|
127
127
|
|
128
128
|
# create and switch to a new branch
|
129
129
|
def create_branch(branch)
|
130
130
|
new_branch_hash = Repos.make_branch branch
|
131
131
|
Repos.update_branch branch
|
132
|
-
puts "Created
|
132
|
+
puts "Created branch #{branch} ".grn + " with head #{new_branch_hash}"
|
133
133
|
end
|
134
134
|
|
135
135
|
def branch(args)
|
136
|
-
branch = args.
|
136
|
+
branch = args.shift
|
137
137
|
if branch.nil? # show all branches
|
138
|
+
puts "Current: ".grn + Repos.current
|
138
139
|
puts "Branches: ".grn + Repos.branches.join(' ')
|
140
|
+
|
139
141
|
elsif branch == '-c' # try to create a new branch
|
140
|
-
|
141
|
-
branch = args[1]
|
142
|
+
branch = args.first # get from the user
|
142
143
|
branch = get "new branch name" if branch.nil?
|
143
|
-
|
144
|
-
# Create and switch to the new branch
|
145
144
|
create_branch branch
|
145
|
+
|
146
146
|
elsif branch == '-r' # rename the current branch
|
147
|
-
|
148
|
-
newname = args[1]
|
147
|
+
newname = args.first # get if not specified
|
149
148
|
newname = get "new name for current branch" if newname.nil?
|
150
|
-
|
151
|
-
oldname = Repos.branch
|
152
|
-
|
153
|
-
# Create and switch to a new branch with the given name
|
149
|
+
oldname = Repos.current
|
154
150
|
create_branch newname
|
155
|
-
|
156
|
-
# Delete the branch with the old name
|
157
151
|
Repos.delete_branch oldname
|
158
152
|
puts "Deleted branch '#{oldname}'".grn
|
159
153
|
puts "Renamed branch '#{oldname}' to '#{newname}'".grn
|
154
|
+
|
160
155
|
elsif branch == '-d' # Delete the specified branch
|
161
|
-
# If
|
162
|
-
branch = args[1]
|
156
|
+
branch = args.first # If not specified, get
|
163
157
|
branch = get "branch to delete" if branch.nil?
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
158
|
+
if branch == Repos.current
|
159
|
+
puts "Cannot delete the current branch!".red
|
160
|
+
else # Delete the specified branch
|
161
|
+
Repos.delete_branch branch
|
162
|
+
puts "Deleted branch '#{branch}'".grn
|
168
163
|
end
|
169
164
|
|
170
|
-
|
171
|
-
Repos.
|
172
|
-
puts "
|
173
|
-
|
174
|
-
|
175
|
-
else # branch does not exist, create it, switch to it
|
165
|
+
elsif Repos.has_branch? branch # switch branch (branch <branch name>)
|
166
|
+
Repos.update_branch branch
|
167
|
+
puts "Current: ".grn + Repos.current
|
168
|
+
|
169
|
+
else # create it, switch to it
|
176
170
|
Repos.create_branch branch
|
177
171
|
end
|
178
172
|
end
|
179
173
|
|
180
174
|
def push(args)
|
181
|
-
|
182
|
-
#
|
175
|
+
# Command usage is:
|
176
|
+
# cn push <user> <repo.host:/dir/of/repo> <branch-name>
|
177
|
+
#
|
178
|
+
# If username not given, get it from the user.
|
179
|
+
user = args[0]
|
180
|
+
if user.nil?
|
181
|
+
user = get "username for push"
|
182
|
+
# Make sure username is the first arg, since PushPull is expecting this.
|
183
|
+
args << user
|
184
|
+
end
|
185
|
+
|
186
|
+
remote = args[1]
|
187
|
+
remote = get "remote path to push to (format: <repo.host:/dir/of/repo>)" if remote.nil?
|
188
|
+
|
189
|
+
branchname = args[2]
|
190
|
+
branchname = get "remote branch to push to" if branchname.nil?
|
191
|
+
|
192
|
+
comm = UIComm.new(command: 'push', opts: args, repo: remote, rev: branchname)
|
193
|
+
# Do the push
|
194
|
+
PushPull.UICommandParser(comm)
|
195
|
+
|
196
|
+
comm
|
183
197
|
end
|
184
198
|
|
185
199
|
def pull(args)
|
186
|
-
|
187
|
-
#
|
188
|
-
#
|
200
|
+
# Command usage is:
|
201
|
+
# cn pull <user> <repo.host:/dir/of/repo> <branch-name>
|
202
|
+
#
|
203
|
+
# If username not given, get it from the user.
|
204
|
+
user = args[0]
|
205
|
+
if user.nil?
|
206
|
+
user = get "username for pull"
|
207
|
+
# Make sure username is the first arg, since PushPull is expecting this.
|
208
|
+
args << user
|
209
|
+
end
|
210
|
+
|
211
|
+
remote = args[1]
|
212
|
+
remote = get "remote path to pull from (format: <repo.host:/dir/of/repo>)" if remote.nil?
|
213
|
+
|
214
|
+
branchname = args[2]
|
215
|
+
branchname = get "remote branch to pull from" if branchname.nil?
|
216
|
+
|
217
|
+
comm = UIComm.new(command: 'pull', opts: args, repo: remote, rev: branchname)
|
218
|
+
# Do the pull
|
219
|
+
PushPull.UICommandParser(comm)
|
220
|
+
|
221
|
+
comm
|
189
222
|
end
|
190
223
|
|
224
|
+
# Take in a revision (snaptshot) id or branch
|
225
|
+
# Doesnt support file checkouts at this time
|
191
226
|
def checkout(args)
|
192
227
|
if args.empty?
|
193
|
-
rev = get 'branch or
|
228
|
+
rev = get 'branch or commit id'
|
194
229
|
else
|
195
230
|
rev = args.shift
|
196
231
|
files = args
|
197
232
|
end
|
198
233
|
|
199
|
-
# if
|
200
|
-
|
234
|
+
# if 'head' keyword, grab the head
|
235
|
+
if rev == 'head'
|
236
|
+
rev = Repos.current_head
|
237
|
+
elsif Repos.has_branch? rev
|
238
|
+
branch = rev
|
239
|
+
rev = Repos.history(rev).last
|
240
|
+
end
|
201
241
|
|
202
242
|
# call workspace checkout the given / branch
|
203
|
-
|
204
|
-
|
205
|
-
ui
|
243
|
+
Workspace.checkout(UIComm.new(rev: rev, files: files))
|
244
|
+
Repos.update_branch branch unless branch.nil?
|
206
245
|
end
|
207
246
|
|
208
247
|
def clean(args = [])
|
@@ -212,15 +251,23 @@ module Copernicium
|
|
212
251
|
end
|
213
252
|
|
214
253
|
def clone(args)
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
254
|
+
# Command usage is:
|
255
|
+
# cn clone <user> <repo.host:/dir/of/repo>
|
256
|
+
user = args.first
|
257
|
+
if user.nil?
|
258
|
+
user = get "username for clone"
|
259
|
+
# Make sure username is first arg, since PushPull is expecting this.
|
260
|
+
args << user
|
219
261
|
end
|
220
262
|
|
221
|
-
|
263
|
+
repo = args[1]
|
264
|
+
repo = get "repo url to clone (format: <repo.host:/dir/of/repo>)" if repo.nil?
|
265
|
+
|
266
|
+
comm = UIComm.new(command: 'clone', opts: args, repo: repo)
|
267
|
+
# Do the clone
|
268
|
+
PushPull.UICommandParser(comm)
|
222
269
|
|
223
|
-
|
270
|
+
comm
|
224
271
|
end
|
225
272
|
|
226
273
|
def commit(args)
|
@@ -239,27 +286,40 @@ module Copernicium
|
|
239
286
|
|
240
287
|
# perform the commit, with workspace
|
241
288
|
ui = UIComm.new(command: 'commit', files: files, cmt_msg: message)
|
242
|
-
Workspace.commit(ui)
|
289
|
+
puts "New commit: ".grn + Workspace.commit(ui)
|
243
290
|
ui
|
244
291
|
end
|
245
292
|
|
246
293
|
def history(args)
|
247
|
-
|
294
|
+
Repos.current_snaps.reverse_each do |snap|
|
295
|
+
puts (snap.time + ' | ') .grn + (snap.id + ' | ').yel + snap.msg
|
296
|
+
end
|
248
297
|
end
|
249
298
|
|
250
299
|
def merge(args)
|
251
300
|
if args.empty?
|
252
|
-
puts 'I need a commit or branch to merge.'
|
253
301
|
rev = get 'single commit or branch to merge'
|
254
|
-
else
|
302
|
+
else
|
255
303
|
rev = args.first
|
256
|
-
# get all branchs, see if arg is in it.
|
257
|
-
# if so, look up snapshot of <branch> head
|
258
|
-
# TODO - parse whether given arg is a branch name, else assume snap id
|
259
|
-
# todo - call repos merge command
|
260
|
-
# todo show conflicting files
|
261
|
-
UIComm.new(command: 'merge', rev: rev)
|
262
304
|
end
|
305
|
+
|
306
|
+
# If rev is a branch name, resolve it to a rev ID.
|
307
|
+
if Repos.has_branch? rev
|
308
|
+
rev = (Repos.history rev).last
|
309
|
+
end
|
310
|
+
|
311
|
+
conflicts = Workspace.merge(rev)
|
312
|
+
|
313
|
+
# If there were any conflicts, display them to the user.
|
314
|
+
if not conflicts.nil?
|
315
|
+
|
316
|
+
conflicts.each do |conflict|
|
317
|
+
puts " #{conflict}".red
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
# Don't return a UIComm object, since we didn't use one for any of the
|
322
|
+
# backend calls.
|
263
323
|
end
|
264
324
|
end # Driver
|
265
325
|
end
|
data/lib/workspace.rb
CHANGED
@@ -18,49 +18,58 @@ module Copernicium
|
|
18
18
|
end
|
19
19
|
|
20
20
|
# returns most recent file id in the snapshot it was saved in
|
21
|
-
def last
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
# helper methods for file IO
|
27
|
-
def writeFile(path, content)
|
28
|
-
f = open(path, 'w')
|
29
|
-
f.write(content)
|
30
|
-
f.close
|
31
|
-
end
|
32
|
-
|
33
|
-
# helper methods for file IO
|
34
|
-
def readFile(path)
|
35
|
-
f = open(path, 'r')
|
36
|
-
txt = f.read
|
37
|
-
f.close
|
38
|
-
txt
|
39
|
-
end
|
21
|
+
def last() @history.last end
|
22
|
+
end # FileObj
|
23
|
+
|
40
24
|
|
25
|
+
# todo - @@files really should be a Hash, with paths as keys, then rather than
|
26
|
+
# using indices.
|
41
27
|
module Workspace
|
42
28
|
include Repos # needed for keeping track of history
|
43
|
-
def Workspace.setup
|
44
|
-
@@files = []
|
29
|
+
def Workspace.setup
|
45
30
|
@@cwd = Dir.pwd
|
46
31
|
@@root = (noroot?? @@cwd : getroot)
|
32
|
+
@@root.sub!(@@cwd, '.')
|
47
33
|
@@copn = File.join(@@root, '.cn')
|
48
|
-
|
49
|
-
@@
|
50
|
-
@@branch = bname
|
34
|
+
@@snap = File.join(@@copn, 'snap')
|
35
|
+
@@revs = File.join(@@copn, 'revs')
|
51
36
|
RevLog.setup @@root
|
52
37
|
Repos.setup @@root
|
38
|
+
@@files = Repos.current_files
|
39
|
+
@@branch = Repos.current
|
53
40
|
end
|
54
41
|
|
55
42
|
# create a new copernicium project
|
56
|
-
def Workspace.create_project(location = Dir.pwd)
|
57
|
-
Dir.mkdir location
|
43
|
+
def Workspace.create_project(location = Dir.pwd, branch = 'master')
|
44
|
+
Dir.mkdir location unless Dir.exist? location
|
58
45
|
Dir.chdir location
|
59
|
-
|
60
|
-
|
46
|
+
|
47
|
+
# create our copernicium folders
|
48
|
+
@@copn = File.join('.', '.cn')
|
49
|
+
@@snap = File.join(@@copn, 'snap')
|
50
|
+
@@revs = File.join(@@copn, 'revs')
|
51
|
+
@@head = File.join(@@copn, 'branch')
|
52
|
+
@@hist = File.join(@@copn, 'history')
|
53
|
+
Dir.mkdir(@@copn) unless Dir.exist?(@@copn)
|
54
|
+
Dir.mkdir(@@snap) unless Dir.exist?(@@snap)
|
55
|
+
Dir.mkdir(@@revs) unless Dir.exist?(@@revs)
|
56
|
+
|
57
|
+
# make default branch, history
|
58
|
+
hist = YAML.dump({branch => []})
|
59
|
+
File.write @@head, branch
|
60
|
+
File.write @@hist, hist
|
61
|
+
|
62
|
+
if Dir.exist?(@@copn)
|
63
|
+
location # return where we made the repo
|
64
|
+
else # something has gone horribly wrong
|
65
|
+
raise 'Could not create or find a Copernicium folder (.cn).'.red
|
66
|
+
end
|
61
67
|
end
|
62
68
|
|
63
|
-
|
69
|
+
|
70
|
+
# PROJECT HELPERS
|
71
|
+
#
|
72
|
+
# find the root .cn folder, or return nil if it doesnt exist
|
64
73
|
def getroot
|
65
74
|
cwd = Dir.pwd
|
66
75
|
max = 0
|
@@ -82,174 +91,136 @@ module Copernicium
|
|
82
91
|
end
|
83
92
|
|
84
93
|
# tells us whether we are in a cn project or not
|
85
|
-
def noroot?
|
86
|
-
getroot.nil?
|
87
|
-
end
|
94
|
+
def noroot?() getroot.nil? end
|
88
95
|
|
89
|
-
|
96
|
+
|
97
|
+
# WORKSPACE MANAGEMENT
|
98
|
+
#
|
90
99
|
def Workspace.indexOf(x)
|
91
|
-
|
92
|
-
|
93
|
-
if e.path == x
|
94
|
-
index = i
|
95
|
-
break
|
96
|
-
end
|
100
|
+
@@files.each_with_index do |f, i|
|
101
|
+
return i if f.path == x
|
97
102
|
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
# if include all the elements in list_files
|
102
|
-
def Workspace.include?(files)
|
103
|
-
files.each { |x| return false if indexOf(x) == -1 }
|
104
|
-
true
|
103
|
+
nil # x is not included in @@files
|
105
104
|
end
|
106
105
|
|
107
|
-
# get
|
108
|
-
|
109
|
-
|
110
|
-
|
106
|
+
# get array of filenamess currently in workspace, except folders and .cn/*
|
107
|
+
# todo - include files and files that start with a dot (.)
|
108
|
+
def Workspace.working_files
|
109
|
+
(Dir[ File.join(@@root, '**', '*') ].reject do |p|
|
110
|
+
File.directory? p || p.include?(@@copn)
|
111
|
+
end).map do |p|
|
112
|
+
p.sub!(/^\.\//, '') # delete leading './'
|
111
113
|
end
|
112
114
|
end
|
113
115
|
|
114
|
-
# Clear the
|
116
|
+
# Clear the workspace
|
115
117
|
def Workspace.clear
|
116
118
|
@@files.each{ |x| File.delete(x.path) }
|
117
119
|
@@files = []
|
118
120
|
end
|
119
121
|
|
120
|
-
#
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
if comm.files.empty? # reset, checkout last commit
|
127
|
-
Workspace.clear
|
128
|
-
Workspace.checkout
|
129
|
-
else # files are not nil
|
122
|
+
# take in file object, restore
|
123
|
+
def Workspace.checkout_file(file)
|
124
|
+
idx = indexOf(file.path)
|
125
|
+
idx.nil?? @@files << file : @@files[idx] = file
|
126
|
+
File.write(file.path, RevLog.get_file(file.last))
|
127
|
+
end
|
130
128
|
|
131
|
-
|
132
|
-
|
129
|
+
# takes in a snapshot id, sets workspace to that snapshot
|
130
|
+
def Workspace.checkout(comm = UIComm.new)
|
131
|
+
comm.rev = Repos.current_head if comm.rev.nil?
|
132
|
+
if ! Repos.has_snapshots? # dont checkout
|
133
|
+
puts 'No snapshots yet! Commit something before checkout.'.red
|
134
|
+
elsif comm.files.nil? # checkout everything
|
135
|
+
Repos.get_snapshot(comm.rev).files.each do |file|
|
136
|
+
Workspace.checkout_file file
|
137
|
+
end
|
138
|
+
else # just checkout given files
|
139
|
+
Repos.get_snapshot(comm.rev).files.select { |f|
|
140
|
+
comm.files.include? f.path }.each do |file|
|
141
|
+
Workspace.checkout_file file
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
133
145
|
|
134
|
-
|
146
|
+
# reset repo back to a given state
|
147
|
+
def Workspace.clean(comm = UIComm.new)
|
148
|
+
if comm.files.nil? # reset everything
|
149
|
+
Workspace.clear
|
150
|
+
else # files are not nil
|
135
151
|
comm.files.each do |x|
|
136
|
-
File.delete(x)
|
137
152
|
idx = indexOf(x)
|
138
|
-
|
153
|
+
if idx.nil?
|
154
|
+
puts "Cannot clean #{x}:".yel + " does not exist in snapshot"
|
155
|
+
else
|
156
|
+
@@files.delete_at(idx)
|
157
|
+
File.delete(x)
|
158
|
+
end
|
139
159
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
160
|
+
end
|
161
|
+
Workspace.checkout comm # cleanse state
|
162
|
+
end
|
163
|
+
|
164
|
+
def Workspace.commit_file(x)
|
165
|
+
puts 'Committing: '.grn + x
|
166
|
+
added, edits, remov = Workspace.status
|
167
|
+
if added.include? x
|
168
|
+
hash = RevLog.add_file(x, File.read(x))
|
169
|
+
@@files.push(FileObj.new x, [hash])
|
170
|
+
elsif edits.include? x
|
171
|
+
hash = RevLog.add_file(x, File.read(x))
|
172
|
+
@@files[indexOf x].history << hash
|
173
|
+
elsif remov.include? x
|
174
|
+
@@files.delete_at(indexOf x)
|
175
|
+
else
|
176
|
+
puts 'Failed, no changes: '.yel + x
|
144
177
|
end
|
145
178
|
end
|
146
179
|
|
147
180
|
# commit a list of files or the entire workspace to make a new snapshot
|
148
|
-
def Workspace.commit(comm)
|
181
|
+
def Workspace.commit(comm = UIComm.new)
|
149
182
|
if comm.files.nil? # commit everything
|
150
|
-
Workspace.
|
151
|
-
|
152
|
-
content = readFile(x)
|
153
|
-
hash = RevLog.add_file(x, content)
|
154
|
-
fobj = FileObj.new(x, [hash,])
|
155
|
-
@@files.push(fobj)
|
156
|
-
else # file exists
|
157
|
-
content = readFile(x)
|
158
|
-
hash = RevLog.add_file(x, content)
|
159
|
-
if @@files[indexOf(x)].history[-1] != hash
|
160
|
-
@@files[indexOf(x)].history << hash
|
161
|
-
end
|
162
|
-
end
|
183
|
+
Workspace.status.each do |st|
|
184
|
+
st.each { |x| Workspace.commit_file x }
|
163
185
|
end
|
164
|
-
else
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
def Workspace.checkout(comm)
|
170
|
-
=begin
|
171
|
-
# just support revisions for now
|
172
|
-
# if argu is an Array Object, we assume it is a list of files to be added
|
173
|
-
# # to the workspace # we add the list of files to @@files regardless
|
174
|
-
# whether it has been in # it. that means there may be multiple versions
|
175
|
-
# of a file.
|
176
|
-
unless comm.files.nil?
|
177
|
-
list_files = comm.files
|
178
|
-
returned_snapshot = Repos.get_snapshot(Repos.history.last)
|
179
|
-
list_files_last_commit = returned_snapshot.files
|
180
|
-
list_files_last_commit.each do |x|
|
181
|
-
if list_files.include? x.path
|
182
|
-
content = RevLog.get_file(x.history.last)
|
183
|
-
idx = indexOf(x.path)
|
184
|
-
if idx == -1
|
185
|
-
@@files << x
|
186
|
-
else
|
187
|
-
@@files[idx] = x
|
188
|
-
end
|
189
|
-
writeFile(x.path, content)
|
186
|
+
else comm.files.each do |x|
|
187
|
+
if File.exist? x
|
188
|
+
Workspace.commit_file(x)
|
189
|
+
else
|
190
|
+
puts "Cannot commit #{x}:".yel + " file does not exist"
|
190
191
|
end
|
191
192
|
end
|
192
|
-
else # if argu is not an Array, we assume it is a String, representing the
|
193
|
-
end
|
194
|
-
=end
|
195
|
-
|
196
|
-
clear # reset workspace
|
197
|
-
|
198
|
-
# Dec. 3th, 2015 by Linfeng,
|
199
|
-
# for this command, the comm.rev should be a string representing the branch name
|
200
|
-
@@branch = comm.rev
|
201
|
-
Repos.update_branch(@@branch)
|
202
|
-
|
203
|
-
# if not snapshots exist, dont checkout
|
204
|
-
return -1 unless Repos.has_snapshots?
|
205
|
-
|
206
|
-
# if no snapshot files, dont checkout
|
207
|
-
snap = Repos.get_snapshot(comm.rev)
|
208
|
-
return -1 if snap.files.nil?
|
209
|
-
|
210
|
-
# object and finally push all files of it to the # workspace
|
211
|
-
snap.files.each do |file|
|
212
|
-
idx = indexOf(file.path)
|
213
|
-
puts file
|
214
|
-
if idx == -1
|
215
|
-
@@files << file
|
216
|
-
else
|
217
|
-
@@files[idx] = file
|
218
|
-
end
|
219
|
-
content = RevLog.get_file(file.history.last)
|
220
|
-
writeFile(file.path, content)
|
221
193
|
end
|
194
|
+
# todo - handle case of no changes, dont make a snapshot
|
195
|
+
Repos.make_snapshot(@@files, comm.cmt_msg) # return snapshot id
|
222
196
|
end
|
223
197
|
|
224
198
|
# wrapper for Repos merge_snapshot, update workspace with result
|
199
|
+
# returns [{path => content}, [conflicting paths]]
|
200
|
+
# todo update workspace with result
|
201
|
+
# todo return any conflicting files
|
225
202
|
def Workspace.merge(id)
|
226
|
-
# returns [{path => content}, [conflicting paths]]
|
227
203
|
Repos.merge_snapshot(id)
|
228
|
-
|
229
|
-
# todo update workspace with result
|
230
|
-
# todo return any conflicting files
|
231
204
|
end
|
232
205
|
|
233
206
|
def Workspace.status
|
234
207
|
added = []
|
235
208
|
edits = []
|
236
209
|
remov = []
|
237
|
-
|
210
|
+
working_files.each do |f|
|
238
211
|
idx = indexOf(f)
|
239
|
-
if idx
|
212
|
+
if idx.nil? # new file
|
240
213
|
added << f
|
241
|
-
else # changed file
|
242
|
-
|
243
|
-
x1 = RevLog.get_file(@@files[idx].history.last)
|
244
|
-
edits << f if x1 != x2
|
214
|
+
else # changed file
|
215
|
+
edits << f if File.read(f) != RevLog.get_file(@@files[idx].last)
|
245
216
|
end
|
246
217
|
end
|
247
218
|
|
248
219
|
# any deleted files from the last commit?
|
249
|
-
|
220
|
+
remov = @@files.map(&:path) - working_files
|
250
221
|
|
251
222
|
[added, edits, remov]
|
252
223
|
end
|
253
|
-
end
|
254
|
-
end
|
224
|
+
end # Workspace
|
225
|
+
end # Copernicium
|
255
226
|
|