[npm] Fix `npm run build` and `npm start`.

Our scripting relied on (seemingly) unsupported (direct) use of various
wrapper scripts in our `DEPS`ed `depot_tools`. With this change, we're
now independent of these wrapper scripts and invoke the python scripts
directly.

Also update the `package.json` scripts to use the `DEPS`ed `vpython3`
instead of relying on having some global `depot_tools` in your PATH.

And finally properly terminate `npm start` when the build step fails,
and fix the spinner when using `npm run build` in watch(only) mode.

Bug: none
Change-Id: I820a0479088c0021d6e0f39c8a79df9e6a18db15
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6486632
Reviewed-by: Nikolay Vitkov <[email protected]>
Auto-Submit: Benedikt Meurer <[email protected]>
diff --git a/package.json b/package.json
index 207de80..232ec2e 100644
--- a/package.json
+++ b/package.json
@@ -17,21 +17,21 @@
     "url": "git+https://github.com/ChromeDevTools/devtools-frontend.git"
   },
   "scripts": {
-    "bake-strings": "npm run collect-strings && vpython3 third_party/node/node.py --output third_party/i18n/bake-strings.js front_end/core/i18n/locales",
-    "build": "vpython3 third_party/node/node.py --output scripts/run_build.mjs",
-    "check-external-links": "vpython3 third_party/node/node.py --output scripts/check_external_links.js",
-    "collect-strings": "vpython3 third_party/node/node.py --output third_party/i18n/collect-strings.js front_end",
-    "components-server": "vpython3 third_party/node/node.py --output scripts/component_server/server.js",
-    "debug-webtest": "vpython3 third_party/node/node.py --output scripts/npm_test.js --debug-devtools",
+    "bake-strings": "npm run collect-strings && third_party/depot_tools/vpython3 third_party/node/node.py --output third_party/i18n/bake-strings.js front_end/core/i18n/locales",
+    "build": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/run_build.mjs",
+    "check-external-links": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/check_external_links.js",
+    "collect-strings": "third_party/depot_tools/vpython3 third_party/node/node.py --output third_party/i18n/collect-strings.js front_end",
+    "components-server": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/component_server/server.js",
+    "debug-webtest": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/npm_test.js --debug-devtools",
     "generate-protocol-resources": "scripts/deps/generate_protocol_resources.py && git cl format --js",
     "install-deps": "scripts/deps/manage_node_deps.py",
-    "lint": "vpython3 third_party/node/node.py --output --experimental-strip-types --no-warnings=ExperimentalWarning scripts/test/run_lint_check.mjs",
+    "lint": "third_party/depot_tools/vpython3 third_party/node/node.py --output --experimental-strip-types --no-warnings=ExperimentalWarning scripts/test/run_lint_check.mjs",
     "prebuild": "gn gen out/Default",
     "rdb": "rdb stream -new -realm chromium:public --",
-    "start": "vpython3 third_party/node/node.py --output scripts/run_start.mjs",
-    "webtest": "vpython3 third_party/node/node.py --output scripts/npm_test.js",
-    "watch": "vpython3 third_party/node/node.py --output scripts/watch_build.js",
-    "test": "vpython3 third_party/node/node.py --output scripts/run_on_target.mjs gen/test/run.js"
+    "start": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/run_start.mjs",
+    "webtest": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/npm_test.js",
+    "watch": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/watch_build.js",
+    "test": "third_party/depot_tools/vpython3 third_party/node/node.py --output scripts/run_on_target.mjs gen/test/run.js"
   },
   "devDependencies": {
     "@rollup/plugin-node-resolve": "15.3.0",
diff --git a/scripts/devtools_build.mjs b/scripts/devtools_build.mjs
index 9062fa3..e6b794e 100644
--- a/scripts/devtools_build.mjs
+++ b/scripts/devtools_build.mjs
@@ -9,9 +9,10 @@
 import util from 'node:util';
 
 import {
-  autoninjaExecutablePath,
-  gnExecutablePath,
+  autoninjaPyPath,
+  gnPyPath,
   rootPath,
+  vpython3ExecutablePath,
 } from './devtools_paths.js';
 
 const execFile = util.promisify(childProcess.execFile);
@@ -220,8 +221,8 @@
   if (!outDirStat?.isDirectory()) {
     // Use GN to (optionally create and) initialize the |outDir|.
     try {
-      const gnExe = gnExecutablePath();
-      const gnArgs = ['-q', 'gen', outDir];
+      const gnExe = vpython3ExecutablePath();
+      const gnArgs = [gnPyPath(), '-q', 'gen', outDir];
       await execFile(gnExe, gnArgs);
     } catch (cause) {
       throw new BuildError(BuildStep.GN, {cause, outDir, target});
@@ -242,8 +243,8 @@
   // since we might be running in a full Chromium checkout and certainly don't
   // want to build all of Chromium first.
   try {
-    const autoninjaExe = autoninjaExecutablePath();
-    const autoninjaArgs = ['-C', outDir, 'devtools_all_files'];
+    const autoninjaExe = vpython3ExecutablePath();
+    const autoninjaArgs = [autoninjaPyPath(), '-C', outDir, 'devtools_all_files'];
     await execFile(autoninjaExe, autoninjaArgs, {signal});
   } catch (cause) {
     if (cause.name === 'AbortError') {
diff --git a/scripts/devtools_paths.js b/scripts/devtools_paths.js
index 9795ae6..ef5fb76 100644
--- a/scripts/devtools_paths.js
+++ b/scripts/devtools_paths.js
@@ -127,12 +127,16 @@
   return path.join(devtoolsRootPath(), 'node_modules');
 }
 
-function autoninjaExecutablePath() {
-  return path.join(thirdPartyPath(), 'depot_tools', 'autoninja');
+function autoninjaPyPath() {
+  return path.join(thirdPartyPath(), 'depot_tools', 'autoninja.py');
 }
 
-function gnExecutablePath() {
-  return path.join(thirdPartyPath(), 'depot_tools', 'gn');
+function vpython3ExecutablePath() {
+  return path.join(thirdPartyPath(), 'depot_tools', os.platform() === 'win32' ? 'vpython3.bat' : 'vpython3');
+}
+
+function gnPyPath() {
+  return path.join(thirdPartyPath(), 'depot_tools', 'gn.py');
 }
 
 function stylelintExecutablePath() {
@@ -172,11 +176,11 @@
 }
 
 module.exports = {
-  autoninjaExecutablePath,
+  autoninjaPyPath,
   devtoolsRootPath,
   downloadedChromeBinaryPath,
   isInChromiumDirectory,
-  gnExecutablePath,
+  gnPyPath,
   litAnalyzerExecutablePath,
   mochaExecutablePath,
   nodeModulesPath,
@@ -185,4 +189,5 @@
   stylelintExecutablePath,
   thirdPartyPath,
   tsconfigJsonPath,
+  vpython3ExecutablePath,
 };
diff --git a/scripts/run_build.mjs b/scripts/run_build.mjs
index 043c7b5..7748578 100644
--- a/scripts/run_build.mjs
+++ b/scripts/run_build.mjs
@@ -54,7 +54,7 @@
 
 // Perform an initial build (unless we should skip).
 if (!skipInitialBuild) {
-  spinner.text = 'Building…';
+  spinner.start('Building…');
   try {
     const {time} = await build(target);
     spinner.succeed(`Build ready (${timeFormatter.format(time)})`);
@@ -64,6 +64,8 @@
   }
 }
 
+spinner.stop();
+
 if (watch) {
   let timeoutId = -1;
   let buildPromise = Promise.resolve();
diff --git a/scripts/run_start.mjs b/scripts/run_start.mjs
index 26bd32e..397c4eb 100644
--- a/scripts/run_start.mjs
+++ b/scripts/run_start.mjs
@@ -115,11 +115,14 @@
 }
 
 // Perform the initial build.
-childProcess.spawnSync(process.argv[0], [runBuildPath, `--target=${target}`], {
+const {status} = childProcess.spawnSync(process.argv[0], [runBuildPath, `--target=${target}`], {
   cwd,
   env,
   stdio: 'inherit',
 });
+if (status !== 0) {
+  process.exit(1);
+}
 
 // Launch Chrome with our custom DevTools front-end.
 function start() {