summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/npm/managed/resolvers/local.rs33
-rw-r--r--resolvers/deno/npm/byonm.rs19
-rw-r--r--tests/specs/install/byonm_run_tag_after_install/__test__.jsonc44
-rw-r--r--tests/specs/install/byonm_run_tag_after_install/deno.json5
-rw-r--r--tests/specs/install/byonm_run_tag_after_install/main.ts1
-rw-r--r--tests/specs/install/byonm_run_tag_after_install/node_modules_out_of_date.out2
-rw-r--r--tests/specs/install/byonm_run_tag_after_install/package.json1
-rw-r--r--tests/specs/install/byonm_run_tag_after_install/replace-version-req.ts7
8 files changed, 109 insertions, 3 deletions
diff --git a/cli/npm/managed/resolvers/local.rs b/cli/npm/managed/resolvers/local.rs
index edc7c7ea0..258c9bf3d 100644
--- a/cli/npm/managed/resolvers/local.rs
+++ b/cli/npm/managed/resolvers/local.rs
@@ -343,6 +343,14 @@ async fn sync_resolution_with_fs(
},
);
let packages_with_deprecation_warnings = Arc::new(Mutex::new(Vec::new()));
+
+ let mut package_tags: HashMap<&PackageNv, Vec<&str>> = HashMap::new();
+ for (package_req, package_nv) in snapshot.package_reqs() {
+ if let Some(tag) = package_req.version_req.tag() {
+ package_tags.entry(package_nv).or_default().push(tag);
+ }
+ }
+
for package in &package_partitions.packages {
if let Some(current_pkg) =
newest_packages_by_name.get_mut(&package.id.nv.name)
@@ -357,11 +365,29 @@ async fn sync_resolution_with_fs(
let package_folder_name =
get_package_folder_id_folder_name(&package.get_package_cache_folder_id());
let folder_path = deno_local_registry_dir.join(&package_folder_name);
+ let tags = package_tags
+ .get(&package.id.nv)
+ .map(|tags| tags.join(","))
+ .unwrap_or_default();
+ enum PackageFolderState {
+ UpToDate,
+ Uninitialized,
+ TagsOutdated,
+ }
let initialized_file = folder_path.join(".initialized");
+ let package_state = std::fs::read_to_string(&initialized_file)
+ .map(|s| {
+ if s != tags {
+ PackageFolderState::TagsOutdated
+ } else {
+ PackageFolderState::UpToDate
+ }
+ })
+ .unwrap_or(PackageFolderState::Uninitialized);
if !cache
.cache_setting()
.should_use_for_npm_package(&package.id.nv.name)
- || !initialized_file.exists()
+ || matches!(package_state, PackageFolderState::Uninitialized)
{
// cache bust the dep from the dep setup cache so the symlinks
// are forced to be recreated
@@ -371,6 +397,7 @@ async fn sync_resolution_with_fs(
let bin_entries_to_setup = bin_entries.clone();
let packages_with_deprecation_warnings =
packages_with_deprecation_warnings.clone();
+
cache_futures.push(async move {
tarball_cache
.ensure_package(&package.id.nv, &package.dist)
@@ -389,7 +416,7 @@ async fn sync_resolution_with_fs(
move || {
clone_dir_recursive(&cache_folder, &package_path)?;
// write out a file that indicates this folder has been initialized
- fs::write(initialized_file, "")?;
+ fs::write(initialized_file, tags)?;
Ok::<_, AnyError>(())
}
@@ -410,6 +437,8 @@ async fn sync_resolution_with_fs(
drop(pb_guard); // explicit for clarity
Ok::<_, AnyError>(())
});
+ } else if matches!(package_state, PackageFolderState::TagsOutdated) {
+ fs::write(initialized_file, tags)?;
}
let sub_node_modules = folder_path.join("node_modules");
diff --git a/resolvers/deno/npm/byonm.rs b/resolvers/deno/npm/byonm.rs
index 5bc4e62b2..3394b3e50 100644
--- a/resolvers/deno/npm/byonm.rs
+++ b/resolvers/deno/npm/byonm.rs
@@ -253,7 +253,24 @@ impl<Fs: DenoResolverFs> ByonmNpmResolver<Fs> {
let Ok(version) = Version::parse_from_npm(version) else {
continue;
};
- if req.version_req.matches(&version) {
+ if let Some(tag) = req.version_req.tag() {
+ let initialized_file =
+ node_modules_deno_dir.join(&entry.name).join(".initialized");
+ let Ok(contents) = self.fs.read_to_string_lossy(&initialized_file)
+ else {
+ continue;
+ };
+ let mut tags = contents.split(',').map(str::trim);
+ if tags.any(|t| t == tag) {
+ if let Some((best_version_version, _)) = &best_version {
+ if version > *best_version_version {
+ best_version = Some((version, entry.name));
+ }
+ } else {
+ best_version = Some((version, entry.name));
+ }
+ }
+ } else if req.version_req.matches(&version) {
if let Some((best_version_version, _)) = &best_version {
if version > *best_version_version {
best_version = Some((version, entry.name));
diff --git a/tests/specs/install/byonm_run_tag_after_install/__test__.jsonc b/tests/specs/install/byonm_run_tag_after_install/__test__.jsonc
new file mode 100644
index 000000000..3803fd26f
--- /dev/null
+++ b/tests/specs/install/byonm_run_tag_after_install/__test__.jsonc
@@ -0,0 +1,44 @@
+{
+ "tempDir": true,
+
+ "tests": {
+ "tag_with_byonm": {
+ "steps": [
+ {
+ "args": "install",
+ "output": "[WILDCARD]"
+ },
+ {
+ "args": "run -A main.ts",
+ "output": ""
+ }
+ ]
+ },
+ "no_tag_then_tag": {
+ "steps": [
+ {
+ "args": "run -A replace-version-req.ts 1.0.0",
+ "output": ""
+ },
+ {
+ "args": "install",
+ "output": "[WILDCARD]"
+ },
+ {
+ "args": "run -A replace-version-req.ts latest",
+ "output": ""
+ },
+ {
+ "args": "run -A main.ts",
+ "output": "node_modules_out_of_date.out",
+ "exitCode": 1
+ },
+ {
+ "args": "install",
+ "output": "[WILDCARD]"
+ },
+ { "args": "run -A main.ts", "output": "" }
+ ]
+ }
+ }
+}
diff --git a/tests/specs/install/byonm_run_tag_after_install/deno.json b/tests/specs/install/byonm_run_tag_after_install/deno.json
new file mode 100644
index 000000000..13238b169
--- /dev/null
+++ b/tests/specs/install/byonm_run_tag_after_install/deno.json
@@ -0,0 +1,5 @@
+{
+ "imports": {
+ "@denotest/esm-basic": "npm:@denotest/esm-basic@latest"
+ }
+}
diff --git a/tests/specs/install/byonm_run_tag_after_install/main.ts b/tests/specs/install/byonm_run_tag_after_install/main.ts
new file mode 100644
index 000000000..7feb95f96
--- /dev/null
+++ b/tests/specs/install/byonm_run_tag_after_install/main.ts
@@ -0,0 +1 @@
+import { add } from "@denotest/esm-basic";
diff --git a/tests/specs/install/byonm_run_tag_after_install/node_modules_out_of_date.out b/tests/specs/install/byonm_run_tag_after_install/node_modules_out_of_date.out
new file mode 100644
index 000000000..2d7fc81d1
--- /dev/null
+++ b/tests/specs/install/byonm_run_tag_after_install/node_modules_out_of_date.out
@@ -0,0 +1,2 @@
+error: Could not find a matching package for 'npm:@denotest/esm-basic@latest' in the node_modules directory. Ensure you have all your JSR and npm dependencies listed in your deno.json or package.json, then run `deno install`. Alternatively, turn on auto-install by specifying `"nodeModulesDir": "auto"` in your deno.json file.
+ at [WILDCARD]main.ts:1:21
diff --git a/tests/specs/install/byonm_run_tag_after_install/package.json b/tests/specs/install/byonm_run_tag_after_install/package.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/tests/specs/install/byonm_run_tag_after_install/package.json
@@ -0,0 +1 @@
+{}
diff --git a/tests/specs/install/byonm_run_tag_after_install/replace-version-req.ts b/tests/specs/install/byonm_run_tag_after_install/replace-version-req.ts
new file mode 100644
index 000000000..6f86ce2b7
--- /dev/null
+++ b/tests/specs/install/byonm_run_tag_after_install/replace-version-req.ts
@@ -0,0 +1,7 @@
+const newReq = Deno.args[0]?.trim();
+if (!newReq) {
+ throw new Error("Missing required argument");
+}
+const config = JSON.parse(Deno.readTextFileSync("deno.json"));
+config.imports["@denotest/esm-basic"] = `npm:@denotest/esm-basic@${newReq}`;
+Deno.writeTextFileSync("deno.json", JSON.stringify(config));