Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add a `QuestionnaireConfiguration` type, that allows to configure an optional trip diary (which can include a visited places and segments sections). The `QuestionnaireFactory` class receives the configuration and returns the builtin widgets and sections from config. (commit [be226aa](https://github.com/chairemobilite/evolution/commit/be226aab8ad8f84b027a380dd90af70e2989e62d)).
- **Generator conditional hidden values**: In the `Conditionals` Excel sheet, you can now set an optional `value_when_hidden` so a value is applied when the conditional hides the question (fixes [#979](https://github.com/chairemobilite/evolution/issues/979)).
- **Generator section conditionals**: The `Sections` Excel sheet supports optional `enable_conditional` and `completion_conditional` columns. Set them to a conditional name from the `Conditionals` sheet (generated as `conditionals.<name>`) or to a custom conditional whose name ends with `CustomConditional` (generated as `customConditionals.<name>`). When omitted, the generator keeps the previous defaults (`true` or `isSectionCompleted` with the previous or current section as appropriate). (fixes [#997](https://github.com/chairemobilite/evolution/issues/997)).
- **Generator selective script generation**: The generator now accepts a `--only` command-line argument to generate only specified scripts (e.g., widgets, conditionals, labels) instead of everything (fixes [#1601](https://github.com/chairemobilite/evolution/issues/1601))

### Changed

Expand Down
2 changes: 2 additions & 0 deletions packages/evolution-generator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ If you want to start your own survey, you can use the following steps:
yarn generateSurvey
```

*Note*: It is also possible to run a single or many specific generation scripts by adding the `--only` parameter to the command line. For example `yarn generateSurvey --only conditionals,labels,widgets` would call the `generate_conditionals`, `generate_labels` and `generate_widgets` scripts, no matter the value in the config file.

## Generate Excel

This step is optional but can greatly improve your workflow if you're frequently updating your project's Excel document. By using Microsoft 365 cloud storage, you can avoid manually uploading your document every time you make a change. Here's how you can set it up:
Expand Down
97 changes: 93 additions & 4 deletions packages/evolution-generator/src/scripts/generate_survey.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
# License text available at https://opensource.org/licenses/MIT

# Note: This script generate the survey with multiple scripts.
# These functions are intended to be invoked with the config YAML file.
# These functions are intended to be invoked with the config YAML file. They
# can be overridden with the --only argument to only run a subset of the
# scripts, which is useful for development and debugging.
import argparse # For command-line arguments
from dotenv import load_dotenv # For environment variables
import os # For file operations
Expand All @@ -23,10 +25,85 @@
from scripts.generate_questionnaire_dictionary import generate_questionnaire_dictionary
from scripts.conditionals_generator import ConditionalsGenerator

# Supported script aliases for the --only argument, mapping to the actual script
# keys in the config file's enabled_scripts section.
SUPPORTED_SCRIPT_ALIASES = {
"excel": "generate_excel",
"copy_excel_to_csv": "copy_excel_to_csv",
"excel_to_csv": "copy_excel_to_csv",
"section_configs": "generate_section_configs",
"sections": "generate_sections",
"widget_configs": "generate_widgets_configs",
"widgets_configs": "generate_widgets_configs",
"widgets": "generate_widgets",
"conditionals": "generate_conditionals",
"choices": "generate_choices",
"input_range": "generate_input_range",
"labels": "generate_labels",
"ui_tests": "generate_UI_tests",
"questionnaire_list": "generate_questionnaire_list",
"questionnaire_dictionary": "generate_questionnaire_dictionary",
}

# List all the supported script keys that can be enabled/disabled in the config
# file and via the --only argument.
SUPPORTED_SCRIPT_KEYS = [
"generate_excel",
"copy_excel_to_csv",
"generate_section_configs",
"generate_sections",
"generate_widgets_configs",
"generate_widgets",
"generate_conditionals",
"generate_choices",
"generate_input_range",
"generate_labels",
"generate_UI_tests",
"generate_questionnaire_list",
"generate_questionnaire_dictionary",
]


# Parse the --only argument to get the set of scripts to run, validating the
# input and mapping aliases to actual script keys. The script keys are separated
# by commas.
def _parse_only_scripts(only_scripts):
Comment thread
tahini marked this conversation as resolved.
if only_scripts is None:
return None

normalized_scripts = set()
for script_name in only_scripts.split(","):
script_key = script_name.strip()
if not script_key:
continue
if script_key not in SUPPORTED_SCRIPT_ALIASES:
valid_values = ", ".join(sorted(SUPPORTED_SCRIPT_ALIASES.keys()))
raise ValueError(
f"Unknown script '{script_key}' in --only argument. "
f"Supported values are: {valid_values}"
)
normalized_scripts.add(SUPPORTED_SCRIPT_ALIASES[script_key])

# Validate that some values were set
if len(normalized_scripts) == 0:
valid_values = ", ".join(sorted(SUPPORTED_SCRIPT_ALIASES.keys()))
raise ValueError(
"--only argument was set with no valid scripts. "
f"Supported values are: {valid_values}"
)

return normalized_scripts
Comment thread
tahini marked this conversation as resolved.


def _override_enabled_scripts(only_scripts):
return {
script_key: script_key in only_scripts for script_key in SUPPORTED_SCRIPT_KEYS
}


# TODO: Add some validation for the config file
# Generate the survey from the config file
def generate_survey(config_path):
def generate_survey(config_path, only_scripts=None):
# Load environment variables from .env file
load_dotenv()

Expand All @@ -37,7 +114,10 @@ def generate_survey(config_path):
# Get the data from the YAML file
survey_folder_path = surveyGenerator["survey_folder_path"]
excel_file_path = surveyGenerator["excel_file_path"]
enabled_scripts = surveyGenerator.get("enabled_scripts", [])
enabled_scripts = surveyGenerator.get("enabled_scripts", {})
# Override enabled_scripts from config file if --only argument is provided
if only_scripts is not None:
enabled_scripts = _override_enabled_scripts(only_scripts)
enabled_generate_excel = enabled_scripts.get("generate_excel", False)
enabled_copy_excel_to_csv = enabled_scripts.get("copy_excel_to_csv", False)
enabled_generate_section_configs = enabled_scripts.get(
Expand Down Expand Up @@ -204,11 +284,20 @@ def main():
parser.add_argument(
"--config_path", required=True, help="Path to the Generator config file"
)
parser.add_argument(
"--only",
required=False,
help=(
"Comma-separated scripts to run and override enabled_scripts from config. "
"Example: --only section_configs,widget_configs"
),
)
args = parser.parse_args()
config_path = args.config_path
only_scripts = _parse_only_scripts(args.only)

# Call the generate_survey function with the config_path argument
generate_survey(config_path)
generate_survey(config_path, only_scripts=only_scripts)


# Check the integrity of the Excel file to avoid generating the survey with invalid data
Expand Down
Loading