Skip to content

Commit

Permalink
Merge pull request #14 from dherman/target-families
Browse files Browse the repository at this point in the history
Target family presets
  • Loading branch information
dherman authored Nov 23, 2023
2 parents 7f267f7 + faca4be commit bf34a89
Show file tree
Hide file tree
Showing 15 changed files with 514 additions and 68 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
uses: neon-actions/[email protected]
with:
working-directory: ./pkgs/cargo-messages
target: linux-x64-gnu
input-directory: npm/linux-x64-gnu
node-version: ${{ env.NODE_VERSION }}
use-cross: false
npm-publish: false
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ jobs:
uses: neon-actions/[email protected]
with:
working-directory: ./pkgs/cargo-messages
target: ${{ matrix.target }}
input-directory: npm/${{ matrix.target }}
node-version: ${{ env.NODE_VERSION }}
npm-publish: false
github-release: ${{ needs.setup.outputs.action == 'publish' }}
Expand Down Expand Up @@ -102,7 +102,7 @@ jobs:
uses: neon-actions/[email protected]
with:
working-directory: ./pkgs/cargo-messages
target: ${{ matrix.target }}
input-directory: npm/${{ matrix.target }}
node-version: ${{ env.NODE_VERSION }}
npm-publish: false
github-release: ${{ needs.setup.outputs.action == 'publish' }}
Expand Down Expand Up @@ -139,7 +139,7 @@ jobs:
uses: neon-actions/[email protected]
with:
working-directory: ./pkgs/cargo-messages
target: ${{ matrix.target }}
input-directory: npm/${{ matrix.target }}
node-version: ${{ env.NODE_VERSION }}
use-cross: true
npm-publish: false
Expand Down
251 changes: 220 additions & 31 deletions pkgs/cli/index.js

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions src/cli/data/family.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"windows": {
"win32-x64-msvc": "x86_64-pc-windows-msvc"
},
"macos": {
"darwin-x64": "x86_64-apple-darwin",
"darwin-arm64": "aarch64-apple-darwin"
},
"linux": {
"linux-x64-gnu": "x86_64-unknown-linux-gnu",
"linux-arm-gnueabihf": "armv7-unknown-linux-gnueabihf"
},
"desktop": {
"win32-x64-msvc": "x86_64-pc-windows-msvc",
"darwin-x64": "x86_64-apple-darwin",
"darwin-arm64": "aarch64-apple-darwin",
"linux-x64-gnu": "x86_64-unknown-linux-gnu"
},
"mobile": {
"win32-arm64-msvc": "aarch64-pc-windows-msvc",
"linux-arm-gnueabihf": "armv7-unknown-linux-gnueabihf",
"android-arm-eabi": "armv7-linux-androideabi"
},
"common": ["desktop"],
"extended": ["desktop", "mobile"]
}
13 changes: 10 additions & 3 deletions src/cli/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ import Bump from './commands/bump.js';
import Tarball from './commands/tarball.js';
import AddTarget from './commands/add-target.js';
import UpdateTargets from './commands/update-targets.js';
import RustTarget from './commands/rust-target.js';
import Help from './commands/help.js';

export interface Command {
run(): Promise<void>;
}

export type CommandSection = { title: string, details: CommandDetail[] };

export interface CommandStatics {
summary(): string;
syntax(): string;
options(): CommandDetail[];
seeAlso(): CommandDetail[] | void;
extraSection(): CommandSection | void;
}

export type CommandClass = (new (argv: string[]) => Command) & CommandStatics;
Expand All @@ -31,7 +35,8 @@ export enum CommandName {
Tarball = 'tarball',
AddTarget = 'add-target',
InstallBuilds = 'install-builds', // deprecated but retained for compat
UpdateTargets = 'update-targets'
UpdateTargets = 'update-targets',
RustTarget = 'rust-target'
};

