Skip to content

Commit

Permalink
feat(rust): update napi to v3
Browse files Browse the repository at this point in the history
  • Loading branch information
Cammisuli committed Jun 25, 2024
1 parent 898f643 commit 86c8ce8
Show file tree
Hide file tree
Showing 41 changed files with 854 additions and 331 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# compiled output
/dist
/tmp
tmp
/out-tsc

# dependencies
Expand Down
54 changes: 54 additions & 0 deletions e2e/rust-e2e/src/napi.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { execSync } from 'child_process';
import { createTestProject, runNxCommand } from './utils';
import { rmSync } from 'fs';
import { listFiles } from '@nx/plugin/testing';

describe('napi', () => {
let projectDirectory: string;
beforeAll(() => {
projectDirectory = createTestProject();

// The plugin has been built and published to a local registry in the jest globalSetup
// Install the plugin built with the latest source code into the test repo
execSync(`npm install @monodon/rust@e2e`, {
cwd: projectDirectory,
stdio: 'inherit',
env: process.env,
});
});

afterAll(() => {
// Cleanup the test project
rmSync(projectDirectory, {
recursive: true,
force: true,
});
});

it('should create a napi project', () => {
runNxCommand(
`generate @monodon/rust:lib napi-proj --napi`,
projectDirectory
);

expect(listFiles('napi_proj/npm').length).toBeGreaterThan(0);

expect(() =>
runNxCommand(`build napi_proj`, projectDirectory)
).not.toThrow();

const files = listFiles('napi_proj');
expect(files).toContain('.node');

expect(() =>
runNxCommand(
`build napi_proj -- --target wasm32-wasip1-threads`,
projectDirectory
)
).not.toThrow();
const files2 = listFiles('napi_proj');
expect(files2).toContain('wasm32-wasi.node');
expect(files2).toContain('wasi-worker.mjs');
expect(files2).toContain('wasi-worker-browser.mjs');
});
});
39 changes: 3 additions & 36 deletions e2e/rust-e2e/src/rust.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { ProjectGraph } from '@nx/devkit';
import { execSync } from 'child_process';
import { mkdirSync, readFileSync, rmSync } from 'fs';
import { dirname, join } from 'path';
import { readFileSync, rmSync } from 'fs';
import { join } from 'path';
import { createTestProject, runNxCommand } from './utils';

