Skip to content

Commit 3e510b7

Browse files
author
J Robert Ray
committed
Lazily load the default workspace as needed
Not all spk [env] command lines contain a request that requires the use of a workspace, but previously the workspace was loaded unconditionally, meaning that any/all *.spk.yaml files in the working directory would be read in and possibly warned about if they do not contain the "api" entry. Avoid this unnecessary file IO overhead when workspaces are not needed. Also reuse the already loaded workspace instead of creating another new one per file in `parse_idents`. Finally, if loading a workspace and warning about possibly more than one file if missing the "api" entry, include the filename of the offending file in the warning message. Signed-off-by: J Robert Ray <[email protected]>
1 parent 4abc83e commit 3e510b7

File tree

2 files changed

+36
-8
lines changed

2 files changed

+36
-8
lines changed

crates/spk-cli/common/src/flags.rs

+35-8
Original file line numberDiff line numberDiff line change
@@ -372,11 +372,18 @@ impl Requests {
372372
repos: &[Arc<storage::RepositoryHandle>],
373373
) -> Result<Vec<AnyIdent>> {
374374
let mut idents = Vec::new();
375-
let mut workspace = self.workspace.load_or_default()?;
375+
let mut workspace = None;
376376
for package in packages {
377377
if package.contains('@') {
378+
if workspace.is_none() {
379+
workspace = Some(self.workspace.load_or_default()?);
380+
}
381+
let Some(ws) = workspace.as_mut() else {
382+
unreachable!();
383+
};
384+
378385
let (recipe, _, stage, _) =
379-
parse_stage_specifier(package, options, &mut workspace, repos).await?;
386+
parse_stage_specifier(package, options, ws, repos).await?;
380387

381388
match stage {
382389
TestStage::Sources => {
@@ -394,8 +401,14 @@ impl Requests {
394401

395402
let path = std::path::Path::new(package);
396403
if path.is_file() {
397-
let workspace = self.workspace.load_or_default()?;
398-
let configured = workspace.find_package_template(package).must_be_found();
404+
if workspace.is_none() {
405+
workspace = Some(self.workspace.load_or_default()?);
406+
}
407+
let Some(ws) = workspace.as_ref() else {
408+
unreachable!();
409+
};
410+
411+
let configured = ws.find_package_template(package).must_be_found();
399412
let rendered_data = configured.template.render(options)?;
400413
let recipe = rendered_data.into_recipe().wrap_err_with(|| {
401414
format!(
@@ -448,18 +461,25 @@ impl Requests {
448461
let override_options = options.get_options()?;
449462
let mut templating_options = override_options.clone();
450463
let mut extra_options = OptionMap::default();
451-
let mut workspace = self.workspace.load_or_default()?;
464+
let mut workspace = None;
452465

453466
// From the positional REQUESTS arg
454467
for r in requests.into_iter() {
455468
let r: &str = r.as_ref();
456469

457470
// Is it a filepath to a package requests yaml file?
458471
if r.ends_with(".spk.yaml") {
472+
if workspace.is_none() {
473+
workspace = Some(self.workspace.load_or_default()?);
474+
}
475+
let Some(ws) = workspace.as_mut() else {
476+
unreachable!();
477+
};
478+
459479
let (spec, filename) = find_package_recipe_from_workspace_or_repo(
460480
Some(&r),
461481
&templating_options,
462-
&mut workspace,
482+
ws,
463483
repos,
464484
)
465485
.await
@@ -508,16 +528,23 @@ impl Requests {
508528
&self,
509529
request: &str,
510530
options: &OptionMap,
511-
workspace: &mut spk_workspace::Workspace,
531+
workspace: &mut Option<spk_workspace::Workspace>,
512532
repos: &[Arc<storage::RepositoryHandle>],
513533
) -> Result<Vec<Request>> {
514534
// Parses a command line request into one or more requests.
515535
// 'file@stage' strings can expand into more than one request.
516536
let mut out = Vec::<Request>::new();
517537

518538
if request.contains('@') {
539+
if workspace.is_none() {
540+
*workspace = Some(self.workspace.load_or_default()?);
541+
}
542+
let Some(ws) = workspace.as_mut() else {
543+
unreachable!();
544+
};
545+
519546
let (recipe, _, stage, build_variant) =
520-
parse_stage_specifier(request, options, workspace, repos)
547+
parse_stage_specifier(request, options, ws, repos)
521548
.await
522549
.wrap_err_with(|| {
523550
format!("parsing {request} as a filename with stage specifier")

crates/spk-schema/src/spec.rs

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ impl TemplateExt for SpecTemplate {
220220

221221
if api.is_none() {
222222
tracing::warn!(
223+
spec_file = %file_path.to_string_lossy(),
223224
"Spec file is missing the 'api' field, this may be an error in the future"
224225
);
225226
tracing::warn!(

0 commit comments

Comments
 (0)