Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cli): clean up output #3851

Merged
merged 3 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { resolvePackageManager, spawnPackageManager } from '@electron-forge/core-utils';
import { describe, expect, it, vi } from 'vitest';

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

vi.mock(import('@electron-forge/core-utils'), async (importOriginal) => {
const mod = await importOriginal();
Expand Down
49 changes: 49 additions & 0 deletions packages/api/cli/spec/util/resolve-working-dir.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import path from 'node:path';

import { describe, expect, it } from 'vitest';

import { resolveWorkingDir } from '../../src/util/resolve-working-dir';

describe('resolveWorkingDir', () => {
it('resolves relative paths according to the current working directory', () => {
const dir = resolveWorkingDir('.');

expect(dir).toEqual(process.cwd());
});

it('works with an absolute directory', () => {
const upOne = path.resolve(process.cwd(), '..');
expect(path.isAbsolute(upOne)).toBe(true);
const dir = resolveWorkingDir(upOne);

expect(dir).toEqual(upOne);
});

it('resolves a relative path if checkExisting=false and dir does not exist', () => {
const dir = resolveWorkingDir('./i-made-this-dir-up', false);

expect(dir).toEqual(path.resolve(process.cwd(), './i-made-this-dir-up'));
});

it('resolves an absolute path if checkExisting=false and dir does not exist', () => {
const fakeDir = path.resolve(process.cwd(), './i-made-this-dir-up');
expect(path.isAbsolute(fakeDir)).toBe(true);
const dir = resolveWorkingDir(fakeDir, false);

expect(dir).toEqual(fakeDir);
});

it('falls back to the current working directory with a relative path if checkExisting=true and dir does not exist', () => {
const dir = resolveWorkingDir('./i-made-this-dir-up', true);

expect(dir).toEqual(process.cwd());
});

it('falls back to the current working directory with an absolute path if checkExisting=true and dir does not exist', () => {
const fakeDir = path.resolve(process.cwd(), './i-made-this-dir-up');
expect(path.isAbsolute(fakeDir)).toBe(true);
const dir = resolveWorkingDir(fakeDir);

expect(dir).toEqual(process.cwd());
});
});
30 changes: 13 additions & 17 deletions packages/api/cli/src/electron-forge-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,17 @@ import { program } from 'commander';
import './util/terminate';
import packageJSON from '../package.json';

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

(async () => {
let dir = process.cwd();
program
.version(packageJSON.version, '-V, --version', 'Output the current version')
.helpOption('-h, --help', 'Output usage information')
.arguments('[name]')
.action((name) => {
dir = workingDir(dir, name, false);
})
.parse(process.argv);

await api.import({
dir,
interactive: true,
});
})();
program
.version(packageJSON.version, '-V, --version', 'Output the current version.')
.helpOption('-h, --help', 'Output usage information.')
.argument('[dir]', 'Directory of the project to import. (default: current directory)')
.action(async (dir: string) => {
const workingDir = resolveWorkingDir(dir, false);
await api.import({
dir: workingDir,
interactive: true,
});
})
.parse(process.argv);
45 changes: 21 additions & 24 deletions packages/api/cli/src/electron-forge-init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,28 @@ import { program } from 'commander';
import './util/terminate';
import packageJSON from '../package.json';

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

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

const options = program.opts();
const options = program.opts();

const initOpts: InitOptions = {
dir,
interactive: true,
copyCIFiles: !!options.copyCiFiles,
force: !!options.force,
};
if (options.template) initOpts.template = options.template;
const initOpts: InitOptions = {
dir: workingDir,
interactive: true,
copyCIFiles: !!options.copyCiFiles,
force: !!options.force,
};
if (options.template) initOpts.template = options.template;

await api.init(initOpts);
})();
await api.init(initOpts);
})
.parse(process.argv);
28 changes: 14 additions & 14 deletions packages/api/cli/src/electron-forge-make.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
import { initializeProxy } from '@electron/get';
import { api, MakeOptions } from '@electron-forge/core';
import chalk from 'chalk';
import { program } from 'commander';

import './util/terminate';
import packageJSON from '../package.json';

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

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

const options = program.opts();

const makeOpts: MakeOptions = {
dir,
dir: workingDir!,
interactive: true,
skipPackage: options.skipPackage,
};
Expand All @@ -37,8 +38,7 @@ export async function getMakeOptions(): Promise<MakeOptions> {
return makeOpts;
}

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

