Skip to content

Commit

Permalink
feat: allow overriding name for file patterns (#422)
Browse files Browse the repository at this point in the history
  • Loading branch information
morgante committed Jul 17, 2024
1 parent d1deb21 commit 8043cfa
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 27 deletions.
2 changes: 2 additions & 0 deletions crates/gritmodule/fixtures/pattern_files/.grit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.gritmodules*
*.log
2 changes: 2 additions & 0 deletions crates/gritmodule/fixtures/pattern_files/.grit/grit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ version: 0.0.1
patterns:
- file: ../docs/guides/version_5_upgrade.md
- file: ../docs/guides/something.md
- file: ../docs/guides/new-name.md
name: renamed_pattern
- name: remove_console_error
level: error
body: |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# This pattern has a different name in the config.

It still works though!

```grit
`foo` => `bar`
```
4 changes: 3 additions & 1 deletion crates/gritmodule/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ use std::{env, fmt, io::ErrorKind, str::FromStr};
use tokio::{fs, io::AsyncWriteExt};
use tracing::instrument;

use crate::fetcher::GritModuleFetcher;
use crate::installer::install_default_stdlib;
use crate::resolver::fetch_modules;
use crate::searcher::{
find_git_dir_from, find_global_grit_dir, find_global_grit_modules_dir, find_grit_dir_from,
};
use crate::{fetcher::GritModuleFetcher, markdown::GritDefinitionOverrides};
use crate::{
fetcher::{FetcherType, ModuleRepo},
parser::PatternFileExt,
Expand All @@ -36,6 +36,8 @@ pub struct GritGitHubConfig {
#[derive(Debug, Deserialize)]
pub struct GritPatternFile {
pub file: PathBuf,
#[serde(flatten)]
pub overrides: GritDefinitionOverrides,
}

/// Pure in-memory representation of the grit config
Expand Down
113 changes: 101 additions & 12 deletions crates/gritmodule/src/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use marzano_language::language::MarzanoLanguage as _;
use marzano_util::cursor_wrapper::CursorWrapper;
use marzano_util::node_with_source::NodeWithSource;
use marzano_util::rich_path::RichFile;
use serde::{Deserialize, Serialize};
use std::io::{Read, Seek, Write};
use std::path::Path;
use tokio::io::SeekFrom;
Expand Down Expand Up @@ -47,10 +48,17 @@ pub fn make_md_parser() -> Result<Parser> {
Ok(parser)
}

/// Allow overriding fields when constructing a pattern from a file
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
pub struct GritDefinitionOverrides {
pub name: Option<String>,
}

pub fn get_patterns_from_md(
file: &mut RichFile,
source_module: &Option<ModuleRepo>,
root: &Option<String>,
overrides: GritDefinitionOverrides,
) -> Result<Vec<ModuleGritPattern>> {
// Tree sitter has weird problems if we are missing a newline at the end of the file
if !file.content.ends_with('\n') {
Expand All @@ -60,10 +68,11 @@ pub fn get_patterns_from_md(
let src = &file.content;

let path = Path::new(&file.path);
let name = path
.file_stem()
.and_then(|stem| stem.to_str())
.unwrap_or_else(|| file.path.trim_end_matches(".md"));
let name = overrides.name.as_deref().unwrap_or_else(|| {
path.file_stem()
.and_then(|stem| stem.to_str())
.unwrap_or_else(|| file.path.trim_end_matches(".md"))
});
if !is_pattern_name(name) {
bail!("Invalid pattern name: '{}'. Grit patterns must match the regex /^[A-Za-z_][A-Za-z0-9_]*$/. For more info, consult the docs at https://docs.grit.io/guides/patterns#pattern-definitions.", name);
}
Expand Down Expand Up @@ -246,6 +255,7 @@ pub fn get_body_from_md_content(content: &str) -> Result<String> {
},
&None,
&None,
GritDefinitionOverrides::default(),
)?;

if let Some(pattern) = patterns.first() {
Expand Down Expand Up @@ -340,7 +350,13 @@ function isTruthy(x) {
}
```
"#.to_string()};
let patterns = get_patterns_from_md(&mut rich_file, &module, &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
println!("{:?}", patterns);
assert_yaml_snapshot!(patterns);
Expand Down Expand Up @@ -407,7 +423,13 @@ function isTruthy(x) {
}
```
"#.to_string()};
let patterns = get_patterns_from_md(&mut rich_file, &module, &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
println!("{:?}", patterns);
assert_eq!(patterns[0].config.samples.as_ref().unwrap().len(), 3);
Expand Down Expand Up @@ -496,7 +518,13 @@ function isTruthy(x) {
"#
.to_string(),
};
let patterns = get_patterns_from_md(&mut rich_file, &module, &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 2);
println!("{:?}", patterns);
assert_yaml_snapshot!(patterns);
Expand Down Expand Up @@ -657,7 +685,13 @@ jobs:
"#
.to_string(),
};
let patterns = get_patterns_from_md(&mut rich_file, &module, &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
println!("{:?}", patterns);
let sample_input = &patterns[0].config.samples.as_ref().unwrap()[0].input;
Expand Down Expand Up @@ -691,12 +725,49 @@ language js
"#
.to_string(),
};
let patterns = get_patterns_from_md(&mut rich_file, &module, &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
println!("{:?}", patterns);
assert_eq!(patterns[0].config.meta.level, Some(EnforcementLevel::Error));
}

#[test]
fn test_with_override() {
let module = Default::default();
let mut rich_file = RichFile {
path: "my-weird-pattern.md".to_string(),
content: r#"# This file name is illegal
```grit
engine marzano(0.1)
language js
`console.log($_)` => .
```
"#
.to_string(),
};
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides {
name: Some("ok_name".to_owned()),
},
)
.unwrap();
assert_eq!(patterns.len(), 1);
println!("{:?}", patterns);
assert_eq!(patterns[0].local_name, "ok_name");
}

#[test]
fn with_non_matching_samples() {
let module = Default::default();
Expand Down Expand Up @@ -781,7 +852,13 @@ while (val !== null) {
```
"#.to_string(),
};
let patterns = get_patterns_from_md(&mut rich_file, &module, &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&module,
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
assert_yaml_snapshot!(patterns);
}
Expand Down Expand Up @@ -818,7 +895,13 @@ multifile {
}
```
"#.to_string(),};
let patterns = get_patterns_from_md(&mut rich_file, &Some(module), &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&Some(module),
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
assert_yaml_snapshot!(patterns);
}
Expand Down Expand Up @@ -875,7 +958,13 @@ $$ LANGUAGE plpgsql;
"#
.to_string(),
};
let patterns = get_patterns_from_md(&mut rich_file, &Some(module), &None).unwrap();
let patterns = get_patterns_from_md(
&mut rich_file,
&Some(module),
&None,
GritDefinitionOverrides::default(),
)
.unwrap();
assert_eq!(patterns.len(), 1);
assert_yaml_snapshot!(patterns);

Expand Down
13 changes: 7 additions & 6 deletions crates/gritmodule/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
config::{ModuleGritPattern, REPO_CONFIG_DIR_NAME},
dot_grit::get_patterns_from_grit,
fetcher::ModuleRepo,
markdown::get_patterns_from_md,
markdown::{get_patterns_from_md, GritDefinitionOverrides},
searcher::find_repo_root_from,
yaml::get_patterns_from_yaml,
};
Expand Down Expand Up @@ -53,6 +53,7 @@ impl PatternFileExt {
file: &mut RichFile,
source_module: &Option<ModuleRepo>,
root: &Option<String>,
overrides: GritDefinitionOverrides,
) -> Result<Vec<ModuleGritPattern>, anyhow::Error> {
match self {
PatternFileExt::Grit => {
Expand All @@ -63,14 +64,13 @@ impl PatternFileExt {
)
})
}
PatternFileExt::Md => {
get_patterns_from_md(file, source_module, root).with_context(|| {
PatternFileExt::Md => get_patterns_from_md(file, source_module, root, overrides)
.with_context(|| {
format!(
"Failed to parse markdown pattern {}",
extract_relative_file_path(file, root)
)
})
}
}),
PatternFileExt::Yaml => {
let res = get_patterns_from_yaml(file, source_module.as_ref(), root, "").await;
res.with_context(|| {
Expand All @@ -96,14 +96,15 @@ pub async fn get_patterns_from_file(
path: PathBuf,
source_module: Option<ModuleRepo>,
ext: PatternFileExt,
overrides: GritDefinitionOverrides,
) -> Result<Vec<ModuleGritPattern>> {
let repo_root = find_repo_root_from(path.clone()).await?;
let content = fs::read_to_string(&path).await?;
let mut file = RichFile {
path: path.to_string_lossy().to_string(),
content,
};
ext.get_patterns(&mut file, &source_module, &repo_root)
ext.get_patterns(&mut file, &source_module, &repo_root, overrides)
.await
}

Expand Down
2 changes: 1 addition & 1 deletion crates/gritmodule/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ mod tests {
.await
.unwrap();

assert_eq!(resolved_patterns.len(), 3);
assert_eq!(resolved_patterns.len(), 4);
assert_eq!(errored_patterns.len(), 0);

resolved_patterns.sort_by(|a, b| a.local_name.cmp(&b.local_name));
Expand Down
10 changes: 9 additions & 1 deletion crates/gritmodule/src/searcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::path::PathBuf;
use std::str::FromStr;
use tokio::fs;

use crate::markdown::GritDefinitionOverrides;
use crate::{
config::{
ModuleGritPattern, GRIT_GLOBAL_DIR_ENV, GRIT_MODULE_DIR, REPO_CONFIG_DIR_NAME,
Expand All @@ -25,7 +26,13 @@ pub async fn collect_from_file(
path.to_string_lossy()
)
})?;
get_patterns_from_file(path.to_path_buf(), source_module.clone(), ext).await
get_patterns_from_file(
path.to_path_buf(),
source_module.clone(),
ext,
GritDefinitionOverrides::default(),
)
.await
}

pub async fn collect_patterns(
Expand Down Expand Up @@ -65,6 +72,7 @@ pub async fn collect_patterns(
path.to_path_buf(),
source_module.clone(),
ext,
GritDefinitionOverrides::default(),
)));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ expression: resolved_patterns
samples: ~
path: ".grit/grit.yaml"
position:
line: 5
line: 7
column: 11
raw: ~
module:
Expand All @@ -26,6 +26,32 @@ expression: resolved_patterns
kind: pattern
language: js
visibility: public
- config:
name: renamed_pattern
body: "\n`foo` => `bar`\n\n"
level: info
title: This pattern has a different name in the config.
description: It still works though!
tags: ~
samples: []
path: ".grit/../docs/guides/new-name.md"
position:
line: 6
column: 1
raw:
format: markdown
content: "# This pattern has a different name in the config.\n\nIt still works though!\n\n```grit\n\n`foo` => `bar`\n\n```\n"
module:
type: Module
host: github.com
fullName: getgrit/rewriter
remote: "https://github.com/getgrit/rewriter.git"
providerName: github.com/getgrit/rewriter
localName: renamed_pattern
body: "\n`foo` => `bar`\n\n"
kind: pattern
language: js
visibility: public
- config:
name: something
body: "engine marzano(0.1)\nlanguage js\n\n// We use the syntax-tree node binary_expression to capture all expressions where $a and $b are operated on by \"==\" or \"!=\".\n// This code takes advantage of Grit's allowing us to nest rewrites inside match conditions and to match syntax-tree fields on patterns.\nbinary_expression($operator, $left, $right) where {\n $operator <: or { \"==\" => `===` , \"!=\" => `!==` },\n or { $left <: `null`, $right <: `null`}\n}\n\n"
Expand Down
Loading

0 comments on commit 8043cfa

Please sign in to comment.