Skip to content

Commit 506dae1

Browse files
authored
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.
1 parent 9f9f7fb commit 506dae1

File tree

10 files changed

+159
-1
lines changed

10 files changed

+159
-1
lines changed

Cargo.lock

Lines changed: 22 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
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"]
2+
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"]
33
resolver = "2"
44

55
# Comment out the below lines if you plan to use a debugger.

harper-jjdescription/Cargo.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[package]
2+
name = "harper-jjdescription"
3+
version = "0.68.0"
4+
edition = "2024"
5+
description = "The language checker for developers."
6+
license = "Apache-2.0"
7+
repository = "https://github.com/automattic/harper"
8+
9+
[dependencies]
10+
harper-core = { path = "../harper-core", version = "0.68.0" }
11+
harper-tree-sitter = { path = "../harper-tree-sitter", version = "0.68.0" }
12+
tree-sitter-jjdescription = "0.0.1"
13+
tree-sitter = "0.25.10"
14+
15+
[dev-dependencies]
16+
paste = "1.0.15"

harper-jjdescription/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use harper_core::Token;
2+
use harper_core::parsers::{self, Markdown, MarkdownOptions, Parser};
3+
use harper_tree_sitter::TreeSitterMasker;
4+
use tree_sitter::Node;
5+
6+
pub struct JJDescriptionParser {
7+
/// Used to grab the text nodes, and parse them as markdown.
8+
inner: parsers::Mask<TreeSitterMasker, Markdown>,
9+
}
10+
11+
impl JJDescriptionParser {
12+
fn node_condition(n: &Node) -> bool {
13+
n.kind() == "text"
14+
}
15+
16+
pub fn new(markdown_options: MarkdownOptions) -> Self {
17+
Self {
18+
inner: parsers::Mask::new(
19+
TreeSitterMasker::new(tree_sitter_jjdescription::language(), Self::node_condition),
20+
Markdown::new(markdown_options),
21+
),
22+
}
23+
}
24+
}
25+
26+
impl Parser for JJDescriptionParser {
27+
fn parse(&self, source: &[char]) -> Vec<Token> {
28+
self.inner.parse(source)
29+
}
30+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use harper_core::linting::{LintGroup, Linter};
2+
use harper_core::parsers::MarkdownOptions;
3+
use harper_core::spell::FstDictionary;
4+
use harper_core::{Dialect, Document};
5+
use harper_jjdescription::JJDescriptionParser;
6+
7+
/// Creates a unit test checking that the linting of a git commit document (in
8+
/// `tests_sources`) produces the expected number of lints.
9+
macro_rules! create_test {
10+
($filename:ident.txt, $correct_expected:expr) => {
11+
paste::paste! {
12+
#[test]
13+
fn [<lints_ $filename _correctly>](){
14+
let source = include_str!(
15+
concat!(
16+
"./test_sources/",
17+
concat!(stringify!($filename), ".txt")
18+
)
19+
);
20+
21+
let dict = FstDictionary::curated();
22+
let document = Document::new(source, &JJDescriptionParser::new(MarkdownOptions::default()), &dict);
23+
24+
let mut linter = LintGroup::new_curated(dict, Dialect::American);
25+
let lints = linter.lint(&document);
26+
27+
dbg!(&lints);
28+
assert_eq!(lints.len(), $correct_expected);
29+
30+
// Make sure that all generated tokens span real characters
31+
for token in document.tokens(){
32+
assert!(token.span.try_get_content(document.get_source()).is_some());
33+
}
34+
}
35+
}
36+
};
37+
}
38+
39+
create_test!(simple_description.txt, 1);
40+
create_test!(complex_verbose_description.txt, 2);
41+
create_test!(conventional_description.txt, 3);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
This is the the subject
2+
3+
This is a first line without typos
4+
JJ: This is a comment with a typoo that should be ignored
5+
This is a line below the comment with typooos
6+
7+
JJ: This commit contains the following changes:
8+
JJ: myfile.txt | 1 +
9+
JJ: 1 file changed, 1 insertion(+), 0 deletions(-)
10+
11+
JJ: ignore-rest
12+
diff --git a/myfile.txt b/myfile.txt
13+
new file mode 100644
14+
index 0000000000..54f266d2db
15+
--- /dev/null
16+
+++ b/myfile.txt
17+
@@ -0,0 +1,1 @@
18+
+typooo in the file
19+
20+
JJ: Lines starting with "JJ:" (like this one) will be removed.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
feat(stuff): use session-based authentiation
2+
3+
BREAKING CHANGE: JWT authentication removed. API clients mustt now use
4+
session cookies instead of Authorization headers with bearer tokens.
5+
6+
Sessions expire after 24 hours of inactvity.
7+
8+
Closes: #247
9+
Reviewed-by: John Doe <john@example.com>
10+
11+
JJ: Change ID: qrutlxlw
12+
JJ: This commit contains the following changes:
13+
JJ: M Cargo.lock
14+
JJ: M Cargo.toml
15+
JJ: A harper-jjdescription/Cargo.toml
16+
JJ: A harper-jjdescription/src/lib.rs
17+
JJ: A harper-jjdescription/tests/run_tests.rs
18+
JJ: A harper-jjdescription/tests/test_sources/complex_verbose_description.txt
19+
JJ: A harper-jjdescription/tests/test_sources/conventional_description.txt
20+
JJ: A harper-jjdescription/tests/test_sources/simple_description.txt
21+
JJ: M harper-ls/Cargo.toml
22+
JJ: M harper-ls/src/backend.rs
23+
JJ:
24+
JJ: Lines starting with "JJ:" (like this one) will be removed.
25+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A simple description with a typo: descrption

harper-ls/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ harper-stats = { path = "../harper-stats", version = "0.68.0" }
1212
harper-literate-haskell = { path = "../harper-literate-haskell", version = "0.68.0" }
1313
harper-core = { path = "../harper-core", version = "0.68.0", features = ["concurrent"] }
1414
harper-comments = { path = "../harper-comments", version = "0.68.0" }
15+
harper-jjdescription = { path = "../harper-jjdescription", version = "0.68.0" }
1516
harper-typst = { path = "../harper-typst", version = "0.68.0" }
1617
harper-html = { path = "../harper-html", version = "0.68.0" }
1718
harper-python = { path = "../harper-python", version = "0.68.0" }

harper-ls/src/backend.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use harper_core::spell::{Dictionary, FstDictionary, MergedDictionary, MutableDic
2121
use harper_core::{Dialect, DictWordMetadata, Document, IgnoredLints};
2222
use harper_html::HtmlParser;
2323
use harper_ink::InkParser;
24+
use harper_jjdescription::JJDescriptionParser;
2425
use harper_literate_haskell::LiterateHaskellParser;
2526
use harper_python::PythonParser;
2627
use harper_stats::{Record, Stats};
@@ -385,6 +386,7 @@ impl Backend {
385386
"git-commit" | "gitcommit" => {
386387
Some(Box::new(GitCommitParser::new_markdown(markdown_options)))
387388
}
389+
"jjdescription" => Some(Box::new(JJDescriptionParser::new(markdown_options))),
388390
"html" => Some(Box::new(HtmlParser::default())),
389391
"mail" | "plaintext" | "text" => Some(Box::new(PlainEnglish)),
390392
"typst" => Some(Box::new(Typst)),

0 commit comments

Comments
 (0)