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

trunk fails to find rust code when build.target = "src/index.html" #857

Open
aslilac opened this issue Aug 24, 2024 · 7 comments
Open

trunk fails to find rust code when build.target = "src/index.html" #857

aslilac opened this issue Aug 24, 2024 · 7 comments

Comments

@aslilac
Copy link

aslilac commented Aug 24, 2024

I would like my index.html to live in the src/ directory, because I consider it to be part of my source code. Trunk unfortunately doesn't seem to handle this well.

[build]
target = "src/index.html"

...results in Trunk saying...

WARN no rust project found

...even though the Cargo.toml and src/main.rs files are unmoved.

I poked around the trunk repo a bit to see if I could figure out a fix, but got lost pretty quickly. :(

@mnemotic
Copy link
Contributor

See #849 (comment).

In your index.html you need to tell Trunk where to look for Cargo.toml.

@aslilac
Copy link
Author

aslilac commented Sep 3, 2024

huh, interesting. I would've really expected this to be configurable from Trunk.toml. it feels really unintuitive to configure something like this inside the index.html, imho. kinda like a Box<Box<ThingIWantToConfigure>>.

@ctron
Copy link
Collaborator

ctron commented Sep 4, 2024

I agree, it could be more intuitive. On the other side, trunk considers the index.html and or Trunk.toml the authoritative source of information. Cargo is "only" a sub-task.

If you have any ideas how to improve that, that would be great.

@aslilac
Copy link
Author

aslilac commented Sep 4, 2024

as a fix for this specific issue, I think it'd be nice if Trunk checked for Cargo.toml..

  • Next to the index.html file (like it already does; this would take precedence to avoid any breakage)
  • Next to the Trunk.toml file

..which would fix my case and other similar ones without any additional configuration

@ctron
Copy link
Collaborator

ctron commented Sep 6, 2024

Sounds reasonable. Could you come up with a PR?

@aslilac
Copy link
Author

aslilac commented Sep 6, 2024

if you could point me at what files I should look in I might be able to work on it tonight :)

@ctron
Copy link
Collaborator

ctron commented Sep 10, 2024

Sorry for the late response. This could/should/might be a good introduction:

trunk/src/config/mod.rs

Lines 1 to 60 in 14b972f

//! Trunk config.
//!
//! Trunk follows a layered configuration approach. There are reasonable defaults, the option
//! to load from a configuration file, followed by overrides from the command line (or env-vars).
//!
//! There are four types of structs: Command Line, Serialization, Runtime Options, and Runtime.
//!
//! ## Command Line
//!
//! The command line structs are based on [`clap`] and support both arguments and environment
//! variables. The command line structs can be found in their respective [`crate::cmd`] module.
//!
//! Most fields in those structs are optional, as the idea is to override what can be found in
//! the configuration.
//!
//! Some options in the command line structs are more intended to influence "what" to run, rather
//! than "how" to execute a command. If that's the case, then this option would not be part of
//! the configuration coming from the configuration files.
//!
//! ## Serialization
//!
//! Trunk has a "project model", covering the aspects of what make up a Trunk project. This model
//! is based on structs in the [`crate::config::models`] module and based on [`serde`]. It is
//! loaded in from a configuration file (TOML, YAML, …) or even the `Cargo.toml` file's metadata.
//!
//! However, there is no hierarchical loading process. The first source found will be used.
//!
//! These structs do have a lot of non-optional fields with defaults. These structs should define
//! the defaults to use if they are not provided in the configuration by the user.
//!
//! ## Runtime
//!
//! The runtime configuration structs in [`crate::config::rt`] contain all the information a Trunk
//! command requires to execute, in the form the command requires it.
//!
//! ## Runtime Options
//!
//! Runtime options are a bit of an outlier. In some cases, the runtime configuration requires some
//! information that doesn't come from the user, but from the command execute it. For example,
//! the "build" process needs to know if the reload websocket needs to be injected. Such information
//! is passed in via the Runtime Options.
//!
//! In some cases, it might also be possible that for some commands the command decides, but in
//! other cases the user might influence the choice. This can also go into those options (see
//! error reporting).
//!
//! ## Bringing it all together
//!
//! Here is how it works in general:
//!
//! * Trunk parses the command line arguments (including env-vars) via `clap`
//! * Trunk finds a configuration source (taking the `--config` argument under consideration).
//! * The configuration file is loaded via `serde` and/or `cargo_metadata`.
//! * The configuration model is validated, this might trigger warnings about deprecated fields.
//! * The command line arguments get applied to the configuration, overriding the configuration.
//! * The command creates the runtime options required for the command.
//! * Trunk creates the runtime configuration from the configuration and the runtime options.
//!
//! One aspect of this is that Trunk will always validate the full configuration, but will only
//! create the required runtime configuration for the requested command.

Here is the code for loading the configuration:

pub async fn load(path: Option<PathBuf>) -> Result<(Configuration, PathBuf)> {
match path {
// if we have a file, load it
Some(path) if path.is_file() => {
// Canonicalize the path to the configuration, so that we get a proper parent.
// Otherwise, we might end up with a parent of '', which won't work later on.
let path = path.canonicalize().with_context(|| {
format!(
"unable to canonicalize path to configuration: '{}'",
path.display()
)
})?;
let Some(cwd) = path.parent() else {
bail!("unable to get parent directory of '{}'", path.display());
};
let cwd = cwd.to_path_buf();
Ok((Source::File(path).load().await?, cwd))
}
// if we have a directory, try finding a file and load it
Some(path) if path.is_dir() => Ok((Source::find(&path)?.load().await?, path)),
// if we have something else, we can't deal with it
Some(path) => bail!("{} is neither a file nor a directory", path.display()),
// if we have nothing, try to find a file in the current directory and load it
None => {
let cwd = std::env::current_dir().context("unable to get current directory")?;
Ok((Source::find(&cwd)?.load().await?, cwd))
}
}
}

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

3 participants