Almirah 0.2.4 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/bin/almirah +4 -4
  3. data/lib/almirah/doc_fabric.rb +65 -65
  4. data/lib/almirah/doc_items/blockquote.rb +21 -21
  5. data/lib/almirah/doc_items/code_block.rb +26 -26
  6. data/lib/almirah/doc_items/controlled_paragraph.rb +112 -112
  7. data/lib/almirah/doc_items/controlled_table.rb +224 -224
  8. data/lib/almirah/doc_items/controlled_table_row.rb +22 -22
  9. data/lib/almirah/doc_items/doc_footer.rb +16 -16
  10. data/lib/almirah/doc_items/doc_item.rb +22 -20
  11. data/lib/almirah/doc_items/frontmatter.rb +9 -0
  12. data/lib/almirah/doc_items/heading.rb +93 -93
  13. data/lib/almirah/doc_items/image.rb +27 -27
  14. data/lib/almirah/doc_items/markdown_list.rb +156 -158
  15. data/lib/almirah/doc_items/markdown_table.rb +61 -63
  16. data/lib/almirah/doc_items/paragraph.rb +25 -27
  17. data/lib/almirah/doc_items/text_line.rb +296 -296
  18. data/lib/almirah/doc_items/todo_block.rb +21 -21
  19. data/lib/almirah/doc_parser.rb +378 -330
  20. data/lib/almirah/doc_types/base_document.rb +64 -70
  21. data/lib/almirah/doc_types/coverage.rb +95 -81
  22. data/lib/almirah/doc_types/index.rb +173 -169
  23. data/lib/almirah/doc_types/persistent_document.rb +17 -20
  24. data/lib/almirah/doc_types/protocol.rb +24 -24
  25. data/lib/almirah/doc_types/specification.rb +67 -67
  26. data/lib/almirah/doc_types/traceability.rb +142 -142
  27. data/lib/almirah/dom/doc_section.rb +25 -25
  28. data/lib/almirah/dom/document.rb +78 -72
  29. data/lib/almirah/navigation_pane.rb +16 -16
  30. data/lib/almirah/project.rb +287 -306
  31. data/lib/almirah/project_configuration.rb +41 -41
  32. data/lib/almirah/project_template.rb +298 -0
  33. data/lib/almirah/project_utility.rb +52 -0
  34. data/lib/almirah/search/specifications_db.rb +79 -83
  35. data/lib/almirah/templates/css/main.css +300 -300
  36. data/lib/almirah/templates/css/search.css +40 -40
  37. data/lib/almirah/templates/page.html +42 -42
  38. data/lib/almirah/templates/scripts/main.js +111 -111
  39. data/lib/almirah/templates/scripts/orama_search.js +138 -138
  40. data/lib/almirah.rb +93 -49
  41. metadata +28 -5
@@ -1,42 +1,42 @@
1
- require 'yaml'
2
-
3
- class ProjectConfiguration
4
-
5
- attr_accessor :project_root_directory
6
- attr_accessor :parameters
7
-
8
- def initialize(path)
9
- @project_root_directory = path
10
- @parameters = {}
11
- load_project_file()
12
- end
13
-
14
- def load_project_file
15
- begin
16
- @parameters = YAML.load_file(@project_root_directory + '/project.yml')
17
- rescue Psych::SyntaxError => e
18
- puts "YAML syntax error: #{e.message}"
19
- rescue Errno::ENOENT
20
- puts "Project file not found: project.yml"
21
- end
22
- end
23
-
24
- def get_design_inputs
25
- if (@parameters.key? 'specifications') and (@parameters['specifications'].key? 'input')
26
- return @parameters['specifications']['input']
27
- end
28
- return []
29
- end
30
-
31
- def is_spec_db_shall_be_created
32
- if (@parameters.key? 'output')
33
- @parameters['output'].each do |p|
34
- if p == 'specifications_db'
35
- return true
36
- end
37
- end
38
- end
39
- return false
40
- end
41
-
1
+ require 'yaml'
2
+
3
+ class ProjectConfiguration
4
+
5
+ attr_accessor :project_root_directory
6
+ attr_accessor :parameters
7
+
8
+ def initialize(path)
9
+ @project_root_directory = path
10
+ @parameters = {}
11
+ load_project_file()
12
+ end
13
+
14
+ def load_project_file
15
+ begin
16
+ @parameters = YAML.load_file(@project_root_directory + '/project.yml')
17
+ rescue Psych::SyntaxError => e
18
+ puts "YAML syntax error: #{e.message}"
19
+ rescue Errno::ENOENT
20
+ puts "Project file not found: project.yml"
21
+ end
22
+ end
23
+
24
+ def get_design_inputs
25
+ if (@parameters.key? 'specifications') and (@parameters['specifications'].key? 'input')
26
+ return @parameters['specifications']['input']
27
+ end
28
+ return []
29
+ end
30
+
31
+ def is_spec_db_shall_be_created
32
+ if (@parameters.key? 'output')
33
+ @parameters['output'].each do |p|
34
+ if p == 'specifications_db'
35
+ return true
36
+ end
37
+ end
38
+ end
39
+ return false
40
+ end
41
+
42
42
  end
