Skip to content

Commit 632153a

Browse files
committed
Add containment --short flag and improve diagram rendering
Features: - Add --short flag to containment command (shows only root elements) - Default containment now shows ALL elements in each file - Change containment diagram to top-down (TD) layout - Add direction TB inside subgraphs for vertical element layout - Add GitHub Pages link to README Updates: - Replace diagram generation workflow with documentation export - Update CLI requirement with --short flag specification - Update verification test criteria for element display modes - Add --short flag test to containment test suite - Fix CLI help structure test for new --short option Docs updated for GitHub Pages
1 parent 22987c6 commit 632153a

File tree

25 files changed

+546
-212
lines changed

25 files changed

+546
-212
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=flat-square)](https://opensource.org/licenses/Apache-2.0)
1111
[![Rust](https://img.shields.io/badge/Built%20with-Rust-orange?style=flat-square&logo=rust)](https://www.rust-lang.org/)
1212

13-
[📖 **Documentation**](https://www.reqvire.org)[🚀 **Quick Start**](#get-started)[👥 **Contributing**](./doc/README.md)[💬 **Community**](https://github.com/reqvire-org/reqvire/discussions)
13+
[📖 **Documentation**](https://www.reqvire.org)[🔍 **Browse Model**](https://reqvire-org.github.io/reqvire/)[🚀 **Quick Start**](#get-started)[👥 **Contributing**](./doc/README.md)
1414

1515
</div>
1616

@@ -58,6 +58,7 @@ For detailed installation options (from source, pre-built binaries, etc.), see t
5858
### Next Steps
5959

6060
- **[Documentation](https://www.reqvire.org)** - Learn how to use Reqvire
61+
- **[Browse Model](https://reqvire-org.github.io/reqvire/)** - Explore Reqvire's own specifications
6162
- **[Use Cases](./specifications/Usecases.md)** - See Reqvire in action
6263

6364
---

cli/src/cli.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,15 @@ pub enum Commands {
389389
},
390390

391391
/// Generate containment view showing folder/file/element hierarchy
392-
#[clap(override_help = "Generate containment view showing folder/file/element hierarchy\n\nCONTAINMENT OPTIONS:\n --json Output results in JSON format")]
392+
#[clap(override_help = "Generate containment view showing folder/file/element hierarchy\n\nCONTAINMENT OPTIONS:\n --json Output results in JSON format\n --short Show only root elements (without hierarchical parents)")]
393393
Containment {
394394
/// Output results in JSON format
395395
#[clap(long, help_heading = "CONTAINMENT OPTIONS")]
396396
json: bool,
397+
398+
/// Show only root elements (without hierarchical parents in same file)
399+
#[clap(long, help_heading = "CONTAINMENT OPTIONS")]
400+
short: bool,
397401
},
398402

399403
/// Interactive shell for GraphRegistry operations (undocumented)
@@ -1078,16 +1082,16 @@ pub fn handle_command(
10781082
render_crud_result(&result);
10791083
return Ok(0);
10801084
},
1081-
Some(Commands::Containment { json }) => {
1085+
Some(Commands::Containment { json, short }) => {
10821086
if json {
10831087
// Build containment hierarchy
1084-
let hierarchy = reqvire::containment::ContainmentHierarchy::build(&model_manager.graph_registry)?;
1088+
let hierarchy = reqvire::containment::ContainmentHierarchy::build(&model_manager.graph_registry, short)?;
10851089
// Serialize to JSON
10861090
let json_output = serde_json::to_string_pretty(&hierarchy)
10871091
.map_err(|e| ReqvireError::ElementError(format!("JSON serialization error: {}", e)))?;
10881092
println!("{}", json_output);
10891093
} else {
1090-
let output = diagrams::generate_containment_diagram(&model_manager.graph_registry)?;
1094+
let output = diagrams::generate_containment_diagram(&model_manager.graph_registry, short)?;
10911095
println!("{}", output);
10921096
}
10931097
return Ok(0);

core/src/containment.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ pub struct ContainmentHierarchy {
5858

5959
impl ContainmentHierarchy {
6060
/// Build containment hierarchy from a registry
61-
pub fn build(registry: &GraphRegistry) -> Result<Self, ReqvireError> {
61+
///
62+
/// When `short` is true, shows only root elements (those without hierarchical parents).
63+
/// When `short` is false (default), shows all elements.
64+
pub fn build(registry: &GraphRegistry, short: bool) -> Result<Self, ReqvireError> {
6265
// Group elements by file
6366
let mut files_map: BTreeMap<String, Vec<&Element>> = BTreeMap::new();
6467
for element in registry.get_all_elements() {
@@ -67,18 +70,26 @@ impl ContainmentHierarchy {
6770
.push(element);
6871
}
6972

70-
// Filter to only top-level elements in each file
71-
let mut filtered_files_map: BTreeMap<String, Vec<ContainmentElement>> = BTreeMap::new();
73+
// Build elements map - filter if short mode, otherwise show all
74+
let mut elements_map: BTreeMap<String, Vec<ContainmentElement>> = BTreeMap::new();
7275
for (file_path, elements) in files_map.iter() {
73-
let filtered = filter_top_level_elements(elements);
74-
filtered_files_map.insert(
75-
file_path.clone(),
76-
filtered.iter().map(|e| ContainmentElement::from_element(e)).collect()
77-
);
76+
let selected_elements: Vec<ContainmentElement> = if short {
77+
// Short mode: only top-level elements
78+
filter_top_level_elements(elements)
79+
.iter()
80+
.map(|e| ContainmentElement::from_element(e))
81+
.collect()
82+
} else {
83+
// Full mode: all elements
84+
elements.iter()
85+
.map(|e| ContainmentElement::from_element(e))
86+
.collect()
87+
};
88+
elements_map.insert(file_path.clone(), selected_elements);
7889
}
7990

8091
// Build folder structure
81-
let root_folder = build_folder_structure(&filtered_files_map);
92+
let root_folder = build_folder_structure(&elements_map);
8293

8394
Ok(ContainmentHierarchy { root_folder })
8495
}

core/src/diagrams.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,18 +1023,25 @@ pub fn escape_label(text: &str) -> String {
10231023
}
10241024

10251025
/// Generate containment view diagram showing folder/file/element hierarchy
1026-
pub fn generate_containment_diagram(registry: &GraphRegistry) -> Result<String, ReqvireError> {
1026+
///
1027+
/// When `short` is true, shows only root elements (those without hierarchical parents).
1028+
/// When `short` is false (default), shows all elements.
1029+
pub fn generate_containment_diagram(registry: &GraphRegistry, short: bool) -> Result<String, ReqvireError> {
10271030
// Build containment hierarchy structure
1028-
let hierarchy = crate::containment::ContainmentHierarchy::build(registry)?;
1031+
let hierarchy = crate::containment::ContainmentHierarchy::build(registry, short)?;
10291032

10301033
let mut output = String::new();
10311034

10321035
// Markdown header
10331036
output.push_str("# Containment View\n\n");
10341037
output.push_str("This diagram shows the containment hierarchy (folders, files, and elements).\n");
1035-
output.push_str("Elements displayed in each file are filtered to show only top-level parents (those without hierarchical parent relations within the same file).\n\n");
1038+
if short {
1039+
output.push_str("Elements displayed in each file are filtered to show only root elements (those without hierarchical parent relations within the same file).\n\n");
1040+
} else {
1041+
output.push_str("All elements in each file are displayed.\n\n");
1042+
}
10361043
output.push_str("```mermaid\n");
1037-
output.push_str("graph LR\n");
1044+
output.push_str("graph TD\n");
10381045

10391046
// CSS class definitions
10401047
output.push_str(" %% Graph styling\n");
@@ -1101,6 +1108,7 @@ fn generate_folder_tree(
11011108

11021109
// Create subgraph for file containing elements
11031110
output.push_str(&format!(" subgraph {}[\"📄 {}\"]\n", file_id, file.name));
1111+
output.push_str(" direction TB\n");
11041112

11051113
// Generate element nodes
11061114
for element in &file.elements {

core/src/export.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ pub fn generate_artifacts_in_temp(
309309
filesystem::write_file("coverage.md", coverage_text.as_bytes())?;
310310

311311
info!("Generating containment.md...");
312-
let containment_diagram = crate::diagrams::generate_containment_diagram(&temp_model_manager.graph_registry)?;
312+
let containment_diagram = crate::diagrams::generate_containment_diagram(&temp_model_manager.graph_registry, false)?;
313313
filesystem::write_file("containment.md", containment_diagram.as_bytes())?;
314314

315315
// Step 6: Convert markdown to HTML
Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Generate Diagrams and Traces SVG on PR Merge
1+
name: Update Documentation on PR Merge
22

33
on:
44
pull_request:
@@ -7,40 +7,40 @@ on:
77
- main
88

99
jobs:
10-
generate-diagrams:
10+
update-docs:
1111
if: github.event.pull_request.merged == true && !startsWith(github.event.pull_request.head.ref, 'release/')
12-
name: Generate and Commit Diagrams
12+
name: Export and Update Documentation
1313
runs-on: ubuntu-latest
14-
14+
1515
permissions:
16-
contents: write # Required to commit to the repository
17-
16+
contents: write
17+
1818
steps:
1919
- name: Checkout Repository
2020
uses: actions/checkout@v4
2121
with:
22-
ref: main # Checkout the main branch
23-
fetch-depth: 0 # Get full history for proper Git operations
24-
22+
ref: main
23+
fetch-depth: 0
24+
2525
- name: Set up Rust
2626
uses: dtolnay/rust-toolchain@stable
27-
27+
2828
- name: Cache Cargo dependencies
2929
uses: Swatinem/rust-cache@v2
30-
30+
3131
- name: Build Reqvire
3232
run: |
3333
cargo build --release
3434
cp target/release/reqvire ./reqvire
35-
35+
3636
- name: Configure Git
3737
run: |
3838
git config --global user.name "GitHub Action"
3939
git config --global user.email "actions@github.com"
40-
41-
- name: Generate Diagrams
40+
41+
- name: Export Documentation to docs folder
4242
run: |
43-
./reqvire generate-diagrams
43+
./reqvire export --output docs
4444
4545
- name: Check for Changes
4646
id: check_changes
@@ -50,10 +50,10 @@ jobs:
5050
else
5151
echo "HAS_CHANGES=false" >> $GITHUB_ENV
5252
fi
53-
53+
5454
- name: Commit and Push Changes
5555
if: env.HAS_CHANGES == 'true'
5656
run: |
5757
git add -A
58-
git commit -m "Auto-generate diagrams after PR merge to main"
58+
git commit -m "Auto-update documentation after PR merge"
5959
git push origin main

docs/cli/src/cli.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,15 @@ pub enum Commands {
389389
},
390390

391391
/// Generate containment view showing folder/file/element hierarchy
392-
#[clap(override_help = "Generate containment view showing folder/file/element hierarchy\n\nCONTAINMENT OPTIONS:\n --json Output results in JSON format")]
392+
#[clap(override_help = "Generate containment view showing folder/file/element hierarchy\n\nCONTAINMENT OPTIONS:\n --json Output results in JSON format\n --short Show only root elements (without hierarchical parents)")]
393393
Containment {
394394
/// Output results in JSON format
395395
#[clap(long, help_heading = "CONTAINMENT OPTIONS")]
396396
json: bool,
397+
398+
/// Show only root elements (without hierarchical parents in same file)
399+
#[clap(long, help_heading = "CONTAINMENT OPTIONS")]
400+
short: bool,
397401
},
398402

399403
/// Interactive shell for GraphRegistry operations (undocumented)
@@ -1078,16 +1082,16 @@ pub fn handle_command(
10781082
render_crud_result(&result);
10791083
return Ok(0);
10801084
},
1081-
Some(Commands::Containment { json }) => {
1085+
Some(Commands::Containment { json, short }) => {
10821086
if json {
10831087
// Build containment hierarchy
1084-
let hierarchy = reqvire::containment::ContainmentHierarchy::build(&model_manager.graph_registry)?;
1088+
let hierarchy = reqvire::containment::ContainmentHierarchy::build(&model_manager.graph_registry, short)?;
10851089
// Serialize to JSON
10861090
let json_output = serde_json::to_string_pretty(&hierarchy)
10871091
.map_err(|e| ReqvireError::ElementError(format!("JSON serialization error: {}", e)))?;
10881092
println!("{}", json_output);
10891093
} else {
1090-
let output = diagrams::generate_containment_diagram(&model_manager.graph_registry)?;
1094+
let output = diagrams::generate_containment_diagram(&model_manager.graph_registry, short)?;
10911095
println!("{}", output);
10921096
}
10931097
return Ok(0);

0 commit comments

Comments
 (0)