Skip to content

Commit 5f0b157

Browse files
committed
fix(cli): clean up output
1 parent ebe0cb9 commit 5f0b157

11 files changed

+195
-153
lines changed

packages/api/cli/spec/check-system.spec.ts packages/api/cli/spec/util/check-system.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { resolvePackageManager, spawnPackageManager } from '@electron-forge/core-utils';
22
import { describe, expect, it, vi } from 'vitest';
33

4-
import { checkPackageManager } from '../src/util/check-system';
4+
import { checkPackageManager } from '../../src/util/check-system';
55

66
vi.mock(import('@electron-forge/core-utils'), async (importOriginal) => {
77
const mod = await importOriginal();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import path from 'node:path';
2+
3+
import { describe, expect, it } from 'vitest';
4+
5+
import { resolveWorkingDir } from '../../src/util/resolve-working-dir';
6+
7+
describe('resolveWorkingDir', () => {
8+
it('resolves relative paths according to the current working directory', () => {
9+
const dir = resolveWorkingDir('.');
10+
11+
expect(dir).toEqual(process.cwd());
12+
});
13+
14+
it('works with an absolute directory', () => {
15+
const upOne = path.resolve(process.cwd(), '..');
16+
expect(path.isAbsolute(upOne)).toBe(true);
17+
const dir = resolveWorkingDir(upOne);
18+
19+
expect(dir).toEqual(upOne);
20+
});
21+
22+
it('resolves a relative path if checkExisting=false and dir does not exist', () => {
23+
const dir = resolveWorkingDir('./i-made-this-dir-up', false);
24+
25+
expect(dir).toEqual(path.resolve(process.cwd(), './i-made-this-dir-up'));
26+
});
27+
28+
it('resolves an absolute path if checkExisting=false and dir does not exist', () => {
29+
const fakeDir = path.resolve(process.cwd(), './i-made-this-dir-up');
30+
expect(path.isAbsolute(fakeDir)).toBe(true);
31+
const dir = resolveWorkingDir(fakeDir, false);
32+
33+
expect(dir).toEqual(fakeDir);
34+
});
35+
36+
it('falls back to the current working directory with a relative path if checkExisting=true and dir does not exist', () => {
37+
const dir = resolveWorkingDir('./i-made-this-dir-up', true);
38+
39+
expect(dir).toEqual(process.cwd());
40+
});
41+
42+
it('falls back to the current working directory with an absolute path if checkExisting=true and dir does not exist', () => {
43+
const fakeDir = path.resolve(process.cwd(), './i-made-this-dir-up');
44+
expect(path.isAbsolute(fakeDir)).toBe(true);
45+
const dir = resolveWorkingDir(fakeDir);
46+
47+
expect(dir).toEqual(process.cwd());
48+
});
49+
});

packages/api/cli/src/electron-forge-import.ts

+13-17
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,17 @@ import { program } from 'commander';
44
import './util/terminate';
55
import packageJSON from '../package.json';
66

7-
import workingDir from './util/working-dir';
7+
import { resolveWorkingDir } from './util/resolve-working-dir';
88

9-
(async () => {
10-
let dir = process.cwd();
11-
program
12-
.version(packageJSON.version, '-V, --version', 'Output the current version')
13-
.helpOption('-h, --help', 'Output usage information')
14-
.arguments('[name]')
15-
.action((name) => {
16-
dir = workingDir(dir, name, false);
17-
})
18-
.parse(process.argv);
19-
20-
await api.import({
21-
dir,
22-
interactive: true,
23-
});
24-
})();
9+
program
10+
.version(packageJSON.version, '-V, --version', 'Output the current version.')
11+
.helpOption('-h, --help', 'Output usage information.')
12+
.argument('[dir]', 'Directory of the project to import. (default: current directory)')
13+
.action(async (dir: string) => {
14+
const workingDir = resolveWorkingDir(dir, false);
15+
await api.import({
16+
dir: workingDir,
17+
interactive: true,
18+
});
19+
})
20+
.parse(process.argv);

packages/api/cli/src/electron-forge-init.ts

+21-24
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,28 @@ import { program } from 'commander';
44
import './util/terminate';
55
import packageJSON from '../package.json';
66

7-
import workingDir from './util/working-dir';
7+
import { resolveWorkingDir } from './util/resolve-working-dir';
88

9-
(async () => {
10-
let dir = process.cwd();
11-
program
12-
.version(packageJSON.version, '-V, --version', 'Output the current version')
13-
.arguments('[name]')
14-
.option('-t, --template [name]', 'Name of the Forge template to use')
15-
.option('-c, --copy-ci-files', 'Whether to copy the templated CI files', false)
16-
.option('-f, --force', 'Whether to overwrite an existing directory', false)
17-
.helpOption('-h, --help', 'Output usage information')
18-
.action((name) => {
19-
dir = workingDir(dir, name, false);
20-
})
21-
.parse(process.argv);
9+
program
10+
.version(packageJSON.version, '-V, --version', 'Output the current version.')
11+
.helpOption('-h, --help', 'Output usage information.')
12+
.argument('[dir]', 'Directory to initialize the project in. (default: current directory)')
13+
.option('-t, --template [name]', 'Name of the Forge template to use.', 'base')
14+
.option('-c, --copy-ci-files', 'Whether to copy the templated CI files.', false)
15+
.option('-f, --force', 'Whether to overwrite an existing directory.', false)
16+
.action(async (dir) => {
17+
const workingDir = resolveWorkingDir(dir, false);
2218

23-
const options = program.opts();
19+
const options = program.opts();
2420

25-
const initOpts: InitOptions = {
26-
dir,
27-
interactive: true,
28-
copyCIFiles: !!options.copyCiFiles,
29-
force: !!options.force,
30-
};
31-
if (options.template) initOpts.template = options.template;
21+
const initOpts: InitOptions = {
22+
dir: workingDir,
23+
interactive: true,
24+
copyCIFiles: !!options.copyCiFiles,
25+
force: !!options.force,
26+
};
27+
if (options.template) initOpts.template = options.template;
3228

33-
await api.init(initOpts);
34-
})();
29+
await api.init(initOpts);
30+
})
31+
.parse(process.argv);

packages/api/cli/src/electron-forge-make.ts

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
11
import { initializeProxy } from '@electron/get';
22
import { api, MakeOptions } from '@electron-forge/core';
3+
import chalk from 'chalk';
34
import { program } from 'commander';
45

56
import './util/terminate';
67
import packageJSON from '../package.json';
78

8-
import workingDir from './util/working-dir';
9+
import { resolveWorkingDir } from './util/resolve-working-dir';
910

1011
export async function getMakeOptions(): Promise<MakeOptions> {
11-
let dir = process.cwd();
12+
let workingDir: string;
1213
program
13-
.version(packageJSON.version, '-V, --version', 'Output the current version')
14-
.arguments('[cwd]')
15-
.option('--skip-package', 'Assume the app is already packaged')
16-
.option('-a, --arch [arch]', 'Target architecture')
17-
.option('-p, --platform [platform]', 'Target build platform')
18-
.option('--targets [targets]', 'Override your make targets for this run')
19-
.helpOption('-h, --help', 'Output usage information')
14+
.version(packageJSON.version, '-V, --version', 'Output the current version.')
15+
.helpOption('-h, --help', 'Output usage information.')
16+
.argument('[dir]', 'Directory to run the command in. (default: current directory)')
17+
.option('--skip-package', `Skip packaging the Electron application, and use the output from a previous ${chalk.green('package')} run instead.`)
18+
.option('-a, --arch [arch]', 'Target build architecture.', process.arch)
19+
.option('-p, --platform [platform]', 'Target build platform.', process.platform)
20+
.option('--targets [targets]', `Override your ${chalk.green('make')} targets for this run.`)
2021
.allowUnknownOption(true)
21-
.action((cwd) => {
22-
dir = workingDir(dir, cwd);
22+
.action((dir) => {
23+
workingDir = resolveWorkingDir(dir, false);
2324
})
2425
.parse(process.argv);
2526

2627
const options = program.opts();
2728

2829
const makeOpts: MakeOptions = {
29-
dir,
30+
dir: workingDir!,
3031
interactive: true,
3132
skipPackage: options.skipPackage,
3233
};
@@ -37,8 +38,7 @@ export async function getMakeOptions(): Promise<MakeOptions> {
3738
return makeOpts;
3839
}
3940

40-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
41-
if (require.main === module || (global as any).__LINKED_FORGE__) {
41+
if (require.main === module) {
4242
(async () => {
4343
const makeOpts = await getMakeOptions();
4444

packages/api/cli/src/electron-forge-package.ts

+20-23
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,28 @@ import { program } from 'commander';
55
import './util/terminate';
66
import packageJSON from '../package.json';
77

8-
import workingDir from './util/working-dir';
8+
import { resolveWorkingDir } from './util/resolve-working-dir';
99

10-
(async () => {
11-
let dir: string = process.cwd();
12-
program
13-
.version(packageJSON.version, '-V, --version', 'Output the current version')
14-
.arguments('[cwd]')
15-
.option('-a, --arch [arch]', 'Target architecture')
16-
.option('-p, --platform [platform]', 'Target build platform')
17-
.helpOption('-h, --help', 'Output usage information')
18-
.action((cwd) => {
19-
dir = workingDir(dir, cwd);
20-
})
21-
.parse(process.argv);
10+
program
11+
.version(packageJSON.version, '-V, --version', 'Output the current version')
12+
.helpOption('-h, --help', 'Output usage information')
13+
.argument('[dir]', 'Directory to run the command in. (default: current directory)')
14+
.option('-a, --arch [arch]', 'Target build architecture')
15+
.option('-p, --platform [platform]', 'Target build platform')
16+
.action(async (dir) => {
17+
const workingDir = resolveWorkingDir(dir);
2218

23-
const options = program.opts();
19+
const options = program.opts();
2420

25-
initializeProxy();
21+
initializeProxy();
2622

27-
const packageOpts: PackageOptions = {
28-
dir,
29-
interactive: true,
30-
};
31-
if (options.arch) packageOpts.arch = options.arch;
32-
if (options.platform) packageOpts.platform = options.platform;
23+
const packageOpts: PackageOptions = {
24+
dir: workingDir,
25+
interactive: true,
26+
};
27+
if (options.arch) packageOpts.arch = options.arch;
28+
if (options.platform) packageOpts.platform = options.platform;
3329

34-
await api.package(packageOpts);
35-
})();
30+
await api.package(packageOpts);
31+
})
32+
.parse(process.argv);
+30-33
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,38 @@
11
import { initializeProxy } from '@electron/get';
22
import { api, PublishOptions } from '@electron-forge/core';
3+
import chalk from 'chalk';
34
import { program } from 'commander';
45

56
import './util/terminate';
67
import packageJSON from '../package.json';
78

89
import { getMakeOptions } from './electron-forge-make';
9-
import workingDir from './util/working-dir';
10-
11-
(async () => {
12-
let dir = process.cwd();
13-
program
14-
.version(packageJSON.version, '-V, --version', 'Output the current version')
15-
.arguments('[cwd]')
16-
.option('--target [target[,target...]]', 'The comma-separated deployment targets, defaults to "github"')
17-
.option('--dry-run', "Triggers a publish dry run which saves state and doesn't upload anything")
18-
.option('--from-dry-run', 'Attempts to publish artifacts from the last saved dry run')
19-
.helpOption('-h, --help', 'Output usage information')
20-
.allowUnknownOption(true)
21-
.action((cwd) => {
22-
dir = workingDir(dir, cwd);
23-
})
24-
.parse(process.argv);
25-
26-
const options = program.opts();
27-
28-
initializeProxy();
29-
30-
const publishOpts: PublishOptions = {
31-
dir,
32-
interactive: true,
33-
dryRun: options.dryRun,
34-
dryRunResume: options.fromDryRun,
35-
};
36-
if (options.target) publishOpts.publishTargets = options.target.split(',');
37-
38-
publishOpts.makeOptions = await getMakeOptions();
39-
40-
await api.publish(publishOpts);
41-
})();
10+
import { resolveWorkingDir } from './util/resolve-working-dir';
11+
12+
program
13+
.version(packageJSON.version, '-V, --version', 'Output the current version.')
14+
.helpOption('-h, --help', 'Output usage information.')
15+
.argument('[dir]', 'Directory to run the command in. (default: current directory)')
16+
.option('--target [target[,target...]]', 'A comma-separated list of deployment targets. (default: all publishers in your Forge config)')
17+
.option('--dry-run', `Run the ${chalk.green('make')} command and save publish metadata without uploading anything.`)
18+
.option('--from-dry-run', 'Publish artifacts from the last saved dry run.')
19+
.allowUnknownOption(true)
20+
.action(async (targetDir) => {
21+
const dir = resolveWorkingDir(targetDir);
22+
const options = program.opts();
23+
24+
initializeProxy();
25+
26+
const publishOpts: PublishOptions = {
27+
dir,
28+
interactive: true,
29+
dryRun: options.dryRun,
30+
dryRunResume: options.fromDryRun,
31+
};
32+
if (options.target) publishOpts.publishTargets = options.target.split(',');
33+
34+
publishOpts.makeOptions = await getMakeOptions();
35+
36+
await api.publish(publishOpts);
37+
})
38+
.parse(process.argv);

packages/api/cli/src/electron-forge-start.ts

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { api, StartOptions } from '@electron-forge/core';
22
import { ElectronProcess } from '@electron-forge/shared-types';
3-
import { program } from 'commander';
3+
import { Option, program } from 'commander';
44

55
import './util/terminate';
66
import packageJSON from '../package.json';
77

8-
import workingDir from './util/working-dir';
8+
import { resolveWorkingDir } from './util/resolve-working-dir';
99

1010
(async () => {
1111
let commandArgs = process.argv;
@@ -17,16 +17,17 @@ import workingDir from './util/working-dir';
1717
appArgs = process.argv.slice(doubleDashIndex + 1);
1818
}
1919

20-
let dir = process.cwd();
20+
let dir;
2121
program
22-
.version(packageJSON.version, '-V, --version', 'Output the current version')
23-
.arguments('[cwd]')
24-
.option('-p, --app-path <path>', "Override the path to the Electron app to launch (defaults to '.')")
25-
.option('-l, --enable-logging', 'Enable advanced logging. This will log internal Electron things')
26-
.option('-n, --run-as-node', 'Run the Electron app as a Node.JS script')
27-
.option('--vscode', 'Used to enable arg transformation for debugging Electron through VSCode. Do not use yourself.')
28-
.option('-i, --inspect-electron', 'Triggers inspect mode on Electron to allow debugging the main process. Electron >1.7 only')
29-
.option('--inspect-brk-electron', 'Triggers inspect-brk mode on Electron to allow debugging the main process. Electron >1.7 only')
22+
.version(packageJSON.version, '-V, --version', 'Output the current version.')
23+
.helpOption('-h, --help', 'Output usage information.')
24+
.argument('[dir]', 'Directory to run the command in. (default: current directory)')
25+
.option('-p, --app-path <path>', 'Path to the Electron app to launch. (default: current directory)')
26+
.option('-l, --enable-logging', 'Enable internal Electron logging.')
27+
.option('-n, --run-as-node', 'Run the Electron app as a Node.JS script.')
28+
.addOption(new Option('--vscode').hideHelp()) // Used to enable arg transformation for debugging Electron through VSCode. Hidden from users.
29+
.option('-i, --inspect-electron', 'Run Electron in inspect mode to allow debugging the main process.')
30+
.option('--inspect-brk-electron', 'Run Electron in inspect-brk mode to allow debugging the main process.')
3031
.addHelpText(
3132
'after',
3233
`
@@ -37,8 +38,8 @@ import workingDir from './util/working-dir';
3738
...will pass the arguments "-d -f foo.txt" to the Electron app.`
3839
)
3940
.passThroughOptions(true) // allows args to be passed down to the Electron executable
40-
.action((cwd) => {
41-
dir = workingDir(dir, cwd);
41+
.action((targetDir: string) => {
42+
dir = resolveWorkingDir(targetDir);
4243
})
4344
.parse(commandArgs);
4445

0 commit comments

Comments
 (0)