build-strap 4.0.0-dev.2 → 4.0.0-dev.5

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.
Files changed (5) hide show
  1. package/npm.d.ts +15 -1
  2. package/npm.js +80 -43
  3. package/package.json +1 -1
  4. package/yarn.d.ts +18 -0
  5. package/yarn.js +81 -1
package/npm.d.ts CHANGED
@@ -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 function npmExec(args: string[], npmPath?: string): Promise<string>;
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;
package/npm.js CHANGED
@@ -1,27 +1,60 @@
1
1
  import fs from 'fs-extra';
2
2
  import { platform } from 'os';
3
3
  import path from 'path';
4
- import { exec, spawn } from './cp.js';
4
+ import { spawn } from './cp.js';
5
5
  import { getCfg, getPkgName } from './pkg.js';
6
6
  import { buildLog } from './run.js';
7
7
  import { getDevBranch, getVersion } from './version.js';
8
8
  export function getNpmConfig() {
9
9
  return getCfg().npm || {};
10
10
  }
11
- const envNpmCreds = (process.env.NPM_CREDS && JSON.parse(process.env.NPM_CREDS)) || null;
11
+ export const envNpmCreds = (process.env.NPM_CREDS && JSON.parse(process.env.NPM_CREDS)) || null;
12
12
  const npmExe = (npmPath) => npmPath || (platform() === 'win32' ? 'npm.cmd' : 'npm');
13
- export async function npmExec(args, npmPath) {
14
- return (await exec(`${npmExe(npmPath)} ${args.join(' ')}`)).stdout.toString();
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);
15
28
  }
16
29
  export async function npmGetVersions(packageName, npmPath) {
17
30
  try {
18
- return JSON.parse((await npmExec(['show', packageName, 'versions', '--json'], npmPath)).trim());
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());
19
39
  }
20
40
  catch (err) {
21
41
  buildLog(`warning: failed to find existing package for ${packageName} in npm registry: ${err.message}`);
22
42
  return [];
23
43
  }
24
44
  }
45
+ export async function npmWriteRc({ authToken, creds, outPath, registry, }) {
46
+ // Write out .npmrc with credentials
47
+ const theRegistry = registry || 'https://registry.npmjs.org/';
48
+ const [, host] = /^(?:http(?:s)?:\/\/)?(.+)$/.exec(theRegistry) || [];
49
+ await fs.mkdirp(path.dirname(outPath));
50
+ await fs.writeFile(outPath, `registry=${theRegistry}
51
+ ${authToken ? `//${host}:_authToken=${authToken}` : ''}
52
+ ${creds
53
+ ? `_auth=${Buffer.from(`${creds.username}:${creds.password}`).toString('base64')}
54
+ always-auth=true
55
+ email=${creds.email}`
56
+ : ''}`);
57
+ }
25
58
  export async function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, publishPath = '.', skipExisting = false, tag, workDir: passedWorkDir, } = {}) {
26
59
  const creds = npmCreds || envNpmCreds;
27
60
  const authToken = npmAuthToken || process.env.NPM_TOKEN;
@@ -42,16 +75,12 @@ export async function npmPublish({ npmAuthToken, npmConfig, npmCreds, npmPath, p
42
75
  }
43
76
  if (creds || registry || authToken) {
44
77
  // Write out .npmrc with credentials
45
- const theRegistry = registry || 'https://registry.npmjs.org/';
46
- const [, host] = /^(?:http(?:s)?:\/\/)?(.+)$/.exec(theRegistry) || [];
47
- await fs.mkdirp(workDir);
48
- await fs.writeFile(path.join(workDir, '.npmrc'), `registry=${theRegistry}
49
- ${authToken ? `//${host}:_authToken=\${NPM_TOKEN}` : ''}
50
- ${creds
51
- ? `_auth=${Buffer.from(`${creds.username}:${creds.password}`).toString('base64')}
52
- always-auth=true
53
- email=${creds.email}`
54
- : ''}`);
78
+ await npmWriteRc({
79
+ authToken: authToken ? `\${NPM_TOKEN}` : undefined,
80
+ creds,
81
+ outPath: path.join(workDir, '.npmrc'),
82
+ registry,
83
+ });
55
84
  }
56
85
  const existing = await npmGetVersions(name, npmPath);
57
86
  const { branch, isRelease, npm: npmVersion } = await getVersion();
@@ -62,26 +91,29 @@ email=${creds.email}`
62
91
  }
63
92
  throw new Error('Failed to publish npm package, this version already exists!');
64
93
  }
