build-strap 4.0.0 → 4.1.0-dev.60
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 +7 -57
- package/{dist/src → src}/ant.d.ts +0 -0
- package/{dist/src → src}/ant.js +0 -0
- package/src/brew.d.ts +6 -0
- package/src/brew.js +74 -0
- package/{dist/src → src}/cert.d.ts +0 -0
- package/{dist/src → src}/cert.js +0 -0
- package/{dist/src → src}/clean.d.ts +0 -0
- package/{dist/src → src}/clean.js +0 -0
- package/{dist/src → src}/copy.d.ts +0 -0
- package/{dist/src → src}/copy.js +0 -0
- package/{dist/src → src}/cp.d.ts +0 -0
- package/{dist/src → src}/cp.js +1 -0
- package/{dist/src → src}/docker.container.d.ts +0 -0
- package/{dist/src → src}/docker.container.js +0 -0
- package/{dist/src → src}/docker.d.ts +4 -1
- package/{dist/src → src}/docker.js +78 -1
- package/{dist/src → src}/docker.network.d.ts +0 -0
- package/{dist/src → src}/docker.network.js +0 -0
- package/{dist/src → src}/docker.volume.d.ts +0 -0
- package/{dist/src → src}/docker.volume.js +0 -0
- package/{dist/src → src}/dockerCleanup.d.ts +0 -0
- package/{dist/src → src}/dockerCleanup.js +0 -0
- package/{dist/src → src}/dockerCompose.d.ts +1 -0
- package/{dist/src → src}/dockerCompose.js +9 -1
- package/src/env.d.ts +19 -0
- package/src/env.js +80 -0
- package/src/fetch.d.ts +1 -0
- package/src/fetch.js +20 -0
- package/{dist/src → src}/fs.d.ts +6 -0
- package/src/fs.js +76 -0
- package/src/gh.d.ts +7 -0
- package/src/gh.js +51 -0
- package/src/git.d.ts +14 -0
- package/src/git.js +44 -0
- package/{dist/src → src}/index.d.ts +4 -0
- package/{dist/src → src}/index.js +4 -0
- package/src/macos.d.ts +3 -0
- package/src/macos.js +36 -0
- package/{dist/src → src}/maps.d.ts +0 -0
- package/{dist/src → src}/maps.js +0 -0
- package/{dist/src → src}/npm.d.ts +16 -3
- package/src/npm.js +143 -0
- package/{dist/src → src}/pkg.d.ts +6 -1
- package/{dist/src → src}/pkg.js +0 -0
- package/src/promise.d.ts +7 -0
- package/src/promise.js +15 -0
- package/src/prompt.d.ts +2 -0
- package/src/prompt.js +19 -0
- package/{dist/src → src}/publish.d.ts +0 -0
- package/{dist/src → src}/publish.js +0 -0
- package/{dist/src → src}/run.d.ts +0 -0
- package/{dist/src → src}/run.js +0 -0
- package/src/ssh.d.ts +1 -0
- package/src/ssh.js +13 -0
- package/{dist/src → src}/tgz.d.ts +0 -0
- package/{dist/src → src}/tgz.js +0 -0
- package/{dist/src → src}/version.d.ts +0 -0
- package/{dist/src → src}/version.js +1 -1
- package/{dist/src → src}/yarn.d.ts +18 -0
- package/src/yarn.js +155 -0
- package/dist/src/fs.js +0 -38
- package/dist/src/git.d.ts +0 -9
- package/dist/src/git.js +0 -24
- package/dist/src/npm.js +0 -104
- package/dist/src/yarn.js +0 -75
package/src/git.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { spawn } from './cp.js';
|
|
2
|
+
import { userQuestion } from './prompt.js';
|
|
3
|
+
import { buildLog } from './run.js';
|
|
4
|
+
export const git = async (args, opts) => (await spawn('git', args, { captureOutput: true, ...opts })).stdout.trim();
|
|
5
|
+
export async function gitBranch() {
|
|
6
|
+
return (await git(['symbolic-ref', '--short', 'HEAD']))
|
|
7
|
+
.replace(/[_+/]/g, '-')
|
|
8
|
+
.trim();
|
|
9
|
+
}
|
|
10
|
+
export async function gitRevId() {
|
|
11
|
+
return (await git(['rev-parse', '--short=12', 'HEAD']))
|
|
12
|
+
.replace(/[+]/g, '')
|
|
13
|
+
.trim();
|
|
14
|
+
}
|
|
15
|
+
let info = null;
|
|
16
|
+
export async function gitInfo(noCache = false) {
|
|
17
|
+
if (!info || noCache) {
|
|
18
|
+
info = {
|
|
19
|
+
branch: await gitBranch(),
|
|
20
|
+
revision: await gitRevId(),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return info;
|
|
24
|
+
}
|
|
25
|
+
export const ensureGitLfsInstalled = async () => {
|
|
26
|
+
await git(['lfs', 'install'], { stdio: 'inherit' });
|
|
27
|
+
};
|
|
28
|
+
export const gitConfigRead = async (key, global = true) => git(['config', ...(global ? ['--global'] : []), key], {
|
|
29
|
+
rejectOnErrorCode: false,
|
|
30
|
+
});
|
|
31
|
+
export const gitConfigWrite = async (key, value, global = true) => {
|
|
32
|
+
await git(['config', ...(global ? ['--global'] : []), key, value]);
|
|
33
|
+
};
|
|
34
|
+
export const ensureGitConfigUserEmail = async (emailRegex = /.+@.+/, emailPrompt = 'Enter your email address: ', global = true) => {
|
|
35
|
+
const existing = await gitConfigRead('user.email', global);
|
|
36
|
+
if (emailRegex.test(existing)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
buildLog('Setting up git user config...');
|
|
40
|
+
const name = await userQuestion('Enter your full name: ');
|
|
41
|
+
await gitConfigWrite('user.name', name, global);
|
|
42
|
+
const email = await userQuestion(emailPrompt, (input) => emailRegex.test(input));
|
|
43
|
+
await gitConfigWrite('user.email', email, global);
|
|
44
|
+
};
|
|
@@ -10,10 +10,14 @@ export * from './docker.volume.js';
|
|
|
10
10
|
export * from './dockerCleanup.js';
|
|
11
11
|
export * from './dockerCompose.js';
|
|
12
12
|
export * from './fs.js';
|
|
13
|
+
export * from './gh.js';
|
|
13
14
|
export * from './git.js';
|
|
15
|
+
export * from './macos.js';
|
|
14
16
|
export * from './npm.js';
|
|
15
17
|
export * from './pkg.js';
|
|
16
18
|
export * from './publish.js';
|
|
19
|
+
export * from './promise.js';
|
|
20
|
+
export * from './prompt.js';
|
|
17
21
|
export * from './run.js';
|
|
18
22
|
export * from './tgz.js';
|
|
19
23
|
export * from './version.js';
|
|
@@ -10,10 +10,14 @@ export * from './docker.volume.js';
|
|
|
10
10
|
export * from './dockerCleanup.js';
|
|
11
11
|
export * from './dockerCompose.js';
|
|
12
12
|
export * from './fs.js';
|
|
13
|
+
export * from './gh.js';
|
|
13
14
|
export * from './git.js';
|
|
15
|
+
export * from './macos.js';
|
|
14
16
|
export * from './npm.js';
|
|
15
17
|
export * from './pkg.js';
|
|
16
18
|
export * from './publish.js';
|
|
19
|
+
export * from './promise.js';
|
|
20
|
+
export * from './prompt.js';
|
|
17
21
|
export * from './run.js';
|
|
18
22
|
export * from './tgz.js';
|
|
19
23
|
export * from './version.js';
|
package/src/macos.d.ts
ADDED
package/src/macos.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { spawn } from './cp.js';
|
|
3
|
+
import { cmdExists, isMac } from './env.js';
|
|
4
|
+
import { producedPathExists } from './fs.js';
|
|
5
|
+
import { buildLog } from './run.js';
|
|
6
|
+
export const mountDmg = async (dmgPath, mountPath) => {
|
|
7
|
+
await fs.ensureDir(mountPath);
|
|
8
|
+
await spawn('hdiutil', [
|
|
9
|
+
'attach',
|
|
10
|
+
dmgPath,
|
|
11
|
+
'-mountpoint',
|
|
12
|
+
mountPath,
|
|
13
|
+
'-nobrowse',
|
|
14
|
+
'-quiet',
|
|
15
|
+
]);
|
|
16
|
+
};
|
|
17
|
+
export const unmountDmg = async (mountPath) => {
|
|
18
|
+
await spawn('hdiutil', ['detach', mountPath, '-force', '-quiet']);
|
|
19
|
+
};
|
|
20
|
+
export const ensureXcodeCmdInstalled = async (ignoreNonMac = true) => {
|
|
21
|
+
if (isMac()) {
|
|
22
|
+
if (!ignoreNonMac) {
|
|
23
|
+
throw new Error('Cannot install Xcode on non-macOS');
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (!(await cmdExists('xcode-select'))) {
|
|
28
|
+
throw new Error('XCode is not installed, get from the app store.');
|
|
29
|
+
}
|
|
30
|
+
if (!(await producedPathExists(async () => (await spawn('xcode-select', ['-p'], { captureOutput: true })).output))) {
|
|
31
|
+
buildLog('Installing XCode Command Line Tools...');
|
|
32
|
+
await spawn('sudo', ['xcode-select', '--install'], {
|
|
33
|
+
stdio: 'inherit',
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
};
|
|
File without changes
|
package/{dist/src → src}/maps.js
RENAMED
|
File without changes
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SpawnOptions, SpawnResult } from './cp.js';
|
|
1
2
|
export declare type NpmCreds = {
|
|
2
3
|
email?: string;
|
|
3
4
|
password?: string;
|
|
@@ -11,8 +12,21 @@ export declare type NpmConfig = {
|
|
|
11
12
|
registry?: string;
|
|
12
13
|
};
|
|
13
14
|
export declare function getNpmConfig(): NpmConfig;
|
|
14
|
-
export declare
|
|
15
|
+
export declare const envNpmCreds: null | NpmCreds;
|
|
16
|
+
export interface NpmOptions {
|
|
17
|
+
args?: string[];
|
|
18
|
+
npmPath?: string;
|
|
19
|
+
spawnOptions?: SpawnOptions;
|
|
20
|
+
}
|
|
21
|
+
export declare function npm({ args, spawnOptions, npmPath, }?: NpmOptions): Promise<SpawnResult>;
|
|
15
22
|
export declare function npmGetVersions(packageName: string, npmPath?: string): Promise<string[]>;
|
|
23
|
+
interface NpmWriteRcOptions {
|
|
24
|
+
authToken?: string;
|
|
25
|
+
creds?: NpmCreds | null;
|
|
26
|
+
outPath: string;
|
|
27
|
+
registry?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function npmWriteRc({ authToken, creds, outPath, registry, }: NpmWriteRcOptions): Promise<void>;
|
|
16
30
|
export interface NpmPublishOptions {
|
|
17
31
|
npmAuthToken?: string;
|
|
18
32
|
npmConfig?: NpmConfig;
|
|
@@ -22,9 +36,8 @@ export interface NpmPublishOptions {
|
|
|
22
36
|
skipExisting?: boolean;
|
|
23
37
|
tag?: string;
|
|
24
38
|
workDir?: string;
|
|
25
|
-
writeNpmrc?: boolean;
|
|
26
39
|
}
|
|
27
|
-
export declare function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath, skipExisting, tag, workDir: passedWorkDir,
|
|
40
|
+
export declare function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath, skipExisting, tag, workDir: passedWorkDir, }?: NpmPublishOptions): Promise<boolean>;
|
|
28
41
|
interface NpmPackOptions {
|
|
29
42
|
destination?: string;
|
|
30
43
|
npmConfig?: NpmConfig;
|
package/src/npm.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { platform } from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { spawn } from './cp.js';
|
|
5
|
+
import { getCfg, getPkgName } from './pkg.js';
|
|
6
|
+
import { buildLog } from './run.js';
|
|
7
|
+
import { getDevBranch, getVersion } from './version.js';
|
|
8
|
+
export function getNpmConfig() {
|
|
9
|
+
return getCfg().npm || {};
|
|
10
|
+
}
|
|
11
|
+
export const envNpmCreds = (process.env.NPM_CREDS && JSON.parse(process.env.NPM_CREDS)) || null;
|
|
12
|
+
const npmExe = (npmPath) => npmPath || (platform() === 'win32' ? 'npm.cmd' : 'npm');
|
|
13
|
+
export async function npm({ args = [], spawnOptions, npmPath, } = {}) {
|
|
14
|
+
const localNpm = path.join(path.dirname(process.execPath), 'lib/node_modules/npm/bin/npm-cli.js');
|
|
15
|
+
const spawnOpts = {
|
|
16
|
+
env: process.env,
|
|
17
|
+
shell: true,
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
...spawnOptions,
|
|
20
|
+
};
|
|
21
|
+
return npmPath
|
|
22
|
+
? spawn(npmPath, args, spawnOpts)
|
|
23
|
+
: (await fs.pathExists(localNpm))
|
|
24
|
+
? // prefer to use local copy of npm
|
|
25
|
+
spawn(process.execPath, [localNpm, ...args], spawnOpts)
|
|
26
|
+
: // fall back to globally installed npm
|
|
27
|
+
spawn(npmExe(), args, spawnOpts);
|
|
28
|
+
}
|
|
29
|
+
export async function npmGetVersions(packageName, npmPath) {
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse((await npm({
|
|
32
|
+
args: ['show', packageName, 'versions', '--json'],
|
|
33
|
+
npmPath,
|
|
34
|
+
spawnOptions: {
|
|
35
|
+
captureOutput: true,
|
|
36
|
+
stdio: 'pipe',
|
|
37
|
+
},
|
|
38
|
+
})).stdout.trim());
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
if (err instanceof Error) {
|
|
42
|
+
buildLog(`warning: failed to find existing package for ${packageName} in npm registry: ${err.message}`);
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function npmWriteRc({ authToken, creds, outPath, registry, }) {
|
|
48
|
+
// Write out .npmrc with credentials
|
|
49
|
+
const theRegistry = registry || 'https://registry.npmjs.org/';
|
|
50
|
+
const [, host] = /^(?:http(?:s)?:\/\/)?(.+)$/.exec(theRegistry) || [];
|
|
51
|
+
await fs.mkdirp(path.dirname(outPath));
|
|
52
|
+
await fs.writeFile(outPath, `registry=${theRegistry}
|
|
53
|
+
${authToken ? `//${host}:_authToken=${authToken}` : ''}
|
|
54
|
+
${creds
|
|
55
|
+
? `_auth=${Buffer.from(`${creds.username}:${creds.password}`).toString('base64')}
|
|
56
|
+
always-auth=true
|
|
57
|
+
email=${creds.email}`
|
|
58
|
+
: ''}`);
|
|
59
|
+
}
|
|
60
|
+
export async function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath = '.', skipExisting = false, tag, workDir: passedWorkDir, } = {}) {
|
|
61
|
+
const creds = npmCreds || envNpmCreds;
|
|
62
|
+
const authToken = npmAuthToken || process.env.NPM_TOKEN;
|
|
63
|
+
const name = getPkgName();
|
|
64
|
+
const { access, dryRun, publish, registry } = npmConfig || getNpmConfig();
|
|
65
|
+
if (!publish) {
|
|
66
|
+
buildLog('npm publish info missing from package.json, skipping npm publish');
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const resolvedPath = path.resolve(publishPath);
|
|
70
|
+
const workDir = passedWorkDir ||
|
|
71
|
+
((await fs.stat(resolvedPath)).isDirectory()
|
|
72
|
+
? resolvedPath
|
|
73
|
+
: path.dirname(resolvedPath));
|
|
74
|
+
if (!(await fs.pathExists(path.join(workDir, 'package.json')))) {
|
|
75
|
+
buildLog(`warning: no package.json found in ${workDir}, skipping npm publish`);
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
if (creds || registry || authToken) {
|
|
79
|
+
// Write out .npmrc with credentials
|
|
80
|
+
await npmWriteRc({
|
|
81
|
+
authToken: authToken ? `\${NPM_TOKEN}` : undefined,
|
|
82
|
+
creds,
|
|
83
|
+
outPath: path.join(workDir, '.npmrc'),
|
|
84
|
+
registry,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
const existing = await npmGetVersions(name, npmPath);
|
|
88
|
+
const { branch, isRelease, npm: npmVersion } = await getVersion();
|
|
89
|
+
if (existing.includes(npmVersion)) {
|
|
90
|
+
if (skipExisting) {
|
|
91
|
+
buildLog('npm package with this same version already exists. Skipping publish...');
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
throw new Error('Failed to publish npm package, this version already exists!');
|
|
95
|
+
}
|
|
96
|
+
await npm({
|
|
97
|
+
args: [
|
|
98
|
+
'publish',
|
|
99
|
+
resolvedPath,
|
|
100
|
+
'--tag',
|
|
101
|
+
tag ||
|
|
102
|
+
(isRelease
|
|
103
|
+
? 'latest'
|
|
104
|
+
: branch === (await getDevBranch())
|
|
105
|
+
? 'next'
|
|
106
|
+
: 'branch'),
|
|
107
|
+
...(access ? ['--access', access] : []),
|
|
108
|
+
...(dryRun ? ['--dry-run'] : []),
|
|
109
|
+
'--color=always',
|
|
110
|
+
],
|
|
111
|
+
npmPath,
|
|
112
|
+
spawnOptions: {
|
|
113
|
+
cwd: workDir,
|
|
114
|
+
env: {
|
|
115
|
+
...process.env,
|
|
116
|
+
NPM_TOKEN: authToken,
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
export async function npmPack({ destination, npmConfig, npmPath, workDir = '.', }) {
|
|
123
|
+
const { dryRun } = npmConfig || getNpmConfig();
|
|
124
|
+
if (destination) {
|
|
125
|
+
await fs.ensureDir(destination);
|
|
126
|
+
}
|
|
127
|
+
const { stdout } = await npm({
|
|
128
|
+
args: [
|
|
129
|
+
'pack',
|
|
130
|
+
...(dryRun ? ['--dry-run'] : []),
|
|
131
|
+
...(destination ? ['--pack-destination', path.resolve(destination)] : []),
|
|
132
|
+
'--color=always',
|
|
133
|
+
],
|
|
134
|
+
npmPath,
|
|
135
|
+
spawnOptions: {
|
|
136
|
+
captureOutput: true,
|
|
137
|
+
cwd: path.resolve(workDir),
|
|
138
|
+
pipeOutput: true,
|
|
139
|
+
stdio: 'pipe',
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
return path.resolve(destination || '.', stdout.trim());
|
|
143
|
+
}
|
|
@@ -22,8 +22,13 @@ export interface PackageJson {
|
|
|
22
22
|
name: string;
|
|
23
23
|
peerDependencies?: Record<string, string>;
|
|
24
24
|
private?: boolean;
|
|
25
|
-
repository?: string
|
|
25
|
+
repository?: string | {
|
|
26
|
+
type: string;
|
|
27
|
+
url: string;
|
|
28
|
+
};
|
|
26
29
|
scripts?: Record<string, string>;
|
|
30
|
+
type?: string;
|
|
31
|
+
types?: string;
|
|
27
32
|
version: string;
|
|
28
33
|
}
|
|
29
34
|
export declare function getPkg(): PackageJson;
|
package/{dist/src → src}/pkg.js
RENAMED
|
File without changes
|
package/src/promise.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This generates a function that, when invoked, will only invoke the producer once.
|
|
3
|
+
* On subsequent calls, the previously produced value will be returned.
|
|
4
|
+
* @param producer a function that produces a promise, will be invoked at most once
|
|
5
|
+
* @returns a function that returns a promise
|
|
6
|
+
*/
|
|
7
|
+
export declare const resolveOnce: <T>(producer: () => Promise<T>) => () => Promise<T>;
|
package/src/promise.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This generates a function that, when invoked, will only invoke the producer once.
|
|
3
|
+
* On subsequent calls, the previously produced value will be returned.
|
|
4
|
+
* @param producer a function that produces a promise, will be invoked at most once
|
|
5
|
+
* @returns a function that returns a promise
|
|
6
|
+
*/
|
|
7
|
+
export const resolveOnce = (producer) => {
|
|
8
|
+
let promisedResult;
|
|
9
|
+
return async () => {
|
|
10
|
+
if (!promisedResult) {
|
|
11
|
+
promisedResult = producer();
|
|
12
|
+
}
|
|
13
|
+
return promisedResult;
|
|
14
|
+
};
|
|
15
|
+
};
|
package/src/prompt.d.ts
ADDED
package/src/prompt.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { stdin as input, stdout as output } from 'process';
|
|
2
|
+
import readline from 'readline';
|
|
3
|
+
export const ask = async (question) => {
|
|
4
|
+
// Once we move to Node 18+, can replace this with a builtin Promise interface
|
|
5
|
+
const rl = readline.createInterface({ input, output });
|
|
6
|
+
return new Promise((resolve) => {
|
|
7
|
+
rl.question(question, (value) => {
|
|
8
|
+
rl.close();
|
|
9
|
+
resolve(value.trim());
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
export const userQuestion = async (question, test = (v) => !!v) => {
|
|
14
|
+
let answer;
|
|
15
|
+
do {
|
|
16
|
+
answer = await ask(question);
|
|
17
|
+
} while (!(await test(answer)));
|
|
18
|
+
return answer;
|
|
19
|
+
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/{dist/src → src}/run.js
RENAMED
|
File without changes
|
package/src/ssh.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const ensureSshKeyGenerated: (keyPath?: string | undefined) => Promise<string>;
|
package/src/ssh.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { spawn } from './cp.js';
|
|
5
|
+
import { buildLog } from './run.js';
|
|
6
|
+
export const ensureSshKeyGenerated = async (keyPath) => {
|
|
7
|
+
const sshKeyPath = keyPath || path.join(os.homedir(), '.ssh', 'id_ed25519');
|
|
8
|
+
if (!(await fs.pathExists(sshKeyPath))) {
|
|
9
|
+
buildLog('Generating SSH key (passphrase is optional)...');
|
|
10
|
+
await spawn('ssh-keygen', ['-t', 'ed25519', '-f', sshKeyPath]);
|
|
11
|
+
}
|
|
12
|
+
return sshKeyPath;
|
|
13
|
+
};
|
|
File without changes
|
package/{dist/src → src}/tgz.js
RENAMED
|
File without changes
|
|
File without changes
|
|
@@ -38,7 +38,7 @@ export async function getRepoInfo() {
|
|
|
38
38
|
}
|
|
39
39
|
export async function getDevBranch() {
|
|
40
40
|
const { devBranch } = getCfg();
|
|
41
|
-
return devBranch || (await getRepoType()) === 'hg' ? 'default' : 'dev';
|
|
41
|
+
return devBranch || ((await getRepoType()) === 'hg' ? 'default' : 'dev');
|
|
42
42
|
}
|
|
43
43
|
export async function getIsRelease(passedBranch = null, releaseOverride = null) {
|
|
44
44
|
const branch = passedBranch || (await getRepoInfo()).branch;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SpawnOptions, SpawnResult } from './cp.js';
|
|
2
|
+
import { NpmConfig, NpmCreds } from './npm.js';
|
|
2
3
|
export interface YarnOptions {
|
|
3
4
|
args?: string[];
|
|
4
5
|
spawnOptions?: SpawnOptions;
|
|
@@ -24,3 +25,20 @@ export interface YarnUpgradeOptions {
|
|
|
24
25
|
outdated?: boolean;
|
|
25
26
|
}
|
|
26
27
|
export declare function yarnUpgrade({ all, outdated, }?: YarnUpgradeOptions): Promise<void>;
|
|
28
|
+
export interface YarnPublishOptions {
|
|
29
|
+
npmAuthToken?: string;
|
|
30
|
+
npmConfig?: NpmConfig;
|
|
31
|
+
npmCreds?: NpmCreds;
|
|
32
|
+
npmPath?: string;
|
|
33
|
+
publishPath?: string;
|
|
34
|
+
skipExisting?: boolean;
|
|
35
|
+
tag?: string;
|
|
36
|
+
workDir?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function yarnPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath, skipExisting, tag, workDir: passedWorkDir, }?: YarnPublishOptions): Promise<boolean>;
|
|
39
|
+
interface YarnPackOptions {
|
|
40
|
+
destination: string;
|
|
41
|
+
workDir?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function yarnPack({ destination, workDir, }: YarnPackOptions): Promise<string>;
|
|
44
|
+
export {};
|
package/src/yarn.js
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { spawn } from './cp.js';
|
|
4
|
+
import { readDir } from './fs.js';
|
|
5
|
+
import { envNpmCreds, getNpmConfig, npmGetVersions, npmWriteRc, } from './npm.js';
|
|
6
|
+
import { getPkg, getPkgName } from './pkg.js';
|
|
7
|
+
import { buildLog } from './run.js';
|
|
8
|
+
import { generateFileHash } from './tgz.js';
|
|
9
|
+
import { getDevBranch, getVersion } from './version.js';
|
|
10
|
+
export async function yarn({ args = [], spawnOptions, } = {}) {
|
|
11
|
+
const localYarn = path.join(path.dirname(process.execPath), '/node_modules/yarn/bin/yarn.js');
|
|
12
|
+
const spawnOpts = {
|
|
13
|
+
env: process.env,
|
|
14
|
+
shell: true,
|
|
15
|
+
stdio: 'inherit',
|
|
16
|
+
...spawnOptions,
|
|
17
|
+
};
|
|
18
|
+
return (await fs.pathExists(localYarn))
|
|
19
|
+
? // prefer to use local copy of yarn
|
|
20
|
+
spawn(process.execPath, [localYarn, ...args], spawnOpts)
|
|
21
|
+
: // fall back to globally installed yarn
|
|
22
|
+
spawn('yarn', args, spawnOpts);
|
|
23
|
+
}
|
|
24
|
+
export const yarnFiles = ['./package.json', './yarn.lock'];
|
|
25
|
+
// Smart yarn invocation, only if package changed
|
|
26
|
+
export async function yarnInstall({ force = false, hashFilePath = './download/buildHash_yarn.md5', nodeModulesPath = './node_modules', } = {}) {
|
|
27
|
+
await fs.ensureDir(nodeModulesPath);
|
|
28
|
+
const currentHash = (await Promise.all(yarnFiles.map(async (f) => generateFileHash(f, 'md5')))).join('|');
|
|
29
|
+
await fs.ensureFile(hashFilePath);
|
|
30
|
+
const prevHash = await fs.readFile(hashFilePath, 'utf8');
|
|
31
|
+
if (currentHash !== prevHash) {
|
|
32
|
+
buildLog('node package definition changed since last build, invoking yarn.');
|
|
33
|
+
}
|
|
34
|
+
else if (!(await readDir(`${nodeModulesPath}/**/*.js`)).length) {
|
|
35
|
+
buildLog('node packages missing, invoking yarn.');
|
|
36
|
+
}
|
|
37
|
+
else if (force) {
|
|
38
|
+
buildLog('node packages unchanged, but yarn forced on command line...');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
buildLog('node packages unchanged since last build, skipping yarn.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
await yarn();
|
|
45
|
+
await fs.writeFile(hashFilePath, currentHash);
|
|
46
|
+
}
|
|
47
|
+
export async function yarnUpgrade({ all = false, outdated = false, } = {}) {
|
|
48
|
+
if (outdated) {
|
|
49
|
+
const { code, stdout } = await yarn({
|
|
50
|
+
args: ['outdated'],
|
|
51
|
+
spawnOptions: {
|
|
52
|
+
captureOutput: true,
|
|
53
|
+
rejectOnErrorCode: false,
|
|
54
|
+
stdio: 'pipe',
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
if (code === 0) {
|
|
58
|
+
buildLog('No outdated packages.');
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const { dependencies = {}, devDependencies = {} } = getPkg();
|
|
62
|
+
const packages = stdout
|
|
63
|
+
.split('\n')
|
|
64
|
+
.slice(5, -1)
|
|
65
|
+
.map((l) => l.split(/\s+/)[0])
|
|
66
|
+
.filter((p) => all || !/^\d/.test(dependencies[p] || devDependencies[p] || ''));
|
|
67
|
+
if (packages.length) {
|
|
68
|
+
await yarn({ args: ['add', ...packages] });
|
|
69
|
+
buildLog(`Upgraded: ${packages.join(', ')}`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
buildLog('No eligible outdated packages');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
await yarn({ args: ['upgrade'] });
|
|
77
|
+
}
|
|
78
|
+
export async function yarnPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath = '.', skipExisting = false, tag, workDir: passedWorkDir, } = {}) {
|
|
79
|
+
const creds = npmCreds || envNpmCreds;
|
|
80
|
+
const authToken = npmAuthToken || process.env.NPM_TOKEN;
|
|
81
|
+
const name = getPkgName();
|
|
82
|
+
const { access, publish, registry } = npmConfig || getNpmConfig();
|
|
83
|
+
if (!publish) {
|
|
84
|
+
buildLog('npm publish info missing from package.json, skipping npm publish');
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const resolvedPath = path.resolve(publishPath);
|
|
88
|
+
const workDir = passedWorkDir ||
|
|
89
|
+
((await fs.stat(resolvedPath)).isDirectory()
|
|
90
|
+
? resolvedPath
|
|
91
|
+
: path.dirname(resolvedPath));
|
|
92
|
+
if (!(await fs.pathExists(path.join(workDir, 'package.json')))) {
|
|
93
|
+
buildLog(`warning: no package.json found in ${workDir}, skipping npm publish`);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (creds || registry || authToken) {
|
|
97
|
+
// Write out .npmrc with credentials
|
|
98
|
+
await npmWriteRc({
|
|
99
|
+
authToken: authToken ? `\${NPM_TOKEN}` : undefined,
|
|
100
|
+
creds,
|
|
101
|
+
outPath: path.join(workDir, '.npmrc'),
|
|
102
|
+
registry,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const existing = await npmGetVersions(name, npmPath);
|
|
106
|
+
const { branch, isRelease, npm: npmVersion } = await getVersion();
|
|
107
|
+
if (existing.includes(npmVersion)) {
|
|
108
|
+
if (skipExisting) {
|
|
109
|
+
buildLog('npm package with this same version already exists. Skipping publish...');
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
throw new Error('Failed to publish npm package, this version already exists!');
|
|
113
|
+
}
|
|
114
|
+
await yarn({
|
|
115
|
+
args: [
|
|
116
|
+
'publish',
|
|
117
|
+
resolvedPath,
|
|
118
|
+
'--new-version',
|
|
119
|
+
npmVersion,
|
|
120
|
+
'--tag',
|
|
121
|
+
tag ||
|
|
122
|
+
(isRelease
|
|
123
|
+
? 'latest'
|
|
124
|
+
: branch === (await getDevBranch())
|
|
125
|
+
? 'next'
|
|
126
|
+
: 'branch'),
|
|
127
|
+
...(access ? ['--access', access] : []),
|
|
128
|
+
],
|
|
129
|
+
spawnOptions: {
|
|
130
|
+
cwd: workDir,
|
|
131
|
+
env: {
|
|
132
|
+
...process.env,
|
|
133
|
+
FORCE_COLOR: 'true',
|
|
134
|
+
NPM_TOKEN: authToken,
|
|
135
|
+
},
|
|
136
|
+
shell: true,
|
|
137
|
+
stdio: 'inherit',
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
export async function yarnPack({ destination, workDir = '.', }) {
|
|
143
|
+
await fs.ensureDir(destination);
|
|
144
|
+
const version = await getVersion();
|
|
145
|
+
const name = getPkgName();
|
|
146
|
+
const filename = path.resolve(destination, `${name}-${version.npm}.tgz`);
|
|
147
|
+
await yarn({
|
|
148
|
+
args: ['pack', ...(destination ? ['--filename', filename] : [])],
|
|
149
|
+
spawnOptions: {
|
|
150
|
+
cwd: path.resolve(workDir),
|
|
151
|
+
pipeOutput: true,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
return filename;
|
|
155
|
+
}
|
package/dist/src/fs.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import glob from 'glob';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import rimraf from 'rimraf';
|
|
5
|
-
export const readDir = async (pattern, options) => new Promise((resolve, reject) => {
|
|
6
|
-
glob(pattern, options || {}, (err, result) => err ? reject(err) : resolve(result));
|
|
7
|
-
});
|
|
8
|
-
export const moveDir = async (source, target) => {
|
|
9
|
-
const dirs = await readDir('**/*.*', {
|
|
10
|
-
cwd: source,
|
|
11
|
-
dot: true,
|
|
12
|
-
nosort: true,
|
|
13
|
-
});
|
|
14
|
-
await Promise.all(dirs.map(async (dir) => {
|
|
15
|
-
const from = path.resolve(source, dir);
|
|
16
|
-
const to = path.resolve(target, dir);
|
|
17
|
-
await fs.ensureDir(path.dirname(to));
|
|
18
|
-
await fs.rename(from, to);
|
|
19
|
-
}));
|
|
20
|
-
};
|
|
21
|
-
export const copyDir = async (source, target, fileGlob = '**/*.*', globOptions = null, renameFn = (n) => n) => {
|
|
22
|
-
const paths = await readDir(fileGlob, {
|
|
23
|
-
cwd: source,
|
|
24
|
-
dot: true,
|
|
25
|
-
nodir: true,
|
|
26
|
-
nosort: true,
|
|
27
|
-
...globOptions,
|
|
28
|
-
});
|
|
29
|
-
await Promise.all(paths.map(async (p) => {
|
|
30
|
-
const from = path.resolve(source, p);
|
|
31
|
-
const to = path.resolve(target, renameFn(p));
|
|
32
|
-
await fs.ensureDir(path.dirname(to));
|
|
33
|
-
await fs.copyFile(from, to);
|
|
34
|
-
}));
|
|
35
|
-
};
|
|
36
|
-
export const cleanDir = async (pattern, globOptions) => new Promise((resolve, reject) => {
|
|
37
|
-
rimraf(pattern, { glob: globOptions }, (err) => err ? reject(err) : resolve());
|
|
38
|
-
});
|
package/dist/src/git.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export declare function git(args: string[]): Promise<string>;
|
|
2
|
-
export declare function gitBranch(): Promise<string>;
|
|
3
|
-
export declare function gitRevId(): Promise<string>;
|
|
4
|
-
declare type GitInfo = {
|
|
5
|
-
branch: string;
|
|
6
|
-
revision: string;
|
|
7
|
-
};
|
|
8
|
-
export declare function gitInfo(noCache?: boolean): Promise<GitInfo>;
|
|
9
|
-
export {};
|