build-strap 5.0.0-dev.66 → 5.0.0-dev.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "build-strap",
3
- "version": "5.0.0-dev.66",
3
+ "version": "5.0.0-dev.70",
4
4
  "description": "Node scripts for building things",
5
5
  "license": "MIT",
6
6
  "authors": [
package/src/brew.js CHANGED
@@ -2,7 +2,7 @@ import fs from 'fs-extra';
2
2
  import os from 'os';
3
3
  import path from 'path';
4
4
  import { spawn } from './cp.js';
5
- import { appendToEnvProfile, cmdExists, ensureProcessPathEnvIncludes, } from './env.js';
5
+ import { appendToEnv, cmdExists, ensureProcessPathEnvIncludes, } from './env.js';
6
6
  const brewPath = async () => {
7
7
  for (const testPath of [
8
8
  '/opt/homebrew/bin/brew',
@@ -26,7 +26,7 @@ const brewPathExists = async () => {
26
26
  };
27
27
  const appendBrewShellEnv = async (opts) => {
28
28
  const brewDir = path.dirname(await brewPath());
29
- await appendToEnvProfile(`\neval "$(${brewDir}/brew shellenv)"`, opts);
29
+ await appendToEnv(`\neval "$(${brewDir}/brew shellenv)"`, opts);
30
30
  ensureProcessPathEnvIncludes(brewDir);
31
31
  };
32
32
  export const ensureBrewInstalled = async () => {
package/src/docker.d.ts CHANGED
@@ -68,4 +68,5 @@ export declare function copyFilesFromDockerImage({ filePaths, ignoreErrors, imag
68
68
  export declare const dockerIsRunning: () => Promise<boolean>;
69
69
  export declare const ensureDockerRunning: (timeoutSeconds?: number) => Promise<void>;
70
70
  export declare const ensureDockerInstalled: () => Promise<void>;
71
+ export declare const ensureDockerForMacConfigured: (desiredConfig?: Record<string, unknown> | null | undefined) => Promise<void>;
71
72
  export {};
package/src/docker.js CHANGED
@@ -263,3 +263,34 @@ export const ensureDockerInstalled = async () => {
263
263
  }
264
264
  }
265
265
  };
266
+ export const ensureDockerForMacConfigured = async (desiredConfig) => {
267
+ if (isMac()) {
268
+ if (!desiredConfig) {
269
+ buildLog('Skipping docker configuration due to empty config value');
270
+ return;
271
+ }
272
+ const configPath = path.join(os.homedir(), '/Library/Group Containers/group.com.docker/settings.json');
273
+ await fs.ensureDir(path.dirname(configPath));
274
+ if (!(await fs.pathExists(configPath))) {
275
+ // Must run Docker at least once to create the config file
276
+ await ensureDockerRunning();
277
+ }
278
+ if (!(await fs.pathExists(configPath))) {
279
+ throw new Error('Failed to locate the Docker config file');
280
+ }
281
+ const existingConfig = await fs.readJson(configPath);
282
+ if (!Object.entries(desiredConfig).every(([key, value]) => existingConfig[key] === value)) {
283
+ buildLog('Adjusting Docker config...');
284
+ await fs.writeJson(configPath, {
285
+ ...existingConfig,
286
+ ...desiredConfig,
287
+ }, { spaces: 2 });
288
+ if (await dockerIsRunning()) {
289
+ // Restart the Docker app
290
+ buildLog('Killing Docker...');
291
+ await spawn('osascript', ['-e', `quit app "Docker"`]);
292
+ await ensureDockerRunning();
293
+ }
294
+ }
295
+ }
296
+ };
package/src/env.d.ts CHANGED
@@ -6,6 +6,7 @@ export declare const isArm: () => boolean;
6
6
  export declare const isAppleSilicon: () => boolean;
7
7
  export declare const shellType: () => string | null;
8
8
  export declare const shellEnvFile: () => string | null;
9
+ export declare const shellProfile: () => string | null;
9
10
  export declare const whichCmd: (cmd: string) => Promise<null | string>;
10
11
  export declare const cmdExists: (cmd: string) => Promise<boolean>;
11
12
  interface ReadShellEnvVarOptions {
@@ -14,13 +15,13 @@ interface ReadShellEnvVarOptions {
14
15
  shell?: string;
15
16
  }
16
17
  export declare const readShellEnvVar: (name: string, { refreshEnv, envFile, shell, }?: ReadShellEnvVarOptions) => Promise<string | null>;
17
- export interface AppendToEnvProfileOptions {
18
+ export interface AppendToEnvOptions {
18
19
  envFile?: string | null;
19
20
  testContent?: string | StringGenFn;
20
21
  }
21
- export declare const appendToEnvProfile: (content: string | StringGenFn, { envFile, testContent }?: AppendToEnvProfileOptions) => Promise<void>;
22
- export declare const appendEnvVarToProfile: (name: string, value: string, { envFile }?: ReadShellEnvVarOptions) => Promise<void>;
22
+ export declare const appendToEnv: (content: string | StringGenFn, { envFile, testContent }?: AppendToEnvOptions) => Promise<void>;
23
+ export declare const appendEnvVar: (name: string, value: string, { envFile }?: ReadShellEnvVarOptions) => Promise<void>;
23
24
  export declare const ensureEnvVarValue: (name: string, value: string, opts?: ReadShellEnvVarOptions | undefined) => Promise<void>;
24
- export declare const ensureEnvVarSet: (name: string, getValue: () => Promise<string>) => Promise<void>;
25
+ export declare const ensureEnvVarSet: (name: string, getValue: () => Promise<string>, opts?: ReadShellEnvVarOptions | undefined) => Promise<void>;
25
26
  export declare const ensureProcessPathEnvIncludes: (binPath: string) => void;
26
27
  export {};
package/src/env.js CHANGED
@@ -27,6 +27,16 @@ const cacheString = (key, fn) => {
27
27
  };
28
28
  export const shellType = () => cacheString('shellType', () => os.userInfo().shell.split('/').pop() || null);
29
29
  export const shellEnvFile = () => cacheString('shellEnvFile', () => {
30
+ switch (shellType()) {
31
+ case 'zsh':
32
+ return path.join(os.homedir(), '.zshrc');
33
+ case 'bash':
34
+ return path.join(os.homedir(), '.bashrc');
35
+ default:
36
+ return null;
37
+ }
38
+ });
39
+ export const shellProfile = () => cacheString('shellProfile', () => {
30
40
  switch (shellType()) {
31
41
  case 'zsh':
32
42
  return path.join(os.homedir(), '.zprofile');
@@ -51,7 +61,7 @@ export const whichCmd = async (cmd) => {
51
61
  return binPath;
52
62
  };
53
63
  export const cmdExists = async (cmd) => !!whichCmd(cmd);
54
- export const readShellEnvVar = async (name, { refreshEnv = false, envFile = shellEnvFile(), shell = os.userInfo().shell, } = {}) => {
64
+ export const readShellEnvVar = async (name, { refreshEnv = true, envFile = shellEnvFile(), shell = os.userInfo().shell, } = {}) => {
55
65
  if (refreshEnv && (!envFile || !(await fs.pathExists(envFile)))) {
56
66
  throw new Error(`Could not find shell env file: ${envFile}`);
57
67
  }
@@ -64,25 +74,25 @@ export const readShellEnvVar = async (name, { refreshEnv = false, envFile = shel
64
74
  return null;
65
75
  }
66
76
  };
67
- export const appendToEnvProfile = async (content, { envFile = shellEnvFile(), testContent } = {}) => {
77
+ export const appendToEnv = async (content, { envFile = shellEnvFile(), testContent } = {}) => {
68
78
  if (!envFile) {
69
79
  throw new Error('envFile must be set');
70
80
  }
71
81
  await appendIfMissing(envFile, content, testContent);
72
82
  };
73
- export const appendEnvVarToProfile = async (name, value, { envFile = shellEnvFile() } = {}) => appendToEnvProfile(`\nexport ${name}=${value}`, { envFile });
83
+ export const appendEnvVar = async (name, value, { envFile = shellEnvFile() } = {}) => appendToEnv(`\nexport ${name}=${value}`, { envFile });
74
84
  export const ensureEnvVarValue = async (name, value, opts) => {
75
85
  const currentValue = await readShellEnvVar(name, opts);
76
86
  if (currentValue !== value) {
77
- await appendEnvVarToProfile(name, value, opts);
87
+ await appendEnvVar(name, value, opts);
78
88
  }
79
89
  process.env[name] = value;
80
90
  };
81
- export const ensureEnvVarSet = async (name, getValue) => {
82
- const currentValue = await readShellEnvVar(name);
91
+ export const ensureEnvVarSet = async (name, getValue, opts) => {
92
+ const currentValue = await readShellEnvVar(name, opts);
83
93
  if (!currentValue) {
84
94
  const newValue = await getValue();
85
- await appendEnvVarToProfile(name, newValue);
95
+ await appendEnvVar(name, newValue, opts);
86
96
  process.env[name] = newValue;
87
97
  }
88
98
  };
package/src/gh.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { SpawnOptions } from './cp.js';
2
2
  export declare const gh: (args: string[], options?: SpawnOptions | undefined) => Promise<import("./cp.js").SpawnResult>;
3
3
  export declare const ghRepoClone: (repo: string, repoDir: string) => Promise<void>;
4
+ export declare const ensureGhRepo: (repo: string, rootDir?: string) => Promise<void>;
4
5
  export declare const ensureGhAuthLogin: ({ host, scopes, }?: {
5
6
  host?: string | undefined;
6
7
  scopes?: string | undefined;
package/src/gh.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import fs from 'fs-extra';
2
+ import path from 'path';
2
3
  import { spawn } from './cp.js';
3
4
  import { buildLog } from './run.js';
4
5
  import { ensureSshKeyGenerated } from './ssh.js';
@@ -8,6 +9,13 @@ export const ghRepoClone = async (repo, repoDir) => {
8
9
  stdio: 'inherit',
9
10
  });
10
11
  };
12
+ export const ensureGhRepo = async (repo, rootDir = '.') => {
13
+ const repoDir = path.join(rootDir, repo);
14
+ if (!(await fs.pathExists(repoDir))) {
15
+ buildLog(`${repo} not found, cloning...`);
16
+ await ghRepoClone(repo, repoDir);
17
+ }
18
+ };
11
19
  export const ensureGhAuthLogin = async ({ host = 'github.com', scopes, } = {}) => {
12
20
  const configured = (await gh(['auth', 'status'], { rejectOnErrorCode: false })).code === 0;
13
21
  if (!configured) {