wortsammler 1.0.3 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +46 -4
- data/.gitpod.Dockerfile +32 -0
- data/.gitpod.yml +1 -0
- data/.idea/.name +1 -0
- data/.idea/.rakeTasks +7 -0
- data/.idea/202_wortsammler-gem.iml +119 -0
- data/.idea/compiler.xml +22 -0
- data/.idea/encodings.xml +6 -0
- data/.idea/inspectionProfiles/profiles_settings.xml +7 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +9 -0
- data/.idea/vcs.xml +7 -0
- data/Gemfile +1 -0
- data/README.md +25 -28
- data/Rakefile +3 -3
- data/changelog.md +17 -1
- data/lib/wortsammler.rb +61 -54
- data/lib/wortsammler/class.Traceable.md.rb +9 -7
- data/lib/wortsammler/class.Traceable.rb +74 -60
- data/lib/wortsammler/class.proolib.rb +1102 -982
- data/lib/wortsammler/mdTraceParser.treetop +2 -2
- data/lib/wortsammler/version.rb +1 -1
- data/resources/default.wortsammler.latex +4 -3
- data/resources/main.md +1 -1
- data/resources/pandocdefault.docx +0 -0
- data/resources/pandocdefault.epub +70 -0
- data/resources/pandocdefault.html +73 -0
- data/resources/pandocdefault.latex +403 -0
- data/resources/sample_the-sample-document.yaml +27 -1
- data/spec/TC_EXP_001.md +2 -1
- data/spec/Zupfnoter.jpg +0 -0
- data/spec/tc_exp_003_reference.txt +14 -29
- data/spec/test_beautify.md +13 -1
- data/spec/test_beautify_reference.md +17 -3
- data/spec/test_mkindex_reference.txt +9 -38
- data/spec/test_slides.md +38 -0
- data/spec/wortsammler_spec.rb +186 -150
- data/testproject.xx/30_Sources/001_Main/main.md +273 -0
- data/testproject.xx/30_Sources/900_snippets/snippets.xlsx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.docx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.html +145 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.latex +416 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_compact.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.beamer.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.docx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.html +145 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.latex +416 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_folien.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.docx +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.html +145 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.latex +416 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_mieter.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_review.latex +582 -0
- data/testproject.xx/30_Sources/ZGEN_Documents/RS_Main_review.pdf +0 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/RS_Main.traces.md +56 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/ZGEN_Reqtrace.graphml +119 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/ZGEN_Reqtrace.md +50 -0
- data/testproject.xx/30_Sources/ZGEN_RequirementsTracing/ZGEN_ReqtraceCompare.txt +52 -0
- data/testproject.xx/30_Sources/ZSUPP_Manifests/sample_the-sample-document.yaml +79 -0
- data/testproject.xx/30_Sources/ZSUPP_Styles/default.wortsammler.latex +321 -0
- data/testproject.xx/30_Sources/ZSUPP_Styles/logo.jpg +0 -0
- data/testproject.xx/30_Sources/ZSUPP_Tools/rakefile.rb +5 -0
- data/testresults/wortsammler_testresults.html +49 -466
- data/uninstall-pandoc.pl +79 -0
- data/wortsammler.gemspec +7 -4
- metadata +84 -14
- data/testresults/wortsammler_testresults.log +0 -325
- data/wortsammler-gem.sublime-project +0 -8
data/lib/wortsammler.rb
CHANGED
@@ -33,8 +33,8 @@ module Wortsammler
|
|
33
33
|
if options[:version] then
|
34
34
|
puts "this is #{Wortsammler::PROGNAME} version #{Wortsammler::VERSION}\n"
|
35
35
|
|
36
|
-
pandoc
|
37
|
-
xetex
|
36
|
+
pandoc=`#{PANDOC_EXE} -v`.split("\n")[0] rescue pandoc="error running pandoc"
|
37
|
+
xetex=`#{LATEX_EXE} -v`.split("\n")[0] rescue pandoc="error running xelatex"
|
38
38
|
|
39
39
|
$log.info "found #{pandoc}"
|
40
40
|
$log.info "found #{xetex}"
|
@@ -43,7 +43,7 @@ module Wortsammler
|
|
43
43
|
|
44
44
|
l= "-----------------"
|
45
45
|
$log.info l
|
46
|
-
options.each {|k,v| $log.info "#{k}: #{v}"}
|
46
|
+
options.each { |k, v| $log.info "#{k}: #{v}" }
|
47
47
|
$log.info l
|
48
48
|
end
|
49
49
|
|
@@ -61,11 +61,11 @@ module Wortsammler
|
|
61
61
|
|
62
62
|
##
|
63
63
|
#
|
64
|
-
# load the manifest
|
64
|
+
# load the manifest or use default configuration
|
65
65
|
#
|
66
|
-
config=
|
66
|
+
config = ProoConfig.new();
|
67
67
|
if config_file=options[:manifest] then
|
68
|
-
config
|
68
|
+
config.load_from_file(config_file)
|
69
69
|
end
|
70
70
|
|
71
71
|
##
|
@@ -78,7 +78,7 @@ module Wortsammler
|
|
78
78
|
$log.error "path does not exist path '#{inputpath}'"
|
79
79
|
exit(false)
|
80
80
|
end
|
81
|
-
if File.file?(inputpath)
|
81
|
+
if File.file?(inputpath) #(RS_Mdc)
|
82
82
|
input_files=[inputpath]
|
83
83
|
elsif File.exists?(inputpath)
|
84
84
|
input_files=Dir["#{inputpath}/**/*.md", "#{inputpath}/**/*.markdown", "#{inputpath}/**/*.plantuml"]
|
@@ -93,17 +93,14 @@ module Wortsammler
|
|
93
93
|
|
94
94
|
if options[:beautify]
|
95
95
|
|
96
|
-
|
97
96
|
# process path
|
98
|
-
|
99
97
|
if input_files then
|
100
|
-
Wortsammler.beautify(input_files)
|
98
|
+
Wortsammler.beautify(input_files, config)
|
101
99
|
end
|
102
100
|
|
103
101
|
# process manifest
|
104
|
-
|
105
|
-
|
106
|
-
Wortsammler.beautify(config.input)
|
102
|
+
if config.input then
|
103
|
+
Wortsammler.beautify(config.input, config)
|
107
104
|
end
|
108
105
|
|
109
106
|
unless input_files or config
|
@@ -119,27 +116,24 @@ module Wortsammler
|
|
119
116
|
|
120
117
|
if options[:plantuml]
|
121
118
|
|
122
|
-
|
123
119
|
# process path
|
124
|
-
|
125
120
|
if input_files then
|
126
121
|
Wortsammler.plantuml(input_files)
|
127
122
|
end
|
128
123
|
|
129
124
|
# process manifest
|
130
125
|
|
131
|
-
if config then
|
126
|
+
if config.input then
|
132
127
|
Wortsammler.plantuml(config.input)
|
133
128
|
end
|
134
129
|
|
135
|
-
unless input_files or config
|
130
|
+
unless input_files or config.input
|
136
131
|
$log.error "no input specified. Please use -m or -i to specify input"
|
137
132
|
exit false
|
138
133
|
end
|
139
134
|
end
|
140
135
|
|
141
136
|
|
142
|
-
|
143
137
|
##
|
144
138
|
# process collect in markdown files
|
145
139
|
#
|
@@ -154,18 +148,17 @@ module Wortsammler
|
|
154
148
|
|
155
149
|
# collect by manifest
|
156
150
|
|
157
|
-
if config then
|
151
|
+
if config.input then
|
158
152
|
Wortsammler.collect_traces(config)
|
159
153
|
end
|
160
154
|
|
161
|
-
unless input_files or config
|
155
|
+
unless input_files or config.input
|
162
156
|
$log.error "no input specified. Please use -m or -i to specify input"
|
163
157
|
exit false
|
164
158
|
end
|
165
159
|
end
|
166
160
|
|
167
161
|
|
168
|
-
|
169
162
|
##
|
170
163
|
# process files
|
171
164
|
#
|
@@ -189,12 +182,12 @@ module Wortsammler
|
|
189
182
|
FileUtils.mkdir_p(outputfolder)
|
190
183
|
end
|
191
184
|
|
192
|
-
input_files.each{|f| Wortsammler.render_single_document(f, outputfolder, outputformats)}
|
185
|
+
input_files.each { |f| Wortsammler.render_single_document(f, outputfolder, outputformats, config) }
|
193
186
|
end
|
194
187
|
|
195
188
|
# collect by manifest
|
196
189
|
|
197
|
-
if config then
|
190
|
+
if config.input then
|
198
191
|
Wortsammler.process(config)
|
199
192
|
end
|
200
193
|
|
@@ -205,19 +198,23 @@ module Wortsammler
|
|
205
198
|
end
|
206
199
|
|
207
200
|
nil
|
208
|
-
end
|
201
|
+
end
|
202
|
+
|
203
|
+
#execute
|
209
204
|
|
210
205
|
|
211
206
|
#
|
212
207
|
# beautify a list of Documents
|
213
208
|
# @param paths [Array of String] Array of filenames which shall be cleaned.
|
209
|
+
# @param [ProoConfig] config
|
214
210
|
#
|
215
211
|
# @return [Nil] no return
|
216
|
-
def self.beautify(paths)
|
212
|
+
def self.beautify(paths, config=nil)
|
217
213
|
|
218
214
|
cleaner = PandocBeautifier.new($log)
|
215
|
+
cleaner.config = config if config
|
219
216
|
|
220
|
-
paths.each{|f| cleaner.beautify(f)}
|
217
|
+
paths.each { |f| cleaner.beautify(f) }
|
221
218
|
nil
|
222
219
|
end
|
223
220
|
|
@@ -225,16 +222,16 @@ module Wortsammler
|
|
225
222
|
#
|
226
223
|
# plantuml a list of Documents
|
227
224
|
# @param paths [Array of String] Array of filenames which shall be converted.
|
225
|
+
# @param [ProoConfig] config
|
228
226
|
#
|
229
227
|
# @return [Nil] no return
|
230
228
|
def self.plantuml(paths)
|
231
229
|
|
232
|
-
cleaner = PandocBeautifier.new($log)
|
233
230
|
plantumljar=File.dirname(__FILE__)+"/../resources/plantuml.jar"
|
234
231
|
|
235
|
-
paths.each{|f|
|
236
|
-
cmd
|
237
|
-
r=`#{cmd}`
|
232
|
+
paths.each { |f|
|
233
|
+
cmd = "java -jar \"#{plantumljar}\" -v \"#{f}\" 2>&1"
|
234
|
+
r =`#{cmd}`
|
238
235
|
no_of_images = r.split($/).grep(/Number of image/).first.split(":")[1]
|
239
236
|
|
240
237
|
$log.info("#{no_of_images} uml diagram(s) in #{File.basename(f)}")
|
@@ -245,13 +242,14 @@ module Wortsammler
|
|
245
242
|
|
246
243
|
|
247
244
|
#
|
248
|
-
# process the documents according to the
|
245
|
+
# process the documents according to the manifest
|
249
246
|
#
|
250
247
|
# @param config [ProoConfig] A configuration object representing the manifest.
|
251
248
|
#
|
252
249
|
# @return [Nil] no return
|
253
250
|
def self.process(config)
|
254
251
|
cleaner = PandocBeautifier.new($log)
|
252
|
+
cleaner.config = config
|
255
253
|
|
256
254
|
cleaner.generateDocument(config.input,
|
257
255
|
config.outdir,
|
@@ -272,13 +270,15 @@ module Wortsammler
|
|
272
270
|
# render a single document
|
273
271
|
# @param filename [String] The filename of the document file which shall be rendered
|
274
272
|
# @param outputfolder [String] The path to the outputfolder where the output files shall be placed.
|
273
|
+
# @param [ProoConfig] config
|
275
274
|
#
|
276
275
|
#
|
277
276
|
# @param outputformats [Array of String] The list of formats which shall be produced
|
278
277
|
#
|
279
278
|
# @return [Nil] no return
|
280
|
-
def self.render_single_document(filename, outputfolder, outputformats)
|
279
|
+
def self.render_single_document(filename, outputfolder, outputformats, config=nil)
|
281
280
|
cleaner = PandocBeautifier.new($log)
|
281
|
+
cleaner.config = config if config
|
282
282
|
cleaner.render_single_document(filename, outputfolder, outputformats)
|
283
283
|
nil
|
284
284
|
end
|
@@ -299,14 +299,14 @@ module Wortsammler
|
|
299
299
|
"ZGEN_RequirementsTracing",
|
300
300
|
"001_Main",
|
301
301
|
"900_snippets"
|
302
|
-
|
302
|
+
]
|
303
303
|
|
304
|
-
folders.each{|folder|
|
304
|
+
folders.each { |folder|
|
305
305
|
FileUtils.mkdir_p("#{root}/#{folder}")
|
306
306
|
}
|
307
307
|
|
308
308
|
resourcedir=File.dirname(__FILE__)+"/../resources"
|
309
|
-
Dir["#{resourcedir}/*.yaml"].each{|f|
|
309
|
+
Dir["#{resourcedir}/*.yaml"].each { |f|
|
310
310
|
FileUtils.cp(f, "#{root}/ZSUPP_Manifests")
|
311
311
|
}
|
312
312
|
FileUtils.cp("#{resourcedir}/main.md", "#{root}/001_Main")
|
@@ -326,17 +326,17 @@ module Wortsammler
|
|
326
326
|
# @return [Nil] no return
|
327
327
|
def self.collect_traces(config)
|
328
328
|
|
329
|
-
files
|
330
|
-
rootdir = config.rootdir
|
329
|
+
files = config.input # get the input files
|
330
|
+
rootdir = config.rootdir # get the root directory
|
331
331
|
|
332
332
|
downstream_tracefile = config.downstream_tracefile # String to save downstram filenames
|
333
|
-
reqtracefile_base
|
334
|
-
upstream_tracefiles
|
333
|
+
reqtracefile_base = config.reqtracefile_base # string to determine the requirements tracing results
|
334
|
+
upstream_tracefiles = config.upstream_tracefiles # String to read upstream tracefiles
|
335
335
|
|
336
336
|
traceable_set = TraceableSet.new
|
337
337
|
|
338
338
|
# collect all traceables in input
|
339
|
-
files.each{|f|
|
339
|
+
files.each { |f|
|
340
340
|
x=TraceableSet.processTracesInMdFile(f)
|
341
341
|
traceable_set.merge(x)
|
342
342
|
}
|
@@ -345,7 +345,7 @@ module Wortsammler
|
|
345
345
|
#
|
346
346
|
upstream_traceable_set=TraceableSet.new
|
347
347
|
unless upstream_tracefiles.nil?
|
348
|
-
upstream_tracefiles.each{|f|
|
348
|
+
upstream_tracefiles.each { |f|
|
349
349
|
x=TraceableSet.processTracesInMdFile(f)
|
350
350
|
upstream_traceable_set.merge(x)
|
351
351
|
}
|
@@ -363,20 +363,20 @@ module Wortsammler
|
|
363
363
|
duplicates=all_traceable_set.duplicate_traces
|
364
364
|
if duplicates.count > 0
|
365
365
|
$log.warn "duplicated trace ids found:"
|
366
|
-
duplicates.each{|d| d.each{|t| $log.warn "#{t.id} in #{t.info}"}}
|
366
|
+
duplicates.each { |d| d.each { |t| $log.warn "#{t.id} in #{t.info}" } }
|
367
367
|
end
|
368
368
|
|
369
369
|
# write traceables to the intermediate Tracing file
|
370
|
-
outname="#{rootdir}/#{reqtracefile_base}.md"
|
370
|
+
outname ="#{rootdir}/#{reqtracefile_base}.md"
|
371
371
|
|
372
372
|
# poke ths sort order for the traceables
|
373
373
|
all_traceable_set.sort_order=config.traceSortOrder if config.traceSortOrder
|
374
|
-
traceable_set.sort_order=config.traceSortOrder if config.traceSortOrder
|
374
|
+
traceable_set.sort_order =config.traceSortOrder if config.traceSortOrder
|
375
375
|
# generate synopsis of traceableruby 1.8.7 garbage at end of file
|
376
376
|
|
377
377
|
|
378
|
-
tracelist=""
|
379
|
-
File.open(outname, "w"){|fx|
|
378
|
+
tracelist =""
|
379
|
+
File.open(outname, "w") { |fx|
|
380
380
|
fx.puts ""
|
381
381
|
fx.puts "\\clearpage"
|
382
382
|
fx.puts ""
|
@@ -389,14 +389,14 @@ module Wortsammler
|
|
389
389
|
# output the graphxml
|
390
390
|
# write traceables to the intermediate Tracing file
|
391
391
|
outname="#{rootdir}/#{reqtracefile_base}.graphml"
|
392
|
-
File.open(outname, "w") {|fx| fx.puts all_traceable_set.to_graphml}
|
392
|
+
File.open(outname, "w") { |fx| fx.puts all_traceable_set.to_graphml }
|
393
393
|
|
394
394
|
outname="#{rootdir}/#{reqtracefile_base}Compare.txt"
|
395
|
-
File.open(outname, "w") {|fx| fx.puts traceable_set.to_compareEntries}
|
395
|
+
File.open(outname, "w") { |fx| fx.puts traceable_set.to_compareEntries }
|
396
396
|
|
397
397
|
# write the downstream_trace file - to be included in downstream - speciifcations
|
398
398
|
outname="#{rootdir}/#{downstream_tracefile}"
|
399
|
-
File.open(outname, "w") {|fx|
|
399
|
+
File.open(outname, "w") { |fx|
|
400
400
|
fx.puts ""
|
401
401
|
fx.puts "\\clearpage"
|
402
402
|
fx.puts ""
|
@@ -407,7 +407,7 @@ module Wortsammler
|
|
407
407
|
|
408
408
|
|
409
409
|
# now add the upstream traces to input
|
410
|
-
files.concat(
|
410
|
+
files.concat(upstream_tracefiles) unless upstream_tracefiles.nil?
|
411
411
|
|
412
412
|
nil
|
413
413
|
end
|
@@ -419,6 +419,14 @@ module Wortsammler
|
|
419
419
|
#
|
420
420
|
# @return [Boolean] true if successful. otherwise exits the program
|
421
421
|
def self.verify_options(options)
|
422
|
+
|
423
|
+
if options[:process] or options[:beautify] or options[:coollect] then
|
424
|
+
unless options[:inputpath] or options[:manifest] then
|
425
|
+
$log.error "no input specified"
|
426
|
+
exit false
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
422
430
|
if options[:inputpath] or options[:manifest] then
|
423
431
|
unless options[:process] or options[:beautify] or options[:collect] or options[:plantuml] then
|
424
432
|
$log.error "no procesing option (p, b, c, u) specified"
|
@@ -428,10 +436,10 @@ module Wortsammler
|
|
428
436
|
|
429
437
|
unless options[:outputfolder] then
|
430
438
|
outputfolder="."
|
431
|
-
inputpath=options[:inputpath]
|
439
|
+
inputpath =options[:inputpath]
|
432
440
|
unless inputpath.nil? then
|
433
|
-
outputfolder = inputpath
|
434
|
-
outputfolder = File.dirname(inputpath)
|
441
|
+
outputfolder = inputpath if File.directory?(inputpath)
|
442
|
+
outputfolder = File.dirname(inputpath) if File.file?(inputpath)
|
435
443
|
end
|
436
444
|
options[:outputfolder] = outputfolder
|
437
445
|
end
|
@@ -447,5 +455,4 @@ module Wortsammler
|
|
447
455
|
end #verify_options
|
448
456
|
|
449
457
|
|
450
|
-
|
451
458
|
end # module
|
@@ -13,6 +13,10 @@ Treetop.load File.dirname(__FILE__) + "/mdTraceParser.treetop"
|
|
13
13
|
class TraceableSet
|
14
14
|
|
15
15
|
|
16
|
+
def mk_hyperlink(id)
|
17
|
+
idm = id.gsub("_","-")
|
18
|
+
"[\[#{id}\]](#RT-#{idm})"
|
19
|
+
end
|
16
20
|
|
17
21
|
# this generates a synopsis of traces in markdown Format
|
18
22
|
# @param [Symbol] selectedCategory the the category of the Traceables
|
@@ -23,20 +27,18 @@ class TraceableSet
|
|
23
27
|
map{|t|
|
24
28
|
tidm=t.id.gsub("_","-")
|
25
29
|
|
26
|
-
lContributes=t.contributes_to.
|
27
|
-
|
28
|
-
map{|c| cm=c.gsub("_","-"); "<a href=\"#RT-#{cm}\">\[#{c}\]</a>"}
|
30
|
+
lContributes = t.contributes_to.
|
31
|
+
map { |c| mk_hyperlink(c) }
|
29
32
|
|
30
33
|
luptraces = [uptrace_ids[t.id]].flatten.compact.map{|x| self[x]}
|
31
34
|
|
32
35
|
luptraces=luptraces.
|
33
36
|
sort_by{|x| trace_order_index(x.id)}.
|
34
37
|
map{|u|
|
35
|
-
|
36
|
-
" - <a href=\"#RT-#{um}\">[#{u.id}]</a> #{u.header_orig}"
|
38
|
+
" - #{mk_hyperlink(u.id)} #{u.header_orig}"
|
37
39
|
}
|
38
40
|
|
39
|
-
["-
|
41
|
+
["- #{mk_hyperlink(t.id)} <!-- --> <a id=\"RT-#{tidm}\"/>**#{t.header_orig}**" +
|
40
42
|
# " (#{t.contributes_to.join(', ')})", "",
|
41
43
|
" (#{lContributes.join(', ')})", "",
|
42
44
|
luptraces
|
@@ -50,7 +52,7 @@ class TraceableSet
|
|
50
52
|
all_traces(selectedCategory).
|
51
53
|
sort_by{|x| trace_order_index(x.id) }.
|
52
54
|
map{|t|
|
53
|
-
"\n\n[#{t.id}] **#{t.header_orig}** { }()"
|
55
|
+
"\n\n\\[#{t.id}\\] **#{t.header_orig}** { }()"
|
54
56
|
}.join("\n\n")
|
55
57
|
end
|
56
58
|
|
@@ -23,16 +23,16 @@ class TraceableSet
|
|
23
23
|
# @return [type] [description]
|
24
24
|
def initialize()
|
25
25
|
# the traces
|
26
|
-
@traces={}
|
26
|
+
@traces = {}
|
27
27
|
|
28
28
|
# the list of supporters
|
29
29
|
# supporters for foo 0 @@supported_by["foo"]
|
30
|
-
@supported_by={}
|
30
|
+
@supported_by = {}
|
31
31
|
|
32
32
|
|
33
33
|
# define the sort order policy
|
34
34
|
# it is the same for all slots
|
35
|
-
@sortOrder=[]
|
35
|
+
@sortOrder = []
|
36
36
|
|
37
37
|
end
|
38
38
|
|
@@ -63,7 +63,7 @@ class TraceableSet
|
|
63
63
|
# @param category [Symbol] Restrict the comparison to a particlar category
|
64
64
|
#
|
65
65
|
# @return [Array] the ids of the added traces (list of trace_id which are not in @referece_set)
|
66
|
-
def added_trace_ids(reference_set, category=nil)
|
66
|
+
def added_trace_ids(reference_set, category = nil)
|
67
67
|
self.all_trace_ids(category) - reference_set.all_trace_ids(category)
|
68
68
|
end
|
69
69
|
|
@@ -74,9 +74,9 @@ class TraceableSet
|
|
74
74
|
# @param category [Symbol] Restrict the operation to traceables of this category.
|
75
75
|
#
|
76
76
|
# @return [Array] List of trace_id which changed not in reference_set
|
77
|
-
def changed_trace_ids(reference_set, category=nil)
|
78
|
-
candidates=self.all_trace_ids(category) & reference_set.all_trace_ids(category)
|
79
|
-
candidates.map{|candidate|
|
77
|
+
def changed_trace_ids(reference_set, category = nil)
|
78
|
+
candidates = self.all_trace_ids(category) & reference_set.all_trace_ids(category)
|
79
|
+
candidates.map { |candidate|
|
80
80
|
self[candidate].get_diff(reference_set[candidate])
|
81
81
|
}.compact
|
82
82
|
end
|
@@ -87,9 +87,9 @@ class TraceableSet
|
|
87
87
|
# @param category [Symbol] Restrict the operation to traceables of this category.
|
88
88
|
#
|
89
89
|
# @return [Array] List of trace_id which unchanged
|
90
|
-
def unchanged_trace_ids(reference_set, category=nil)
|
91
|
-
candidates=self.all_trace_ids(category) & reference_set.all_trace_ids(category)
|
92
|
-
candidates.select{|candidate|
|
90
|
+
def unchanged_trace_ids(reference_set, category = nil)
|
91
|
+
candidates = self.all_trace_ids(category) & reference_set.all_trace_ids(category)
|
92
|
+
candidates.select { |candidate|
|
93
93
|
self[candidate].get_diff(reference_set[candidate]).nil?
|
94
94
|
}.compact
|
95
95
|
end
|
@@ -101,7 +101,7 @@ class TraceableSet
|
|
101
101
|
# @param category [Symbol] Restrict the operation to traceables of this category.
|
102
102
|
#
|
103
103
|
# @return [Array] List of trace_id which are deleted (not in current set)
|
104
|
-
def deleted_trace_ids(reference_set, category=nil)
|
104
|
+
def deleted_trace_ids(reference_set, category = nil)
|
105
105
|
reference_set.all_trace_ids(category) - self.all_trace_ids(category)
|
106
106
|
end
|
107
107
|
|
@@ -109,31 +109,31 @@ class TraceableSet
|
|
109
109
|
# export the trace as graphml for yed
|
110
110
|
# @return - the requirements tree in graphml
|
111
111
|
def to_graphml
|
112
|
-
f
|
112
|
+
f = File.open("#{File.dirname(__FILE__)}/../../resources/requirementsSynopsis.graphml")
|
113
113
|
doc = Nokogiri::XML(f)
|
114
114
|
f.close
|
115
115
|
|
116
|
-
graph=doc.xpath("//xmlns:graph").first
|
116
|
+
graph = doc.xpath("//xmlns:graph").first
|
117
117
|
|
118
118
|
# generate all nodes
|
119
|
-
self.all_traces(nil).each{|theTrace|
|
120
|
-
n_node
|
121
|
-
n_node["id"]
|
122
|
-
n_data
|
123
|
-
n_data["key"]= "d6"
|
124
|
-
n_ShapeNode
|
125
|
-
n_NodeLabel
|
119
|
+
self.all_traces(nil).each { |theTrace|
|
120
|
+
n_node = Nokogiri::XML::Node.new "node", doc
|
121
|
+
n_node["id"] = theTrace.id
|
122
|
+
n_data = Nokogiri::XML::Node.new "data", doc
|
123
|
+
n_data["key"] = "d6"
|
124
|
+
n_ShapeNode = Nokogiri::XML::Node.new "y:ShapeNode", doc
|
125
|
+
n_NodeLabel = Nokogiri::XML::Node.new "y:NodeLabel", doc
|
126
126
|
n_NodeLabel.content = "[#{theTrace.id}] #{theTrace.header_orig}"
|
127
127
|
n_ShapeNode << n_NodeLabel
|
128
128
|
n_data << n_ShapeNode
|
129
129
|
n_node << n_data
|
130
130
|
graph << n_node
|
131
131
|
|
132
|
-
theTrace.contributes_to.each{|up|
|
133
|
-
n_edge=Nokogiri::XML::Node.new "edge", doc
|
134
|
-
n_edge["source"
|
135
|
-
n_edge["target"
|
136
|
-
n_edge["id"
|
132
|
+
theTrace.contributes_to.each { |up|
|
133
|
+
n_edge = Nokogiri::XML::Node.new "edge", doc
|
134
|
+
n_edge["source"] = theTrace.id
|
135
|
+
n_edge["target"] = up
|
136
|
+
n_edge["id"] = "#{up}_#{theTrace.id}"
|
137
137
|
graph << n_edge
|
138
138
|
}
|
139
139
|
}
|
@@ -146,7 +146,7 @@ class TraceableSet
|
|
146
146
|
# @return [Array of String] an array of the registered Traceables
|
147
147
|
# of the selectedCategory
|
148
148
|
def all_trace_ids(selected_category = nil)
|
149
|
-
@traces.keys.select{|x|
|
149
|
+
@traces.keys.select { |x|
|
150
150
|
y = @traces[x].first
|
151
151
|
selected_category.nil? or y.category == selected_category
|
152
152
|
}.sort
|
@@ -161,7 +161,7 @@ class TraceableSet
|
|
161
161
|
#
|
162
162
|
# @return [Array of Traceable] The array of traceables
|
163
163
|
def all_traces(selected_category = nil)
|
164
|
-
all_trace_ids(selected_category).map{|t| @traces[t].first}
|
164
|
+
all_trace_ids(selected_category).map { |t| @traces[t].first }
|
165
165
|
end
|
166
166
|
|
167
167
|
|
@@ -187,43 +187,43 @@ class TraceableSet
|
|
187
187
|
# this lists duplicate traces
|
188
188
|
# @return [Array of String] the list of the id of duplicate Traces
|
189
189
|
def duplicate_ids()
|
190
|
-
@traces.select{|id, traceables| traceables.length > 1}.map{|id, traceable| id}.sort
|
190
|
+
@traces.select { |id, traceables| traceables.length > 1 }.map { |id, traceable| id }.sort
|
191
191
|
end
|
192
192
|
|
193
193
|
# this lists duplicate traces
|
194
194
|
# @return [Array of Traceable] the list duplicate Traces.
|
195
195
|
def duplicate_traces()
|
196
|
-
@traces.select{|id, traceables| traceables.length > 1}.map{|id, traceable| traceable}.sort
|
196
|
+
@traces.select { |id, traceables| traceables.length > 1 }.map { |id, traceable| traceable }.sort
|
197
197
|
end
|
198
198
|
|
199
199
|
|
200
200
|
# this serializes a particular slot for caching
|
201
201
|
# @param file [String] name of the cachefile
|
202
202
|
def dump_to_marshal(file)
|
203
|
-
File.open(file, "wb"){|f|
|
203
|
+
File.open(file, "wb") { |f|
|
204
204
|
Marshal.dump(self, f)
|
205
205
|
}
|
206
206
|
end
|
207
207
|
|
208
208
|
# this loads cached information into a particular slot
|
209
209
|
# @param file [String] name of the cachefile
|
210
|
-
def
|
211
|
-
a=nil
|
212
|
-
File.open(file, "rb"){|f| a=Marshal.load(f)}
|
210
|
+
def self.load_from_marshal(file)
|
211
|
+
a = nil
|
212
|
+
File.open(file, "rb") { |f| a = Marshal.load(f) }
|
213
213
|
a
|
214
214
|
end
|
215
215
|
|
216
216
|
# this merges a TraceableSet
|
217
217
|
# @return [Treaceable] the current traceable set
|
218
218
|
def merge(set)
|
219
|
-
set.all_traces_as_arrays.values.flatten.each{|t| self.add(t)}
|
219
|
+
set.all_traces_as_arrays.values.flatten.each { |t| self.add(t) }
|
220
220
|
end
|
221
221
|
|
222
222
|
# this retunrs traces marked as supported but not being defined
|
223
223
|
# @return [Array of String] the list of the id of undefined Traces
|
224
224
|
# traces which are marked as uptraces but do not exist.
|
225
225
|
def undefined_ids
|
226
|
-
@supported_by.keys.select{|t| not @traces.has_key?(t)}.sort
|
226
|
+
@supported_by.keys.select { |t| not @traces.has_key?(t) }.sort
|
227
227
|
end
|
228
228
|
|
229
229
|
#
|
@@ -243,7 +243,7 @@ class TraceableSet
|
|
243
243
|
# it is placed according to the sequence
|
244
244
|
# in the array. Otherwise it is sorted at the end
|
245
245
|
def sort_order= (sort_order)
|
246
|
-
@sort_order=sort_order
|
246
|
+
@sort_order = sort_order
|
247
247
|
end
|
248
248
|
|
249
249
|
# this determines the sort order index of a trace
|
@@ -252,11 +252,11 @@ class TraceableSet
|
|
252
252
|
# the sort order index shall be coumputed.
|
253
253
|
# @return [String] the sort key of the given id.
|
254
254
|
def trace_order_index(trace_id)
|
255
|
-
global
|
256
|
-
|
255
|
+
global = @sort_order.index { |x| trace_id.start_with? x } ||
|
256
|
+
(@sort_order.length + 1)
|
257
257
|
|
258
258
|
# add the {index} of the trace to
|
259
|
-
orderId = [global.to_s.rjust(5,"0"),trace_id].join("_")
|
259
|
+
orderId = [global.to_s.rjust(5, "0"), trace_id].join("_")
|
260
260
|
orderId
|
261
261
|
end
|
262
262
|
|
@@ -272,11 +272,10 @@ class TraceableSet
|
|
272
272
|
#
|
273
273
|
# @return [type] [description]
|
274
274
|
def to_compareEntries
|
275
|
-
all_traces.sort.map{|t| "\n\n[#{t.id}]\n#{t.as_oneline}" }.join("\n")
|
275
|
+
all_traces.sort.map { |t| "\n\n[#{t.id}]\n#{t.as_oneline}" }.join("\n")
|
276
276
|
end
|
277
277
|
|
278
278
|
|
279
|
-
|
280
279
|
#############################
|
281
280
|
|
282
281
|
private
|
@@ -286,7 +285,7 @@ class TraceableSet
|
|
286
285
|
# @param [Nokogiri::XML::Document] doc - the document
|
287
286
|
# @return [Nokogiri::XML::Document] the beautified document
|
288
287
|
def xp(doc)
|
289
|
-
xsl
|
288
|
+
xsl = <<-XSL
|
290
289
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
291
290
|
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
|
292
291
|
<xsl:strip-space elements="*"/>
|
@@ -307,16 +306,19 @@ class TraceableSet
|
|
307
306
|
end
|
308
307
|
|
309
308
|
|
309
|
+
class Traceable
|
310
310
|
|
311
|
+
def clear_trace_id(id)
|
312
|
+
id.gsub("\\_", "_")
|
313
|
+
end
|
311
314
|
|
312
|
-
class Traceable
|
313
315
|
include Comparable
|
314
316
|
|
315
317
|
|
316
318
|
# String: The trace-Id
|
317
|
-
|
319
|
+
attr_reader :id
|
318
320
|
# string: the alternative Id, used e.g. for the constraint number
|
319
|
-
|
321
|
+
attr_reader :alternative_id
|
320
322
|
# String: The header in plain text
|
321
323
|
attr_accessor :header_plain
|
322
324
|
# String: The header in original format
|
@@ -326,7 +328,7 @@ class Traceable
|
|
326
328
|
# String: he body in original format
|
327
329
|
attr_accessor :body_orig
|
328
330
|
# Array of Strings: The uplink as an array of Trace-ids
|
329
|
-
|
331
|
+
attr_reader :contributes_to
|
330
332
|
# String: the Traceable in its original format
|
331
333
|
attr_accessor :trace_orig
|
332
334
|
# String: origin of the entry
|
@@ -338,18 +340,30 @@ class Traceable
|
|
338
340
|
|
339
341
|
|
340
342
|
def initialize()
|
341
|
-
@id
|
343
|
+
@id = ""
|
342
344
|
@alternative_id = ""
|
343
|
-
@header_orig
|
344
|
-
@body_plain
|
345
|
-
@body_orig
|
345
|
+
@header_orig = ""
|
346
|
+
@body_plain = ""
|
347
|
+
@body_orig = ""
|
346
348
|
@contributes_to = []
|
347
|
-
@trace_orig
|
348
|
-
@category
|
349
|
-
@info
|
349
|
+
@trace_orig = ""
|
350
|
+
@category = ""
|
351
|
+
@info = ""
|
352
|
+
end
|
353
|
+
|
354
|
+
def id=(id)
|
355
|
+
@id = clear_trace_id(id)
|
356
|
+
end
|
357
|
+
|
358
|
+
def alternative_id=()
|
359
|
+
@alternative_id = clear_trace_id(id)
|
360
|
+
end
|
361
|
+
|
362
|
+
def contributes_to=(list)
|
363
|
+
@contributes_to = list.map { |id| id = clear_trace_id(id) }
|
350
364
|
end
|
351
365
|
|
352
|
-
# define the comparison to makeit really
|
366
|
+
# define the comparison to makeit really comparable
|
353
367
|
# @param [Traceable] other the other traceable for comparison.
|
354
368
|
def <=> (other)
|
355
369
|
@id <=> other.id
|
@@ -366,19 +380,19 @@ class Traceable
|
|
366
380
|
if newval == oldval
|
367
381
|
result = nil
|
368
382
|
else
|
369
|
-
diff_as_html= "<pre>#{other.trace_orig}</pre><hr/><pre>#{self.trace_orig}</pre>"#Diffy::Diff.new(other.trace_orig, self.trace_orig).to_s(:text)
|
370
|
-
rawDiff
|
371
|
-
diff_as_html=rawDiff.to_s(:html)
|
383
|
+
diff_as_html = "<pre>#{other.trace_orig}</pre><hr/><pre>#{self.trace_orig}</pre>" #Diffy::Diff.new(other.trace_orig, self.trace_orig).to_s(:text)
|
384
|
+
rawDiff = Diffy::Diff.new(self.trace_orig, other.trace_orig)
|
385
|
+
diff_as_html = rawDiff.to_s(:html)
|
372
386
|
|
373
|
-
result
|
374
|
-
diff_as_html=nil
|
387
|
+
result = [self.id, similarity, diff_as_html]
|
388
|
+
diff_as_html = nil
|
375
389
|
end
|
376
390
|
result
|
377
391
|
end
|
378
392
|
|
379
393
|
|
380
394
|
def get_comparison_string
|
381
|
-
"#{header_orig};#{body_orig};#{contributes_to.sort}".gsub(/\s+/," ")
|
395
|
+
"#{header_orig};#{body_orig};#{contributes_to.sort}".gsub(/\s+/, " ")
|
382
396
|
end
|
383
397
|
|
384
398
|
def as_oneline
|