UNPKG

2.4 kBPlain TextView Raw
1import debug from "debug";
2import findUp from "find-up";
3import path from "path";
4
5const log = debug("buidler:core:execution-mode");
6
7/**
8 * This module defines different Buidler execution modes and autodetects them.
9 *
10 * IMPORTANT: This will have to be revisited once Yarn PnP and npm's tink get
11 * widely adopted.
12 */
13export enum ExecutionMode {
14 EXECUTION_MODE_TS_NODE_TESTS,
15 EXECUTION_MODE_LINKED,
16 EXECUTION_MODE_GLOBAL_INSTALLATION,
17 EXECUTION_MODE_LOCAL_INSTALLATION,
18}
19
20const workingDirectoryOnLoad = process.cwd();
21
22export function getExecutionMode(): ExecutionMode {
23 const isInstalled = __filename.includes("node_modules");
24
25 if (!isInstalled) {
26 // When running the tests with ts-node we set the CWD to the root of
27 // buidler-core. We could check if the __filename ends with .ts
28 if (__dirname.startsWith(workingDirectoryOnLoad)) {
29 return ExecutionMode.EXECUTION_MODE_TS_NODE_TESTS;
30 }
31
32 return ExecutionMode.EXECUTION_MODE_LINKED;
33 }
34
35 try {
36 if (require("is-installed-globally")) {
37 return ExecutionMode.EXECUTION_MODE_GLOBAL_INSTALLATION;
38 }
39 } catch (error) {
40 log(
41 "Failed to load is-installed-globally. Using alternative local installation detection\n",
42 error
43 );
44
45 if (!alternativeIsLocalInstallation()) {
46 return ExecutionMode.EXECUTION_MODE_GLOBAL_INSTALLATION;
47 }
48 }
49
50 return ExecutionMode.EXECUTION_MODE_LOCAL_INSTALLATION;
51}
52
53/**
54 * Checks whether we're using Buidler in development mode (that is, we're working _on_ Buidler).
55 */
56export function isLocalDev(): boolean {
57 const executionMode = getExecutionMode();
58
59 return (
60 executionMode === ExecutionMode.EXECUTION_MODE_LINKED ||
61 executionMode === ExecutionMode.EXECUTION_MODE_TS_NODE_TESTS
62 );
63}
64
65/**
66 * This is a somewhat more limited detection, but we use it if
67 * is-installed-globally fails.
68 *
69 * If a user installs buidler locally, and executes it from outside the
70 * directory that contains the `node_module` with the installation, this will
71 * fail and return `false`.
72 */
73function alternativeIsLocalInstallation(): boolean {
74 let cwd = workingDirectoryOnLoad;
75
76 while (true) {
77 const nodeModules = findUp.sync("node_modules", { cwd });
78
79 if (nodeModules === null) {
80 return false;
81 }
82
83 if (__dirname.startsWith(nodeModules)) {
84 return true;
85 }
86
87 cwd = path.join(nodeModules, "..", "..");
88 }
89}