cpee-model-management 1.0.12 → 1.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f01249cf02b86d83022b913a2b81ebcfd06e48f19eb307bcf8645c619260da7
4
- data.tar.gz: '08805c52f1143242b9e2f675886ab894d33fe28f5a05cc4408e0563eac592937'
3
+ metadata.gz: d3a70760a747bb5dd295cac87766307d1d3775767af440e3090d2e108757837d
4
+ data.tar.gz: ed59f63e220bb3c6fb8e096ce21ee41f5542c59fff051e48c0d04ff7ee8ccd79
5
5
  SHA512:
6
- metadata.gz: 4ea1643623a79c0ad75814965d0ed339591767f7c7d423c4d5f0a15dd88eb4f2626c0246b3f4e72a24989aff9dc8eb6cca2f5f72bea0751f6f0831ee437e5db7
7
- data.tar.gz: a36b6d9995c293f6ed8c2eca53ed0231c74cf1a44b07a3e53bd50e6c958349612fd71ce586e1cba65989a334148e35ae7752ca0eaddcd615bfc812ddf9d8084f
6
+ metadata.gz: fd9497631d3a6d95a98b0f829211aa13712626bf1aac340a4bdb19eb80ee1b26e624bfa3e5766d1f8cceeb37d215f75b8c05478566802daf667a297eb4c4b075
7
+ data.tar.gz: 04c947de228d452fa277b01213c0a4a5deaa8d47bd3b357a94593c350c1ae15a728c470a38023a4298d9a2db808580bfe187cb1fe19dcf9bd4b634819a25a0a2
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cpee-model-management"
3
- s.version = "1.0.12"
3
+ s.version = "1.0.17"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.license = "LGPL-3.0"
6
6
  s.summary = "(Lifecycle) manage your process models in a directory or git repo."
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_runtime_dependency 'riddl', '~> 0.99'
24
24
  s.add_runtime_dependency 'json', '~> 2.1'
25
+ s.add_runtime_dependency 'cpee', '~> 2.1', '>= 2.1.7'
25
26
  end
@@ -7,8 +7,6 @@ new = File.basename(new)
7
7
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}" 2>/dev/null`
8
8
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.active" 2>/dev/null`
9
9
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.active-uuid" 2>/dev/null`
10
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.author" 2>/dev/null`
11
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.creator" 2>/dev/null`
12
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.stage" 2>/dev/null`
10
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple add "#{new}.attrs" 2>/dev/null`
13
11
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple commit -m "#{author.gsub(/"/,"'")}"`
14
12
  `GIT_TERMINAL_PROMPT=0 git push` rescue nil
@@ -24,6 +24,7 @@ require 'riddl/protocols/utils'
24
24
  require 'fileutils'
25
25
  require 'pathname'
26
26
  require 'shellwords'
27
+ require 'securerandom'
27
28
 
28
29
  module CPEE
29
30
  module ModelManagement
@@ -37,12 +38,10 @@ module CPEE
37
38
  p2 = Pathname.new(File.dirname(new))
38
39
  told = File.basename(old)
39
40
  tnew = File.join(p1.relative_path_from(p1).to_s,File.basename(new))
40
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told}" "#{tnew}" 2>/dev/null`
41
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active'}" 2>/dev/null`
42
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active-uuid'}" 2>/dev/null`
43
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.author'}" "#{tnew + '.author'}" 2>/dev/null`
44
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.creator'}" "#{tnew + '.creator'}" 2>/dev/null`
45
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.stage'}" "#{tnew + '.stage'}" 2>/dev/null`
41
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told}" "#{tnew}" 2>/dev/null`
42
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active'}" 2>/dev/null`
43
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{told + '.active-uuid'}" 2>/dev/null`
44
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple mv "#{told + '.attrs'}" "#{tnew + '.attrs'}" 2>/dev/null`
46
45
  Dir.chdir(cdir)
47
46
  CPEE::ModelManagement::fs_mv(models,old,new) # fallback
48
47
  end
@@ -54,9 +53,7 @@ module CPEE
54
53
  FileUtils.rm_rf(tnew)
55
54
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.active" 2>/dev/null`
56
55
  `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.active-uuid" 2>/dev/null`
57
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.author" 2>/dev/null`
58
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.creator" 2>/dev/null`
59
- `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.stage" 2>/dev/null`
56
+ `git -c user.name='Christine Ashcreek' -c user.email=dev@null.com -c push.default=simple rm -rf "#{tnew}.attrs" 2>/dev/null`
60
57
  Dir.chdir(cdir)
61
58
  CPEE::ModelManagement::fs_rm(models,new) # fallback
62
59
  end
@@ -80,9 +77,7 @@ module CPEE
80
77
  FileUtils.mv(fname,fnname) rescue nil
81
78
  File.delete(fname + '.active',fnname + '.active') rescue nil
82
79
  File.delete(fname + '.active-uuid',fnname + '.active-uuid') rescue nil
83
- FileUtils.mv(fname + '.author',fnname + '.author') rescue nil
84
- FileUtils.mv(fname + '.creator',fnname + '.creator') rescue nil
85
- FileUtils.mv(fname + '.stage',fnname + '.stage') rescue nil
80
+ FileUtils.mv(fname + '.attrs',fnname + '.attrs') rescue nil
86
81
  end
87
82
  def self::fs_cp(models,old,new)
88
83
  fname = File.join(models,old)
