Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Script to check for outdated tree-sitter grammars #12310

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion helix-loader/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ fn get_revision(repository_dir: &Path) -> Option<String> {

// A wrapper around 'git' commands which returns stdout in success and a
// helpful error message showing the command, stdout, and stderr in error.
fn git<I, S>(repository_dir: &Path, args: I) -> Result<String>
pub fn git<I, S>(repository_dir: &Path, args: I) -> Result<String>
where
I: IntoIterator<Item = S>,
S: AsRef<std::ffi::OsStr>,
Expand Down
2 changes: 2 additions & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ helix-core = { path = "../helix-core" }
helix-view = { path = "../helix-view" }
helix-loader = { path = "../helix-loader" }
toml = "0.8"
threadpool = { version = "1.0" }
serde = { version = "1.0", features = ["derive"] }
68 changes: 68 additions & 0 deletions xtask/src/grammarcheck.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use helix_core::unicode::segmentation::UnicodeSegmentation;
use helix_loader::grammar::git;

use crate::{helpers::lang_config_grammars, DynError};

pub fn grammar_check() -> Result<(), DynError> {
let pool = threadpool::Builder::new().build();
let (tx, rx) = std::sync::mpsc::channel::<String>();

let current_dir = std::sync::Arc::new(std::env::current_dir().unwrap().as_path().to_owned());

for language in lang_config_grammars().grammar {
let tx = tx.clone();
let current_dir = std::sync::Arc::clone(&current_dir);

pool.execute(move || {
let bold_green = "\x1b[1;32m";
let reset = "\x1b[0m";
let blue = "\x1b[34m";
let dark = "\x1b[35m";

if let Ok(result) = git(&current_dir, ["ls-remote", &language.source.git]) {
let latest_commit = result.split_word_bounds().next().unwrap();

let current_commit = language.source.rev;

let updates_available = current_commit != latest_commit;

let repo = language.source.git;
let name = language.name;

let link = if repo.starts_with("https://github.com") {
let url = format!("{blue}\u{1b}]8;;{}/compare{current_commit}...{latest_commit}\u{1b}\\{}\u{1b}]8;;\u{1b}\\{reset}", repo, "[View Diff]");
url
} else {
let url = format!("{dark}\u{1b}]8;;{}\u{1b}\\{}\u{1b}]8;;\u{1b}\\{reset}", repo, "[Repo Link]");
url
};


let status = if updates_available {
format!("{bold_green}Updates available{reset}")
} else {
"Up to date".into()
};

let out = if updates_available {
format!(
"{status} {link} {name} ",
)
} else {
format!("{status} {name}")
};
let _ = tx.send(out);
}
});
}

drop(tx);

println!("\n\n");

for msg in rx.iter() {
println!(" {msg}");
}

Ok(())
}
23 changes: 23 additions & 0 deletions xtask/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::path::{Path, PathBuf};
use crate::path;
use helix_core::syntax::Configuration as LangConfig;
use helix_term::health::TsFeature;
use serde::Deserialize;

/// Get the list of languages that support a particular tree-sitter
/// based feature.
Expand Down Expand Up @@ -42,3 +43,25 @@ pub fn lang_config() -> LangConfig {
let text = std::fs::read_to_string(path::lang_config()).unwrap();
toml::from_str(&text).unwrap()
}

#[derive(Deserialize)]
pub struct Configuration {
pub grammar: Vec<Grammar>,
}

#[derive(Deserialize)]
pub struct Grammar {
pub name: String,
pub source: GitSource,
}

#[derive(Deserialize)]
pub struct GitSource {
pub git: String,
pub rev: String,
}

pub fn lang_config_grammars() -> Configuration {
let text = std::fs::read_to_string(path::lang_config()).unwrap();
toml::from_str(&text).unwrap()
}
9 changes: 9 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod docgen;
mod grammarcheck;
mod helpers;
mod path;
mod querycheck;
Expand All @@ -13,10 +14,15 @@ pub mod tasks {
use crate::docgen::{
LANG_SUPPORT_MD_OUTPUT, STATIC_COMMANDS_MD_OUTPUT, TYPABLE_COMMANDS_MD_OUTPUT,
};
use crate::grammarcheck::grammar_check;
use crate::querycheck::query_check;
use crate::theme_check::theme_check;
use crate::DynError;

pub fn grammarcheck() -> Result<(), DynError> {
grammar_check()
}

pub fn docgen() -> Result<(), DynError> {
write(TYPABLE_COMMANDS_MD_OUTPUT, &typable_commands()?);
write(STATIC_COMMANDS_MD_OUTPUT, &static_commands()?);
Expand All @@ -40,6 +46,8 @@ Usage: Run with `cargo xtask <task>`, eg. `cargo xtask docgen`.
Tasks:
docgen: Generate files to be included in the mdbook output.
query-check: Check that tree-sitter queries are valid.
theme-check: Check that themes are valid.
grammar-check: Check for outdated tree-sitter grammars.
"
);
}
Expand All @@ -53,6 +61,7 @@ fn main() -> Result<(), DynError> {
"docgen" => tasks::docgen()?,
"query-check" => tasks::querycheck()?,
"theme-check" => tasks::themecheck()?,
"grammar-check" => tasks::grammarcheck()?,
invalid => return Err(format!("Invalid task name: {}", invalid).into()),
},
};
Expand Down
Loading