summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Whitaker <17734409+nathanwhit@users.noreply.github.com>2024-08-20 07:55:47 -0700
committerGitHub <noreply@github.com>2024-08-20 14:55:47 +0000
commit5168700be669179382462214724115a3013cb58e (patch)
treef30a134722a079b4cc7b2c25a799fe11bf40c6cd
parentf1c58ec041a05276d9f33562a5843c0bb7fb95b3 (diff)
feat(config): Support frozen lockfile config option in deno.json (#25100)
Closes #24544
-rw-r--r--cli/args/flags.rs12
-rw-r--r--cli/args/lockfile.rs18
-rw-r--r--cli/lsp/config.rs14
-rw-r--r--cli/schemas/config-file.v1.json16
-rw-r--r--cli/tools/installer.rs2
-rw-r--r--tests/specs/lockfile/frozen_lockfile/__test__.jsonc29
6 files changed, 73 insertions, 18 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs
index 0ceac4563..a273d8b37 100644
--- a/cli/args/flags.rs
+++ b/cli/args/flags.rs
@@ -589,7 +589,7 @@ pub struct Flags {
pub argv: Vec<String>,
pub subcommand: DenoSubcommand,
- pub frozen_lockfile: bool,
+ pub frozen_lockfile: Option<bool>,
pub ca_stores: Option<Vec<String>>,
pub ca_data: Option<CaData>,
pub cache_blocklist: Vec<String>,
@@ -5231,7 +5231,7 @@ fn cached_only_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) {
fn frozen_lockfile_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) {
if let Some(&v) = matches.get_one::<bool>("frozen") {
- flags.frozen_lockfile = v;
+ flags.frozen_lockfile = Some(v);
}
}
@@ -10923,10 +10923,10 @@ mod tests {
#[test]
fn run_with_frozen_lockfile() {
let cases = [
- (Some("--frozen"), true),
- (Some("--frozen=true"), true),
- (Some("--frozen=false"), false),
- (None, false),
+ (Some("--frozen"), Some(true)),
+ (Some("--frozen=true"), Some(true)),
+ (Some("--frozen=false"), Some(false)),
+ (None, None),
];
for (flag, frozen) in cases {
let mut args = svec!["deno", "run"];
diff --git a/cli/args/lockfile.rs b/cli/args/lockfile.rs
index 953278e7d..00d1f929d 100644
--- a/cli/args/lockfile.rs
+++ b/cli/args/lockfile.rs
@@ -147,22 +147,28 @@ impl CliLockfile {
},
};
+ let root_folder = workspace.root_folder_configs();
+ // CLI flag takes precedence over the config
+ let frozen = flags.frozen_lockfile.unwrap_or_else(|| {
+ root_folder
+ .deno_json
+ .as_ref()
+ .and_then(|c| c.to_lock_config().ok().flatten().map(|c| c.frozen()))
+ .unwrap_or(false)
+ });
+
let lockfile = if flags.lock_write {
log::warn!(
"{} \"--lock-write\" flag is deprecated and will be removed in Deno 2.",
crate::colors::yellow("Warning")
);
- CliLockfile::new(
- Lockfile::new_empty(filename, true),
- flags.frozen_lockfile,
- )
+ CliLockfile::new(Lockfile::new_empty(filename, true), frozen)
} else {
- Self::read_from_path(filename, flags.frozen_lockfile)?
+ Self::read_from_path(filename, frozen)?
};
// initialize the lockfile with the workspace's configuration
let root_url = workspace.root_dir();
- let root_folder = workspace.root_folder_configs();
let config = deno_lockfile::WorkspaceConfig {
root: WorkspaceMemberConfig {
package_json_deps: pkg_json_deps(root_folder.pkg_json.as_deref()),
diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs
index e32303baa..f99f1fa10 100644
--- a/cli/lsp/config.rs
+++ b/cli/lsp/config.rs
@@ -1846,7 +1846,12 @@ fn resolve_lockfile_from_workspace(
return None;
}
};
- resolve_lockfile_from_path(lockfile_path)
+ let frozen = workspace
+ .workspace
+ .root_deno_json()
+ .and_then(|c| c.to_lock_config().ok().flatten().map(|c| c.frozen()))
+ .unwrap_or(false);
+ resolve_lockfile_from_path(lockfile_path, frozen)
}
fn resolve_node_modules_dir(
@@ -1875,8 +1880,11 @@ fn resolve_node_modules_dir(
canonicalize_path_maybe_not_exists(&node_modules_dir).ok()
}
-fn resolve_lockfile_from_path(lockfile_path: PathBuf) -> Option<CliLockfile> {
- match CliLockfile::read_from_path(lockfile_path, false) {
+fn resolve_lockfile_from_path(
+ lockfile_path: PathBuf,
+ frozen: bool,
+) -> Option<CliLockfile> {
+ match CliLockfile::read_from_path(lockfile_path, frozen) {
Ok(value) => {
if value.filename.exists() {
if let Ok(specifier) = ModuleSpecifier::from_file_path(&value.filename)
diff --git a/cli/schemas/config-file.v1.json b/cli/schemas/config-file.v1.json
index adfe3b0c2..733a9cab6 100644
--- a/cli/schemas/config-file.v1.json
+++ b/cli/schemas/config-file.v1.json
@@ -552,8 +552,20 @@
},
"lock": {
"description": "Whether to use a lock file or the path to use for the lock file. Can be overridden by CLI arguments.",
- "type": ["string", "boolean"],
- "default": true
+ "type": ["string", "boolean", "object"],
+ "default": true,
+ "properties": {
+ "path": {
+ "type": "string",
+ "description": "The path to use for the lock file.",
+ "default": "deno.lock"
+ },
+ "frozen": {
+ "type": "boolean",
+ "description": "Whether to exit with an error if lock file is out of date.",
+ "default": false
+ }
+ }
},
"unstable": {
"type": "array",
diff --git a/cli/tools/installer.rs b/cli/tools/installer.rs
index 648b766b8..456e5c1a6 100644
--- a/cli/tools/installer.rs
+++ b/cli/tools/installer.rs
@@ -472,7 +472,7 @@ async fn resolve_shim_data(
executable_args.push("--cached-only".to_string());
}
- if flags.frozen_lockfile {
+ if flags.frozen_lockfile.unwrap_or(false) {
executable_args.push("--frozen".to_string());
}
diff --git a/tests/specs/lockfile/frozen_lockfile/__test__.jsonc b/tests/specs/lockfile/frozen_lockfile/__test__.jsonc
index 8faa45b4e..3036c8db5 100644
--- a/tests/specs/lockfile/frozen_lockfile/__test__.jsonc
+++ b/tests/specs/lockfile/frozen_lockfile/__test__.jsonc
@@ -123,6 +123,35 @@
}
]
},
+
+ "lockfile_config": {
+ "steps": [
+ {
+ "args": [
+ "eval",
+ "Deno.writeTextFileSync('deno.json', JSON.stringify({ lock: { frozen: true }, ...JSON.parse(Deno.readTextFileSync('deno.json')) }))"
+ ],
+ "output": ""
+ },
+ {
+ "args": "cache --frozen=false add.ts",
+ "output": "[WILDCARD]"
+ },
+ {
+ // sub.ts imports from an npm package
+ // that's not in the lockfile
+ "args": "run sub.ts",
+ "output": "frozen_new_dep_run.out",
+ "exitCode": 1
+ },
+ {
+ "args": "cache sub.ts",
+ "output": "frozen_new_dep_cache.out",
+ "exitCode": 1
+ }
+ ]
+ },
+
"non_analyzable_dynamic_npm": {
"steps": [
{