Almirah 0.3.1 → 0.4.1
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/lib/almirah/console_reporter.rb +46 -0
- data/lib/almirah/doc_fabric.rb +16 -7
- data/lib/almirah/doc_items/controlled_paragraph.rb +28 -2
- data/lib/almirah/doc_items/controlled_table.rb +5 -4
- data/lib/almirah/doc_items/doc_item.rb +12 -0
- data/lib/almirah/doc_items/markdown_list.rb +2 -2
- data/lib/almirah/doc_items/markdown_table.rb +17 -8
- data/lib/almirah/doc_items/text_line.rb +243 -41
- data/lib/almirah/doc_parser.rb +20 -3
- data/lib/almirah/doc_types/base_document.rb +41 -24
- data/lib/almirah/doc_types/decision.rb +161 -0
- data/lib/almirah/doc_types/decisions_overview.rb +202 -0
- data/lib/almirah/doc_types/protocol.rb +3 -0
- data/lib/almirah/doc_types/source_file.rb +4 -8
- data/lib/almirah/link_registry.rb +38 -0
- data/lib/almirah/project/doc_linker.rb +24 -0
- data/lib/almirah/project/project_data.rb +7 -2
- data/lib/almirah/project.rb +117 -14
- data/lib/almirah/project_configuration.rb +1 -1
- data/lib/almirah/project_template.rb +89 -1
- data/lib/almirah/relative_url.rb +22 -0
- data/lib/almirah/search/specifications_db.rb +4 -4
- data/lib/almirah/templates/css/main.css +41 -1
- data/lib/almirah/templates/scripts/main.js +7 -1
- data/lib/almirah/templates/scripts/orama_search.js +3 -3
- metadata +6 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b4a6b0c92714af081d54b235449ab825fa86842d61869f31cd331a44c702efdc
|
|
4
|
+
data.tar.gz: cf2074e5c3f500689359912872166c1f13c08e59bde29408c90ee7b34fbe18fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 21654dccede23f1828f02b4446f11f626d12ee5d7d3689b96636d6b1be0465de44fddbacd05606935326a27d4317bfaf0b5596813e907a38580ea6591bc430ca
|
|
7
|
+
data.tar.gz: d3821259aeb7e5ff6306c3d9ccec25720030e659e351cd2c32a7791a8520ddea0039e6cab7f083b0244c82095e7c219c14de465bcda55b326eca184d06ce3bc7
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Reporter prints concise, aligned progress lines for the processing pipeline:
|
|
4
|
+
#
|
|
5
|
+
# parsing specifications ..... 4 ok
|
|
6
|
+
# parsing test protocols ..... 2 ok
|
|
7
|
+
# parsing decisions .......... 14 ok
|
|
8
|
+
# traceability matrices ...... 4 ok
|
|
9
|
+
# coverage matrices .......... 1 ok
|
|
10
|
+
# implementation matrices .... 1 ok
|
|
11
|
+
# decision links ............. 5 ok
|
|
12
|
+
# rendering HTML ............. ./build/index.html
|
|
13
|
+
#
|
|
14
|
+
# ANSI colour is applied only when writing to an interactive terminal, so piped
|
|
15
|
+
# or captured output stays clean.
|
|
16
|
+
module ConsoleReporter
|
|
17
|
+
COLUMN = 28 # label is dot-padded out to this column, then the value follows
|
|
18
|
+
|
|
19
|
+
module_function
|
|
20
|
+
|
|
21
|
+
def count(label, number)
|
|
22
|
+
emit(label, "#{number} ok", 92) # green highlight
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def result(label, value)
|
|
26
|
+
emit(label, value, 96) # cyan highlight
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def warn(label, value)
|
|
30
|
+
emit(label, value.to_s, 91) # red highlight
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Colourises a detail line with the same red as warn (TTY-gated).
|
|
34
|
+
def warn_detail(text)
|
|
35
|
+
colorize(text, 91)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def emit(label, value, color_code)
|
|
39
|
+
dotted = "#{label} ".ljust(COLUMN, '.')
|
|
40
|
+
puts "#{dotted} #{colorize(value, color_code)}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def colorize(text, color_code)
|
|
44
|
+
$stdout.tty? ? "\e[#{color_code}m#{text}\e[0m" : text
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/almirah/doc_fabric.rb
CHANGED
|
@@ -5,6 +5,8 @@ require_relative 'doc_types/protocol'
|
|
|
5
5
|
require_relative 'doc_types/coverage'
|
|
6
6
|
require_relative 'doc_types/implementation'
|
|
7
7
|
require_relative 'doc_types/traceability'
|
|
8
|
+
require_relative 'doc_types/decision'
|
|
9
|
+
require_relative 'doc_types/decisions_overview'
|
|
8
10
|
require_relative 'doc_parser'
|
|
9
11
|
require_relative 'source_file_parser'
|
|
10
12
|
require_relative 'dom/document'
|
|
@@ -15,12 +17,6 @@ class DocFabric
|
|
|
15
17
|
@@spec_colors = %w[cff4d2 fbeee6 ffcad4 bce6ff e4dfd9 f9e07f cbe54e d3e7ee eab595 86e3c3
|
|
16
18
|
ffdca2 ffffff ffdd94 d0e6a5 ffb284 f3dbcf c9bbc8 c6c09c]
|
|
17
19
|
|
|
18
|
-
def self.add_lazy_doc_id(path)
|
|
19
|
-
if res = /(\w+)[.]md$/.match(path)
|
|
20
|
-
TextLine.add_lazy_doc_id(res[1])
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
20
|
def self.create_specification(path)
|
|
25
21
|
color = @@spec_colors[@@color_index]
|
|
26
22
|
@@color_index += 1
|
|
@@ -64,6 +60,19 @@ class DocFabric
|
|
|
64
60
|
doc
|
|
65
61
|
end
|
|
66
62
|
|
|
63
|
+
def self.create_decision(path)
|
|
64
|
+
doc = Decision.new path
|
|
65
|
+
DocFabric.parse_document doc
|
|
66
|
+
doc.extract_current_status
|
|
67
|
+
doc.extract_start_date
|
|
68
|
+
doc.extract_target_release_version
|
|
69
|
+
doc
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self.create_decisions_overview(project)
|
|
73
|
+
DecisionsOverview.new project
|
|
74
|
+
end
|
|
75
|
+
|
|
67
76
|
def self.create_source_file(repository_path, path, repository_name)
|
|
68
77
|
doc = SourceFile.new repository_path, path, repository_name
|
|
69
78
|
DocFabric.parse_source_file doc
|
|
@@ -78,7 +87,7 @@ class DocFabric
|
|
|
78
87
|
DocParser.parse(doc, file_lines)
|
|
79
88
|
|
|
80
89
|
# Build dom
|
|
81
|
-
doc.dom = Document.new(doc.headings) if doc.is_a?(Specification) || doc.is_a?(Protocol)
|
|
90
|
+
doc.dom = Document.new(doc.headings) if doc.is_a?(Specification) || doc.is_a?(Protocol) || doc.is_a?(Decision)
|
|
82
91
|
end
|
|
83
92
|
|
|
84
93
|
def self.parse_source_file(doc)
|
|
@@ -2,7 +2,7 @@ require_relative 'paragraph'
|
|
|
2
2
|
|
|
3
3
|
# <REQ> Implementa a controlled paragraph as a subclass of the DocItem >[SRS-001] </REQ>
|
|
4
4
|
class ControlledParagraph < Paragraph
|
|
5
|
-
attr_accessor :id, :up_link_ids, :down_links, :coverage_links, :source_code_links
|
|
5
|
+
attr_accessor :id, :up_link_ids, :down_links, :coverage_links, :source_code_links, :decision_record_links
|
|
6
6
|
|
|
7
7
|
def initialize(doc, text, id)
|
|
8
8
|
super(doc, text)
|
|
@@ -12,6 +12,7 @@ class ControlledParagraph < Paragraph
|
|
|
12
12
|
@down_links = nil
|
|
13
13
|
@coverage_links = nil
|
|
14
14
|
@source_code_links = nil
|
|
15
|
+
@decision_record_links = nil
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def to_html
|
|
@@ -19,7 +20,7 @@ class ControlledParagraph < Paragraph
|
|
|
19
20
|
unless @@html_table_render_in_progress
|
|
20
21
|
s += "<table class=\"controlled\">\n"
|
|
21
22
|
s += "\t<thead> <th>#</th> <th></th> <th title=\"Up-links\">UL</th> <th title=\"Down-links\">DL</th> \
|
|
22
|
-
<th title=\"Test Coverage\">COV</th> </thead>\n"
|
|
23
|
+
<th title=\"Test Coverage\">COV</th> <th title=\"Decision Record\">DR</th> </thead>\n"
|
|
23
24
|
@@html_table_render_in_progress = true # rubocop:disable Style/ClassVars
|
|
24
25
|
end
|
|
25
26
|
f_text = format_string(@text)
|
|
@@ -108,6 +109,31 @@ class ControlledParagraph < Paragraph
|
|
|
108
109
|
else
|
|
109
110
|
s += "\t\t<td class=\"item_id\"></td>\n"
|
|
110
111
|
end
|
|
112
|
+
|
|
113
|
+
if @decision_record_links
|
|
114
|
+
if @decision_record_links.length == 1
|
|
115
|
+
dr_doc = @decision_record_links[0].parent_doc
|
|
116
|
+
s += "\t\t<td class=\"item_id\">\
|
|
117
|
+
<a href=\"./../../decisions/#{dr_doc.html_rel_path}\" \
|
|
118
|
+
class=\"external\" title=\"Decision Record\">#{dr_doc.id.upcase}</a></td>\n"
|
|
119
|
+
else
|
|
120
|
+
s += "\t\t<td class=\"item_id\">"
|
|
121
|
+
s += "<div id=\"DR_#{@id}\" style=\"display: block;\">"
|
|
122
|
+
s += "<a href=\"#\" onclick=\"decisionLink_OnClick(this.parentElement); return false;\" \
|
|
123
|
+
class=\"external\" title=\"Number of decision records\">#{@decision_record_links.length}</a>"
|
|
124
|
+
s += '</div>'
|
|
125
|
+
s += "<div id=\"DRS_#{@id}\" style=\"display: none;\">"
|
|
126
|
+
@decision_record_links.each do |lnk|
|
|
127
|
+
dr_doc = lnk.parent_doc
|
|
128
|
+
s += "\t\t\t<a href=\"./../../decisions/#{dr_doc.html_rel_path}\" \
|
|
129
|
+
class=\"external\" title=\"Referenced in\">#{dr_doc.id.upcase}</a>\n<br>"
|
|
130
|
+
end
|
|
131
|
+
s += '</div>'
|
|
132
|
+
s += "</td>\n"
|
|
133
|
+
end
|
|
134
|
+
else
|
|
135
|
+
s += "\t\t<td class=\"item_id\"></td>\n"
|
|
136
|
+
end
|
|
111
137
|
s += "\t</tr>\n"
|
|
112
138
|
s
|
|
113
139
|
end
|
|
@@ -101,13 +101,14 @@ class TestStepReferenceColumn < ControlledTableColumn # rubocop:disable Style/Do
|
|
|
101
101
|
|
|
102
102
|
def to_html # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
|
103
103
|
s = ''
|
|
104
|
+
specifications_path = @parent_row.parent_doc.specifications_path
|
|
104
105
|
if @up_link_ids
|
|
105
106
|
if @up_link_ids.length == 1
|
|
106
107
|
if tmp = /^([a-zA-Z]+)-\d+/.match(@up_link_ids[0])
|
|
107
108
|
up_link_doc_name = tmp[1].downcase
|
|
108
109
|
end
|
|
109
110
|
s += "\t\t<td class=\"item_id\" style=\"text-align: center;\">\
|
|
110
|
-
<a href=\"
|
|
111
|
+
<a href=\"#{specifications_path}#{up_link_doc_name}/#{up_link_doc_name}.html##{@up_link_ids[0]}\" \
|
|
111
112
|
class=\"external\" title=\"Linked to\">#{@up_link_ids[0]}</a></td>\n"
|
|
112
113
|
else
|
|
113
114
|
s += "\t\t<td class=\"item_id\" style=\"text-align: center;\">"
|
|
@@ -120,7 +121,7 @@ class TestStepReferenceColumn < ControlledTableColumn # rubocop:disable Style/Do
|
|
|
120
121
|
if tmp = /^([a-zA-Z]+)-\d+/.match(lnk)
|
|
121
122
|
up_link_doc_name = tmp[1].downcase
|
|
122
123
|
end
|
|
123
|
-
s += "\t\t\t<a href=\"
|
|
124
|
+
s += "\t\t\t<a href=\"#{specifications_path}#{up_link_doc_name}/#{up_link_doc_name}.html##{lnk}\" \
|
|
124
125
|
class=\"external\" title=\"Verifies\">#{lnk}</a>\n<br>"
|
|
125
126
|
end
|
|
126
127
|
s += '</div>'
|
|
@@ -150,7 +151,7 @@ class ControlledTable < DocItem # rubocop:disable Style/Documentation
|
|
|
150
151
|
end
|
|
151
152
|
|
|
152
153
|
def add_row(row)
|
|
153
|
-
columns = row
|
|
154
|
+
columns = split_table_cells(row)
|
|
154
155
|
|
|
155
156
|
@rows.append(format_columns(columns))
|
|
156
157
|
|
|
@@ -184,7 +185,7 @@ class ControlledTable < DocItem # rubocop:disable Style/Documentation
|
|
|
184
185
|
end
|
|
185
186
|
end
|
|
186
187
|
|
|
187
|
-
elsif index + 2 == columns.length
|
|
188
|
+
elsif (index + 2 == columns.length) && @parent_doc.instance_of?(Protocol) # test step result column applies only to Protocols
|
|
188
189
|
|
|
189
190
|
col = TestStepResultColumn.new element
|
|
190
191
|
new_row.columns.append col
|
|
@@ -19,4 +19,16 @@ class DocItem < TextLine # rubocop:disable Style/Documentation
|
|
|
19
19
|
def get_url
|
|
20
20
|
''
|
|
21
21
|
end
|
|
22
|
+
|
|
23
|
+
# Splits a Markdown table row into its cell strings, treating a backslash-escaped
|
|
24
|
+
# pipe (\|) as a literal character within a cell rather than a column separator
|
|
25
|
+
# (e.g. a "|" inside an inline code span such as `[[target\|alias]]`). The escaping
|
|
26
|
+
# backslash is dropped so the cell renders the intended literal pipe.
|
|
27
|
+
def split_table_cells(row)
|
|
28
|
+
row.split(/(?<!\\)\|/).map { |cell| cell.gsub('\\|', '|') }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def owner_document
|
|
32
|
+
@parent_doc
|
|
33
|
+
end
|
|
22
34
|
end
|
|
@@ -73,7 +73,7 @@ class MarkdownList < DocItem
|
|
|
73
73
|
s.each_char do |c|
|
|
74
74
|
case state
|
|
75
75
|
when 'looking_for_list_item_marker'
|
|
76
|
-
if c == '*'
|
|
76
|
+
if c == '*' || c == '-'
|
|
77
77
|
state = 'looking_for_space'
|
|
78
78
|
elsif numeric?(c)
|
|
79
79
|
state = 'looking_for_dot'
|
|
@@ -106,7 +106,7 @@ class MarkdownList < DocItem
|
|
|
106
106
|
end
|
|
107
107
|
|
|
108
108
|
def self.unordered_list_item?(raw_text)
|
|
109
|
-
res =
|
|
109
|
+
res = /^\s*([*\-]\s+)(.*)/.match(raw_text)
|
|
110
110
|
return true if res
|
|
111
111
|
|
|
112
112
|
false
|
|
@@ -3,21 +3,23 @@
|
|
|
3
3
|
require_relative 'doc_item'
|
|
4
4
|
|
|
5
5
|
class MarkdownTable < DocItem
|
|
6
|
-
attr_accessor :column_names, :rows, :heading_row, :is_separator_detected, :column_aligns
|
|
6
|
+
attr_accessor :column_names, :rows, :heading_row, :is_separator_detected, :column_aligns,
|
|
7
|
+
:is_decision_status_table
|
|
7
8
|
|
|
8
|
-
def initialize(doc, heading_row)
|
|
9
|
+
def initialize(doc, heading_row) # rubocop:disable Metrics/MethodLength
|
|
9
10
|
super(doc)
|
|
10
11
|
@heading_row = heading_row
|
|
11
12
|
|
|
12
13
|
res = /^[|](.*[|])/.match(heading_row)
|
|
13
14
|
@column_names = if res
|
|
14
|
-
res[1]
|
|
15
|
+
split_table_cells(res[1])
|
|
15
16
|
else
|
|
16
17
|
['# ERROR# ']
|
|
17
18
|
end
|
|
18
19
|
@rows = []
|
|
19
20
|
@is_separator_detected = false
|
|
20
21
|
@column_aligns = []
|
|
22
|
+
@is_decision_status_table = false
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def add_separator(line)
|
|
@@ -47,7 +49,7 @@ class MarkdownTable < DocItem
|
|
|
47
49
|
end
|
|
48
50
|
|
|
49
51
|
def add_row(row)
|
|
50
|
-
columns = row
|
|
52
|
+
columns = split_table_cells(row)
|
|
51
53
|
@rows.append(columns.map!(&:strip))
|
|
52
54
|
true
|
|
53
55
|
end
|
|
@@ -69,10 +71,17 @@ class MarkdownTable < DocItem
|
|
|
69
71
|
s += " </thead>\n"
|
|
70
72
|
|
|
71
73
|
@rows.each do |row|
|
|
72
|
-
|
|
74
|
+
tr_class = if @is_decision_status_table && row[0].to_s.strip == '*'
|
|
75
|
+
' class="current_status"'
|
|
76
|
+
else
|
|
77
|
+
''
|
|
78
|
+
end
|
|
79
|
+
s += "\t<tr#{tr_class}>\n"
|
|
73
80
|
row.each_with_index do |col, index|
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
cell = col
|
|
82
|
+
cell = '▶' if @is_decision_status_table && index.zero? && col.strip == '*'
|
|
83
|
+
if cell.to_i.positive? && cell.to_i.to_s == cell # autoalign cells with numbers
|
|
84
|
+
s += "\t\t<td style=\"text-align: center;\">#{cell}</td>\n"
|
|
76
85
|
else
|
|
77
86
|
align = ''
|
|
78
87
|
case @column_aligns[index]
|
|
@@ -83,7 +92,7 @@ class MarkdownTable < DocItem
|
|
|
83
92
|
when 'center'
|
|
84
93
|
align = 'style="text-align: center;"'
|
|
85
94
|
end
|
|
86
|
-
f_text = format_string(
|
|
95
|
+
f_text = format_string(cell)
|
|
87
96
|
s += "\t\t<td #{align}>#{f_text}</td>\n"
|
|
88
97
|
end
|
|
89
98
|
end
|