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

Support regexp in files section of config #10

Merged
merged 5 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ repos:
- repo: local
hooks:
- id: rustfmt
name: 'Run rustfmt'
name: 'Cargo fmt(nightly mode)'
language: 'rust'
entry: 'rustfmt'
entry: 'cargo +nightly fmt'
types: ['file', 'rust']
pass_filenames: false
- id: clippy
name: 'Cargo clippy'
language: 'rust'
types: ['file', 'rust']
entry: 'cargo clippy --workspace --all-targets --all-features --locked -- -Dwarnings'
pass_filenames: false
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.3.0
Expand Down
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'