blob: 42d240cc968b6d23831fbd35905693da2c8dad8b [file] [log] [blame]
Liviu Rau3f146242022-02-23 11:48:281#!/usr/bin/env vpython3
Mathias Bynens8555df02020-04-27 14:19:062#
Yang Guo4fd355c2019-09-19 08:59:033# Copyright 2019 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
Jack Franklincc58dfa2022-11-29 10:08:146
Yang Guo4fd355c2019-09-19 08:59:037"""
Peter Marshall9c4cbce2020-07-06 07:36:548Helper to manage DEPS. Use this script to update node_modules instead of
9running npm install manually. To upgrade a dependency, change the version
Jack Franklincc58dfa2022-11-29 10:08:1410number in DEPS below and run this script, which can be done with `npm run
11install-deps` locally.
Yang Guo4fd355c2019-09-19 08:59:0312"""
13
14import os
15import os.path as path
Yang Guo4fd355c2019-09-19 08:59:0316import json
Yang Guo91178352019-10-31 07:50:1917import subprocess
18import sys
Tim van der Lippe6d109a92021-02-16 16:00:3219from collections import OrderedDict
Yang Guo91178352019-10-31 07:50:1920
21scripts_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
22sys.path.append(scripts_path)
23
24import devtools_paths
Yang Guo4fd355c2019-09-19 08:59:0325
Paul Lewise184c4c2019-12-02 12:30:1526LICENSES = [
27 "MIT",
28 "Apache-2.0",
29 "BSD",
30 "BSD-2-Clause",
31 "BSD-3-Clause",
32 "CC0-1.0",
33 "CC-BY-3.0",
Mathias Bynens79e2cf02020-05-29 14:46:1734 "CC-BY-4.0",
Paul Lewise184c4c2019-12-02 12:30:1535 "ISC",
Tim van der Lippe1fe7f952021-01-05 12:41:0636 "MPL-2.0",
Tim van der Lippe6d109a92021-02-16 16:00:3237 "Python-2.0",
Johan Bay0c881d52022-02-01 19:42:4438 "W3C",
Paul Lewise184c4c2019-12-02 12:30:1539]
40
Yang Guo4fd355c2019-09-19 08:59:0341# List all DEPS here.
42DEPS = {
Tim van der Lippefe1b4262021-09-13 13:46:1443 "@istanbuljs/schema": "0.1.3",
Randolf Jungbcb3bc82023-06-26 16:30:1444 "@puppeteer/replay": "2.11.2",
Tim van der Lippe0150c2a2022-01-07 13:20:3745 "@types/chai": "4.3.0",
Simon Zünd0cc29a72023-03-22 05:44:4046 "@types/codemirror": "5.60.7",
Tim van der Lippef8c34ae2021-07-29 15:15:0547 "@types/estree": "0.0.50",
48 "@types/filesystem": "0.0.32",
Tim van der Lippe0150c2a2022-01-07 13:20:3749 "@types/istanbul-lib-coverage": "2.0.4",
Tim van der Lippea0dce6d2021-05-07 14:59:5050 "@types/istanbul-lib-instrument": "1.7.4",
51 "@types/istanbul-lib-report": "3.0.0",
52 "@types/istanbul-lib-source-maps": "4.0.1",
Tim van der Lippe4965ccd2021-06-02 15:37:4853 "@types/istanbul-reports": "3.0.1",
Tim van der Lippef8c34ae2021-07-29 15:15:0554 "@types/karma-chai-sinon": "0.1.16",
Nancy Li64037132022-11-22 15:32:2655 "@types/node": "18.11.9",
Tim van der Lippec581bb82021-11-23 16:44:0656 "@types/marked": "4.0.1",
Tim van der Lippef8c34ae2021-07-29 15:15:0557 "@types/mocha": "9.0.0",
Tim van der Lippe8fc2d462021-09-13 14:26:2858 "@types/rimraf": "3.0.2",
Tim van der Lippe0150c2a2022-01-07 13:20:3759 "@types/sinon": "10.0.6",
Johan Bay986acd02022-02-02 14:30:3760 "@types/webidl2": "23.13.6",
Jack Franklinb6e869c2023-06-02 13:30:1361 "@typescript-eslint/parser": "5.59.8",
62 "@typescript-eslint/eslint-plugin": "5.59.8",
Tim van der Lippe0b2df652021-06-10 09:44:5263 "@web/rollup-plugin-import-meta-assets": "1.0.7",
Tim van der Lippe0a9b84d2021-03-24 11:53:1564 "chai": "4.3.4",
Tim van der Lippeb693eb32022-01-07 13:50:5465 "chokidar": "3.5.2",
Tim van der Lippeb693eb32022-01-07 13:50:5466 "convert-source-map": "1.8.0",
Takuto Ikuta2e08a7d2022-01-27 02:01:2367
68 # This should be match with esbuild in DEPS.
Jack Franklin5ee20e32022-12-01 10:35:5469 "esbuild": "0.14.13",
Tim van der Lippedc4637c2020-11-13 15:30:3070 "escodegen": "2.0.0",
Jack Franklin5445f5c2022-07-13 12:23:1271 "eslint": "8.19.0",
Tim van der Lippe0ceb4652022-01-06 13:23:3672 "eslint-plugin-import": "2.25.4",
Tim van der Lippe10714b52021-11-08 15:17:3073 "eslint-plugin-lit-a11y": "2.1.0",
Tim van der Lippe0ceb4652022-01-06 13:23:3674 "eslint-plugin-mocha": "10.0.3",
Tim van der Lippe0124c682021-11-23 15:12:1075 "eslint-plugin-rulesdir": "0.2.1",
Jack Franklinfd72c072022-12-21 11:45:0176 "eslint-plugin-jsdoc": "39.6.4",
Tim van der Lippeb693eb32022-01-07 13:50:5477 "istanbul-lib-instrument": "5.1.0",
Tim van der Lippea0dce6d2021-05-07 14:59:5078 "istanbul-lib-report": "3.0.0",
Jack Franklin8f8ec222022-07-05 10:10:5279 "karma": "6.4.0",
Yang Guo4fd355c2019-09-19 08:59:0380 "karma-chai": "0.1.0",
81 "karma-chrome-launcher": "3.1.0",
Tim van der Lipped3425b92022-01-07 13:05:0982 "karma-coverage": "2.1.0",
Tim van der Lippee8c10002020-05-11 12:23:0383 "karma-mocha": "2.0.1",
Jan Schefflerc53174b2021-05-21 10:16:5584 "karma-mocha-reporter": "2.2.5",
Paul Lewis40e28672020-11-27 09:51:3785 "karma-sinon": "1.0.5",
Tim van der Lippe5226a882020-11-09 16:59:0486 "karma-sourcemap-loader": "0.3.8",
Paul Lewis34a16602020-11-20 16:05:4187 "karma-spec-reporter": "0.0.32",
Paul Lewise184c4c2019-12-02 12:30:1588 "license-checker": "25.0.1",
Tim van der Lipped3425b92022-01-07 13:05:0989 "mocha": "9.1.3",
Tim van der Lippe4cb09742022-01-07 13:25:0390 "postcss": "8.4.5",
Jack Franklina5fd0a42022-12-09 11:30:2491 "cssnano": "5.1.14",
Jack Franklina682d932022-12-16 11:52:0492 "cssnano-preset-lite": "2.1.3",
Randolf Jungbcb3bc82023-06-26 16:30:1493 "puppeteer-core": "20.7.3",
Tim van der Lippeb693eb32022-01-07 13:50:5494 "recast": "0.20.5",
Paul Lewisea0d7562020-02-12 10:59:0595 "rimraf": "3.0.2",
Tim van der Lippe0150c2a2022-01-07 13:20:3796 "rollup": "2.63.0",
Tim van der Lippe652ccb72021-05-27 16:07:1297 "rollup-plugin-minify-html-template-literals": "1.2.0",
Simon Zünd1bd98ee2023-04-04 12:15:1698 "rollup-plugin-sourcemaps": "0.6.2",
Tim van der Lippe59b55bb2020-11-13 15:46:0899 "rollup-plugin-terser": "7.0.2",
Tim van der Lipped3425b92022-01-07 13:05:09100 "sinon": "12.0.1",
Tim van der Lippeb693eb32022-01-07 13:50:54101 "source-map-support": "0.5.21",
Tim van der Lippe4cb09742022-01-07 13:25:03102 "stylelint": "14.2.0",
103 "stylelint-config-standard": "24.0.0",
Tim van der Lippeb693eb32022-01-07 13:50:54104 "svgo": "2.8.0",
Tim van der Lippe0150c2a2022-01-07 13:20:37105 "terser": "5.10.0",
Jack Franklin98d9d462023-06-02 11:26:24106 "typescript": "5.1.3",
Tim van der Lippeb693eb32022-01-07 13:50:54107 "ws": "8.4.0",
108 "yargs": "17.3.1",
Johan Bay986acd02022-02-02 14:30:37109 "glob": "7.1.7",
Victor Porof6e096922022-06-10 13:01:05110 "webidl2": "24.2.2",
111 "@webref/idl": "3.12.0",
Yang Guo4fd355c2019-09-19 08:59:03112}
113
Takuto Ikuta2e08a7d2022-01-27 02:01:23114ADDITIONAL_NPM_ARGS = [
115 # This is to avoid downloading esbuild-* package.
116 '--omit', 'optional', '--ignore-scripts'
117]
118
Tim van der Lippe6d109a92021-02-16 16:00:32119def load_json_file(location):
120 # By default, json load uses a standard Python dictionary, which is not ordered.
121 # To prevent subsequent invocations of this script to erroneously alter the order
122 # of keys defined in package.json files, we should use an `OrderedDict`. This
123 # ensures not only that we use a strict ordering, it will also make sure we maintain
124 # the order defined by the NPM packages themselves. That in turn is important, since
125 # NPM packages can define `exports`, where the order of entrypoints is crucial for
126 # how an NPM package is loaded. If you would change the order, it could break loading
127 # that package.
128 return json.load(location, object_pairs_hook=OrderedDict)
129
Paul Lewis66e12062019-12-02 12:04:54130def exec_command(cmd):
Yang Guo4fd355c2019-09-19 08:59:03131 try:
Peter Marshall9c4cbce2020-07-06 07:36:54132 new_env = os.environ.copy()
Peter Marshall9c4cbce2020-07-06 07:36:54133 cmd_proc_result = subprocess.check_call(cmd,
134 cwd=devtools_paths.root_path(),
135 env=new_env)
Tim van der Lippe35cca412020-04-06 12:03:38136 except Exception as error:
137 print(error)
Paul Lewis66e12062019-12-02 12:04:54138 return True
139
140 return False
Yang Guo4fd355c2019-09-19 08:59:03141
142
Paul Lewise184c4c2019-12-02 12:30:15143def ensure_licenses():
144 cmd = [
145 devtools_paths.node_path(),
146 devtools_paths.license_checker_path(),
147 '--onlyAllow',
148 ('%s' % (';'.join(LICENSES)))
149 ]
150
151 return exec_command(cmd)
152
153
Yang Guo4fd355c2019-09-19 08:59:03154def strip_private_fields():
155 # npm adds private fields which need to be stripped.
Yang Guo4fd355c2019-09-19 08:59:03156 packages = []
Liviu Rau3f146242022-02-23 11:48:28157 for root, _, filenames in os.walk(devtools_paths.node_modules_path()):
158 if 'package.json' in filenames:
159 packages.append(path.join(root, 'package.json'))
Yang Guo4fd355c2019-09-19 08:59:03160
161 for pkg in packages:
162 with open(pkg, 'r+') as pkg_file:
Yang Guo4fd355c2019-09-19 08:59:03163 try:
Tim van der Lippe6d109a92021-02-16 16:00:32164 pkg_data = load_json_file(pkg_file)
Tim van der Lippeece3c512022-03-08 15:07:28165 updated_pkg_data = pkg_data.copy()
Yang Guo4fd355c2019-09-19 08:59:03166
167 # Remove anything that begins with an underscore, as these are
168 # the private fields in a package.json
169 for key in pkg_data.keys():
Liviu Rau3f146242022-02-23 11:48:28170 if key.find('_') == 0:
Tim van der Lippeece3c512022-03-08 15:07:28171 updated_pkg_data.pop(key)
Yang Guo4fd355c2019-09-19 08:59:03172
173 pkg_file.truncate(0)
174 pkg_file.seek(0)
Tim van der Lippeece3c512022-03-08 15:07:28175 json.dump(updated_pkg_data, pkg_file, indent=2, separators=(',', ': '))
Mathias Bynens8604a982020-06-23 06:41:44176 pkg_file.write('\n')
Yang Guo4fd355c2019-09-19 08:59:03177 except:
Tim van der Lippeece3c512022-03-08 15:07:28178 print('Unable to fix: %s, %s' % (pkg, sys.exc_info()))
Yang Guo4fd355c2019-09-19 08:59:03179 return True
180
181 return False
182
183
Tim van der Lippe35cca412020-04-06 12:03:38184# Required to keep the package-lock.json in sync with the package.json dependencies
Paul Lewis66e12062019-12-02 12:04:54185def install_missing_deps():
186 with open(devtools_paths.package_lock_json_path(), 'r+') as pkg_lock_file:
187 try:
Tim van der Lippe6d109a92021-02-16 16:00:32188 pkg_lock_data = load_json_file(pkg_lock_file)
Liviu Rau3f146242022-02-23 11:48:28189 existing_deps = pkg_lock_data['dependencies']
Paul Lewis66e12062019-12-02 12:04:54190 new_deps = []
191
192 # Find any new DEPS and add them in.
193 for dep, version in DEPS.items():
Paul Lewise184c4c2019-12-02 12:30:15194 if not dep in existing_deps or not existing_deps[dep]['version'] == version:
Paul Lewis66e12062019-12-02 12:04:54195 new_deps.append("%s@%s" % (dep, version))
196
197 # Now install.
198 if len(new_deps) > 0:
Takuto Ikuta2e08a7d2022-01-27 02:01:23199 cmd = [
200 'npm',
201 'install',
202 '--save-dev',
203 ] + ADDITIONAL_NPM_ARGS
Paul Lewis66e12062019-12-02 12:04:54204 cmd.extend(new_deps)
205 return exec_command(cmd)
206
207 except Exception as exception:
Paul Lewise184c4c2019-12-02 12:30:15208 print('Unable to install: %s' % exception)
Paul Lewis66e12062019-12-02 12:04:54209 return True
210
211 return False
212
213
Paul Lewisd9039092019-11-27 17:06:23214def append_package_json_entries():
215 with open(devtools_paths.package_json_path(), 'r+') as pkg_file:
216 try:
Tim van der Lippe6d109a92021-02-16 16:00:32217 pkg_data = load_json_file(pkg_file)
Paul Lewisd9039092019-11-27 17:06:23218
219 # Replace the dev deps.
Liviu Rau3f146242022-02-23 11:48:28220 pkg_data['devDependencies'] = DEPS
Paul Lewisd9039092019-11-27 17:06:23221
222 pkg_file.truncate(0)
223 pkg_file.seek(0)
Tim van der Lippe6d109a92021-02-16 16:00:32224 json.dump(pkg_data, pkg_file, indent=2, separators=(',', ': '))
Mathias Bynens8604a982020-06-23 06:41:44225 pkg_file.write('\n')
Paul Lewisd9039092019-11-27 17:06:23226
227 except:
228 print('Unable to fix: %s' % sys.exc_info()[0])
229 return True
230 return False
231
232
Paul Lewis75090cf2019-10-25 13:13:11233def remove_package_json_entries():
234 with open(devtools_paths.package_json_path(), 'r+') as pkg_file:
235 try:
Tim van der Lippe6d109a92021-02-16 16:00:32236 pkg_data = load_json_file(pkg_file)
Paul Lewis75090cf2019-10-25 13:13:11237
238 # Remove the dependencies and devDependencies from the root package.json
239 # so that they can't be used to overwrite the node_modules managed by this file.
240 for key in pkg_data.keys():
Liviu Rau3f146242022-02-23 11:48:28241 if key.find('dependencies') == 0 or key.find(
242 'devDependencies') == 0:
Paul Lewis75090cf2019-10-25 13:13:11243 pkg_data.pop(key)
244
245 pkg_file.truncate(0)
246 pkg_file.seek(0)
Tim van der Lippe6d109a92021-02-16 16:00:32247 json.dump(pkg_data, pkg_file, indent=2, separators=(',', ': '))
Mathias Bynens8604a982020-06-23 06:41:44248 pkg_file.write('\n')
Paul Lewis75090cf2019-10-25 13:13:11249 except:
250 print('Unable to fix: %s' % pkg)
251 return True
252 return False
253
254
Tim van der Lippe1511efc2020-03-20 11:57:11255def addClangFormat():
256 with open(path.join(devtools_paths.node_modules_path(), '.clang-format'), 'w+') as clang_format_file:
257 try:
Tim van der Lippe6541ce62020-10-28 10:24:26258 clang_format_file.write('DisableFormat: true\n')
Tim van der Lippe1511efc2020-03-20 11:57:11259 except:
260 print('Unable to write .clang-format file')
261 return True
262 return False
263
264
Tim van der Lipped79d79b2020-05-27 14:55:46265def addOwnersFile():
266 with open(path.join(devtools_paths.node_modules_path(), 'OWNERS'),
267 'w+') as owners_file:
268 try:
Tim van der Lippe2e143872021-04-08 11:56:40269 owners_file.write('file://config/owner/INFRA_OWNERS\n')
Tim van der Lipped79d79b2020-05-27 14:55:46270 except:
271 print('Unable to write OWNERS file')
272 return True
273 return False
274
Tim van der Lippe6541ce62020-10-28 10:24:26275def addChromiumReadme():
276 with open(path.join(devtools_paths.node_modules_path(), 'README.chromium'),
277 'w+') as readme_file:
278 try:
279 readme_file.write('This directory hosts all packages downloaded from NPM that are used in either the build system or infrastructure scripts.\n')
280 readme_file.write('If you want to make any changes to this directory, please see "scripts/deps/manage_node_deps.py".\n')
281 except:
282 print('Unable to write README.chromium file')
283 return True
284 return False
285
Tim van der Lipped79d79b2020-05-27 14:55:46286
Tim van der Lippe35cca412020-04-06 12:03:38287def run_npm_command(npm_command_args=None):
Paul Lewis66e12062019-12-02 12:04:54288 for (name, version) in DEPS.items():
Liviu Rau3f146242022-02-23 11:48:28289 if (version.find('^') == 0):
Paul Lewis66e12062019-12-02 12:04:54290 print('Versions must be locked to a specific version; remove ^ from the start of the version.')
291 return True
Yang Guo4fd355c2019-09-19 08:59:03292
Tim van der Lippe35cca412020-04-06 12:03:38293 run_custom_command = npm_command_args is not None
294
Paul Lewis66e12062019-12-02 12:04:54295 if append_package_json_entries():
296 return True
297
298 if install_missing_deps():
Paul Lewisd9039092019-11-27 17:06:23299 return True
300
Tim van der Lippee44bf092020-12-01 12:15:45301 runs_analysis_command = False
302
303 if run_custom_command:
304 runs_analysis_command = npm_command_args[:1] == [
305 'outdated'
Tim van der Lippe38208902021-05-11 15:37:59306 ] or npm_command_args[:1] == ['audit'
307 ] or npm_command_args[:1] == ['ls']
Tim van der Lippee44bf092020-12-01 12:15:45308
Tim van der Lippe35cca412020-04-06 12:03:38309 # By default, run the CI version of npm, which prevents updates to the versions of modules.
Tim van der Lippee44bf092020-12-01 12:15:45310 # However, when we are analyzing the installed NPM dependencies, we don't need to run
311 # the installation process again.
Tim van der Lippeb475b812021-02-19 11:05:31312 if not runs_analysis_command:
Takuto Ikuta2e08a7d2022-01-27 02:01:23313 if exec_command([
314 'npm',
315 'ci',
316 ] + ADDITIONAL_NPM_ARGS):
Tim van der Lippeb475b812021-02-19 11:05:31317 return True
Tim van der Lippe459f4022021-02-19 12:09:57318
Tim van der Lippeb475b812021-02-19 11:05:31319 # To minimize disk usage for Chrome DevTools node_modules, always try to dedupe dependencies.
320 # We need to perform this every time, as the order of dependencies added could lead to a
321 # non-optimal dependency tree, resulting in unnecessary disk usage.
Takuto Ikuta2e08a7d2022-01-27 02:01:23322 if exec_command([
323 'npm',
324 'dedupe',
325 ] + ADDITIONAL_NPM_ARGS):
Tim van der Lippeb475b812021-02-19 11:05:31326 return True
Yang Guo4fd355c2019-09-19 08:59:03327
Tim van der Lippe35cca412020-04-06 12:03:38328 if run_custom_command:
329 custom_command_result = exec_command(['npm'] + npm_command_args)
330
331 if remove_package_json_entries():
332 return True
333
Paul Lewis66e12062019-12-02 12:04:54334 if strip_private_fields():
Paul Lewis75090cf2019-10-25 13:13:11335 return True
336
Tim van der Lippe1511efc2020-03-20 11:57:11337 if addClangFormat():
338 return True
339
Tim van der Lipped79d79b2020-05-27 14:55:46340 if addOwnersFile():
341 return True
342
Tim van der Lippe6541ce62020-10-28 10:24:26343 if addChromiumReadme():
344 return True
345
Tim van der Lippe35cca412020-04-06 12:03:38346 if run_custom_command:
347 return custom_command_result
348
Paul Lewise184c4c2019-12-02 12:30:15349 return ensure_licenses()
Yang Guo4fd355c2019-09-19 08:59:03350
351
Tim van der Lippe35cca412020-04-06 12:03:38352npm_args = None
353
354if (len(sys.argv[1:]) > 0):
355 npm_args = sys.argv[1:]
356
357npm_errors_found = run_npm_command(npm_args)
Yang Guo4fd355c2019-09-19 08:59:03358
359if npm_errors_found:
Tim van der Lippe35cca412020-04-06 12:03:38360 print('npm command failed')
361 exit(1)