@@ -90,18 +85,14 @@ module CPEE
90
85
  FileUtils.cp(fname,fnname)
91
86
  File.delete(fname + '.active',fnname + '.active') rescue nil
92
87
  File.delete(fname + '.active-uuid',fnname + '.active-uuid') rescue nil
93
- FileUtils.cp(fname + '.author',fnname + '.author') rescue nil
94
- FileUtils.cp(fname + '.creator',fnname + '.creator') rescue nil
95
- FileUtils.cp(fname + '.stage',fnname + '.stage') rescue nil
88
+ FileUtils.cp(fname + '.attrs',fnname + '.attrs') rescue nil
96
89
  end
97
90
  def self::fs_rm(models,new)
98
91
  fname = File.join(models,new)
99
92
  FileUtils.rm_rf(fname)
100
93
  File.delete(fname + '.active') rescue nil
101
94
  File.delete(fname + '.active-uuid') rescue nil
102
- File.delete(fname + '.author') rescue nil
103
- File.delete(fname + '.creator') rescue nil
104
- File.delete(fname + '.stage') rescue nil
95
+ File.delete(fname + '.attrs') rescue nil
105
96
  end
106
97
  def self::fs_shift(models,new)
107
98
  fname = File.join(models,new)
@@ -168,14 +159,16 @@ module CPEE
168
159
  if op == 'delete'
169
160
  { :op => op, :type => :dir, :name => File.basename(f) }
170
161
  else
171
- { :op => op, :type => :dir, :name => File.basename(f), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
162
+ attrs = JSON::load File.open(f + '.attrs')
163
+ { :op => op, :type => :dir, :name => File.basename(f), :creator => attrs['creator'], :date => File.mtime(f).xmlschema }
172
164
  end
173
165
  else
174
166
  if op == 'delete'
175
167
  { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),'') }
176
168
  else
177
- fstage = File.read(f + '.stage').strip rescue 'draft'
178
- { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),''), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema }
169
+ attrs = JSON::load File.open(f + '.attrs')
170
+ fstage = attrs['design_stage'] rescue 'draft'
171
+ { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),''), :creator => attrs['creator'], :author => attrs['author'], :stage => fstage, :date => File.mtime(f).xmlschema }
179
172
  end
180
173
  end
