@@ -49,9 +49,52 @@ pub struct ApplicationContext {
4949 component_generated_base_wit_deps : HashMap < AppComponentName , WitDepsResolver > ,
5050 selected_component_names : BTreeSet < AppComponentName > ,
5151 remote_components : RemoteComponents ,
52+ pub tools_with_ensured_common_deps : ToolsWithEnsuredCommonDeps ,
53+ }
54+
55+ pub struct ToolsWithEnsuredCommonDeps {
5256 tools_with_ensured_common_deps : tokio:: sync:: RwLock < HashSet < String > > ,
5357}
5458
59+ impl Default for ToolsWithEnsuredCommonDeps {
60+ fn default ( ) -> Self {
61+ Self :: new ( )
62+ }
63+ }
64+
65+ impl ToolsWithEnsuredCommonDeps {
66+ pub fn new ( ) -> ToolsWithEnsuredCommonDeps {
67+ ToolsWithEnsuredCommonDeps {
68+ tools_with_ensured_common_deps : tokio:: sync:: RwLock :: new ( HashSet :: new ( ) ) ,
69+ }
70+ }
71+
72+ pub async fn ensure_common_deps_for_tool_once (
73+ & self ,
74+ tool : & str ,
75+ ensure : impl AsyncFnOnce ( ) -> anyhow:: Result < ( ) > ,
76+ ) -> anyhow:: Result < ( ) > {
77+ if self
78+ . tools_with_ensured_common_deps
79+ . read ( )
80+ . await
81+ . contains ( tool)
82+ {
83+ return Ok ( ( ) ) ;
84+ }
85+
86+ let mut lock = self . tools_with_ensured_common_deps . write ( ) . await ;
87+
88+ let result = ensure ( ) . await ;
89+
90+ if result. is_ok ( ) {
91+ lock. insert ( tool. to_string ( ) ) ;
92+ }
93+
94+ result
95+ }
96+ }
97+
5598pub struct ApplicationPreloadResult {
5699 pub source_mode : ApplicationSourceMode ,
57100 pub loaded_with_warnings : bool ,
@@ -81,7 +124,7 @@ impl ApplicationContext {
81124 }
82125 }
83126
84- pub fn new (
127+ pub async fn new (
85128 available_profiles : & BTreeSet < ProfileName > ,
86129 source_mode : ApplicationSourceMode ,
87130 config : ApplicationConfig ,
@@ -93,29 +136,7 @@ impl ApplicationContext {
93136
94137 let ctx = to_anyhow (
95138 "Failed to load application manifest, see problems above" ,
96- app_and_calling_working_dir. and_then ( |( application, calling_working_dir) | {
97- ResolvedWitApplication :: new ( & application, config. build_profile . as_ref ( ) ) . map ( {
98- let temp_dir = application. temp_dir ( ) ;
99- let offline = config. offline ;
100- move |wit| ApplicationContext {
101- loaded_with_warnings : false ,
102- config,
103- application,
104- wit,
105- calling_working_dir,
106- component_stub_defs : HashMap :: new ( ) ,
107- common_wit_deps : OnceLock :: new ( ) ,
108- component_generated_base_wit_deps : HashMap :: new ( ) ,
109- selected_component_names : BTreeSet :: new ( ) ,
110- remote_components : RemoteComponents :: new (
111- file_download_client,
112- temp_dir,
113- offline,
114- ) ,
115- tools_with_ensured_common_deps : tokio:: sync:: RwLock :: new ( HashSet :: new ( ) ) ,
116- }
117- } )
118- } ) ,
139+ Self :: create_context ( app_and_calling_working_dir, config, file_download_client) . await ,
119140 Some ( |mut app_ctx| {
120141 app_ctx. loaded_with_warnings = true ;
121142 app_ctx
@@ -131,6 +152,55 @@ impl ApplicationContext {
131152 Ok ( Some ( ctx) )
132153 }
133154
155+ async fn create_context (
156+ app_and_calling_working_dir : ValidatedResult < ( Application , PathBuf ) > ,
157+ config : ApplicationConfig ,
158+ file_download_client : reqwest:: Client ,
159+ ) -> ValidatedResult < ApplicationContext > {
160+ let mut result = ValidatedResult :: Ok ( ( ) ) ;
161+
162+ let ( r, v) = result. merge_and_get ( app_and_calling_working_dir) ;
163+ result = r;
164+ if let Some ( ( application, calling_working_dir) ) = v {
165+ let tools_with_ensured_common_deps = ToolsWithEnsuredCommonDeps :: new ( ) ;
166+ let wit_result = ResolvedWitApplication :: new (
167+ & application,
168+ config. build_profile . as_ref ( ) ,
169+ & tools_with_ensured_common_deps,
170+ )
171+ . await ;
172+
173+ let ( r, v) = result. merge_and_get ( wit_result) ;
174+ result = r;
175+ if let Some ( wit) = v {
176+ let temp_dir = application. temp_dir ( ) ;
177+ let offline = config. offline ;
178+ let ctx = ApplicationContext {
179+ loaded_with_warnings : false ,
180+ config,
181+ application,
182+ wit,
183+ calling_working_dir,
184+ component_stub_defs : HashMap :: new ( ) ,
185+ common_wit_deps : OnceLock :: new ( ) ,
186+ component_generated_base_wit_deps : HashMap :: new ( ) ,
187+ selected_component_names : BTreeSet :: new ( ) ,
188+ remote_components : RemoteComponents :: new (
189+ file_download_client,
190+ temp_dir,
191+ offline,
192+ ) ,
193+ tools_with_ensured_common_deps,
194+ } ;
195+ ValidatedResult :: Ok ( ctx)
196+ } else {
197+ result. expect_error ( )
198+ }
199+ } else {
200+ result. expect_error ( )
201+ }
202+ }
203+
134204 fn validate_build_profile ( & self ) -> anyhow:: Result < ( ) > {
135205 let Some ( profile) = & self . config . build_profile else {
136206 return Ok ( ( ) ) ;
@@ -160,10 +230,16 @@ impl ApplicationContext {
160230 self . config . build_profile . as_ref ( )
161231 }
162232
163- pub fn update_wit_context ( & mut self ) -> anyhow:: Result < ( ) > {
233+ pub async fn update_wit_context ( & mut self ) -> anyhow:: Result < ( ) > {
164234 to_anyhow (
165235 "Failed to update application wit context, see problems above" ,
166- ResolvedWitApplication :: new ( & self . application , self . build_profile ( ) ) . map ( |wit| {
236+ ResolvedWitApplication :: new (
237+ & self . application ,
238+ self . build_profile ( ) ,
239+ & self . tools_with_ensured_common_deps ,
240+ )
241+ . await
242+ . map ( |wit| {
167243 self . wit = wit;
168244 } ) ,
169245 None ,
@@ -639,31 +715,6 @@ impl ApplicationContext {
639715
640716 Ok ( ( ) )
641717 }
642-
643- pub async fn ensure_common_deps_for_tool_once (
644- & self ,
645- tool : & str ,
646- ensure : impl AsyncFnOnce ( ) -> anyhow:: Result < ( ) > ,
647- ) -> anyhow:: Result < ( ) > {
648- if self
649- . tools_with_ensured_common_deps
650- . read ( )
651- . await
652- . contains ( tool)
653- {
654- return Ok ( ( ) ) ;
655- }
656-
657- let mut lock = self . tools_with_ensured_common_deps . write ( ) . await ;
658-
659- let result = ensure ( ) . await ;
660-
661- if result. is_ok ( ) {
662- lock. insert ( tool. to_string ( ) ) ;
663- }
664-
665- result
666- }
667718}
668719
669720fn load_app (
0 commit comments