Skip to content

Commit 5168700

Browse files
authored
feat(config): Support frozen lockfile config option in deno.json (#25100)
Closes #24544
1 parent f1c58ec commit 5168700

File tree

6 files changed

+73
-18
lines changed

6 files changed

+73
-18
lines changed

cli/args/flags.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ pub struct Flags {
589589
pub argv: Vec<String>,
590590
pub subcommand: DenoSubcommand,
591591

592-
pub frozen_lockfile: bool,
592+
pub frozen_lockfile: Option<bool>,
593593
pub ca_stores: Option<Vec<String>>,
594594
pub ca_data: Option<CaData>,
595595
pub cache_blocklist: Vec<String>,
@@ -5231,7 +5231,7 @@ fn cached_only_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) {
52315231

52325232
fn frozen_lockfile_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) {
52335233
if let Some(&v) = matches.get_one::<bool>("frozen") {
5234-
flags.frozen_lockfile = v;
5234+
flags.frozen_lockfile = Some(v);
52355235
}
52365236
}
52375237

@@ -10923,10 +10923,10 @@ mod tests {
1092310923
#[test]
1092410924
fn run_with_frozen_lockfile() {
1092510925
let cases = [
10926-
(Some("--frozen"), true),
10927-
(Some("--frozen=true"), true),
10928-
(Some("--frozen=false"), false),
10929-
(None, false),
10926+
(Some("--frozen"), Some(true)),
10927+
(Some("--frozen=true"), Some(true)),
10928+
(Some("--frozen=false"), Some(false)),
10929+
(None, None),
1093010930
];
1093110931
for (flag, frozen) in cases {
1093210932
let mut args = svec!["deno", "run"];

cli/args/lockfile.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,22 +147,28 @@ impl CliLockfile {
147147
},
148148
};
149149

150+
let root_folder = workspace.root_folder_configs();
151+
// CLI flag takes precedence over the config
152+
let frozen = flags.frozen_lockfile.unwrap_or_else(|| {
153+
root_folder
154+
.deno_json
155+
.as_ref()
156+
.and_then(|c| c.to_lock_config().ok().flatten().map(|c| c.frozen()))
157+
.unwrap_or(false)
158+
});
159+
150160
let lockfile = if flags.lock_write {
151161
log::warn!(
152162
"{} \"--lock-write\" flag is deprecated and will be removed in Deno 2.",
153163
crate::colors::yellow("Warning")
154164
);
155-
CliLockfile::new(
156-
Lockfile::new_empty(filename, true),
157-
flags.frozen_lockfile,
158-
)
165+
CliLockfile::new(Lockfile::new_empty(filename, true), frozen)
159166
} else {
160-
Self::read_from_path(filename, flags.frozen_lockfile)?
167+
Self::read_from_path(filename, frozen)?
161168
};
162169

163170
// initialize the lockfile with the workspace's configuration
164171
let root_url = workspace.root_dir();
165-
let root_folder = workspace.root_folder_configs();
166172
let config = deno_lockfile::WorkspaceConfig {
167173
root: WorkspaceMemberConfig {
168174
package_json_deps: pkg_json_deps(root_folder.pkg_json.as_deref()),

cli/lsp/config.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,7 +1846,12 @@ fn resolve_lockfile_from_workspace(
18461846
return None;
18471847
}
18481848
};
1849-
resolve_lockfile_from_path(lockfile_path)
1849+
let frozen = workspace
1850+
.workspace
1851+
.root_deno_json()
1852+
.and_then(|c| c.to_lock_config().ok().flatten().map(|c| c.frozen()))
1853+
.unwrap_or(false);
1854+
resolve_lockfile_from_path(lockfile_path, frozen)
18501855
}
18511856

18521857
fn resolve_node_modules_dir(
@@ -1875,8 +1880,11 @@ fn resolve_node_modules_dir(
18751880
canonicalize_path_maybe_not_exists(&node_modules_dir).ok()
18761881
}
18771882

1878-
fn resolve_lockfile_from_path(lockfile_path: PathBuf) -> Option<CliLockfile> {
1879-
match CliLockfile::read_from_path(lockfile_path, false) {
1883+
fn resolve_lockfile_from_path(
1884+
lockfile_path: PathBuf,
1885+
frozen: bool,
1886+
) -> Option<CliLockfile> {
1887+
match CliLockfile::read_from_path(lockfile_path, frozen) {
18801888
Ok(value) => {
18811889
if value.filename.exists() {
18821890
if let Ok(specifier) = ModuleSpecifier::from_file_path(&value.filename)

cli/schemas/config-file.v1.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,20 @@
552552
},
553553
"lock": {
554554
"description": "Whether to use a lock file or the path to use for the lock file. Can be overridden by CLI arguments.",
555-
"type": ["string", "boolean"],
556-
"default": true
555+
"type": ["string", "boolean", "object"],
556+
"default": true,
557+
"properties": {
558+
"path": {
559+
"type": "string",
560+
"description": "The path to use for the lock file.",
561+
"default": "deno.lock"
562+
},
563+
"frozen": {
564+
"type": "boolean",
565+
"description": "Whether to exit with an error if lock file is out of date.",
566+
"default": false
567+
}
568+
}
557569
},
558570
"unstable": {
559571
"type": "array",

cli/tools/installer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ async fn resolve_shim_data(
472472
executable_args.push("--cached-only".to_string());
473473
}
474474

475-
if flags.frozen_lockfile {
475+
if flags.frozen_lockfile.unwrap_or(false) {
476476
executable_args.push("--frozen".to_string());
477477
}
478478

tests/specs/lockfile/frozen_lockfile/__test__.jsonc

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,35 @@
123123
}
124124
]
125125
},
126+
127+
"lockfile_config": {
128+
"steps": [
129+
{
130+
"args": [
131+
"eval",
132+
"Deno.writeTextFileSync('deno.json', JSON.stringify({ lock: { frozen: true }, ...JSON.parse(Deno.readTextFileSync('deno.json')) }))"
133+
],
134+
"output": ""
135+
},
136+
{
137+
"args": "cache --frozen=false add.ts",
138+
"output": "[WILDCARD]"
139+
},
140+
{
141+
// sub.ts imports from an npm package
142+
// that's not in the lockfile
143+
"args": "run sub.ts",
144+
"output": "frozen_new_dep_run.out",
145+
"exitCode": 1
146+
},
147+
{
148+
"args": "cache sub.ts",
149+
"output": "frozen_new_dep_cache.out",
150+
"exitCode": 1
151+
}
152+
]
153+
},
154+
126155
"non_analyzable_dynamic_npm": {
127156
"steps": [
128157
{

0 commit comments

Comments
 (0)