dim-toolkit 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/dim +9 -9
- data/lib/dim/commands/check.rb +13 -13
- data/lib/dim/commands/export.rb +145 -145
- data/lib/dim/commands/format.rb +196 -198
- data/lib/dim/commands/stats.rb +64 -64
- data/lib/dim/consistency.rb +157 -187
- data/lib/dim/dimmain.rb +28 -28
- data/lib/dim/encoding.rb +4 -4
- data/lib/dim/exit_helper.rb +23 -23
- data/lib/dim/exporter/csv.rb +24 -25
- data/lib/dim/exporter/exporterInterface.rb +37 -37
- data/lib/dim/exporter/json.rb +30 -32
- data/lib/dim/exporter/rst.rb +142 -142
- data/lib/dim/ext/psych.rb +63 -63
- data/lib/dim/ext/string.rb +85 -85
- data/lib/dim/globals.rb +12 -12
- data/lib/dim/helpers/attribute_helper.rb +126 -126
- data/lib/dim/helpers/file_helper.rb +25 -25
- data/lib/dim/loader.rb +561 -581
- data/lib/dim/options.rb +116 -116
- data/lib/dim/requirement.rb +217 -236
- data/lib/dim/ver.rb +7 -7
- data/lib/dim.rb +1 -1
- data/license.txt +205 -205
- data/version.txt +1 -1
- metadata +4 -4
data/lib/dim/consistency.rb
CHANGED
@@ -1,187 +1,157 @@
|
|
1
|
-
require_relative 'globals'
|
2
|
-
require_relative 'exit_helper'
|
3
|
-
|
4
|
-
module Dim
|
5
|
-
class Consistency
|
6
|
-
def initialize(loader)
|
7
|
-
@loader = loader
|
8
|
-
end
|
9
|
-
|
10
|
-
def cyclic_check(ref, previous_ref, checked_ids = {}, list = [])
|
11
|
-
return if checked_ids[ref.id]
|
12
|
-
|
13
|
-
# Circular dependency can occur only on same category level
|
14
|
-
return if previous_ref && (ref.category_level != previous_ref.category_level)
|
15
|
-
|
16
|
-
if list.include?(ref.id)
|
17
|
-
Dim::ExitHelper.exit(
|
18
|
-
code: 1,
|
19
|
-
filename: ref.filename,
|
20
|
-
msg: "\"#{ref.id}\" is cyclically referenced: #{list.join(' -> ')} -> #{ref.id}"
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
list << ref.id
|
25
|
-
|
26
|
-
ref.existingRefs.each do |ref_id|
|
27
|
-
cyclic_check(@loader.requirements[ref_id], ref, checked_ids, list)
|
28
|
-
end
|
29
|
-
|
30
|
-
list.pop
|
31
|
-
|
32
|
-
# Any value other than nil and false will work, as this is being used to check
|
33
|
-
# boolean condition on line#11
|
34
|
-
checked_ids[ref.id] = 1 if list.empty?
|
35
|
-
end
|
36
|
-
private :cyclic_check
|
37
|
-
|
38
|
-
def insert_default_values(req)
|
39
|
-
req.all_attributes.each do |key, config|
|
40
|
-
next if req.data.key?(key)
|
41
|
-
|
42
|
-
req.data[key] = config[:default]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def insert_property_file_definitions(ref)
|
47
|
-
@loader.property_table.fetch(ref.document, {}).each do |attr, value|
|
48
|
-
ref.data[attr] = value if ref.data[attr].nil?
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
|
-
def
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
def
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
@loader.requirements.each do |_id, r|
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
if !@loader.requirements.has_key?(ref)
|
159
|
-
unless allow_missing
|
160
|
-
Dim::ExitHelper.exit(
|
161
|
-
code: 1,
|
162
|
-
filename: r.filename,
|
163
|
-
msg: "\"#{id}\" refers to non-existing \"#{ref}\""
|
164
|
-
)
|
165
|
-
end
|
166
|
-
else
|
167
|
-
# Generate upstream and downstream refs based on category level
|
168
|
-
if @loader.requirements[id].category_level <= @loader.requirements[ref].category_level
|
169
|
-
@loader.requirements[id].downstreamRefs |= [ref]
|
170
|
-
@loader.requirements[ref].upstreamRefs |= [id]
|
171
|
-
else
|
172
|
-
@loader.requirements[id].upstreamRefs |= [ref]
|
173
|
-
@loader.requirements[ref].downstreamRefs |= [id]
|
174
|
-
end
|
175
|
-
@loader.requirements[ref].backwardRefs << id
|
176
|
-
r.existingRefs << ref
|
177
|
-
end
|
178
|
-
end
|
179
|
-
end
|
180
|
-
|
181
|
-
@checked_ids = {}
|
182
|
-
@loader.requirements.each do |_id, r|
|
183
|
-
cyclic_check(r, nil, @checked_ids)
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
1
|
+
require_relative 'globals'
|
2
|
+
require_relative 'exit_helper'
|
3
|
+
|
4
|
+
module Dim
|
5
|
+
class Consistency
|
6
|
+
def initialize(loader)
|
7
|
+
@loader = loader
|
8
|
+
end
|
9
|
+
|
10
|
+
def cyclic_check(ref, previous_ref, checked_ids = {}, list = [])
|
11
|
+
return if checked_ids[ref.id]
|
12
|
+
|
13
|
+
# Circular dependency can occur only on same category level
|
14
|
+
return if previous_ref && (ref.category_level != previous_ref.category_level)
|
15
|
+
|
16
|
+
if list.include?(ref.id)
|
17
|
+
Dim::ExitHelper.exit(
|
18
|
+
code: 1,
|
19
|
+
filename: ref.filename,
|
20
|
+
msg: "\"#{ref.id}\" is cyclically referenced: #{list.join(' -> ')} -> #{ref.id}"
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
list << ref.id
|
25
|
+
|
26
|
+
ref.existingRefs.each do |ref_id|
|
27
|
+
cyclic_check(@loader.requirements[ref_id], ref, checked_ids, list)
|
28
|
+
end
|
29
|
+
|
30
|
+
list.pop
|
31
|
+
|
32
|
+
# Any value other than nil and false will work, as this is being used to check
|
33
|
+
# boolean condition on line#11
|
34
|
+
checked_ids[ref.id] = 1 if list.empty?
|
35
|
+
end
|
36
|
+
private :cyclic_check
|
37
|
+
|
38
|
+
def insert_default_values(req)
|
39
|
+
req.all_attributes.each do |key, config|
|
40
|
+
next if req.data.key?(key)
|
41
|
+
|
42
|
+
req.data[key] = config[:default]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def insert_property_file_definitions(ref)
|
47
|
+
@loader.property_table.fetch(ref.document, {}).each do |attr, value|
|
48
|
+
ref.data[attr] = value if ref.data[attr].nil?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def calculate_verification_methods(ref)
|
53
|
+
return unless ref.data['verification_methods'].nil?
|
54
|
+
|
55
|
+
tags = ref.data['tags'].cleanArray
|
56
|
+
|
57
|
+
ref.data['verification_methods'] = if ref.data['type'] != 'requirement' || tags.include?('process')
|
58
|
+
'none'
|
59
|
+
elsif ref.category == 'input' || ref.category == 'unspecified'
|
60
|
+
'none'
|
61
|
+
elsif ref.category == 'module'
|
62
|
+
'off_target'
|
63
|
+
elsif tags.include?('tool')
|
64
|
+
'off_target'
|
65
|
+
else
|
66
|
+
'on_target'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def calculate_review_status(ref)
|
71
|
+
return unless ref.data['review_status'].nil?
|
72
|
+
|
73
|
+
ref.data['review_status'] = if ref.category == 'input' || ref.category == 'unspecified'
|
74
|
+
'not_reviewed'
|
75
|
+
else
|
76
|
+
'accepted'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def clean_comma_separated(ref)
|
81
|
+
%w[tags developer tester refs verification_methods].each do |var|
|
82
|
+
ref.data[var] = ref.data[var].cleanString
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def calculate_developer_tester(ref)
|
87
|
+
%w[developer tester].each do |t|
|
88
|
+
next unless ref.data[t].nil?
|
89
|
+
|
90
|
+
ref.data[t] = if ref.data['type'] != 'requirement'
|
91
|
+
''
|
92
|
+
elsif ref.data['tags'].cleanArray.include?('process') && t == 'tester'
|
93
|
+
''
|
94
|
+
elsif ref.category == 'input' || ref.category == 'unspecified'
|
95
|
+
''
|
96
|
+
else
|
97
|
+
ref.origin
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def calculate_status(ref)
|
103
|
+
return unless ref.data['status'].nil?
|
104
|
+
|
105
|
+
ref.data['status'] = %w[requirement information].include?(ref.data['type']) ? 'draft' : 'valid'
|
106
|
+
end
|
107
|
+
|
108
|
+
def check(allow_missing:)
|
109
|
+
requirements_by_module = {}
|
110
|
+
@loader.module_data.keys.each { |um| requirements_by_module[um] = [] }
|
111
|
+
@loader.requirements.each { |_id, r| requirements_by_module[r.document] << r }
|
112
|
+
|
113
|
+
@loader.requirements.each do |_id, r|
|
114
|
+
insert_property_file_definitions(r)
|
115
|
+
insert_default_values(r)
|
116
|
+
calculate_verification_methods(r)
|
117
|
+
calculate_review_status(r)
|
118
|
+
calculate_developer_tester(r)
|
119
|
+
calculate_status(r)
|
120
|
+
end
|
121
|
+
|
122
|
+
@loader.requirements.each do |_id, r|
|
123
|
+
clean_comma_separated(r)
|
124
|
+
end
|
125
|
+
|
126
|
+
@loader.requirements.each do |id, r|
|
127
|
+
r.data['refs'].cleanArray.each do |ref|
|
128
|
+
if !@loader.requirements.has_key?(ref)
|
129
|
+
unless allow_missing
|
130
|
+
Dim::ExitHelper.exit(
|
131
|
+
code: 1,
|
132
|
+
filename: r.filename,
|
133
|
+
msg: "\"#{id}\" refers to non-existing \"#{ref}\""
|
134
|
+
)
|
135
|
+
end
|
136
|
+
else
|
137
|
+
# Generate upstream and downstream refs based on category level
|
138
|
+
if @loader.requirements[id].category_level <= @loader.requirements[ref].category_level
|
139
|
+
@loader.requirements[id].downstreamRefs |= [ref]
|
140
|
+
@loader.requirements[ref].upstreamRefs |= [id]
|
141
|
+
else
|
142
|
+
@loader.requirements[id].upstreamRefs |= [ref]
|
143
|
+
@loader.requirements[ref].downstreamRefs |= [id]
|
144
|
+
end
|
145
|
+
@loader.requirements[ref].backwardRefs << id
|
146
|
+
r.existingRefs << ref
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
@checked_ids = {}
|
152
|
+
@loader.requirements.each do |_id, r|
|
153
|
+
cyclic_check(r, nil, @checked_ids)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
data/lib/dim/dimmain.rb
CHANGED
@@ -1,28 +1,28 @@
|
|
1
|
-
$stdout.sync = true
|
2
|
-
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
require_relative 'globals'
|
6
|
-
require_relative 'exit_helper'
|
7
|
-
require_relative 'ext/string'
|
8
|
-
require_relative 'loader'
|
9
|
-
require_relative 'ver'
|
10
|
-
require_relative 'requirement'
|
11
|
-
require_relative 'commands/stats'
|
12
|
-
require_relative 'commands/check'
|
13
|
-
require_relative 'commands/export'
|
14
|
-
require_relative 'commands/format'
|
15
|
-
require_relative 'options'
|
16
|
-
|
17
|
-
module Dim
|
18
|
-
def self.main(args = ARGV)
|
19
|
-
Dim::Options.parse(args)
|
20
|
-
loader = Dim::Loader.new
|
21
|
-
loader.load(file: OPTIONS[:input],
|
22
|
-
attributes_file: OPTIONS[:attributes],
|
23
|
-
allow_missing: OPTIONS[:allow_missing],
|
24
|
-
no_check_enclosed: OPTIONS[:no_check_enclosed] || false,
|
25
|
-
silent: OPTIONS[:silent] || false)
|
26
|
-
SUBCOMMANDS[OPTIONS[:subcommand]].new(loader).execute(silent: OPTIONS[:silent] || false)
|
27
|
-
end
|
28
|
-
end
|
1
|
+
$stdout.sync = true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
require_relative 'globals'
|
6
|
+
require_relative 'exit_helper'
|
7
|
+
require_relative 'ext/string'
|
8
|
+
require_relative 'loader'
|
9
|
+
require_relative 'ver'
|
10
|
+
require_relative 'requirement'
|
11
|
+
require_relative 'commands/stats'
|
12
|
+
require_relative 'commands/check'
|
13
|
+
require_relative 'commands/export'
|
14
|
+
require_relative 'commands/format'
|
15
|
+
require_relative 'options'
|
16
|
+
|
17
|
+
module Dim
|
18
|
+
def self.main(args = ARGV)
|
19
|
+
Dim::Options.parse(args)
|
20
|
+
loader = Dim::Loader.new
|
21
|
+
loader.load(file: OPTIONS[:input],
|
22
|
+
attributes_file: OPTIONS[:attributes],
|
23
|
+
allow_missing: OPTIONS[:allow_missing],
|
24
|
+
no_check_enclosed: OPTIONS[:no_check_enclosed] || false,
|
25
|
+
silent: OPTIONS[:silent] || false)
|
26
|
+
SUBCOMMANDS[OPTIONS[:subcommand]].new(loader).execute(silent: OPTIONS[:silent] || false)
|
27
|
+
end
|
28
|
+
end
|
data/lib/dim/encoding.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# This overwrites the configuration of local machines,
|
2
|
-
# Dim shall read, process and write only UTF_8.
|
3
|
-
Encoding.default_external = Encoding::UTF_8
|
4
|
-
Encoding.default_internal = Encoding::UTF_8
|
1
|
+
# This overwrites the configuration of local machines,
|
2
|
+
# Dim shall read, process and write only UTF_8.
|
3
|
+
Encoding.default_external = Encoding::UTF_8
|
4
|
+
Encoding.default_internal = Encoding::UTF_8
|
data/lib/dim/exit_helper.rb
CHANGED
@@ -1,23 +1,23 @@
|
|
1
|
-
module Dim
|
2
|
-
class ExitHelper
|
3
|
-
@exit_code = 0
|
4
|
-
|
5
|
-
class << self
|
6
|
-
def exit_code
|
7
|
-
@exit_code
|
8
|
-
end
|
9
|
-
|
10
|
-
def reset_exit_code
|
11
|
-
@exit_code = 0
|
12
|
-
end
|
13
|
-
|
14
|
-
def exit(msg:, code: 0, filename: nil)
|
15
|
-
@exit_code = code
|
16
|
-
inf = filename ? "in #{filename}: " : ''
|
17
|
-
pre = code.positive? ? 'Error: ' : ''
|
18
|
-
warn("#{pre}#{inf}#{msg}")
|
19
|
-
Kernel.exit(code)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
1
|
+
module Dim
|
2
|
+
class ExitHelper
|
3
|
+
@exit_code = 0
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def exit_code
|
7
|
+
@exit_code
|
8
|
+
end
|
9
|
+
|
10
|
+
def reset_exit_code
|
11
|
+
@exit_code = 0
|
12
|
+
end
|
13
|
+
|
14
|
+
def exit(msg:, code: 0, filename: nil)
|
15
|
+
@exit_code = code
|
16
|
+
inf = filename ? "in #{filename}: " : ''
|
17
|
+
pre = code.positive? ? 'Error: ' : ''
|
18
|
+
warn("#{pre}#{inf}#{msg}")
|
19
|
+
Kernel.exit(code)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/dim/exporter/csv.rb
CHANGED
@@ -1,25 +1,24 @@
|
|
1
|
-
require_relative '../globals'
|
2
|
-
require_relative '../requirement'
|
3
|
-
|
4
|
-
module Dim
|
5
|
-
class Csv < ExporterInterface
|
6
|
-
EXPORTER['csv'] = self
|
7
|
-
|
8
|
-
def header(content)
|
9
|
-
@keys = @loader.all_attributes.keys
|
10
|
-
|
11
|
-
content.puts '
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
1
|
+
require_relative '../globals'
|
2
|
+
require_relative '../requirement'
|
3
|
+
|
4
|
+
module Dim
|
5
|
+
class Csv < ExporterInterface
|
6
|
+
EXPORTER['csv'] = self
|
7
|
+
|
8
|
+
def header(content)
|
9
|
+
@keys = @loader.all_attributes.keys
|
10
|
+
content.puts 'Sep=,'
|
11
|
+
content.puts "id,document_name,originator,#{@keys.join(',')}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def requirement(content, req)
|
15
|
+
vals = [req.id, req.document, req.origin]
|
16
|
+
@keys.each { |k| vals << req.data[k] }
|
17
|
+
# These values will never be nil.
|
18
|
+
# ID cannot be nil in Dim file, so as origin (default is "") and
|
19
|
+
# document cannot be missing in Dim files.
|
20
|
+
# Which leaves with data and YAML file cannot define nil value.
|
21
|
+
content.puts(vals.map { |a| "\"#{a.gsub('"', '""')}\"" }.join(','))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,37 +1,37 @@
|
|
1
|
-
module Dim
|
2
|
-
# This is how the interface is used by the Dim::Export:
|
3
|
-
#
|
4
|
-
# initialize()
|
5
|
-
#
|
6
|
-
# for every
|
7
|
-
# header()
|
8
|
-
# document()
|
9
|
-
# metadata()
|
10
|
-
# for every requirement in
|
11
|
-
# requirement()
|
12
|
-
# footer()
|
13
|
-
#
|
14
|
-
# if hasIndex:
|
15
|
-
# for every originator/category combination:
|
16
|
-
# index()
|
17
|
-
class ExporterInterface
|
18
|
-
attr_reader :hasIndex
|
19
|
-
|
20
|
-
def initialize(loader)
|
21
|
-
@hasIndex = false
|
22
|
-
@loader = loader
|
23
|
-
end
|
24
|
-
|
25
|
-
def header(f); end
|
26
|
-
|
27
|
-
def document(f, name); end
|
28
|
-
|
29
|
-
def metadata(f, metadata); end
|
30
|
-
|
31
|
-
def requirement(f, r); end
|
32
|
-
|
33
|
-
def footer(f); end
|
34
|
-
|
35
|
-
def index(f, category, origin, modules); end
|
36
|
-
end
|
37
|
-
end
|
1
|
+
module Dim
|
2
|
+
# This is how the interface is used by the Dim::Export:
|
3
|
+
#
|
4
|
+
# initialize()
|
5
|
+
#
|
6
|
+
# for every document:
|
7
|
+
# header()
|
8
|
+
# document()
|
9
|
+
# metadata()
|
10
|
+
# for every requirement in document:
|
11
|
+
# requirement()
|
12
|
+
# footer()
|
13
|
+
#
|
14
|
+
# if hasIndex:
|
15
|
+
# for every originator/category combination:
|
16
|
+
# index()
|
17
|
+
class ExporterInterface
|
18
|
+
attr_reader :hasIndex
|
19
|
+
|
20
|
+
def initialize(loader)
|
21
|
+
@hasIndex = false
|
22
|
+
@loader = loader
|
23
|
+
end
|
24
|
+
|
25
|
+
def header(f); end
|
26
|
+
|
27
|
+
def document(f, name); end
|
28
|
+
|
29
|
+
def metadata(f, metadata); end
|
30
|
+
|
31
|
+
def requirement(f, r); end
|
32
|
+
|
33
|
+
def footer(f); end
|
34
|
+
|
35
|
+
def index(f, category, origin, modules); end
|
36
|
+
end
|
37
|
+
end
|
data/lib/dim/exporter/json.rb
CHANGED
@@ -1,32 +1,30 @@
|
|
1
|
-
require 'json'
|
2
|
-
|
3
|
-
require_relative '../globals'
|
4
|
-
require_relative '../requirement'
|
5
|
-
|
6
|
-
module Dim
|
7
|
-
class Json < ExporterInterface
|
8
|
-
EXPORTER['json'] = self
|
9
|
-
|
10
|
-
def header(_f)
|
11
|
-
@content = []
|
12
|
-
end
|
13
|
-
|
14
|
-
def requirement(_f, r)
|
15
|
-
vals = { 'id' => r.id, 'document_name' => r.document, 'originator' => r.origin }
|
16
|
-
|
17
|
-
@loader.all_attributes.keys.each do |k|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
32
|
-
end
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require_relative '../globals'
|
4
|
+
require_relative '../requirement'
|
5
|
+
|
6
|
+
module Dim
|
7
|
+
class Json < ExporterInterface
|
8
|
+
EXPORTER['json'] = self
|
9
|
+
|
10
|
+
def header(_f)
|
11
|
+
@content = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def requirement(_f, r)
|
15
|
+
vals = { 'id' => r.id, 'document_name' => r.document, 'originator' => r.origin }
|
16
|
+
|
17
|
+
@loader.all_attributes.keys.each do |k|
|
18
|
+
v = r.data[k]
|
19
|
+
v = v.cleanUniqArray.join(',') if k == 'refs'
|
20
|
+
vals[k] = v.strip
|
21
|
+
end
|
22
|
+
|
23
|
+
@content << vals
|
24
|
+
end
|
25
|
+
|
26
|
+
def footer(f)
|
27
|
+
f.puts(JSON.pretty_generate(@content))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|