neon-cli
Version:
Build and load native Rust/Neon modules.
83 lines (70 loc) • 2.34 kB
text/typescript
import path from "path";
import Crate from "./crate";
import Target from "./target";
import BuildSettings from "./build-settings";
import log from "./log";
import { execFile, spawn } from "./async/child_process";
import * as rust from "./rust";
export type ProjectOptions = {
crate: string;
targetDirectory: string;
};
/** A Neon project and its directory tree. */
export default class Project {
readonly root: string;
readonly targetDirectory: string;
readonly crate: Crate;
private constructor(root: string, options: ProjectOptions) {
let { crate, targetDirectory } = options;
this.root = root;
this.targetDirectory = targetDirectory;
this.crate = new Crate(this, { subdirectory: crate });
}
static async create(
root: string,
options: Partial<ProjectOptions> = {}
): Promise<Project> {
let { crate = "native" } = options;
const { stdout } = await execFile(
"cargo",
["metadata", "--format-version=1", "--no-deps"],
{
cwd: path.join(root, crate),
}
);
const targetDirectory: string = JSON.parse(stdout).target_directory;
return new Project(root, {
targetDirectory,
crate,
...options,
});
}
async build(toolchain: rust.Toolchain, release: boolean, args: string[]) {
let target = new Target(this.crate, { release: release });
let settings = BuildSettings.current(toolchain);
// 1. Force a rebuild if build settings have changed.
if (!target.inState(settings)) {
log("forcing rebuild for new build settings");
await target.clean();
}
// 2. Build the dylib.
log("running cargo");
await target.build(toolchain, settings, args);
// 3. Copy the dylib as the main addon file.
log(
"generating " + path.join(this.crate.subdirectory, this.crate.nodefile)
);
await this.crate.finish(target.dylib);
}
async clean() {
// 1. Do a `cargo clean` to delete the `target` directory.
log("cargo clean");
await spawn("cargo", ["clean"], { cwd: this.crate.root, stdio: "inherit" });
// 2. Remove the main addon file.
log("remove " + path.join(this.crate.subdirectory, this.crate.nodefile));
await this.crate.removeAddon();
// 3. Clear the artifacts file.
this.crate.resetArtifacts();
this.crate.saveArtifacts();
}
}