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

feat(rust): update napi to v3 #56

Merged
merged 4 commits into from
Oct 3, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/setup/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ runs:
with:
node-version: ${{ inputs.node_version}}
- name: Install
uses: dtolnay/rust-toolchain@stable
uses: dtolnay/rust-toolchain@1.79.0
- uses: actions/cache@v4
id: workspace-cache
with:
Expand Down
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
58 changes: 58 additions & 0 deletions e2e/rust-e2e/src/napi.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
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('napi');

// 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(`yarn add -D @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(`test-project-napi/napi_proj/npm`).length).toBeGreaterThan(
0
);

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

const files = listFiles(`test-project-napi/napi_proj`);
expect(files.some((file) => file.endsWith('.node'))).toBeTruthy();

expect(() =>
runNxCommand(
`build napi_proj -- --target wasm32-wasip1-threads`,
projectDirectory
)
).not.toThrow();
const files2 = listFiles(`test-project-napi/napi_proj`);
expect(
files2.some((file) => file.endsWith('wasm32-wasi.wasm'))
).toBeTruthy();
expect(files2).toContain('wasi-worker.mjs');
expect(files2).toContain('wasi-worker-browser.mjs');
});
});
41 changes: 4 additions & 37 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 All @@ -11,7 +12,7 @@ describe('rust', () => {

// 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`, {
execSync(`yarn add -D @monodon/rust@e2e`, {
cwd: projectDirectory,
stdio: 'inherit',
env: process.env,
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(testId = '') {
const projectName = 'test-project-' + testId;
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 --packageManager yarn`,
{
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"packageManager": "[email protected]",
"dependencies": {
"@ltd/j-toml": "1.38.0",
"@napi-rs/cli": "3.0.0-alpha.63",
"@nx/devkit": "19.8.3",
"@nx/js": "19.8.3",
"@swc/helpers": "0.5.13",
Expand Down
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
12 changes: 12 additions & 0 deletions packages/rust/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## 2.0.0-beta.1 (2024-06-25)


### 🚀 Features

- **rust:** update napi to v3 ([86c8ce8](https://github.com/Cammisuli/monodon/commit/86c8ce8))


### ❤️ Thank You

- Jonathan Cammisuli

# Changelog

## 1.4.0 (2024-02-23)
Expand Down
25 changes: 25 additions & 0 deletions packages/rust/migrations.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"generators": {},
"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.63",
"alwaysAddToPackageJson": false
},
"@napi-rs/wasm-runtime": {
"version": "^0.2.4",
"alwaysAddToPackageJson": true
},
"emnapi": {
"version": "^1.1.0",
"alwaysAddToPackageJson": true
}
}
}
}
}
6 changes: 6 additions & 0 deletions packages/rust/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,11 @@
"nx": ">=19.8.0",
"semver": "7.5.4",
"tslib": "^2.0.0"
},
"peerDependencies": {
"@napi-rs/cli": "^3.0.0-alpha.55"
},
"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.

Loading