mirror of
https://github.com/Automattic/harper.git
synced 2025-12-05 19:26:55 -06:00
feat: add jjdescription parser (#2082)
jjdescription file types are used by jujutsu to write messages in, similar to git commits. We use tree-sitter-jjdescription and the existing markdown parser to parse these kinds of files.
This commit is contained in:
22
Cargo.lock
generated
22
Cargo.lock
generated
@@ -2405,6 +2405,17 @@ dependencies = [
|
||||
"tree-sitter-ink-lbz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "harper-jjdescription"
|
||||
version = "0.68.0"
|
||||
dependencies = [
|
||||
"harper-core",
|
||||
"harper-tree-sitter",
|
||||
"paste",
|
||||
"tree-sitter",
|
||||
"tree-sitter-jjdescription",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "harper-literate-haskell"
|
||||
version = "0.68.0"
|
||||
@@ -2429,6 +2440,7 @@ dependencies = [
|
||||
"harper-core",
|
||||
"harper-html",
|
||||
"harper-ink",
|
||||
"harper-jjdescription",
|
||||
"harper-literate-haskell",
|
||||
"harper-python",
|
||||
"harper-stats",
|
||||
@@ -4892,6 +4904,16 @@ dependencies = [
|
||||
"tree-sitter-language",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-jjdescription"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3af4295730637817c988dd0af3ab622505fc91b4bbccf8bbcc20cae0a6e43527"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-kotlin-ng"
|
||||
version = "1.1.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[workspace]
|
||||
members = ["harper-cli", "harper-core", "harper-ls", "harper-comments", "harper-wasm", "harper-tree-sitter", "harper-html", "harper-literate-haskell", "harper-typst", "harper-stats", "harper-pos-utils", "harper-brill", "harper-ink", "harper-python"]
|
||||
members = ["harper-cli", "harper-core", "harper-ls", "harper-comments", "harper-wasm", "harper-tree-sitter", "harper-html", "harper-literate-haskell", "harper-typst", "harper-stats", "harper-pos-utils", "harper-brill", "harper-ink", "harper-python", "harper-jjdescription"]
|
||||
resolver = "2"
|
||||
|
||||
# Comment out the below lines if you plan to use a debugger.
|
||||
|
||||
16
harper-jjdescription/Cargo.toml
Normal file
16
harper-jjdescription/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "harper-jjdescription"
|
||||
version = "0.68.0"
|
||||
edition = "2024"
|
||||
description = "The language checker for developers."
|
||||
license = "Apache-2.0"
|
||||
repository = "https://github.com/automattic/harper"
|
||||
|
||||
[dependencies]
|
||||
harper-core = { path = "../harper-core", version = "0.68.0" }
|
||||
harper-tree-sitter = { path = "../harper-tree-sitter", version = "0.68.0" }
|
||||
tree-sitter-jjdescription = "0.0.1"
|
||||
tree-sitter = "0.25.10"
|
||||
|
||||
[dev-dependencies]
|
||||
paste = "1.0.15"
|
||||
30
harper-jjdescription/src/lib.rs
Normal file
30
harper-jjdescription/src/lib.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use harper_core::Token;
|
||||
use harper_core::parsers::{self, Markdown, MarkdownOptions, Parser};
|
||||
use harper_tree_sitter::TreeSitterMasker;
|
||||
use tree_sitter::Node;
|
||||
|
||||
pub struct JJDescriptionParser {
|
||||
/// Used to grab the text nodes, and parse them as markdown.
|
||||
inner: parsers::Mask<TreeSitterMasker, Markdown>,
|
||||
}
|
||||
|
||||
impl JJDescriptionParser {
|
||||
fn node_condition(n: &Node) -> bool {
|
||||
n.kind() == "text"
|
||||
}
|
||||
|
||||
pub fn new(markdown_options: MarkdownOptions) -> Self {
|
||||
Self {
|
||||
inner: parsers::Mask::new(
|
||||
TreeSitterMasker::new(tree_sitter_jjdescription::language(), Self::node_condition),
|
||||
Markdown::new(markdown_options),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parser for JJDescriptionParser {
|
||||
fn parse(&self, source: &[char]) -> Vec<Token> {
|
||||
self.inner.parse(source)
|
||||
}
|
||||
}
|
||||
41
harper-jjdescription/tests/run_tests.rs
Normal file
41
harper-jjdescription/tests/run_tests.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use harper_core::linting::{LintGroup, Linter};
|
||||
use harper_core::parsers::MarkdownOptions;
|
||||
use harper_core::spell::FstDictionary;
|
||||
use harper_core::{Dialect, Document};
|
||||
use harper_jjdescription::JJDescriptionParser;
|
||||
|
||||
/// Creates a unit test checking that the linting of a git commit document (in
|
||||
/// `tests_sources`) produces the expected number of lints.
|
||||
macro_rules! create_test {
|
||||
($filename:ident.txt, $correct_expected:expr) => {
|
||||
paste::paste! {
|
||||
#[test]
|
||||
fn [<lints_ $filename _correctly>](){
|
||||
let source = include_str!(
|
||||
concat!(
|
||||
"./test_sources/",
|
||||
concat!(stringify!($filename), ".txt")
|
||||
)
|
||||
);
|
||||
|
||||
let dict = FstDictionary::curated();
|
||||
let document = Document::new(source, &JJDescriptionParser::new(MarkdownOptions::default()), &dict);
|
||||
|
||||
let mut linter = LintGroup::new_curated(dict, Dialect::American);
|
||||
let lints = linter.lint(&document);
|
||||
|
||||
dbg!(&lints);
|
||||
assert_eq!(lints.len(), $correct_expected);
|
||||
|
||||
// Make sure that all generated tokens span real characters
|
||||
for token in document.tokens(){
|
||||
assert!(token.span.try_get_content(document.get_source()).is_some());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
create_test!(simple_description.txt, 1);
|
||||
create_test!(complex_verbose_description.txt, 2);
|
||||
create_test!(conventional_description.txt, 3);
|
||||
@@ -0,0 +1,20 @@
|
||||
This is the the subject
|
||||
|
||||
This is a first line without typos
|
||||
JJ: This is a comment with a typoo that should be ignored
|
||||
This is a line below the comment with typooos
|
||||
|
||||
JJ: This commit contains the following changes:
|
||||
JJ: myfile.txt | 1 +
|
||||
JJ: 1 file changed, 1 insertion(+), 0 deletions(-)
|
||||
|
||||
JJ: ignore-rest
|
||||
diff --git a/myfile.txt b/myfile.txt
|
||||
new file mode 100644
|
||||
index 0000000000..54f266d2db
|
||||
--- /dev/null
|
||||
+++ b/myfile.txt
|
||||
@@ -0,0 +1,1 @@
|
||||
+typooo in the file
|
||||
|
||||
JJ: Lines starting with "JJ:" (like this one) will be removed.
|
||||
@@ -0,0 +1,25 @@
|
||||
feat(stuff): use session-based authentiation
|
||||
|
||||
BREAKING CHANGE: JWT authentication removed. API clients mustt now use
|
||||
session cookies instead of Authorization headers with bearer tokens.
|
||||
|
||||
Sessions expire after 24 hours of inactvity.
|
||||
|
||||
Closes: #247
|
||||
Reviewed-by: John Doe <john@example.com>
|
||||
|
||||
JJ: Change ID: qrutlxlw
|
||||
JJ: This commit contains the following changes:
|
||||
JJ: M Cargo.lock
|
||||
JJ: M Cargo.toml
|
||||
JJ: A harper-jjdescription/Cargo.toml
|
||||
JJ: A harper-jjdescription/src/lib.rs
|
||||
JJ: A harper-jjdescription/tests/run_tests.rs
|
||||
JJ: A harper-jjdescription/tests/test_sources/complex_verbose_description.txt
|
||||
JJ: A harper-jjdescription/tests/test_sources/conventional_description.txt
|
||||
JJ: A harper-jjdescription/tests/test_sources/simple_description.txt
|
||||
JJ: M harper-ls/Cargo.toml
|
||||
JJ: M harper-ls/src/backend.rs
|
||||
JJ:
|
||||
JJ: Lines starting with "JJ:" (like this one) will be removed.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
A simple description with a typo: descrption
|
||||
@@ -12,6 +12,7 @@ harper-stats = { path = "../harper-stats", version = "0.68.0" }
|
||||
harper-literate-haskell = { path = "../harper-literate-haskell", version = "0.68.0" }
|
||||
harper-core = { path = "../harper-core", version = "0.68.0", features = ["concurrent"] }
|
||||
harper-comments = { path = "../harper-comments", version = "0.68.0" }
|
||||
harper-jjdescription = { path = "../harper-jjdescription", version = "0.68.0" }
|
||||
harper-typst = { path = "../harper-typst", version = "0.68.0" }
|
||||
harper-html = { path = "../harper-html", version = "0.68.0" }
|
||||
harper-python = { path = "../harper-python", version = "0.68.0" }
|
||||
|
||||
@@ -21,6 +21,7 @@ use harper_core::spell::{Dictionary, FstDictionary, MergedDictionary, MutableDic
|
||||
use harper_core::{Dialect, DictWordMetadata, Document, IgnoredLints};
|
||||
use harper_html::HtmlParser;
|
||||
use harper_ink::InkParser;
|
||||
use harper_jjdescription::JJDescriptionParser;
|
||||
use harper_literate_haskell::LiterateHaskellParser;
|
||||
use harper_python::PythonParser;
|
||||
use harper_stats::{Record, Stats};
|
||||
@@ -385,6 +386,7 @@ impl Backend {
|
||||
"git-commit" | "gitcommit" => {
|
||||
Some(Box::new(GitCommitParser::new_markdown(markdown_options)))
|
||||
}
|
||||
"jjdescription" => Some(Box::new(JJDescriptionParser::new(markdown_options))),
|
||||
"html" => Some(Box::new(HtmlParser::default())),
|
||||
"mail" | "plaintext" | "text" => Some(Box::new(PlainEnglish)),
|
||||
"typst" => Some(Box::new(Typst)),
|
||||
|
||||
Reference in New Issue
Block a user