181
174
  what[:source] = s.sub(/models\//,'') unless s.nil?
@@ -192,12 +185,13 @@ module CPEE
192
185
  stage = [@p[0]&.value] || ['draft']
193
186
  stage << views[stage[0]] if views && views[stage[0]]
194
187
 
195
-
196
188
  names = Dir.glob(File.join(models,where,'*.dir')).map do |f|
197
- { :type => :dir, :name => File.basename(f), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
189
+ attrs = JSON::load File.open(f + '.attrs')
190
+ { :type => :dir, :name => File.basename(f), :creator => attrs['creator'], :date => File.mtime(f).xmlschema }
198
191
  end.compact.uniq.sort_by{ |e| e[:name] } + Dir.glob(File.join(models,where,'*.xml')).map do |f|
199
- fstage = File.read(f + '.stage').strip rescue 'draft'
200
- { :type => :file, :name => File.basename(f), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
192
+ attrs = JSON::load File.open(f + '.attrs')
193
+ fstage = attrs['design_stage'] rescue 'draft'
194
+ { :type => :file, :name => File.basename(f), :creator => attrs['creator'], :author => attrs['author'], :guarded => attrs['guarded'], :guarded_id => attrs['guarded_id'], :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
201
195
  end.compact.uniq.sort_by{ |e| e[:name] }
202
196
 
203
197
  Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(names))
@@ -211,10 +205,12 @@ module CPEE
211
205
  stage << views[stage[0]] if views && views[stage[0]]
212
206
 
213
207
  names = Dir.glob(File.join(models,'*.dir/*.xml')).map do |f|
214
- { :type => :file, :name => File.join(File.basename(File.dirname(f)),File.basename(f)), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
208
+ attrs = JSON::load File.open(f + '.attrs')
209
+ { :type => :file, :name => File.join(File.basename(File.dirname(f)),File.basename(f)), :creator => attrs['creator'], :date => File.mtime(f).xmlschema }
215
210
  end.compact.uniq.sort_by{ |e| e[:name] } + Dir.glob(File.join(models,'*.xml')).map do |f|
216
- fstage = File.read(f + '.stage').strip rescue 'draft'
217
- { :type => :file, :name => File.basename(f), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
211
+ attrs = JSON::load File.open(f + '.attrs')
212
+ fstage = attrs['design_stage'] rescue 'draft'
213
+ { :type => :file, :name => File.basename(f), :creator => attrs['creator'], :author => attrs['author'], :guarded => attrs['guarded'], :guarded_id => attrs['guarded_id'], :stage => fstage, :date => File.mtime(f).xmlschema } if stage.include?(fstage)
218
214
  end.compact.uniq.sort_by{ |e| e[:name] }
219
215
 
220
216
  Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(names))
@@ -240,6 +236,7 @@ module CPEE
240
236
  dn = CPEE::ModelManagement::get_dn @h['DN']
241
237
  author = dn['GN'] + ' ' + dn['SN']
242
238
 
239
+ attrs = {}
243
240
  XML::Smart::modify(fname) do |doc|
244
241
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
245
242
  doc.find('/p:testset/p:attributes/p:author').each do |ele|
@@ -251,9 +248,11 @@ module CPEE
251
248
  doc.find('/p:testset/p:attributes/p:theme').each do |ele|
252
249
  ele.text = themes[nstage] || 'model'
253
250
  end
251
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
252
+ [e.qname.name,e.text]
253
+ end.to_h
254
254
  end
255
- File.write(fname + '.author',author)
256
- File.write(fname + '.stage',nstage)
255
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
257
256
 
258
257
  CPEE::ModelManagement::op author, 'shift', models, File.join('.', where, name + '.xml'), File.join('.', where, name + '.xml')
259
258
  CPEE::ModelManagement::notify conns, 'shift', models, fname, fname
@@ -280,6 +279,7 @@ module CPEE
280
279
  dn = CPEE::ModelManagement::get_dn @h['DN']
281
280
  author = dn['GN'] + ' ' + dn['SN']
282
281
 
282
+ attrs = {}
283
283
  XML::Smart::modify(fname) do |doc|
284
284
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
285
285
  doc.find('/p:testset/p:attributes/p:info').each do |ele|
@@ -288,8 +288,11 @@ module CPEE
288
288
  doc.find('/p:testset/p:attributes/p:author').each do |ele|
289
289
  ele.text = author
290
290
  end
291
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
292
+ [e.qname.name,e.text]
293
+ end.to_h
291
294
  end
292
- File.write(fname + '.author',author)
295
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
293
296
 
294
297
  CPEE::ModelManagement::op author, 'mv', models, File.join('.', where, nname + '.xml'), File.join('.', where, name + '.xml')
295
298
  CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
@@ -312,7 +315,23 @@ module CPEE
312
315
 
313
316
  dn = CPEE::ModelManagement::get_dn @h['DN']
314
317
  author = dn['GN'] + ' ' + dn['SN']
315
- File.write(fname + '.author',author)
318
+
319
+ attrs = JSON::load File.open(fname + '.attrs')
320
+ attrs['author'] = author
321
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
322
+
323
+ Dir.glob(File.join(fname + '/*.xml')).each do |f|
324
+ XML::Smart::modify(f) do |doc|
325
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
326
+ doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
327
+ ele.text = nname + '.dir'
328
+ end
329
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
330
+ [e.qname.name,e.text]
331
+ end.to_h
332
+ end
333
+ File.write(f + '.attrs',JSON::pretty_generate(attrs))
334
+ end
316
335
 
317
336
  CPEE::ModelManagement::op author, 'mv', models, File.join(nname + '.dir'), File.join(name + '.dir')
318
337
  CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
@@ -338,8 +357,11 @@ module CPEE
338
357
 
339
358
  Dir.mkdir(fname)
340
359
  FileUtils.touch(File.join(fname,'.gitignore'))
341
- File.write(fname + '.creator',creator)
342
- File.write(fname + '.author',creator)
360
+
361
+ attrs = JSON::load File.open(fname + '.attrs')
362
+ attrs['creator'] = creator
363
+ attrs['author'] = creator
364
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
343
365
 
344
366
  CPEE::ModelManagement::op creator, 'add', models, name + '.dir'
345
367
  CPEE::ModelManagement::notify conns, 'create', models, fname
@@ -363,7 +385,8 @@ module CPEE
363
385
  source = @p[1] ? File.join(models,where,@p[1].value) : (templates[stage] ? templates[stage] : 'testset.xml')
364
386
  fname = File.join(models,where,name + '.xml')
365
387
 
366
- stage = File.read(source + '.stage') if stage.nil? && File.exists?(source + '.stage')
388
+ attrs = JSON::load File.open(fname + '.attrs') rescue {}
389
+ stage = attrs['design_stage'] if stage.nil? && attrs['design_stage']
367
390
  stage = views[stage] if views && views[stage]
368
391
 
369
392
  counter = 0
@@ -375,6 +398,7 @@ module CPEE
375
398
  dn = CPEE::ModelManagement::get_dn @h['DN']
376
399
  creator = dn['GN'] + ' ' + dn['SN']
377
400
  FileUtils.cp(source,fname)
401
+ attrs = {}
378
402
  XML::Smart::modify(fname) do |doc|
379
403
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
380
404
  doc.find('/p:testset/p:attributes/p:info').each do |ele|
@@ -389,15 +413,19 @@ module CPEE
389
413
  doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
390
414
  ele.text = where
391
415
  end
416
+ doc.find('/p:testset/p:attributes/p:model_uuid').each do |ele|
417
+ ele.text = SecureRandom.uuid
418
+ end
392
419
  if stage
393
420
  doc.find('/p:testset/p:attributes/p:design_stage').each do |ele|
394
421
  ele.text = stage
395
422
  end
396
423
  end
424
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
425
+ [e.qname.name,e.text]
426
+ end.to_h
397
427
  end
398
- File.write(fname + '.creator',creator)
399
- File.write(fname + '.author',creator)
400
- File.write(fname + '.stage',stage)
428
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
401
429
 
402
430
  CPEE::ModelManagement::op creator, 'add', models, File.join('.', where, name + '.xml')
403
431
  CPEE::ModelManagement::notify conns, 'create', models, fname
@@ -492,13 +520,17 @@ module CPEE
492
520
  dn = CPEE::ModelManagement::get_dn @h['DN']
493
521
  author = dn['GN'] + ' ' + dn['SN']
494
522
  if !File.exist?(File.join(models,to,name + '.xml'))
523
+ attrs = {}
495
524
  XML::Smart::modify(fname) do |doc|
496
525
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
497
526
  doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
498
527
  ele.text = to
499
528
  end
529
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
530
+ [e.qname.name,e.text]
531
+ end.to_h
500
532
  end
501
- File.write(fname + '.author',author)
533
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
502
534
 
503
535
  CPEE::ModelManagement::op author, 'mv', models, File.join('.', to, name + '.xml'), File.join('.', where, name + '.xml')
504
536
  CPEE::ModelManagement::notify conns, 'move', models, File.join(models,to,name + '.xml'), fname
@@ -518,20 +550,25 @@ module CPEE
518
550
 
519
551
  if File.exists?(fname)
520
552
  author = dn['GN'] + ' ' + dn['SN']
553
+ attrs = {}
521
554
  XML::Smart.string(cont) do |doc|
522
555
  doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
523
- unless File.exists?(File.join(models,where,name + '.xml.creator'))
524
- doc.find('/p:testset/p:attributes/p:author').each do |ele|
525
- File.write(File.join(models,where,name + '.xml.creator'),ele.text)
526
- end
527
- end
528
556
  doc.find('/p:testset/p:attributes/p:author').each do |ele|
529
557
  ele.text = dn['GN'] + ' ' + dn['SN']
530
558
  end
559
+ if doc.find('/p:testset/p:attributes/p:design_stage').empty?
560
+ doc.find('/p:testset/p:attributes').first.add('p:design_stage','draft')
561
+ else
562
+ doc.find('/p:testset/p:attributes/p:design_stage').each do |ele|
563
+ ele.text = 'draft' if ele.text.strip == ''
564
+ end
565
+ end
566
+ attrs = doc.find('/p:testset/p:attributes/*').map do |e|
567
+ [e.qname.name,e.text]
568
+ end.to_h
531
569
  File.write(fname,doc.to_s)
532
- File.write(fname + '.author',author)
533
- File.write(fname + '.stage',doc.find('string(/p:testset/p:attributes/p:design_stage)').sub(/^$/,'draft'))
534
570
  end
571
+ File.write(fname + '.attrs',JSON::pretty_generate(attrs))
535
572
  CPEE::ModelManagement::op author, 'add', models, File.join('.', where, name + '.xml')
536
573
  CPEE::ModelManagement::notify conns, 'put', models, fname
537
574
  else
data/server/model.xml CHANGED
@@ -25,6 +25,10 @@
25
25
  <info>none</info>
26
26
  <creator>Juergen Mangler</creator>
27
27
  <author>Juergen Mangler</author>
28
+ <guarded>none</guarded>
29
+ <guarded_id></guarded_id>
30
+ <model_uuid></model_uuid>
31
+ <model_version></model_version>
28
32
  <modeltype>CPEE</modeltype>
29
33
  <theme>model</theme>
30
34
  <design_dir></design_dir>
data/server/moma.conf CHANGED
@@ -1,5 +1,6 @@
1
1
  :port: 9316
2
2
  :models: models
3
+ :location: https://cpee.org/design/server/
3
4
  :instantiate: https://cpee.org/flow/start/
4
5
  :cockpit:
5
6
  draft: https://cpee.org/flow/model.html?monitor=
data/server/testset.xml CHANGED
@@ -18,6 +18,10 @@
18
18
  <creator>Juergen Mangler</creator>
19
19
  <author>Juergen Mangler</author>
20
20
  <modeltype>CPEE</modeltype>
21
+ <guarded>none</guarded>
22
+ <guarded_id></guarded_id>
23
+ <model_uuid></model_uuid>
24
+ <model_version></model_version>
21
25
  <theme>extended</theme>
22
26
  <design_dir></design_dir>
23
27
  <design_stage>draft</design_stage>
data/tools/cpee-moma CHANGED
@@ -6,6 +6,8 @@ require 'fileutils'
6
6
  require 'xml/smart'
7
7
  require 'zip'
8
8
  require 'typhoeus'
9
+ require 'json'
10
+ require 'securerandom'
9
11
 
10
12
  def wrap(s, width=78, indent=18)
11
13
  lines = []
@@ -84,7 +86,7 @@ if command == 'cpui'
84
86
  js_libs(p1)
85
87
  elsif command == 'convert'
86
88
  Dir['*.xml'].each do |f|
87
- XML::Smart.modify(f) do |doc|
89
+ XML::Smart.open(f) do |doc|
88
90
  doc.register_namespace 'x', 'http://cpee.org/ns/properties/2.0'
89
91
  if doc.root.qname.name == 'testset'
90
92
  name = File.basename(f,'.xml')
@@ -94,6 +96,10 @@ elsif command == 'convert'
94
96
  n = doc.root.add('x:attributes')
95
97
  end
96
98
 
99
+ if doc.find('/x:testset/x:attributes/x:model_uuid').length == 0
100
+ n = doc.find('/x:testset/x:attributes').first
101
+ n.add('x:model_uuid',SecureRandom.uuid)
102
+ end
97
103
  if doc.find('/x:testset/x:attributes/x:theme').length == 0
98
104
  n = doc.find('/x:testset/x:attributes').first
99
105
  n.add('x:theme','extended')
@@ -113,7 +119,6 @@ elsif command == 'convert'
113
119
  e.add('x:creator',creator)
114
120
  end
115
121
  end
116
- File.write(f + '.creator',creator)
117
122
 
118
123
  if (dt = doc.find('/x:testset/x:attributes/x:author')).length > 0
119
124
  dt.each do |e|
@@ -125,7 +130,6 @@ elsif command == 'convert'
125
130
  e.add('x:author',author)
126
131
  end
127
132
  end
128
- File.write(f + '.author',author)
129
133
 
130
134
  if (dt = doc.find('/x:testset/x:attributes/x:design_stage')).length > 0
131
135
  dt.each do |e|
@@ -137,7 +141,6 @@ elsif command == 'convert'
137
141
  e.add('x:design_stage',design_stage)
138
142
  end
139
143
  end
140
- File.write(f + '.stage',design_stage)
141
144
 
142
145
  dd = ENV['PWD'] || Dir.pwd
143
146
  ma = dd.scan(/\/([^\/]+\.dir)/)
@@ -157,9 +160,28 @@ elsif command == 'convert'
157
160
  e.text = name
158
161
  end
159
162
  end
163
+
164
+
165
+ attrs = doc.find('/x:testset/x:attributes/*').map do |e|
166
+ [e.qname.name,e.text]
167
+ end.to_h
168
+ File.write(f + '.attrs',JSON::pretty_generate(attrs))
169
+
170
+ File.unlink(f + '.creator') rescue nil
171
+ File.unlink(f + '.author') rescue nil
172
+ File.unlink(f + '.stage') rescue nil
160
173
  end
161
174
  end
162
175
  end
176
+ Dir['*.dir'].each do |f|
177
+ attrs = JSON::load File.open(f + '.attrs') rescue {}
178
+ attrs['creator'] = File.read(f + '.creator') if File.exists?(f + '.creator')
179
+ attrs['author'] = File.read(f + '.author') if File.exists?(f + '.author')
180
+ File.write(f + '.attrs',JSON::pretty_generate(attrs))
181
+
182
+ File.unlink(f + '.creator') rescue nil
183
+ File.unlink(f + '.author') rescue nil
184
+ end
163
185
  elsif command == 'new'
164
186
  if !File.exists?(p1)
165
187
  FileUtils.mkdir(File.join(p1)) rescue nil
data/ui/css/design.css CHANGED
@@ -22,6 +22,12 @@ form input {
22
22
 
23
23
  ui-behind {
24
24
  text-transform: capitalize;
25
+ font-weight: bold;
26
+ color: #d0d0d0;
27
+ }
28
+
29
+ ui-behind span {
30
+ cursor: pointer;
25
31
  }
26
32
 
27
33
  [is="x-ui-"] table.ui-table {
@@ -48,3 +54,9 @@ ui-behind {
48
54
  [is="x-ui-"] table.ui-table tbody tr:hover td[data-class=ops] {
49
55
  background-color: #99cee6b0;
50
56
  }
57
+
58
+ [is="x-ui-"] ui-rest > ui-content > ui-area { padding: 1em; }
59
+
60
+ tr.contextmenuitem .capitalized {
61
+ text-transform: capitalize;
62
+ }
data/ui/design.js ADDED
@@ -0,0 +1,239 @@
1
+ var gstage;
2
+ var gdir;
3
+
4
+ function move_it(name,todir) {
5
+ $.ajax({
6
+ type: "PUT",
7
+ url: "server/" + gdir + name,
8
+ data: { dir: todir }
9
+ });
10
+ }
11
+ function shift_it(name,to) {
12
+ $.ajax({
13
+ type: "PUT",
14
+ url: "server/" + gdir + name,
15
+ data: { stage: to }
16
+ });
17
+ }
18
+ function rename_it(name) {
19
+ var newname;
20
+ if (newname = prompt('New name please!',name.replace(/\.xml$/,'').replace(/\.dir$/,''))) {
21
+ $.ajax({
22
+ type: "PUT",
23
+ url: "server/" + gdir + name,
24
+ data: { new: newname }
25
+ });
26
+ }
27
+ }
28
+ function duplicate_it(name) {
29
+ var newname;
30
+ if (newname = prompt('New name please!',name.replace(/\.xml$/,'').replace(/\.dir$/,''))) {
31
+ $.ajax({
32
+ type: "POST",
33
+ url: "server/" + gdir,
34
+ data: { new: newname, old: name }
35
+ });
36
+ }
37
+ }
38
+ function delete_it(name) {
39
+ if (confirm('Are you really, really, REALLY sure!')) {
40
+ $.ajax({
41
+ type: "DELETE",
42
+ url: "server/" + gdir + name
43
+ });
44
+ }
45
+ }
46
+
47
+ function es_init(gdir,gstage) {
48
+ var es = new EventSource('server/');
49
+ es.onopen = function() {
50
+ console.log('es open');
51
+ };
52
+ es.onmessage = function(e) {
53
+ paint(gdir,gstage);
54
+ };
55
+ es.onerror = function() {
56
+ console.log('es error');
57
+ // es_init();
58
+ };
59
+ }
60
+
61
+ function paint(gdir,gstage) {
62
+ $('#models tbody').empty();
63
+ if (gdir && gdir != '') {
64
+ var clone = document.importNode(document.querySelector('#up').content,true);
65
+ $('[data-class=name] a',clone).text('..');
66
+ $('[data-class=name] a',clone).attr('href',window.location.pathname + '?stage=' + gstage + '&dir=');
67
+ $('#models tbody').append(clone);
68
+ }
69
+ $.ajax({
70
+ type: "GET",
71
+ url: "server/" + gdir,
72
+ data: { stage: gstage },
73
+ success: function(res) {
74
+ $(res).each(function(k,data) {
75
+ if (data.type == 'dir') {
76
+ var clone = document.importNode(document.querySelector('#folder').content,true);
77
+ $('[data-class=name] a',clone).text(data['name'].replace(/\.dir$/,''));
78
+ $('[data-class=name]',clone).attr('data-full-name',data['name']);
79
+ $('[data-class=name] a',clone).attr('href',window.location.pathname + '?stage=' + gstage + '&dir=' + data['name']);
80
+ } else {
81
+ var clone = document.importNode(document.querySelector('#model').content,true);
82
+ $('[data-class=name] a',clone).text(data['name']);
83
+ $('[data-class=name]',clone).attr('data-full-name',data['name']);
84
+ $('[data-class=name] a',clone).attr('href','server/' + gdir + data['name'] + '/open?stage=' + gstage);
85
+ $('[data-class=force] a',clone).attr('href','server/' + gdir + data['name'] + '/open-new?stage=' + gstage);
86
+ $('[data-class=raw] a',clone).attr('href','server/' + gdir + data['name']);
87
+
88
+ $('[data-class=guarded] abbr',clone).attr('title',data['guarded'] || '');
89
+ $('[data-class=guarded] abbr',clone).text((data['guarded'] || '').match(/none/i) ? '' : (data['guarded'] || '').charAt(0).toUpperCase());
90
+ $('[data-class=resource]',clone).text(data['guarded_id'] || '');
91
+ }
92
+ $('[data-class=author]',clone).text(data['author']);
93
+ $('[data-class=date]',clone).text(new Date(data['date']).strftime('%Y-%m-%d, %H:%M:%S'));
94
+ $('#models tbody').append(clone);
95
+ });
96
+ }
97
+ });
98
+ }
99
+
100
+ function change_it(gdir,gstage) {
101
+ window.location.href = window.location.pathname + '?stage=' + gstage + '&dir=' + gdir;
102
+ }
103
+
104
+ $(document).ready(function() {
105
+ const queryString = window.location.search;
106
+ const urlParams = new URLSearchParams(queryString);
107
+
108
+ gstage = urlParams.get('stage') || 'draft';
109
+ gdir = urlParams.get('dir') ? (urlParams.get('dir') + '/').replace(/\/+/,'/') : '';
110
+
111
+ es_init(gdir,gstage);
112
+
113
+ var shifts = []
114
+ $.ajax({
115
+ type: "GET",
116
+ url: "server/",
117
+ data: { stages: 'stages' },
118
+ success: (r) => {
119
+ shifts = shifts.concat(r);
120
+ shifts = shifts.filter(item => item !== gstage);
121
+ }
122
+ });
123
+
124
+ $('input[name=stage]').val(gstage);
125
+ $('input[name=dir]').val(gdir);
126
+ $('ui-behind span').text(gstage);
127
+ $('ui-behind span').click((e) => {
128
+ if (shifts.length > 0) {
129
+ var menu = {};
130
+ menu['Change to'] = [];
131
+ shifts.forEach(ele => {
132
+ menu['Change to'].push(
133
+ {
134
+ 'label': ele,
135
+ 'function_call': change_it,
136
+ 'text_icon': '➔',
137
+ 'type': undefined,
138
+ 'class': 'capitalized',
139
+ 'params': [gdir,ele]
140
+ }
141
+ );
142
+ });
143
+ new CustomMenu(e).contextmenu(menu);
144
+ }
145
+ });
146
+
147
+ var dragged;
148
+ $('#models').on('drag','td[data-class=model]',false);
149
+ $('#models').on('dragstart','td[data-class=model]',(e) => {
150
+ dragged = $(e.currentTarget).parents('tr').find('td[data-class=name]').text();
151
+ });
152
+ $('#models').on('dragover','td[data-class=folder]',false);
153
+ $('#models').on('drop','td[data-class=folder]',(e) => {
154
+ e.preventDefault();
155
+ e.stopPropagation();
156
+ if (dragged) {
157
+ var todir = $(e.currentTarget).parents('tr').find('td[data-class=name]').text();
158
+ todir = todir.replace(/\./g,'');
159
+ if (todir != '') {
160
+ todir += '.dir';
161
+ }
162
+ move_it(dragged,todir);
163
+ dragged = undefined;
164
+ }
165
+ });
166
+ $('#models').on('click','td[data-class=ops]',(e) => {
167
+ var menu = {};
168
+ var name = $(e.currentTarget).parents('tr').find('td[data-class=name]').attr('data-full-name');
169
+ menu['Operations'] = [
170
+ {
171
+ 'label': 'Delete',
172
+ 'function_call': delete_it,
173
+ 'text_icon': '❌',
174
+ 'type': undefined,
175
+ 'params': [name]
176
+ },
177
+ {
178
+ 'label': 'Rename',
179
+ 'function_call': rename_it,
180
+ 'type': undefined,
181
+ 'text_icon': '📛',
182
+ 'params': [name]
183
+ }
184
+ ];
185
+ if (name.match(/\.xml$/)) {
186
+ menu['Operations'].unshift(
187
+ {
188
+ 'label': 'Duplicate',
189
+ 'function_call': duplicate_it,
190
+ 'text_icon': '➕',
191
+ 'type': undefined,
192
+ 'params': [name]
193
+ }
194
+ );
195
+ }
196
+ if (shifts.length > 0) {
197
+ menu['Shifting'] = [];
198
+ shifts.forEach(ele => {
199
+ menu['Shifting'].push(
200
+ {
201
+ 'label': 'Shift to ' + ele,
202
+ 'function_call': shift_it,
203
+ 'text_icon': '➔',
204
+ 'type': undefined,
205
+ 'params': [name,ele]
206
+ }
207
+ );
208
+ });
209
+ }
210
+ new CustomMenu(e).contextmenu(menu);
211
+ });
212
+
213
+ history.pushState({}, document.title, window.location.pathname + '?stage=' + gstage + '&dir=' + gdir);
214
+ paint(gdir,gstage);
215
+
216
+ $('#newmod').on('submit',(e) => {
217
+ $.ajax({
218
+ type: "POST",
219
+ url: "server/" + gdir,
220
+ data: { stage: gstage, new: $("#newmod input[name=new]").val() },
221
+ success: (r) => {
222
+ uidash_activate_tab($('ui-tab').first());
223
+ }
224
+ });
225
+ return false;
226
+ });
227
+
228
+ $('#newdir').on('submit',(e) => {
229
+ $.ajax({
230
+ type: "POST",
231
+ url: "server/",
232
+ data: { dir: $("#newdir input[name=newdir]").val() },
233
+ success: (r) => {
234
+ uidash_activate_tab($('ui-tab').first());
235
+ }
236
+ });
237
+ return false;
238
+ });
239
+ });
data/ui/index.html CHANGED
@@ -61,20 +61,35 @@
61
61
  <ui-tab class="" data-tab="models" >Models</ui-tab>
62
62
  <ui-tab class="inactive" data-tab="newmodel">New Model</ui-tab>
63
63
  <ui-tab class="inactive" data-tab="newdir" >New Dir</ui-tab>
64
- <ui-behind ></ui-behind>
64
+ <ui-space ></ui-space>
65
+ <ui-tab class="inactive" data-tab="running" >Running</ui-tab>
66
+ <ui-tab class="inactive" data-tab="stopped" >Stopped</ui-tab>
67
+ <ui-behind ><span></span></ui-behind>
65
68
  <ui-last ><a class="logo" href=".."></a></ui-last>
66
69
  </ui-tabbar>
67
70
  <ui-content class="noselect">
68
71
  <ui-area data-belongs-to-tab="models">
69
72
  <p>Your Models are saved/versioned in <a target='_blank' href='https://git-scm.com/'>GIT</a>. So fret not. Just send an email to <a href="mail:helpdesk@acdp.at">helpdesk@acdp.at</a> if you are lost. And as always: <a target='_blank' href='https://www.youtube.com/watch?v=kkxj5xVLyj0&feature=youtu.be&t=56'>get dressed for success</a>.</p>
70
73
  <table id="models" class='ui-table'>
74
+ <thead>
75
+ <th></th>
76
+ <th>Name</th>
77
+ <th><abbr title='force new instance'>F</abbr></th>
78
+ <th><abbr title='link to model source'>M</abbr></th>
79
+ <th>Changed By</th>
80
+ <th><abbr title='Guarded'>G</abbr></th>
81
+ <th><abbr title='Resource'>R</abbr></th>
82
+ <th>Changed At</th>
83
+ <th><abbr title='Operations'>Op</abbr></th>
84
+ </thead>
71
85
  <template id="up">
72
86
  <tr>
73
87
  <td data-class='folder' class="noselect">📁</td>
74
88
  <td data-class='name' data-full-name=''><a href=''></a></td>
75
89
  <td></td>
76
90
  <td></td>
77
- <td data-class='creator'></td>
91
+ <td></td>
92
+ <td></td>
78
93
  <td></td>
79
94
  <td data-class='date'></td>
80
95
  <td data-class=''></td>
@@ -86,7 +101,8 @@
86
101
  <td data-class='name' data-full-name=''><a href=''></a></td>
87
102
  <td></td>
88
103
  <td></td>
89
- <td data-class='creator'></td>
104
+ <td></td>
105
+ <td></td>
90
106
  <td></td>
91
107
  <td data-class='date'></td>
92
108
  <td data-class='ops' class="noselect"><span>…</span></td>
@@ -98,8 +114,9 @@
98
114
  <td data-class='name' data-full-name=''><a target='_blank' href=''></a></td>
99
115
  <td data-class='force'>[<a target='_blank' href='' title='force new instance'>F</a>]</td>
100
116
  <td data-class='raw'>[<a target='_blank' href='' title='link to model source'>M</a>]</td>
101
- <td data-class='creator'></td>
102
117
  <td data-class='author'></td>
118
+ <td data-class='guarded'><abbr title=''></abbr></td>
119
+ <td data-class='resource'></td>
103
120
  <td data-class='date'></td>
104
121
  <td data-class='ops' class="noselect"><span>…</span></td>
105
122
  </tr>
data/ui/js/design.js CHANGED
@@ -84,8 +84,17 @@ function paint(gdir,gstage) {
84
84
  $('[data-class=name] a',clone).attr('href','server/' + gdir + data['name'] + '/open?stage=' + gstage);
85
85
  $('[data-class=force] a',clone).attr('href','server/' + gdir + data['name'] + '/open-new?stage=' + gstage);
86
86
  $('[data-class=raw] a',clone).attr('href','server/' + gdir + data['name']);
87
+
88
+ $('[data-class=guarded] abbr',clone).attr('title',data['guarded'] || '');
89
+ $('[data-class=guarded] abbr',clone).text((data['guarded'] || '').match(/none/i) ? '' : (data['guarded'] || '').charAt(0).toUpperCase());
90
+ $('[data-class=resource]',clone).text(data['guarded_id'] || '');
91
+
92
+ if (data['guarded']) {
93
+ $('[data-class=guarded] abbr',clone).attr('title',data['guarded']);
94
+ $('[data-class=guarded] abbr',clone).text(data['guarded'].match(/none/i) ? '' : data['guarded'].charAt(0).toUpperCase());
95
+ $('[data-class=resource]',clone).text(data['guarded_what']);
96
+ }
87
97
  }
88
- $('[data-class=creator]',clone).text(data['creator']);
89
98
  $('[data-class=author]',clone).text(data['author']);
90
99
  $('[data-class=date]',clone).text(new Date(data['date']).strftime('%Y-%m-%d, %H:%M:%S'));
91
100
  $('#models tbody').append(clone);
@@ -94,6 +103,10 @@ function paint(gdir,gstage) {
94
103
  });
95
104
  }
96
105
 
106
+ function change_it(gdir,gstage) {
107
+ window.location.href = window.location.pathname + '?stage=' + gstage + '&dir=' + gdir;
108
+ }
109
+
97
110
  $(document).ready(function() {
98
111
  const queryString = window.location.search;
99
112
  const urlParams = new URLSearchParams(queryString);
@@ -103,9 +116,39 @@ $(document).ready(function() {
103
116
 
104
117
  es_init(gdir,gstage);
105
118
 
119
+ var shifts = []
120
+ $.ajax({
121
+ type: "GET",
122
+ url: "server/",
123
+ data: { stages: 'stages' },
124
+ success: (r) => {
125
+ shifts = shifts.concat(r);
126
+ shifts = shifts.filter(item => item !== gstage);
127
+ }
128
+ });
129
+
106
130
  $('input[name=stage]').val(gstage);
107
131
  $('input[name=dir]').val(gdir);
108
- $('ui-behind').text(gstage);
132
+ $('ui-behind span').text(gstage);
133
+ $('ui-behind span').click((e) => {
134
+ if (shifts.length > 0) {
135
+ var menu = {};
136
+ menu['Change to'] = [];
137
+ shifts.forEach(ele => {
138
+ menu['Change to'].push(
139
+ {
140
+ 'label': ele,
141
+ 'function_call': change_it,
142
+ 'text_icon': '➔',
143
+ 'type': undefined,
144
+ 'class': 'capitalized',
145
+ 'params': [gdir,ele]
146
+ }
147
+ );
148
+ });
149
+ new CustomMenu(e).contextmenu(menu);
150
+ }
151
+ });
109
152
 
110
153
  var dragged;
111
154
  $('#models').on('drag','td[data-class=model]',false);
@@ -117,7 +160,6 @@ $(document).ready(function() {
117
160
  e.preventDefault();
118
161
  e.stopPropagation();
119
162
  if (dragged) {
120
- console.log(dragged);
121
163
  var todir = $(e.currentTarget).parents('tr').find('td[data-class=name]').text();
122
164
  todir = todir.replace(/\./g,'');
123
165
  if (todir != '') {
@@ -127,16 +169,6 @@ $(document).ready(function() {
127
169
  dragged = undefined;
128
170
  }
129
171
  });
130
- var shifts = []
131
- $.ajax({
132
- type: "GET",
133
- url: "server/",
134
- data: { stages: 'stages' },
135
- success: (r) => {
136
- shifts = shifts.concat(r);
137
- shifts = shifts.filter(item => item !== gstage);
138
- }
139
- });
140
172
  $('#models').on('click','td[data-class=ops]',(e) => {
141
173
  var menu = {};
142
174
  var name = $(e.currentTarget).parents('tr').find('td[data-class=name]').attr('data-full-name');
@@ -181,7 +213,6 @@ $(document).ready(function() {
181
213
  );
182
214
  });
183
215
  }
184
- console.log(shifts);
185
216
  new CustomMenu(e).contextmenu(menu);
186
217
  });
187
218
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpee-model-management
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.12
4
+ version: 1.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juergen eTM Mangler
8
8
  autorequire:
9
9
  bindir: tools
10
10
  cert_chain: []
11
- date: 2021-05-27 00:00:00.000000000 Z
11
+ date: 2021-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: riddl
@@ -38,6 +38,26 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cpee
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.1'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 2.1.7
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '2.1'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 2.1.7
41
61
  description: see http://cpee.org
42
62
  email: juergen.mangler@gmail.com
43
63
  executables:
@@ -61,6 +81,7 @@ files:
61
81
  - server/testset.xml
62
82
  - tools/cpee-moma
63
83
  - ui/css/design.css
84
+ - ui/design.js
64
85
  - ui/index.html
65
86
  - ui/js/design.js
66
87
  homepage: http://cpee.org/
@@ -82,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
103
  - !ruby/object:Gem::Version
83
104
  version: '0'
84
105
  requirements: []
85
- rubygems_version: 3.1.6
106
+ rubygems_version: 3.2.22
86
107
  signing_key:
87
108
  specification_version: 4
88
109
  summary: "(Lifecycle) manage your process models in a directory or git repo."