From c8d6444e883e70a499994ea22e37afbfdc9d3d1f Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 8 Jan 2025 01:30:52 -0600 Subject: [PATCH] Improve error message when dx is called on a virtual or library package (#3505) * Improve error message when dx is called on a virtual or library package --- packages/cli/src/cli/bundle.rs | 23 +++++++++++++++++------ packages/cli/src/dioxus_crate.rs | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/cli/bundle.rs b/packages/cli/src/cli/bundle.rs index aea8417a5..9bcdc3846 100644 --- a/packages/cli/src/cli/bundle.rs +++ b/packages/cli/src/cli/bundle.rs @@ -78,7 +78,8 @@ impl Bundle { for src in bundle.bundle_paths { let src = if let Some(outdir) = &self.outdir { let dest = outdir.join(src.file_name().expect("Filename to exist")); - crate::fastfs::copy_asset(&src, &dest)?; + crate::fastfs::copy_asset(&src, &dest) + .context("Failed to copy or compress optimized asset")?; dest } else { src.clone() @@ -141,13 +142,15 @@ impl Bundle { if cfg!(windows) { name.set_extension("exe"); } - std::fs::create_dir_all(krate.bundle_dir(self.build_arguments.platform()))?; + std::fs::create_dir_all(krate.bundle_dir(self.build_arguments.platform())) + .context("Failed to create bundle directory")?; std::fs::copy( &bundle.app.exe, krate .bundle_dir(self.build_arguments.platform()) .join(&name), - )?; + ) + .with_context(|| "Failed to copy the output executable into the bundle directory")?; let binaries = vec![ // We use the name of the exe but it has to be in the same directory @@ -175,8 +178,14 @@ impl Bundle { bundle_settings.resources_map = Some(HashMap::new()); } - for entry in std::fs::read_dir(bundle.build.asset_dir())?.flatten() { - let old = entry.path().canonicalize()?; + let asset_dir = bundle.build.asset_dir(); + let asset_dir_entries = std::fs::read_dir(&asset_dir) + .with_context(|| format!("failed to read asset directory {:?}", asset_dir))?; + for entry in asset_dir_entries.flatten() { + let old = entry + .path() + .canonicalize() + .with_context(|| format!("Failed to canonicalize {entry:?}"))?; let new = PathBuf::from("assets").join(old.file_name().expect("Filename to exist")); tracing::debug!("Bundled asset: {old:?} -> {new:?}"); @@ -221,7 +230,9 @@ impl Bundle { settings = settings.target("aarch64-apple-ios".to_string()); } - let settings = settings.build()?; + let settings = settings + .build() + .context("failed to bundle tauri bundle settings")?; tracing::debug!("Bundling project with settings: {:#?}", settings); if cfg!(target_os = "macos") { std::env::set_var("CI", "true"); diff --git a/packages/cli/src/dioxus_crate.rs b/packages/cli/src/dioxus_crate.rs index b66c9c041..bf9d2f4f9 100644 --- a/packages/cli/src/dioxus_crate.rs +++ b/packages/cli/src/dioxus_crate.rs @@ -58,7 +58,27 @@ impl DioxusCrate { .find(|target| { target_name == target.name.as_str() && target.kind.contains(&target_kind) }) - .with_context(|| format!("Failed to find target {target_name}"))? + .with_context(|| { + let target_of_kind = |kind|-> String { + let filtered_packages = main_package + .targets + .iter() + .filter_map(|target| { + target.kind.contains(kind).then_some(target.name.as_str()) + }).collect::>(); + filtered_packages.join(", ")}; + if let Some(example) = &target.example { + let examples = target_of_kind(&TargetKind::Example); + format!("Failed to find example {example}. \nAvailable examples are:\n{}", examples) + } else if let Some(bin) = &target.bin { + let binaries = target_of_kind(&TargetKind::Bin); + format!("Failed to find binary {bin}. \nAvailable binaries are:\n{}", binaries) + } else { + format!("Failed to find target {target_name}. \nIt looks like you are trying to build dioxus in a library crate. \ + You either need to run dx from inside a binary crate or build a specific example with the `--example` flag. \ + Available examples are:\n{}", target_of_kind(&TargetKind::Example)) + } + })? .clone(); let settings = CliSettings::load(); @@ -686,7 +706,15 @@ fn find_main_package(krates: &Krates, package: Option) -> Result let kid = closest_parent .map(|(id, _)| id) - .context("Failed to find current package")?; + .with_context(|| { + let bin_targets = krates.workspace_members().filter_map(|krate|match krate { + krates::Node::Krate { krate, .. } if krate.targets.iter().any(|t| t.kind.contains(&krates::cm::TargetKind::Bin))=> { + Some(format!("- {}", krate.name)) + } + _ => None + }).collect::>(); + format!("Failed to find binary package to build.\nYou need to either run dx from inside a binary crate or specify a binary package to build with the `--package` flag. Try building again with one of the binary packages in the workspace:\n{}", bin_targets.join("\n")) + })?; let package = krates.nid_for_kid(kid).unwrap(); Ok(package)