Skip to content

Commit

Permalink
feat: Implement replace by regex
Browse files Browse the repository at this point in the history
  • Loading branch information
attakei committed Apr 9, 2024
1 parent 3e0be04 commit aeda08c
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 13 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
25 changes: 18 additions & 7 deletions src/workspace.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::panic;
use std::path::PathBuf;

use anyhow::{anyhow, Result};
Expand All @@ -6,7 +7,7 @@ use log::{debug, warn};
use semver::Version;

use crate::config::{resolve_config, Config, ConfigDocument};
use crate::writer::{WriteRule, Writer};
use crate::writer::{SearchPattern, WriteRule, Writer};

/**
* CLI workspace.
Expand Down Expand Up @@ -53,15 +54,25 @@ impl Workspace {
fn init_writer(&self, ctx: &Context) -> Writer {
let mut writer = Writer::new(&ctx.for_tera());
for f in &self.config.files {
if f.search.is_none() {
warn!("Search is required untl.");
if f.search.is_none() && f.regex.is_none() {
warn!("Required either 'search' or 'regex'.");
continue;
}
let rule = WriteRule {
search: f.search.as_ref().unwrap().to_string(),
replace: f.replace.to_string(),
let search = 'pattern: {
if f.search.is_some() {
break 'pattern SearchPattern::String(f.search.as_ref().unwrap().to_string());
} else if f.regex.is_some() {
break 'pattern SearchPattern::Regex(f.regex.as_ref().unwrap().to_string());
}
panic!()
};
writer.add_target(&f.path, rule)
writer.add_target(
&f.path,
WriteRule {
search,
replace: f.replace.to_string(),
},
);
}
writer
}
Expand Down
28 changes: 24 additions & 4 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::io::prelude::*;
use std::path::{Path, PathBuf};

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

/**
Expand Down Expand Up @@ -76,14 +77,33 @@ impl WriteTarget {
*/
pub struct WriteRule {
/** Search target that is rendered by Tera. */
pub search: String,
pub search: SearchPattern,
/** Replacement content that is rendered by Tera. */
pub replace: String,
}

pub enum SearchPattern {
String(String),
Regex(String),
}

impl WriteRule {
fn update(&self, target: String, context: &Context) -> String {
let search = Tera::one_off(&self.search.to_string(), context, true).unwrap();
match &self.search {
SearchPattern::String(s) => self.update_string(target, context, s),
SearchPattern::Regex(s) => self.update_regex(target, context, s),
}
}

fn update_regex(&self, target: String, context: &Context, search: &String) -> String {
let search = Tera::one_off(search, context, true).unwrap();
let search = Regex::new(&search).unwrap();
let replace = Tera::one_off(&self.replace.to_string(), context, true).unwrap();
search.replace(&target, replace).to_string()
}

fn update_string(&self, target: String, context: &Context, search: &String) -> String {
let search = Tera::one_off(&search, context, true).unwrap();
let replace = Tera::one_off(&self.replace.to_string(), context, true).unwrap();

let lines = search.split('\n').count();
Expand Down Expand Up @@ -132,14 +152,14 @@ mod tests {
writer.add_target(
&filepath,
WriteRule {
search: String::from("target-1"),
search: SearchPattern::String(String::from("target-1")),
replace: String::from("target-2"),
},
);
writer.add_target(
&filepath,
WriteRule {
search: String::from("target-2"),
search: SearchPattern::String(String::from("target-2")),
replace: String::from("replace-2"),
},
);
Expand Down
12 changes: 12 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,12 @@
current_version = "0.2.0"

[[files]]
path = "example.txt"
regex = """
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.
12 changes: 12 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,12 @@
current_version = "0.1.0"

[[files]]
path = "example.txt"
regex = """
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.
2 changes: 2 additions & 0 deletions tests/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def test_valid_env(cmd, env_path: Path, tmp_path: Path):
"""Run test caese on env having valid files."""
shutil.copytree(env_path / "before", tmp_path, dirs_exist_ok=True)
proc: CompletedProcess = cmd("update", "0.2.0")
print(proc.stdout)
print(proc.stderr)
assert proc.returncode == 0
diff = run(["diff", "--recursive", str(tmp_path), str(env_path / "after")])
assert diff.returncode == 0
Expand Down

0 comments on commit aeda08c

Please sign in to comment.