-
Notifications
You must be signed in to change notification settings - Fork 290
Dependencies by component ID reference #3290
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
base: main
Are you sure you want to change the base?
Dependencies by component ID reference #3290
Conversation
This is great, thank you so much! I can't really comment on the implementation all that much, so instead I'll comment on the color of this bikeshed's cladding and suggest changing Okay, I have a slightly more substantial question, though it still pertains to the paint more than the construction, and is only kinda-sorta related to this particular change: Would it at all be possible to support the following syntax, by any chance? [component.the-main-course.dependencies."useless:feature@0.0.1"]
component_id = "yet-another-example-dep" The reason I ask is that I would quite like to be able to add more "stuff" to the individual dependencies' tables, which is impossible for all reasonable intents and purposes if all I can work with are inline tables. |
Not just possible; those are equivalent in TOML. |
if surprises.is_empty() { | ||
Ok(()) | ||
} else { | ||
anyhow::bail!("Dependencies may not have their own resources or permissions. Component {depended_on_id} cannot be used as a dependency of {depender_id} because it specifies: {}", surprises.join(", ")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
anyhow::bail!("Dependencies may not have their own resources or permissions. Component {depended_on_id} cannot be used as a dependency of {depender_id} because it specifies: {}", surprises.join(", ")); | |
anyhow::bail!("🎉 Dependencies may not have their own resources or permissions. Component {depended_on_id} cannot be used as a dependency of {depender_id} because it specifies: {} 🥳", surprises.join(", ")); |
Just confirming: is the goal here just to enable nicer |
crates/manifest/src/normalize.rs
Outdated
if !component.ai_models.is_empty() { | ||
surprises.push("ai_models"); | ||
} | ||
if !component.allowed_outbound_hosts.is_empty() { | ||
surprises.push("allowed_outbound_hosts"); | ||
} | ||
if !component.dependencies.inner.is_empty() { | ||
surprises.push("dependencies"); | ||
} | ||
if !component.environment.is_empty() { | ||
surprises.push("environment"); | ||
} | ||
if !component.files.is_empty() { | ||
surprises.push("files"); | ||
} | ||
if !component.key_value_stores.is_empty() { | ||
surprises.push("key_value_stores"); | ||
} | ||
if !component.sqlite_databases.is_empty() { | ||
surprises.push("sqlite_databases"); | ||
} | ||
if !component.variables.is_empty() { | ||
surprises.push("variables"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This kind of validation always makes me a little nervous where a future field addition could easily slip through the net here.
Two alternative suggestions:
- Destructure all the fields of
component
and let the compiler complain if you miss one:let Component { ai_models, // ... variables, } = component;
- (Ab)use
toml::Value
; something vaguely like:#[derive(Deserialize)] struct DependencyComponent { source: serde::de::IgnoredAny, #[serde(flatten)] surprises: Map<String, serde::de::IgnoredAny>, } let value = toml::Value::try_from(component).unwrap(); let dep_component: DependencyComponent = value.try_into()?; let surprises = dep_component.surprises.keys();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call - I did the first and it showed me I'd forgotten allowed_http_hosts
!
Kinda, in this version? Where this gets more interesting is once you combine it with profiles. I would expect (and, @itowlson, we should probably make sure that whichever of these PRs lands first makes it so) a dependency defined in this way to automatically use the right profile for the dependency, so you don't have to list the entire |
I could swear I had this failing for me the other day, but I must've done something wrong. (For posterity: I was, indeed, wrong, and the error I encountered was unrelated.) |
Another option, with its own warts: [component.the-main-course.dependencies."useless:feature@0.0.1"]
path = "dep/target/wasm32-wasip2/release/dep.wasm"
[component.the-main-course.dependencies."useless:feature@0.0.1".build]
command = "cargo build"
workdir = "dep" |
So effectively inline definition of dependencies? I don't think I'm necessarily opposed to this as an option, but it's certainly not a replacement for anything: we'll always want to have the ability to use a component as a dependency for multiple other components. |
As well as Till's note, for me it is intention-revealing. That is, although we can achieve the same thing by duplicating a file path, that creates a submarine dependency - the reader has to spot "oh that file is the same as this file" - whereas naming the depended-on component makes it obvious "ah that is part of this application and I can go here to look at it." |
4576c80
to
b1a961f
Compare
c27efc2
to
dc021cc
Compare
Signed-off-by: itowlson <[email protected]>
dc021cc
to
3c94860
Compare
Draft for discussion of the approach.
The idea here is to allow dependencies of the form:
where
yet-another-example-dep
is another component in the manifest (typically, one not attached to a trigger).I originally took a sane and reasonable approach, but had to abandon it because I had problems passing enough component info through to the composer for it to resolve the ID. The current approach uses or misuses the normalisation step instead, to turn the ID reference into a "proper" dependency source (e.g. local file, package reference, etc.) based on the
component.source
of the dependency.This works (by which I mean it has worked for me at least once). However:
ComponentDependency
to have a variant that's used in deserialisation but which must never be seen by the composer (because the composer can't process it, it has to be normalised away first).So I'm putting this up for people to point out the OBVIOUSLY SUPERIOR IN EVERY RESPECT way of doing this that I've completely overlooked.
(or of course to tell me it's a terrible idea and we shouldn't do it anyway)
Thanks!
cc @fibonacci1729 @tschneidereit