diff --git a/src/cli.rs b/src/cli.rs index 2f05778..bbcc96a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -45,6 +45,9 @@ pub enum SyncTarget { Studio, /// Write assets to the .asphalt-debug folder. Debug, + /// Generate code from existing lockfile entries only. + /// Fails if any asset is not already in the lockfile. + Existing, } impl SyncTarget { diff --git a/src/sync/collect.rs b/src/sync/collect.rs index fdb8c9f..efcd5fa 100644 --- a/src/sync/collect.rs +++ b/src/sync/collect.rs @@ -161,6 +161,7 @@ impl Progress { SyncTarget::Cloud { dry_run: true } => "checked", SyncTarget::Cloud { dry_run: false } => "uploaded", SyncTarget::Studio | SyncTarget::Debug => "written", + SyncTarget::Existing => "resolved", }; parts.push(format!("{} {}", self.new, target_msg)); } diff --git a/src/sync/mod.rs b/src/sync/mod.rs index ef8af27..6497e72 100644 --- a/src/sync/mod.rs +++ b/src/sync/mod.rs @@ -103,6 +103,7 @@ pub async fn sync(args: SyncArgs, mp: MultiProgress) -> anyhow::Result<()> { SyncTarget::Studio => { Some(TargetBackend::Studio(backend::Studio::new(params).await?)) } + SyncTarget::Existing => None, } }, }; diff --git a/src/sync/walk.rs b/src/sync/walk.rs index c16cbc9..7c61bcd 100644 --- a/src/sync/walk.rs +++ b/src/sync/walk.rs @@ -6,7 +6,7 @@ use crate::{ lockfile::Lockfile, sync::TargetBackend, }; -use anyhow::Context; +use anyhow::{Context, bail}; use fs_err::tokio as fs; use log::{debug, warn}; use relative_path::PathExt; @@ -124,6 +124,13 @@ async fn process_entry( .existing_lockfile .get(&state.input_name, &asset.hash); + if matches!(state.params.target, SyncTarget::Existing) && lockfile_entry.is_none() { + bail!( + "Asset '{}' is not in the lockfile. Upload it first with 'asphalt sync'.", + rel_path + ); + } + { let mut seen_hashes = state.seen_hashes.lock().await;