Expand Down
43 changes: 20 additions & 23 deletions packages/api/cli/src/electron-forge-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,28 @@ import { program } from 'commander';
import './util/terminate';
import packageJSON from '../package.json';

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

(async () => {
let dir: string = process.cwd();
program
.version(packageJSON.version, '-V, --version', 'Output the current version')
.arguments('[cwd]')
.option('-a, --arch [arch]', 'Target architecture')
.option('-p, --platform [platform]', 'Target build platform')
.helpOption('-h, --help', 'Output usage information')
.action((cwd) => {
dir = workingDir(dir, cwd);
})
.parse(process.argv);
program
.version(packageJSON.version, '-V, --version', 'Output the current version')
.helpOption('-h, --help', 'Output usage information')
.argument('[dir]', 'Directory to run the command in. (default: current directory)')
.option('-a, --arch [arch]', 'Target build architecture')
.option('-p, --platform [platform]', 'Target build platform')
.action(async (dir) => {
const workingDir = resolveWorkingDir(dir);

const options = program.opts();
const options = program.opts();

initializeProxy();
initializeProxy();

const packageOpts: PackageOptions = {
dir,
interactive: true,
};
if (options.arch) packageOpts.arch = options.arch;
if (options.platform) packageOpts.platform = options.platform;
const packageOpts: PackageOptions = {
dir: workingDir,
interactive: true,
};
if (options.arch) packageOpts.arch = options.arch;
if (options.platform) packageOpts.platform = options.platform;

await api.package(packageOpts);
})();
await api.package(packageOpts);
})
.parse(process.argv);
63 changes: 30 additions & 33 deletions packages/api/cli/src/electron-forge-publish.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,38 @@
import { initializeProxy } from '@electron/get';
import { api, PublishOptions } from '@electron-forge/core';
import chalk from 'chalk';
import { program } from 'commander';

import './util/terminate';
import packageJSON from '../package.json';

import { getMakeOptions } from './electron-forge-make';
import workingDir from './util/working-dir';

(async () => {
let dir = process.cwd();
program
.version(packageJSON.version, '-V, --version', 'Output the current version')
.arguments('[cwd]')
.option('--target [target[,target...]]', 'The comma-separated deployment targets, defaults to "github"')
.option('--dry-run', "Triggers a publish dry run which saves state and doesn't upload anything")
.option('--from-dry-run', 'Attempts to publish artifacts from the last saved dry run')
.helpOption('-h, --help', 'Output usage information')
.allowUnknownOption(true)
.action((cwd) => {
dir = workingDir(dir, cwd);
})
.parse(process.argv);

const options = program.opts();

initializeProxy();

const publishOpts: PublishOptions = {
dir,
interactive: true,
dryRun: options.dryRun,
dryRunResume: options.fromDryRun,
};
if (options.target) publishOpts.publishTargets = options.target.split(',');

publishOpts.makeOptions = await getMakeOptions();

await api.publish(publishOpts);
})();
import { resolveWorkingDir } from './util/resolve-working-dir';

program
.version(packageJSON.version, '-V, --version', 'Output the current version.')
.helpOption('-h, --help', 'Output usage information.')
.argument('[dir]', 'Directory to run the command in. (default: current directory)')
.option('--target [target[,target...]]', 'A comma-separated list of deployment targets. (default: all publishers in your Forge config)')
.option('--dry-run', `Run the ${chalk.green('make')} command and save publish metadata without uploading anything.`)
.option('--from-dry-run', 'Publish artifacts from the last saved dry run.')
.allowUnknownOption(true)
.action(async (targetDir) => {
const dir = resolveWorkingDir(targetDir);
const options = program.opts();

initializeProxy();

const publishOpts: PublishOptions = {
dir,
interactive: true,
dryRun: options.dryRun,
dryRunResume: options.fromDryRun,
};
if (options.target) publishOpts.publishTargets = options.target.split(',');

publishOpts.makeOptions = await getMakeOptions();

await api.publish(publishOpts);
})
.parse(process.argv);
27 changes: 14 additions & 13 deletions packages/api/cli/src/electron-forge-start.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { api, StartOptions } from '@electron-forge/core';
import { ElectronProcess } from '@electron-forge/shared-types';
import { program } from 'commander';
import { Option, program } from 'commander';

import './util/terminate';
import packageJSON from '../package.json';

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

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

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

Expand Down
Loading