export function isCommandName(s: string): s is CommandName {
Expand All @@ -54,7 +59,8 @@ const COMMANDS: Record<CommandName, CommandClass> = {
[CommandName.Tarball]: Tarball,
[CommandName.AddTarget]: AddTarget,
[CommandName.InstallBuilds]: UpdateTargets, // deprecated but retained for compat
[CommandName.UpdateTargets]: UpdateTargets
[CommandName.UpdateTargets]: UpdateTargets,
[CommandName.RustTarget]: RustTarget
};

export function commandFor(name: CommandName): CommandClass {
Expand All @@ -68,6 +74,7 @@ export function summaries(): CommandDetail[] {
{ name: CommandName.Bump, summary: Bump.summary() },
{ name: CommandName.Tarball, summary: Tarball.summary() },
{ name: CommandName.AddTarget, summary: AddTarget.summary() },
{ name: CommandName.UpdateTargets, summary: UpdateTargets.summary() }
{ name: CommandName.UpdateTargets, summary: UpdateTargets.summary() },
{ name: CommandName.RustTarget, summary: RustTarget.summary() }
];
}
83 changes: 68 additions & 15 deletions src/cli/src/commands/add-target.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,66 @@
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import commandLineArgs from 'command-line-args';
import { Command, CommandDetail } from '../command.js';
import { getCurrentTarget, isNodeTarget, isRustTarget } from '../target.js';
import { Command, CommandDetail, CommandSection } from '../command.js';
import { expandTargetFamily, getCurrentTarget, isNodeTarget, isRustTarget, isTargetFamilyKey, NodeTarget, RustTarget, TargetPair } from '../target.js';
import { SourceManifest } from '../manifest.js';

function optionArray<T>(option: T | undefined | null): T[] {
return option == null ? [] : [option];
}

const OPTIONS = [
{ name: 'bundle', alias: 'b', type: String, defaultValue: null },
{ name: 'platform', alias: 'p', type: String, defaultValue: null },
{ name: 'arch', alias: 'a', type: String, defaultValue: null },
{ name: 'abi', type: String, defaultValue: null },
{ name: 'out-dir', alias: 'o', type: String, defaultValue: 'npm' },
{ name: 'verbose', alias: 'v', type: Boolean, defaultValue: false }
];

export default class AddTarget implements Command {
static summary(): string { return 'Add a new build target to package.json.'; }
static syntax(): string { return 'neon add-target [<target> | -p <plat> -a <arch> [--abi <abi>]] [-b <file>]'; }
static syntax(): string { return 'neon add-target [<t> | -p <p> -a <arch> [--abi <abi>]] [-o <d>] [-b <f>]'; }
static options(): CommandDetail[] {
return [
{ name: '<target>', summary: 'Full target name, in either Node or Rust convention. (Default: current target)' },
{ name: '-p, --platform <plat>', summary: 'Target platform name. (Default: current platform)' },
{ name: '<t>', summary: 'Full target name, in either Node or Rust convention.' },
{
name: '',
summary: 'This may be a target name in either Node or Rust convention, or one of the Neon target family presets described below. (Default: current target)'
},
{ name: '-p, --platform <p>', summary: 'Target platform name. (Default: current platform)' },
{ name: '-a, --arch <arch>', summary: 'Target architecture name. (Default: current arch)' },
{ name: '--abi <abi>', summary: 'Target ABI name. (Default: current ABI)' },
{ name: '-b, --bundle <file>', summary: 'File to generate bundling metadata.' },
{ name: '-o, --out-dir <d>', summary: 'Output directory for target template tree. (Default: npm)' },
{ name: '-b, --bundle <f>', summary: 'File to generate bundling metadata.' },
{
name: '',
summary: 'This generated file ensures support for bundlers (e.g. @vercel/ncc), which rely on static analysis to detect and enable any addons used by the library.'
},
{ name: '-v, --verbose', summary: 'Enable verbose logging. (Default: false)' }
];
}
static seeAlso(): CommandDetail[] | void {
return [
];
static seeAlso(): CommandDetail[] | void { }
static extraSection(): CommandSection | void {
return {
title: 'Target Family Presets',
details: [
{ name: 'linux', summary: 'Common desktop Linux targets.' },
{ name: 'macos', summary: 'Common desktop macOS targets.' },
{ name: 'windows', summary: 'Common desktop Windows targets.' },
{ name: 'mobile', summary: 'Common mobile and tablet targets.' },
{ name: 'desktop', summary: 'All common desktop targets.' },
{ name: 'common', summary: 'All common targets.' },
{ name: 'extended', summary: 'All supported targets.' }
]
};
}

private _platform: string | null;
private _arch: string | null;
private _abi: string | null;
private _target: string | null;
private _outDir: string;
private _bundle: string | null;
private _verbose: boolean;

Expand All @@ -46,6 +70,7 @@ export default class AddTarget implements Command {
this._platform = options.platform || null;
this._arch = options.arch || null;
this._abi = options.abi || null;
this._outDir = options['out-dir'] || path.join(process.cwd(), 'dist');
this._bundle = options.bundle || null;
this._verbose = !!options.verbose;

Expand All @@ -67,7 +92,11 @@ export default class AddTarget implements Command {
}
this._target = options._unknown[0];
} else {
this._target = null;
this._target = `${options.platform}-${options.arch}`;

if (!!options.abi) {
this._target = `${this._target}-${options.abi}`;
}
}
}

Expand All @@ -77,28 +106,52 @@ export default class AddTarget implements Command {
}
}

async addTarget(sourceManifest: SourceManifest): Promise<boolean> {
async addTarget(sourceManifest: SourceManifest): Promise<TargetPair[]> {
if (!this._target) {
this.log('adding default system target');
return sourceManifest.addRustTarget(await getCurrentTarget(msg => this.log(msg)));
return optionArray(await sourceManifest.addRustTarget(await getCurrentTarget(msg => this.log(msg))));
} else if (isRustTarget(this._target)) {
this.log(`adding Rust target ${this._target}`);
return sourceManifest.addRustTarget(this._target);
return optionArray(await sourceManifest.addRustTarget(this._target));
} else if (isNodeTarget(this._target)) {
this.log(`adding Node target ${this._target}`);
return sourceManifest.addNodeTarget(this._target);
return optionArray(await sourceManifest.addNodeTarget(this._target));
} else if (isTargetFamilyKey(this._target)) {
return sourceManifest.addTargets(expandTargetFamily(this._target));
} else {
throw new Error(`unrecognized target ${this._target}`);
}
}

async createTemplateTree(sourceManifest: SourceManifest, pair: TargetPair): Promise<void> {
const { node, rust } = pair;
const binaryManifest = sourceManifest.manifestFor(rust);
this.log(`prebuild manifest: ${binaryManifest.stringify()}`);

const treeDir = path.join(this._outDir, node);

this.log(`creating ${treeDir}`);
await fs.mkdir(treeDir, { recursive: true });
this.log(`created ${treeDir}`);

this.log(`creating ${treeDir}/package.json`);
await binaryManifest.save(treeDir);

this.log(`creating ${treeDir}/README.md`);
await fs.writeFile(path.join(treeDir, "README.md"), `# \`${binaryManifest.name}\`\n\n${binaryManifest.description}\n`);
}

async run() {
this.log(`reading package.json`);
const sourceManifest = await SourceManifest.load();
this.log(`manifest: ${sourceManifest.stringify()}`);

if (await this.addTarget(sourceManifest)) {
const modified = await this.addTarget(sourceManifest);
if (modified.length) {
sourceManifest.updateTargets(msg => this.log(msg), this._bundle);
for (const pair of modified) {
await this.createTemplateTree(sourceManifest, pair);
}
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/cli/src/commands/bump.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { execa } from 'execa';
import commandLineArgs from 'command-line-args';
import * as fs from 'node:fs/promises';
import * as path from 'node:path';
import { Command, CommandDetail } from '../command.js';
import { Command, CommandDetail, CommandSection } from '../command.js';

const OPTIONS = [
{ name: 'verbose', alias: 'v', type: Boolean, defaultValue: false },
Expand Down Expand Up @@ -43,6 +43,7 @@ export default class Bump implements Command {
{ name: 'npm version', summary: '<https://docs.npmjs.com/cli/commands/npm-version>' }
];
}
static extraSection(): CommandSection | void { }

private _verbose: boolean;
private _dir: string | null;
Expand Down
3 changes: 2 additions & 1 deletion src/cli/src/commands/dist.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createReadStream } from 'node:fs';
import { copyFile } from 'node:fs/promises';
import commandLineArgs from 'command-line-args';
import { Command, CommandDetail } from '../command.js';
import { Command, CommandDetail, CommandSection } from '../command.js';
import { CargoMessages, CargoReader } from 'cargo-messages';

// FIXME: add options to infer crate name from manifests
Expand Down Expand Up @@ -44,6 +44,7 @@ export default class Dist implements Command {
{ name: 'cross-rs', summary: '<https://github.com/cross-rs/cross>' }
];
}
static extraSection(): CommandSection | void { }

private _log: string | null;
private _file: string | null;
Expand Down
3 changes: 2 additions & 1 deletion src/cli/src/commands/help.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { printMainUsage, printCommandUsage } from '../print.js';
import { Command, CommandName, CommandDetail, asCommandName } from '../command.js';
import { Command, CommandName, CommandDetail, CommandSection, asCommandName } from '../command.js';

export default class Help implements Command {
static summary(): string { return 'Display help information about Neon.'; }
Expand All @@ -10,6 +10,7 @@ export default class Help implements Command {
];
}
static seeAlso(): CommandDetail[] | void { }
static extraSection(): CommandSection | void { }

private _name?: CommandName;

Expand Down
Loading

0 comments on commit bf34a89

Please sign in to comment.