summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2023-05-17 17:38:50 -0400
committerGitHub <noreply@github.com>2023-05-17 17:38:50 -0400
commit41f618a1df6bb8c66d7968ac64456139b9f4c197 (patch)
treedbcc67e009cf70099be82ea3774669e8aefc6023 /cli
parentad223362451688c13a4441563210f58bdb046a78 (diff)
fix(npm): improved optional dependency support (#19135)
Note: If the package information has already been cached, then this requires running with `--reload` or for the registry information to be fetched some other way (ex. the cache busting). Closes #15544 --------- Co-authored-by: Bartek IwaƄczuk <biwanczuk@gmail.com>
Diffstat (limited to 'cli')
-rw-r--r--cli/args/lockfile.rs20
-rw-r--r--cli/args/mod.rs37
-rw-r--r--cli/factory.rs4
-rw-r--r--cli/lsp/language_server.rs14
-rw-r--r--cli/npm/resolution.rs26
-rw-r--r--cli/npm/resolvers/common.rs1
-rw-r--r--cli/npm/resolvers/global.rs48
-rw-r--r--cli/npm/resolvers/local.rs9
-rw-r--r--cli/npm/resolvers/mod.rs4
-rw-r--r--cli/standalone/binary.rs30
-rw-r--r--cli/standalone/mod.rs2
-rw-r--r--cli/tests/integration/npm_tests.rs81
-rw-r--r--cli/tests/testdata/npm/binary_package/main.js1
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js1
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json8
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js1
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json8
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js1
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json8
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js13
-rw-r--r--cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json10
-rw-r--r--cli/tools/info.rs3
22 files changed, 273 insertions, 57 deletions
diff --git a/cli/args/lockfile.rs b/cli/args/lockfile.rs
index 8cb21781a..aa7e51fa1 100644
--- a/cli/args/lockfile.rs
+++ b/cli/args/lockfile.rs
@@ -107,8 +107,12 @@ pub async fn snapshot_from_lockfile(
packages.push(SerializedNpmResolutionSnapshotPackage {
pkg_id,
- dist: Default::default(), // temporarily empty
dependencies,
+ // temporarily empty
+ os: Default::default(),
+ cpu: Default::default(),
+ dist: Default::default(),
+ optional_dependencies: Default::default(),
});
}
(root_packages, packages)
@@ -131,11 +135,17 @@ pub async fn snapshot_from_lockfile(
}))
};
let mut version_infos = get_version_infos();
-
let mut i = 0;
while let Some(result) = version_infos.next().await {
- packages[i].dist = match result {
- Ok(version_info) => version_info.dist,
+ match result {
+ Ok(version_info) => {
+ let mut package = &mut packages[i];
+ package.dist = version_info.dist;
+ package.cpu = version_info.cpu;
+ package.os = version_info.os;
+ package.optional_dependencies =
+ version_info.optional_dependencies.into_keys().collect();
+ }
Err(err) => {
if api.mark_force_reload() {
// reset and try again
@@ -146,7 +156,7 @@ pub async fn snapshot_from_lockfile(
return Err(err);
}
}
- };
+ }
i += 1;
}
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index 31035fdd0..53dad9cae 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -13,6 +13,7 @@ use self::package_json::PackageJsonDeps;
use ::import_map::ImportMap;
use deno_core::resolve_url_or_path;
use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
+use deno_npm::NpmSystemInfo;
use deno_runtime::deno_tls::RootCertStoreProvider;
use deno_semver::npm::NpmPackageReqReference;
use indexmap::IndexMap;
@@ -688,6 +689,42 @@ impl CliOptions {
}
}
+ pub fn npm_system_info(&self) -> NpmSystemInfo {
+ match self.sub_command() {
+ DenoSubcommand::Compile(CompileFlags {
+ target: Some(target),
+ ..
+ }) => {
+ // the values of NpmSystemInfo align with the possible values for the
+ // `arch` and `platform` fields of Node.js' `process` global:
+ // https://nodejs.org/api/process.html
+ match target.as_str() {
+ "aarch64-apple-darwin" => NpmSystemInfo {
+ os: "darwin".to_string(),
+ cpu: "arm64".to_string(),
+ },
+ "x86_64-apple-darwin" => NpmSystemInfo {
+ os: "darwin".to_string(),
+ cpu: "x64".to_string(),
+ },
+ "x86_64-unknown-linux-gnu" => NpmSystemInfo {
+ os: "linux".to_string(),
+ cpu: "x64".to_string(),
+ },
+ "x86_64-pc-windows-msvc" => NpmSystemInfo {
+ os: "win32".to_string(),
+ cpu: "x64".to_string(),
+ },
+ value => {
+ log::warn!("Not implemented NPM system info for target '{value}'. Using current system default. This may impact NPM ");
+ NpmSystemInfo::default()
+ }
+ }
+ }
+ _ => NpmSystemInfo::default(),
+ }
+ }
+
pub fn resolve_deno_dir(&self) -> Result<DenoDir, AnyError> {
Ok(DenoDir::new(self.maybe_custom_root())?)
}
diff --git a/cli/factory.rs b/cli/factory.rs
index a3da40036..0c85536c4 100644
--- a/cli/factory.rs
+++ b/cli/factory.rs
@@ -313,6 +313,7 @@ impl CliFactory {
CliNpmRegistryApi::default_url().to_owned(),
npm_resolution.clone(),
self.options.node_modules_dir_path(),
+ self.options.npm_system_info(),
);
Ok(Arc::new(CliNpmResolver::new(
fs.clone(),
@@ -557,8 +558,9 @@ impl CliFactory {
self.deno_dir()?,
self.npm_api()?,
self.npm_cache()?,
- self.npm_resolver().await?,
self.npm_resolution().await?,
+ self.npm_resolver().await?,
+ self.options.npm_system_info(),
self.package_json_deps_provider(),
))
}
diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs
index e76ea0040..96329e4a1 100644
--- a/cli/lsp/language_server.rs
+++ b/cli/lsp/language_server.rs
@@ -10,6 +10,7 @@ use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::task::spawn;
use deno_core::ModuleSpecifier;
+use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs;
use deno_runtime::deno_node::NodeResolver;
use deno_runtime::deno_node::PackageJson;
@@ -467,6 +468,7 @@ fn create_lsp_structs(
registry_url.clone(),
resolution.clone(),
None,
+ NpmSystemInfo::default(),
);
(
api,
@@ -725,6 +727,7 @@ impl Inner {
self.npm_api.base_url().clone(),
npm_resolution,
None,
+ NpmSystemInfo::default(),
),
None,
));
@@ -1242,11 +1245,12 @@ impl Inner {
async fn refresh_npm_specifiers(&mut self) {
let package_reqs = self.documents.npm_package_reqs();
- if let Err(err) = self
- .npm_resolver
- .set_package_reqs((*package_reqs).clone())
- .await
- {
+ let npm_resolver = self.npm_resolver.clone();
+ // spawn to avoid the LSP's Send requirements
+ let handle = spawn(async move {
+ npm_resolver.set_package_reqs((*package_reqs).clone()).await
+ });
+ if let Err(err) = handle.await.unwrap() {
lsp_warn!("Could not set npm package requirements. {:#}", err);
}
}
diff --git a/cli/npm/resolution.rs b/cli/npm/resolution.rs
index edc7ec647..3e9438ffa 100644
--- a/cli/npm/resolution.rs
+++ b/cli/npm/resolution.rs
@@ -23,6 +23,7 @@ use deno_npm::resolution::ValidSerializedNpmResolutionSnapshot;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage;
+use deno_npm::NpmSystemInfo;
use deno_semver::npm::NpmPackageNv;
use deno_semver::npm::NpmPackageNvReference;
use deno_semver::npm::NpmPackageReq;
@@ -237,12 +238,21 @@ impl NpmResolution {
Ok(nv)
}
- pub fn all_packages(&self) -> Vec<NpmResolutionPackage> {
- self.snapshot.read().all_packages()
+ pub fn all_system_packages(
+ &self,
+ system_info: &NpmSystemInfo,
+ ) -> Vec<NpmResolutionPackage> {
+ self.snapshot.read().all_system_packages(system_info)
}
- pub fn all_packages_partitioned(&self) -> NpmPackagesPartitioned {
- self.snapshot.read().all_packages_partitioned()
+ pub fn all_system_packages_partitioned(
+ &self,
+ system_info: &NpmSystemInfo,
+ ) -> NpmPackagesPartitioned {
+ self
+ .snapshot
+ .read()
+ .all_system_packages_partitioned(system_info)
}
pub fn has_packages(&self) -> bool {
@@ -322,7 +332,7 @@ fn populate_lockfile_from_snapshot(
.as_serialized(),
);
}
- for package in snapshot.all_packages() {
+ for package in snapshot.all_packages_for_every_system() {
lockfile
.check_or_insert_npm_package(npm_package_to_lockfile_info(package))?;
}
@@ -330,13 +340,13 @@ fn populate_lockfile_from_snapshot(
}
fn npm_package_to_lockfile_info(
- pkg: NpmResolutionPackage,
+ pkg: &NpmResolutionPackage,
) -> NpmPackageLockfileInfo {
let dependencies = pkg
.dependencies
- .into_iter()
+ .iter()
.map(|(name, id)| NpmPackageDependencyLockfileInfo {
- name,
+ name: name.clone(),
id: id.as_serialized(),
})
.collect();
diff --git a/cli/npm/resolvers/common.rs b/cli/npm/resolvers/common.rs
index c91b206cf..abfdd6371 100644
--- a/cli/npm/resolvers/common.rs
+++ b/cli/npm/resolvers/common.rs
@@ -69,7 +69,6 @@ pub async fn cache_packages(
let mut handles = Vec::with_capacity(packages.len());
for package in packages {
- assert_eq!(package.copy_index, 0); // the caller should not provide any of these
let cache = cache.clone();
let registry_url = registry_url.clone();
let handle = spawn(async move {
diff --git a/cli/npm/resolvers/global.rs b/cli/npm/resolvers/global.rs
index fe8764b0c..22211071a 100644
--- a/cli/npm/resolvers/global.rs
+++ b/cli/npm/resolvers/global.rs
@@ -14,6 +14,7 @@ use deno_npm::resolution::PackageNotFoundFromReferrerError;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
use deno_npm::NpmResolutionPackage;
+use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FileSystem;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NodeResolutionMode;
@@ -33,6 +34,7 @@ pub struct GlobalNpmPackageResolver {
cache: Arc<NpmCache>,
resolution: Arc<NpmResolution>,
registry_url: Url,
+ system_info: NpmSystemInfo,
}
impl GlobalNpmPackageResolver {
@@ -41,12 +43,14 @@ impl GlobalNpmPackageResolver {
cache: Arc<NpmCache>,
registry_url: Url,
resolution: Arc<NpmResolution>,
+ system_info: NpmSystemInfo,
) -> Self {
Self {
fs,
cache,
resolution,
registry_url,
+ system_info,
}
}
@@ -125,7 +129,26 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
}
async fn cache_packages(&self) -> Result<(), AnyError> {
- cache_packages_in_resolver(self).await
+ let package_partitions = self
+ .resolution
+ .all_system_packages_partitioned(&self.system_info);
+
+ cache_packages(
+ package_partitions.packages,
+ &self.cache,
+ &self.registry_url,
+ )
+ .await?;
+
+ // create the copy package folders
+ for copy in package_partitions.copy_packages {
+ self.cache.ensure_copy_package(
+ &copy.get_package_cache_folder_id(),
+ &self.registry_url,
+ )?;
+ }
+
+ Ok(())
}
fn ensure_read_permission(
@@ -137,26 +160,3 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
ensure_registry_read_permission(&self.fs, permissions, &registry_path, path)
}
}
-
-async fn cache_packages_in_resolver(
- resolver: &GlobalNpmPackageResolver,
-) -> Result<(), AnyError> {
- let package_partitions = resolver.resolution.all_packages_partitioned();
-
- cache_packages(
- package_partitions.packages,
- &resolver.cache,
- &resolver.registry_url,
- )
- .await?;
-
- // create the copy package folders
- for copy in package_partitions.copy_packages {
- resolver.cache.ensure_copy_package(
- &copy.get_package_cache_folder_id(),
- &resolver.registry_url,
- )?;
- }
-
- Ok(())
-}
diff --git a/cli/npm/resolvers/local.rs b/cli/npm/resolvers/local.rs
index b2ad08357..e14d7e0c5 100644
--- a/cli/npm/resolvers/local.rs
+++ b/cli/npm/resolvers/local.rs
@@ -24,6 +24,7 @@ use deno_core::url::Url;
use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::NpmPackageCacheFolderId;
use deno_npm::NpmPackageId;
+use deno_npm::NpmSystemInfo;
use deno_runtime::deno_core::futures;
use deno_runtime::deno_fs;
use deno_runtime::deno_node::NodePermissions;
@@ -52,6 +53,7 @@ pub struct LocalNpmPackageResolver {
registry_url: Url,
root_node_modules_path: PathBuf,
root_node_modules_url: Url,
+ system_info: NpmSystemInfo,
}
impl LocalNpmPackageResolver {
@@ -62,6 +64,7 @@ impl LocalNpmPackageResolver {
registry_url: Url,
node_modules_folder: PathBuf,
resolution: Arc<NpmResolution>,
+ system_info: NpmSystemInfo,
) -> Self {
Self {
fs,
@@ -72,6 +75,7 @@ impl LocalNpmPackageResolver {
root_node_modules_url: Url::from_directory_path(&node_modules_folder)
.unwrap(),
root_node_modules_path: node_modules_folder,
+ system_info,
}
}
@@ -205,6 +209,7 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
&self.progress_bar,
&self.registry_url,
&self.root_node_modules_path,
+ &self.system_info,
)
.await
}
@@ -230,6 +235,7 @@ async fn sync_resolution_with_fs(
progress_bar: &ProgressBar,
registry_url: &Url,
root_node_modules_dir_path: &Path,
+ system_info: &NpmSystemInfo,
) -> Result<(), AnyError> {
if snapshot.is_empty() {
return Ok(()); // don't create the directory
@@ -254,7 +260,8 @@ async fn sync_resolution_with_fs(
// Copy (hardlink in future) <global_registry_cache>/<package_id>/ to
// node_modules/.deno/<package_folder_id_folder_name>/node_modules/<package_name>
let sync_download = should_sync_download();
- let mut package_partitions = snapshot.all_packages_partitioned();
+ let mut package_partitions =
+ snapshot.all_system_packages_partitioned(system_info);
if sync_download {
// we're running the tests not with --quiet
// and we want the output to be deterministic
diff --git a/cli/npm/resolvers/mod.rs b/cli/npm/resolvers/mod.rs
index f54e509f0..a41727dda 100644
--- a/cli/npm/resolvers/mod.rs
+++ b/cli/npm/resolvers/mod.rs
@@ -18,6 +18,7 @@ use deno_npm::resolution::NpmResolutionSnapshot;
use deno_npm::resolution::PackageReqNotFoundError;
use deno_npm::resolution::SerializedNpmResolutionSnapshot;
use deno_npm::NpmPackageId;
+use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs::FileSystem;
use deno_runtime::deno_node::NodePermissions;
use deno_runtime::deno_node::NodeResolutionMode;
@@ -289,6 +290,7 @@ pub fn create_npm_fs_resolver(
registry_url: Url,
resolution: Arc<NpmResolution>,
maybe_node_modules_path: Option<PathBuf>,
+ system_info: NpmSystemInfo,
) -> Arc<dyn NpmPackageFsResolver> {
match maybe_node_modules_path {
Some(node_modules_folder) => Arc::new(LocalNpmPackageResolver::new(
@@ -298,12 +300,14 @@ pub fn create_npm_fs_resolver(
registry_url,
node_modules_folder,
resolution,
+ system_info,
)),
None => Arc::new(GlobalNpmPackageResolver::new(
fs,
cache,
registry_url,
resolution,
+ system_info,
)),
}
}
diff --git a/cli/standalone/binary.rs b/cli/standalone/binary.rs
index 9ccb39e54..b71fda776 100644
--- a/cli/standalone/binary.rs
+++ b/cli/standalone/binary.rs
@@ -19,6 +19,7 @@ use deno_core::serde_json;
use deno_core::url::Url;
use deno_npm::registry::PackageDepNpmSchemeValueParseError;
use deno_npm::resolution::SerializedNpmResolutionSnapshot;
+use deno_npm::NpmSystemInfo;
use deno_runtime::permissions::PermissionsOptions;
use deno_semver::npm::NpmPackageReq;
use deno_semver::npm::NpmVersionReqSpecifierParseError;
@@ -343,8 +344,9 @@ pub struct DenoCompileBinaryWriter<'a> {
deno_dir: &'a DenoDir,
npm_api: &'a CliNpmRegistryApi,
npm_cache: &'a NpmCache,
+ npm_resolution: &'a NpmResolution,
npm_resolver: &'a CliNpmResolver,
- resolution: &'a NpmResolution,
+ npm_system_info: NpmSystemInfo,
package_json_deps_provider: &'a PackageJsonDepsProvider,
}
@@ -356,8 +358,9 @@ impl<'a> DenoCompileBinaryWriter<'a> {
deno_dir: &'a DenoDir,
npm_api: &'a CliNpmRegistryApi,
npm_cache: &'a NpmCache,
+ npm_resolution: &'a NpmResolution,
npm_resolver: &'a CliNpmResolver,
- resolution: &'a NpmResolution,
+ npm_system_info: NpmSystemInfo,
package_json_deps_provider: &'a PackageJsonDepsProvider,
) -> Self {
Self {
@@ -367,7 +370,8 @@ impl<'a> DenoCompileBinaryWriter<'a> {
npm_api,
npm_cache,
npm_resolver,
- resolution,
+ npm_system_info,
+ npm_resolution,
package_json_deps_provider,
}
}
@@ -488,13 +492,14 @@ impl<'a> DenoCompileBinaryWriter<'a> {
.resolve_import_map(self.file_fetcher)
.await?
.map(|import_map| (import_map.base_url().clone(), import_map.to_json()));
- let (npm_snapshot, npm_vfs, npm_files) = if self.resolution.has_packages() {
- let (root_dir, files) = self.build_vfs()?.into_dir_and_files();
- let snapshot = self.resolution.serialized_snapshot();
- (Some(snapshot), Some(root_dir), files)
- } else {
- (None, None, Vec::new())
- };
+ let (npm_snapshot, npm_vfs, npm_files) =
+ if self.npm_resolution.has_packages() {
+ let (root_dir, files) = self.build_vfs()?.into_dir_and_files();
+ let snapshot = self.npm_resolution.serialized_snapshot();
+ (Some(snapshot), Some(root_dir), files)
+ } else {
+ (None, None, Vec::new())
+ };
let metadata = Metadata {
argv: compile_flags.args.clone(),
@@ -540,7 +545,10 @@ impl<'a> DenoCompileBinaryWriter<'a> {
let registry_url = self.npm_api.base_url();
let root_path = self.npm_cache.registry_folder(registry_url);
let mut builder = VfsBuilder::new(root_path);
- for package in self.resolution.all_packages() {
+ for package in self
+ .npm_resolution
+ .all_system_packages(&self.npm_system_info)
+ {
let folder = self
.npm_resolver
.resolve_pkg_folder_from_pkg_id(&package.pkg_id)?;
diff --git a/cli/standalone/mod.rs b/cli/standalone/mod.rs
index eb5cf5d82..64143c08f 100644
--- a/cli/standalone/mod.rs
+++ b/cli/standalone/mod.rs
@@ -37,6 +37,7 @@ use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier;
use deno_core::ModuleType;
use deno_core::ResolutionKind;
+use deno_npm::NpmSystemInfo;
use deno_runtime::deno_fs;
use deno_runtime::deno_node;
use deno_runtime::deno_node::analyze::NodeCodeTranslator;
@@ -350,6 +351,7 @@ pub async fn run(
npm_registry_url,
npm_resolution.clone(),
node_modules_path,
+ NpmSystemInfo::default(),
);
let npm_resolver = Arc::new(CliNpmResolver::new(
fs.clone(),
diff --git a/cli/tests/integration/npm_tests.rs b/cli/tests/integration/npm_tests.rs
index c04322027..dc3aa7b11 100644
--- a/cli/tests/integration/npm_tests.rs
+++ b/cli/tests/integration/npm_tests.rs
@@ -1799,3 +1799,84 @@ fn reload_info_not_found_cache_but_exists_remote() {
output.assert_exit_code(0);
}
}
+
+#[test]
+fn binary_package_with_optional_dependencies() {
+ let context = TestContextBuilder::for_npm()
+ .use_sync_npm_download()
+ .use_separate_deno_dir() // the "npm" folder means something in the deno dir, so use a separate folder
+ .use_copy_temp_dir("npm/binary_package")
+ .cwd("npm/binary_package")
+ .build();
+
+ let temp_dir = context.temp_dir();
+ let temp_dir_path = temp_dir.path();
+ let project_path = temp_dir_path.join("npm/binary_package");
+
+ // write empty config file so a lockfile gets created
+ temp_dir.write("npm/binary_package/deno.json", "{}");
+
+ // run it twice, with the first time creating the lockfile and the second using it
+ for i in 0..2 {
+ if i == 1 {
+ assert!(project_path.join("deno.lock").exists());
+ }
+
+ let output = context
+ .new_command()
+ .args("run -A --node-modules-dir main.js")
+ .run();
+
+ #[cfg(target_os = "windows")]
+ {
+ output.assert_exit_code(0);
+ output.assert_matches_text(
+ "[WILDCARD]Hello from binary package on windows[WILDCARD]",
+ );
+ assert!(project_path
+ .join("node_modules/.deno/@denotest+binary-package-windows@1.0.0")
+ .exists());
+ assert!(!project_path
+ .join("node_modules/.deno/@denotest+binary-package-linux@1.0.0")
+ .exists());
+ assert!(!project_path
+ .join("node_modules/.deno/@denotest+binary-package-mac@1.0.0")
+ .exists());
+ }
+
+ #[cfg(target_os = "macos")]
+ {
+ output.assert_exit_code(0);
+ output.assert_matches_text(
+ "[WILDCARD]Hello from binary package on mac[WILDCARD]",
+ );
+
+ assert!(!project_path
+ .join("node_modules/.deno/@denotest+binary-package-windows@1.0.0")
+ .exists());
+ assert!(!project_path
+ .join("node_modules/.deno/@denotest+binary-package-linux@1.0.0")
+ .exists());
+ assert!(project_path
+ .join("node_modules/.deno/@denotest+binary-package-mac@1.0.0")
+ .exists());
+ }
+
+ #[cfg(target_os = "linux")]
+ {
+ output.assert_exit_code(0);
+ output.assert_matches_text(
+ "[WILDCARD]Hello from binary package on linux[WILDCARD]",
+ );
+ assert!(!project_path
+ .join("node_modules/.deno/@denotest+binary-package-windows@1.0.0")
+ .exists());
+ assert!(project_path
+ .join("node_modules/.deno/@denotest+binary-package-linux@1.0.0")
+ .exists());
+ assert!(!project_path
+ .join("node_modules/.deno/@denotest+binary-package-mac@1.0.0")
+ .exists());
+ }
+ }
+}
diff --git a/cli/tests/testdata/npm/binary_package/main.js b/cli/tests/testdata/npm/binary_package/main.js
new file mode 100644
index 000000000..8823c5a5b
--- /dev/null
+++ b/cli/tests/testdata/npm/binary_package/main.js
@@ -0,0 +1 @@
+import "npm:@denotest/binary-package";
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js b/cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js
new file mode 100644
index 000000000..03ecfc377
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/index.js
@@ -0,0 +1 @@
+console.log("Hello from binary package on linux"); \ No newline at end of file
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json b/cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json
new file mode 100644
index 000000000..3b450e0d9
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package-linux/1.0.0/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@denotest/binary-package-linux",
+ "version": "1.0.0",
+ "main": "index.js",
+ "os": [
+ "linux"
+ ]
+}
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js b/cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js
new file mode 100644
index 000000000..ac8c91f50
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/index.js
@@ -0,0 +1 @@
+console.log("Hello from binary package on mac"); \ No newline at end of file
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json b/cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json
new file mode 100644
index 000000000..02916e65b
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package-mac/1.0.0/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@denotest/binary-package-linux",
+ "version": "1.0.0",
+ "main": "index.js",
+ "os": [
+ "darwin"
+ ]
+}
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js b/cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js
new file mode 100644
index 000000000..57344ca00
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/index.js
@@ -0,0 +1 @@
+console.log("Hello from binary package on windows"); \ No newline at end of file
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json b/cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json
new file mode 100644
index 000000000..1c0af637d
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package-windows/1.0.0/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@denotest/binary-package-windows",
+ "version": "1.0.0",
+ "main": "index.js",
+ "os": [
+ "win32"
+ ]
+}
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js b/cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js
new file mode 100644
index 000000000..5870118e7
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/index.js
@@ -0,0 +1,13 @@
+const packageByOs = {
+ "darwin": "@denotest/binary-package-mac",
+ "linux": "@denotest/binary-package-linux",
+ "win32": "@denotest/binary-package-windows",
+}
+
+const selectedPackage = packageByOs[process.platform];
+
+if (!selectedPackage) {
+ throw new Error("trying to run on unsupported platform");
+}
+
+require(selectedPackage); \ No newline at end of file
diff --git a/cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json b/cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json
new file mode 100644
index 000000000..dc8859bb4
--- /dev/null
+++ b/cli/tests/testdata/npm/registry/@denotest/binary-package/1.0.0/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "@denotest/binary-package",
+ "version": "1.0.0",
+ "main": "index.js",
+ "optionalDependencies": {
+ "@denotest/binary-package-linux": "1.0.0",
+ "@denotest/binary-package-mac": "1.0.0",
+ "@denotest/binary-package-windows": "1.0.0"
+ }
+}
diff --git a/cli/tools/info.rs b/cli/tools/info.rs
index d491f55dc..14c85f4d8 100644
--- a/cli/tools/info.rs
+++ b/cli/tools/info.rs
@@ -217,7 +217,8 @@ fn add_npm_packages_to_json(
}
}
- let mut sorted_packages = snapshot.all_packages();
+ let mut sorted_packages =
+ snapshot.all_packages_for_every_system().collect::<Vec<_>>();
sorted_packages.sort_by(|a, b| a.pkg_id.cmp(&b.pkg_id));
let mut json_packages = serde_json::Map::with_capacity(sorted_packages.len());
for pkg in sorted_packages {