cpee-model-management 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 28a4708fee10b56828b2e1cc17ee2bc7387765132991cf5c615f81fcea9e7006
4
+ data.tar.gz: d4b7307f3e0a31dd18f3538b48c2a6e79e3611ba2ecca20ae4acfce351e6d22e
5
+ SHA512:
6
+ metadata.gz: ed03d2f9904eee9563f75ef01145bbfcee94eb84daeb5c09244df7cbcaf8db9a9f3bc7b87883bf304ccbdf7cb523097edf7c4bf902d28bda2dd1f3a7be6203ba
7
+ data.tar.gz: b64f5f194e8657b8110131c703b846ec1a78709f1d4ad77f0321a11fd752cee9aa89bc50d766405c0d87a617fe081b28c3ce416395230258e686532218765a6e
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Jürgen Mangler <juergen.mangler@gmail.com>
data/LICENSE ADDED
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # CPEE Model Manager
2
+
3
+ To install the model manager go to the commandline
4
+
5
+ ```bash
6
+ gem install cpee-model-manager
7
+ cpee-moma new moma
8
+ cd moma
9
+ ./moma start
10
+ ```
11
+ The service is running under port 9316. If this port has to be changed (or the
12
+ host, or local-only access, ...), modify the file moma.conf and change:
13
+
14
+ ```yaml
15
+ :port: 9250
16
+ ```
17
+
18
+ You may also change the directory where the models are saved:
19
+
20
+ ```yaml
21
+ :models: /var/models
22
+ ```
23
+
24
+ If the models directory is a git, each model change is automatically commited and
25
+ pushed IF push works without passwort. So take care to either use a password-less key or
26
+ in case of http basic auth, add user and password to the url.
data/Rakefile ADDED
@@ -0,0 +1,21 @@
1
+ require 'rake'
2
+ require 'rubygems/package_task'
3
+
4
+ spec = eval(File.read('cpee-model-management.gemspec'))
5
+ Gem::PackageTask.new(spec) do |pkg|
6
+ pkg.need_zip = true
7
+ pkg.need_tar = true
8
+ FileUtils.mkdir 'pkg' rescue nil
9
+ FileUtils.rm_rf Dir.glob('pkg/*')
10
+ FileUtils.ln_sf "#{pkg.name}.gem", "pkg/#{spec.name}.gem"
11
+ end
12
+
13
+ task :default => [:gem]
14
+
15
+ task :push => :gem do |r|
16
+ `gem push pkg/cpee-model-management.gem`
17
+ end
18
+
19
+ task :install => :gem do |r|
20
+ `gem install pkg/cpee-model-management.gem`
21
+ end
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "cpee-model-management"
3
+ s.version = "1.0.0"
4
+ s.platform = Gem::Platform::RUBY
5
+ s.license = "LGPL-3.0"
6
+ s.summary = "(Lifecycle) manage your process models in a directory or git repo."
7
+
8
+ s.description = "see http://cpee.org"
9
+
10
+ s.files = Dir['{server/**/*,tools/**/*,lib/**/*}'] + %w(LICENSE Rakefile cpee-model-management.gemspec README.md AUTHORS)
11
+ s.require_path = 'lib'
12
+ s.extra_rdoc_files = ['README.md']
13
+ s.bindir = 'tools'
14
+ s.executables = ['cpee-moma']
15
+
16
+ s.required_ruby_version = '>=2.7.0'
17
+
18
+ s.authors = ['Juergen eTM Mangler']
19
+
20
+ s.email = 'juergen.mangler@gmail.com'
21
+ s.homepage = 'http://cpee.org/'
22
+
23
+ s.add_runtime_dependency 'riddl', '~> 0.99'
24
+ s.add_runtime_dependency 'json', '~> 2.1'
25
+ end
@@ -0,0 +1,568 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # This file is part of CPEE-MODEL-MANAGEMENT
4
+ #
5
+ # CPEE-MODEL-MANAGEMENT is free software: you can redistribute it and/or
6
+ # modify it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or (at your
8
+ # option) any later version.
9
+ #
10
+ # CPEE-MODEL-MANAGEMENT is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13
+ # Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License along with
16
+ # CPEE-MODEL-MANAGEMENT (file LICENSE in the main directory). If not, see
17
+ # <http://www.gnu.org/licenses/>.
18
+
19
+ require 'rubygems'
20
+ require 'json'
21
+ require 'riddl/server'
22
+ require 'riddl/client'
23
+ require 'riddl/protocols/utils'
24
+ require 'fileutils'
25
+
26
+ module CPEE
27
+ module ModelManagement
28
+
29
+ SERVER = File.expand_path(File.join(__dir__,'moma.xml'))
30
+
31
+ def self::op(author,op,models,new,old=nil) #{{{
32
+ if File.exists?(File.join(models,'.git'))
33
+ cdir = Dir.pwd
34
+ Dir.chdir(models)
35
+ case op
36
+ when 'mv'
37
+ fname = old
38
+ fnname = new
39
+ `git mv "#{fname}" "#{fnname}" 2>/dev/null`
40
+ `git rm -rf "#{fname + '.active'}" "#{fnname + '.active'}" 2>/dev/null`
41
+ `git rm -rf "#{fname + '.active-uuid'}" "#{fnname + '.active-uuid'}" 2>/dev/null`
42
+ `git mv "#{fname + '.author'}" "#{fnname + '.author'}" 2>/dev/null`
43
+ `git mv "#{fname + '.creator'}" "#{fnname + '.creator'}" 2>/dev/null`
44
+ `git mv "#{fname + '.stage'}" "#{fnname + '.stage'}" 2>/dev/null`
45
+ when 'rm'
46
+ fname = new
47
+ `git rm -rf "#{fname}" 2>/dev/null`
48
+ FileUtils.rm_rf(fname)
49
+ `git rm -rf "#{fname}.active" 2>/dev/null`
50
+ `git rm -rf "#{fname}.active-uuid" 2>/dev/null`
51
+ `git rm -rf "#{fname}.author" 2>/dev/null`
52
+ `git rm -rf "#{fname}.creator" 2>/dev/null`
53
+ `git rm -rf "#{fname}.stage" 2>/dev/null`
54
+ when 'shift'
55
+ fname = new
56
+ `git rm -rf "#{fname}.active" 2>/dev/null`
57
+ `git rm -rf "#{fname}.active-uuid" 2>/dev/null`
58
+ end
59
+ fname = new
60
+ `git add "#{fname}" 2>/dev/null`
61
+ `git add "#{fname}.active" 2>/dev/null`
62
+ `git add "#{fname}.active-uuid" 2>/dev/null`
63
+ `git add "#{fname}.author" 2>/dev/null`
64
+ `git add "#{fname}.creator" 2>/dev/null`
65
+ `git add "#{fname}.stage" 2>/dev/null`
66
+ `git commit -m "#{author.gsub(/"/,"'")}"`
67
+ Dir.chdir(cdir)
68
+ else
69
+ case op
70
+ when 'mv'
71
+ fname = File.join(models,old)
72
+ fnname = File.join(models,new)
73
+ FileUtils.mv(fname,fnname)
74
+ File.delete(fname + '.active',fnname + '.active') rescue nil
75
+ File.delete(fname + '.active-uuid',fnname + '.active-uuid') rescue nil
76
+ FileUtils.mv(fname + '.author',fnname + '.author') rescue nil
77
+ FileUtils.mv(fname + '.creator',fnname + '.creator') rescue nil
78
+ FileUtils.mv(fname + '.stage',fnname + '.stage') rescue nil
79
+ when 'rm'
80
+ fname = File.join(models,new)
81
+ FileUtils.rm_rf(fname)
82
+ File.delete(fname + '.active') rescue nil
83
+ File.delete(fname + '.active-uuid') rescue nil
84
+ File.delete(fname + '.author') rescue nil
85
+ File.delete(fname + '.creator') rescue nil
86
+ File.delete(fname + '.stage') rescue nil
87
+ when 'shift'
88
+ fname = File.join(models,new)
89
+ File.delete(fname + '.active') rescue nil
90
+ File.delete(fname + '.active-uuid') rescue nil
91
+ end
92
+ end
93
+ end #}}}
94
+ def self::get_dn(dn) #{{{
95
+ if dn
96
+ dn.split(',').map{ |e| e.split('=',2) }.to_h
97
+ else
98
+ { 'GN' => 'Christine', 'SN' => 'Ashcreek' }
99
+ end
100
+ end #}}}
101
+ def self::notify(conns,op,models,f,s=nil) #{{{
102
+ what = if f =~ /\.dir$/
103
+ if op == 'delete'
104
+ { :op => op, :type => :dir, :name => File.basename(f) }
105
+ else
106
+ { :op => op, :type => :dir, :name => File.basename(f), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
107
+ end
108
+ else
109
+ if op == 'delete'
110
+ { :op => op, :type => :file, :name => f.sub(Regexp.compile(File.join(models,'/')),'') }
111
+ else
112
+ fstage = File.read(f + '.stage').strip rescue 'draft'
113
+ { :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 }
114
+ end
115
+ end
116
+ what[:source] = s.sub(/models\//,'') unless s.nil?
117
+ conns.each do |e|
118
+ e.send what
119
+ end
120
+ end #}}}
121
+
122
+ class GetList < Riddl::Implementation #{{{
123
+ def response
124
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r.last)
125
+ views = @a[1]
126
+ models = @a[2]
127
+ stage = @p[0]&.value || 'draft'
128
+ stage = views[stage] if views && views[stage]
129
+
130
+ names = Dir.glob(File.join(models,where,'*.dir')).map do |f|
131
+ { :type => :dir, :name => File.basename(f), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
132
+ end.compact.uniq.sort_by{ |e| e[:name] } + Dir.glob(File.join(models,where,'*.xml')).map do |f|
133
+ fstage = File.read(f + '.stage').strip rescue 'draft'
134
+ { :type => :file, :name => File.basename(f), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema } if fstage == stage
135
+ end.compact.uniq.sort_by{ |e| e[:name] }
136
+
137
+ Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(names))
138
+ end
139
+ end #}}}
140
+ class GetListFull < Riddl::Implementation #{{{
141
+ def response
142
+ views = @a[0]
143
+ models = @a[1]
144
+ stage = @p[0]&.value || 'draft'
145
+ stage = views[stage] if views && views[stage]
146
+
147
+ names = Dir.glob(File.join(models,'*.dir/*.xml')).map do |f|
148
+ { :type => :file, :name => File.join(File.basename(File.dirname(f)),File.basename(f)), :creator => File.read(f + '.creator'), :date => File.mtime(f).xmlschema }
149
+ end.compact.uniq.sort_by{ |e| e[:name] } + Dir.glob(File.join(models,'*.xml')).map do |f|
150
+ fstage = File.read(f + '.stage').strip rescue 'draft'
151
+ { :type => :file, :name => File.basename(f), :creator => File.read(f + '.creator'), :author => File.read(f + '.author'), :stage => fstage, :date => File.mtime(f).xmlschema } if fstage == stage
152
+ end.compact.uniq.sort_by{ |e| e[:name] }
153
+
154
+ Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(names))
155
+ end
156
+ end #}}}
157
+ class GetStages < Riddl::Implementation #{{{
158
+ def response
159
+ themes = @a[0]
160
+ Riddl::Parameter::Complex.new('list','application/json',JSON::pretty_generate(themes&.keys || []))
161
+ end
162
+ end #}}}
163
+
164
+ class ShiftItem < Riddl::Implementation #{{{
165
+ def response
166
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
167
+ conns = @a[1]
168
+ themes = @a[2]
169
+ models = @a[3]
170
+ name = File.basename(@r.last,'.xml')
171
+ nstage = @p[0].value
172
+ fname = File.join(models,where,name + '.xml')
173
+
174
+ dn = CPEE::ModelManagement::get_dn @h['DN']
175
+ author = dn['GN'] + ' ' + dn['SN']
176
+
177
+ XML::Smart::modify(fname) do |doc|
178
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
179
+ doc.find('/p:testset/p:attributes/p:author').each do |ele|
180
+ ele.text = author
181
+ end
182
+ doc.find('/p:testset/p:attributes/p:design_stage').each do |ele|
183
+ ele.text = nstage
184
+ end
185
+ doc.find('/p:testset/p:attributes/p:theme').each do |ele|
186
+ ele.text = themes[nstage] || 'model'
187
+ end
188
+ end
189
+ File.write(fname + '.author',author)
190
+ File.write(fname + '.stage',nstage)
191
+
192
+ CPEE::ModelManagement::op author, 'shift', models, File.join('.', where, name + '.xml'), File.join('.', where, name + '.xml')
193
+ CPEE::ModelManagement::notify conns, 'shift', models, fname, fname
194
+ nil
195
+ end
196
+ end #}}}
197
+
198
+ class RenameItem < Riddl::Implementation #{{{
199
+ def response
200
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
201
+ conns = @a[1]
202
+ models = @a[2]
203
+ name = File.basename(@r.last,'.xml')
204
+ nname = @p[0].value
205
+ fname = File.join(models,where,name + '.xml')
206
+ fnname = File.join(models,where,nname + '.xml')
207
+ counter = 0
208
+ stage = 'draft'
209
+ while File.exists?(fnname)
210
+ counter += 1
211
+ fnname = File.join(models,where,nname + counter.to_s + '.xml')
212
+ end
213
+
214
+ dn = CPEE::ModelManagement::get_dn @h['DN']
215
+ author = dn['GN'] + ' ' + dn['SN']
216
+
217
+ XML::Smart::modify(fname) do |doc|
218
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
219
+ doc.find('/p:testset/p:attributes/p:info').each do |ele|
220
+ ele.text = File.basename(fnname,'.xml')
221
+ end
222
+ doc.find('/p:testset/p:attributes/p:author').each do |ele|
223
+ ele.text = author
224
+ end
225
+ end
226
+ File.write(fname + '.author',author)
227
+
228
+ CPEE::ModelManagement::op author, 'mv', models, File.join('.', where, nname + '.xml'), File.join('.', where, name + '.xml')
229
+ CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
230
+ nil
231
+ end
232
+ end #}}}
233
+ class RenameDir < Riddl::Implementation #{{{
234
+ def response
235
+ conns = @a[0]
236
+ models = @a[1]
237
+ name = File.basename(@r.last,'.dir')
238
+ nname = @p[0].value
239
+ fname = File.join(models,name + '.dir')
240
+ fnname = File.join(models,nname + '.dir')
241
+ counter = 0
242
+ while File.exists?(fnname)
243
+ counter += 1
244
+ fnname = File.join(models,nname + counter.to_s + '.dir')
245
+ end
246
+
247
+ dn = CPEE::ModelManagement::get_dn @h['DN']
248
+ author = dn['GN'] + ' ' + dn['SN']
249
+ File.write(fname + '.author',author)
250
+
251
+ CPEE::ModelManagement::op author, 'mv', models, File.join(nname + '.dir'), File.join(name + '.dir')
252
+ CPEE::ModelManagement::notify conns, 'rename', models, fnname, fname
253
+ nil
254
+ end
255
+ end #}}}
256
+
257
+ class CreateDir < Riddl::Implementation #{{{
258
+ def response
259
+ name = @p[0].value
260
+ conns = @a[0]
261
+ models = @a[1]
262
+
263
+ fname = File.join(models,name + '.dir')
264
+ counter = 0
265
+ while File.exists?(fname)
266
+ counter += 1
267
+ fname = File.join(models,name + counter.to_s + '.dir')
268
+ end
269
+
270
+ dn = CPEE::ModelManagement::get_dn @h['DN']
271
+ creator = dn['GN'] + ' ' + dn['SN']
272
+
273
+ Dir.mkdir(fname)
274
+ FileUtils.touch(File.join(fname,'.gitignore'))
275
+ File.write(fname + '.creator',creator)
276
+ File.write(fname + '.author',creator)
277
+
278
+ CPEE::ModelManagement::op creator, 'add', models, name + '.dir'
279
+ CPEE::ModelManagement::notify conns, 'create', models, fname
280
+ nil
281
+ end
282
+ end #}}}
283
+ class Create < Riddl::Implementation #{{{
284
+ def response
285
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r.last)
286
+ stage = if @a[1] == :cre
287
+ @p.shift.value
288
+ else
289
+ nil
290
+ end
291
+ views = @a[2]
292
+ conns = @a[3]
293
+ templates = @a[4]
294
+ models = @a[5]
295
+
296
+ name = @p[0].value
297
+ source = @p[1] ? File.join(models,where,@p[1].value) : (templates[stage] ? templates[stage] : 'testset.xml')
298
+ fname = File.join(models,where,name + '.xml')
299
+
300
+ stage = File.read(source + '.stage') if stage.nil? && File.exists?(source + '.stage')
301
+ stage = views[stage] if views && views[stage]
302
+
303
+ counter = 0
304
+ while File.exists?(fname)
305
+ counter += 1
306
+ fname = File.join(models,where,name + counter.to_s + '.xml')
307
+ end
308
+
309
+ dn = CPEE::ModelManagement::get_dn @h['DN']
310
+ creator = dn['GN'] + ' ' + dn['SN']
311
+ FileUtils.cp(source,fname)
312
+ XML::Smart::modify(fname) do |doc|
313
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
314
+ doc.find('/p:testset/p:attributes/p:info').each do |ele|
315
+ ele.text = File.basename(fname,'.xml')
316
+ end
317
+ doc.find('/p:testset/p:attributes/p:creator').each do |ele|
318
+ ele.text = creator
319
+ end
320
+ doc.find('/p:testset/p:attributes/p:author').each do |ele|
321
+ ele.text = creator
322
+ end
323
+ doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
324
+ ele.text = where
325
+ end
326
+ if stage
327
+ doc.find('/p:testset/p:attributes/p:design_stage').each do |ele|
328
+ ele.text = stage
329
+ end
330
+ end
331
+ end
332
+ File.write(fname + '.creator',creator)
333
+ File.write(fname + '.author',creator)
334
+ File.write(fname + '.stage',stage)
335
+
336
+ CPEE::ModelManagement::op creator, 'add', models, File.join('.', where, name + '.xml')
337
+ CPEE::ModelManagement::notify conns, 'create', models, fname
338
+ nil
339
+ end
340
+ end #}}}
341
+
342
+ class GetItem < Riddl::Implementation #{{{
343
+ def response
344
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
345
+ models = @a[1]
346
+ name = File.basename(@r[-1],'.xml')
347
+ fname = File.join(models,where,name + '.xml')
348
+ if File.exists? fname
349
+ Riddl::Parameter::Complex.new('content','application/xml',File.read(fname))
350
+ else
351
+ @status = 400
352
+ end
353
+ end
354
+ end #}}}
355
+ class OpenItem < Riddl::Implementation #{{{
356
+ def response
357
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-3])
358
+ name = File.basename(@r[-2],'.xml')
359
+ insta = @a[1]
360
+ cock = @a[2]
361
+ views = @a[3]
362
+ force = @a[4]
363
+ models = @a[5]
364
+ stage = @p[0]&.value || 'draft'
365
+
366
+ fname = File.join(models,where,name + '.xml')
367
+
368
+ inst = nil
369
+ begin
370
+ inst = if File.exists?(fname + '.active') && File.exists?(fname + '.active-uuid') && !force
371
+ t = {
372
+ 'CPEE-INSTANCE-URL' => File.read(fname + '.active'),
373
+ 'CPEE-INSTANCE-UUID' => File.read(fname + '.active-uuid')
374
+ }
375
+ status, result, headers = Riddl::Client.new(File.join(t['CPEE-INSTANCE-URL'],'properties','state')).get
376
+
377
+ if status && status >= 200 && status < 300 && (result[0].value == 'finished' || result[0].value == 'abandoned')
378
+ force = true
379
+ raise
380
+ end
381
+ status, result, headers = Riddl::Client.new(File.join(t['CPEE-INSTANCE-URL'],'properties','attributes','uuid')).get
382
+ if status && status >= 200 && status < 300
383
+ t['CPEE-INSTANCE-UUID'] == result[0].value ? t : nil
384
+ else
385
+ nil
386
+ end
387
+ end || begin
388
+ status, result, headers = Riddl::Client.new(File.join(insta,'xml')).post [
389
+ Riddl::Parameter::Simple.new('behavior','fork_ready'),
390
+ Riddl::Parameter::Complex.new('xml','application/xml',File.read(fname))
391
+ ] rescue nil
392
+ if status && status >= 200 && status < 300
393
+ JSON::parse(result[0].value.read).tap do |t|
394
+ File.write(File.join(fname + '.active'),t['CPEE-INSTANCE-URL'])
395
+ File.write(File.join(fname + '.active-uuid'),t['CPEE-INSTANCE-UUID'])
396
+ end
397
+ else
398
+ nil
399
+ end
400
+ end
401
+ rescue
402
+ retry
403
+ end
404
+
405
+ if inst.nil?
406
+ @status = 400
407
+ return Riddl::Parameter::Complex.new('nope','text/plain','No longer exists.')
408
+ else
409
+ insturl = inst['CPEE-INSTANCE-URL']
410
+ @status = 302
411
+ @headers << Riddl::Header.new('Location',cock[stage] + insturl)
412
+ end
413
+ nil
414
+ end
415
+ end #}}}
416
+ class MoveItem < Riddl::Implementation #{{{
417
+ def response
418
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
419
+ conns = @a[1]
420
+ models = @a[2]
421
+
422
+ name = File.basename(@r.last,'.xml')
423
+ to = @p[0].value
424
+
425
+ fname = File.join(models,where,name + '.xml')
426
+ dn = CPEE::ModelManagement::get_dn @h['DN']
427
+ author = dn['GN'] + ' ' + dn['SN']
428
+ if !File.exist?(File.join(models,to,name + '.xml'))
429
+ XML::Smart::modify(fname) do |doc|
430
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
431
+ doc.find('/p:testset/p:attributes/p:design_dir').each do |ele|
432
+ ele.text = to
433
+ end
434
+ end
435
+ File.write(fname + '.author',author)
436
+
437
+ CPEE::ModelManagement::op author, 'mv', models, File.join('.', to, name + '.xml'), File.join('.', where, name + '.xml')
438
+ CPEE::ModelManagement::notify conns, 'move', models, File.join(models,to,name + '.xml'), fname
439
+ end
440
+ end
441
+ end #}}}
442
+ class PutItem < Riddl::Implementation #{{{
443
+ def response
444
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
445
+ conns = @a[1]
446
+ models = @a[2]
447
+ name = File.basename(@r.last,'.xml')
448
+ cont = @p[0].value.read
449
+ dn = CPEE::ModelManagement::get_dn @h['DN']
450
+
451
+ fname = File.join(models,where,name + '.xml')
452
+
453
+ if File.exists?(fname)
454
+ author = dn['GN'] + ' ' + dn['SN']
455
+ XML::Smart.string(cont) do |doc|
456
+ doc.register_namespace 'p', 'http://cpee.org/ns/properties/2.0'
457
+ unless File.exists?(File.join(models,where,name + '.xml.creator'))
458
+ doc.find('/p:testset/p:attributes/p:author').each do |ele|
459
+ File.write(File.join(models,where,name + '.xml.creator'),ele.text)
460
+ end
461
+ end
462
+ doc.find('/p:testset/p:attributes/p:author').each do |ele|
463
+ ele.text = dn['GN'] + ' ' + dn['SN']
464
+ end
465
+ File.write(fname,doc.to_s)
466
+ File.write(fname + '.author',author)
467
+ File.write(fname + '.stage',doc.find('string(/p:testset/p:attributes/p:design_stage)').sub(/^$/,'draft'))
468
+ end
469
+ CPEE::ModelManagement::op author, 'add', models, File.join('.', where, name + '.xml')
470
+ CPEE::ModelManagement::notify conns, 'put', models, fname
471
+ else
472
+ @status = 400
473
+ end
474
+ end
475
+ end #}}}
476
+ class DeleteItem < Riddl::Implementation #{{{
477
+ def response
478
+ where = @a[0] == :main ? '' : Riddl::Protocols::Utils::unescape(@r[-2])
479
+ conns = @a[1]
480
+ models = @a[2]
481
+ name = File.basename(@r.last,'.xml')
482
+ fname = File.join(models,where,name + '.xml')
483
+
484
+ dn = CPEE::ModelManagement::get_dn @h['DN']
485
+ author = dn['GN'] + ' ' + dn['SN']
486
+
487
+ CPEE::ModelManagement::op author, 'rm', models, File.join('.', where, name + '.xml')
488
+ CPEE::ModelManagement::notify conns, 'delete', models, fname
489
+ end
490
+ end #}}}
491
+ class DeleteDir < Riddl::Implementation #{{{
492
+ def response
493
+ conns = @a[0]
494
+ models = @a[1]
495
+ name = File.basename(@r.last,'.dir')
496
+ fname = File.join(models,name + '.dir')
497
+
498
+ dn = CPEE::ModelManagement::get_dn @h['DN']
499
+ author = dn['GN'] + ' ' + dn['SN']
500
+
501
+ CPEE::ModelManagement::op author, 'rm', models, File.join(name + '.dir')
502
+ CPEE::ModelManagement::notify conns, 'delete', models, fname
503
+ end
504
+ end #}}}
505
+
506
+ class Active < Riddl::SSEImplementation #{{{
507
+ def onopen
508
+ @conns = @a[0]
509
+ @conns << self
510
+ end
511
+ def onclose
512
+ @conns.delete(self)
513
+ end
514
+ end #}}}
515
+
516
+ def self::implementation(opts)
517
+ opts[:connections] = []
518
+
519
+ Proc.new do
520
+ on resource do
521
+ run GetList, :main, opts[:views], opts[:models] if get 'stage'
522
+ run GetListFull, opts[:views], opts[:models] if get 'full'
523
+ run GetStages, opts[:themes] if get 'stages'
524
+ run Create, :main, :cre, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'item'
525
+ run Create, :main, :dup, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'duplicate'
526
+ run CreateDir, opts[:connections], opts[:models] if post 'dir'
527
+ run Active, opts[:connections] if sse
528
+ on resource '[a-zA-Z0-9öäüÖÄÜ _-]+\.dir' do
529
+ run GetList, :sub, opts[:views], opts[:models] if get 'stage'
530
+ run Create, :sub, :cre, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'item'
531
+ run Create, :sub, :dup, opts[:views], opts[:connections], opts[:templates], opts[:models] if post 'duplicate'
532
+ run DeleteDir, opts[:connections], opts[:models] if delete
533
+ run RenameDir, opts[:connections], opts[:models] if put 'name'
534
+ on resource '[a-zA-Z0-9öäüÖÄÜ _-]+\.xml' do
535
+ run DeleteItem, :sub, opts[:connections], opts[:models] if delete
536
+ run GetItem, :sub, opts[:models] if get
537
+ run PutItem, :sub, opts[:connections], opts[:models] if put 'content'
538
+ run RenameItem, :sub, opts[:connections], opts[:models] if put 'name'
539
+ run MoveItem, :sub, opts[:connections], opts[:models] if put 'dirname'
540
+ run ShiftItem, :sub, opts[:connections], opts[:themes], opts[:models] if put 'newstage'
541
+ on resource 'open' do
542
+ run OpenItem, :sub, opts[:instantiate], opts[:cockpit], opts[:views], false, opts[:models] if get 'stage'
543
+ end
544
+ on resource 'open-new' do
545
+ run OpenItem, :sub, opts[:instantiate], opts[:cockpit], opts[:views], true, opts[:models] if get 'stage'
546
+ end
547
+ end
548
+ end
549
+ on resource '[a-zA-Z0-9öäüÖÄÜ _-]+\.xml' do
550
+ run DeleteItem, :main, opts[:connections], opts[:models] if delete
551
+ run GetItem, :main, opts[:models] if get
552
+ run PutItem, :main, opts[:connections], opts[:models] if put 'content'
553
+ run RenameItem, :main, opts[:connections], opts[:models] if put 'name'
554
+ run MoveItem, :main, opts[:connections], opts[:models] if put 'dirname'
555
+ run ShiftItem, :main, opts[:connections], opts[:themes], opts[:models] if put 'newstage'
556
+ on resource 'open' do
557
+ run OpenItem, :main, opts[:instantiate], opts[:cockpit], opts[:views], false, opts[:models] if get 'stage'
558
+ end
559
+ on resource 'open-new' do
560
+ run OpenItem, :main, opts[:instantiate], opts[:cockpit], opts[:views], true, opts[:models] if get 'stage'
561
+ end
562
+ end
563
+ end
564
+ end
565
+ end
566
+
567
+ end
568
+ end
@@ -0,0 +1,98 @@
1
+ <description xmlns="http://riddl.org/ns/description/1.0" xmlns:ann="http://riddl.org/ns/annotation/1.0" xmlns:xi="http://www.w3.org/2001/XInclude" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
2
+ <message name="item">
3
+ <parameter name="stage" type="string">
4
+ <xi:include href="stages"/>
5
+ </parameter>
6
+ <parameter name="new" type="string">
7
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
8
+ </parameter>
9
+ </message>
10
+ <message name="name">
11
+ <parameter name="new" type="string">
12
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
13
+ </parameter>
14
+ </message>
15
+ <message name="dir">
16
+ <parameter name="dir" type="string">
17
+ <param name="pattern">([a-zA-Z0-9öäüÖÄÜ _-]+)|</param>
18
+ </parameter>
19
+ </message>
20
+ <message name="dirname">
21
+ <parameter name="dir" type="string">
22
+ <param name="pattern">([a-zA-Z0-9öäüÖÄÜ _-]+)\.dir|</param>
23
+ </parameter>
24
+ </message>
25
+ <message name="duplicate">
26
+ <parameter name="new" type="string">
27
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+</param>
28
+ </parameter>
29
+ <parameter name="old" type="string">
30
+ <param name="pattern">[a-zA-Z0-9öäüÖÄÜ _-]+\.xml</param>
31
+ </parameter>
32
+ </message>
33
+ <message name="stages">
34
+ <parameter name="stages" type="string"/>
35
+ </message>
36
+ <message name="newstage">
37
+ <parameter name="stage" type="string">
38
+ <xi:include href="stages"/>
39
+ </parameter>
40
+ </message>
41
+ <message name="stage">
42
+ <optional>
43
+ <parameter name="stage" type="string">
44
+ <xi:include href="stages"/>
45
+ </parameter>
46
+ </optional>
47
+ </message>
48
+ <message name="full">
49
+ <parameter name="full" type="string"/>
50
+ <optional>
51
+ <parameter name="stage" type="string">
52
+ <xi:include href="stages"/>
53
+ </parameter>
54
+ </optional>
55
+ </message>
56
+ <message name="list">
57
+ <parameter name="list" mimetype="application/json"/>
58
+ </message>
59
+ <message name="content">
60
+ <parameter name="content" mimetype="application/xml"/>
61
+ </message>
62
+ <resource>
63
+ <post in="item"/>
64
+ <post in="dir"/>
65
+ <post in="duplicate"/>
66
+ <get in="stage" out="list"/>
67
+ <get in="full" out="list"/>
68
+ <get in="stages" out="list"/>
69
+ <sse/>
70
+ <resource relative="[a-zA-Z0-9&#xF6;&#xE4;&#xFC;&#xD6;&#xC4;&#xDC; _-]+\.dir">
71
+ <post in="item"/>
72
+ <post in="duplicate"/>
73
+ <get in="stage" out="list"/>
74
+ <delete/>
75
+ <put in="name"/> <!-- rename -->
76
+ <resource relative="[a-zA-Z0-9&#xF6;&#xE4;&#xFC;&#xD6;&#xC4;&#xDC; _-]+\.xml">
77
+ <get out='content'/>
78
+ <delete/>
79
+ <put in="content"/>
80
+ <put in="name"/> <!-- rename -->
81
+ <put in="dirname"/> <!-- move -->
82
+ <put in="newstage"/> <!-- shift -->
83
+ <resource relative="open"><get in="stage"/></resource>
84
+ <resource relative="open-new"><get in="stage"/></resource>
85
+ </resource>
86
+ </resource>
87
+ <resource relative="[a-zA-Z0-9&#xF6;&#xE4;&#xFC;&#xD6;&#xC4;&#xDC; _-]+\.xml">
88
+ <get out='content'/>
89
+ <delete/>
90
+ <put in="content"/>
91
+ <put in="name"/> <!-- rename -->
92
+ <put in="dirname"/> <!-- move -->
93
+ <put in="newstage"/> <!-- shift -->
94
+ <resource relative="open"><get in="stage"/></resource>
95
+ <resource relative="open-new"><get in="stage"/></resource>
96
+ </resource>
97
+ </resource>
98
+ </description>
@@ -0,0 +1,6 @@
1
+ <choice>
2
+ <value>draft</value>
3
+ <value>development</value>
4
+ <value>production</value>
5
+ <value>archive</value>
6
+ </choice>
data/server/model.xml ADDED
@@ -0,0 +1,33 @@
1
+ <testset xmlns="http://cpee.org/ns/properties/2.0">
2
+ <dataelements/>
3
+ <handlerwrapper>DefaultHandlerWrapper</handlerwrapper>
4
+ <endpoints>
5
+ <machine>machine</machine>
6
+ <sensor>sensor</sensor>
7
+ <human>human</human>
8
+ <plc>plc</plc>
9
+ <robot>robot</robot>
10
+ <robot_subprocess>robot_subprocess</robot_subprocess>
11
+ <send>send</send>
12
+ <receive>receive</receive>
13
+ <subprocess>subprocess</subprocess>
14
+ <wait>wait</wait>
15
+ </endpoints>
16
+ <description>
17
+ <description xmlns="http://cpee.org/ns/description/1.0"/>
18
+ </description>
19
+ <transformation>
20
+ <description type="copy"/>
21
+ <dataelements type="none"/>
22
+ <endpoints type="none"/>
23
+ </transformation>
24
+ <attributes>
25
+ <info>none</info>
26
+ <creator>Juergen Mangler</creator>
27
+ <author>Juergen Mangler</author>
28
+ <modeltype>CPEE</modeltype>
29
+ <theme>model</theme>
30
+ <design_dir></design_dir>
31
+ <design_stage>draft</design_stage>
32
+ </attributes>
33
+ </testset>
@@ -0,0 +1,25 @@
1
+ <testset xmlns="http://cpee.org/ns/properties/2.0">
2
+ <dataelements/>
3
+ <handlerwrapper>DefaultHandlerWrapper</handlerwrapper>
4
+ <endpoints>
5
+ <timeout>https://cpee.org/services/timeout.php</timeout>
6
+ <subprocess>https://cpee.org/flow/start/url/</subprocess>
7
+ </endpoints>
8
+ <description>
9
+ <description xmlns="http://cpee.org/ns/description/1.0"/>
10
+ </description>
11
+ <transformation>
12
+ <description type="copy"/>
13
+ <dataelements type="none"/>
14
+ <endpoints type="none"/>
15
+ </transformation>
16
+ <attributes>
17
+ <info>agar</info>
18
+ <creator>Christine Ashcreek</creator>
19
+ <author>Christine Ashcreek</author>
20
+ <modeltype>CPEE</modeltype>
21
+ <theme>extended</theme>
22
+ <design_dir/>
23
+ <design_stage>development</design_stage>
24
+ </attributes>
25
+ </testset>
@@ -0,0 +1 @@
1
+ https://cpee.org/flow/engine/4842
@@ -0,0 +1 @@
1
+ 6945f9e2-105a-4b14-84e6-3a4ca6921e93
@@ -0,0 +1 @@
1
+ Christine Ashcreek
@@ -0,0 +1 @@
1
+ Christine Ashcreek
@@ -0,0 +1 @@
1
+ development
data/server/moma ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/ruby
2
+ require 'rubygems'
3
+ require_relative '../lib/cpee-model-management/implementation'
4
+
5
+ options = {
6
+ :host => 'localhost',
7
+ :port => 9316,
8
+ :secure => false
9
+ }
10
+
11
+ Riddl::Server.new(CPEE::ModelManagement::SERVER, options) do |opts|
12
+ accessible_description true
13
+ cross_site_xhr true
14
+
15
+ use CPEE::ModelManagement::implementation(opts)
16
+ end.loop!
data/server/moma.conf ADDED
@@ -0,0 +1,20 @@
1
+ :port: 9316
2
+ :models: models
3
+ :instantiate: https://cpee.org/flow/start/
4
+ :cockpit:
5
+ draft: https://cpee.org/flow/model.html?monitor=
6
+ development: https://cpee.org/flow/edit.html?monitor=
7
+ production: https://cpee.org/flow/track.html?monitor=
8
+ archive: https://cpee.org/flow/edit.html?monitor=
9
+ :views:
10
+ production: development
11
+ :templates:
12
+ draft: model.xml
13
+ development: testset.xml
14
+ production: testset.xml
15
+ archive: testset.xml
16
+ :themes:
17
+ draft: model
18
+ development: extended
19
+ production: extended
20
+ archive: extended
@@ -0,0 +1,25 @@
1
+ <testset xmlns="http://cpee.org/ns/properties/2.0">
2
+ <dataelements/>
3
+ <handlerwrapper>DefaultHandlerWrapper</handlerwrapper>
4
+ <endpoints>
5
+ <timeout>https://cpee.org/services/timeout.php</timeout>
6
+ <subprocess>https://cpee.org/flow/start/url/</subprocess>
7
+ </endpoints>
8
+ <description>
9
+ <description xmlns="http://cpee.org/ns/description/1.0"/>
10
+ </description>
11
+ <transformation>
12
+ <description type="copy"/>
13
+ <dataelements type="none"/>
14
+ <endpoints type="none"/>
15
+ </transformation>
16
+ <attributes>
17
+ <info>none</info>
18
+ <creator>Juergen Mangler</creator>
19
+ <author>Juergen Mangler</author>
20
+ <modeltype>CPEE</modeltype>
21
+ <theme>extended</theme>
22
+ <design_dir></design_dir>
23
+ <design_stage>draft</design_stage>
24
+ </attributes>
25
+ </testset>
data/tools/cpee-moma ADDED
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/ruby
2
+ curpath = __dir__
3
+ require 'rubygems'
4
+ require 'optparse'
5
+ require 'fileutils'
6
+ require 'xml/smart'
7
+ require 'zip'
8
+
9
+ def wrap(s, width=78, indent=18)
10
+ lines = []
11
+ line, s = s[0..indent-2], s[indent..-1]
12
+ s.split(/\n/).each do |ss|
13
+ ss.split(/[ \t]+/).each do |word|
14
+ if line.size + word.size >= width
15
+ lines << line
16
+ line = (" " * (indent)) + word
17
+ else
18
+ line << " " << word
19
+ end
20
+ end
21
+ lines << line if line
22
+ line = (" " * (indent-1))
23
+ end
24
+ return lines.join "\n"
25
+ end
26
+
27
+ ARGV.options { |opt|
28
+ opt.summary_indent = ' ' * 2
29
+ opt.summary_width = 15
30
+ opt.banner = "Usage:\n#{opt.summary_indent}#{File.basename($0)} [options] convert | cpui DIR | new DIR\n"
31
+ opt.on("Options:")
32
+ opt.on("--help", "-h", "This text") { puts opt; exit }
33
+ opt.on("")
34
+ opt.on(wrap("[new DIR] scaffolds a sample design server."))
35
+ opt.on("")
36
+ opt.on(wrap("[cpui DIR] scaffolds a sample html client. New versions might require manual merging if you changed something."))
37
+ opt.on("")
38
+ opt.on(wrap("[convert] converts all testsets in the current directory to design terminology."))
39
+ opt.parse!
40
+ }
41
+ if (ARGV.length == 0) ||
42
+ (ARGV.length == 1 && !(%w(convert).include?(ARGV[0]))) ||
43
+ (ARGV.length == 2 && !(%w(cpui new).include?(ARGV[0]))) ||
44
+ (ARGV.length > 2)
45
+ puts ARGV.options
46
+ exit
47
+ end
48
+ command = ARGV[0]
49
+ p1 = ARGV[1]
50
+ p2 = ARGV[2]
51
+ ui = "#{curpath}/../ui/"
52
+
53
+ if command == 'cpui'
54
+ if !File.exists?(p1)
55
+ FileUtils.cp_r(ui,p1)
56
+ else
57
+ FileUtils.cp_r(Dir.glob(File.join(ui,'*')),p1,remove_destination: true)
58
+ puts "Directory already exists, updating ..."
59
+ end
60
+ js_libs(p1)
61
+ elsif command == 'convert'
62
+ Dir['*.xml'].each do |f|
63
+ XML::Smart.modify(f) do |doc|
64
+ doc.register_namespace 'x', 'http://cpee.org/ns/properties/2.0'
65
+ if doc.root.qname.name == 'testset'
66
+ name = File.basename(f,'.xml')
67
+ creator = author = design_dir = design_stage = nil
68
+
69
+ if (dt = doc.find('/x:testset/x:attributes/x:creator')).length > 0
70
+ dt.each do |e|
71
+ creator = e.text
72
+ end
73
+ else
74
+ creator = 'Christine Ashcreek'
75
+ doc.find('/x:testset/x:attributes').each do |e|
76
+ e.add('x:creator',creator)
77
+ end
78
+ end
79
+ File.write(f + '.creator',creator)
80
+
81
+ if (dt = doc.find('/x:testset/x:attributes/x:author')).length > 0
82
+ dt.each do |e|
83
+ author = e.text
84
+ end
85
+ else
86
+ author = 'Christine Ashcreek'
87
+ doc.find('/x:testset/x:attributes').each do |e|
88
+ e.add('x:author',author)
89
+ end
90
+ end
91
+ File.write(f + '.author',author)
92
+
93
+ if (dt = doc.find('/x:testset/x:attributes/x:design_stage')).length > 0
94
+ dt.each do |e|
95
+ design_stage = e.text
96
+ end
97
+ else
98
+ design_stage = 'development'
99
+ doc.find('/x:testset/x:attributes').each do |e|
100
+ e.add('x:design_stage',design_stage)
101
+ end
102
+ end
103
+ File.write(f + '.stage',design_stage)
104
+
105
+ if (dt = doc.find('/x:testset/x:attributes/x:design_dir')).length > 0
106
+ dt.each do |e|
107
+ design_dir = e.text
108
+ end
109
+ else
110
+ design_dir = Dir.pwd.sub(/^.*?models\/?/,'')
111
+ doc.find('/x:testset/x:attributes').each do |e|
112
+ e.add('x:design_dir',design_dir)
113
+ end
114
+ end
115
+
116
+ if (dt = doc.find('/x:testset/x:attributes/x:info')).length > 0
117
+ dt.each do |e|
118
+ e.text = name
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
124
+ elsif command == 'new'
125
+ if !File.exists?(p1)
126
+ FileUtils.mkdir(File.join(p1)) rescue nil
127
+ FileUtils.cp_r("#{curpath}/../server/moma",p1) unless File.exists?(File.join('p1','moma'))
128
+ FileUtils.cp_r("#{curpath}/../server/moma.conf",p1) unless File.exists?(File.join('p1','moma.conf'))
129
+ FileUtils.cp_r("#{curpath}/../server/testset.xml",p1) unless File.exists?(File.join('p1','testset.xml'))
130
+ FileUtils.cp_r("#{curpath}/../server/model.xml",p1) unless File.exists?(File.join('p1','model.xml'))
131
+ FileUtils.mkdir(File.join(p1,'models')) rescue nil
132
+ else
133
+ puts 'Directory already exists.'
134
+ end
135
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cpee-model-management
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Juergen eTM Mangler
8
+ autorequire:
9
+ bindir: tools
10
+ cert_chain: []
11
+ date: 2021-03-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: riddl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.99'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.99'
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
41
+ description: see http://cpee.org
42
+ email: juergen.mangler@gmail.com
43
+ executables:
44
+ - cpee-moma
45
+ extensions: []
46
+ extra_rdoc_files:
47
+ - README.md
48
+ files:
49
+ - AUTHORS
50
+ - LICENSE
51
+ - README.md
52
+ - Rakefile
53
+ - cpee-model-management.gemspec
54
+ - lib/cpee-model-management/implementation.rb
55
+ - lib/cpee-model-management/moma.xml
56
+ - lib/cpee-model-management/stages
57
+ - server/model.xml
58
+ - server/models/agar.xml
59
+ - server/models/agar.xml.active
60
+ - server/models/agar.xml.active-uuid
61
+ - server/models/agar.xml.author
62
+ - server/models/agar.xml.creator
63
+ - server/models/agar.xml.stage
64
+ - server/moma
65
+ - server/moma.conf
66
+ - server/testset.xml
67
+ - tools/cpee-moma
68
+ homepage: http://cpee.org/
69
+ licenses:
70
+ - LGPL-3.0
71
+ metadata: {}
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 2.7.0
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.1.4
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: "(Lifecycle) manage your process models in a directory or git repo."
91
+ test_files: []