Skip to content

Commit 757e16a

Browse files
feat: add document generation (#841)
* chore: establish a basic structure for document generation * chore: playing around with location and granularity * chore: add gherkin extraction * docs: generate requirements document * fix: don't use sudo in workflows * fix: allow sudo in workflow that needs it * ci: install missing package * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Ron <[email protected]> * docs: generate nicer PDF * chore: correct workflow syntax * chore: minor refactor to workflow * chore: pin pip dependencies * docs: make the pdf more appealing --------- Signed-off-by: Ron <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 239fe97 commit 757e16a

File tree

5 files changed

+202
-13
lines changed

5 files changed

+202
-13
lines changed

.github/workflows/wc-build-push-test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,8 @@ jobs:
9696
- uses: EnricoMi/publish-unit-test-result-action@3a74b2957438d0b6e2e61d67b05318aa25c9e6c6 # v2.20.0
9797
with:
9898
files: test-report-*.xml
99+
100+
generate-documents:
101+
uses: ./.github/workflows/wc-document-generation.yml
102+
permissions:
103+
contents: read
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
name: Document Generation
3+
4+
on:
5+
workflow_call:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
generate-documents:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: step-security/harden-runner@002fdce3c6a235733a90a27c80493a3241e56863 # v2.12.1
15+
with:
16+
egress-policy: audit
17+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
18+
with:
19+
persist-credentials: false
20+
- name: Install dependencies
21+
run: |
22+
set -Eeuo pipefail
23+
sudo apt-get update && sudo apt-get install --no-install-recommends -y plantuml
24+
python -m pip install gherkin-official==35.1.0 sbdl==1.16.4
25+
- name: Generate requirements document
26+
run: |
27+
set -Eeuo pipefail
28+
python docs/support/gherkin-to-csv.py test/cpp/features/*.feature
29+
python -m csv-to-sbdl --identifier 0 --description 1 --skipheader rules.csv
30+
sbdl -m template-fill --template docs/templates/requirements.template.md output.sbdl > requirements.md
31+
- uses: docker://pandoc/extra:3.7.0@sha256:a703d335fa237f8fc3303329d87e2555dca5187930da38bfa9010fa4e690933a
32+
with:
33+
args: --template eisvogel --output requirements.pdf requirements.md
34+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
35+
with:
36+
name: documents
37+
path: requirements.pdf
38+
retention-days: 2

docs/support/gherkin-to-csv.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import csv
5+
import os
6+
import sys
7+
from dataclasses import dataclass, asdict, fields
8+
from typing import List
9+
from gherkin.parser import Parser
10+
from gherkin.token_scanner import TokenScanner
11+
12+
@dataclass
13+
class Rule:
14+
"""A class representing a rule extracted from a Gherkin feature file."""
15+
identifier: str
16+
description: str
17+
18+
@classmethod
19+
def field_names(cls) -> List[str]:
20+
return [f.name for f in fields(cls)]
21+
22+
def extract_rules_from_feature(file_path):
23+
"""Parse a Gherkin feature file and extract the rules."""
24+
try:
25+
with open(file_path, 'r', encoding='utf-8') as file:
26+
content = file.read()
27+
28+
parser = Parser()
29+
feature_document = parser.parse(TokenScanner(content))
30+
rules = []
31+
32+
if 'feature' in feature_document:
33+
feature = feature_document['feature']
34+
35+
if 'children' in feature:
36+
for child in feature['children']:
37+
if 'rule' in child:
38+
rule = child['rule']
39+
rule_id = rule.get('name', '').strip()
40+
description = rule.get('description', '').strip()
41+
rules.append(Rule(
42+
identifier=rule_id,
43+
description=description
44+
))
45+
46+
return rules
47+
except Exception as e:
48+
print(f"Error parsing {file_path}: {e}", file=sys.stderr)
49+
return []
50+
51+
def main():
52+
parser = argparse.ArgumentParser(description='Extract rules from Gherkin feature files and save to CSV')
53+
parser.add_argument('feature_files', nargs='+', help='Paths to feature files')
54+
parser.add_argument('--output', '-o', default='rules.csv', help='Output CSV file path')
55+
56+
args = parser.parse_args()
57+
all_rules = []
58+
59+
for feature_path in args.feature_files:
60+
if os.path.isfile(feature_path):
61+
print(f"Processing {feature_path}")
62+
rules = extract_rules_from_feature(feature_path)
63+
all_rules.extend(rules)
64+
else:
65+
print(f"File not found: {feature_path}", file=sys.stderr)
66+
67+
with open(args.output, 'w', newline='', encoding='utf-8') as csvfile:
68+
writer = csv.DictWriter(csvfile, fieldnames=Rule.field_names())
69+
writer.writeheader()
70+
writer.writerows([asdict(rule) for rule in all_rules])
71+
72+
print(f"Extracted {len(all_rules)} rules to {args.output}")
73+
74+
if __name__ == '__main__':
75+
main()
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# amp-devcontainer requirement specification
2+
3+
## Introduction
4+
5+
### Purpose
6+
7+
This document describes the software system requirements for amp-devcontainer.
8+
9+
### Definitions of key words
10+
11+
The key words *MUST*, *MUST NOT*, *REQUIRED*, *SHALL*, *SHALL NOT*, *SHOULD*, *SHOULD NOT*, *RECOMMENDED*, *MAY*, and *OPTIONAL* in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).
12+
13+
### Abstract
14+
15+
amp-devcontainer is a set of [devcontainers](https://containers.dev/) tailored towards modern, embedded, software development.
16+
17+
The containers may be used both for local development and continuous integration (ci).
18+
19+
### Terminology and Abbreviations
20+
21+
| Terminology and Abbreviations | Description/Definition |
22+
|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
23+
| ARM | A family of RISC architectures for computer processors and micro controllers, formerly an acronym for Advanced RISC Machines and originally Acorn RISC Machine |
24+
| Continuous Integration (ci) | The practice of continuously merging developers work to a shared code-base; ideally including automation for build, test and deployment |
25+
| ELF | Executable and Linkable Format, formerly named Extensible Linking Format |
26+
| RISC | Reduced Instruction Set Computer |
27+
28+
## Requirements
29+
30+
{%- macro reencode(text) -%}
31+
{{ text.encode('utf-8').decode('unicode_escape') }}
32+
{%- endmacro -%}
33+
34+
{%- macro sbdl_id_to_header(text) -%}
35+
{{ text.replace('_', ' ') }}
36+
{%- endmacro -%}
37+
38+
{% for req_id, requirement in sbdl.items() %}
39+
{% if requirement.type == 'requirement' %}
40+
### {{ reencode(sbdl_id_to_header(req_id)) }}
41+
42+
{{ reencode(requirement.description) }}
43+
44+
{% endif %}
45+
{% endfor %}
Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,45 @@
1-
Feature: Compile source code into working software
1+
Feature: Compilation
22

3-
As a developer
4-
To generate working software
5-
Source code needs to be compiled successfully
3+
As a software developer
4+
To generate a working product
5+
Source code needs to be compiled into working software
66

7-
Scenario: Compile valid source code into working software targeting the host architecture
7+
Rule: Compile for container host architecture and operating system
8+
amp-devcontainer *SHALL* be able to compile valid source code into a working executable targeting the container host architecture and operating system.
89

9-
Compiling valid source code into working software, able to run on the host architecture,
10+
Compiling valid source code into working software, able to run on the container host architecture and operating system,
1011
can be necessary in several scenarios; for example when:
1112

12-
- the host is the deployment target
13-
- running tests on the host
14-
- building plug-ins, extensions, code generators, or other additional tools that need to run on the host
13+
- the container host is the deployment target
14+
- running tests on the container host
15+
- building plug-ins, extensions, code generators, or other additional tools that need to run on the container host
1516

16-
Given build configuration "gcc" is selected
17-
And build preset "gcc" is selected
18-
When the selected target is built
19-
Then the output should contain "Build finished with exit code 0"
17+
@flavor:cpp
18+
Scenario: Compile valid source code into working software targeting the container host architecture
19+
Given build configuration "gcc" is selected
20+
And build preset "gcc" is selected
21+
When the selected target is built
22+
Then the output should contain "Build finished with exit code 0"
23+
24+
Rule: Compile for ARM Cortex target architecture
25+
amp-devcontainer *SHALL* be able to compile valid source-code into a working ELF executable targeting the ARM Cortex architecture.
26+
27+
Compiling valid source-code into working ELF executables, able to run on the ARM Cortex architecture,
28+
is a primary function for amp-devcontainer. It enables building firmware for micro-controllers based
29+
on the ARM Cortex architecture.
30+
31+
Rule: Compile for Microsoft® Windows operating system
32+
amp-devcontainer *SHALL* be able to compile valid source-code into a working executable targeting the Microsoft® Windows operating system.
33+
34+
Compiling valid source-code into working executables, able to run on the Microsoft® Windows operating system, can be necessary in several scenarios e.g.
35+
36+
- Cross platform code is written and needs to be compiled and deployed
37+
- Executables needs to be deployed outside of container context to a host running the Microsoft® Windows operating system
38+
39+
Rule: Compilation cache
40+
amp-devcontainer *SHOULD* be able to cache the results of a compilation to speed-up subsequent compilations.
41+
42+
Maintaining a compilation cache can be useful in both local and ci development scenarios. A compilation cache can provide benefits like:
43+
44+
- Reduce developer waiting time and context switches, [maintaining flow-state](https://azure.microsoft.com/en-us/blog/quantifying-the-impact-of-developer-experience/)
45+
- Reduce CPU usage at the cost of more storage usage, potentially reducing energy consumption and cost for metered ci-systems

0 commit comments

Comments
 (0)