-
Notifications
You must be signed in to change notification settings - Fork 0
Feature MBEP#333 image support #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
4fe8e26
Added image support
michal-kurowski-n7s a1b6520
Added example project with SDL
michal-kurowski-n7s 131f9af
Test example for SDL behaviour generation (paths need fixing)
michal-kurowski-n7s bdfba5a
Image files are copied to the output directory
michal-kurowski-n7s 4169a2c
Fixed paths for docx generation
michal-kurowski-n7s 6793e62
Updated README
michal-kurowski-n7s de29421
Code cleanup
michal-kurowski-n7s 6625624
Improved loggign
michal-kurowski-n7s c434ff0
Added pillow dependency
michal-kurowski-n7s fdad30e
Merge branch 'main' into feature-mbep#333-image-support
michal-kurowski-n7s 6652d2b
Moved harness sources
michal-kurowski-n7s 8874845
Added better logging to template
michal-kurowski-n7s File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
179 changes: 179 additions & 0 deletions
179
data/ecss-template/ecss-e-st-40c_4_3_software_behaviour.tmplt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| <% | ||
| ## Data Initialization | ||
| # Get all functions | ||
|
|
||
| funcs = [] | ||
| def get_function_children(func): | ||
| result = [] | ||
| if func.nested_functions: | ||
| for nested in func.nested_functions: | ||
| result.append(nested) | ||
| result.extend(get_function_children(nested)) | ||
| return result | ||
|
|
||
| for func in interface_view.functions: | ||
| funcs.append(func) | ||
| funcs.extend(get_function_children(func)) | ||
|
|
||
| funcs.sort(key=lambda f: f.name.lower()) | ||
|
|
||
| # Get functions deployed to the target partition | ||
| target_partition_name = values["TARGET"] | ||
|
|
||
| deployed_funcs = [] | ||
| target_partition = None | ||
| for node in deployment_view.nodes: | ||
| for partition in node.partitions: | ||
| if partition.name == target_partition_name: | ||
| target_partition = partition | ||
|
|
||
| deployed_func_names = [f.name for f in target_partition.functions] | ||
| for fun in funcs: | ||
| if fun.name in deployed_func_names: | ||
| deployed_funcs.append(fun) | ||
|
|
||
| # Only leaf functions are deployed, so a correction for parents must be applied | ||
| for func in funcs: | ||
| if func.nested_functions: | ||
| for nested in func.nested_functions: | ||
| if nested in deployed_funcs and not func in deployed_funcs: | ||
| deployed_funcs.append(func) | ||
| deployed_func_names.append(func.name) | ||
|
|
||
| # Filter SDL functions only | ||
| import os | ||
| import subprocess | ||
| import glob | ||
|
|
||
| sdl_funcs = [func for func in deployed_funcs if func.language and func.language.value == "SDL"] | ||
|
|
||
| # Generate SDL behavior diagrams using OpenGEODE | ||
| def generate_sdl_images(func): | ||
| """Generate SDL images for a function using OpenGEODE""" | ||
| func_lower = func.name.lower() | ||
| images = [] | ||
|
|
||
| # Try different path patterns for SDL/src directory | ||
| # Pattern 1: work/{function}/SDL/src | ||
| sdl_path_1 = f"work/{func_lower}/SDL/src" | ||
| # Pattern 2: work/{function}/implem/{implementation}/SDL/src | ||
| sdl_path_2_pattern = f"work/{func_lower}/implem/*/SDL/src" | ||
|
|
||
| sdl_paths = [] | ||
| if os.path.exists(sdl_path_1): | ||
| sdl_paths.append(sdl_path_1) | ||
| else: | ||
| # Check for implementation-specific paths | ||
| matching_paths = glob.glob(sdl_path_2_pattern) | ||
| sdl_paths.extend(matching_paths) | ||
|
|
||
| for sdl_path in sdl_paths: | ||
| if not os.path.exists(sdl_path): | ||
| continue | ||
|
|
||
| # Find the system_structure.pr and function.pr files | ||
| system_pr = os.path.join(sdl_path, "system_structure.pr") | ||
| func_pr = os.path.join(sdl_path, f"{func_lower}.pr") | ||
|
|
||
| if not os.path.exists(system_pr) or not os.path.exists(func_pr): | ||
| continue | ||
|
|
||
| # Generate images using OpenGEODE | ||
| try: | ||
| # Change to SDL/src directory to run opengeode | ||
| original_dir = os.getcwd() | ||
|
|
||
| # Get absolute path to output directory before changing directories | ||
| abs_output_dir = None | ||
| if output_directory: | ||
| abs_output_dir = os.path.abspath(output_directory) | ||
| print(f"Output directory (absolute): {abs_output_dir}") | ||
| print(f"Output directory exists: {os.path.exists(abs_output_dir)}") | ||
|
|
||
| # Get absolute path to SDL directory | ||
| abs_sdl_path = os.path.abspath(sdl_path) | ||
|
|
||
| os.chdir(sdl_path) | ||
|
|
||
| # Run OpenGEODE to generate PNG images | ||
| subprocess.run( | ||
| ["opengeode", "--png", "system_structure.pr", f"{func_lower}.pr"], | ||
| check=False, | ||
| capture_output=True | ||
| ) | ||
|
|
||
| # Find all generated PNG files and move them to output directory | ||
| png_files = glob.glob("*.png") | ||
| print(f"Found {len(png_files)} PNG files in {abs_sdl_path}") | ||
|
|
||
| for png_file in sorted(png_files): | ||
| # Extract caption from filename (remove extension) | ||
| caption = os.path.splitext(png_file)[0].replace("-", " ").replace("_", " ") | ||
|
|
||
| # If output_directory is specified, copy the image there | ||
| if abs_output_dir and os.path.exists(abs_output_dir): | ||
| import shutil | ||
| # Since we're in the sdl_path directory, png_file is in current dir | ||
| src_path = png_file | ||
| # Create unique filename with function name to avoid collisions | ||
| dest_filename = f"{func_lower}_{png_file}" | ||
| dest_path = os.path.join(abs_output_dir, dest_filename) | ||
| print(f"Copying {src_path} to {dest_path}") | ||
| shutil.copy2(src_path, dest_path) | ||
| # Use only the filename (no path) for markdown reference | ||
| images.append((dest_filename, caption)) | ||
| else: | ||
| # Fallback: use relative path from original working directory | ||
| abs_img_path = os.path.join(abs_sdl_path, png_file) | ||
| rel_path = os.path.relpath(abs_img_path, original_dir) | ||
| images.append((rel_path, caption)) | ||
|
|
||
| os.chdir(original_dir) | ||
| except Exception as e: | ||
| # If OpenGEODE fails, just continue | ||
| if 'original_dir' in locals(): | ||
| os.chdir(original_dir) | ||
| pass | ||
|
|
||
| return images | ||
|
|
||
| # Generate images for all SDL functions | ||
| func_images = {} | ||
| for func in sdl_funcs: | ||
| images = generate_sdl_images(func) | ||
| if images: | ||
| func_images[func.name] = images | ||
|
|
||
| %> | ||
|
|
||
| This section describes the behaviour of software components implemented in SDL. | ||
|
|
||
| The behaviour of each SDL function is documented using state machine diagrams generated from the SDL implementation. | ||
|
|
||
| % if not sdl_funcs: | ||
| *No SDL functions found in the ${target_partition_name} partition.* | ||
| % else: | ||
| ## SDL Functions | ||
|
|
||
| The following functions are implemented in SDL and their behaviour is documented below: | ||
|
|
||
| % for func in sdl_funcs: | ||
| ${"###"} ${func.name} | ||
|
|
||
| **Description:** ${func.comment if func.comment else "No description available."} | ||
|
|
||
| % if func.name in func_images and func_images[func.name]: | ||
| **Behavioural Diagrams:** | ||
|
|
||
| The following diagrams illustrate the behaviour of the ${func.name} function: | ||
|
|
||
| % for (img_path, caption) in func_images[func.name]: | ||
|  | ||
|
|
||
| % endfor | ||
| % else: | ||
| *No SDL diagrams available for this function. The function may not have SDL source files in the expected location, or OpenGEODE image generation was not successful.* | ||
| % endif | ||
|
|
||
| % endfor | ||
| % endif | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.