dim-toolkit 2.1.1 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|