blob: e8025acca76c5a8bbff92dd071ff12c43ebbacfc [file] [log] [blame]
Jack Franklin65c824b2021-01-14 14:34:23 +00001// 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
13const path = require('path');
14const os = require('os');
15
16/**
17 * You would think we can use __filename here but we cannot because __filename
Jack Franklinbc302342021-01-18 10:03:30 +000018 * 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.
Jack Franklin65c824b2021-01-14 14:34:23 +000022 *
Jack Franklinbc302342021-01-18 10:03:30 +000023 * 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
Jack Franklin65c824b2021-01-14 14:34:23 +000034 */
Jack Franklinbc302342021-01-18 10:03:30 +000035const PATH_TO_EXECUTED_FILE = process.argv[1];
Jack Franklin65c824b2021-01-14 14:34:23 +000036
Jack Franklinbc302342021-01-18 10:03:30 +000037function 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;
Jack Franklin65c824b2021-01-14 14:34:23 +000045}
46
Jack Franklinbc302342021-01-18 10:03:30 +000047
48const _lookUpCaches = new Map(
49 [['chromium', null]],
50);
51/**
52 * This function figures out if we're within a chromium directory, and therefore
53 * we are in the integrated workflow mode, rather than working in a standalone
54 * devtools-frontend repository.
55 */
56function isInChromiumDirectory() {
57 const cached = _lookUpCaches.get('chromium');
58 if (cached) {
59 return cached;
60 }
61
62 let potentialChromiumDir = PATH_TO_EXECUTED_FILE;
63 let isInChromium = false;
64 while (!pathIsMostTopLevelPath(potentialChromiumDir)) {
65 potentialChromiumDir = path.dirname(potentialChromiumDir);
66 if (path.basename(potentialChromiumDir) === 'chromium') {
67 isInChromium = true;
68 break;
69 }
70 }
71 const result = {isInChromium, chromiumDirectory: potentialChromiumDir};
72 _lookUpCaches.set('chromium', result);
73 return result;
74}
75/**
76 * Returns the path to the root of the devtools-frontend repository.
77 *
78 * If we're in Chromium, this will be /path/to/chromium/src/third_party/devtools-frontend/src
79 * If it's standalone, it will be /path/to/devtools-frontend
80 */
81function devtoolsRootPath() {
82 const nodeScriptFileThatIsBeingExecuted = PATH_TO_EXECUTED_FILE;
83 let devtoolsRootFolder = nodeScriptFileThatIsBeingExecuted;
84 while (path.basename(devtoolsRootFolder) !== 'devtools-frontend') {
85 devtoolsRootFolder = path.dirname(devtoolsRootFolder);
86 // We reached the end and can't find devtools-frontend.
87 if (pathIsMostTopLevelPath(devtoolsRootFolder)) {
88 throw new Error(
89 'Could not find devtools-frontend in path. If you have cloned the repository to a different directory name, it will not work.');
90 }
91 }
92 // In Chromium the path to the source code for devtools-frontend is:
93 // third_party/devtools-frontend/src
94 const {isInChromium} = isInChromiumDirectory();
95 if (isInChromium) {
96 return path.join(devtoolsRootFolder, 'src');
97 }
98
99 // But if you're in a standalone repo it's just the devtools-frontend folder.
100 return devtoolsRootFolder;
101}
102
103/**
104 * Returns the path to the root of the main repository we're in.
105 * if we're in Chromium, this is /path/to/chromium/src
106 * if we're in standalone, this is /path/to/devtools-frontend
107 *
108 * Note this is different to devtoolsRootPath(), which always returns the path
109 * to the devtools-frontend source code.
110 */
111function rootPath() {
112 const {isInChromium, chromiumDirectory} = isInChromiumDirectory();
113 if (isInChromium) {
114 return path.join(chromiumDirectory, 'src');
115 }
116 return devtoolsRootPath();
117}
118
119/**
120 * Path to the third_party directory. Used because if we're running in Chromium
121 * land we need to use e.g. the Node executable from Chromium's third_party
122 * directory, not from the devtools-frontend third_party directory.
123 */
Jack Franklin65c824b2021-01-14 14:34:23 +0000124function thirdPartyPath() {
Jack Franklinbc302342021-01-18 10:03:30 +0000125 return path.join(rootPath(), 'third_party');
Jack Franklin65c824b2021-01-14 14:34:23 +0000126}
127
128function nodePath() {
129 const paths = {
130 'darwin': path.join('mac', 'node-darwin-x64', 'bin', 'node'),
131 'linux': path.join('linux', 'node-linux-x64', 'bin', 'node'),
132 'win32': path.join('win', 'node.exe'),
133 };
Jack Franklinbc302342021-01-18 10:03:30 +0000134 return path.join(thirdPartyPath(), 'node', paths[os.platform()]);
Jack Franklin65c824b2021-01-14 14:34:23 +0000135}
136
Jack Franklinbc302342021-01-18 10:03:30 +0000137/**
138 * The path to the devtools-frontend node_modules folder.
139 */
Jack Franklin65c824b2021-01-14 14:34:23 +0000140function nodeModulesPath() {
141 return path.join(devtoolsRootPath(), 'node_modules');
142}
143
Jack Franklinbc302342021-01-18 10:03:30 +0000144function stylelintExecutablePath() {
145 return path.join(nodeModulesPath(), 'stylelint', 'bin', 'stylelint.js');
146}
147
Jack Franklin40b5fb62021-02-01 14:06:15 +0000148function downloadedChromeBinaryPath() {
149 const paths = {
150 'linux': path.join('chrome-linux', 'chrome'),
Tim van der Lippe51257fc2021-02-24 12:08:09 +0000151 'darwin': path.join('chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'),
Jack Franklin40b5fb62021-02-01 14:06:15 +0000152 'win32': path.join('chrome-win', 'chrome.exe'),
153 };
154 return path.join(thirdPartyPath(), 'chrome', paths[os.platform()]);
155}
156
Jack Franklinbc302342021-01-18 10:03:30 +0000157module.exports = {
158 thirdPartyPath,
159 nodePath,
160 devtoolsRootPath,
161 nodeModulesPath,
Jack Franklin40b5fb62021-02-01 14:06:15 +0000162 stylelintExecutablePath,
163 downloadedChromeBinaryPath
Jack Franklinbc302342021-01-18 10:03:30 +0000164};