feat(task): support scripts in package.json (#17887)

This is a super basic initial implementation. We don't create a
`node_modules/.bin` folder at the moment and add it to the PATH like we
should which is necessary to make command name resolution in the
subprocess work properly (ex. you run a script that launches another
script that then tries to launch an "npx command"... this won't work
atm).

Closes #17492
This commit is contained in:
David Sherret 2023-02-22 22:45:35 -05:00 committed by GitHub
parent cc8e4a00aa
commit b15f9e60a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 561 additions and 197 deletions

View file

@ -9,9 +9,9 @@ pub mod package_json;
pub use self::import_map::resolve_import_map_from_specifier;
use ::import_map::ImportMap;
use indexmap::IndexMap;
use crate::npm::NpmResolutionSnapshot;
use crate::util::fs::canonicalize_path;
pub use config_file::BenchConfig;
pub use config_file::CompilerOptions;
pub use config_file::ConfigFile;
@ -49,7 +49,6 @@ use deno_runtime::deno_tls::webpki_roots;
use deno_runtime::inspector_server::InspectorServer;
use deno_runtime::permissions::PermissionsOptions;
use once_cell::sync::Lazy;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::env;
use std::io::BufReader;
@ -398,6 +397,7 @@ fn discover_package_json(
) -> Result<Option<PackageJson>, AnyError> {
const PACKAGE_JSON_NAME: &str = "package.json";
// note: ancestors() includes the `start` path
for ancestor in start.ancestors() {
let path = ancestor.join(PACKAGE_JSON_NAME);
@ -430,17 +430,10 @@ fn discover_package_json(
// TODO(bartlomieju): discover for all subcommands, but print warnings that
// `package.json` is ignored in bundle/compile/etc.
if let crate::args::DenoSubcommand::Task(TaskFlags {
cwd: Some(path), ..
}) = &flags.subcommand
{
// attempt to resolve the config file from the task subcommand's
// `--cwd` when specified
let task_cwd = canonicalize_path(&PathBuf::from(path))?;
return discover_from(&task_cwd, None);
} else if let Some(package_json_arg) = flags.package_json_arg() {
let package_json_arg = canonicalize_path(&package_json_arg)?;
return discover_from(&package_json_arg, maybe_stop_at);
if let Some(package_json_dir) = flags.package_json_search_dir() {
let package_json_dir =
canonicalize_path_maybe_not_exists(&package_json_dir)?;
return discover_from(&package_json_dir, maybe_stop_at);
}
log::debug!("No package.json file found");
@ -802,9 +795,11 @@ impl CliOptions {
pub fn resolve_tasks_config(
&self,
) -> Result<BTreeMap<String, String>, AnyError> {
) -> Result<IndexMap<String, String>, AnyError> {
if let Some(config_file) = &self.maybe_config_file {
config_file.resolve_tasks_config()
} else if self.maybe_package_json.is_some() {
Ok(Default::default())
} else {
bail!("No config file found")
}
@ -841,7 +836,13 @@ impl CliOptions {
pub fn maybe_package_json_deps(
&self,
) -> Result<Option<HashMap<String, NpmPackageReq>>, AnyError> {
if let Some(package_json) = self.maybe_package_json() {
if matches!(
self.flags.subcommand,
DenoSubcommand::Task(TaskFlags { task: None, .. })
) {
// don't have any package json dependencies for deno task with no args
Ok(None)
} else if let Some(package_json) = self.maybe_package_json() {
package_json::get_local_package_json_version_reqs(package_json).map(Some)
} else {
Ok(None)