From 66d25df42cf94e289b1173020a50065732a081d1 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Thu, 18 May 2023 21:51:17 +0200 Subject: [PATCH] fix(npm): run pre and post tasks if present (#19178) This PR optionally runs pre and posts tasks from `package.json` if available. Fixes #19157 --- cli/tests/integration/task_tests.rs | 54 +++++++++++++++++++ .../testdata/task/deno_json_pre_post/bin.out | 2 + .../task/deno_json_pre_post/deno.json | 7 +++ .../testdata/task/deno_json_pre_post/echo.out | 1 + .../testdata/task/package_json_post/bin.out | 5 ++ .../testdata/task/package_json_post/echo.out | 1 + .../task/package_json_post/package.json | 6 +++ .../task/package_json_post_only/bin.out | 4 ++ .../task/package_json_post_only/echo.out | 1 + .../task/package_json_post_only/package.json | 5 ++ .../testdata/task/package_json_pre/bin.out | 5 ++ .../testdata/task/package_json_pre/echo.out | 1 + .../task/package_json_pre/package.json | 6 +++ .../task/package_json_pre_only/bin.out | 4 ++ .../task/package_json_pre_only/echo.out | 1 + .../task/package_json_pre_only/package.json | 5 ++ .../task/package_json_pre_post/bin.out | 7 +++ .../task/package_json_pre_post/echo.out | 1 + .../task/package_json_pre_post/package.json | 7 +++ cli/tools/task.rs | 41 +++++++++----- 20 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 cli/tests/testdata/task/deno_json_pre_post/bin.out create mode 100644 cli/tests/testdata/task/deno_json_pre_post/deno.json create mode 100644 cli/tests/testdata/task/deno_json_pre_post/echo.out create mode 100644 cli/tests/testdata/task/package_json_post/bin.out create mode 100644 cli/tests/testdata/task/package_json_post/echo.out create mode 100644 cli/tests/testdata/task/package_json_post/package.json create mode 100644 cli/tests/testdata/task/package_json_post_only/bin.out create mode 100644 cli/tests/testdata/task/package_json_post_only/echo.out create mode 100644 cli/tests/testdata/task/package_json_post_only/package.json create mode 100644 cli/tests/testdata/task/package_json_pre/bin.out create mode 100644 cli/tests/testdata/task/package_json_pre/echo.out create mode 100644 cli/tests/testdata/task/package_json_pre/package.json create mode 100644 cli/tests/testdata/task/package_json_pre_only/bin.out create mode 100644 cli/tests/testdata/task/package_json_pre_only/echo.out create mode 100644 cli/tests/testdata/task/package_json_pre_only/package.json create mode 100644 cli/tests/testdata/task/package_json_pre_post/bin.out create mode 100644 cli/tests/testdata/task/package_json_pre_post/echo.out create mode 100644 cli/tests/testdata/task/package_json_pre_post/package.json diff --git a/cli/tests/integration/task_tests.rs b/cli/tests/integration/task_tests.rs index 45b091b083..47be2acdfb 100644 --- a/cli/tests/integration/task_tests.rs +++ b/cli/tests/integration/task_tests.rs @@ -233,3 +233,57 @@ itest!(task_npx_on_own { exit_code: 1, http_server: true, }); + +itest!(task_pre_post { + args: "task test", + cwd: Some("task/package_json_pre_post/"), + output: "task/package_json_pre_post/bin.out", + copy_temp_dir: Some("task/package_json_pre_post/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_pre { + args: "task test", + cwd: Some("task/package_json_pre/"), + output: "task/package_json_pre/bin.out", + copy_temp_dir: Some("task/package_json_pre/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_post { + args: "task test", + cwd: Some("task/package_json_post/"), + output: "task/package_json_post/bin.out", + copy_temp_dir: Some("task/package_json_post/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_post_only { + args: "task test", + cwd: Some("task/package_json_post_only/"), + output: "task/package_json_post_only/bin.out", + copy_temp_dir: Some("task/package_json_post_only/"), + exit_code: 1, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_pre_only { + args: "task test", + cwd: Some("task/package_json_pre_only/"), + output: "task/package_json_pre_only/bin.out", + copy_temp_dir: Some("task/package_json_pre_only/"), + exit_code: 1, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); + +itest!(task_deno_no_pre_post { + args: "task test", + cwd: Some("task/deno_json_pre_post/"), + output: "task/deno_json_pre_post/bin.out", + copy_temp_dir: Some("task/deno_json_pre_post/"), + exit_code: 0, + envs: vec![("NO_COLOR".to_string(), "1".to_string())], +}); diff --git a/cli/tests/testdata/task/deno_json_pre_post/bin.out b/cli/tests/testdata/task/deno_json_pre_post/bin.out new file mode 100644 index 0000000000..ad66595f1e --- /dev/null +++ b/cli/tests/testdata/task/deno_json_pre_post/bin.out @@ -0,0 +1,2 @@ +Task test echo 'test' +test diff --git a/cli/tests/testdata/task/deno_json_pre_post/deno.json b/cli/tests/testdata/task/deno_json_pre_post/deno.json new file mode 100644 index 0000000000..165b92e3ad --- /dev/null +++ b/cli/tests/testdata/task/deno_json_pre_post/deno.json @@ -0,0 +1,7 @@ +{ + "tasks": { + "pretest": "echo 'pretest'", + "posttest": "echo 'posttest'", + "test": "echo 'test'" + } +} diff --git a/cli/tests/testdata/task/deno_json_pre_post/echo.out b/cli/tests/testdata/task/deno_json_pre_post/echo.out new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/cli/tests/testdata/task/deno_json_pre_post/echo.out @@ -0,0 +1 @@ +0 diff --git a/cli/tests/testdata/task/package_json_post/bin.out b/cli/tests/testdata/task/package_json_post/bin.out new file mode 100644 index 0000000000..9864cc76d0 --- /dev/null +++ b/cli/tests/testdata/task/package_json_post/bin.out @@ -0,0 +1,5 @@ +Warning Currently only basic package.json `scripts` are supported. Programs like `rimraf` or `cross-env` will not work correctly. This will be fixed in an upcoming release. +Task test echo 'test' +test +Task posttest echo 'posttest' +posttest diff --git a/cli/tests/testdata/task/package_json_post/echo.out b/cli/tests/testdata/task/package_json_post/echo.out new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/cli/tests/testdata/task/package_json_post/echo.out @@ -0,0 +1 @@ +0 diff --git a/cli/tests/testdata/task/package_json_post/package.json b/cli/tests/testdata/task/package_json_post/package.json new file mode 100644 index 0000000000..82689f7d44 --- /dev/null +++ b/cli/tests/testdata/task/package_json_post/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "posttest": "echo 'posttest'", + "test": "echo 'test'" + } +} diff --git a/cli/tests/testdata/task/package_json_post_only/bin.out b/cli/tests/testdata/task/package_json_post_only/bin.out new file mode 100644 index 0000000000..9e7cea0916 --- /dev/null +++ b/cli/tests/testdata/task/package_json_post_only/bin.out @@ -0,0 +1,4 @@ +Task not found: test +Available tasks: +- posttest (package.json) + echo 'posttest' diff --git a/cli/tests/testdata/task/package_json_post_only/echo.out b/cli/tests/testdata/task/package_json_post_only/echo.out new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/cli/tests/testdata/task/package_json_post_only/echo.out @@ -0,0 +1 @@ +0 diff --git a/cli/tests/testdata/task/package_json_post_only/package.json b/cli/tests/testdata/task/package_json_post_only/package.json new file mode 100644 index 0000000000..ce8a6bbd54 --- /dev/null +++ b/cli/tests/testdata/task/package_json_post_only/package.json @@ -0,0 +1,5 @@ +{ + "scripts": { + "posttest": "echo 'posttest'" + } +} diff --git a/cli/tests/testdata/task/package_json_pre/bin.out b/cli/tests/testdata/task/package_json_pre/bin.out new file mode 100644 index 0000000000..89c64f2e5a --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre/bin.out @@ -0,0 +1,5 @@ +Warning Currently only basic package.json `scripts` are supported. Programs like `rimraf` or `cross-env` will not work correctly. This will be fixed in an upcoming release. +Task pretest echo 'pretest' +pretest +Task test echo 'test' +test diff --git a/cli/tests/testdata/task/package_json_pre/echo.out b/cli/tests/testdata/task/package_json_pre/echo.out new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre/echo.out @@ -0,0 +1 @@ +0 diff --git a/cli/tests/testdata/task/package_json_pre/package.json b/cli/tests/testdata/task/package_json_pre/package.json new file mode 100644 index 0000000000..d3eba02a19 --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre/package.json @@ -0,0 +1,6 @@ +{ + "scripts": { + "test": "echo 'test'", + "pretest": "echo 'pretest'" + } +} diff --git a/cli/tests/testdata/task/package_json_pre_only/bin.out b/cli/tests/testdata/task/package_json_pre_only/bin.out new file mode 100644 index 0000000000..e96e8e3417 --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre_only/bin.out @@ -0,0 +1,4 @@ +Task not found: test +Available tasks: +- pretest (package.json) + echo 'pretest' diff --git a/cli/tests/testdata/task/package_json_pre_only/echo.out b/cli/tests/testdata/task/package_json_pre_only/echo.out new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre_only/echo.out @@ -0,0 +1 @@ +1 diff --git a/cli/tests/testdata/task/package_json_pre_only/package.json b/cli/tests/testdata/task/package_json_pre_only/package.json new file mode 100644 index 0000000000..032a5d4eab --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre_only/package.json @@ -0,0 +1,5 @@ +{ + "scripts": { + "pretest": "echo 'pretest'" + } +} diff --git a/cli/tests/testdata/task/package_json_pre_post/bin.out b/cli/tests/testdata/task/package_json_pre_post/bin.out new file mode 100644 index 0000000000..0c686b9cdb --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre_post/bin.out @@ -0,0 +1,7 @@ +Warning Currently only basic package.json `scripts` are supported. Programs like `rimraf` or `cross-env` will not work correctly. This will be fixed in an upcoming release. +Task pretest echo 'pretest' +pretest +Task test echo 'test' +test +Task posttest echo 'posttest' +posttest diff --git a/cli/tests/testdata/task/package_json_pre_post/echo.out b/cli/tests/testdata/task/package_json_pre_post/echo.out new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre_post/echo.out @@ -0,0 +1 @@ +0 diff --git a/cli/tests/testdata/task/package_json_pre_post/package.json b/cli/tests/testdata/task/package_json_pre_post/package.json new file mode 100644 index 0000000000..24a3ff1ed7 --- /dev/null +++ b/cli/tests/testdata/task/package_json_pre_post/package.json @@ -0,0 +1,7 @@ +{ + "scripts": { + "pretest": "echo 'pretest'", + "posttest": "echo 'posttest'", + "test": "echo 'test'" + } +} diff --git a/cli/tools/task.rs b/cli/tools/task.rs index 37a1aa1c97..7dd7e7bc4d 100644 --- a/cli/tools/task.rs +++ b/cli/tools/task.rs @@ -65,7 +65,7 @@ pub async fn execute_script( deno_task_shell::execute(seq_list, env_vars, &cwd, Default::default()); let exit_code = local.run_until(future).await; Ok(exit_code) - } else if let Some(script) = package_json_scripts.get(task_name) { + } else if package_json_scripts.contains_key(task_name) { let package_json_deps_provider = factory.package_json_deps_provider(); let package_json_deps_installer = factory.package_json_deps_installer().await?; @@ -105,17 +105,34 @@ pub async fn execute_script( .unwrap() .to_owned(), }; - let script = get_script_with_args(script, cli_options); - output_task(task_name, &script); - let seq_list = deno_task_shell::parser::parse(&script) - .with_context(|| format!("Error parsing script '{task_name}'."))?; - let npx_commands = resolve_npm_commands(npm_resolver, node_resolver)?; - let env_vars = collect_env_vars(); - let local = LocalSet::new(); - let future = - deno_task_shell::execute(seq_list, env_vars, &cwd, npx_commands); - let exit_code = local.run_until(future).await; - Ok(exit_code) + + // At this point we already checked if the task name exists in package.json. + // We can therefore check for "pre" and "post" scripts too, since we're only + // dealing with package.json here and not deno.json + let task_names = vec![ + format!("pre{}", task_name), + task_name.clone(), + format!("post{}", task_name), + ]; + for task_name in task_names { + if let Some(script) = package_json_scripts.get(&task_name) { + let script = get_script_with_args(script, cli_options); + output_task(&task_name, &script); + let seq_list = deno_task_shell::parser::parse(&script) + .with_context(|| format!("Error parsing script '{task_name}'."))?; + let npx_commands = resolve_npm_commands(npm_resolver, node_resolver)?; + let env_vars = collect_env_vars(); + let local = LocalSet::new(); + let future = + deno_task_shell::execute(seq_list, env_vars, &cwd, npx_commands); + let exit_code = local.run_until(future).await; + if exit_code > 0 { + return Ok(exit_code); + } + } + } + + Ok(0) } else { eprintln!("Task not found: {task_name}"); print_available_tasks(&tasks_config, &package_json_scripts);