Skip to content

Commit

Permalink
feat(bindings): add prebuildify to node
Browse files Browse the repository at this point in the history
  • Loading branch information
ObserverOfTime committed Mar 9, 2024
1 parent 6f4014b commit a6a5313
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 49 deletions.
101 changes: 68 additions & 33 deletions cli/src/generate/grammar_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ pub fn generate_grammar_files(
) -> Result<()> {
let dashed_language_name = language_name.to_kebab_case();

// TODO: remove legacy code updates in v0.24.0

// Create or update package.json
let package_json_path_state = missing_path_else(
repo_path.join("package.json"),
Expand All @@ -113,24 +115,58 @@ pub fn generate_grammar_files(
fs::read_to_string(path).with_context(|| "Failed to read package.json")?;
let mut package_json = serde_json::from_str::<Map<String, Value>>(&package_json_str)
.with_context(|| "Failed to parse package.json")?;
let package_json_needs_update = generate_bindings
&& (package_json
.get("dependencies")
.map_or(false, |d| d.get("nan").is_some())
|| !package_json.contains_key("peerDependencies")
|| !package_json.contains_key("types")
|| !package_json.contains_key("files"));
if package_json_needs_update {
if generate_bindings {
let mut updated = false;

let dependencies = package_json
.entry("dependencies".to_string())
.or_insert_with(|| Value::Object(Map::new()));
let dependencies = dependencies.as_object_mut().unwrap();
.or_insert_with(|| Value::Object(Map::new()))
.as_object_mut()
.unwrap();
if dependencies.remove("nan").is_some() {
eprintln!("Replacing package.json's nan dependency with node-addon-api");
eprintln!("Replacing nan dependency with node-addon-api in package.json");
dependencies.insert(
"node-addon-api".to_string(),
Value::String("^7.1.0".to_string()),
);
updated = true;
}
if !dependencies.contains_key("node-gyp-build") {
eprintln!("Adding node-gyp-build dependency to package.json");
dependencies.insert(
"node-gyp-build".to_string(),
Value::string("^4.8.0".to_string()),
);
updated = true;
}

let dev_dependencies = package_json
.entry("devDependencies".to_string())
.or_insert_with(|| Value::Object(Map::new()))
.as_object_mut()
.unwrap();

if !dev_dependencies.contains_key("prebuildify") {
eprintln!("Adding prebuildify devDependency to package.json");
dependencies.insert(
"prebuildify".to_string(),
Value::string("^6.0.0".to_string()),
);
updated = true;
}

let scripts = package_json
.entry("scripts".to_string())
.or_insert_with(|| Value::Object(Map::new()))
.as_object_mut()
.unwrap();
if scripts.get("install").unwrap_or("") != "node-gyp-build" {
eprintln!("Updating the install script in package.json");
scripts.insert(
"install".to_string(),
Value::String("node-gyp-build".to_string()),
);
updated = true;
}

// insert `peerDependencies` after `dependencies`
Expand Down Expand Up @@ -159,6 +195,7 @@ pub fn generate_grammar_files(
"dependencies",
Value::Object(peer_dependencies_meta),
);
updated = true;
}

// insert `types` right after `main`
Expand All @@ -170,6 +207,7 @@ pub fn generate_grammar_files(
"main",
Value::String("bindings/node".to_string()),
);
updated = true;
}

// insert `files` right after `keywords`
Expand All @@ -184,11 +222,14 @@ pub fn generate_grammar_files(
Value::String("src/**".to_string()),
]);
package_json = insert_after(package_json, "files", "keywords", files);
updated = true;
}

let mut package_json_str = serde_json::to_string_pretty(&package_json)?;
package_json_str.push('\n');
write_file(path, package_json_str)?;
if updated {
let mut package_json_str = serde_json::to_string_pretty(&package_json)?;
package_json_str.push('\n');
write_file(path, package_json_str)?;
}
}

Ok(())
Expand Down Expand Up @@ -272,9 +313,19 @@ pub fn generate_grammar_files(

// Generate Node bindings
missing_path(bindings_dir.join("node"), create_dir)?.apply(|path| {
missing_path(path.join("index.js"), |path| {
generate_file(path, INDEX_JS_TEMPLATE, language_name)
})?;
missing_path_else(
path.join("index.js"),
|path| generate_file(path, INDEX_JS_TEMPLATE, language_name),
|path| {
let index_js =
fs::read_to_string(path).with_context(|| "Failed to read index.js")?;
if index_js.contains("../../build/Release") {
eprintln!("Replacing index.js with new binding API");
generate_file(path, INDEX_JS_TEMPLATE, language_name)?;
}
Ok(())
},
)?;

missing_path(path.join("index.d.ts"), |path| {
generate_file(path, INDEX_D_TS_TEMPLATE, language_name)
Expand Down Expand Up @@ -309,10 +360,6 @@ pub fn generate_grammar_files(
},
)?;

// Remove files from old node binding paths.
existing_path(repo_path.join("index.js"), remove_file)?;
existing_path(repo_path.join("src").join("binding.cc"), remove_file)?;

Ok(())
})?;

Expand Down Expand Up @@ -508,18 +555,6 @@ impl PathState {
}
}

fn existing_path<F>(path: PathBuf, mut action: F) -> Result<PathState>
where
F: FnMut(&Path) -> Result<()>,
{
if path.exists() {
action(path.as_path())?;
Ok(PathState::Exists(path))
} else {
Ok(PathState::Missing(path))
}
}

fn missing_path<F>(path: PathBuf, mut action: F) -> Result<PathState>
where
F: FnMut(&Path) -> Result<()>,
Expand Down
1 change: 1 addition & 0 deletions cli/src/generate/templates/gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ target/

# Node artifacts
build/
prebuilds/
node_modules/
*.tgz

Expand Down
18 changes: 3 additions & 15 deletions cli/src/generate/templates/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
try {
module.exports = require("../../build/Release/tree_sitter_PARSER_NAME_binding");
} catch (error1) {
if (error1.code !== "MODULE_NOT_FOUND") {
throw error1;
}
try {
module.exports = require("../../build/Debug/tree_sitter_PARSER_NAME_binding");
} catch (error2) {
if (error2.code !== "MODULE_NOT_FOUND") {
throw error2;
}
throw error1
}
}
const root = require("path").join(__dirname, "..", "..");

module.exports = require("node-gyp-build")(root);

try {
module.exports.nodeTypeInfo = require("../../src/node-types.json");
Expand Down
5 changes: 4 additions & 1 deletion cli/src/generate/templates/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
"src/**"
],
"dependencies": {
"node-addon-api": "^7.1.0"
"node-addon-api": "^7.1.0",
"node-gyp-build": "^4.8.0"
},
"devDependencies": {
"prebuildify": "^6.0.0",
"tree-sitter-cli": "^CLI_VERSION"
},
"peerDependencies": {
Expand All @@ -35,6 +37,7 @@
}
},
"scripts": {
"install": "node-gyp-build",
"build": "tree-sitter generate --no-bindings",
"build-wasm": "tree-sitter build-wasm",
"test": "tree-sitter test",
Expand Down

0 comments on commit a6a5313

Please sign in to comment.