Skip to content
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

[docs] Explain which conditional blocks are valid in cargo-generate.toml #1119

Open
Andrew15-5 opened this issue Feb 5, 2024 · 6 comments
Open

Comments

@Andrew15-5
Copy link
Contributor

Andrew15-5 commented Feb 5, 2024

Here is an example from https://github.com/dioxuslabs/dioxus-template (very verbose and repetitive):

original example
[placeholders.platform]
type = "string"
prompt = "What platform are you targeting?"
choices = ["web", "fullstack", "desktop", "liveview", "TUI"]
default = "web"

[conditional.'platform == "liveview"'.placeholders.backend]
type = "string"
prompt = "What backend framework are you using?"
choices = ["Axum", "Warp", "Salvo"]
default = "Axum"

[conditional.'platform == "fullstack"'.placeholders.backend]
type = "string"
prompt = "What backend framework are you using?"
choices = ["Axum", "Warp", "Salvo"]
default = "Axum"

[conditional.'platform == "web"'.placeholders.styling]
type = "string"
prompt = "How do you want to create CSS?"
choices = ["Tailwind", "Vanilla"]
default = "Vanilla"

[conditional.'platform == "desktop"'.placeholders.styling]
type = "string"
prompt = "How do you want to create CSS?"
choices = ["Tailwind", "Vanilla"]
default = "Vanilla"

[conditional.'platform == "fullstack"'.placeholders.styling]
type = "string"
prompt = "How do you want to create CSS?"
choices = ["Tailwind", "Vanilla"]
default = "Vanilla"

It uses the same conditional block as in https://cargo-generate.github.io/cargo-generate/templates/conditional.html.


Placeholder values defined in conditional sections cannot be used to enable/disable further conditional sections, they can however still be used in the actual template!

I don't understand this sentence. IIUC, the "placeholder values", i.e, .placeholders.<value> can be used to enable further conditional sections, because depending on which platform I chose the next questions will change depending on the value of the platform variable. So maybe this also should be addressed in the docs.


I tried using || operator in the conditions and surprisingly it worked! So I was able to optimize the config to this:

optimized example 1
[placeholders.platform]
type = "string"
prompt = "What platform are you targeting?"
choices = ["web", "fullstack", "desktop", "liveview", "TUI"]
default = "web"

[conditional.'platform == "liveview" || platform == "fullstack"'.placeholders.backend]
type = "string"
prompt = "What backend framework are you using?"
choices = ["Axum", "Warp", "Salvo"]
default = "Axum"

[conditional.'platform == "web" || platform == "desktop" || platform == "fullstack"'.placeholders.styling]
type = "string"
prompt = "How do you want to create CSS?"
choices = ["Tailwind", "Vanilla"]
default = "Vanilla"

I was going to ask if conditional is actually a Rust code evaluation, but after another successful optimization:

optimized example 2
[placeholders.platform]
type = "string"
prompt = "What platform are you targeting?"
choices = ["web", "fullstack", "desktop", "liveview", "TUI"]
default = "web"

[conditional.'["liveview", "fullstack"].contains(platform)'.placeholders.backend]
type = "string"
prompt = "What backend framework are you using?"
choices = ["Axum", "Warp", "Salvo"]
default = "Axum"

[conditional.'["web", "desktop", "fullstack"].contains(platform)'.placeholders.styling]
type = "string"
prompt = "How do you want to create CSS?"
choices = ["Tailwind", "Vanilla"]
default = "Vanilla"

I'm almost 100% sure that it is indeed a Rust conditional, or could be a JS? I wasn't able to use Some and unwrap like I can do here:

fn main() {
    if [Some("web").unwrap(), "other"].contains(&"web") {
        println!("Hello, world!");
    }
}
[conditional.'[Some("web").unwrap(), "desktop", "fullstack"].contains(platform)'.placeholders.styling]

(Also, TOML syntax highlighting breaks if I use [] inside the '<condition>'. yj successfully converts this to YAML and JSON, but fails at converting to TOML. So either yj isn't perfect or above syntax is indeed invalid. Does anyone know which one is true?)

So, maybe a restricted version of Rust?

Either way, I didn't find anything even close to "this level" of conditions in the docs, so I think the docs just missing it and should be updated with more examples and an explanation of what you can and can't do in conditional block.

Update: I tried using the optimized syntax and it does generate all the same stuff.

@sassman
Copy link
Member

sassman commented Feb 16, 2024

Hey @Andrew15-5,

that's a very good question!
I've seen this stuff first some time ago in a Cargo.toml like

[target.'cfg(target_arch = "x86_64")'.dependencies]

and I found it quite creepy.

So I did not found much documentation about it on the toml repo.
I added some more tests for now (see #1133) but I guess extended documentation and those examples of yours are valuable for users.

@Andrew15-5
Copy link
Contributor Author

Wait, are you saying cargo-generate is not the one responsible for evaluating the conditional blocks? Then who is?

@sassman
Copy link
Member

sassman commented Feb 17, 2024

Sorry, I found it this code here actually takes care of the conditional evaluation.

And, the whole logic is not backed by toml as I thought but by our rhai script hooks.

Haven't looked at this code in quite a while.

But I guess the whole conversation already reveals that our docs about the whole conditionals feature are not good enough.

@Andrew15-5
Copy link
Contributor Author

I never used Rhai. Is any valid Rhai conditional statement can be used in the conditional block? Or are there some restrictions?

@sassman
Copy link
Member

sassman commented Feb 17, 2024

it's a simple rhai expression that is evaluated.

@Andrew15-5
Copy link
Contributor Author

Ok. I'll probably check out Rhai in general to understand what kind of expressions can be evaluated. So that I can insert the most clever and ugly conditional statement in the cargo-generate.toml that has ever been created! /s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants