Skip to content

Commit e0b0722

Browse files
committed
feat(napi): add basic oxlint napi bindings (#11877)
1 parent 06781ab commit e0b0722

File tree

16 files changed

+600
-42
lines changed

16 files changed

+600
-42
lines changed

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ oxc_linter = { path = "crates/oxc_linter" }
136136
oxc_macros = { path = "crates/oxc_macros" }
137137
oxc_tasks_common = { path = "tasks/common" }
138138
oxc_tasks_transform_checker = { path = "tasks/transform_checker" }
139+
oxlint = { path = "apps/oxlint" }
139140

140141
# Relaxed version so the user can decide which version to use.
141142
napi = "3.0.0-beta"

apps/oxlint/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ description.workspace = true
1616
workspace = true
1717

1818
[lib]
19+
crate-type = ["lib"]
20+
path = "src/lib.rs"
1921
doctest = false
2022

2123
[[bin]]
@@ -34,6 +36,7 @@ bpaf = { workspace = true, features = ["autocomplete", "bright-color", "derive"]
3436
cow-utils = { workspace = true }
3537
ignore = { workspace = true, features = ["simd-accel"] }
3638
miette = { workspace = true }
39+
napi = { workspace = true }
3740
rayon = { workspace = true }
3841
rustc-hash = { workspace = true }
3942
serde = { workspace = true }

apps/oxlint/src/lib.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,67 @@ mod tester;
77
mod walk;
88

99
pub mod cli {
10-
1110
pub use crate::{command::*, lint::LintRunner, result::CliRunResult, runner::Runner};
1211
}
12+
13+
#[cfg(all(feature = "allocator", not(miri), not(target_family = "wasm")))]
14+
#[global_allocator]
15+
static GLOBAL: mimalloc_safe::MiMalloc = mimalloc_safe::MiMalloc;
16+
17+
use cli::{CliRunResult, LintRunner, Runner};
18+
use std::{ffi::OsStr, io::BufWriter};
19+
20+
pub fn lint() -> CliRunResult {
21+
init_tracing();
22+
init_miette();
23+
24+
let mut args = std::env::args_os().peekable();
25+
26+
let args = match args.peek() {
27+
Some(s) if s == OsStr::new("node") => args.skip(2),
28+
_ => args.skip(1),
29+
};
30+
let args = args.collect::<Vec<_>>();
31+
32+
// SAFELY skip first two args (node + script.js)
33+
// let cli_args = std::env::args_os().skip(2);
34+
let cmd = crate::cli::lint_command();
35+
let command = match cmd.run_inner(&*args) {
36+
Ok(cmd) => cmd,
37+
Err(e) => {
38+
e.print_message(100);
39+
return CliRunResult::InvalidOptionConfig;
40+
}
41+
};
42+
43+
command.handle_threads();
44+
// stdio is blocked by LineWriter, use a BufWriter to reduce syscalls.
45+
// See `https://github.com/rust-lang/rust/issues/60673`.
46+
let mut stdout = BufWriter::new(std::io::stdout());
47+
48+
LintRunner::new(command).run(&mut stdout)
49+
}
50+
51+
// Initialize the data which relies on `is_atty` system calls so they don't block subsequent threads.
52+
fn init_miette() {
53+
miette::set_hook(Box::new(|_| Box::new(miette::MietteHandlerOpts::new().build()))).unwrap();
54+
}
55+
56+
/// To debug `oxc_resolver`:
57+
/// `OXC_LOG=oxc_resolver oxlint --import-plugin`
58+
fn init_tracing() {
59+
use tracing_subscriber::{filter::Targets, prelude::*};
60+
61+
// Usage without the `regex` feature.
62+
// <https://github.com/tokio-rs/tracing/issues/1436#issuecomment-918528013>
63+
tracing_subscriber::registry()
64+
.with(std::env::var("OXC_LOG").map_or_else(
65+
|_| Targets::new(),
66+
|env_var| {
67+
use std::str::FromStr;
68+
Targets::from_str(&env_var).unwrap()
69+
},
70+
))
71+
.with(tracing_subscriber::fmt::layer())
72+
.init();
73+
}

apps/oxlint/src/main.rs

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,5 @@
1-
// NOTE: Miri does not support custom allocators
2-
#[cfg(all(feature = "allocator", not(miri), not(target_family = "wasm")))]
3-
#[global_allocator]
4-
static GLOBAL: mimalloc_safe::MiMalloc = mimalloc_safe::MiMalloc;
5-
6-
use oxlint::cli::{CliRunResult, LintRunner, Runner};
7-
use std::io::BufWriter;
1+
use oxlint::{cli::CliRunResult, lint};
82

93
fn main() -> CliRunResult {
10-
init_tracing();
11-
init_miette();
12-
13-
let command = oxlint::cli::lint_command().run();
14-
command.handle_threads();
15-
// stdio is blocked by LineWriter, use a BufWriter to reduce syscalls.
16-
// See `https://github.com/rust-lang/rust/issues/60673`.
17-
let mut stdout = BufWriter::new(std::io::stdout());
18-
19-
LintRunner::new(command).run(&mut stdout)
20-
}
21-
22-
// Initialize the data which relies on `is_atty` system calls so they don't block subsequent threads.
23-
fn init_miette() {
24-
miette::set_hook(Box::new(|_| Box::new(miette::MietteHandlerOpts::new().build()))).unwrap();
25-
}
26-
27-
/// To debug `oxc_resolver`:
28-
/// `OXC_LOG=oxc_resolver oxlint --import-plugin`
29-
fn init_tracing() {
30-
use tracing_subscriber::{filter::Targets, prelude::*};
31-
32-
// Usage without the `regex` feature.
33-
// <https://github.com/tokio-rs/tracing/issues/1436#issuecomment-918528013>
34-
tracing_subscriber::registry()
35-
.with(std::env::var("OXC_LOG").map_or_else(
36-
|_| Targets::new(),
37-
|env_var| {
38-
use std::str::FromStr;
39-
Targets::from_str(&env_var).unwrap()
40-
},
41-
))
42-
.with(tracing_subscriber::fmt::layer())
43-
.init();
4+
lint()
445
}

dprint.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
"**/CHANGELOG.md",
1818
"pnpm-workspace.yaml",
1919
"pnpm-lock.yaml",
20+
"napi/oxlint2/src/bindings.js",
21+
"napi/oxlint2/src/bindings.d.ts",
2022
"napi/{transform,minify,playground}/index.js",
2123
"napi/{parser,transform,minify,playground}/index.d.ts",
2224
"napi/{parser,transform,minify,playground}/*.wasi-browser.js",

napi/oxlint2/Cargo.toml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[package]
2+
name = "oxc_linter_napi"
3+
version = "0.1.0"
4+
authors.workspace = true
5+
categories.workspace = true
6+
edition.workspace = true
7+
homepage.workspace = true
8+
include = ["/src", "build.rs"]
9+
keywords.workspace = true
10+
license.workspace = true
11+
publish = false
12+
repository.workspace = true
13+
rust-version.workspace = true
14+
description.workspace = true
15+
16+
[lints]
17+
workspace = true
18+
19+
[lib]
20+
crate-type = ["cdylib", "lib"]
21+
test = false
22+
doctest = false
23+
24+
[dependencies]
25+
oxlint = { workspace = true }
26+
27+
napi = { workspace = true, features = ["async"] }
28+
napi-derive = { workspace = true }
29+
30+
[target.'cfg(not(any(target_os = "linux", target_os = "freebsd", target_arch = "arm", target_family = "wasm")))'.dependencies]
31+
mimalloc-safe = { workspace = true, optional = true, features = ["skip_collect_on_exit"] }
32+
33+
[target.'cfg(all(target_os = "linux", not(target_arch = "arm"), not(target_arch = "aarch64")))'.dependencies]
34+
mimalloc-safe = { workspace = true, optional = true, features = ["skip_collect_on_exit", "local_dynamic_tls"] }
35+
36+
[target.'cfg(all(target_os = "linux", target_arch = "aarch64"))'.dependencies]
37+
mimalloc-safe = { workspace = true, optional = true, features = ["skip_collect_on_exit", "local_dynamic_tls", "no_opt_arch"] }
38+
39+
[build-dependencies]
40+
napi-build = { workspace = true }
41+
42+
[features]
43+
default = []

napi/oxlint2/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Oxlint 2

napi/oxlint2/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
napi_build::setup();
3+
}

napi/oxlint2/package.json

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "oxlint2",
3+
"version": "0.1.0",
4+
"main": "src/index.js",
5+
"type": "module",
6+
"scripts": {
7+
"build-dev": "napi build --platform --js ./bindings.js --dts ./bindings.d.ts --output-dir src --no-dts-cache --esm",
8+
"build": "pnpm run build-dev --release",
9+
"test": "echo 'No tests defined yet'"
10+
},
11+
"engines": {
12+
"node": ">=20.0.0"
13+
},
14+
"description": "Staging package for oxlint while we integrate custom JS plugins into oxlint",
15+
"author": "Boshen and oxc contributors",
16+
"license": "MIT",
17+
"homepage": "https://oxc.rs",
18+
"bugs": "https://github.com/oxc-project/oxc/issues",
19+
"repository": {
20+
"type": "git",
21+
"url": "https://github.com/oxc-project/oxc.git",
22+
"directory": "napi/oxlint2"
23+
},
24+
"publishConfig": {
25+
"registry": "https://registry.npmjs.org/",
26+
"access": "public"
27+
},
28+
"devDependencies": {
29+
"typescript": "catalog:"
30+
},
31+
"napi": {
32+
"binaryName": "oxlint",
33+
"targets": [
34+
"win32-x64",
35+
"win32-arm64",
36+
"linux-x64-gnu",
37+
"linux-arm64-gnu",
38+
"linux-x64-musl",
39+
"linux-arm64-musl",
40+
"darwin-x64",
41+
"darwin-arm64"
42+
]
43+
}
44+
}

0 commit comments

Comments
 (0)