describe('rust', () => {
let projectDirectory: string;
Expand Down Expand Up @@ -72,37 +73,3 @@ describe('rust', () => {
`);
});
});

function runNxCommand(command: string, projectDir: string) {
execSync(`npx nx ${command}`, { cwd: projectDir, stdio: 'inherit' });
}

/**
* Creates a test project with create-nx-workspace and installs the plugin
* @returns The directory where the test project was created
*/
function createTestProject() {
const projectName = 'test-project';
const projectDirectory = join(process.cwd(), 'tmp', projectName);

// Ensure projectDirectory is empty
rmSync(projectDirectory, {
recursive: true,
force: true,
});
mkdirSync(dirname(projectDirectory), {
recursive: true,
});

execSync(
`npx --yes create-nx-workspace@latest ${projectName} --preset apps --nxCloud=skip --no-interactive`,
{
cwd: dirname(projectDirectory),
stdio: 'inherit',
env: process.env,
}
);
console.log(`Created test project in "${projectDirectory}"`);

return projectDirectory;
}
38 changes: 38 additions & 0 deletions e2e/rust-e2e/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { dirname, join } from 'path';
import { mkdirSync, rmSync } from 'fs';
import { execSync } from 'child_process';
import { tmpProjPath } from '@nx/plugin/testing';

/**
* Creates a test project with create-nx-workspace and installs the plugin
* @returns The directory where the test project was created
*/
export function createTestProject() {
const projectName = 'test-project';
const projectDirectory = tmpProjPath(projectName);

// Ensure projectDirectory is empty
rmSync(projectDirectory, {
recursive: true,
force: true,
});
mkdirSync(dirname(projectDirectory), {
recursive: true,
});

execSync(
`npx --yes create-nx-workspace@latest ${projectName} --preset apps --nxCloud=skip --no-interactive`,
{
cwd: dirname(projectDirectory),
stdio: 'inherit',
env: process.env,
}
);
console.log(`Created test project in "${projectDirectory}"`);

return projectDirectory;
}

export function runNxCommand(command: string, projectDir: string) {
execSync(`npx nx ${command}`, { cwd: projectDir, stdio: 'inherit' });
}
2 changes: 1 addition & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"libsDir": "packages"
},
"release": {
"projects": ["rust", "typescript-nx-imports-plugin"],
"projects": ["rust"],
"projectsRelationship": "independent",
"releaseTagPattern": "{projectName}-{version}",
"version": {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"devDependencies": {
"@commitlint/cli": "17.3.0",
"@commitlint/config-conventional": "17.3.0",
"@napi-rs/cli": "3.0.0-alpha.50",
"@nx/eslint": "18.2.1",
"@nx/eslint-plugin": "18.2.1",
"@nx/jest": "18.2.1",
Expand Down Expand Up @@ -60,4 +61,3 @@
"includedScripts": []
}
}

7 changes: 6 additions & 1 deletion packages/rust/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
"rules": {}
},
{
"files": ["./package.json", "./generators.json", "./executors.json"],
"files": [
"./package.json",
"./generators.json",
"./executors.json",
"./migrations.json"
],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/nx-plugin-checks": "error",
Expand Down
31 changes: 31 additions & 0 deletions packages/rust/migrations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"generators": {
"updating-napi": {
"version": "2.0.0",
"description": "Migration for v2.0.0",
"implementation": "./src/migrations/updating-napi"
}
},
"packageJsonUpdates": {
"2.0.0": {
"version": "2.0.0-beta.1",
"requires": {
"@napi-rs/cli": "<3.0.0"
},
"packages": {
"@napi-rs/cli": {
"version": "3.0.0-alpha.55",
"alwaysAddToPackageJson": false
},
"@napi-rs/wasm-runtime": {
"version": "^0.2.4",
"alwaysAddToPackageJson": true
},
"emnapi": {
"version": "^1.1.0",
"alwaysAddToPackageJson": true
}
}
}
}
}
3 changes: 3 additions & 0 deletions packages/rust/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@
"nx": ">=18.1.1",
"semver": "7.5.4",
"tslib": "^2.0.0"
},
"nx-migrations": {
"migrations": "./migrations.json"
}
}
9 changes: 7 additions & 2 deletions packages/rust/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/rust/src",
"projectType": "library",
"tags": [],
"targets": {
"lint": {
"executor": "@nx/eslint:lint",
Expand Down Expand Up @@ -44,10 +45,14 @@
"input": "./packages/rust",
"glob": "executors.json",
"output": "."
},
{
"input": "./packages/rust",
"glob": "migrations.json",
"output": "."
}
]
}
}
},
"tags": []
}
}
65 changes: 34 additions & 31 deletions packages/rust/src/executors/napi/executor.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,53 @@
import { ExecutorContext, getPackageManagerCommand } from '@nx/devkit';
import { NapiExecutorSchema } from './schema';
import { runProcess } from '../../utils/run-process';
import { ExecutorContext, joinPathFragments, workspaceRoot } from '@nx/devkit';
import { NapiExecutorSchema } from './schema.js';
import { join } from 'path';
import { fileExists } from 'nx/src/utils/fileutils';
import { fileExists } from 'nx/src/utils/fileutils.js';
import { cargoMetadata } from '../../utils/cargo';

export default async function runExecutor(
options: NapiExecutorSchema,
context: ExecutorContext
) {
const { exec } = getPackageManagerCommand();
const command = `${exec} napi build`;
const args: string[] = [];
if (options.release) {
args.push('--release');
const { NapiCli } = await import('@napi-rs/cli');
const projectRoot =
context.projectGraph?.nodes[context.projectName ?? ''].data.root;
const packageJson = join(projectRoot ?? '.', 'package.json');
if (!fileExists(packageJson)) {
throw new Error(`Could not find package.json at ${packageJson}`);
}

if (options.target) {
args.push('--target');
args.push(options.target);
}
const napi = new NapiCli();

args.push('--platform');
const buildOptions: Parameters<typeof napi.build>[0] = {};

const projectRoot =
context.projectGraph?.nodes[context.projectName ?? ''].data.root;
const projectJson = join(projectRoot ?? '.', 'package.json');
if (!fileExists(projectJson)) {
throw new Error(`Could not find package.json at ${projectJson}`);
buildOptions.platform = true;
buildOptions.jsBinding = options.jsFile;
buildOptions.outputDir = options.dist;
buildOptions.manifestPath = join(projectRoot ?? '.', 'Cargo.toml');
buildOptions.packageJsonPath = packageJson;
if (options.release) {
buildOptions.release = true;
}

args.push('-c');
args.push(projectJson);

if (typeof projectRoot == 'string') {
args.push('--cargo-cwd');
args.push(projectRoot);
if (options.target) {
buildOptions.target = options.target;
}

args.push('--js');
args.push(options.jsFile);
if (options.zig) {
buildOptions.crossCompile = true;
}

args.push(options.dist);
const metadata = cargoMetadata();
buildOptions.targetDir =
metadata?.target_directory ??
joinPathFragments(workspaceRoot, 'dist', 'cargo');

if (options.zig) {
args.push('--zig');
if (process.env.VERCEL) {
// Vercel doesnt have support for cargo atm, so auto success builds
return { success: true };
}

return runProcess(command, ...args);
const { task } = await napi.build(buildOptions);
const output = await task;
return { success: true, terminalOutput: output };
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 86c8ce8

Please sign in to comment.