Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
181
tools/EVerest-main/cmake/trailbook/EXTENDING.md
Normal file
181
tools/EVerest-main/cmake/trailbook/EXTENDING.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Extending the trailbook package
|
||||
|
||||
The trailbook package provides a set of targets and target properties
|
||||
that can be used to hook into the build process of the trailbook documentation
|
||||
and extend it with custom functionality.
|
||||
|
||||
## Important Note
|
||||
|
||||
Since the trailbook packages work a lot with custom CMake targets and
|
||||
custom CMake commands, it is important to set dependencies correctly
|
||||
when extending the trailbook package.
|
||||
|
||||
This means that it is not sufficient to just depend on the targets
|
||||
and extend target dependencies with `add_dependencies()`. Instead,
|
||||
you should also make sure to extend the file-level dependencies. For this
|
||||
a set of custom target properties is provided that can be used
|
||||
to add additional dependencies to the custom commands used in the
|
||||
trailbook build process.
|
||||
|
||||
## Available Stages to Hook Into
|
||||
|
||||
To hook into the build process custom commands can be placed in between
|
||||
stages
|
||||
|
||||
### Hook in before stage: Prepare Sphinx Source
|
||||
|
||||
If you want to hook into the build process before the Sphinx source
|
||||
is prepared, you can define a custom command that doesn't need to
|
||||
depend on any files, but the created files and targets should be appended to
|
||||
the target list property `ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE`.
|
||||
|
||||
This can be done by using the following code snippet:
|
||||
|
||||
```cmake
|
||||
# Your custom cmake code here
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
COMMAND
|
||||
<your_command_here>
|
||||
DEPENDS
|
||||
<your_dependencies_here>
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
<wrapper_target_name>
|
||||
DEPENDS
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
)
|
||||
|
||||
# Hook into the trailbook build process
|
||||
set_property(
|
||||
TARGET trailbook_<trailbook_name>
|
||||
APPEND
|
||||
PROPERTY
|
||||
ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE
|
||||
<wrapper_target_name>
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
)
|
||||
```
|
||||
|
||||
* `<output_file1>`, `<output_file2>` can be any custom files created
|
||||
by your command.
|
||||
* `<wrapper_target_name>` is a custom target that
|
||||
wraps your command for example.
|
||||
* `<trailbook_name>` should be replaced with the name of your trailbook
|
||||
provided in the `add_trailbook()` function call.
|
||||
|
||||
With this target-level dependencies and file-level dependencies can be added.
|
||||
If there is a target that depends on the output files, the file-level
|
||||
dependencies should be added as well.
|
||||
|
||||
### Hook in before stage: Build Sphinx
|
||||
|
||||
If you want to hook in before the Sphinx build process starts,
|
||||
you can use the target list property `ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE`.
|
||||
and `DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER` to add file-level dependencies
|
||||
to the stage before.
|
||||
|
||||
This can be done by using the following code snippet:
|
||||
|
||||
```cmake
|
||||
# Hook into the trailbook build process after the prepare stage
|
||||
get_target_property(
|
||||
DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER
|
||||
trailbook_<trailbook_name>
|
||||
DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER
|
||||
)
|
||||
|
||||
# Your custom cmake code here
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
DEPENDS
|
||||
<your_dependencies_here>
|
||||
${DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER}
|
||||
COMMAND
|
||||
<your_command_here>
|
||||
)
|
||||
add_custom_target(
|
||||
<wrapper_target_name>
|
||||
DEPENDS
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
${DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER}
|
||||
)
|
||||
|
||||
# Hook into the trailbook build process before the build stage
|
||||
set_property(
|
||||
TARGET trailbook_<trailbook_name>
|
||||
APPEND
|
||||
PROPERTY
|
||||
ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE
|
||||
<wrapper_target_name>
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
)
|
||||
```
|
||||
|
||||
* `<output_file1>`, `<output_file2>` can be any custom files created
|
||||
by your command.
|
||||
* `<wrapper_target_name>` is a custom target that
|
||||
wraps your command for example.
|
||||
* `<trailbook_name>` should be replaced with the name of your trailbook
|
||||
provided in the `add_trailbook()` function call.
|
||||
|
||||
With the `get_target_property()` call the file-level dependencies
|
||||
from the previous stage are retrieved and added to the custom command
|
||||
and the custom target. This ensures that the custom command is executed
|
||||
after the previous stage is completed.
|
||||
|
||||
With the `set_property()` call the custom target and the output files
|
||||
are added to the target-level dependencies of the build stage.
|
||||
This ensures that the build stage waits for the custom command
|
||||
to complete before starting the Sphinx build process.
|
||||
|
||||
### Hook in before stage: Post Process Sphinx
|
||||
|
||||
This can be done analogously to the previous stage, but using the target list property
|
||||
`ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE` and `DEPS_STAGE_BUILD_SPHINX_AFTER`.
|
||||
|
||||
```cmake
|
||||
# Hook into the trailbook build process after the build stage
|
||||
get_target_property(
|
||||
DEPS_STAGE_BUILD_SPHINX_AFTER
|
||||
trailbook_<trailbook_name>
|
||||
DEPS_STAGE_BUILD_SPHINX_AFTER
|
||||
)
|
||||
# Your custom cmake code here
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
DEPENDS
|
||||
<your_dependencies_here>
|
||||
${DEPS_STAGE_BUILD_SPHINX_AFTER}
|
||||
COMMAND
|
||||
<your_command_here>
|
||||
)
|
||||
add_custom_target(
|
||||
<wrapper_target_name>
|
||||
DEPENDS
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
${DEPS_STAGE_BUILD_SPHINX_AFTER}
|
||||
)
|
||||
# Hook into the trailbook build process before the post process stage
|
||||
set_property(
|
||||
TARGET trailbook_<trailbook_name>
|
||||
APPEND
|
||||
PROPERTY
|
||||
ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE
|
||||
<wrapper_target_name>
|
||||
<output_file1>
|
||||
<output_file2>
|
||||
)
|
||||
```
|
||||
137
tools/EVerest-main/cmake/trailbook/README.md
Normal file
137
tools/EVerest-main/cmake/trailbook/README.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# CMake Package trailbook
|
||||
|
||||
This package provides CMake functions and macros to include
|
||||
the build of a trailbook documentation in a CMake-based project.
|
||||
|
||||
## Usage in CMake
|
||||
|
||||
To use this package in your CMake project, include the following line in your `CMakeLists.txt` file:
|
||||
|
||||
```cmake
|
||||
find_package(
|
||||
trailbook
|
||||
0.1.0
|
||||
REQUIRED
|
||||
PATHS "${CMAKE_SOURCE_DIR}/<path-to-the-package>"
|
||||
)
|
||||
```
|
||||
|
||||
* Specify the version to make sure you are using
|
||||
a compatible version of the package.
|
||||
* If the package is not found, CMake will
|
||||
stop with an error due to the `REQUIRED` keyword.
|
||||
* If the package is not installed in a standard
|
||||
location, you can specify the path to the package using the `PATHS` option.
|
||||
|
||||
After finding the package, you can use the provided functions.
|
||||
At the moment, the package provides the following functions:
|
||||
|
||||
### `add_trailbook()`
|
||||
|
||||
This function is the initial call for your trailbook documentation.
|
||||
It can be called as follows:
|
||||
|
||||
```cmake
|
||||
add_trailbook(
|
||||
NAME <trailbook_name>
|
||||
[STEM_DIRECTORY <stem_directory>]
|
||||
[REQUIREMENTS_TXT <requirements_txt>]
|
||||
INSTANCE_NAME <instance_name>
|
||||
[DEPLOYED_DOCS_REPO_URL <deployed_docs_repo_url>]
|
||||
[DEPLOYED_DOCS_REPO_BRANCH <deployed_docs_repo_branch>]
|
||||
)
|
||||
```
|
||||
|
||||
* This function needs to be called once per trailbook.
|
||||
* The `NAME` argument specifies the name of the trailbook.
|
||||
This name will be used to create unique target names.
|
||||
* The optional `STEM_DIRECTORY` argument specifies the
|
||||
directory containing the Sphinx source files.
|
||||
If not provided, it defaults to `${CMAKE_CURRENT_SOURCE_DIR}`
|
||||
* The optional `REQUIREMENTS_TXT` argument specifies the path to a
|
||||
`requirements.txt` file for Python dependencies.
|
||||
If not provided, it defaults to `${STEM_DIRECTORY}/requirements.txt`,
|
||||
if this file exists.
|
||||
This requirements file will be used to check if the required Python packages are installed and if not to install them, if a
|
||||
python virtual environment is active
|
||||
* The `INSTANCE_NAME` argument specifies the name that is used for
|
||||
the version in the multiversion structure.
|
||||
* The optional `DEPLOYED_DOCS_REPO_URL` argument specifies the URL of the
|
||||
repository where the already deployed documentation is located.
|
||||
It is required if `TRAILBOOK_<NAME>_DOWNLOAD_ALL_VERSIONS` is set to `ON`.
|
||||
* The optional `DEPLOYED_DOCS_REPO_BRANCH` argument
|
||||
specifies the branch of the deployed documentation repository.
|
||||
It defaults to `main` if not provided.
|
||||
|
||||
## Configuring
|
||||
|
||||
There are several options that can be configured
|
||||
for each trailbook by setting CMake variables.
|
||||
|
||||
### `TRAILBOOK_<NAME>_DOWNLOAD_ALL_VERSIONS`
|
||||
|
||||
* `<NAME>` should be replaced with the trailbook name provided
|
||||
in the `add_trailbook()` function call.
|
||||
|
||||
If `TRAILBOOK_<NAME>_DOWNLOAD_ALL_VERSIONS` is set to `ON`,
|
||||
the build process will attempt to download all previously deployed versions
|
||||
of the trailbook from the specified repository. And then embed the
|
||||
new version into the multiversion structure.
|
||||
|
||||
If `TRAILBOOK_<NAME>_DOWNLOAD_ALL_VERSIONS` is set to `OFF` (default),
|
||||
only the current version of the trailbook will be built. For this
|
||||
an empty multiversion skeleton will be created.
|
||||
|
||||
This configuration shouldn'T be changed after the first build.
|
||||
|
||||
### `TRAILBOOK_<NAME>_IS_RELEASE`
|
||||
|
||||
* `<NAME>` should be replaced with the trailbook name provided
|
||||
in the `add_trailbook()` function call.
|
||||
|
||||
If `TRAILBOOK_<NAME>_IS_RELEASE` is set to `ON` (default),
|
||||
the trailbook will be built as a release version. This means
|
||||
that the `latest` version is updated, and the `index.html` and
|
||||
`404.html` files are updated.
|
||||
|
||||
If `TRAILBOOK_<NAME>_IS_RELEASE` is set to `OFF`,
|
||||
the mentioned files are not updated, and the `latest` version
|
||||
is not changed. This can be used for example to build
|
||||
nightly versions without affecting the released version.
|
||||
|
||||
## Building
|
||||
|
||||
To build the trailbook documentation, simply run the following command, after configuring the project with CMake:
|
||||
|
||||
```bash
|
||||
cmake --build <build_directory> --target trailbook_<trailbook_name>
|
||||
```
|
||||
|
||||
* Replace `<build_directory>` with the path to your CMake build directory.
|
||||
* Replace `<trailbook_name>` with the name of your trailbook
|
||||
provided in the `add_trailbook()` function call.
|
||||
|
||||
This target will trigger the full build of the trailbook documentation
|
||||
|
||||
Furthermore, you can use the following additional targets:
|
||||
|
||||
```bash
|
||||
cmake --build <build_directory> --target trailbook_<trailbook_name>_preview
|
||||
```
|
||||
|
||||
This target will start a local server to preview the built documentation.
|
||||
|
||||
```bash
|
||||
cmake --build <build_directory> --target trailbook_<trailbook_name>_live_preview
|
||||
```
|
||||
This target will start a local server that watches for changes
|
||||
in the source files and automatically rebuilds the documentation
|
||||
and refreshes the preview in the browser.
|
||||
|
||||
## How to build a extension for the trailbook package
|
||||
|
||||
The trailbook package provides a set of targets and target properties
|
||||
that can be used to hook into the build process of the trailbook documentation
|
||||
and extend it with custom functionality.
|
||||
|
||||
See the full explanation in the [EXTENDING.md](EXTENDING.md) file.
|
||||
721
tools/EVerest-main/cmake/trailbook/add-trailbook.cmake
Normal file
721
tools/EVerest-main/cmake/trailbook/add-trailbook.cmake
Normal file
@@ -0,0 +1,721 @@
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It checks the requirements defined by the requirements.txt file
|
||||
# and installs any missing packages into the current Python virtual environment.
|
||||
# It checks during the configuration phase.
|
||||
macro(_add_trailbook_check_requirements_txt)
|
||||
if(EXISTS ${args_REQUIREMENTS_TXT})
|
||||
execute_process(
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_requirements_txt.py
|
||||
${args_REQUIREMENTS_TXT}
|
||||
--fix-in-venv
|
||||
RESULT_VARIABLE _CHECK_REQUIREMENTS_TXT_RESULT
|
||||
)
|
||||
|
||||
if(NOT _CHECK_REQUIREMENTS_TXT_RESULT EQUAL 0)
|
||||
message(FATAL_ERROR "Trailbook: ${args_NAME} - ${args_REQUIREMENTS_TXT} not satisfied.")
|
||||
else()
|
||||
message(STATUS "Trailbook: ${args_NAME} - ${args_REQUIREMENTS_TXT} satisfied.")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Trailbook: ${args_NAME} - No requirements.txt found.")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It sets up the trailbook build directory where the multiversion HTML docs will be located.
|
||||
# If TRAILBOOK_INSTANCE_DOWNLOAD_ALL_VERSIONS is ON, it clones the deployed docs repo.
|
||||
# Otherwise, it creates an empty skeleton directory.
|
||||
# This configuration is checked during the configuration phase and should not be switched
|
||||
macro(_add_trailbook_setup_build_directory)
|
||||
set(CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/setup_build_directory.check_done")
|
||||
set(SETUP_BUILD_DIRECTORY_FILE_LIST "${CMAKE_CURRENT_BINARY_DIR}/setup_build_directory_filelist.yaml")
|
||||
set(DEPLOYED_DOCS_REPO_DIR "${CMAKE_CURRENT_BINARY_DIR}/deployed_docs_repo/")
|
||||
|
||||
if(TRAILBOOK_INSTANCE_DOWNLOAD_ALL_VERSIONS)
|
||||
if(_SETUP_BUILD_DIRECTORY_LAST_CONFIGURATION STREQUAL "EMPTY_SKELETON")
|
||||
message(FATAL_ERROR "add_trailbook: Cannot switch between DOWNLOAD_ALL_VERSIONS and EMPTY_SKELETON configurations for trailbook ${args_NAME} without cleaning build directory")
|
||||
endif()
|
||||
else()
|
||||
if(_SETUP_BUILD_DIRECTORY_LAST_CONFIGURATION STREQUAL "DOWNLOAD_ALL_VERSIONS")
|
||||
message(FATAL_ERROR "add_trailbook: Cannot switch between DOWNLOAD_ALL_VERSIONS and EMPTY_SKELETON configurations for trailbook ${args_NAME} without cleaning build directory")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(TRAILBOOK_INSTANCE_DOWNLOAD_ALL_VERSIONS)
|
||||
find_program(
|
||||
GIT_EXECUTABLE
|
||||
NAMES git
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
set(CONDITIONAL_DELETE_LATEST_DIR_COMMAND "")
|
||||
if(TRAILBOOK_INSTANCE_IS_RELEASE)
|
||||
set(CONDITIONAL_DELETE_LATEST_DIR_COMMAND
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -rf
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download/docs/latest
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CONDITIONAL_DELETE_INSTANCE_DIR_OR_FAIL_COMMAND "")
|
||||
if(TRAILBOOK_${args_NAME}_OVERWRITE_EXISTING_INSTANCE)
|
||||
set(CONDITIONAL_DELETE_INSTANCE_DIR_OR_FAIL_COMMAND
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -rf
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download/docs/${TRAILBOOK_${args_NAME}_INSTANCE_NAME}
|
||||
)
|
||||
else()
|
||||
# check if instance directory already exists and fail if it does
|
||||
set(CONDITIONAL_DELETE_INSTANCE_DIR_OR_FAIL_COMMAND
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
--directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download/docs/${TRAILBOOK_${args_NAME}_INSTANCE_NAME}
|
||||
--return-zero-if-not-exists
|
||||
)
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE>
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Downloading all versions repo"
|
||||
COMMAND # Remove existing files in deployed docs repo directory from previous builds
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
remove
|
||||
--data-file ${SETUP_BUILD_DIRECTORY_FILE_LIST}
|
||||
--root-directory ${DEPLOYED_DOCS_REPO_DIR}
|
||||
COMMAND # Clone deployed docs repo
|
||||
${GIT_EXECUTABLE} clone
|
||||
-b ${args_DEPLOYED_DOCS_REPO_BRANCH}
|
||||
--depth 1
|
||||
${args_DEPLOYED_DOCS_REPO_URL}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download/
|
||||
# Remove latest directory if this is a release instance
|
||||
${CONDITIONAL_DELETE_LATEST_DIR_COMMAND}
|
||||
# Remove existing instance directory if overwrite is enabled or fail if it exists
|
||||
${CONDITIONAL_DELETE_INSTANCE_DIR_OR_FAIL_COMMAND}
|
||||
COMMAND # Create file list of existing files in deployed docs repo directory after clone
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
create
|
||||
--data-file ${SETUP_BUILD_DIRECTORY_FILE_LIST}
|
||||
--root-directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download
|
||||
COMMAND # Move cloned files to deployed docs repo directory
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
move
|
||||
--data-file ${SETUP_BUILD_DIRECTORY_FILE_LIST}
|
||||
--root-directory ${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download
|
||||
--target-root-directory ${DEPLOYED_DOCS_REPO_DIR}/
|
||||
COMMAND # Delete temporary clone directory
|
||||
${CMAKE_COMMAND} -E rm -rf
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tmp_repo_download/
|
||||
COMMAND # Create convenience symlink to docs/ in build directory
|
||||
${CMAKE_COMMAND} -E create_symlink
|
||||
${DEPLOYED_DOCS_REPO_DIR}/docs/
|
||||
${TRAILBOOK_BUILD_DIRECTORY}
|
||||
COMMAND # Create done file
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY}
|
||||
)
|
||||
set(_SETUP_BUILD_DIRECTORY_LAST_CONFIGURATION "DOWNLOAD_ALL_VERSIONS")
|
||||
else()
|
||||
set(CONDITIONAL_CLEANUP_COMMAND "")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE>
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Creating empty skeleton multiversion root directory"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E make_directory
|
||||
${TRAILBOOK_BUILD_DIRECTORY}/
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY}
|
||||
)
|
||||
set(_SETUP_BUILD_DIRECTORY_LAST_CONFIGURATION "EMPTY_SKELETON")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It adds a custom command to copy the trailbook stem files to the build directory.
|
||||
# To be used a base for the tailbook instance source directory.
|
||||
macro(_add_trailbook_copy_stem_command)
|
||||
file(
|
||||
GLOB_RECURSE
|
||||
STEM_FILES_SOURCE_DIR
|
||||
CONFIGURE_DEPENDS
|
||||
"${args_STEM_DIRECTORY}/*"
|
||||
)
|
||||
|
||||
set(STEM_FILES_BUILD_DIR "")
|
||||
foreach(file_path IN LISTS STEM_FILES_SOURCE_DIR)
|
||||
file(RELATIVE_PATH rel_path "${args_STEM_DIRECTORY}" "${file_path}")
|
||||
list(APPEND STEM_FILES_BUILD_DIR "${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}/${rel_path}")
|
||||
endforeach()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${STEM_FILES_BUILD_DIR}
|
||||
DEPENDS
|
||||
${STEM_FILES_SOURCE_DIR}
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE>
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Copying stem files to build directory"
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
remove
|
||||
--data-file ${CMAKE_CURRENT_BINARY_DIR}/copy_stem_filelist.yaml
|
||||
--root-directory ${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
create
|
||||
--data-file ${CMAKE_CURRENT_BINARY_DIR}/copy_stem_filelist.yaml
|
||||
--root-directory ${args_STEM_DIRECTORY}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory
|
||||
${args_STEM_DIRECTORY}
|
||||
${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It adds a custom command to create the metadata YAML file for the trailbook instance.
|
||||
# The metadata YAML file is used by Sphinx during the build process.
|
||||
# It contains a list of all versions available in the multiversion root directory.
|
||||
macro(_add_trailbook_create_metadata_yaml_command)
|
||||
set(METADATA_YAML_FILE "${CMAKE_CURRENT_BINARY_DIR}/metadata_${args_NAME}.yaml")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${METADATA_YAML_FILE}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/create_metadata_yaml.py
|
||||
${STEM_FILES_BUILD_DIR}
|
||||
${CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY}
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE>
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Creating metadata YAML file"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -f ${METADATA_YAML_FILE}
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/create_metadata_yaml.py
|
||||
--multiversion-root-directory "${TRAILBOOK_BUILD_DIRECTORY}"
|
||||
"--output-path" "${METADATA_YAML_FILE}"
|
||||
--additional-version "${TRAILBOOK_${args_NAME}_INSTANCE_NAME}"
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It adds a custom command to build the Sphinx HTML documentation for the trailbook instance.
|
||||
# It builds from the trailbook instance source directory to the trailbook instance build directory.
|
||||
macro(_add_trailbook_sphinx_build_command)
|
||||
set(CHECK_DONE_FILE_SPHINX_BUILD_COMMAND "${CMAKE_CURRENT_BINARY_DIR}/build_html.check_done")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_build_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE>
|
||||
${STEM_FILES_BUILD_DIR}
|
||||
${METADATA_YAML_FILE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Building HTML documentation with Sphinx"
|
||||
USES_TERMINAL
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
remove
|
||||
--data-file ${CMAKE_CURRENT_BINARY_DIR}/sphinx_build_filelist.yaml
|
||||
--root-directory ${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}/
|
||||
COMMAND
|
||||
EVEREST_METADATA_YAML_PATH=${METADATA_YAML_FILE}
|
||||
${_SPHINX_BUILD_EXECUTABLE}
|
||||
-b html
|
||||
${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/sphinx_build_temp/
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
create
|
||||
--data-file ${CMAKE_CURRENT_BINARY_DIR}/sphinx_build_filelist.yaml
|
||||
--root-directory ${CMAKE_CURRENT_BINARY_DIR}/sphinx_build_temp/
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/filelist_manager.py
|
||||
move
|
||||
--data-file ${CMAKE_CURRENT_BINARY_DIR}/sphinx_build_filelist.yaml
|
||||
--root-directory ${CMAKE_CURRENT_BINARY_DIR}/sphinx_build_temp/
|
||||
--target-root-directory ${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}/
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E echo
|
||||
"Trailbook: ${args_NAME} - HTML documentation built at ${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It adds a custom command to replace the 'latest' copy in the multiversion root directory
|
||||
# It should be only called if TRAILBOOK_INSTANCE_IS_RELEASE is ON.
|
||||
macro(_add_trailbook_replace_latest_command)
|
||||
set(CHECK_DONE_FILE_REPLACE_LATEST "${CMAKE_CURRENT_BINARY_DIR}/replace_latest.check_done")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_REPLACE_LATEST}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Replacing 'latest' copy with copy of current instance"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -rf ${TRAILBOOK_BUILD_DIRECTORY}/latest
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory
|
||||
${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}
|
||||
${TRAILBOOK_BUILD_DIRECTORY}/latest
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_REPLACE_LATEST}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It copies the 404.html file from the trailbook instance build directory
|
||||
# to the multiversion root directory.
|
||||
# It should only be called if TRAILBOOK_INSTANCE_IS_RELEASE is ON.
|
||||
macro(_add_trailbook_copy_404_command)
|
||||
set(CHECK_DONE_FILE_COPY_404 "${CMAKE_CURRENT_BINARY_DIR}/copy_404.check_done")
|
||||
set(TRAILBOOK_404_FILE "${TRAILBOOK_BUILD_DIRECTORY}/404.html")
|
||||
set(TRAILBOOK_INSTANCE_404_FILE "${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}/404.html")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${TRAILBOOK_INSTANCE_404_FILE}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Checking for 404.html in built documentation"
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
--file "${TRAILBOOK_INSTANCE_404_FILE}"
|
||||
--return-zero-if-exists
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_COPY_404}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
${TRAILBOOK_INSTANCE_404_FILE}
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Copying 404.html to multiversion root directory"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -f ${TRAILBOOK_404_FILE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy
|
||||
${TRAILBOOK_INSTANCE_404_FILE}
|
||||
${TRAILBOOK_404_FILE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_COPY_404}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_tailbook.
|
||||
# It adds a custom command to render the redirect template. The rendered file
|
||||
# will be used as the index.html in the multiversion root directory.
|
||||
# This macro should only be called if TRAILBOOK_INSTANCE_IS_RELEASE is ON.
|
||||
macro(_add_trailbook_render_redirect_template_command)
|
||||
set(CHECK_DONE_FILE_RENDER_REDIRECT_TEMPLATE "${CMAKE_CURRENT_BINARY_DIR}/render_redirect_template.check_done")
|
||||
set(REDIRECT_TEMPLATE_FILE "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/templates/redirect.html.jinja")
|
||||
set(TRAILBOOK_REDIRECT_FILE "${TRAILBOOK_BUILD_DIRECTORY}/index.html")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_RENDER_REDIRECT_TEMPLATE}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/render_redirect_template.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Rendering redirect.html from template"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -f ${TRAILBOOK_REDIRECT_FILE}
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/render_redirect_template.py
|
||||
--redirect-template "${REDIRECT_TEMPLATE_FILE}"
|
||||
"--target-path" "${TRAILBOOK_REDIRECT_FILE}"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_RENDER_REDIRECT_TEMPLATE}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_trailbook.
|
||||
# It adds a custom command to copy the versions_index.html file to the multiversion root directory
|
||||
macro(_add_trailbook_copy_versions_index_command)
|
||||
set(CHECK_DONE_FILE_COPY_VERSIONS_INDEX "${CMAKE_CURRENT_BINARY_DIR}/copy_versions_index.check_done")
|
||||
set(TRAILBOOK_VERSIONS_INDEX_FILE "${TRAILBOOK_BUILD_DIRECTORY}/versions_index.html")
|
||||
set(TRAILBOOK_INSTANCE_VERSIONS_INDEX_FILE "${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}/versions_index.html")
|
||||
set(CHECK_DONE_FILE_CHECK_LATEST_INSTANCE "${CMAKE_CURRENT_BINARY_DIR}/check_latest_instance.check_done")
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${TRAILBOOK_INSTANCE_VERSIONS_INDEX_FILE}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Checking for versions_index.html in built documentation"
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
--file "${TRAILBOOK_INSTANCE_VERSIONS_INDEX_FILE}"
|
||||
--return-zero-if-exists
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_CHECK_LATEST_INSTANCE}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
${CHECK_DONE_FILE_REPLACE_LATEST}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Checking for latest/ in multiversion root directory"
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/check_path_exists.py
|
||||
--directory ${TRAILBOOK_BUILD_DIRECTORY}/latest
|
||||
--return-zero-if-exists
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_CHECK_LATEST_INSTANCE}
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CHECK_DONE_FILE_COPY_VERSIONS_INDEX}
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
${TRAILBOOK_INSTANCE_VERSIONS_INDEX_FILE}
|
||||
${CHECK_DONE_FILE_CHECK_LATEST_INSTANCE}
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Copying versions_index.html to multiversion root directory"
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E rm -f ${TRAILBOOK_VERSIONS_INDEX_FILE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy
|
||||
${TRAILBOOK_INSTANCE_VERSIONS_INDEX_FILE}
|
||||
${TRAILBOOK_VERSIONS_INDEX_FILE}
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E touch ${CHECK_DONE_FILE_COPY_VERSIONS_INDEX}
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_tailbook.
|
||||
# It adds a custom target to serve the built HTML documentation via a simple HTTP server.
|
||||
macro(_add_trailbook_preview_target)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_preview
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Serve HTML documentation"
|
||||
USES_TERMINAL
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E echo
|
||||
"Trailbook: ${args_NAME} - Serving HTML output at http://localhost:8000/"
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE} -m http.server --directory ${TRAILBOOK_BUILD_DIRECTORY} 8000
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This macro is for internal use only
|
||||
#
|
||||
# It is used in the function add_tailbook.
|
||||
# It adds a custom target to watch the trailbook instance target for changes
|
||||
# and automatically rebuild the HTML documentation with Sphinx and serve it.
|
||||
macro(_add_trailbook_live_preview_target)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_live_preview
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/target_observer.py
|
||||
COMMENT
|
||||
"Trailbook: ${args_NAME} - Auto-build HTML documentation with Sphinx and serve"
|
||||
USES_TERMINAL
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E echo
|
||||
"Trailbook: ${args_NAME} - Auto-building HTML output and serving at http://localhost:8000/"
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE}
|
||||
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/target_observer.py
|
||||
"trailbook_${args_NAME}"
|
||||
"trailbook_${args_NAME}_preview"
|
||||
--build-dir ${CMAKE_BINARY_DIR}
|
||||
--interval-ms 2000
|
||||
)
|
||||
endmacro()
|
||||
|
||||
# This is the main function to add a trailbook to the build system.
|
||||
# It sets up the necessary build commands and targets
|
||||
# to build the trailbook documentation.
|
||||
# It takes the following parameters:
|
||||
# NAME (required): The name of the trailbook.
|
||||
# STEM_DIRECTORY (optional): The directory containing the trailbook stem files.
|
||||
# Defaults to CMAKE_CURRENT_SOURCE_DIR.
|
||||
# REQUIREMENTS_TXT (optional): The path to the requirements.txt file.
|
||||
# Defaults to CMAKE_CURRENT_SOURCE_DIR/requirements.txt if exists.
|
||||
# INSTANCE_NAME (required): The instance name for the trailbook.
|
||||
# Needs to be lowercase alphanumeric and underscores only.
|
||||
# DEPLOYED_DOCS_REPO_URL (optional): The URL of the deployed docs repository.
|
||||
# Required if TRAILBOOK_<NAME>_DOWNLOAD_ALL_VERSIONS is ON.
|
||||
# DEPLOYED_DOCS_REPO_BRANCH (optional): The branch of the deployed docs repository.
|
||||
# Defaults to 'main'.
|
||||
# Usage:
|
||||
# add_trailbook(
|
||||
# NAME <trailbook_name>
|
||||
# [STEM_DIRECTORY <stem_directory>]
|
||||
# [REQUIREMENTS_TXT <requirements_txt_path>]
|
||||
# INSTANCE_NAME <instance_name>
|
||||
# [DEPLOYED_DOCS_REPO_URL <deployed_docs_repo_url>]
|
||||
# [DEPLOYED_DOCS_REPO_BRANCH <deployed_docs_repo_branch>]
|
||||
# )
|
||||
function(add_trailbook)
|
||||
set(options)
|
||||
set(one_value_args
|
||||
NAME
|
||||
STEM_DIRECTORY
|
||||
REQUIREMENTS_TXT
|
||||
DEPLOYED_DOCS_REPO_URL
|
||||
DEPLOYED_DOCS_REPO_BRANCH
|
||||
)
|
||||
set(multi_value_args)
|
||||
cmake_parse_arguments(
|
||||
"args"
|
||||
"${options}"
|
||||
"${one_value_args}"
|
||||
"${multi_value_args}"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
option(TRAILBOOK_${args_NAME}_DOWNLOAD_ALL_VERSIONS "Download all versions for trailbook ${args_NAME} and build complete trailbook" OFF)
|
||||
option(TRAILBOOK_${args_NAME}_IS_RELEASE "If enabled, the trailbook ${args_NAME} will be marked as release version in versions index" ON)
|
||||
set(TRAILBOOK_${args_NAME}_INSTANCE_NAME "local" CACHE STRING "Instance name for trailbook ${args_NAME}")
|
||||
option(TRAILBOOK_${args_NAME}_OVERWRITE_EXISTING_INSTANCE "Overwrite existing instance with name ${TRAILBOOK_${args_NAME}_INSTANCE_NAME} if it exists" OFF)
|
||||
# Check that at least one of DOWNLOAD_ALL_VERSIONS or IS_RELEASE is ON
|
||||
if(NOT TRAILBOOK_${args_NAME}_DOWNLOAD_ALL_VERSIONS AND NOT TRAILBOOK_${args_NAME}_IS_RELEASE)
|
||||
message(FATAL_ERROR "add_trailbook: TRAILBOOK_${args_NAME}_DOWNLOAD_ALL_VERSIONS and TRAILBOOK_${args_NAME}_IS_RELEASE cannot both be OFF")
|
||||
endif()
|
||||
# Check that instance name is lowercase alphanumeric and underscores only
|
||||
string(REGEX MATCH "^[a-z0-9_]+$" _valid_instance_name "${TRAILBOOK_${args_NAME}_INSTANCE_NAME}")
|
||||
if("${_valid_instance_name}" STREQUAL "")
|
||||
message(FATAL_ERROR "add_trailbook: TRAILBOOK_${args_NAME}_INSTANCE_NAME needs to be lowercase alphanumeric and underscores only")
|
||||
endif()
|
||||
|
||||
# Parameter NAME
|
||||
# is required
|
||||
if("${args_NAME}" STREQUAL "")
|
||||
message(FATAL_ERROR "add_trailbook: NAME argument is required")
|
||||
endif()
|
||||
|
||||
# Parameter STEM_DIRECTORY
|
||||
# - defaults to CMAKE_CURRENT_SOURCE_DIR
|
||||
# - needs to be absolute path
|
||||
if("${args_STEM_DIRECTORY}" STREQUAL "")
|
||||
set(args_STEM_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
endif()
|
||||
if(NOT IS_ABSOLUTE "${args_STEM_DIRECTORY}")
|
||||
message(FATAL_ERROR "add_trailbook: STEM_DIRECTORY needs to be an absolute path")
|
||||
endif()
|
||||
cmake_path(SET args_STEM_DIRECTORY NORMALIZE ${args_STEM_DIRECTORY})
|
||||
|
||||
# Parameter REQUIREMENTS_TXT
|
||||
# - defaults to ${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt if exists
|
||||
# - needs to be absolute path if set
|
||||
if("${args_REQUIREMENTS_TXT}" STREQUAL "")
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt")
|
||||
set(args_REQUIREMENTS_TXT "${CMAKE_CURRENT_SOURCE_DIR}/requirements.txt")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT "${args_REQUIREMENTS_TXT}" STREQUAL "")
|
||||
if(NOT IS_ABSOLUTE "${args_REQUIREMENTS_TXT}")
|
||||
message(FATAL_ERROR "add_trailbook: REQUIREMENTS_TXT needs to be an absolute path")
|
||||
endif()
|
||||
if(NOT EXISTS "${args_REQUIREMENTS_TXT}")
|
||||
message(FATAL_ERROR "add_trailbook: REQUIREMENTS_TXT file does not exist: ${args_REQUIREMENTS_TXT}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Parameter DEPLOYED_DOCS_REPO_URL
|
||||
# - required if TRAILBOOK_<NAME>_DOWNLOAD_ALL_VERSIONS is ON
|
||||
if(TRAILBOOK_${args_NAME}_DOWNLOAD_ALL_VERSIONS AND "${args_DEPLOYED_DOCS_REPO_URL}" STREQUAL "")
|
||||
message(FATAL_ERROR "add_trailbook: DEPLOYED_DOCS_REPO_URL argument is required if TRAILBOOK_${args_NAME}_DOWNLOAD_ALL_VERSIONS is ON")
|
||||
endif()
|
||||
|
||||
# Parameter DEPLOYED_DOCS_REPO_BRANCH
|
||||
# - defaults to 'main'
|
||||
if("${args_DEPLOYED_DOCS_REPO_BRANCH}" STREQUAL "")
|
||||
set(args_DEPLOYED_DOCS_REPO_BRANCH "main")
|
||||
endif()
|
||||
|
||||
set(TRAILBOOK_INSTANCE_SOURCE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/trailbook_${args_NAME}_source")
|
||||
set(TRAILBOOK_BUILD_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/trailbook_${args_NAME}_build")
|
||||
set(TRAILBOOK_INSTANCE_BUILD_DIRECTORY "${TRAILBOOK_BUILD_DIRECTORY}/${TRAILBOOK_${args_NAME}_INSTANCE_NAME}")
|
||||
set(TRAILBOOK_INSTANCE_IS_RELEASE "${TRAILBOOK_${args_NAME}_IS_RELEASE}")
|
||||
set(TRAILBOOK_INSTANCE_DOWNLOAD_ALL_VERSIONS "${TRAILBOOK_${args_NAME}_DOWNLOAD_ALL_VERSIONS}")
|
||||
|
||||
message(STATUS "Adding trailbook: ${args_NAME}")
|
||||
message(STATUS " Stem directory: ${args_STEM_DIRECTORY}")
|
||||
message(STATUS " Build directory: ${TRAILBOOK_BUILD_DIRECTORY}")
|
||||
message(STATUS " Instance source directory: ${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}")
|
||||
message(STATUS " Instance build directory: ${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}")
|
||||
if(NOT "${args_REQUIREMENTS_TXT}" STREQUAL "")
|
||||
message(STATUS " Requirements.txt: ${args_REQUIREMENTS_TXT}")
|
||||
else()
|
||||
message(STATUS " Requirements.txt: <none>")
|
||||
endif()
|
||||
message(STATUS " Deployed docs repo url: ${args_DEPLOYED_DOCS_REPO_URL}")
|
||||
message(STATUS " Deployed docs repo branch: ${args_DEPLOYED_DOCS_REPO_BRANCH}")
|
||||
|
||||
_add_trailbook_check_requirements_txt()
|
||||
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_before
|
||||
DEPENDS
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE>
|
||||
)
|
||||
|
||||
_add_trailbook_setup_build_directory()
|
||||
_add_trailbook_copy_stem_command()
|
||||
_add_trailbook_create_metadata_yaml_command()
|
||||
set(DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_before
|
||||
${CHECK_DONE_FILE_SETUP_BUILD_DIRECTORY}
|
||||
${STEM_FILES_BUILD_DIR}
|
||||
${METADATA_YAML_FILE}
|
||||
)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_after
|
||||
DEPENDS
|
||||
${DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER}
|
||||
COMMENT
|
||||
"Prepare Sphinx source for trailbook: ${args_NAME}"
|
||||
)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_stage_build_sphinx_before
|
||||
DEPENDS
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE>
|
||||
trailbook_${args_NAME}_stage_prepare_sphinx_source_after
|
||||
)
|
||||
_add_trailbook_sphinx_build_command()
|
||||
set(DEPS_STAGE_BUILD_SPHINX_AFTER
|
||||
trailbook_${args_NAME}_stage_build_sphinx_before
|
||||
${CHECK_DONE_FILE_SPHINX_BUILD_COMMAND}
|
||||
)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_stage_build_sphinx_after
|
||||
DEPENDS
|
||||
${DEPS_STAGE_BUILD_SPHINX_AFTER}
|
||||
COMMENT
|
||||
"Build Sphinx documentation for trailbook: ${args_NAME}"
|
||||
)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
DEPENDS
|
||||
$<TARGET_PROPERTY:trailbook_${args_NAME},ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE>
|
||||
trailbook_${args_NAME}_stage_build_sphinx_after
|
||||
)
|
||||
if(TRAILBOOK_INSTANCE_IS_RELEASE)
|
||||
_add_trailbook_replace_latest_command()
|
||||
_add_trailbook_copy_404_command()
|
||||
_add_trailbook_render_redirect_template_command()
|
||||
endif()
|
||||
_add_trailbook_copy_versions_index_command()
|
||||
|
||||
set(DEPS_STAGE_POSTPROCESS_SPHINX_AFTER
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_before
|
||||
${CHECK_DONE_FILE_REPLACE_LATEST}
|
||||
${CHECK_DONE_FILE_COPY_404}
|
||||
${CHECK_DONE_FILE_COPY_VERSIONS_INDEX}
|
||||
${CHECK_DONE_FILE_RENDER_REDIRECT_TEMPLATE}
|
||||
)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_after
|
||||
DEPENDS
|
||||
${DEPS_STAGE_POSTPROCESS_SPHINX_AFTER}
|
||||
COMMENT
|
||||
"Post-process Sphinx documentation for trailbook: ${args_NAME}"
|
||||
)
|
||||
add_custom_target(
|
||||
trailbook_${args_NAME} ALL
|
||||
DEPENDS
|
||||
trailbook_${args_NAME}_stage_postprocess_sphinx_after
|
||||
COMMENT
|
||||
"Build trailbook: ${args_NAME}"
|
||||
)
|
||||
|
||||
_add_trailbook_preview_target()
|
||||
_add_trailbook_live_preview_target()
|
||||
|
||||
set_target_properties(
|
||||
trailbook_${args_NAME}
|
||||
PROPERTIES
|
||||
TRAILBOOK_INSTANCE_BUILD_DIRECTORY "${TRAILBOOK_INSTANCE_BUILD_DIRECTORY}"
|
||||
TRAILBOOK_BUILD_DIRECTORY "${TRAILBOOK_BUILD_DIRECTORY}"
|
||||
TRAILBOOK_INSTANCE_NAME "${TRAILBOOK_${args_NAME}_INSTANCE_NAME}"
|
||||
TRAILBOOK_INSTANCE_SOURCE_DIRECTORY "${TRAILBOOK_INSTANCE_SOURCE_DIRECTORY}"
|
||||
TRAILBOOK_CURRENT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
ADDITIONAL_DEPS_STAGE_PREPARE_SPHINX_SOURCE_BEFORE ""
|
||||
ADDITIONAL_DEPS_STAGE_BUILD_SPHINX_BEFORE ""
|
||||
ADDITIONAL_DEPS_STAGE_POSTPROCESS_SPHINX_BEFORE ""
|
||||
DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER "${DEPS_STAGE_PREPARE_SPHINX_SOURCE_AFTER}"
|
||||
DEPS_STAGE_BUILD_SPHINX_AFTER "${DEPS_STAGE_BUILD_SPHINX_AFTER}"
|
||||
DEPS_STAGE_POSTPROCESS_SPHINX_AFTER "${DEPS_STAGE_POSTPROCESS_SPHINX_AFTER}"
|
||||
)
|
||||
endfunction()
|
||||
107
tools/EVerest-main/cmake/trailbook/check_path_exists.py
Executable file
107
tools/EVerest-main/cmake/trailbook/check_path_exists.py
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
#
|
||||
"""
|
||||
author: andreas.heinrich@pionix.de
|
||||
This script checks whether a directory exists or not and returns zero based on the flags provided.
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Checks whether a directory exists or not and returns zero based on the flags provided')
|
||||
parser.add_argument(
|
||||
'--directory',
|
||||
type=Path,
|
||||
dest='directory',
|
||||
action='store',
|
||||
required=False,
|
||||
help='Directory to check for existence'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--file',
|
||||
type=Path,
|
||||
dest='file',
|
||||
action='store',
|
||||
required=False,
|
||||
help='Path to a file to check for existence'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--return-zero-if-exists',
|
||||
action='store_true',
|
||||
help='Return zero if the file/directory exists',
|
||||
dest='return_zero_if_exists',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--return-zero-if-not-exists',
|
||||
action='store_true',
|
||||
help='Return zero if the file/directory does not exist',
|
||||
dest='return_zero_if_not_exists',
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.directory and not args.file:
|
||||
raise ValueError("Either --directory or --file must be specified")
|
||||
if args.return_zero_if_exists and args.return_zero_if_not_exists:
|
||||
raise ValueError("Cannot use both --return-zero-if-exists and --return-zero-if-not-exists at the same time")
|
||||
|
||||
if args.file:
|
||||
if not args.file.is_absolute():
|
||||
raise ValueError("File path must be absolute")
|
||||
if args.return_zero_if_exists:
|
||||
if not args.file.exists():
|
||||
print(f"❌ File does not exist at {args.file}")
|
||||
exit(1)
|
||||
if not args.file.is_file():
|
||||
print(f"❌ Path exists but is not a file at {args.file}")
|
||||
exit(2)
|
||||
print(f"✅ File exists at {args.file}")
|
||||
exit(0)
|
||||
elif args.return_zero_if_not_exists:
|
||||
if args.file.is_file():
|
||||
print(f"❌ File exists at {args.file}")
|
||||
exit(1)
|
||||
if args.file.exists():
|
||||
print(f"❌ Path exists but is not a file at {args.file}")
|
||||
exit(2)
|
||||
print(f"✅ File does not exist at {args.file}")
|
||||
exit(0)
|
||||
else:
|
||||
raise ValueError("Either --return-zero-if-exists or --return-zero-if-not-exists must be specified")
|
||||
else:
|
||||
if not args.directory.is_absolute():
|
||||
raise ValueError("Directory path must be absolute")
|
||||
if args.return_zero_if_exists:
|
||||
if not args.directory.exists():
|
||||
print(f"❌ Directory does not exist at {args.directory}")
|
||||
exit(1)
|
||||
if not args.directory.is_dir():
|
||||
print(f"❌ Path exists but is not a directory at {args.directory}")
|
||||
exit(2)
|
||||
print(f"✅ Directory exists at {args.directory}")
|
||||
exit(0)
|
||||
elif args.return_zero_if_not_exists:
|
||||
if args.directory.is_dir():
|
||||
print(f"❌ Directory exists at {args.directory}")
|
||||
exit(1)
|
||||
if args.directory.exists():
|
||||
print(f"❌ Path exists but is not a directory at {args.directory}")
|
||||
exit(2)
|
||||
print(f"✅ Directory does not exist at {args.directory}")
|
||||
exit(0)
|
||||
else:
|
||||
raise ValueError("Either --return-zero-if-exists or --return-zero-if-not-exists must be specified")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
exit(1)
|
||||
76
tools/EVerest-main/cmake/trailbook/check_requirements_txt.py
Executable file
76
tools/EVerest-main/cmake/trailbook/check_requirements_txt.py
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
#
|
||||
"""
|
||||
author: andreas.heinrich@pionix.de
|
||||
This script checks whether the packages in a requirements.txt are satisfied.
|
||||
If run inside a virtual environment, it can optionally fix unmet requirements by running pip install -r.
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from importlib.metadata import version, PackageNotFoundError
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
def parse_requirement(req_line: str):
|
||||
req_line = req_line.strip()
|
||||
if not req_line or req_line.startswith("#"):
|
||||
return None
|
||||
match = re.match(r"([a-zA-Z0-9_\-]+)==([0-9\.]+)", req_line)
|
||||
if match:
|
||||
return match.groups()
|
||||
return (req_line, None)
|
||||
|
||||
|
||||
def check_requirements(file_path: str, fix_in_venv: bool = False):
|
||||
errors = []
|
||||
with open(file_path, "r") as f:
|
||||
for line in f:
|
||||
parsed = parse_requirement(line)
|
||||
if not parsed:
|
||||
continue
|
||||
pkg, req_version = parsed
|
||||
try:
|
||||
installed_version = version(pkg)
|
||||
if req_version and installed_version != req_version:
|
||||
errors.append(f"{pkg}=={req_version} (installed: {installed_version})")
|
||||
except PackageNotFoundError:
|
||||
errors.append(f"{pkg}=={req_version or 'any version'} (not installed)")
|
||||
|
||||
if fix_in_venv and errors:
|
||||
if sys.prefix != sys.base_prefix:
|
||||
print(f"Attempting to fix requirements in the current venv: {sys.prefix}")
|
||||
subprocess.run([sys.executable, "-m", "pip", "install", "-r", file_path], check=True)
|
||||
return check_requirements(file_path, fix_in_venv=False)
|
||||
else:
|
||||
print("Not in a virtual environment. Cannot fix requirements automatically.")
|
||||
|
||||
if not errors:
|
||||
print("✅ All requirements are met.")
|
||||
else:
|
||||
print("❌ There are unmet requirements:")
|
||||
for e in errors:
|
||||
print(" ", e)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Checks if the packages in a requirements.txt are satisfied.")
|
||||
parser.add_argument("requirements_file", type=str, help="Path to the requirements.txt")
|
||||
parser.add_argument("--fix-in-venv", action="store_true", help="Run pip install -r in the current venv if there are unmet requirements")
|
||||
args = parser.parse_args()
|
||||
check_requirements(args.requirements_file, args.fix_in_venv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
exit(1)
|
||||
85
tools/EVerest-main/cmake/trailbook/create_metadata_yaml.py
Executable file
85
tools/EVerest-main/cmake/trailbook/create_metadata_yaml.py
Executable file
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
#
|
||||
"""
|
||||
author: andreas.heinrich@pionix.de
|
||||
This script creates a trailbook_metadata.yaml file
|
||||
based on the versions found in the multiversion root directory.
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Creates a trailbook_metadata.yaml file')
|
||||
|
||||
parser.add_argument(
|
||||
'--multiversion-root-directory',
|
||||
type=Path,
|
||||
dest='multiversion_root_dir',
|
||||
action='store',
|
||||
required=True,
|
||||
help='Path to the root directory of the multiversion documentation'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--output-path',
|
||||
type=Path,
|
||||
dest='output_path',
|
||||
action='store',
|
||||
required=True,
|
||||
help='Path where the trailbook_metadata.yaml file will be created'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--additional-version',
|
||||
type=str,
|
||||
dest='additional_versions',
|
||||
action='append',
|
||||
default=[],
|
||||
help='Additional version to include in the metadata (can be used multiple times)'
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.multiversion_root_dir.is_absolute():
|
||||
raise ValueError("Multiversion root directory must be absolute")
|
||||
if not args.multiversion_root_dir.is_dir():
|
||||
print(f"\033[33mWarning: {args.multiversion_root_dir} does not exist or is not a directory, it is treated as an empty multiversion root dir\033[0m")
|
||||
if not args.output_path.is_absolute():
|
||||
raise ValueError("Output path must be absolute")
|
||||
if args.output_path.exists():
|
||||
raise FileExistsError("Output path already exists")
|
||||
|
||||
versions_list = []
|
||||
if args.multiversion_root_dir.is_dir():
|
||||
for instance_dir in args.multiversion_root_dir.iterdir():
|
||||
if not instance_dir.is_dir():
|
||||
continue
|
||||
if not (instance_dir / 'index.html').is_file():
|
||||
continue
|
||||
versions_list.append(instance_dir.name)
|
||||
versions_list.extend(args.additional_versions)
|
||||
versions_list = list(set(versions_list))
|
||||
if len(versions_list) == 0:
|
||||
raise ValueError("No versions found in the specified multiversion root directory")
|
||||
versions_list.sort()
|
||||
|
||||
# create yaml content
|
||||
data = {
|
||||
'versions': versions_list
|
||||
}
|
||||
# render yaml content
|
||||
with args.output_path.open('w') as f:
|
||||
yaml.dump(data, f, default_flow_style=False)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
exit(1)
|
||||
223
tools/EVerest-main/cmake/trailbook/filelist_manager.py
Executable file
223
tools/EVerest-main/cmake/trailbook/filelist_manager.py
Executable file
@@ -0,0 +1,223 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
#
|
||||
"""
|
||||
author: andreas.heinrich@pionix.de
|
||||
This script provides command to manage a list of file paths
|
||||
It can be used for custom cmake commands to track created files and directories
|
||||
and later remove or move them.
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
import yaml
|
||||
|
||||
|
||||
def create_filelist(args):
|
||||
if not args.root_dir.exists():
|
||||
raise ValueError("Root directory does not exist")
|
||||
if not args.root_dir.is_dir():
|
||||
raise ValueError("Root directory must be a directory")
|
||||
|
||||
if args.data_file.exists():
|
||||
raise FileExistsError("Data file already exists")
|
||||
|
||||
file_paths = []
|
||||
directory_paths = []
|
||||
for item in args.root_dir.rglob('*'):
|
||||
relative_path = item.relative_to(args.root_dir)
|
||||
if item.is_dir():
|
||||
directory_paths.append(str(relative_path))
|
||||
elif item.is_file():
|
||||
file_paths.append(str(relative_path))
|
||||
else:
|
||||
raise ValueError(f"Unknown file type: {item}")
|
||||
|
||||
data = {
|
||||
'files': file_paths,
|
||||
'directories': directory_paths
|
||||
}
|
||||
|
||||
args.data_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with args.data_file.open('w') as f:
|
||||
yaml.dump(data, f)
|
||||
exit(0)
|
||||
|
||||
|
||||
def remove_filelist(args):
|
||||
if not args.data_file.exists():
|
||||
exit(0)
|
||||
if not args.data_file.is_file():
|
||||
raise ValueError("Data file path is not a file")
|
||||
|
||||
with args.data_file.open('r') as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
for file_path in data.get('files', []):
|
||||
full_path = args.root_dir / file_path
|
||||
if not full_path.exists():
|
||||
raise FileNotFoundError(f"File does not exist: {full_path}")
|
||||
if not full_path.is_file():
|
||||
raise ValueError(f"Path is not a file: {full_path}")
|
||||
full_path.unlink()
|
||||
|
||||
for dir_path in data.get('directories', []):
|
||||
full_path = args.root_dir / dir_path
|
||||
if not full_path.exists():
|
||||
raise FileNotFoundError(f"Directory does not exist: {full_path}")
|
||||
if not full_path.is_dir():
|
||||
raise ValueError(f"Path is not a directory: {full_path}")
|
||||
|
||||
if len(list(full_path.iterdir())) > 0:
|
||||
continue
|
||||
|
||||
full_path.rmdir()
|
||||
|
||||
args.data_file.unlink()
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
def move_filelist(args):
|
||||
if not args.root_dir.exists():
|
||||
raise ValueError("Root directory does not exist")
|
||||
if not args.root_dir.is_dir():
|
||||
raise ValueError("Root directory must be a directory")
|
||||
|
||||
if not args.data_file.exists():
|
||||
raise FileNotFoundError("Data file does not exist")
|
||||
if not args.data_file.is_file():
|
||||
raise ValueError("Data file path is not a file")
|
||||
|
||||
if not args.target_root_dir.is_absolute():
|
||||
raise ValueError("Target root directory must be absolute")
|
||||
if args.target_root_dir.exists():
|
||||
if not args.target_root_dir.is_dir():
|
||||
raise ValueError("Target root directory must be a directory")
|
||||
|
||||
with args.data_file.open('r') as f:
|
||||
data = yaml.safe_load(f)
|
||||
|
||||
for file_path in data.get('files', []):
|
||||
source_file = args.root_dir / file_path
|
||||
target_file = args.target_root_dir / file_path
|
||||
target_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
source_file.rename(target_file)
|
||||
|
||||
for dir_path in data.get('directories', []):
|
||||
source_dir = args.root_dir / dir_path
|
||||
target_dir = args.target_root_dir / dir_path
|
||||
if not target_dir.exists():
|
||||
source_dir.rename(target_dir)
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='This script provides command to manage a list of file paths')
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
create_parser = subparsers.add_parser(
|
||||
"create",
|
||||
description="Creates the file with a list of all paths in it",
|
||||
add_help=True,
|
||||
)
|
||||
create_parser.add_argument(
|
||||
'--data-file',
|
||||
type=Path,
|
||||
dest='data_file',
|
||||
action='store',
|
||||
required=True,
|
||||
help='File to read/write from/to filelist'
|
||||
)
|
||||
create_parser.add_argument(
|
||||
'--root-directory',
|
||||
type=Path,
|
||||
dest='root_dir',
|
||||
action='store',
|
||||
required=True,
|
||||
help='Path to the directory to list'
|
||||
)
|
||||
create_parser.set_defaults(
|
||||
action_handler=create_filelist
|
||||
)
|
||||
|
||||
remove_parser = subparsers.add_parser(
|
||||
"remove",
|
||||
description="Removes all files and directories listed in the filelist",
|
||||
add_help=True,
|
||||
)
|
||||
remove_parser.add_argument(
|
||||
'--data-file',
|
||||
type=Path,
|
||||
dest='data_file',
|
||||
action='store',
|
||||
required=True,
|
||||
help='File to read/write from/to filelist'
|
||||
)
|
||||
remove_parser.add_argument(
|
||||
'--root-directory',
|
||||
type=Path,
|
||||
dest='root_dir',
|
||||
action='store',
|
||||
required=True,
|
||||
help='Path to the directory to list'
|
||||
)
|
||||
remove_parser.set_defaults(
|
||||
action_handler=remove_filelist
|
||||
)
|
||||
|
||||
move_parser = subparsers.add_parser(
|
||||
"move",
|
||||
description="Moves all files and directories listed in the filelist to a new root directory",
|
||||
add_help=True,
|
||||
)
|
||||
move_parser.add_argument(
|
||||
'--data-file',
|
||||
type=Path,
|
||||
dest='data_file',
|
||||
action='store',
|
||||
required=True,
|
||||
help='File to read/write from/to filelist'
|
||||
)
|
||||
move_parser.add_argument(
|
||||
'--root-directory',
|
||||
type=Path,
|
||||
dest='root_dir',
|
||||
action='store',
|
||||
required=True,
|
||||
help='Path to the directory to list'
|
||||
)
|
||||
move_parser.add_argument(
|
||||
'--target-root-directory',
|
||||
type=Path,
|
||||
dest='target_root_dir',
|
||||
action='store',
|
||||
required=True,
|
||||
help='Path to the target root directory to move files to'
|
||||
)
|
||||
move_parser.set_defaults(
|
||||
action_handler=move_filelist
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.root_dir.is_absolute():
|
||||
raise ValueError("Root directory must be absolute")
|
||||
|
||||
if not args.data_file.is_absolute():
|
||||
raise ValueError("Data file path must be absolute")
|
||||
|
||||
if 'action_handler' not in args:
|
||||
raise ValueError("No action specified")
|
||||
|
||||
args.action_handler(args)
|
||||
exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
80
tools/EVerest-main/cmake/trailbook/render_redirect_template.py
Executable file
80
tools/EVerest-main/cmake/trailbook/render_redirect_template.py
Executable file
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
#
|
||||
"""
|
||||
author: andreas.heinrich@pionix.de
|
||||
This script processes a redirect template and generates a <target_file_name>.html file
|
||||
"""
|
||||
|
||||
|
||||
import argparse
|
||||
import jinja2
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Process versions_index.html.jinja and place redirect.html in the output directory')
|
||||
parser.add_argument(
|
||||
'--redirect-template',
|
||||
type=Path,
|
||||
dest='redirect_template',
|
||||
action='store',
|
||||
required=True,
|
||||
help="Redirect jinja template file"
|
||||
)
|
||||
parser.add_argument(
|
||||
'--target-path',
|
||||
type=Path,
|
||||
dest='target_path',
|
||||
action='store',
|
||||
required=True,
|
||||
help="Target path for the output"
|
||||
)
|
||||
parser.add_argument(
|
||||
'--latest-release-name',
|
||||
type=str,
|
||||
dest='latest_release_name',
|
||||
action='store',
|
||||
default="latest",
|
||||
help="Name of the latest release"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.redirect_template.is_absolute():
|
||||
raise ValueError("Redirect template path must be absolute")
|
||||
if not args.redirect_template.exists():
|
||||
raise FileNotFoundError(
|
||||
"Redirect template path: '"
|
||||
+ str(args.redirect_template)
|
||||
+ "' doesn't exist"
|
||||
)
|
||||
if not args.redirect_template.is_file():
|
||||
raise FileNotFoundError(
|
||||
f"Redirect template path: '{args.redirect_template}' is not a file"
|
||||
)
|
||||
|
||||
template_dir = args.redirect_template.parent
|
||||
template_name = args.redirect_template.name
|
||||
|
||||
env = jinja2.Environment(
|
||||
loader=jinja2.FileSystemLoader(template_dir),
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True
|
||||
)
|
||||
|
||||
template = env.get_template(template_name)
|
||||
output = template.render(
|
||||
latest_release=args.latest_release_name
|
||||
)
|
||||
args.target_path.write_text(output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
exit(1)
|
||||
46
tools/EVerest-main/cmake/trailbook/setup-trailbook.cmake
Normal file
46
tools/EVerest-main/cmake/trailbook/setup-trailbook.cmake
Normal file
@@ -0,0 +1,46 @@
|
||||
# Internal macro to find the sphinx-build executable.
|
||||
macro(_find_sphinx_build)
|
||||
execute_process(
|
||||
COMMAND
|
||||
${Python3_EXECUTABLE} -m sphinx.cmd.build --version
|
||||
RESULT_VARIABLE RESULT_SPHINX_VERSION
|
||||
)
|
||||
if("${RESULT_SPHINX_VERSION}" STREQUAL "0")
|
||||
set(_SPHINX_BUILD_EXECUTABLE "${Python3_EXECUTABLE}" "-m" "sphinx.cmd.build")
|
||||
else()
|
||||
set(_SPHINX_BUILD_EXECUTABLE "_SPHINX_BUILD_EXECUTABLE-NOTFOUND")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Internal macro to find sphinx-build, and if not found, try to install it in an active python venv.
|
||||
macro(_find_and_fix_sphinx_build)
|
||||
_find_sphinx_build()
|
||||
|
||||
if("${_SPHINX_BUILD_EXECUTABLE}" STREQUAL "_SPHINX_BUILD_EXECUTABLE-NOTFOUND")
|
||||
ev_is_python_venv_active(
|
||||
RESULT_VAR IS_PYTHON_VENV_ACTIVE
|
||||
)
|
||||
if(IS_PYTHON_VENV_ACTIVE)
|
||||
message(STATUS "sphinx-build executable not found in system, but python venv is active. Trying to use 'python3 -m pip install sphinx'.")
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -m pip install sphinx
|
||||
)
|
||||
_find_sphinx_build()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if("${_SPHINX_BUILD_EXECUTABLE}" STREQUAL "_SPHINX_BUILD_EXECUTABLE-NOTFOUND")
|
||||
message(FATAL_ERROR "sphinx-build executable not found. Please install Sphinx. You can install it via pip: pip install sphinx")
|
||||
endif()
|
||||
|
||||
message(STATUS "Found sphinx-build: ${_SPHINX_BUILD_EXECUTABLE}")
|
||||
endmacro()
|
||||
|
||||
# Internal macro to set up the trailbook environment.
|
||||
macro(_setup_trailbook)
|
||||
if(NOT _TRAILBOOK_SETUP_DONE)
|
||||
_find_and_fix_sphinx_build()
|
||||
|
||||
set(_TRAILBOOK_SETUP_DONE TRUE)
|
||||
endif()
|
||||
endmacro()
|
||||
123
tools/EVerest-main/cmake/trailbook/target_observer.py
Executable file
123
tools/EVerest-main/cmake/trailbook/target_observer.py
Executable file
@@ -0,0 +1,123 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Copyright Pionix GmbH and Contributors to EVerest
|
||||
#
|
||||
"""
|
||||
author: andreas.heinrich@pionix.de
|
||||
This script starts a CMake target http server and triggers
|
||||
regular rebuilds of a specified CMake target upon changes.
|
||||
"""
|
||||
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import argparse
|
||||
import signal
|
||||
from pathlib import Path
|
||||
from rich.live import Live
|
||||
from rich.console import Console
|
||||
from rich.panel import Panel
|
||||
from rich.layout import Layout
|
||||
from threading import Thread
|
||||
|
||||
|
||||
console = Console()
|
||||
|
||||
|
||||
def run_target(build_dir: Path, target: str, live_panel, panel_size: int) -> None:
|
||||
process = subprocess.Popen(
|
||||
[
|
||||
"cmake",
|
||||
"--build", build_dir.as_posix(),
|
||||
"--target", target
|
||||
],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True
|
||||
)
|
||||
output_lines = []
|
||||
output_lines.append(f"Running target {target} at {time.strftime('%X')}\n")
|
||||
for line in iter(process.stdout.readline, ""):
|
||||
line = line.rstrip()
|
||||
output_lines.append(line)
|
||||
output_lines = output_lines[-panel_size:]
|
||||
live_panel.update(Panel("\n".join(output_lines), title=f"{target} output"))
|
||||
process.wait()
|
||||
|
||||
|
||||
def start_server(build_dir: Path, server_target: str, server_lines: list, live_panel, panel_size: int) -> subprocess.Popen:
|
||||
print(f"Starting server target {server_target}...")
|
||||
process = subprocess.Popen(
|
||||
[
|
||||
"cmake",
|
||||
"--build", str(build_dir),
|
||||
"--target", server_target
|
||||
],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
)
|
||||
|
||||
def read_server_output():
|
||||
for line in iter(process.stdout.readline, ""):
|
||||
line = line.rstrip()
|
||||
server_lines.append(line)
|
||||
server_lines[:] = server_lines[-panel_size:]
|
||||
live_panel.update(Panel("\n".join(server_lines), title=f"{server_target} output"))
|
||||
|
||||
t = Thread(target=read_server_output, daemon=True)
|
||||
t.start()
|
||||
return process
|
||||
|
||||
|
||||
def stop_server(proc: subprocess.Popen) -> None:
|
||||
if proc and proc.poll() is None:
|
||||
print("Stopping server...")
|
||||
proc.send_signal(signal.SIGINT)
|
||||
try:
|
||||
proc.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
proc.kill()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Watch CMake target and manage server target")
|
||||
parser.add_argument("watch_target", help="CMake target to monitor and rerun if changed")
|
||||
parser.add_argument("server_target", help="CMake target that runs the server")
|
||||
parser.add_argument("--build-dir", default="build", help="CMake build directory")
|
||||
parser.add_argument("--interval-ms", type=int, default=2000, help="Check interval in milliseconds")
|
||||
args = parser.parse_args()
|
||||
|
||||
build_dir = Path(args.build_dir)
|
||||
watch_target = args.watch_target
|
||||
server_target = args.server_target
|
||||
|
||||
panel_size = 10
|
||||
layout = Layout()
|
||||
layout.split_column(
|
||||
Layout(name="server", size=panel_size+2),
|
||||
Layout(name="watch", size=panel_size+2)
|
||||
)
|
||||
with Live(layout, console=console, refresh_per_second=1):
|
||||
server_lines = []
|
||||
server_lines.append("Starting server...")
|
||||
server_panel = Panel("\n".join(server_lines), title=f"{server_target} output")
|
||||
layout["server"].update(server_panel)
|
||||
watch_panel = Panel("\n\n\n", title=f"{watch_target} output")
|
||||
layout["watch"].update(watch_panel)
|
||||
|
||||
server_proc = start_server(build_dir, server_target, server_lines, layout["server"], panel_size)
|
||||
try:
|
||||
while True:
|
||||
time.sleep(args.interval_ms / 1000)
|
||||
run_target(build_dir, watch_target, layout["watch"], panel_size)
|
||||
except KeyboardInterrupt:
|
||||
stop_server(server_proc)
|
||||
print("\n Exiting.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>
|
||||
Redirecting...
|
||||
</title>
|
||||
<meta http-equiv="refresh" content="0;url=./{{ latest_release }}">
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,13 @@
|
||||
set(PACKAGE_VERSION 0.1.0)
|
||||
|
||||
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
elseif(PACKAGE_FIND_VERSION_MAJOR STREQUAL "0")
|
||||
if(PACKAGE_FIND_VERSION_MINOR GREATER "1")
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
endif()
|
||||
else()
|
||||
set(PACKAGE_VERSION_UNSUITABLE TRUE)
|
||||
endif()
|
||||
@@ -0,0 +1,5 @@
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/setup-trailbook.cmake")
|
||||
_setup_trailbook()
|
||||
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/add-trailbook.cmake")
|
||||
Reference in New Issue
Block a user