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

Anticipate packages #224

Closed
wants to merge 3 commits into from
Closed

Anticipate packages #224

wants to merge 3 commits into from

Conversation

macovedj
Copy link
Collaborator

@macovedj macovedj commented Jan 29, 2024

Today, one can publish a cargo-component generated component to a registry and then add it as a dependency in another cargo-component project. However, the consuming component's wit will not refer to a foreign package if an interface is imported, but instead will define that interface inline. The example below should help make this clear.

Given a simple component with the following wit:

package component:hello;

interface greeter {
  hello-world: func() -> string;
}
/// An example world for the component to target.
world example {
  import greeter;
  export greeter;
}

That is added via cargo-component add to another component, we can reference it in the project that is added to like so:

use bindings::hello_greeter::hello_world;
use bindings::Guest;

struct Component;

impl Guest for Component {
    /// Say hello!
    fn goodbye_world() -> String {
        hello_world()
    }
}

However, when printing out the wit of the compiled component, the greeter interface appears as follows:

package root:component;

world root {
  import hello-greeter: interface {
    hello-world: func() -> string;
  }
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:io/[email protected];
  import wasi:io/[email protected];
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:clocks/[email protected];
  import wasi:filesystem/[email protected];
  import wasi:filesystem/[email protected];

  export goodbye-world: func() -> string;
}

We can see that it is not surfaced to the wit that this interface is defined by the dependency. The use case I specifically am motivated by is in is docs gen so that a UI can link to the package where the type is actually defined.

These changes will produce a binary with the following wit

world root {
  import wasi:hello/greeter;
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:io/[email protected];
  import wasi:io/[email protected];
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:cli/[email protected];
  import wasi:clocks/[email protected];
  import wasi:filesystem/[email protected];
  import wasi:filesystem/[email protected];

  export goodbye-world: func() -> string;
}

For the motivating use case, this would surface sufficient information for robust docgen.

Note that as it stands, in order for these changes to function properly would also require that the wit-bindgen branch referenced gets merged, which has the side effect of prepending the namespace to the module exposed in rust bindings, and the rust import would then look like so

use bindings::<namespace>_hello_greeter::hello_world;

@macovedj
Copy link
Collaborator Author

I commented out a test that I'm still trying to get to work that would verify we get the expected results when publishing components to a registry. But I have tested against real components and it works.

I also brought over the test changes from here, and if these changes end up feeling like the correct approach, I can just go ahead and close the other PR.

Can open up the wit-bindgen PR also once it's confirmed that this approach is fine and/or get good tests pushed.

@macovedj macovedj closed this Mar 7, 2024
@macovedj macovedj deleted the anticipate-packages branch March 12, 2024 16:09
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

Successfully merging this pull request may close these issues.

1 participant