65
- await spawn(npmExe(npmPath), [
66
- 'publish',
67
- resolvedPath,
68
- '--tag',
69
- tag ||
70
- (isRelease
71
- ? 'latest'
72
- : branch === (await getDevBranch())
73
- ? 'next'
74
- : 'branch'),
75
- ...(access ? ['--access', access] : []),
76
- ...(dryRun ? ['--dry-run'] : []),
77
- '--color=always',
78
- ], {
79
- cwd: workDir,
80
- env: {
81
- ...process.env,
82
- NPM_TOKEN: authToken,
94
+ await npm({
95
+ args: [
96
+ 'publish',
97
+ resolvedPath,
98
+ '--tag',
99
+ tag ||
100
+ (isRelease
101
+ ? 'latest'
102
+ : branch === (await getDevBranch())
103
+ ? 'next'
104
+ : 'branch'),
105
+ ...(access ? ['--access', access] : []),
106
+ ...(dryRun ? ['--dry-run'] : []),
107
+ '--color=always',
108
+ ],
109
+ npmPath,
110
+ spawnOptions: {
111
+ cwd: workDir,
112
+ env: {
113
+ ...process.env,
114
+ NPM_TOKEN: authToken,
115
+ },
83
116
  },
84
- stdio: 'inherit',
85
117
  });
86
118
  return true;
87
119
  }
@@ -90,15 +122,20 @@ export async function npmPack({ destination, npmConfig, npmPath, workDir = '.',
90
122
  if (destination) {
91
123
  await fs.ensureDir(destination);
92
124
  }
93
- const { stdout } = await spawn(npmExe(npmPath), [
94
- 'pack',
95
- ...(dryRun ? ['--dry-run'] : []),
96
- ...(destination ? ['--pack-destination', path.resolve(destination)] : []),
97
- '--color=always',
98
- ], {
99
- captureOutput: true,
100
- cwd: path.resolve(workDir),
101
- pipeOutput: true,
125
+ const { stdout } = await npm({
126
+ args: [
127
+ 'pack',
128
+ ...(dryRun ? ['--dry-run'] : []),
129
+ ...(destination ? ['--pack-destination', path.resolve(destination)] : []),
130
+ '--color=always',
131
+ ],
132
+ npmPath,
133
+ spawnOptions: {
134
+ captureOutput: true,
135
+ cwd: path.resolve(workDir),
136
+ pipeOutput: true,
137
+ stdio: 'pipe',
138
+ },
102
139
  });
103
140
  return path.resolve(destination || '.', stdout.trim());
104
141
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "build-strap",
3
- "version": "4.0.0-dev.2",
3
+ "version": "4.0.0-dev.5",
4
4
  "description": "Node scripts for building things",
5
5
  "license": "MIT",
6
6
  "authors": [
package/yarn.d.ts CHANGED
@@ -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/yarn.js CHANGED
@@ -2,9 +2,11 @@ import fs from 'fs-extra';
2
2
  import path from 'path';
3
3
  import { spawn } from './cp.js';
4
4
  import { readDir } from './fs.js';
5
- import { getPkg } from './pkg.js';
5
+ import { envNpmCreds, getNpmConfig, npmGetVersions, npmWriteRc, } from './npm.js';
6
+ import { getPkg, getPkgName } from './pkg.js';
6
7
  import { buildLog } from './run.js';
7
8
  import { generateFileHash } from './tgz.js';
9
+ import { getDevBranch, getVersion } from './version.js';
8
10
  export async function yarn({ args = [], spawnOptions, } = {}) {
9
11
  const localYarn = path.join(path.dirname(process.execPath), '/node_modules/yarn/bin/yarn.js');
10
12
  const spawnOpts = {
@@ -73,3 +75,81 @@ export async function yarnUpgrade({ all = false, outdated = false, } = {}) {
73
75
  }
74
76
  await yarn({ args: ['upgrade'] });
75
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
+ }