1 | // Copyright 2020 The Chromium Authors. All rights reserved.
|
2 | // Use of this source code is governed by a BSD-style license that can be
|
3 | // found in the LICENSE file.
|
4 |
|
5 | /**
|
6 | * This file contains helpers to load the correct path to various scripts and
|
7 | * directories. It is the Node equivalent of devtools_paths.py.
|
8 | *
|
9 | * Note that not all paths implemented in devtools_paths.py are implemented
|
10 | * here. Please add any paths you need that are missing.
|
11 | */
|
12 |
|
13 | const path = require('path');
|
14 | const os = require('os');
|
15 |
|
16 | /**
|
17 | * You would think we can use __filename here but we cannot because __filename
|
18 | * has any symlinks resolved. This means we can't use it to tell if the user is
|
19 | * using the external repo with a standalone build setup because the symlink
|
20 | * from chromium/src/third_party/devtools-frontend => devtools-frontend repo
|
21 | * gets resolved by Node before it gives us __filename.
|
22 | *
|
23 | * We can use process.argv[1], which is the path to the file currently being
|
24 | * executed without any symlinks resolution. If we assume that file is always in
|
25 | * the devtools-frontend repository/directory, we can use that file as the
|
26 | * starting point for figuring out if we're in Chromium or not. until we find
|
27 | * the scripts directory, at which point we've found this file and can use it
|
28 | * for all subsequent logic.
|
29 | *
|
30 | * e.g. the user executes a script: scripts/test/run_lint_check_css.js
|
31 | *
|
32 | * process.argv[1] =
|
33 | * /full/path/devtools-frontend/src/scripts/test/run_lint_check_css.js
|
34 | */
|
35 | const PATH_TO_EXECUTED_FILE = process.argv[1];
|
36 |
|
37 | function pathIsMostTopLevelPath(filePath) {
|
38 | /**
|
39 | * On Linux/Mac, if we do path.dirname(X) as many times as possible, it will
|
40 | * eventually equal `/`. On Windows, it will end up equalling C:\, and
|
41 | * path.dirname('C:\') === 'C:\', so we use that to figure out if we've made
|
42 | * it as far up the tree as we can.
|
43 | */
|
44 | return filePath === path.sep || path.dirname(filePath) === filePath;
|
45 | }
|
46 |
|
47 | const _lookUpCaches = new Map(
|
48 | [['chromium', null]],
|
49 | );
|
50 | /**
|
51 | * This function figures out if we're within a chromium directory, and therefore
|
52 | * we are in the integrated workflow mode, rather than working in a standalone
|
53 | * devtools-frontend repository.
|
54 | */
|
55 | function isInChromiumDirectory() {
|
56 | const cached = _lookUpCaches.get('chromium');
|
57 | if (cached) {
|
58 | return cached;
|
59 | }
|
60 |
|
61 | const normalizedPath = PATH_TO_EXECUTED_FILE.split(path.sep).join('/');
|
62 | const isInChromium = normalizedPath.includes('chromium/src/third_party/devtools-frontend');
|
63 | const potentialChromiumDir = PATH_TO_EXECUTED_FILE.substring(0, PATH_TO_EXECUTED_FILE.indexOf('chromium') + 8);
|
64 | const result = {isInChromium, chromiumDirectory: potentialChromiumDir};
|
65 | _lookUpCaches.set('chromium', result);
|
66 | return result;
|
67 | }
|
68 | /**
|
69 | * Returns the path to the root of the devtools-frontend repository.
|
70 | *
|
71 | * If we're in Chromium, this will be /path/to/chromium/src/third_party/devtools-frontend/src
|
72 | * If it's standalone, it will be /path/to/devtools-frontend
|
73 | */
|
74 | function devtoolsRootPath() {
|
75 | const nodeScriptFileThatIsBeingExecuted = PATH_TO_EXECUTED_FILE;
|
76 | let devtoolsRootFolder = nodeScriptFileThatIsBeingExecuted;
|
77 | while (path.basename(devtoolsRootFolder) !== 'devtools-frontend') {
|
78 | devtoolsRootFolder = path.dirname(devtoolsRootFolder);
|
79 | // We reached the end and can't find devtools-frontend.
|
80 | if (pathIsMostTopLevelPath(devtoolsRootFolder)) {
|
81 | throw new Error(
|
82 | 'Could not find devtools-frontend in path. If you have cloned the repository to a different directory name, it will not work.');
|
83 | }
|
84 | }
|
85 | // In Chromium the path to the source code for devtools-frontend is:
|
86 | // third_party/devtools-frontend/src
|
87 | const {isInChromium} = isInChromiumDirectory();
|
88 | if (isInChromium) {
|
89 | return path.join(devtoolsRootFolder, 'src');
|
90 | }
|
91 |
|
92 | // But if you're in a standalone repo it's just the devtools-frontend folder.
|
93 | return devtoolsRootFolder;
|
94 | }
|
95 |
|
96 | /**
|
97 | * Returns the path to the root of the main repository we're in.
|
98 | * if we're in Chromium, this is /path/to/chromium/src
|
99 | * if we're in standalone, this is /path/to/devtools-frontend
|
100 | *
|
101 | * Note this is different to devtoolsRootPath(), which always returns the path
|
102 | * to the devtools-frontend source code.
|
103 | */
|
104 | function rootPath() {
|
105 | const {isInChromium, chromiumDirectory} = isInChromiumDirectory();
|
106 | if (isInChromium) {
|
107 | return path.join(chromiumDirectory, 'src');
|
108 | }
|
109 | return devtoolsRootPath();
|
110 | }
|
111 |
|
112 | /**
|
113 | * Path to the third_party directory. Used because if we're running in Chromium
|
114 | * land we need to use e.g. the Node executable from Chromium's third_party
|
115 | * directory, not from the devtools-frontend third_party directory.
|
116 | */
|
117 | function thirdPartyPath() {
|
118 | return path.join(rootPath(), 'third_party');
|
119 | }
|
120 |
|
121 | function nodePath() {
|
122 | const paths = {
|
123 | 'darwin': path.join('mac', 'node-darwin-x64', 'bin', 'node'),
|
124 | 'linux': path.join('linux', 'node-linux-x64', 'bin', 'node'),
|
125 | 'win32': path.join('win', 'node.exe'),
|
126 | };
|
127 | return path.join(thirdPartyPath(), 'node', paths[os.platform()]);
|
128 | }
|
129 |
|
130 | /**
|
131 | * The path to the devtools-frontend node_modules folder.
|
132 | */
|
133 | function nodeModulesPath() {
|
134 | return path.join(devtoolsRootPath(), 'node_modules');
|
135 | }
|
136 |
|
137 | function stylelintExecutablePath() {
|
138 | return path.join(nodeModulesPath(), 'stylelint', 'bin', 'stylelint.js');
|
139 | }
|
140 |
|
141 | function mochaExecutablePath() {
|
142 | return path.join(nodeModulesPath(), 'mocha', 'bin', 'mocha');
|
143 | }
|
144 |
|
145 | function downloadedChromeBinaryPath() {
|
146 | const paths = {
|
147 | 'linux': path.join('chrome-linux', 'chrome'),
|
148 | 'darwin': path.join('chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'),
|
149 | 'win32': path.join('chrome-win', 'chrome.exe'),
|
150 | };
|
151 | return path.join(thirdPartyPath(), 'chrome', paths[os.platform()]);
|
152 | }
|
153 |
|
154 | module.exports = {
|
155 | thirdPartyPath,
|
156 | nodePath,
|
157 | devtoolsRootPath,
|
158 | nodeModulesPath,
|
159 | mochaExecutablePath,
|
160 | stylelintExecutablePath,
|
161 | downloadedChromeBinaryPath
|
162 | };
|