Common Pitfalls
When creating templates with cargo-generate
, there are several common issues and pitfalls that template authors may encounter. This section aims to highlight these issues and provide guidance on how to avoid them.
GitHub Actions and Liquid Template Language Interference
GitHub Actions use their own templating language, which can interfere with the Liquid template language used by cargo-generate
. This can lead to unexpected behavior when placeholders are used in GitHub Actions workflow files.
Issue
When using placeholders in GitHub Actions workflow files, the syntax for GitHub Actions (${{ ... }}
) can conflict with the Liquid syntax ({{ ... }}
). This can cause errors or unexpected behavior during template generation.
For more details, you can refer to the discussion that was opened for this purpose.
Workarounds
-
Escape Liquid Syntax: One way to avoid conflicts is to escape the Liquid syntax in the workflow files. This can be done by using
{% raw %}
and{% endraw %}
tags around the GitHub Actions syntax.jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Run cargo-generate run: | cargo generate --git https://github.com/your/repo.git --name ${{ '{% raw %}' }}{{ project-name }}{% endraw %}
-
Use Different Placeholders: Another approach is to use different placeholders for GitHub Actions and Liquid. For example, you can use a different syntax for placeholders in GitHub Actions and then replace them with the correct values in a pre-processing step.
jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up project run: | PROJECT_NAME={{ project-name }} echo "Project name is $PROJECT_NAME"
-
Use
cargo-generate
Placeholders Sparingly: Limit the use ofcargo-generate
placeholders in GitHub Actions workflow files to only where necessary. This reduces the chances of conflicts and makes the workflow files easier to manage. -
Liquid Prepend and Append: Use Liquid's
prepend
andappend
filters to dynamically generate the GitHub Actions syntax. This ensures that the placeholders are correctly processed by Liquid and result in the correct GitHub Actions markup.jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v2 - name: Set up project run: | echo "${{ "github-variable" | prepend: "{{" | append: "}}" }}"
-
Pre-Hook Rhai Script: Another solution is to create a pre-hook Rhai script that executes
gsed
orsed
to replace all GitHub Actions placeholders with the Liquid syntax on the fly. This automates the escaping process.[hooks] pre = ["pre-hook.rhai"]
// pre-hook.rhai let result = system::command("gsed", ["-i", 's/${{ /${{ "{{" | prepend: "{{" | append: "}}" }}/g', "path/to/workflow/file.yml"]); if result != 0 { abort("Failed to replace GitHub Actions placeholders"); }
For more details, you can refer to the issue that was opened for this.
Undefined Placeholders
Another common pitfall is using placeholders that are not defined. When a placeholder is not defined, cargo-generate
will not throw an error; instead, it will replace the placeholder with an empty string. This can lead to unexpected results in the generated files.
Issue
If a placeholder is used in a template file but is not defined in the cargo-generate.toml
file or provided by the user, it will be replaced with an empty string. This can cause issues such as missing values in configuration files or broken code.
Solution
-
Define All Placeholders: Ensure that all placeholders used in the template files are defined in the
cargo-generate.toml
file. This includes providing default values or prompting the user for input.[placeholders] project_name = { prompt = "Enter project name", default = "my_project", type = "string" } author_name = { prompt = "Enter author name", default = "John Doe", type = "string" }
-
Validate Placeholder Usage: Before generating the template, validate that all placeholders used in the template files are defined. This can be done by reviewing the template files and cross-referencing them with the placeholders defined in the
cargo-generate.toml
file. -
Provide Default Values: Where possible, provide default values for placeholders to ensure that they are always replaced with meaningful values.
[placeholders] project_name = { prompt = "Enter project name", default = "my_project", type = "string" }
By being aware of these common issues and pitfalls, template authors can create more robust and reliable templates with cargo-generate
. Proper handling of GitHub Actions and Liquid template language interference, as well as ensuring that all placeholders are defined, will help avoid unexpected behavior and improve the overall template generation experience.