diff --git a/MODULE.bazel b/MODULE.bazel index d3f3c8b..e4b537f 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -28,6 +28,14 @@ pip.parse( use_repo(pip, "trlc_dependencies") +pip.parse( + hub_name = "trlc_renderer_dependencies", + python_version = "3.12", + requirements_lock = "//renderer:requirements_lock.txt", +) + +use_repo(pip, "trlc_renderer_dependencies") + http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 599ca36..92f5edb 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1,6 +1,6 @@ { "lockFileVersion": 6, - "moduleFileHash": "d1aa03ce3bc4998f68ee9b5fa371dfa11e9d9045cc027a323cf921effb6fd544", + "moduleFileHash": "d8e0c11600a908e1c981d634269ee00d3530bc64a772deee664c72cfe65eb9b6", "flags": { "cmdRegistries": [ "https://bcr.bazel.build/" @@ -42,7 +42,7 @@ "tagName": "toolchain", "attributeValues": { "is_default": true, - "python_version": "3.11" + "python_version": "3.12" }, "devDependency": false, "location": { @@ -65,7 +65,8 @@ "column": 20 }, "imports": { - "trlc_dependencies": "trlc_dependencies" + "trlc_dependencies": "trlc_dependencies", + "trlc_renderer_dependencies": "trlc_renderer_dependencies" }, "devImports": [], "tags": [ @@ -73,7 +74,7 @@ "tagName": "parse", "attributeValues": { "hub_name": "trlc_dependencies", - "python_version": "3.11", + "python_version": "3.12", "requirements_lock": "//:requirements.txt" }, "devDependency": false, @@ -82,6 +83,20 @@ "line": 23, "column": 10 } + }, + { + "tagName": "parse", + "attributeValues": { + "hub_name": "trlc_renderer_dependencies", + "python_version": "3.12", + "requirements_lock": "//renderer:requirements_lock.txt" + }, + "devDependency": false, + "location": { + "file": "@@//:MODULE.bazel", + "line": 31, + "column": 10 + } } ], "hasDevUseExtension": false, @@ -107,15 +122,15 @@ "tagName": "@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributeValues": { "build_file": "@trlc//:cvc5.BUILD", - "sha256": "cf291aef67da8eaa8d425a51f67f3f72f36db8b1040655dc799b64e3d69e6086", - "strip_prefix": "cvc5-Linux-static", - "url": "https://github.com/cvc5/cvc5/releases/download/cvc5-1.1.2/cvc5-Linux-static.zip", + "sha256": "ab9344e2dddda794669c888a3afcd99f25f2627e1d426bd7d08ecb267361b331", + "strip_prefix": "cvc5-Linux-x86_64-static-gpl", + "url": "https://github.com/cvc5/cvc5/releases/download/cvc5-1.2.0/cvc5-Linux-x86_64-static-gpl.zip", "name": "cvc5_linux" }, "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 33, + "line": 41, "column": 13 } }, @@ -123,15 +138,15 @@ "tagName": "@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributeValues": { "build_file": "@trlc//:cvc5.BUILD", - "sha256": "561a5ee82416441fa616c6f416ecaae2fa2dfc06dc81c2c6cc8dcfb31936e326", - "strip_prefix": "cvc5-macOS-static", - "url": "https://github.com/cvc5/cvc5/releases/download/cvc5-1.1.2/cvc5-macOS-static.zip", + "sha256": "2b983ca743ef1327b51408bf8ba6c08c97beaadde2c3968da701ca16bb1e3740", + "strip_prefix": "cvc5-macOS-arm64-static-gpl", + "url": "https://github.com/cvc5/cvc5/releases/download/cvc5-1.2.0/cvc5-macOS-arm64-static-gpl.zip", "name": "cvc5_mac" }, "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 41, + "line": 49, "column": 13 } }, @@ -139,15 +154,15 @@ "tagName": "@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributeValues": { "build_file": "@trlc//:cvc5.BUILD", - "sha256": "f06715b796020c810b2713e6df3969dae99d38c24d2a6eac225a029fc70fe1ee", - "strip_prefix": "cvc5-Win64-static", - "url": "https://github.com/cvc5/cvc5/releases/download/cvc5-1.1.2/cvc5-Win64-static.zip", + "sha256": "256f4af3f4181e770801df436852cb3c76c86dbf9b69a47064d7f8d5bc0ee1d2", + "strip_prefix": "cvc5-Win64-x86_64-static", + "url": "https://github.com/cvc5/cvc5/releases/download/cvc5-1.2.0/cvc5-Win64-x86_64-static.zip", "name": "cvc5_windows" }, "devDependency": false, "location": { "file": "@@//:MODULE.bazel", - "line": 49, + "line": 57, "column": 13 } } @@ -2962,24 +2977,33 @@ }, "@@rules_python~//python/extensions:pip.bzl%pip": { "os:linux,arch:amd64": { - "bzlTransitiveDigest": "0gZJEM7jEV2MrLCzKZVk0IIzCKChDWnMpbekGUC2Udc=", + "bzlTransitiveDigest": "gh4aiz5+D6NTIqyAgddebCgJ8kAdIC06MngwcS1CrWA=", "recordedFileInputs": { - "@@//requirements.txt": "e0808b352560a9317b342b353e02a42ab6578a0e4050334c5b0928054d14c7da" + "@@//requirements.txt": "b9318249d997255dc8b9f944f861ed8bf5ade7000888bc898efa8c3af978c29b", + "@@//renderer/requirements_lock.txt": "2e5116d75b40a3355df9861157bb059eade3af27d2d2b1460a6b4062a8c7db25" }, "recordedDirentsInputs": {}, "envVariables": {}, "generatedRepoSpecs": { - "trlc_dependencies_311_cvc5": { + "trlc_renderer_dependencies_312__groups": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "group_library", + "attributes": { + "repo_prefix": "trlc_renderer_dependencies_312_", + "groups": {} + } + }, + "trlc_renderer_dependencies_312_bigtree": { "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", "ruleClassName": "whl_library", "attributes": { - "requirement": "cvc5>=1.1.1; sys.platform == \"linux\" or sys.platform == \"darwin\"", - "repo": "trlc_dependencies_311", - "repo_prefix": "trlc_dependencies_311_", + "requirement": "bigtree==0.9.5 --hash=sha256:543ebb92d32bf0b2eb764255ab29b6501741934a2e0e82f31b465e4c647b3df4 --hash=sha256:ce774ac48c5a7896c6cee923429980fc0d7571fc32a1e4876e827dfa5b0678e4", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", "whl_patches": {}, "experimental_target_platforms": [], "python_interpreter": "", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", "quiet": true, "timeout": 600, "isolated": true, @@ -2993,33 +3017,126 @@ "group_deps": [] } }, - "trlc_dependencies": { + "trlc_renderer_dependencies_312_pydot": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "pydot==4.0.1 --hash=sha256:869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6 --hash=sha256:c2148f681c4a33e08bf0e26a9e5f8e4099a82e0e2a068098f32ce86577364ad5", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_renderer_dependencies_312_six": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "six==1.17.0 --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_renderer_dependencies": { "bzlFile": "@@rules_python~//python/private/bzlmod:pip_repository.bzl", "ruleClassName": "pip_repository", "attributes": { - "repo_name": "trlc_dependencies", + "repo_name": "trlc_renderer_dependencies", "whl_map": { - "cvc5": [ - "3.11" + "bigtree": [ + "3.12" ], - "pyvcg": [ - "3.11" + "numpy": [ + "3.12" + ], + "pandas": [ + "3.12" + ], + "pydot": [ + "3.12" + ], + "pyparsing": [ + "3.12" + ], + "python_dateutil": [ + "3.12" + ], + "pytz": [ + "3.12" + ], + "six": [ + "3.12" + ], + "tzdata": [ + "3.12" ] }, - "default_version": "3.11" + "default_version": "3.12" + } + }, + "trlc_renderer_dependencies_312_pandas": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "pandas==2.3.1 --hash=sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232 --hash=sha256:09e3b1587f0f3b0913e21e8b32c3119174551deb4a4eba4a89bc7377947977e7 --hash=sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2 --hash=sha256:0f951fbb702dacd390561e0ea45cdd8ecfa7fb56935eb3dd78e306c19104b9b0 --hash=sha256:1b916a627919a247d865aed068eb65eb91a344b13f5b57ab9f610b7716c92de1 --hash=sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956 --hash=sha256:1d12f618d80379fde6af007f65f0c25bd3e40251dbd1636480dfffce2cf1e6da --hash=sha256:22c2e866f7209ebc3a8f08d75766566aae02bcc91d196935a1d9e59c7b990ac9 --hash=sha256:2323294c73ed50f612f67e2bf3ae45aea04dce5690778e08a09391897f35ff88 --hash=sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b --hash=sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9 --hash=sha256:2eb789ae0274672acbd3c575b0598d213345660120a257b47b5dafdc618aec83 --hash=sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab --hash=sha256:342e59589cc454aaff7484d75b816a433350b3d7964d7847327edda4d532a2e3 --hash=sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d --hash=sha256:3583d348546201aff730c8c47e49bc159833f971c2899d6097bce68b9112a4f1 --hash=sha256:4645f770f98d656f11c69e81aeb21c6fca076a44bed3dcbb9396a4311bc7f6d8 --hash=sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299 --hash=sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8 --hash=sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444 --hash=sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3 --hash=sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a --hash=sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb --hash=sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928 --hash=sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4 --hash=sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a --hash=sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22 --hash=sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275 --hash=sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678 --hash=sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e --hash=sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8 --hash=sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab --hash=sha256:b4b0de34dc8499c2db34000ef8baad684cfa4cbd836ecee05f323ebfba348c7d --hash=sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679 --hash=sha256:cd05b72ec02ebfb993569b4931b2e16fbb4d6ad6ce80224a3ee838387d83a191 --hash=sha256:dd71c47a911da120d72ef173aeac0bf5241423f9bfea57320110a978457e069e --hash=sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12 --hash=sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85 --hash=sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9 --hash=sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96 --hash=sha256:fe67dc676818c186d5a3d5425250e40f179c2a89145df477dd82945eaea89e97 --hash=sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] } }, - "trlc_dependencies_311_pyvcg": { + "trlc_renderer_dependencies_312_tzdata": { "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", "ruleClassName": "whl_library", "attributes": { - "requirement": "pyvcg==1.0.6", - "repo": "trlc_dependencies_311", - "repo_prefix": "trlc_dependencies_311_", + "requirement": "tzdata==2025.2 --hash=sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 --hash=sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", "whl_patches": {}, "experimental_target_platforms": [], "python_interpreter": "", - "python_interpreter_target": "@@rules_python~~python~python_3_11_host//:python", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", "quiet": true, "timeout": 600, "isolated": true, @@ -3033,13 +3150,173 @@ "group_deps": [] } }, - "trlc_dependencies_311__groups": { + "trlc_renderer_dependencies_312_python_dateutil": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "python-dateutil==2.9.0.post0 --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_renderer_dependencies_312_pyparsing": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "pyparsing==3.2.3 --hash=sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf --hash=sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_dependencies_312_pyvcg": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "pyvcg==1.0.7", + "repo": "trlc_dependencies_312", + "repo_prefix": "trlc_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_dependencies_312__groups": { "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", "ruleClassName": "group_library", "attributes": { - "repo_prefix": "trlc_dependencies_311_", + "repo_prefix": "trlc_dependencies_312_", "groups": {} } + }, + "trlc_dependencies_312_cvc5": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "cvc5>=1.2.0", + "repo": "trlc_dependencies_312", + "repo_prefix": "trlc_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_renderer_dependencies_312_numpy": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "numpy==2.3.2 --hash=sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5 --hash=sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b --hash=sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631 --hash=sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58 --hash=sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b --hash=sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc --hash=sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089 --hash=sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf --hash=sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15 --hash=sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f --hash=sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3 --hash=sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170 --hash=sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910 --hash=sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91 --hash=sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45 --hash=sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c --hash=sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f --hash=sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b --hash=sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89 --hash=sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a --hash=sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220 --hash=sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e --hash=sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab --hash=sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2 --hash=sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b --hash=sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370 --hash=sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2 --hash=sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee --hash=sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619 --hash=sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712 --hash=sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1 --hash=sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec --hash=sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a --hash=sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450 --hash=sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a --hash=sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2 --hash=sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168 --hash=sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2 --hash=sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73 --hash=sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296 --hash=sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9 --hash=sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125 --hash=sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0 --hash=sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19 --hash=sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b --hash=sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f --hash=sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2 --hash=sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f --hash=sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a --hash=sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6 --hash=sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286 --hash=sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981 --hash=sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f --hash=sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2 --hash=sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0 --hash=sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b --hash=sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b --hash=sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56 --hash=sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5 --hash=sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3 --hash=sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8 --hash=sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0 --hash=sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036 --hash=sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6 --hash=sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8 --hash=sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48 --hash=sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07 --hash=sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b --hash=sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b --hash=sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d --hash=sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0 --hash=sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097 --hash=sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be --hash=sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } + }, + "trlc_dependencies": { + "bzlFile": "@@rules_python~//python/private/bzlmod:pip_repository.bzl", + "ruleClassName": "pip_repository", + "attributes": { + "repo_name": "trlc_dependencies", + "whl_map": { + "cvc5": [ + "3.12" + ], + "pyvcg": [ + "3.12" + ] + }, + "default_version": "3.12" + } + }, + "trlc_renderer_dependencies_312_pytz": { + "bzlFile": "@@rules_python~//python/pip_install:pip_repository.bzl", + "ruleClassName": "whl_library", + "attributes": { + "requirement": "pytz==2025.2 --hash=sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3 --hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", + "repo": "trlc_renderer_dependencies_312", + "repo_prefix": "trlc_renderer_dependencies_312_", + "whl_patches": {}, + "experimental_target_platforms": [], + "python_interpreter": "", + "python_interpreter_target": "@@rules_python~~python~python_3_12_host//:python", + "quiet": true, + "timeout": 600, + "isolated": true, + "extra_pip_args": [], + "download_only": false, + "pip_data_exclude": [], + "enable_implicit_namespace_pkgs": false, + "environment": {}, + "envsubst": [], + "group_name": "", + "group_deps": [] + } } }, "recordedRepoMappingEntries": [ @@ -3157,6 +3434,16 @@ "rules_python~~python~pythons_hub", "python_3_11_x86_64-unknown-linux-gnu", "rules_python~~python~python_3_11_x86_64-unknown-linux-gnu" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_host", + "rules_python~~python~python_3_12_host" + ], + [ + "rules_python~~python~pythons_hub", + "python_3_12_x86_64-unknown-linux-gnu", + "rules_python~~python~python_3_12_x86_64-unknown-linux-gnu" ] ] } @@ -3203,12 +3490,143 @@ ] } }, - "python_3_11": { + "python_3_11_aarch64-unknown-linux-gnu": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "b102eaf865eb715aa98a8a2ef19037b6cc3ae7dfd4a632802650f29de635aa13", + "patches": [], + "platform": "aarch64-unknown-linux-gnu", + "python_version": "3.11.7", + "release_filename": "20240107/cpython-3.11.7+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_11_aarch64-apple-darwin": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "b042c966920cf8465385ca3522986b12d745151a72c060991088977ca36d3883", + "patches": [], + "platform": "aarch64-apple-darwin", + "python_version": "3.11.7", + "release_filename": "20240107/cpython-3.11.7+20240107-aarch64-apple-darwin-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-aarch64-apple-darwin-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "pythons_hub": { + "bzlFile": "@@rules_python~//python/private/bzlmod:pythons_hub.bzl", + "ruleClassName": "hub_repo", + "attributes": { + "default_python_version": "3.12", + "toolchain_prefixes": [ + "_0000_python_3_11_", + "_0001_python_3_12_" + ], + "toolchain_python_versions": [ + "3.11", + "3.12" + ], + "toolchain_set_python_version_constraints": [ + "True", + "False" + ], + "toolchain_user_repository_names": [ + "python_3_11", + "python_3_12" + ] + } + }, + "python_3_12_x86_64-pc-windows-msvc": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "fd5a9e0f41959d0341246d3643f2b8794f638adc0cec8dd5e1b6465198eae08a", + "patches": [], + "platform": "x86_64-pc-windows-msvc", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_12_x86_64-unknown-linux-gnu": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "74e330b8212ca22fd4d9a2003b9eec14892155566738febc8e5e572f267b9472", + "patches": [], + "platform": "x86_64-unknown-linux-gnu", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-x86_64-unknown-linux-gnu-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_11_x86_64-pc-windows-msvc": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "67077e6fa918e4f4fd60ba169820b00be7c390c497bf9bc9cab2c255ea8e6f3e", + "patches": [], + "platform": "x86_64-pc-windows-msvc", + "python_version": "3.11.7", + "release_filename": "20240107/cpython-3.11.7+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_12_aarch64-apple-darwin": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "f93f8375ca6ac0a35d58ff007043cbd3a88d9609113f1cb59cf7c8d215f064af", + "patches": [], + "platform": "aarch64-apple-darwin", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-aarch64-apple-darwin-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-aarch64-apple-darwin-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_12": { "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", "ruleClassName": "toolchain_aliases", "attributes": { - "python_version": "3.11.7", - "user_repository_name": "python_3_11", + "python_version": "3.12.1", + "user_repository_name": "python_3_12", "platforms": [ "aarch64-apple-darwin", "aarch64-unknown-linux-gnu", @@ -3220,17 +3638,17 @@ ] } }, - "python_3_11_aarch64-unknown-linux-gnu": { + "python_3_12_x86_64-apple-darwin": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "b102eaf865eb715aa98a8a2ef19037b6cc3ae7dfd4a632802650f29de635aa13", + "sha256": "eca96158c1568dedd9a0b3425375637a83764d1fa74446438293089a8bfac1f8", "patches": [], - "platform": "aarch64-unknown-linux-gnu", - "python_version": "3.11.7", - "release_filename": "20240107/cpython-3.11.7+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz", + "platform": "x86_64-apple-darwin", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-x86_64-apple-darwin-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-x86_64-apple-darwin-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", @@ -3238,17 +3656,35 @@ "ignore_root_user_error": false } }, - "python_3_11_aarch64-apple-darwin": { + "python_3_12_s390x-unknown-linux-gnu": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "b042c966920cf8465385ca3522986b12d745151a72c060991088977ca36d3883", + "sha256": "60631211c701f8d2c56e5dd7b154e68868128a019b9db1d53a264f56c0d4aee2", "patches": [], - "platform": "aarch64-apple-darwin", - "python_version": "3.11.7", - "release_filename": "20240107/cpython-3.11.7+20240107-aarch64-apple-darwin-install_only.tar.gz", + "platform": "s390x-unknown-linux-gnu", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-s390x-unknown-linux-gnu-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-aarch64-apple-darwin-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-s390x-unknown-linux-gnu-install_only.tar.gz" + ], + "distutils_content": "", + "strip_prefix": "python", + "coverage_tool": "", + "ignore_root_user_error": false + } + }, + "python_3_12_aarch64-unknown-linux-gnu": { + "bzlFile": "@@rules_python~//python:repositories.bzl", + "ruleClassName": "python_repository", + "attributes": { + "sha256": "236533ef20e665007a111c2f36efb59c87ae195ad7dca223b6dc03fb07064f0b", + "patches": [], + "platform": "aarch64-unknown-linux-gnu", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz", + "urls": [ + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-aarch64-unknown-linux-gnu-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", @@ -3256,6 +3692,23 @@ "ignore_root_user_error": false } }, + "python_3_11": { + "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", + "ruleClassName": "toolchain_aliases", + "attributes": { + "python_version": "3.11.7", + "user_repository_name": "python_3_11", + "platforms": [ + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "ppc64le-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu" + ] + } + }, "python_3_11_ppc64le-unknown-linux-gnu": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", @@ -3292,45 +3745,27 @@ "ignore_root_user_error": false } }, - "pythons_hub": { - "bzlFile": "@@rules_python~//python/private/bzlmod:pythons_hub.bzl", - "ruleClassName": "hub_repo", - "attributes": { - "default_python_version": "3.11", - "toolchain_prefixes": [ - "_0000_python_3_11_" - ], - "toolchain_python_versions": [ - "3.11" - ], - "toolchain_set_python_version_constraints": [ - "False" - ], - "toolchain_user_repository_names": [ - "python_3_11" - ] - } - }, "python_versions": { "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", "ruleClassName": "multi_toolchain_aliases", "attributes": { "python_versions": { + "3.12": "python_3_12", "3.11": "python_3_11" } } }, - "python_3_11_x86_64-pc-windows-msvc": { + "python_3_12_ppc64le-unknown-linux-gnu": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", "attributes": { - "sha256": "67077e6fa918e4f4fd60ba169820b00be7c390c497bf9bc9cab2c255ea8e6f3e", + "sha256": "78051f0d1411ee62bc2af5edfccf6e8400ac4ef82887a2affc19a7ace6a05267", "patches": [], - "platform": "x86_64-pc-windows-msvc", - "python_version": "3.11.7", - "release_filename": "20240107/cpython-3.11.7+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz", + "platform": "ppc64le-unknown-linux-gnu", + "python_version": "3.12.1", + "release_filename": "20240107/cpython-3.12.1+20240107-ppc64le-unknown-linux-gnu-install_only.tar.gz", "urls": [ - "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.11.7+20240107-x86_64-pc-windows-msvc-shared-install_only.tar.gz" + "https://github.com/indygreg/python-build-standalone/releases/download/20240107/cpython-3.12.1+20240107-ppc64le-unknown-linux-gnu-install_only.tar.gz" ], "distutils_content": "", "strip_prefix": "python", @@ -3338,6 +3773,23 @@ "ignore_root_user_error": false } }, + "python_3_12_host": { + "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl", + "ruleClassName": "host_toolchain", + "attributes": { + "python_version": "3.12.1", + "user_repository_name": "python_3_12", + "platforms": [ + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "ppc64le-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-msvc", + "x86_64-unknown-linux-gnu" + ] + } + }, "python_3_11_x86_64-unknown-linux-gnu": { "bzlFile": "@@rules_python~//python:repositories.bzl", "ruleClassName": "python_repository", diff --git a/renderer/BUILD b/renderer/BUILD new file mode 100644 index 0000000..6c78574 --- /dev/null +++ b/renderer/BUILD @@ -0,0 +1,20 @@ +load("@rules_python//python:pip.bzl", "compile_pip_requirements") +load("@trlc_renderer_dependencies//:requirements.bzl", "requirement") + + +compile_pip_requirements( + name = "requirements", + src = "requirements.in", + requirements_txt = "requirements_lock.txt", +) + +py_binary( + name = "trlc_renderer", + srcs = ["trlc_renderer.py"], + visibility = ["//visibility:public"], + deps = [ + requirement("bigtree"), + requirement("pydot"), + "//trlc", + ], +) diff --git a/renderer/README.md b/renderer/README.md new file mode 100644 index 0000000..bc03198 --- /dev/null +++ b/renderer/README.md @@ -0,0 +1,59 @@ +# Renderer + +`Renderer` helps to view requirements written in TRLC as ReStructuredText. +This way, it is possible to generate and HTML or PDF version of them, using Sphinx. + +The `Renderer` can be used as follows + +``` +load("//tools/trlc_renderer:trlc_renderer.bzl", "trlc_renderer") +load("@trlc//:trlc.bzl", "trlc_requirements") + +trlc_requirements( + name = "some_requriement", + srcs = ["some_requirement.trlc"], + spec = [...], +) + +trlc_renderer( + name = "requirements", + reqs = [":some_requirement"], +) + +``` + +## Design + +In general the `Renderer` is right now quite simple. It parses the TRLC files, using the TRLC Python library, then creates a tree of requirements including its sections. In a last step it writes the requirements in the rst file including the sections as headlines. + +### Mapping + +If the requirement types in the TRLC Model and in the rst file should differ it is possible to specify a mapping file (--mapping) in following format: + +```json + +"Type in TRLC": { + "mapped_type": "Type in RST", + // Specify the attributes which should be exported into the rst file. It is possible to provide a default value (attribute = value). This value applies if the attribute is not found in the TRLC model + "attributes": [ + "status", + "security = yes" + ], + // Specify the links which should be exported. In contrary to the attributes the links are formatted according to the defined format before they are written into the rst file + "links": ["derived_from", "satisfied_by"], + // Definition of the Format how the ID should be converted in the rst file. It is also possible to specify casing + "generate_id_format": "{type}__{package}__{name}", + "id_case_format": { + "type": "screaming_snake_case", + "package": "snake_case", + "name": "snake_case" + } + }, + +``` + +If no mapping file is specified all types and attributes are exported 1:1 into the rst file. + +### Sequence Diagram + +[TRLC Renderer Sequence Diagramm](assets/trlc_renderer_seq.puml) diff --git a/renderer/assets/trlc_renderer_seq.puml b/renderer/assets/trlc_renderer_seq.puml new file mode 100644 index 0000000..23b3579 --- /dev/null +++ b/renderer/assets/trlc_renderer_seq.puml @@ -0,0 +1,27 @@ +@startuml +participant "TRLCRenderer" as Renderer +participant "Source_Manager" as SourceManager +participant "TRLC AST" as TRLC +participant "Output File" as Output + +== Initialization == +Renderer -> Renderer: load_type_mapping(mapping_file) +Renderer -> Renderer: parse_trlc_files_in() + +== Create AST == +Renderer -> SourceManager: Source_Manager(Handler) +SourceManager -> Renderer: register_directory(input_directory) +SourceManager -> TRLC: process() +TRLC -> Renderer: return symbols + +== Convert AST == +Renderer -> Renderer: convert_symbols_to_objects() +Renderer -> Renderer: build_parent_tree(section) + +== Write Output == +Renderer -> Renderer: render_restructured_text_file() +Renderer -> Output: write output +Output -> Renderer: output complete + + +@enduml diff --git a/renderer/requirements.in b/renderer/requirements.in new file mode 100644 index 0000000..fb53211 --- /dev/null +++ b/renderer/requirements.in @@ -0,0 +1,2 @@ +bigtree==0.9.5 +pydot==4.0.1 \ No newline at end of file diff --git a/renderer/requirements_lock.txt b/renderer/requirements_lock.txt new file mode 100644 index 0000000..0d4dfa3 --- /dev/null +++ b/renderer/requirements_lock.txt @@ -0,0 +1,154 @@ +# +# This file is autogenerated by pip-compile with Python 3.12 +# by the following command: +# +# bazel run //renderer:requirements.update +# +bigtree==0.9.5 \ + --hash=sha256:543ebb92d32bf0b2eb764255ab29b6501741934a2e0e82f31b465e4c647b3df4 \ + --hash=sha256:ce774ac48c5a7896c6cee923429980fc0d7571fc32a1e4876e827dfa5b0678e4 + # via -r renderer/requirements.in +numpy==2.3.2 \ + --hash=sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5 \ + --hash=sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b \ + --hash=sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631 \ + --hash=sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58 \ + --hash=sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b \ + --hash=sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc \ + --hash=sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089 \ + --hash=sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf \ + --hash=sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15 \ + --hash=sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f \ + --hash=sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3 \ + --hash=sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170 \ + --hash=sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910 \ + --hash=sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91 \ + --hash=sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45 \ + --hash=sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c \ + --hash=sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f \ + --hash=sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b \ + --hash=sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89 \ + --hash=sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a \ + --hash=sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220 \ + --hash=sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e \ + --hash=sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab \ + --hash=sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2 \ + --hash=sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b \ + --hash=sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370 \ + --hash=sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2 \ + --hash=sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee \ + --hash=sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619 \ + --hash=sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712 \ + --hash=sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1 \ + --hash=sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec \ + --hash=sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a \ + --hash=sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450 \ + --hash=sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a \ + --hash=sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2 \ + --hash=sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168 \ + --hash=sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2 \ + --hash=sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73 \ + --hash=sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296 \ + --hash=sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9 \ + --hash=sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125 \ + --hash=sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0 \ + --hash=sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19 \ + --hash=sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b \ + --hash=sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f \ + --hash=sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2 \ + --hash=sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f \ + --hash=sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a \ + --hash=sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6 \ + --hash=sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286 \ + --hash=sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981 \ + --hash=sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f \ + --hash=sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2 \ + --hash=sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0 \ + --hash=sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b \ + --hash=sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b \ + --hash=sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56 \ + --hash=sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5 \ + --hash=sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3 \ + --hash=sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8 \ + --hash=sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0 \ + --hash=sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036 \ + --hash=sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6 \ + --hash=sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8 \ + --hash=sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48 \ + --hash=sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07 \ + --hash=sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b \ + --hash=sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b \ + --hash=sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d \ + --hash=sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0 \ + --hash=sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097 \ + --hash=sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be \ + --hash=sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5 + # via pandas +pandas==2.3.1 \ + --hash=sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232 \ + --hash=sha256:09e3b1587f0f3b0913e21e8b32c3119174551deb4a4eba4a89bc7377947977e7 \ + --hash=sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2 \ + --hash=sha256:0f951fbb702dacd390561e0ea45cdd8ecfa7fb56935eb3dd78e306c19104b9b0 \ + --hash=sha256:1b916a627919a247d865aed068eb65eb91a344b13f5b57ab9f610b7716c92de1 \ + --hash=sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956 \ + --hash=sha256:1d12f618d80379fde6af007f65f0c25bd3e40251dbd1636480dfffce2cf1e6da \ + --hash=sha256:22c2e866f7209ebc3a8f08d75766566aae02bcc91d196935a1d9e59c7b990ac9 \ + --hash=sha256:2323294c73ed50f612f67e2bf3ae45aea04dce5690778e08a09391897f35ff88 \ + --hash=sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b \ + --hash=sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9 \ + --hash=sha256:2eb789ae0274672acbd3c575b0598d213345660120a257b47b5dafdc618aec83 \ + --hash=sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab \ + --hash=sha256:342e59589cc454aaff7484d75b816a433350b3d7964d7847327edda4d532a2e3 \ + --hash=sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d \ + --hash=sha256:3583d348546201aff730c8c47e49bc159833f971c2899d6097bce68b9112a4f1 \ + --hash=sha256:4645f770f98d656f11c69e81aeb21c6fca076a44bed3dcbb9396a4311bc7f6d8 \ + --hash=sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299 \ + --hash=sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8 \ + --hash=sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444 \ + --hash=sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3 \ + --hash=sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a \ + --hash=sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb \ + --hash=sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928 \ + --hash=sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4 \ + --hash=sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a \ + --hash=sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22 \ + --hash=sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275 \ + --hash=sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678 \ + --hash=sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e \ + --hash=sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8 \ + --hash=sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab \ + --hash=sha256:b4b0de34dc8499c2db34000ef8baad684cfa4cbd836ecee05f323ebfba348c7d \ + --hash=sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679 \ + --hash=sha256:cd05b72ec02ebfb993569b4931b2e16fbb4d6ad6ce80224a3ee838387d83a191 \ + --hash=sha256:dd71c47a911da120d72ef173aeac0bf5241423f9bfea57320110a978457e069e \ + --hash=sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12 \ + --hash=sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85 \ + --hash=sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9 \ + --hash=sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96 \ + --hash=sha256:fe67dc676818c186d5a3d5425250e40f179c2a89145df477dd82945eaea89e97 \ + --hash=sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f + # via bigtree +pydot==4.0.1 \ + --hash=sha256:869c0efadd2708c0be1f916eb669f3d664ca684bc57ffb7ecc08e70d5e93fee6 \ + --hash=sha256:c2148f681c4a33e08bf0e26a9e5f8e4099a82e0e2a068098f32ce86577364ad5 + # via -r renderer/requirements.in +pyparsing==3.2.3 \ + --hash=sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf \ + --hash=sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be + # via pydot +python-dateutil==2.9.0.post0 \ + --hash=sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3 \ + --hash=sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 + # via pandas +pytz==2025.2 \ + --hash=sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3 \ + --hash=sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 + # via pandas +six==1.17.0 \ + --hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \ + --hash=sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81 + # via python-dateutil +tzdata==2025.2 \ + --hash=sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 \ + --hash=sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9 + # via pandas diff --git a/renderer/trlc_renderer.bzl b/renderer/trlc_renderer.bzl new file mode 100644 index 0000000..c30bae9 --- /dev/null +++ b/renderer/trlc_renderer.bzl @@ -0,0 +1,31 @@ +def _trlc_renderer_impl(ctx): + rendered_file = ctx.actions.declare_file("{}.rst".format(ctx.attr.name)) + args = ctx.actions.args() + args.add("--output", rendered_file.path) + + # Add the mapping file from the filegroup + for req in ctx.files.reqs: + if req.basename == "mapping.json": + args.add("--mapping", req.path) + + ctx.actions.run( + inputs = ctx.files.reqs, + outputs = [rendered_file], + arguments = [args], + executable = ctx.executable._renderer, + ) + + return [DefaultInfo(files = depset([rendered_file]))] + +trlc_renderer = rule( + implementation = _trlc_renderer_impl, + attrs = { + "reqs": attr.label_list(allow_files = True), + "_renderer": attr.label( + default = Label("@trlc//renderer:trlc_renderer"), + executable = True, + allow_files = True, + cfg = "exec", + ), + }, +) diff --git a/renderer/trlc_renderer.py b/renderer/trlc_renderer.py new file mode 100644 index 0000000..0a8be32 --- /dev/null +++ b/renderer/trlc_renderer.py @@ -0,0 +1,235 @@ +import argparse +import re +import logging +import json # Import json for loading the mapping file +from bigtree import Node, preorder_iter +import trlc.ast +from trlc.errors import Message_Handler +from trlc.trlc import Source_Manager + +RST_HEADLINE_SEPERATOR = { + 0: "**********", + 1: "==========", + 2: "----------", + 3: "^^^^^^^^^^", +} + +class TRLCRenderer: + def __init__(self, input_directory: str, output_path: str, mapping_file: str = None, debug: bool = False): + self.input_directory = input_directory + self.output_path = output_path + self.debug = debug + self.symbols = None + self.requirements = None + self.req_objects = None + self.type_mapping = self.load_type_mapping(mapping_file) # Load the mapping file if provided + + if self.debug: + logging.basicConfig(level=logging.DEBUG) + + def load_type_mapping(self, mapping_file: str) -> dict: + """Load the requirement type mapping from a JSON file or return an empty mapping.""" + if mapping_file: + with open(mapping_file, 'r') as file: + mapping = json.load(file) + logging.debug("Loaded type mapping successfully.") + return mapping + else: + logging.debug("No mapping file provided; using default types.") + return {} # Return an empty mapping if no file is provided + + def parse_trlc_files_in(self) -> trlc.ast.Symbol_Table: + message_handler = Message_Handler() + source_manager = Source_Manager(message_handler) + source_manager.register_directory(self.input_directory) + self.symbols = source_manager.process() + + if self.symbols is None: + raise ValueError("Failed to parse TRLC Files") + + logging.debug("Parsed TRLC files successfully.") + return self.symbols + + def convert_symbols_to_objects(self): + requirements_root = Node("root") + object_list = {} + + for obj in self.symbols.iter_record_objects(): + parent_tree = self.build_parent_tree(obj.section, Node("root")) + parent_tree.append(Node(obj.fully_qualified_name())) + object_list[obj.fully_qualified_name()] = obj + + # Merge both trees + to_tree = requirements_root + for from_node in preorder_iter(parent_tree): + if from_node.is_root: + continue + + found_node = next((to_node for to_node in to_tree.children if to_node.name == from_node.name), None) + if found_node is None: + to_tree.append(from_node) + break + else: + to_tree = found_node + + self.requirements = requirements_root + self.req_objects = object_list + logging.debug("Converted symbols to objects successfully.") + + def apply_case_format(self, value: str, case_format: str) -> str: + """Apply the specified case format to a string.""" + if case_format == "snake_case": + return re.sub(r'(? str: + """Generates a unique identifier for a requirement object based on its type, package, + and its name using the format specified in the mapping file.""" + req_type = reqobj.n_typ.name + req_package = reqobj.n_package.name + req_name = reqobj.name + + # Get the ID format from the mapping + mapped_type, _, _ = self.map_requirement_type(req_type) + + id_format = self.type_mapping.get(req_type, {}).get("generate_id_format") + + # If no format is defined, use only the name + if id_format is None: + return req_name # Return only the name if no format is defined + + # Get the casing formats + id_case_format = self.type_mapping.get(req_type, {}).get("id_case_format", {}) + formatted_type = self.apply_case_format(mapped_type, id_case_format.get("type", "")) + formatted_package = self.apply_case_format(req_package, id_case_format.get("package", "")) + formatted_name = self.apply_case_format(req_name, id_case_format.get("name", "")) + + # Format the ID using the specified format + return id_format.format(type=formatted_type, package=formatted_package, name=formatted_name) + + def generate_link_id_score(self, link, objects) -> str: + """Generates a unique identifier for a link object based on its identifier and version, + using the same format as defined in generate_id_format.""" + linkobj = objects[link['item']] + # Use the same ID format for links + return self.generate_need_id(linkobj) + f"@{link['LinkVersion']}" + + def get_link_attribute_value(self, value) -> str: + """Generates the attribute value for link attributes.""" + return ', '.join(self.generate_link_id_score(v, self.req_objects) for v in value if v is not None) + + def map_requirement_type(self, req_type: str) -> tuple: + """Maps the requirement type using the loaded mapping or returns the original type and attributes.""" + mapping = self.type_mapping.get(req_type) + if mapping is None: + logging.debug(f"Type {req_type} not found in mapping, using {req_type} with default attributes.") + return req_type, [], [] # Return original type and empty attributes if not found + + # Extract the mapped type, attributes, and links + mapped_type = mapping.get("mapped_type", req_type) + attributes = mapping.get("attributes", []) + links = mapping.get("links", []) + + return mapped_type, attributes, links # Return mapped type, attributes, and links + def _convert_to_title(self, identifier: str) -> str: + transformed_title="" + for i in identifier: + if i.isupper(): + transformed_title+=" "+i + else: + transformed_title+=i + return transformed_title.join(" ") + + def render_restructured_text_file(self): + with open(self.output_path, "w", newline="") as file: + file.write("Requirements\n============\n") + + for node in preorder_iter(self.requirements): + if node.is_root: + continue + + if node.is_leaf: + reqobj = self.req_objects[node.name] + req_type = reqobj.n_typ.name # Get the requirement type + mapped_type, attributes_to_export, links_to_export = self.map_requirement_type(req_type) # Use mapping + + title = self._convert_to_title(node.name) + id = self.generate_need_id(reqobj) + + # Write the requirement header + file.write(f".. {mapped_type}:: {title}\n") + file.write(f" :id: {id}\n") + + reqobjpython_dict = reqobj.to_python_dict() + for attr in attributes_to_export: + # Split the attribute and default value if specified + if '=' in attr: + key, default_value = map(str.strip, attr.split('=', 1)) + else: + key, default_value = attr, "Not specified" + + if key not in reqobjpython_dict: + # Use default value if the attribute is not defined + file.write(f" :{key}: {default_value}\n") + continue + + value = reqobjpython_dict[key] + if key in links_to_export: + attr_val = self.get_link_attribute_value(value) + file.write(f" :{key}: {attr_val}\n") + else: + # Handle regular attributes + if isinstance(value, list): + attr_val = ', '.join( + str(v) if not isinstance(v, dict) else ', '.join(f"{v2}" for v2 in v.values()) + for v in value if v is not None + ) + else: + attr_val = str(value) if not isinstance(value, dict) else ', '.join(f"{v2}" for v2 in value.values()) + + file.write(f" :{key}: {attr_val}\n") + + # Output links even if they are not in attributes + for link in links_to_export: + if link in reqobjpython_dict: + link_value = reqobjpython_dict[link] + link_attr_val = self.get_link_attribute_value(link_value) + file.write(f" :{link}: {link_attr_val}\n") + + # Write the description at the end + file.write(f" {reqobj.field['description'].value}\n\n\n") + + def build_parent_tree(self, section: trlc.ast.Section, root) -> Node: + if section is None: + return root + parent = self.build_parent_tree(section.parent, root) + return Node(section.name, parent=parent) + + def run(self): + self.parse_trlc_files_in() + self.convert_symbols_to_objects() + self.render_restructured_text_file() + + +def argument_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser() + parser.add_argument("-o", "--output", required=True, help="Output file path") + parser.add_argument("-m", "--mapping", help="Path to the JSON mapping file (optional)") + parser.add_argument("--debug", action='store_true', help="Enable debug output") + return parser + + +def main() -> None: + parser = argument_parser() + args = parser.parse_args() + + renderer = TRLCRenderer(".", args.output, args.mapping, args.debug) + renderer.run() + + +if __name__ == "__main__": + main()