@@ -0,0 +1,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ class ProjectTemplate # rubocop:disable Style/Documentation
6
+ attr_accessor :project_root
7
+
8
+ def initialize(project_name)
9
+ path = File.join(Dir.pwd, project_name)
10
+ Kernel.abort 'Suggested project folder already exists' if Dir.exist? path
11
+ FileUtils.mkdir_p path
12
+ @project_root = path
13
+ create_requirements
14
+ create_architecture
15
+ create_tests
16
+ create_test_runs
17
+ end
18
+
19
+ def create_requirements
20
+ path = File.join(@project_root, 'specifications/req')
21
+ FileUtils.mkdir_p path
22
+
23
+ file_content = <<~EOS
24
+ ---
25
+ title: Requirements Specification
26
+ author: put your name here
27
+ ---
28
+
29
+ # Overview
30
+
31
+ This is an example of software requirements specification.
32
+
33
+ # Requirements
34
+
35
+ This is a regular paragraph in the document.
36
+
37
+ [REQ-001] This is a first requirement (controlled paragraph with ID equal to "REQ-001").
38
+
39
+ [REQ-002] This is a second requirement.
40
+
41
+ # Document Histrory
42
+
43
+ | Revision | Description of changes | Date |
44
+ |---|---|---|
45
+ | A | Initial version | #{Time.now.strftime('%Y-%d-%m')} |
46
+
47
+ EOS
48
+
49
+ path = File.join(path, 'req.md')
50
+ file = File.open(path, 'w')
51
+ file.puts file_content
52
+ file.close
53
+ end
54
+
55
+ def create_architecture
56
+ path = File.join(@project_root, 'specifications/arch')
57
+ FileUtils.mkdir_p path
58
+
59
+ file_content = <<~EOS
60
+ ---
61
+ title: Architecture Specification
62
+ author: put your name here
63
+ ---
64
+
65
+ # Overview
66
+
67
+ This is an example of software architecture document.
68
+
69
+ # System Overview
70
+
71
+ This is a regular paragraph in the document.
72
+
73
+ [ARCH-004] This is an architecture item that is related to requirement "REQ-001". >[REQ-001]
74
+
75
+ [ARCH-002] This is a regular architecture item.
76
+
77
+ # System Decomposition
78
+
79
+ [ARCH-005] This is an architecture irem that is related to requirement "REQ-002". >[REQ-002]
80
+
81
+ # Document Histrory
82
+
83
+ | Revision | Description of changes | Date |
84
+ |---|---|---|
85
+ | A | Initial version | #{Time.now.strftime('%Y-%d-%m')} |
86
+
87
+ EOS
88
+
89
+ path = File.join(path, 'arch.md')
90
+ file = File.open(path, 'w')
91
+ file.puts file_content
92
+ file.close
93
+ end
94
+
95
+ def create_tests
96
+ create_test_001
97
+ create_test_002
98
+ create_test_003
99
+ end
100
+
101
+ def create_test_001
102
+ path = File.join(@project_root, 'tests/protocols/tp-001')
103
+ FileUtils.mkdir_p path
104
+
105
+ file_content = <<~EOS
106
+ # Test Case TP-001
107
+
108
+ This is an example of test case for software requirement "REQ-001".
109
+
110
+ # Test Summary
111
+
112
+ | Param | Value |
113
+ |---|---|
114
+ | Software Version | |
115
+ | Tester Name | |
116
+ | Date | |
117
+
118
+ # Test Procedure
119
+
120
+ | Test Step # | Test Step Description | Result | Req. Id |
121
+ |---|---|---|---|
122
+ | 1 | Some preparation step | | |
123
+ | 2 | Some verification step for requirement "REQ-001" | | >[REQ-001] |
124
+
125
+ EOS
126
+
127
+ path = File.join(path, 'tp-001.md')
128
+ file = File.open(path, 'w')
129
+ file.puts file_content
130
+ file.close
131
+ end
132
+
133
+ def create_test_002
134
+ path = File.join(@project_root, 'tests/protocols/tp-002')
135
+ FileUtils.mkdir_p path
136
+
137
+ file_content = <<~EOS
138
+ # Test Case TP-002
139
+
140
+ This is an example of test case for software requirement "REQ-002".
141
+
142
+ # Test Summary
143
+
144
+ | Param | Value |
145
+ |---|---|
146
+ | Software Version | |
147
+ | Tester Name | |
148
+ | Date | |
149
+
150
+ # Test Procedure
151
+
152
+ | Test Step # | Test Step Description | Result | Req. Id |
153
+ |---|---|---|---|
154
+ | 1 | Some preparation step | | |
155
+ | 2 | Some verification step for requirement "REQ-002" | | >[REQ-002] |
156
+
157
+ EOS
158
+
159
+ path = File.join(path, 'tp-002.md')
160
+ file = File.open(path, 'w')
161
+ file.puts file_content
162
+ file.close
163
+ end
164
+
165
+ def create_test_003
166
+ path = File.join(@project_root, 'tests/protocols/tq-001')
167
+ FileUtils.mkdir_p path
168
+
169
+ file_content = <<~EOS
170
+ # Test Case TQ-001
171
+
172
+ This is an example of test case for software architecture item "ARCH-002".
173
+
174
+ # Test Summary
175
+
176
+ | Param | Value |
177
+ |---|---|
178
+ | Software Version | |
179
+ | Tester Name | |
180
+ | Date | |
181
+
182
+ # Test Procedure
183
+
184
+ | Test Step # | Test Step Description | Result | Req. Id |
185
+ |---|---|---|---|
186
+ | 1 | Some preparation step | | |
187
+ | 2 | Some verification step for architecture item "ARCH-002" | | >[ARCH-002] |
188
+
189
+ EOS
190
+
191
+ path = File.join(path, 'tq-001.md')
192
+ file = File.open(path, 'w')
193
+ file.puts file_content
194
+ file.close
195
+ end
196
+
197
+ def create_test_runs
198
+ run_test_001
199
+ run_test_002
200
+ run_test_003
201
+ end
202
+
203
+ def run_test_001
204
+ path = File.join(@project_root, 'tests/runs/001/tp-001')
205
+ FileUtils.mkdir_p path
206
+
207
+ file_content = <<~EOS
208
+ # Test Case TP-001
209
+
210
+ This is an example of test case for software requirement "REQ-001".
211
+
212
+ # Test Summary
213
+
214
+ | Param | Value |
215
+ |---|---|
216
+ | Software Version | |
217
+ | Tester Name | |
218
+ | Date | |
219
+
220
+ # Test Procedure
221
+
222
+ | Test Step # | Test Step Description | Result | Req. Id |
223
+ |---|---|---|---|
224
+ | 1 | Some preparation step | n/a | |
225
+ | 2 | Some verification step for requirement "REQ-001" | pass | >[REQ-001] |
226
+
227
+ EOS
228
+
229
+ path = File.join(path, 'tp-001.md')
230
+ file = File.open(path, 'w')
231
+ file.puts file_content
232
+ file.close
233
+ end
234
+
235
+ def run_test_002
236
+ path = File.join(@project_root, 'tests/runs/001/tp-002')
237
+ FileUtils.mkdir_p path
238
+
239
+ file_content = <<~EOS
240
+ # Test Case TP-002
241
+
242
+ This is an example of test case for software requirement "REQ-002".
243
+
244
+ # Test Summary
245
+
246
+ | Param | Value |
247
+ |---|---|
248
+ | Software Version | |
249
+ | Tester Name | |
250
+ | Date | |
251
+
252
+ # Test Procedure
253
+
254
+ | Test Step # | Test Step Description | Result | Req. Id |
255
+ |---|---|---|---|
256
+ | 1 | Some preparation step | n/a | |
257
+ | 2 | Some verification step for requirement "REQ-002" | fail | >[REQ-002] |
258
+
259
+ EOS
260
+
261
+ path = File.join(path, 'tp-002.md')
262
+ file = File.open(path, 'w')
263
+ file.puts file_content
264
+ file.close
265
+ end
266
+
267
+ def run_test_003
268
+ path = File.join(@project_root, 'tests/runs/010/tq-002')
269
+ FileUtils.mkdir_p path
270
+
271
+ file_content = <<~EOS
272
+ # Test Case TQ-001
273
+
274
+ This is an example of test case for software architecture item "ARCH-002".
275
+
276
+ # Test Summary
277
+
278
+ | Param | Value |
279
+ |---|---|
280
+ | Software Version | |
281
+ | Tester Name | |
282
+ | Date | |
283
+
284
+ # Test Procedure
285
+
286
+ | Test Step # | Test Step Description | Result | Req. Id |
287
+ |---|---|---|---|
288
+ | 1 | Some preparation step | n/a | |
289
+ | 2 | Some verification step for architecture item "ARCH-002" | pass | >[ARCH-002] |
290
+
291
+ EOS
292
+
293
+ path = File.join(path, 'tq-001.md')
294
+ file = File.open(path, 'w')
295
+ file.puts file_content
296
+ file.close
297
+ end
298
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ class ProjectUtility # rubocop:disable Style/Documentation
6
+ attr_accessor :configuration
7
+
8
+ def initialize(configuration)
9
+ @configuration = configuration
10
+ end
11
+
12
+ def combine_protocols
13
+ combine nil
14
+ end
15
+
16
+ def combine_run(run_id)
17
+ combine run_id
18
+ end
19
+
20
+ private
21
+
22
+ def combine(run_id) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
23
+ path = @configuration.project_root_directory
24
+ dst_folder = "#{@configuration.project_root_directory}/build"
25
+ FileUtils.mkdir_p(dst_folder)
26
+
27
+ dst_file = "#{dst_folder}/combined.md"
28
+ File.delete(dst_file) if File.exist?(dst_file)
29
+ dst_f = File.open(dst_file, 'a')
30
+
31
+ src_path = if run_id
32
+ unless Dir.exist? "#{path}/tests/runs/#{run_id}"
33
+ puts "\e[1m\e[31m Run #{run_id} folder does not exists"
34
+ end
35
+ "#{path}/tests/runs/#{run_id}/**/*.md"
36
+ else
37
+ "#{path}/tests/protocols/**/*.md"
38
+ end
39
+
40
+ Dir.glob(src_path).sort.each do |f|
41
+ puts "\e[35m #{f}"
42
+ file = File.open(f)
43
+ file_data = file.readlines
44
+ file.close
45
+
46
+ dst_f.puts file_data
47
+ dst_f.puts # empty line
48
+ end
49
+
50
+ dst_f.close
51
+ end
52
+ end
@@ -1,83 +1,79 @@
1
- require 'json'
2
- # Prepare JSON database file for further indexing by other tools
3
- class SpecificationsDb
4
-
5
- attr_accessor :specifications
6
- attr_accessor :data
7
-
8
- def initialize(spec_list)
9
- @specifications = spec_list
10
- @data = []
11
- create_data
12
- end
13
-
14
- def create_data
15
- @specifications.each do |sp|
16
- sp.items.each do |i|
17
- if (i.instance_of? Paragraph) or (i.instance_of? ControlledParagraph)
18
- e = {"document" => i.parent_doc.title, \
19
- "doc_color" => i.parent_doc.color, \
20
- "text" => i.text, \
21
- "heading_url" => i.parent_heading.get_url(), \
22
- "heading_text" => i.parent_heading.get_section_info()
23
- }
24
- @data.append e
25
- elsif i.instance_of? MarkdownList
26
- e = add_markdown_list_item_to_db( @data, i, i)
27
- elsif i.instance_of? MarkdownTable
28
- add_markdown_table_item_to_db( @data, i, i)
29
- end
30
- end
31
- end
32
- end
33
-
34
- def add_markdown_list_item_to_db(data, item_for_reference, item_to_process)
35
- e = nil
36
- item_to_process.rows.each do |r|
37
- if r.is_a?(MarkdownList)
38
- f_text = r.text
39
- e = { "document" => item_for_reference.parent_doc.title, \
40
- "doc_color" => item_for_reference.parent_doc.color, \
41
- "text" => f_text, \
42
- "heading_url" => item_for_reference.parent_heading.get_url(), \
43
- "heading_text" => item_for_reference.parent_heading.get_section_info()
44
- }
45
- data << e
46
- add_markdown_list_item_to_db(data, item_for_reference, r)
47
- else
48
- f_text = r
49
- e = { "document" => item_for_reference.parent_doc.title, \
50
- "doc_color" => item_for_reference.parent_doc.color, \
51
- "text" => f_text, \
52
- "heading_url" => item_for_reference.parent_heading.get_url(), \
53
- "heading_text" => item_for_reference.parent_heading.get_section_info()
54
- }
55
- data << e
56
- end
57
- end
58
- return e
59
- end
60
-
61
- def add_markdown_table_item_to_db(data, item_for_reference, item_to_process)
62
- e = nil
63
- table_text = ""
64
- item_to_process.rows.each do |row|
65
- table_text += "| " + row.join(" | ") + " |"
66
- end
67
- e = { "document" => item_for_reference.parent_doc.title, \
68
- "doc_color" => item_for_reference.parent_doc.color, \
69
- "text" => table_text, \
70
- "heading_url" => item_for_reference.parent_heading.get_url(), \
71
- "heading_text" => item_for_reference.parent_heading.get_section_info()
72
- }
73
- data << e
74
- end
75
-
76
- def save(path)
77
- json = JSON.generate(@data)
78
-
79
- file = File.open( path + "/specifications_db.json", "w" )
80
- file.puts json
81
- file.close
82
- end
83
- end
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ # Prepare JSON database file for further indexing by other tools
6
+ class SpecificationsDb
7
+ attr_accessor :specifications, :data
8
+
9
+ def initialize(spec_list)
10
+ @specifications = spec_list
11
+ @data = []
12
+ create_data
13
+ end
14
+
15
+ def create_data # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
16
+ @specifications.each do |sp|
17
+ sp.items.each do |i|
18
+ if (i.instance_of? Paragraph) or (i.instance_of? ControlledParagraph)
19
+ e = { 'document' => i.parent_doc.title, \
20
+ 'doc_color' => i.parent_doc.color, \
21
+ 'text' => i.text, \
22
+ 'heading_url' => i.parent_heading.get_url, \
23
+ 'heading_text' => i.parent_heading.get_section_info }
24
+ @data.append e
25
+ elsif i.instance_of? MarkdownList
26
+ add_markdown_list_item_to_db(@data, i, i)
27
+ elsif i.instance_of? MarkdownTable
28
+ add_markdown_table_item_to_db(@data, i, i)
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def add_markdown_list_item_to_db(data, item_for_reference, item_to_process) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
35
+ e = nil
36
+ item_to_process.rows.each do |r|
37
+ if r.is_a?(MarkdownList)
38
+ f_text = r.text
39
+ e = { 'document' => item_for_reference.parent_doc.title, \
40
+ 'doc_color' => item_for_reference.parent_doc.color, \
41
+ 'text' => f_text, \
42
+ 'heading_url' => item_for_reference.parent_heading.get_url, \
43
+ 'heading_text' => item_for_reference.parent_heading.get_section_info }
44
+ data << e
45
+ add_markdown_list_item_to_db(data, item_for_reference, r)
46
+ else
47
+ f_text = r
48
+ e = { 'document' => item_for_reference.parent_doc.title, \
49
+ 'doc_color' => item_for_reference.parent_doc.color, \
50
+ 'text' => f_text, \
51
+ 'heading_url' => item_for_reference.parent_heading.get_url, \
52
+ 'heading_text' => item_for_reference.parent_heading.get_section_info }
53
+ data << e
54
+ end
55
+ end
56
+ e
57
+ end
58
+
59
+ def add_markdown_table_item_to_db(data, item_for_reference, item_to_process)
60
+ table_text = ''
61
+ item_to_process.rows.each do |row|
62
+ table_text += "| #{row.join(' | ')} |"
63
+ end
64
+ e = { 'document' => item_for_reference.parent_doc.title, \
65
+ 'doc_color' => item_for_reference.parent_doc.color, \
66
+ 'text' => table_text, \
67
+ 'heading_url' => item_for_reference.parent_heading.get_url, \
68
+ 'heading_text' => item_for_reference.parent_heading.get_section_info }
69
+ data << e
70
+ end
71
+
72
+ def save(path)
73
+ json = JSON.generate(@data)
74
+
75
+ file = File.open("#{path}/specifications_db.json", 'w')
76
+ file.puts json
77
+ file.close
78
+ end
79
+ end