Skip to content

Commit

Permalink
Fixes #24 adds project transforms
Browse files Browse the repository at this point in the history
  • Loading branch information
ncipollo committed Sep 18, 2023
1 parent a7ec720 commit 1d2fe02
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 55 deletions.
59 changes: 41 additions & 18 deletions src/project.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,61 @@
mod dryrun;
mod strings;
pub mod operation;
mod project_version;
mod strings;

use std::path::Path;
use git2::{Repository};
use mockall_double::double;
use crate::config::{Config, RepoConfig};
use crate::error::SheepError;
use crate::project::operation::Operation;
use crate::repo::clone::GitCloner;
use crate::repo::open::{GitOpener};
use crate::repo::open::GitOpener;
use crate::repo::path;
use crate::repo::remote::GitRemotes;
use git2::Repository;
use mockall_double::double;
use std::path::Path;

#[double]
use crate::project::project_version::ProjectVersion;
use crate::project::strings::ProjectStrings;
use crate::repo::branch::GitBranches;
use crate::repo::commit::GitCommits;
use crate::repo::tag::GitTags;
use crate::transform::project_transform::ProjectTransformer;
use crate::version::update::VersionUpdate;

pub struct Project {
config: Config,
repo: Repository,
transformer: ProjectTransformer,
is_dry_run_project: bool,
}

