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

Use libraries instead of locally installed binaries for Cargo Generate and Wasm Opt #429

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
1,382 changes: 1,331 additions & 51 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ categories = ["development-tools", "wasm", "web-programming"]
keywords = ["leptos"]
version = "0.2.27"
edition = "2021"
rust-version = "1.71"
rust-version = "1.82.0"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clippy was giving warnings that the earliest rust version to support is_none_or (which is used in this project) is 1.82.0.

authors = ["Henrik Akesson", "Greg Johnston", "Ben Wishovich"]

[package.metadata.wix]
Expand Down Expand Up @@ -88,6 +88,8 @@ base64ct = { version = "1.6.0", features = ["alloc"] }
swc = "10.0"
swc_common = "5.0"
shlex = "1.3.0"
cargo-generate = "0.22"
wasm-opt = "0.116.1"

[dev-dependencies]
insta = { version = "1.40.0", features = ["yaml"] }
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,7 @@ For setting up your project, have a look at the [examples](https://github.com/le

## Dependencies

The dependencies for [sass](https://sass-lang.com/install), [wasm-opt](https://github.com/WebAssembly/binaryen) and
[cargo-generate](https://github.com/cargo-generate/cargo-generate#installation) are automatically installed in a cache directory
when they are used if they are not already installed and found by [which](https://crates.io/crates/which).
The dependency for [sass](https://sass-lang.com/install) is automatically installed in a cache directory when they are used if they are not already installed and found by [which](https://crates.io/crates/which).
Different versions of the dependencies might accumulate in this directory, so feel free to delete it.

| OS | Example |
Expand Down Expand Up @@ -334,10 +332,8 @@ Note when using directories:
Internally the versions of the external tools called by `cargo-leptos` are hardcoded. Use these environment variables to
override the versions `cargo-leptos` should use (e.g. `LEPTOS_SASS_VERSION=1.69.5`):

- LEPTOS_CARGO_GENERATE_VERSION
- LEPTOS_TAILWIND_VERSION
- LEPTOS_SASS_VERSION
- LEPTOS_WASM_OPT_VERSION

## End-to-end testing

Expand Down
114 changes: 45 additions & 69 deletions src/command/new.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use crate::ext::anyhow::{Context, Result};
use cargo_generate::{generate, GenerateArgs, TemplatePath};
use clap::Args;

use tokio::process::Command;

use crate::ext::exe::Exe;

// A subset of the cargo-generate commands available.
// See: https://github.com/cargo-generate/cargo-generate/blob/main/src/args.rs

Expand Down Expand Up @@ -51,77 +48,56 @@ pub struct NewCommand {
}

impl NewCommand {
pub async fn run(&self) -> Result<()> {
let args = self.to_args();
let exe = Exe::CargoGenerate.get().await.dot()?;
pub fn run(self) -> Result<()> {
let Self {
git,
branch,
tag,
path,
name,
force,
verbose,
init,
} = self;
let args = GenerateArgs {
template_path: TemplatePath {
git: absolute_git_url(git),
branch,
tag,
path,
..Default::default()
},
name,
force,
verbose,
init,
..Default::default()
};

generate(args).dot()?;

let mut process = Command::new(exe)
.arg("generate")
.args(&args)
.spawn()
.context("Could not spawn cargo-generate command (verify that it is installed)")?;
process.wait().await.dot()?;
Ok(())
}

pub fn to_args(&self) -> Vec<String> {
let mut args = vec![];
opt_push(&mut args, "git", &absolute_git_url(&self.git));
opt_push(&mut args, "branch", &self.branch);
opt_push(&mut args, "tag", &self.tag);
opt_push(&mut args, "path", &self.path);
opt_push(&mut args, "name", &self.name);
bool_push(&mut args, "force", self.force);
bool_push(&mut args, "verbose", self.verbose);
bool_push(&mut args, "init", self.init);
args
}
}

fn bool_push(args: &mut Vec<String>, name: &str, set: bool) {
if set {
args.push(format!("--{name}"))
}
}

fn opt_push(args: &mut Vec<String>, name: &str, arg: &Option<String>) {
if let Some(arg) = arg {
args.push(format!("--{name}"));
args.push(arg.clone());
}
}

/// Workaround to support short `new --git leptos-rs/start` command when behind Git proxy.
/// See https://github.com/cargo-generate/cargo-generate/issues/752.
fn absolute_git_url(url: &Option<String>) -> Option<String> {
match url {
Some(url) => match url.as_str() {
// leptos-rs official templates
// NB: The alternate workarounds enable an even shorter `cargo leptos new --git start-{{trunk | actix | axum | ..}}` command syntax
"start-trunk" => Some("https://github.com/leptos-rs/start-trunk".to_string()),
"leptos-rs/start-trunk" => Some("https://github.com/leptos-rs/start-trunk".to_string()),

"start-actix" => Some("https://github.com/leptos-rs/start".to_string()),
"leptos-rs/start" => Some("https://github.com/leptos-rs/start".to_string()),
"leptos-rs/start-actix" => Some("https://github.com/leptos-rs/start".to_string()),

"start-axum" => Some("https://github.com/leptos-rs/start-axum".to_string()),
"leptos-rs/start-axum" => Some("https://github.com/leptos-rs/start-axum".to_string()),

"start-axum-workspace" => {
Some("https://github.com/leptos-rs/start-axum-workspace".to_string())
}
"leptos-rs/start-axum-workspace" => {
Some("https://github.com/leptos-rs/start-axum-workspace".to_string())
}
"start-aws" => Some("https://github.com/leptos-rs/start-aws".to_string()),
"leptos-rs/start-aws" => Some("https://github.com/leptos-rs/start-aws".to_string()),

"start-spin" => Some("https://github.com/leptos-rs/start-spin".to_string()),
"leptos-rs/start-spin" => Some("https://github.com/leptos-rs/start-spin".to_string()),
fn absolute_git_url(url: Option<String>) -> Option<String> {
url.map(|url| match url.as_str() {
"start-trunk" | "leptos-rs/start-trunk" => format_leptos_starter_url("start-trunk"),
"start-actix" | "leptos-rs/start" | "leptos-rs/start-actix" => {
format_leptos_starter_url("start")
}
"start-axum" | "leptos-rs/start-axum" => format_leptos_starter_url("start-axum"),
"start-axum-workspace" | "leptos-rs/start-axum-workspace" => {
format_leptos_starter_url("start-axum-workspace")
}
"start-aws" | "leptos-rs/start-aws" => format_leptos_starter_url("start-aws"),
"start-spin" | "leptos-rs/start-spin" => format_leptos_starter_url("start-spin"),
_ => url,
})
}

_ => Some(url.to_string()),
},
None => None,
}
fn format_leptos_starter_url(repo: &str) -> String {
format!("https://github.com/leptos-rs/{repo}")
}
32 changes: 9 additions & 23 deletions src/compile/front.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ use crate::ext::sync::{wait_interruptible, CommandResult};
use crate::ext::{fs, PathBufExt};
use crate::signal::{Interrupt, Outcome, Product};
use crate::{
ext::{
anyhow::{Context, Result},
exe::Exe,
},
ext::anyhow::{Context, Result},
logger::GRAY,
};
use anyhow::Ok;
use camino::Utf8Path;
use std::sync::Arc;
use swc::config::IsModule;
use swc::JsMinifyExtras;
use swc::{config::JsMinifyOptions, try_with_handler, BoolOrDataConfig};
use swc_common::{FileName, SourceMap, GLOBALS};
use tokio::process::Child;
use tokio::{process::Command, sync::broadcast, task::JoinHandle};
use tokio::{process::Command, task::JoinHandle};
use wasm_bindgen_cli_support::Bindgen;
use wasm_opt::OptimizationOptions;

pub async fn front(
proj: &Arc<Project>,
Expand Down Expand Up @@ -106,7 +105,6 @@ pub fn build_cargo_front_cmd(

async fn bindgen(proj: &Project) -> Result<Outcome<Product>> {
let wasm_file = &proj.lib.wasm_file;
let interrupt = Interrupt::subscribe_any();

log::info!("Front generating JS/WASM with wasm-bindgen");

Expand Down Expand Up @@ -153,11 +151,7 @@ async fn bindgen(proj: &Project) -> Result<Outcome<Product>> {
.dot()?;

if proj.release {
match optimize(&wasm_file.dest, interrupt).await.dot()? {
CommandResult::Interrupted => return Ok(Outcome::Stopped),
CommandResult::Failure(_) => return Ok(Outcome::Failed),
_ => {}
}
optimize(&wasm_file.dest)?;
}

let wasm_optimize_end_time = tokio::time::Instant::now();
Expand Down Expand Up @@ -193,18 +187,10 @@ async fn bindgen(proj: &Project) -> Result<Outcome<Product>> {
Ok(Outcome::Success(Product::Front))
}

async fn optimize(
file: &Utf8Path,
interrupt: broadcast::Receiver<()>,
) -> Result<CommandResult<()>> {
let wasm_opt = Exe::WasmOpt.get().await.dot()?;

let args = [file.as_str(), "-Oz", "-o", file.as_str()];
let process = Command::new(wasm_opt)
.args(args)
.spawn()
.context("Could not spawn command")?;
wait_interruptible("wasm-opt", process, interrupt).await
fn optimize(file: &Utf8Path) -> Result<()> {
OptimizationOptions::new_optimize_for_size_aggressively()
.run(file, file)
Copy link
Contributor Author

@SleeplessOne1917 SleeplessOne1917 Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how to make this interruptable since run is synchronous. It might not be needed since it's not a child process anymore.

.dot()
}

fn minify<JS: AsRef<str>>(js: JS) -> Result<String> {
Expand Down
2 changes: 1 addition & 1 deletion src/compile/tailwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub async fn compile_tailwind(proj: &Project, tw_conf: &TailwindConfig) -> Resul
create_default_tailwind_config(tw_conf).await?;
}

let (line, process) = tailwind_process(&proj, "tailwindcss", tw_conf).await?;
let (line, process) = tailwind_process(proj, "tailwindcss", tw_conf).await?;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to fix a Clippy warning.


match wait_piped_interruptible("Tailwind", process, Interrupt::subscribe_any()).await? {
CommandResult::Success(output) => {
Expand Down
2 changes: 0 additions & 2 deletions src/config/dotenvs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ fn overlay(conf: &mut ProjectConfig, envs: impl Iterator<Item = (String, String)
// good way at the moment to pull the ProjectConfig all the way to Exe
exe::ENV_VAR_LEPTOS_TAILWIND_VERSION => {}
exe::ENV_VAR_LEPTOS_SASS_VERSION => {}
exe::ENV_VAR_LEPTOS_CARGO_GENERATE_VERSION => {}
exe::ENV_VAR_LEPTOS_WASM_OPT_VERSION => {}
_ if key.starts_with("LEPTOS_") => {
log::warn!("Env {key} is not used by cargo-leptos")
}
Expand Down
Loading