diff --git a/cli/codegen/commands.ts b/cli/codegen/commands.ts index d78e8444..33e7bd50 100644 --- a/cli/codegen/commands.ts +++ b/cli/codegen/commands.ts @@ -31,7 +31,7 @@ const NEW_OPTIONS: CommandSchema = { { name: 'path', type: 'string', - description: 'The path where the napi-rs project will be created.', + description: 'The path where the NAPI-RS project will be created.', required: true, }, ], @@ -108,7 +108,7 @@ const NEW_OPTIONS: CommandSchema = { const BUILD_OPTIONS: CommandSchema = { name: 'build', - description: 'Build the napi-rs project', + description: 'Build the NAPI-RS project', args: [], options: [ { @@ -129,6 +129,12 @@ const BUILD_OPTIONS: CommandSchema = { type: 'string', description: 'Path to `Cargo.toml`', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', @@ -253,7 +259,7 @@ const BUILD_OPTIONS: CommandSchema = { name: 'watch', type: 'boolean', description: - 'watch the crate changes and build continiously with `cargo-watch` crates', + 'watch the crate changes and build continuously with `cargo-watch` crates', short: 'w', }, { @@ -288,6 +294,12 @@ const ARTIFACTS_OPTIONS: CommandSchema = { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', default: 'process.cwd()', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', @@ -323,6 +335,12 @@ const CREATE_NPM_DIRS_OPTIONS: CommandSchema = { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', default: 'process.cwd()', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', @@ -346,7 +364,7 @@ const CREATE_NPM_DIRS_OPTIONS: CommandSchema = { const RENAME_OPTIONS: CommandSchema = { name: 'rename', - description: 'Rename the napi-rs project', + description: 'Rename the NAPI-RS project', args: [], options: [ { @@ -356,6 +374,12 @@ const RENAME_OPTIONS: CommandSchema = { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', default: 'process.cwd()', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', @@ -416,6 +440,12 @@ const UNIVERSALIZE_OPTIONS: CommandSchema = { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', default: 'process.cwd()', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', @@ -445,6 +475,12 @@ const VERSION_OPTIONS: CommandSchema = { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', default: 'process.cwd()', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', @@ -472,6 +508,12 @@ const PRE_PUBLISH_OPTIONS: CommandSchema = { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', default: 'process.cwd()', }, + { + name: 'configPath', + type: 'string', + description: 'Path to `napi` config json file', + short: 'c', + }, { name: 'packageJsonPath', type: 'string', diff --git a/cli/docs/artifacts.md b/cli/docs/artifacts.md index 8a218f7b..0638900b 100644 --- a/cli/docs/artifacts.md +++ b/cli/docs/artifacts.md @@ -26,6 +26,7 @@ new NapiCli().artifacts({ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | | | --help,-h | | | | get help | | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | | outputDir | --output-dir,-o | string | false | './artifacts' | Path to the folder where all built `.node` files put, same as `--output-dir` of build command | | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | diff --git a/cli/docs/build.md b/cli/docs/build.md index 00f4c257..4e5cd616 100644 --- a/cli/docs/build.md +++ b/cli/docs/build.md @@ -2,7 +2,7 @@ > This file is generated by cli/codegen. Do not edit this file manually. -Build the napi-rs project +Build the NAPI-RS project ## Usage @@ -28,6 +28,7 @@ new NapiCli().build({ | target | --target,-t | string | false | | Build for the target triple, bypassed to `cargo build --target` | | cwd | --cwd | string | false | | The working directory of where napi command will be executed in, all other paths options are relative to this path | | manifestPath | --manifest-path | string | false | | Path to `Cargo.toml` | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | | Path to `package.json` | | targetDir | --target-dir | string | false | | Directory for all crate generated artifacts, see `cargo build --target-dir` | | outputDir | --output-dir,-o | string | false | | Path to where all the built files would be put. Default to the crate folder | @@ -48,7 +49,7 @@ new NapiCli().build({ | crossCompile | --cross-compile,-x | boolean | false | | [experimental] cross-compile for the specified target with `cargo-xwin` on windows and `cargo-zigbuild` on other platform | | useCross | --use-cross | boolean | false | | [experimental] use [cross](https://github.com/cross-rs/cross) instead of `cargo` | | useNapiCross | --use-napi-cross | boolean | false | | [experimental] use @napi-rs/cross-toolchain to cross-compile Linux arm/arm64/x64 gnu targets. | -| watch | --watch,-w | boolean | false | | watch the crate changes and build continiously with `cargo-watch` crates | +| watch | --watch,-w | boolean | false | | watch the crate changes and build continuously with `cargo-watch` crates | | features | --features,-F | string[] | false | | Space-separated list of features to activate | | allFeatures | --all-features | boolean | false | | Activate all available features | | noDefaultFeatures | --no-default-features | boolean | false | | Do not activate the `default` feature | diff --git a/cli/docs/create-npm-dirs.md b/cli/docs/create-npm-dirs.md index 6279bad8..1ee705a7 100644 --- a/cli/docs/create-npm-dirs.md +++ b/cli/docs/create-npm-dirs.md @@ -26,6 +26,7 @@ new NapiCli().createNpmDirs({ | --------------- | ------------------- | ------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | | | --help,-h | | | | get help | | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | | dryRun | --dry-run | boolean | false | false | Dry run without touching file system | diff --git a/cli/docs/new.md b/cli/docs/new.md index ad17bfdb..a58b9e3b 100644 --- a/cli/docs/new.md +++ b/cli/docs/new.md @@ -25,7 +25,7 @@ new NapiCli().new({ | Options | CLI Options | type | required | default | description | | -------------------- | ------------------------ | -------- | -------- | ------- | -------------------------------------------------------------------------------- | | | --help,-h | | | | get help | -| path | | true | string | | The path where the napi-rs project will be created. | +| path | | true | string | | The path where the NAPI-RS project will be created. | | name | --name,-n | string | false | | The name of the project, default to the name of the directory if not provided | | minNodeApiVersion | --min-node-api,-v | number | false | 4 | The minimum Node-API version to support | | license | --license,-l | string | false | 'MIT' | License for open-sourced project | diff --git a/cli/docs/pre-publish.md b/cli/docs/pre-publish.md index 3b983561..c2a9e059 100644 --- a/cli/docs/pre-publish.md +++ b/cli/docs/pre-publish.md @@ -26,6 +26,7 @@ new NapiCli().prePublish({ | --------------- | ------------------- | ---------------- | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | | | --help,-h | | | | get help | | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | | tagStyle | --tag-style | 'npm' \| 'lerna' | false | 'lerna' | git tag style, `npm` or `lerna` | diff --git a/cli/docs/rename.md b/cli/docs/rename.md index 0ade2270..b75e52b5 100644 --- a/cli/docs/rename.md +++ b/cli/docs/rename.md @@ -2,7 +2,7 @@ > This file is generated by cli/codegen. Do not edit this file manually. -Rename the napi-rs project +Rename the NAPI-RS project ## Usage @@ -26,6 +26,7 @@ new NapiCli().rename({ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | | | --help,-h | | | | get help | | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | | name | --name,-n | string | false | | The new name of the project | diff --git a/cli/docs/universalize.md b/cli/docs/universalize.md index a5916ea1..57adf10e 100644 --- a/cli/docs/universalize.md +++ b/cli/docs/universalize.md @@ -26,5 +26,6 @@ new NapiCli().universalize({ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | | | --help,-h | | | | get help | | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | | outputDir | --output-dir,-o | string | false | './' | Path to the folder where all built `.node` files put, same as `--output-dir` of build command | diff --git a/cli/docs/version.md b/cli/docs/version.md index 8cc02c80..5e6fa7bc 100644 --- a/cli/docs/version.md +++ b/cli/docs/version.md @@ -26,5 +26,6 @@ new NapiCli().version({ | --------------- | ------------------- | ------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | | | --help,-h | | | | get help | | cwd | --cwd | string | false | process.cwd() | The working directory of where napi command will be executed in, all other paths options are relative to this path | +| configPath | --config-path,-c | string | false | | Path to `napi` config json file | | packageJsonPath | --package-json-path | string | false | 'package.json' | Path to `package.json` | | npmDir | --npm-dir | string | false | 'npm' | Path to the folder where the npm packages put | diff --git a/cli/src/api/build.ts b/cli/src/api/build.ts index 8b664ad6..97f5505c 100644 --- a/cli/src/api/build.ts +++ b/cli/src/api/build.ts @@ -90,7 +90,10 @@ export async function buildProject(options: BuildOptions) { process.env.CARGO_BUILD_TARGET_DIR ?? metadata.target_directory, await readNapiConfig( - resolvePath(options.packageJsonPath ?? 'package.json'), + resolvePath( + options.configPath ?? options.packageJsonPath ?? 'package.json', + ), + options.configPath ? resolvePath(options.configPath) : undefined, ), ) diff --git a/cli/src/api/create-npm-dirs.ts b/cli/src/api/create-npm-dirs.ts index e4cbdb08..d2065552 100644 --- a/cli/src/api/create-npm-dirs.ts +++ b/cli/src/api/create-npm-dirs.ts @@ -43,10 +43,13 @@ export async function createNpmDirs(userOptions: CreateNpmDirsOptions) { const packageJsonPath = resolve(options.cwd, options.packageJsonPath) const npmPath = resolve(options.cwd, options.npmDir) - debug(`Read content from [${packageJsonPath}]`) + debug(`Read content from [${options.configPath ?? packageJsonPath}]`) const { targets, binaryName, packageName, packageJson } = - await readNapiConfig(packageJsonPath) + await readNapiConfig( + packageJsonPath, + options.configPath ? resolve(options.cwd, options.configPath) : undefined, + ) for (const target of targets) { const targetDir = join(npmPath, `${target.platformArchABI}`) diff --git a/cli/src/api/pre-publish.ts b/cli/src/api/pre-publish.ts index b6e4f5b7..87d94f5e 100644 --- a/cli/src/api/pre-publish.ts +++ b/cli/src/api/pre-publish.ts @@ -31,10 +31,14 @@ export async function prePublish(userOptions: PrePublishOptions) { const options = applyDefaultPrePublishOptions(userOptions) + const configPath = relative( + options.cwd, + options.configPath ?? options.packageJsonPath, + ) const packageJsonPath = relative(options.cwd, options.packageJsonPath) const { packageJson, targets, packageName, binaryName, npmClient } = - await readNapiConfig(packageJsonPath) + await readNapiConfig(configPath, configPath) async function createGhRelease(packageName: string, version: string) { if (!options.ghRelease) { diff --git a/cli/src/api/rename.ts b/cli/src/api/rename.ts index c948b7e0..e4da7541 100644 --- a/cli/src/api/rename.ts +++ b/cli/src/api/rename.ts @@ -30,6 +30,15 @@ export async function renameProject(userOptions: RenameOptions) { }, ) + if (options.configPath) { + const configPath = resolve(options.cwd, options.configPath) + const configContent = await readFileAsync(configPath, 'utf8') + const configData = JSON.parse(configContent) + configData.binaryName = options.binaryName + configData.packageName = options.packageName + await writeFileAsync(configPath, JSON.stringify(configData, null, 2)) + } + await writeFileAsync( packageJsonPath, JSON.stringify(packageJsonData, null, 2), diff --git a/cli/src/api/universalize.ts b/cli/src/api/universalize.ts index 53ebd860..a0a05c70 100644 --- a/cli/src/api/universalize.ts +++ b/cli/src/api/universalize.ts @@ -27,7 +27,10 @@ export async function universalizeBinaries(userOptions: UniversalizeOptions) { const packageJsonPath = join(options.cwd, options.packageJsonPath) - const config = await readNapiConfig(packageJsonPath) + const config = await readNapiConfig( + packageJsonPath, + options.configPath ? resolve(options.cwd, options.configPath) : undefined, + ) const target = config.targets.find( (t) => t.platform === process.platform && t.arch === 'universal', diff --git a/cli/src/api/version.ts b/cli/src/api/version.ts index fa3e47cc..af0a6f41 100644 --- a/cli/src/api/version.ts +++ b/cli/src/api/version.ts @@ -13,7 +13,10 @@ export async function version(userOptions: VersionOptions) { const options = applyDefaultVersionOptions(userOptions) const packageJsonPath = resolve(options.cwd, options.packageJsonPath) - const config = await readNapiConfig(packageJsonPath) + const config = await readNapiConfig( + packageJsonPath, + options.configPath ? resolve(options.cwd, options.configPath) : undefined, + ) for (const target of config.targets) { const pkgDir = resolve(options.cwd, options.npmDir, target.platformArchABI) diff --git a/cli/src/def/artifacts.ts b/cli/src/def/artifacts.ts index 2e50439f..2e74c82b 100644 --- a/cli/src/def/artifacts.ts +++ b/cli/src/def/artifacts.ts @@ -15,6 +15,10 @@ export abstract class BaseArtifactsCommand extends Command { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath = Option.String('--package-json-path', 'package.json', { description: 'Path to `package.json`', }) @@ -31,6 +35,7 @@ export abstract class BaseArtifactsCommand extends Command { getOptions() { return { cwd: this.cwd, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, outputDir: this.outputDir, npmDir: this.npmDir, @@ -48,6 +53,10 @@ export interface ArtifactsOptions { * @default process.cwd() */ cwd?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` * diff --git a/cli/src/def/build.ts b/cli/src/def/build.ts index cb6ca2b7..3656da94 100644 --- a/cli/src/def/build.ts +++ b/cli/src/def/build.ts @@ -6,7 +6,7 @@ export abstract class BaseBuildCommand extends Command { static paths = [['build']] static usage = Command.Usage({ - description: 'Build the napi-rs project', + description: 'Build the NAPI-RS project', }) target?: string = Option.String('--target,-t', { @@ -23,6 +23,10 @@ export abstract class BaseBuildCommand extends Command { description: 'Path to `Cargo.toml`', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath?: string = Option.String('--package-json-path', { description: 'Path to `package.json`', }) @@ -117,7 +121,7 @@ export abstract class BaseBuildCommand extends Command { watch?: boolean = Option.Boolean('--watch,-w', { description: - 'watch the crate changes and build continiously with `cargo-watch` crates', + 'watch the crate changes and build continuously with `cargo-watch` crates', }) features?: string[] = Option.Array('--features,-F', { @@ -137,6 +141,7 @@ export abstract class BaseBuildCommand extends Command { target: this.target, cwd: this.cwd, manifestPath: this.manifestPath, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, targetDir: this.targetDir, outputDir: this.outputDir, @@ -166,7 +171,7 @@ export abstract class BaseBuildCommand extends Command { } /** - * Build the napi-rs project + * Build the NAPI-RS project */ export interface BuildOptions { /** @@ -181,6 +186,10 @@ export interface BuildOptions { * Path to `Cargo.toml` */ manifestPath?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` */ @@ -262,7 +271,7 @@ export interface BuildOptions { */ useNapiCross?: boolean /** - * watch the crate changes and build continiously with `cargo-watch` crates + * watch the crate changes and build continuously with `cargo-watch` crates */ watch?: boolean /** diff --git a/cli/src/def/create-npm-dirs.ts b/cli/src/def/create-npm-dirs.ts index d44bd630..5921be97 100644 --- a/cli/src/def/create-npm-dirs.ts +++ b/cli/src/def/create-npm-dirs.ts @@ -14,6 +14,10 @@ export abstract class BaseCreateNpmDirsCommand extends Command { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath = Option.String('--package-json-path', 'package.json', { description: 'Path to `package.json`', }) @@ -29,6 +33,7 @@ export abstract class BaseCreateNpmDirsCommand extends Command { getOptions() { return { cwd: this.cwd, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, npmDir: this.npmDir, dryRun: this.dryRun, @@ -46,6 +51,10 @@ export interface CreateNpmDirsOptions { * @default process.cwd() */ cwd?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` * diff --git a/cli/src/def/new.ts b/cli/src/def/new.ts index 387eb050..609e1f9e 100644 --- a/cli/src/def/new.ts +++ b/cli/src/def/new.ts @@ -72,7 +72,7 @@ export abstract class BaseNewCommand extends Command { */ export interface NewOptions { /** - * The path where the napi-rs project will be created. + * The path where the NAPI-RS project will be created. */ path: string /** diff --git a/cli/src/def/pre-publish.ts b/cli/src/def/pre-publish.ts index 12e7b9f3..12098cb8 100644 --- a/cli/src/def/pre-publish.ts +++ b/cli/src/def/pre-publish.ts @@ -15,6 +15,10 @@ export abstract class BasePrePublishCommand extends Command { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath = Option.String('--package-json-path', 'package.json', { description: 'Path to `package.json`', }) @@ -46,6 +50,7 @@ export abstract class BasePrePublishCommand extends Command { getOptions() { return { cwd: this.cwd, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, npmDir: this.npmDir, tagStyle: this.tagStyle, @@ -67,6 +72,10 @@ export interface PrePublishOptions { * @default process.cwd() */ cwd?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` * diff --git a/cli/src/def/rename.ts b/cli/src/def/rename.ts index ac54454d..3431039d 100644 --- a/cli/src/def/rename.ts +++ b/cli/src/def/rename.ts @@ -6,7 +6,7 @@ export abstract class BaseRenameCommand extends Command { static paths = [['rename']] static usage = Command.Usage({ - description: 'Rename the napi-rs project', + description: 'Rename the NAPI-RS project', }) cwd = Option.String('--cwd', process.cwd(), { @@ -14,6 +14,10 @@ export abstract class BaseRenameCommand extends Command { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath = Option.String('--package-json-path', 'package.json', { description: 'Path to `package.json`', }) @@ -49,6 +53,7 @@ export abstract class BaseRenameCommand extends Command { getOptions() { return { cwd: this.cwd, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, npmDir: this.npmDir, name: this.$$name, @@ -62,7 +67,7 @@ export abstract class BaseRenameCommand extends Command { } /** - * Rename the napi-rs project + * Rename the NAPI-RS project */ export interface RenameOptions { /** @@ -71,6 +76,10 @@ export interface RenameOptions { * @default process.cwd() */ cwd?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` * diff --git a/cli/src/def/universalize.ts b/cli/src/def/universalize.ts index 099bb851..624cbf84 100644 --- a/cli/src/def/universalize.ts +++ b/cli/src/def/universalize.ts @@ -14,6 +14,10 @@ export abstract class BaseUniversalizeCommand extends Command { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath = Option.String('--package-json-path', 'package.json', { description: 'Path to `package.json`', }) @@ -26,6 +30,7 @@ export abstract class BaseUniversalizeCommand extends Command { getOptions() { return { cwd: this.cwd, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, outputDir: this.outputDir, } @@ -42,6 +47,10 @@ export interface UniversalizeOptions { * @default process.cwd() */ cwd?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` * diff --git a/cli/src/def/version.ts b/cli/src/def/version.ts index c1fe0c2f..b6e8d1bf 100644 --- a/cli/src/def/version.ts +++ b/cli/src/def/version.ts @@ -14,6 +14,10 @@ export abstract class BaseVersionCommand extends Command { 'The working directory of where napi command will be executed in, all other paths options are relative to this path', }) + configPath?: string = Option.String('--config-path,-c', { + description: 'Path to `napi` config json file', + }) + packageJsonPath = Option.String('--package-json-path', 'package.json', { description: 'Path to `package.json`', }) @@ -25,6 +29,7 @@ export abstract class BaseVersionCommand extends Command { getOptions() { return { cwd: this.cwd, + configPath: this.configPath, packageJsonPath: this.packageJsonPath, npmDir: this.npmDir, } @@ -41,6 +46,10 @@ export interface VersionOptions { * @default process.cwd() */ cwd?: string + /** + * Path to `napi` config json file + */ + configPath?: string /** * Path to `package.json` * diff --git a/cli/src/utils/__tests__/__snapshots__/config.spec.ts.md b/cli/src/utils/__tests__/__snapshots__/config.spec.ts.md new file mode 100644 index 00000000..e3c8cc5c --- /dev/null +++ b/cli/src/utils/__tests__/__snapshots__/config.spec.ts.md @@ -0,0 +1,97 @@ +# Snapshot report for `src/utils/__tests__/config.spec.ts` + +The actual snapshot is saved in `config.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## should be able to read config from package.json + +> Snapshot 1 + + { + binaryName: 'testing', + npmClient: 'npm', + packageJson: { + name: '@napi-rs/testing', + napi: { + binaryName: 'testing', + packageName: '@napi-rs/testing', + targets: [ + 'x86_64-unknown-linux-gnu', + 'x86_64-pc-windows-msvc', + 'x86_64-apple-darwin', + ], + }, + version: '0.0.0', + }, + packageName: '@napi-rs/testing', + targets: [ + { + abi: 'gnu', + arch: 'x64', + platform: 'linux', + platformArchABI: 'linux-x64-gnu', + triple: 'x86_64-unknown-linux-gnu', + }, + { + abi: 'msvc', + arch: 'x64', + platform: 'win32', + platformArchABI: 'win32-x64-msvc', + triple: 'x86_64-pc-windows-msvc', + }, + { + abi: null, + arch: 'x64', + platform: 'darwin', + platformArchABI: 'darwin-x64', + triple: 'x86_64-apple-darwin', + }, + ], + } + +## should be able to read config from napi.json + +> Snapshot 1 + + { + binaryName: 'testing', + npmClient: 'npm', + packageJson: { + name: '@napi-rs/testing', + napi: { + binaryName: 'testing', + packageName: '@node-rs/testing', + targets: [ + 'x86_64-unknown-linux-gnu', + 'x86_64-apple-darwin', + 'aarch64-apple-darwin', + ], + }, + version: '0.0.0', + }, + packageName: '@node-rs/testing', + targets: [ + { + abi: 'gnu', + arch: 'x64', + platform: 'linux', + platformArchABI: 'linux-x64-gnu', + triple: 'x86_64-unknown-linux-gnu', + }, + { + abi: null, + arch: 'x64', + platform: 'darwin', + platformArchABI: 'darwin-x64', + triple: 'x86_64-apple-darwin', + }, + { + abi: null, + arch: 'arm64', + platform: 'darwin', + platformArchABI: 'darwin-arm64', + triple: 'aarch64-apple-darwin', + }, + ], + } diff --git a/cli/src/utils/__tests__/__snapshots__/config.spec.ts.snap b/cli/src/utils/__tests__/__snapshots__/config.spec.ts.snap new file mode 100644 index 00000000..38093d05 Binary files /dev/null and b/cli/src/utils/__tests__/__snapshots__/config.spec.ts.snap differ diff --git a/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap b/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap index a17f2328..cad503c8 100644 Binary files a/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap and b/cli/src/utils/__tests__/__snapshots__/typegen.spec.ts.snap differ diff --git a/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md index e6972c74..0b092625 100644 --- a/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md +++ b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.md @@ -9,12 +9,13 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 [ - '>= 8.6.0', - '>= 8.10.0 < 9 || >= 9.3.0', - '>= 6.14.2 < 7 || >= 8.11.2 < 9 || >= 9.11.0', - '>= 10.16.0 < 11 || >= 11.8.0', - '>= 10.17.0 < 11 || >= 12.11.0', + '>= 8.6.0 < 9 || >= 9.0.0 < 10 || >= 10.0.0', + '>= 8.10.0 < 9 || >= 9.3.0 < 10 || >= 10.0.0', + '>= 6.14.2 < 7 || >= 8.11.2 < 9 || >= 9.11.0 < 10 || >= 10.0.0', + '>= 10.16.0 < 11 || >= 11.8.0 < 12 || >= 12.0.0', + '>= 10.17.0 < 11 || >= 12.11.0 < 13 || >= 13.0.0', '>= 10.20.0 < 11 || >= 12.17.0 < 13 || >= 14.0.0', - '>= 10.23.0 < 11 || >= 12.19.0 < 13 || >= 14.12.0', - '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0', + '>= 10.23.0 < 11 || >= 12.19.0 < 13 || >= 14.12.0 < 15 || >= 15.0.0', + '>= 12.22.0 < 13 || >= 14.17.0 < 15 || >= 15.12.0 < 16 || >= 16.0.0', + '>= 18.17.0 < 19 || >= 20.3.0 < 21 || >= 21.1.0', ] diff --git a/cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap index 657b24b2..a9b699be 100644 Binary files a/cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap and b/cli/src/utils/__tests__/__snapshots__/version.spec.ts.snap differ diff --git a/cli/src/utils/__tests__/config.spec.ts b/cli/src/utils/__tests__/config.spec.ts new file mode 100644 index 00000000..70538a3e --- /dev/null +++ b/cli/src/utils/__tests__/config.spec.ts @@ -0,0 +1,81 @@ +import { unlink, writeFile } from 'node:fs/promises' +import { tmpdir } from 'node:os' +import { join } from 'node:path' + +import ava, { TestFn } from 'ava' + +import { + CommonPackageJsonFields, + UserNapiConfig, + readNapiConfig, +} from '../config.js' + +const NON_EXISTENT_FILE = 'non-existent-file' + +const test = ava as TestFn<{ + configPath: string + packageJson: string + pkgJson: CommonPackageJsonFields + config: UserNapiConfig +}> + +test.before(async (t) => { + const tmp = tmpdir() + const configPath = join(tmp, 'napi.json') + const packageJson = join(tmp, 'package.json') + const pkgJson = { + name: '@napi-rs/testing', + version: '0.0.0', + napi: { + binaryName: 'testing', + packageName: '@napi-rs/testing', + targets: [ + 'x86_64-unknown-linux-gnu', + 'x86_64-pc-windows-msvc', + 'x86_64-apple-darwin', + ], + }, + } + await writeFile(packageJson, JSON.stringify(pkgJson, null, 2)) + const config = { + binaryName: 'testing', + packageName: '@node-rs/testing', + targets: [ + 'x86_64-unknown-linux-gnu', + 'x86_64-apple-darwin', + 'aarch64-apple-darwin', + ], + } + await writeFile(configPath, JSON.stringify(config, null, 2)) + t.context = { configPath, config, packageJson, pkgJson } +}) + +test.after(async (t) => { + await unlink(t.context.configPath) + await unlink(t.context.packageJson) +}) + +test('should throw if package.json not found', async (t) => { + await t.throwsAsync(() => readNapiConfig(NON_EXISTENT_FILE), { + message: `package.json not found at ${NON_EXISTENT_FILE}`, + }) +}) + +test('should throw if napi.json not found', async (t) => { + const { packageJson } = t.context + await t.throwsAsync(() => readNapiConfig(packageJson, NON_EXISTENT_FILE), { + message: `NAPI-RS config not found at ${NON_EXISTENT_FILE}`, + }) +}) + +test('should be able to read config from package.json', async (t) => { + const { packageJson } = t.context + const config = await readNapiConfig(packageJson) + t.snapshot(config) +}) + +test('should be able to read config from napi.json', async (t) => { + const { packageJson, configPath } = t.context + const config = await readNapiConfig(packageJson, configPath) + t.snapshot(config) +}) diff --git a/cli/src/utils/config.ts b/cli/src/utils/config.ts index 7546f61a..04b00adf 100644 --- a/cli/src/utils/config.ts +++ b/cli/src/utils/config.ts @@ -1,9 +1,10 @@ +import { underline, yellow } from 'colorette' import { merge, omit } from 'lodash-es' import { fileExists, readFileAsync } from './misc.js' import { DEFAULT_TARGETS, parseTriple, Target } from './target.js' -interface UserNapiConfig { +export interface UserNapiConfig { /** * Name of the binary to be generated, default to `index` */ @@ -89,9 +90,15 @@ export type NapiConfig = Required< packageJson: CommonPackageJsonFields } -export async function readNapiConfig(path: string): Promise { +export async function readNapiConfig( + path: string, + configPath?: string, +): Promise { + if (configPath && !(await fileExists(configPath))) { + throw new Error(`NAPI-RS config not found at ${configPath}`) + } if (!(await fileExists(path))) { - throw new Error(`napi-rs config not found at ${path}`) + throw new Error(`package.json not found at ${path}`) } // May support multiple config sources later on. const content = await readFileAsync(path, 'utf8') @@ -99,12 +106,34 @@ export async function readNapiConfig(path: string): Promise { try { pkgJson = JSON.parse(content) as CommonPackageJsonFields } catch (e) { - throw new Error('Failed to parse napi-rs config', { + throw new Error(`Failed to parse package.json at ${path}`, { cause: e, }) } + let separatedConfig: UserNapiConfig | undefined + if (configPath) { + const configContent = await readFileAsync(configPath, 'utf8') + try { + separatedConfig = JSON.parse(configContent) as UserNapiConfig + } catch (e) { + throw new Error(`Failed to parse NAPI-RS config at ${configPath}`, { + cause: e, + }) + } + } + const userNapiConfig = pkgJson.napi ?? {} + if (pkgJson.napi && separatedConfig) { + const pkgJsonPath = underline(path) + const configPathUnderline = underline(configPath!) + console.warn( + yellow( + `Both napi field in ${pkgJsonPath} and [NAPI-RS config](${configPathUnderline}) file are found, the NAPI-RS config file will be used.`, + ), + ) + Object.assign(userNapiConfig, separatedConfig) + } const napiConfig: NapiConfig = merge( { binaryName: 'index', @@ -120,16 +149,26 @@ export async function readNapiConfig(path: string): Promise { // compatible with old config if (userNapiConfig?.name) { + console.warn( + `[DEPRECATED] napi.name is deprecated, use napi.binaryName instead.`, + ) napiConfig.binaryName = userNapiConfig.name } if (!targets.length) { + let deprecatedWarned = false + const warning = `[DEPRECATED] napi.triples is deprecated, use napi.targets instead.` if (userNapiConfig.triples?.defaults) { + deprecatedWarned = true + console.warn(warning) targets = targets.concat(DEFAULT_TARGETS) } if (userNapiConfig.triples?.additional?.length) { targets = targets.concat(userNapiConfig.triples.additional) + if (!deprecatedWarned) { + console.warn(warning) + } } } diff --git a/cli/src/utils/version.ts b/cli/src/utils/version.ts index 5470a257..01d0cb21 100644 --- a/cli/src/utils/version.ts +++ b/cli/src/utils/version.ts @@ -7,20 +7,22 @@ export enum NapiVersion { Napi6, Napi7, Napi8, + Napi9, } /// because node support new napi version in some minor version updates, so we might meet such situation: /// `node v10.20.0` supports `napi5` and `napi6`, but `node v12.0.0` only support `napi4`, -/// by which, we can not tell directly napi version supportness from node version directly. +/// by which, we can not tell directly napi version supportless from node version directly. const NAPI_VERSION_MATRIX = new Map([ - [NapiVersion.Napi1, '8.6.0'], - [NapiVersion.Napi2, '8.10.0 | 9.3.0'], - [NapiVersion.Napi3, '6.14.2 | 8.11.2 | 9.11.0'], - [NapiVersion.Napi4, '10.16.0 | 11.8.0'], - [NapiVersion.Napi5, '10.17.0 | 12.11.0'], + [NapiVersion.Napi1, '8.6.0 | 9.0.0 | 10.0.0'], + [NapiVersion.Napi2, '8.10.0 | 9.3.0 | 10.0.0'], + [NapiVersion.Napi3, '6.14.2 | 8.11.2 | 9.11.0 | 10.0.0'], + [NapiVersion.Napi4, '10.16.0 | 11.8.0 | 12.0.0'], + [NapiVersion.Napi5, '10.17.0 | 12.11.0 | 13.0.0'], [NapiVersion.Napi6, '10.20.0 | 12.17.0 | 14.0.0'], - [NapiVersion.Napi7, '10.23.0 | 12.19.0 | 14.12.0'], - [NapiVersion.Napi8, '12.22.0 | 14.17.0 | 15.12.0'], + [NapiVersion.Napi7, '10.23.0 | 12.19.0 | 14.12.0 | 15.0.0'], + [NapiVersion.Napi8, '12.22.0 | 14.17.0 | 15.12.0 | 16.0.0'], + [NapiVersion.Napi9, '18.17.0 | 20.3.0 | 21.1.0'], ]) interface NodeVersion {