Skip to content
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
20 changes: 20 additions & 0 deletions .denolint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"rules": {
"tags": [
"recommended"
],
"exclude": [
"no-explicit-any",
"camelcase",
"ban-unknown-rule-code",
"no-window-prefix",
"no-empty-interface",
"ban-types",
"ban-untagged-todo",
"no-unused-vars",
"ban-ts-comment",
"no-case-declarations",
"no-this-alias"
]
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"devDependencies": {
"@napi-rs/cli": "^1.3.1",
"@swc-node/register": "^1.3.4",
"@typescript-eslint/eslint-plugin": "^4.30.0",
"@typescript-eslint/parser": "^4.30.0",
"@typescript-eslint/eslint-plugin": "^4.31.0",
"@typescript-eslint/parser": "^4.31.0",
"ava": "^3.15.0",
"benchmark": "^2.1.4",
"codecov": "^3.8.3",
Expand Down
5 changes: 0 additions & 5 deletions packages/bcrypt/simple-test.js

This file was deleted.

5 changes: 0 additions & 5 deletions packages/crc32/simple-test.js

This file was deleted.

3 changes: 3 additions & 0 deletions packages/deno-lint/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
cli.js
cli.d.ts
cli.js.map
8 changes: 5 additions & 3 deletions packages/deno-lint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ crate-type = ["cdylib"]

[dependencies]
annotate-snippets = {version = "0.9", features = ["color"]}
ast_view = {version = "0.33.1", package = "dprint-swc-ecma-ast-view"}
deno_lint = "=0.14.0"
anyhow = "1"
deno_ast = "0.1"
deno_lint = "0.15"
env_logger = "0.9"
globwalk = "0.8"
ignore = "0.4"
napi = {version = "1", features = ["serde-json"]}
napi-derive = "1"
serde = "1"
serde_json = "1"
swc_ecmascript = {version = "=0.61.0", features = ["parser", "transforms", "utils", "visit"]}

[target.'cfg(all(target_arch = "x86_64", not(target_env = "musl")))'.dependencies]
mimalloc = {version = "0.1"}
Expand Down
28 changes: 26 additions & 2 deletions packages/deno-lint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,30 @@ Emit nothing even if there were errors happened.

`npx denolint`

### `--all`, `-a`
### `--config`, `-c`

Config path relative to the lint path. Config file must be a JSON file:

Example:

```json
{
"rules": {
"tags": ["recommended"],
"exclude": [
"no-explicit-any",
"ban-unknown-rule-code",
"no-window-prefix",
"no-empty-interface",
"ban-types",
"ban-untagged-todo",
"no-unused-vars",
"ban-ts-comment",
"no-case-declarations",
"no-this-alias"
]
}
}
```

Enable all rules flag, if not present, denolint will run with recommend rules.
Checkout [deno_lint rules](https://github.com/denoland/deno_lint/tree/main/docs/rules) for all rules.
2 changes: 1 addition & 1 deletion packages/deno-lint/benchmark/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ suite
const parseForESLintResult = parseForESLint(sourcecode, {
filePath: filepath,
sourceType: 'module',
ecmaVersion: 2019,
ecmaVersion: 2020,
project: tsconfigPath,
loc: true,
range: true,
Expand Down
26 changes: 16 additions & 10 deletions packages/deno-lint/bin.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
#!/usr/bin/env node

const { binding } = require('@node-rs/deno-lint')
const { cli } = require('./cli')

const { argv } = process

const enableAllRules = argv.includes('--all') || argv.includes('-a')

const hasError = binding.denolint(__dirname, enableAllRules)

if (hasError) {
process.exit(1)
}
cli
.run(process.argv.slice(2), {
stdin: process.stdin,
stdout: process.stdout,
stderr: process.stderr,
})
.then((code) => {
if (code !== 0) {
process.exit(code)
}
})
.catch((e) => {
console.error(e)
process.exit(1)
})
26 changes: 26 additions & 0 deletions packages/deno-lint/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { denolint } from '@node-rs/deno-lint'
import { Cli, Command, Option } from 'clipanion'

class LintCommand extends Command {
static usage = {
description: 'deno lint [options] [path]',
}

private readonly cwd = Option.String({ required: false })

private readonly configPath = Option.String('-c,--config', { required: false })

private readonly checkOnly = Option.Boolean('--check-only', { required: false })

execute() {
const hasError = denolint(this.cwd ?? __dirname, this.configPath ?? '.denolint.json')
return Promise.resolve(hasError && !this.checkOnly ? 1 : 0)
}
}

export const cli = new Cli({
binaryLabel: 'deno-lint',
binaryVersion: require('./package.json').version,
})

cli.register(LintCommand)
1 change: 1 addition & 0 deletions packages/deno-lint/index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export function lint(filename: string, source: string | Buffer): string[]
export function denolint(cwd: string, configPath?: string): boolean
2 changes: 1 addition & 1 deletion packages/deno-lint/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { loadBinding } = require('@node-rs/helper')
const binding = loadBinding(__dirname, 'deno-lint', '@node-rs/deno-lint')

module.exports = {
binding,
...binding,
lint: function lint(path, sourcecode, allRules = false) {
const source = Buffer.isBuffer(sourcecode) ? sourcecode : Buffer.from(sourcecode)
return binding.lint(path, source, allRules)
Expand Down
3 changes: 2 additions & 1 deletion packages/deno-lint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"denolint": "./bin.js"
},
"typings": "index.d.ts",
"files": ["index.js", "index.d.ts", "bin.js", "webpack-loader.js", "LICENSE"],
"files": ["index.js", "index.d.ts", "bin.js", "cli.js", "webpack-loader.js", "LICENSE"],
"napi": {
"name": "deno-lint",
"triples": {
Expand Down Expand Up @@ -53,6 +53,7 @@
},
"dependencies": {
"@node-rs/helper": "^1.2.1",
"clipanion": "^3.0.1",
"loader-utils": "^2.0.0"
},
"devDependencies": {
Expand Down
12 changes: 0 additions & 12 deletions packages/deno-lint/simple-test.js

This file was deleted.

126 changes: 126 additions & 0 deletions packages/deno-lint/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// Copyright 2020-2021 the Deno authors. All rights reserved. MIT license.
use std::path::Path;
use std::sync::Arc;

use deno_lint::rules::{get_filtered_rules, LintRule};
use serde::Deserialize;

#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct RulesConfig {
pub tags: Vec<String>,
pub include: Vec<String>,
pub exclude: Vec<String>,
}

#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct FilesConfig {
pub include: Vec<String>,
pub exclude: Vec<String>,
}

#[derive(Debug, Default, Deserialize)]
#[serde(default)]
pub struct Config {
pub rules: RulesConfig,
pub ignore: Option<Vec<String>>,
}

impl Config {
pub fn get_rules(&self) -> Arc<Vec<Box<dyn LintRule>>> {
get_filtered_rules(
Some(self.rules.tags.clone()),
Some(self.rules.exclude.clone()),
Some(self.rules.include.clone()),
)
}
}

pub fn load_from_json(config_path: &Path) -> Result<Config, std::io::Error> {
let json_str = std::fs::read_to_string(config_path)?;
let config: Config = serde_json::from_str(&json_str)?;
Ok(config)
}

#[cfg(test)]
mod tests {
use super::*;
use deno_lint::rules::get_recommended_rules;
use std::collections::HashSet;

macro_rules! svec {
($( $elem:literal ),* $(,)?) => {{
vec![$( $elem.to_string() ),*]
}}
}
macro_rules! set {
($( $elem:literal ),* $(,)?) => {{
vec![$( $elem ),*].into_iter().collect::<HashSet<&'static str>>()
}}
}

fn into_codes(rules: &Vec<Box<dyn LintRule>>) -> HashSet<&'static str> {
rules.iter().map(|rule| rule.code()).collect()
}

#[test]
fn test_get_rules() {
let config = Config {
rules: RulesConfig {
tags: svec![],
include: svec![],
exclude: svec![],
},
..Default::default()
};
assert!(config.get_rules().is_empty());

let config = Config {
rules: RulesConfig {
tags: svec!["recommended"],
include: svec![],
exclude: svec![],
},
..Default::default()
};
let recommended_rules_codes = into_codes(&get_recommended_rules());
assert_eq!(into_codes(&config.get_rules()), recommended_rules_codes);

// even if "recommended" is specified in `tags` and `include` contains a rule
// code that is in the "recommended" set, we have to make sure that each
// rule is run just once respectively.
let config = Config {
rules: RulesConfig {
tags: svec!["recommended"],
include: svec!["no-empty"], // "no-empty" belongs to "recommended"
exclude: svec![],
},
..Default::default()
};
let recommended_rules_codes = into_codes(&get_recommended_rules());
assert_eq!(into_codes(&config.get_rules()), recommended_rules_codes);

// `include` has higher precedence over `exclude`
let config = Config {
rules: RulesConfig {
tags: svec![],
include: svec!["eqeqeq"],
exclude: svec!["eqeqeq"],
},
..Default::default()
};
assert_eq!(into_codes(&config.get_rules()), set!["eqeqeq"]);

// if unknown rule is specified, just ignore it
let config = Config {
rules: RulesConfig {
tags: svec![],
include: svec!["this-is-a-totally-unknown-rule"],
exclude: svec!["this-is-also-another-unknown-rule"],
},
..Default::default()
};
assert_eq!(into_codes(&config.get_rules()), set![]);
}
}
Loading