Skip to content

Commit

Permalink
Merge pull request #10 from attakei/feature/regexp
Browse files Browse the repository at this point in the history
Support regexp in files section of config

Refs: #8
  • Loading branch information
attakei authored Apr 13, 2024
2 parents 383c08a + 411a8dc commit 460d4e5
Show file tree
Hide file tree
Showing 18 changed files with 143 additions and 22 deletions.
5 changes: 3 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ chrono = "0.4.35"
clap = { version = "4.5.2", features = ["derive"] }
env_logger = "0.11.3"
log = "0.4.21"
regex = "1.10.4"
semver = { version = "1.0.22", features = ["serde"] }
serde = { version = "1.0.197", features = ["derive"] }
tera = { version = "1.19.1", features = ["builtins"] }
Expand Down
12 changes: 12 additions & 0 deletions doc/usage/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ This should be relative path of configuration file.
Search target of file.
This accepts multi-line text and using templating.

``files[].regex``
------------------

:Required: No
:Default: ``false``

Flag to use regular expression (regex) when searching target.

If it is ``true``, age search target using regex and replace text with captured text.

.. note:: See it: https://docs.rs/regex/1.10.4/regex/

``files[].replace``
-------------------

Expand Down
7 changes: 7 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ pub struct FileConfig {
pub path: PathBuf,
pub search: String,
pub replace: String,
pub regex: Option<bool>,
}

impl FileConfig {
pub fn regex(&self) -> bool {
self.regex.is_some() && self.regex.unwrap()
}
}

pub trait ParseAvailable {
Expand Down
2 changes: 1 addition & 1 deletion src/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl Workspace {
fn init_writer(&self, ctx: &Context) -> Writer {
let mut writer = Writer::new(&ctx.for_tera());
for f in &self.config.files {
writer.add_target(&f.path, &f.search, &f.replace);
writer.add_target(f);
}
writer
}
Expand Down
51 changes: 32 additions & 19 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ use std::io::prelude::*;
use std::path::{Path, PathBuf};

use anyhow::Result;
use regex::Regex;
use tera::{Context, Tera};

use crate::config::FileConfig;

/**
* File writer.
*/
Expand Down Expand Up @@ -34,6 +37,7 @@ pub struct WriteRule {
pub search: String,
/** Replacement content that is rendered by Tera. */
pub replace: String,
pub regex: bool,
}

impl Writer {
Expand All @@ -44,21 +48,23 @@ impl Writer {
}
}

pub fn add_target(&mut self, path: &Path, search: &str, replace: &str) {
let path_key = path.display().to_string();
pub fn add_target(&mut self, config: &FileConfig) {
let path_key = config.path.display().to_string();
if !self.targets.contains_key(&path_key) {
self.targets
.insert(path_key.clone(), WriteTarget::new(path));
.insert(path_key.clone(), WriteTarget::new(&config.path));
}
let target = self.targets.get_mut(&path_key).unwrap();
target.add_rule(
Tera::one_off(search, &self.context, true)
let rule = WriteRule {
search: Tera::one_off(&config.search, &self.context, true)
.unwrap()
.to_string(),
Tera::one_off(replace, &self.context, true)
replace: Tera::one_off(&config.replace, &self.context, true)
.unwrap()
.to_string(),
);
regex: config.regex(),
};
target.add_rule(rule);
}

pub fn update_all(&self) -> Result<()> {
Expand Down Expand Up @@ -87,13 +93,18 @@ impl WriteTarget {
Ok(())
}

pub fn add_rule(&mut self, search: String, replace: String) {
self.rules.push(WriteRule { search, replace });
pub fn add_rule(&mut self, rule: WriteRule) {
self.rules.push(rule);
}
}

impl WriteRule {
fn update(&self, target: String) -> String {
// If regex is enabled, func runs using Regex directly.
if self.regex {
let search = Regex::new(&self.search).unwrap();
return search.replace(&target, &self.replace).to_string();
}
let lines = self.search.split('\n').count();
let mut buf: VecDeque<String> = VecDeque::new();
let mut output: Vec<String> = Vec::new();
Expand Down Expand Up @@ -137,16 +148,18 @@ mod tests {
ctx.insert("new_version", &Version::new(0, 2, 0));
let mut writer = Writer::new(&ctx);
let filepath = PathBuf::from("dummy.txt");
writer.add_target(
&filepath,
&String::from("target-1"),
&String::from("replace-2"),
);
writer.add_target(
&filepath,
&String::from("target-2"),
&String::from("replace-2"),
);
writer.add_target(&FileConfig {
path: filepath.clone(),
search: String::from("target-1"),
replace: String::from("replace-2"),
regex: Some(false),
});
writer.add_target(&FileConfig {
path: filepath.clone(),
search: String::from("target-2"),
replace: String::from("replace-2"),
regex: Some(false),
});
assert_eq!(writer.targets.len(), 1);
}
}
14 changes: 14 additions & 0 deletions tests/return-0/multi-line-regex-captured/after/.age.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
current_version = "0.2.0"

[[files]]
path = "example.txt"
regex = true
search = """
version = '{{current_version}}'
hello (?<name>.+)
"""
replace = """
version = '{{new_version}}'
hello
from $name
"""
5 changes: 5 additions & 0 deletions tests/return-0/multi-line-regex-captured/after/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version = '0.2.0'
hello
from world

This line is kept.
14 changes: 14 additions & 0 deletions tests/return-0/multi-line-regex-captured/before/.age.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
current_version = "0.1.0"

[[files]]
path = "example.txt"
regex = true
search = """
version = '{{current_version}}'
hello (?<name>.+)
"""
replace = """
version = '{{new_version}}'
hello
from $name
"""
4 changes: 4 additions & 0 deletions tests/return-0/multi-line-regex-captured/before/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = '0.1.0'
hello world

This line is kept.
13 changes: 13 additions & 0 deletions tests/return-0/multi-line-regex/after/.age.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
current_version = "0.2.0"

[[files]]
path = "example.txt"
regex = true
search = """
version = '{{current_version}}'
(.+)
"""
replace = """
version = '{{new_version}}'
world
"""
4 changes: 4 additions & 0 deletions tests/return-0/multi-line-regex/after/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = '0.2.0'
world

This line is kept.
13 changes: 13 additions & 0 deletions tests/return-0/multi-line-regex/before/.age.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
current_version = "0.1.0"

[[files]]
path = "example.txt"
regex = true
search = """
version = '{{current_version}}'
(.+)
"""
replace = """
version = '{{new_version}}'
world
"""
4 changes: 4 additions & 0 deletions tests/return-0/multi-line-regex/before/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version = '0.1.0'
hello

This line is kept.
7 changes: 7 additions & 0 deletions tests/return-0/single-line-no-regex/after/.age.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
current_version = "0.2.0"

[[files]]
regex = false
path = "example.txt"
search = "version = '{{current_version}}'"
replace = "version = '{{new_version}}'"
1 change: 1 addition & 0 deletions tests/return-0/single-line-no-regex/after/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = '0.2.0'
7 changes: 7 additions & 0 deletions tests/return-0/single-line-no-regex/before/.age.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
current_version = "0.1.0"

[[files]]
regex = false
path = "example.txt"
search = "version = '{{current_version}}'"
replace = "version = '{{new_version}}'"
1 change: 1 addition & 0 deletions tests/return-0/single-line-no-regex/before/example.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version = '0.1.0'

0 comments on commit 460d4e5

Please sign in to comment.