mirror of
https://github.com/denoland/deno.git
synced 2025-07-24 05:35:33 +00:00
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:
parent
cc8e4a00aa
commit
b15f9e60a0
45 changed files with 561 additions and 197 deletions
|
@ -18,6 +18,7 @@ use deno_core::serde_json;
|
|||
use deno_core::serde_json::json;
|
||||
use deno_core::serde_json::Value;
|
||||
use deno_core::ModuleSpecifier;
|
||||
use indexmap::IndexMap;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
|
@ -760,9 +761,9 @@ impl ConfigFile {
|
|||
|
||||
pub fn to_tasks_config(
|
||||
&self,
|
||||
) -> Result<Option<BTreeMap<String, String>>, AnyError> {
|
||||
) -> Result<Option<IndexMap<String, String>>, AnyError> {
|
||||
if let Some(config) = self.json.tasks.clone() {
|
||||
let tasks_config: BTreeMap<String, String> =
|
||||
let tasks_config: IndexMap<String, String> =
|
||||
serde_json::from_value(config)
|
||||
.context("Failed to parse \"tasks\" configuration")?;
|
||||
Ok(Some(tasks_config))
|
||||
|
@ -815,25 +816,22 @@ impl ConfigFile {
|
|||
|
||||
pub fn resolve_tasks_config(
|
||||
&self,
|
||||
) -> Result<BTreeMap<String, String>, AnyError> {
|
||||
) -> Result<IndexMap<String, String>, AnyError> {
|
||||
let maybe_tasks_config = self.to_tasks_config()?;
|
||||
if let Some(tasks_config) = maybe_tasks_config {
|
||||
for key in tasks_config.keys() {
|
||||
if key.is_empty() {
|
||||
bail!("Configuration file task names cannot be empty");
|
||||
} else if !key
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | ':'))
|
||||
{
|
||||
bail!("Configuration file task names must only contain alpha-numeric characters, colons (:), underscores (_), or dashes (-). Task: {}", key);
|
||||
} else if !key.chars().next().unwrap().is_ascii_alphabetic() {
|
||||
bail!("Configuration file task names must start with an alphabetic character. Task: {}", key);
|
||||
}
|
||||
let tasks_config = maybe_tasks_config.unwrap_or_default();
|
||||
for key in tasks_config.keys() {
|
||||
if key.is_empty() {
|
||||
bail!("Configuration file task names cannot be empty");
|
||||
} else if !key
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_alphanumeric() || matches!(c, '_' | '-' | ':'))
|
||||
{
|
||||
bail!("Configuration file task names must only contain alpha-numeric characters, colons (:), underscores (_), or dashes (-). Task: {}", key);
|
||||
} else if !key.chars().next().unwrap().is_ascii_alphabetic() {
|
||||
bail!("Configuration file task names must start with an alphabetic character. Task: {}", key);
|
||||
}
|
||||
Ok(tasks_config)
|
||||
} else {
|
||||
bail!("No tasks found in configuration file")
|
||||
}
|
||||
Ok(tasks_config)
|
||||
}
|
||||
|
||||
pub fn to_lock_config(&self) -> Result<Option<LockConfig>, AnyError> {
|
||||
|
@ -1237,11 +1235,6 @@ mod tests {
|
|||
assert!(err.to_string().contains("Unable to parse config file"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tasks_no_tasks() {
|
||||
run_task_error_test(r#"{}"#, "No tasks found in configuration file");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn task_name_invalid_chars() {
|
||||
run_task_error_test(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue