From 275418473e7bda2b0bd33c86ae54cf3ac8ac5341 Mon Sep 17 00:00:00 2001 From: Nathan Whitaker <17734409+nathanwhit@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:16:46 -0700 Subject: fix(install): store tags associated with package in node_modules dir (#26000) Fixes #25998. Fixes https://github.com/denoland/deno/issues/25928. Originally I was just going to make this an error message instead of a panic, but once I got to a minimal repro I felt that this really should work. The panic occurs when you have `nodeModulesDir: manual` (or a package.json present), and you have an npm package with a tag in your deno.json (see the spec test that illustrates this). This code path only actually executes when trying to choose an appropriate package version from `node_modules/.deno`, so we should be able to fix it by storing some extra data at install time. The fix proposed here is to repurpose the `.initialized` file that we store in `node_modules` to store the tags associated with a package. Basically, if you have a version requirement with a tag (e.g. `npm:chalk@latest`), when we set up the node_modules folder for that package, we store the tag (`latest`) in `.initialized`. Then, when doing BYONM resolution, if we have a version requirement with a tag, we read that file and check if the tag is present. The downside is that we do more work when setting up `node_modules`. We _could_ do this only when BYONM is enabled, but that would have the downside of needing to re-run `deno install` when you switch from auto -> manual, though maybe that's not a big deal. --- .../byonm_run_tag_after_install/__test__.jsonc | 44 ++++++++++++++++++++++ .../install/byonm_run_tag_after_install/deno.json | 5 +++ .../install/byonm_run_tag_after_install/main.ts | 1 + .../node_modules_out_of_date.out | 2 + .../byonm_run_tag_after_install/package.json | 1 + .../replace-version-req.ts | 7 ++++ 6 files changed, 60 insertions(+) create mode 100644 tests/specs/install/byonm_run_tag_after_install/__test__.jsonc create mode 100644 tests/specs/install/byonm_run_tag_after_install/deno.json create mode 100644 tests/specs/install/byonm_run_tag_after_install/main.ts create mode 100644 tests/specs/install/byonm_run_tag_after_install/node_modules_out_of_date.out create mode 100644 tests/specs/install/byonm_run_tag_after_install/package.json create mode 100644 tests/specs/install/byonm_run_tag_after_install/replace-version-req.ts (limited to 'tests') 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)); -- cgit v1.2.3