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
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
|
|