impl Project {
pub fn new_local_project<P: AsRef<Path>>(path: P) -> Result<Project, SheepError> {
let repo = GitOpener::new().open(&path)?;
let config = Config::open(&path)?;
let transformer = ProjectTransformer::new(path);
let project = Project {
config,
repo,
transformer,
is_dry_run_project: false,
};
Ok(project)
}

pub fn new_remote_project<P: AsRef<Path>>(url: &str, directory: P) -> Result<Project, SheepError> {
pub fn new_remote_project<P: AsRef<Path>>(
url: &str,
directory: P,
) -> Result<Project, SheepError> {
let repo_path = path::repo_path(url, directory)?;
let repo = GitCloner::new().clone(url, &repo_path)?;
let config = Config::open(&repo_path)?;
let transformer = ProjectTransformer::new(&repo_path);
let project = Project {
config,
repo,
transformer,
is_dry_run_project: false,
};
Ok(project)
Expand All @@ -62,6 +72,7 @@ impl Project {
config: local_project.config,
is_dry_run_project: true,
repo: remote_project.repo,
transformer: remote_project.transformer,
};
Ok(dry_run_project)
}
Expand All @@ -72,7 +83,7 @@ impl Project {
let version_update = operation.version_update(&project_version);
let project_strings = ProjectStrings::new(&self.config, &version_update);

self.update_repo(repo_config, &project_strings)?;
self.update_repo(repo_config, &project_strings, &version_update)?;

// Process subprojects if there are any

Expand All @@ -91,7 +102,9 @@ impl Project {
fn update_repo(
&self,
repo_config: &RepoConfig,
project_strings: &ProjectStrings) -> Result<(), SheepError> {
project_strings: &ProjectStrings,
version_update: &VersionUpdate,
) -> Result<(), SheepError> {
let repo = &self.repo;
// Create branch if enabled in configuration
if repo_config.enable_branch {
Expand All @@ -102,6 +115,10 @@ impl Project {
}
// Create commit if enabled in configuration
if repo_config.enable_commit {
if !self.config.transforms.is_empty() {
println!("🤖 applying transforms");
self.transformer.transform(&self.config.transforms, version_update)?;
}
println!("✍️ committing changes");
let commits = GitCommits::with_default_branch(&repo_config.default_branch);
commits.commit(repo, vec![], &project_strings.commit_message)?;
Expand All @@ -118,20 +135,26 @@ impl Project {

let remotes = GitRemotes::new();
if repo_config.enable_branch {
remotes.push_branch(repo,
&project_strings.branch_name,
&project_strings.remote_name)?;
remotes.push_branch(
repo,
&project_strings.branch_name,
&project_strings.remote_name,
)?;
} else if repo_config.enable_commit {
remotes.push_branch(repo,
&repo_config.default_branch,
&project_strings.remote_name)?;
remotes.push_branch(
repo,
&repo_config.default_branch,
&project_strings.remote_name,
)?;
}
if repo_config.enable_tag {
remotes.push_tag(repo,
&project_strings.tag_name,
&project_strings.remote_name)?;
remotes.push_tag(
repo,
&project_strings.tag_name,
&project_strings.remote_name,
)?;
}
}
Ok(())
}
}
}
2 changes: 1 addition & 1 deletion src/transform.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
mod file_transform;
mod project_transform;
pub mod project_transform;
42 changes: 31 additions & 11 deletions src/transform/file_transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,47 @@ use crate::file::{FileReader, FileWriter};
use crate::version::update::VersionUpdate;
use crate::{token, SheepError};
use mockall_double::double;
use std::path::{Path, PathBuf};

pub struct FileTransformer<'a> {
config: &'a TransformConfig,
file_reader: &'a FileReader,
file_writer: &'a FileWriter,
project_path: &'a Path,
}

impl<'a> FileTransformer<'a> {
pub fn new(
config: &'a TransformConfig,
file_reader: &'a FileReader,
file_writer: &'a FileWriter,
project_path: &'a Path,
) -> Self {
Self {
config,
file_reader,
file_writer,
project_path,
}
}

pub fn transform(&self, version_update: &VersionUpdate) -> Result<(), SheepError> {
let path = &self.config.path;
let file_text = self.file_reader.read_to_string(path)?;
let relative_path = &self.config.path;
let path = self.full_path(relative_path);
let file_text = self.file_reader.read_to_string(&path)?;
let transformed = file_text.replacen(
&self.find_string(version_update),
&self.replace_string(version_update),
1,
);
self.file_writer.write_string_to_file(path, &transformed)?;
self.file_writer.write_string_to_file(&path, &transformed)?;
Ok(())
}

fn full_path(&self, relative_path: &str) -> PathBuf {
[self.project_path, &Path::new(relative_path)].iter().collect()
}

fn find_string(&self, version_update: &VersionUpdate) -> String {
let find = self
.config
Expand All @@ -57,13 +66,16 @@ impl<'a> FileTransformer<'a> {

#[cfg(test)]
mod test {
const PATH: &str = "path";

use crate::config::TransformConfig;
use crate::file::{MockFileReader, MockFileWriter};
use crate::transform::file_transform::FileTransformer;
use crate::version::update::VersionUpdate;
use semver::Version;
use std::path::{PathBuf};

const PATH: &str = "path";
const PROJECT_PATH: &str = "project";
const FULL_PATH: &str = "project/path";

#[test]
fn transform_find_and_replace_no_version() {
Expand All @@ -74,7 +86,8 @@ mod test {
find: Some("find".to_string()),
replace: "replace".to_string(),
};
let file_transformer = FileTransformer::new(&config, &reader, &writer);
let project_path = project_path();
let file_transformer = FileTransformer::new(&config, &reader, &writer, &project_path);
file_transformer
.transform(&version_update())
.expect("transform failed");
Expand All @@ -89,7 +102,8 @@ mod test {
find: Some("find_{version}".to_string()),
replace: "replace".to_string(),
};
let file_transformer = FileTransformer::new(&config, &reader, &writer);
let project_path = project_path();
let file_transformer = FileTransformer::new(&config, &reader, &writer, &project_path);
file_transformer
.transform(&version_update())
.expect("transform failed");
Expand All @@ -104,7 +118,8 @@ mod test {
find: Some("find_{version}".to_string()),
replace: "replace__{version}".to_string(),
};
let file_transformer = FileTransformer::new(&config, &reader, &writer);
let project_path = project_path();
let file_transformer = FileTransformer::new(&config, &reader, &writer, &project_path);
file_transformer
.transform(&version_update())
.expect("transform failed");
Expand All @@ -119,12 +134,17 @@ mod test {
find: None,
replace: "version_{version}".to_string(),
};
let file_transformer = FileTransformer::new(&config, &reader, &writer);
let project_path = project_path();
let file_transformer = FileTransformer::new(&config, &reader, &writer, &project_path);
file_transformer
.transform(&version_update())
.expect("transform failed");
}

fn project_path() -> PathBuf {
PathBuf::from(PROJECT_PATH)
}

fn version_update() -> VersionUpdate {
VersionUpdate {
current_version: Version::parse("1.0.0").expect("failed to parse version"),
Expand All @@ -136,7 +156,7 @@ mod test {
let text_copy = text.to_string();
let mut mock = MockFileReader::default();
mock.expect_read_to_string()
.withf_st(|p| p.as_ref().to_str().unwrap() == PATH)
.withf_st(|p| p.as_ref().to_str().unwrap() == FULL_PATH)
.return_once(|_| Ok(text_copy));
mock
}
Expand All @@ -146,7 +166,7 @@ mod test {
let mut mock = MockFileWriter::default();
mock.expect_write_string_to_file()
.withf_st(move |p, t| {
p.as_ref().to_str().unwrap() == PATH && t == expected_copy.clone()
p.as_ref().to_str().unwrap() == FULL_PATH && t == expected_copy.clone()
})
.return_once(|_, _| Ok(()));
mock
Expand Down
Loading

0 comments on commit 1d2fe02

Please sign in to comment.