@@ -18,21 +18,27 @@ use spin_manifest::{
1818 Application , ApplicationInformation , ApplicationOrigin , CoreComponent , ModuleSource ,
1919 SpinVersion , WasmConfig ,
2020} ;
21- use std:: { path:: Path , sync:: Arc } ;
21+ use std:: { path:: Path , str :: FromStr , sync:: Arc } ;
2222use tokio:: { fs:: File , io:: AsyncReadExt } ;
2323
24+ use crate :: bindle:: BindleConnectionInfo ;
25+
2426/// Given the path to a spin.toml manifest file, prepare its assets locally and
2527/// get a prepared application configuration consumable by a Spin execution context.
2628/// If a directory is provided, use it as the base directory to expand the assets,
2729/// otherwise create a new temporary directory.
28- pub async fn from_file ( app : impl AsRef < Path > , base_dst : impl AsRef < Path > ) -> Result < Application > {
30+ pub async fn from_file (
31+ app : impl AsRef < Path > ,
32+ base_dst : impl AsRef < Path > ,
33+ bindle_connection : & Option < BindleConnectionInfo > ,
34+ ) -> Result < Application > {
2935 let app = app
3036 . as_ref ( )
3137 . absolutize ( )
3238 . context ( "Failed to resolve absolute path to manifest file" ) ?;
3339 let manifest = raw_manifest_from_file ( & app) . await ?;
3440
35- prepare_any_version ( manifest, app, base_dst) . await
41+ prepare_any_version ( manifest, app, base_dst, bindle_connection ) . await
3642}
3743
3844/// Reads the spin.toml file as a raw manifest.
@@ -54,9 +60,10 @@ async fn prepare_any_version(
5460 raw : RawAppManifestAnyVersion ,
5561 src : impl AsRef < Path > ,
5662 base_dst : impl AsRef < Path > ,
63+ bindle_connection : & Option < BindleConnectionInfo > ,
5764) -> Result < Application > {
5865 match raw {
59- RawAppManifestAnyVersion :: V1 ( raw) => prepare ( raw, src, base_dst) . await ,
66+ RawAppManifestAnyVersion :: V1 ( raw) => prepare ( raw, src, base_dst, bindle_connection ) . await ,
6067 }
6168}
6269
@@ -79,6 +86,7 @@ async fn prepare(
7986 mut raw : RawAppManifest ,
8087 src : impl AsRef < Path > ,
8188 base_dst : impl AsRef < Path > ,
89+ bindle_connection : & Option < BindleConnectionInfo > ,
8290) -> Result < Application > {
8391 let info = info ( raw. info , & src) ;
8492
@@ -104,7 +112,7 @@ async fn prepare(
104112 let components = future:: join_all (
105113 raw. components
106114 . into_iter ( )
107- . map ( |c| async { core ( c, & src, & base_dst) . await } )
115+ . map ( |c| async { core ( c, & src, & base_dst, bindle_connection ) . await } )
108116 . collect :: < Vec < _ > > ( ) ,
109117 )
110118 . await
@@ -125,7 +133,10 @@ async fn core(
125133 raw : RawComponentManifest ,
126134 src : impl AsRef < Path > ,
127135 base_dst : impl AsRef < Path > ,
136+ bindle_connection : & Option < BindleConnectionInfo > ,
128137) -> Result < CoreComponent > {
138+ let id = raw. id ;
139+
129140 let src = src
130141 . as_ref ( )
131142 . parent ( )
@@ -139,12 +150,33 @@ async fn core(
139150
140151 ModuleSource :: FileReference ( p)
141152 }
142- config:: RawModuleSource :: Bindle ( _) => {
143- todo ! ( "Bindle module sources are not yet supported in file-based app config" )
153+ config:: RawModuleSource :: Bindle ( b) => {
154+ let bindle_id = bindle:: Id :: from_str ( & b. reference ) . with_context ( || {
155+ format ! ( "Invalid bindle ID {} in component {}" , b. reference, id)
156+ } ) ?;
157+ let parcel_sha = & b. parcel ;
158+ let client = match bindle_connection {
159+ None => anyhow:: bail!(
160+ "Component {} requires a Bindle connection but none was specified" ,
161+ id
162+ ) ,
163+ Some ( c) => c. client ( ) ?,
164+ } ;
165+ let bindle_reader = crate :: bindle:: BindleReader :: remote ( & client, & bindle_id) ;
166+ let bytes = bindle_reader
167+ . get_parcel ( parcel_sha)
168+ . await
169+ . with_context ( || {
170+ format ! (
171+ "Failed to download parcel {}@{} for component {}" ,
172+ bindle_id, parcel_sha, id
173+ )
174+ } ) ?;
175+ let name = format ! ( "{}@{}" , bindle_id, parcel_sha) ;
176+ ModuleSource :: Buffer ( bytes, name)
144177 }
145178 } ;
146179
147- let id = raw. id ;
148180 let description = raw. description ;
149181 let mounts = match raw. wasm . files {
150182 Some ( f) => assets:: prepare_component ( & f, src, & base_dst, & id) . await ?,
0 commit comments