mz_deploy/cli/commands/
lock.rs1use std::time::Instant;
20
21use crate::cli::CliError;
22use crate::cli::progress;
23use crate::client::Client;
24use crate::config::Settings;
25use crate::project::ir::object_id::ObjectId;
26
27pub async fn run(settings: &Settings) -> Result<(), CliError> {
29 let directory = &settings.directory;
30
31 let start = Instant::now();
32 let canonical = directory.canonicalize();
33 let shown = canonical.as_deref().unwrap_or(directory);
34 progress::action("Locking", &shown.display().to_string());
35
36 let source_tables = discover_source_tables(settings)?;
39
40 if settings.dependencies.is_empty() && source_tables.is_empty() {
41 progress::finished("lock", start.elapsed());
42 return Ok(());
43 }
44
45 let profile = settings.connection();
47 let client = Client::connect_with_profile(profile.clone())
48 .await
49 .map_err(CliError::Connection)?;
50
51 let declared: Vec<ObjectId> = settings.dependencies.iter().cloned().collect();
55 let (types, missing) = client
56 .types()
57 .query_types_for_objects(&declared, &source_tables)
58 .await
59 .map_err(CliError::Connection)?;
60
61 if !missing.is_empty() {
62 return Err(CliError::DeclaredDependenciesMissing { missing });
63 }
64
65 types.write_types_lock(directory)?;
66
67 progress::finished(
68 &format!("locking {} objects", types.tables.len()),
69 start.elapsed(),
70 );
71
72 Ok(())
73}
74
75fn discover_source_tables(settings: &Settings) -> Result<Vec<ObjectId>, CliError> {
77 let fs = crate::fs::FileSystem::new();
78 let planned = crate::project::plan_sync(
79 &fs,
80 &settings.directory,
81 settings.profile_name(),
82 settings.profile_suffix(),
83 settings.variables(),
84 )?;
85 Ok(planned.get_tables_from_source().collect())
86}