Skip to content

Commit 6a61b5b

Browse files
J Robert Rayjrray
J Robert Ray
authored andcommitted
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 3b4609b commit 6a61b5b

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 mut workspace = self.workspace.load_or_default()?;
398-
let configured = workspace
404+
if workspace.is_none() {
405+
workspace = Some(self.workspace.load_or_default()?);
406+
}
407+
let Some(ws) = workspace.as_mut() else {
408+
unreachable!();
409+
};
410+
411+
let configured = ws
399412
.find_or_load_package_template(package)
400413
.wrap_err("did not find recipe template")?;
401414
let rendered_data = configured.template.render(options)?;
@@ -450,18 +463,25 @@ impl Requests {
450463
let override_options = options.get_options()?;
451464
let mut templating_options = override_options.clone();
452465
let mut extra_options = OptionMap::default();
453-
let mut workspace = self.workspace.load_or_default()?;
466+
let mut workspace = None;
454467

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

459472
// Is it a filepath to a package requests yaml file?
460473
if r.ends_with(".spk.yaml") {
474+
if workspace.is_none() {
475+
workspace = Some(self.workspace.load_or_default()?);
476+
}
477+
let Some(ws) = workspace.as_mut() else {
478+
unreachable!();
479+
};
480+
461481
let (spec, filename) = find_package_recipe_from_workspace_or_repo(
462482
Some(&r),
463483
&templating_options,
464-
&mut workspace,
484+
ws,
465485
repos,
466486
)
467487
.await
@@ -510,16 +530,23 @@ impl Requests {
510530
&self,
511531
request: &str,
512532
options: &OptionMap,
513-
workspace: &mut spk_workspace::Workspace,
533+
workspace: &mut Option<spk_workspace::Workspace>,
514534
repos: &[Arc<storage::RepositoryHandle>],
515535
) -> Result<Vec<Request>> {
516536
// Parses a command line request into one or more requests.
517537
// 'file@stage' strings can expand into more than one request.
518538
let mut out = Vec::<Request>::new();
519539

520540
if request.contains('@') {
541+
if workspace.is_none() {
542+
*workspace = Some(self.workspace.load_or_default()?);
543+
}
544+
let Some(ws) = workspace.as_mut() else {
545+
unreachable!();
546+
};
547+
521548
let (recipe, _, stage, build_variant) =
522-
parse_stage_specifier(request, options, workspace, repos)
549+
parse_stage_specifier(request, options, ws, repos)
523550
.await
524551
.wrap_err_with(|| {
525552
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)