@@ -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,6 +133,7 @@ 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 > {
129138 let src = src
130139 . as_ref ( )
@@ -139,8 +148,20 @@ async fn core(
139148
140149 ModuleSource :: FileReference ( p)
141150 }
142- config:: RawModuleSource :: Bindle ( _) => {
143- todo ! ( "Bindle module sources are not yet supported in file-based app config" )
151+ config:: RawModuleSource :: Bindle ( b) => {
152+ let bindle_id = bindle:: Id :: from_str ( & b. reference ) ?;
153+ let parcel_sha = & b. parcel ;
154+ let client = match bindle_connection {
155+ None => anyhow:: bail!(
156+ "Component {} requires a Bindle connection but none was specified" ,
157+ raw. id
158+ ) ,
159+ Some ( c) => c. client ( ) ?,
160+ } ;
161+ let bindle_reader = crate :: bindle:: BindleReader :: remote ( & client, & bindle_id) ;
162+ let bytes = bindle_reader. get_parcel ( parcel_sha) . await ?;
163+ let name = format ! ( "{}@{}" , bindle_id, parcel_sha) ;
164+ ModuleSource :: Buffer ( bytes, name)
144165 }
145166 } ;
146167
0 commit comments