Skip to content

Commit

Permalink
Use impl AsRef<Path> in place of &Path for more flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
JamyGolden committed Oct 6, 2024
1 parent 5c316d9 commit c216652
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 50 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

### Changed

- Change `get_scheme_files` and `SchemeFile::new` type arguments from
`&Path` to `impl AsRef<Path>` to allow for more flexibility

## [0.12.1] - 2024-10-06

### Fixed
Expand Down
45 changes: 28 additions & 17 deletions tinted-builder-rust/src/operations/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ const REPO_NAME: &str = env!("CARGO_PKG_NAME");
///
/// # Arguments
///
/// * `theme_template_path` - A reference to a `Path` representing the path to the theme template
/// directory or file. * `user_schemes_path` - A reference to a `Path` representing the directory
/// where user schemes are stored. * `is_quiet` - A boolean flag that, when set to `true`,
/// suppresses most of the output, making the build process quieter.
/// * `theme_template_path` - A `impl AsRef<Path>` representing the path to the theme template
/// directory or file.
/// * `user_schemes_path` - A `impl AsRef<Path>` representing the directory where user schemes are
/// stored.
/// * `is_quiet` - A boolean flag that, when set to `true`, suppresses most of the output,
/// making the build process quieter.
///
/// # Returns
///
Expand All @@ -50,19 +52,27 @@ const REPO_NAME: &str = env!("CARGO_PKG_NAME");
///
/// The function will read the configuration from the specified paths and generate the
/// corresponding themes.
pub fn build(theme_template_path: &Path, user_schemes_path: &Path, is_quiet: bool) -> Result<()> {
if !user_schemes_path.exists() {
pub fn build(
theme_template_path: impl AsRef<Path>,
user_schemes_path: impl AsRef<Path>,
is_quiet: bool,
) -> Result<()> {
if !user_schemes_path.as_ref().exists() {
return Err(anyhow!(
"Schemes don't exist locally. First run `{} sync` and try again",
REPO_NAME
));
}

let template_config_path = {
if theme_template_path.join("templates/config.yml").is_file() {
theme_template_path.join("templates/config.yml")
if theme_template_path
.as_ref()
.join("templates/config.yml")
.is_file()
{
theme_template_path.as_ref().join("templates/config.yml")
} else {
theme_template_path.join("templates/config.yaml")
theme_template_path.as_ref().join("templates/config.yaml")
}
};
if !template_config_path.exists() || !template_config_path.is_file() {
Expand Down Expand Up @@ -114,7 +124,7 @@ pub fn build(theme_template_path: &Path, user_schemes_path: &Path, is_quiet: boo
generate_themes_for_config(
template_item_config_name,
template_item_config_value,
theme_template_path,
&theme_template_path,
&template_item_scheme_files,
is_quiet,
)?;
Expand All @@ -126,7 +136,7 @@ pub fn build(theme_template_path: &Path, user_schemes_path: &Path, is_quiet: boo
fn generate_themes_for_config(
config_name: &str,
config_value: &TemplateConfig,
theme_template_path: &Path,
theme_template_path: impl AsRef<Path>,
scheme_files: &Vec<(PathBuf, Scheme)>,
is_quiet: bool,
) -> Result<()> {
Expand Down Expand Up @@ -173,8 +183,9 @@ fn generate_themes_for_config(
"Config file is missing \"filepath\" or \"extension\" and \"output\" properties"
)),
}?;
let mustache_template_path =
theme_template_path.join(format!("templates/{}.mustache", config_name));
let mustache_template_path = theme_template_path
.as_ref()
.join(format!("templates/{}.mustache", config_name));
let supported_systems = &config_value
.supported_systems
.clone()
Expand Down Expand Up @@ -202,7 +213,7 @@ fn generate_themes_for_config(
.replace("{{ scheme-system }}", &scheme_system.to_string())
.replace("{{scheme-system}}", &scheme_system.to_string());

let parsed_filename = parse_filename(theme_template_path, &filepath)?;
let parsed_filename = parse_filename(&theme_template_path, &filepath)?;
if !parsed_filename.directory.exists() {
create_dir_all(&parsed_filename.directory)?
}
Expand All @@ -224,7 +235,7 @@ fn generate_themes_for_config(
.collect::<Vec<String>>()
.join(", "),
config_name,
theme_template_path.join(filename).display(),
theme_template_path.as_ref().join(filename).display(),
);
}

Expand All @@ -244,7 +255,7 @@ fn generate_themes_for_config(
///
/// * `template_content` - A reference to a string slice containing the template's content.
/// * `output_dir` - A reference to a `PathBuf` representing the directory where the output file will be written.
/// * `scheme_path` - A reference to a `Path` representing the file path to the scheme file.
/// * `scheme_path` - A `impl AsRef<Path>` representing the file path to the scheme file.
/// * `system` - The `SchemeSystem` that the scheme file should match.
/// * `explicit_extension` - A string slice representing the file extension for the generated theme
/// file. The parameter is named "explict" extension because it includes the "dot" or lack thereof
Expand Down Expand Up @@ -273,7 +284,7 @@ fn generate_themes_for_config(
fn generate_theme(
template_content: &str,
parsed_filename: ParsedFilename,
scheme_path: &Path,
scheme_path: impl AsRef<Path>,
system: SchemeSystem,
) -> Result<()> {
let scheme_file_type = SchemeFile::new(scheme_path)?;
Expand Down
20 changes: 12 additions & 8 deletions tinted-builder-rust/src/operations/build/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ pub enum SchemeFile {
}

impl SchemeFile {
pub fn new(path: &Path) -> Result<Self> {
pub fn new(path: impl AsRef<Path>) -> Result<Self> {
let extension = path
.as_ref()
.extension()
.unwrap_or_default()
.to_str()
.unwrap_or_default();

match extension {
"yaml" => Ok(Self::Yaml(path.to_path_buf())),
"yml" => Ok(Self::Yml(path.to_path_buf())),
"yaml" => Ok(Self::Yaml(path.as_ref().to_path_buf())),
"yml" => Ok(Self::Yml(path.as_ref().to_path_buf())),
_ => Err(anyhow!("Invalid file extension: {}", extension.to_string())),
}
}
Expand Down Expand Up @@ -122,10 +123,10 @@ impl ParsedFilename {
/// * If the directory cannot be read.
/// * If there is an issue accessing the contents of the directory.
/// * If there is an issue creating a `SchemeFile` from a file path.
pub fn get_scheme_files(dirpath: &Path, is_recursive: bool) -> Result<Vec<SchemeFile>> {
pub fn get_scheme_files(dirpath: impl AsRef<Path>, is_recursive: bool) -> Result<Vec<SchemeFile>> {
let mut scheme_paths: Vec<SchemeFile> = vec![];

for item in dirpath.read_dir()? {
for item in dirpath.as_ref().read_dir()? {
let file_path = item?.path();
let file_stem = file_path
.file_stem()
Expand Down Expand Up @@ -170,16 +171,19 @@ pub fn get_scheme_files(dirpath: &Path, is_recursive: bool) -> Result<Vec<Scheme
/// - `directory`: the directory of the file (relative to `template_path` or `.` if not present)
/// - `filestem`: the filename without the extension
/// - `file_extension`: the optional file extension
pub(crate) fn parse_filename(template_path: &Path, filepath: &str) -> Result<ParsedFilename> {
pub(crate) fn parse_filename(
template_path: impl AsRef<Path>,
filepath: &str,
) -> Result<ParsedFilename> {
let re = Regex::new(r"^(?P<directory>.*/)?(?P<filestem>[^/\.]+)(?:\.(?P<extension>[^/]+))?$")
.unwrap();

if let Some(captures) = re.captures(filepath) {
// Extract the directory (if present), or use "." if there's no directory
let directory = captures
.name("directory")
.map(|d| template_path.join(d.as_str()))
.unwrap_or_else(|| template_path.to_path_buf());
.map(|d| template_path.as_ref().join(d.as_str()))
.unwrap_or_else(|| template_path.as_ref().to_path_buf());
let filestem = captures.name("filestem").unwrap().as_str().to_string();
let file_extension = captures
.name("extension")
Expand Down
52 changes: 32 additions & 20 deletions tinted-builder-rust/src/operations/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ const SCHEMES_URL: &str = "https://github.com/tinted-theming/schemes";
///
/// # Arguments
///
/// * `schemes_path` - A reference to a `Path` representing the directory where the schemes
/// repository is or should be located. * `is_quiet` - A boolean flag that, when set to `true`,
/// * `schemes_path` - A `impl AsRef<Path>` representing the directory where the schemes
/// repository is or should be located.
/// * `is_quiet` - A boolean flag that, when set to `true`,
/// suppresses most of the output, making the operation quieter.
///
/// # Returns
Expand All @@ -45,9 +46,9 @@ const SCHEMES_URL: &str = "https://github.com/tinted-theming/schemes";
///
/// The function will ensure that the schemes repository is up-to-date, either by pulling the
/// latest changes or by cloning the repository if it does not already exist.
pub(crate) fn sync(schemes_path: &Path, is_quiet: bool) -> Result<()> {
if schemes_path.is_dir() {
let is_diff = git_diff(schemes_path)?;
pub(crate) fn sync(schemes_path: impl AsRef<Path>, is_quiet: bool) -> Result<()> {
if schemes_path.as_ref().is_dir() {
let is_diff = git_diff(&schemes_path)?;

if !is_diff {
git_pull(schemes_path, is_quiet).with_context(|| {
Expand All @@ -71,18 +72,18 @@ pub(crate) fn sync(schemes_path: &Path, is_quiet: bool) -> Result<()> {
Ok(())
}

fn git_clone(repo_url: &str, target_dir: &Path, is_quiet: bool) -> Result<()> {
if target_dir.exists() {
fn git_clone(repo_url: &str, target_dir: impl AsRef<Path>, is_quiet: bool) -> Result<()> {
if target_dir.as_ref().exists() {
return Err(anyhow!(
"Error cloning {}. Target directory '{}' already exists",
repo_url,
target_dir.display()
target_dir.as_ref().display()
));
}

let mut cmd = Command::new("git");

cmd.arg("clone").arg(repo_url).arg(target_dir);
cmd.arg("clone").arg(repo_url).arg(target_dir.as_ref());

if is_quiet {
cmd.stdout(Stdio::null()).stderr(Stdio::null());
Expand All @@ -94,40 +95,51 @@ fn git_clone(repo_url: &str, target_dir: &Path, is_quiet: bool) -> Result<()> {
Ok(())
}

fn git_pull(repo_path: &Path, is_quiet: bool) -> Result<()> {
if !repo_path.is_dir() {
fn git_pull(repo_path: impl AsRef<Path>, is_quiet: bool) -> Result<()> {
if !repo_path.as_ref().is_dir() {
return Err(anyhow!(
"Error with git pull. {} is not a directory",
repo_path.display()
repo_path.as_ref().display()
));
}

let mut cmd = Command::new("git");

cmd.arg("pull").current_dir(repo_path);
cmd.arg("pull").current_dir(&repo_path);

if is_quiet {
cmd.stdout(Stdio::null()).stderr(Stdio::null());
}

let status = cmd
.status()
.with_context(|| format!("Failed to execute process in {}", repo_path.display()))?;
let status = cmd.status().with_context(|| {
format!(
"Failed to execute process in {}",
repo_path.as_ref().display()
)
})?;

if status.success() {
Ok(())
} else {
Err(anyhow!("Error wth git pull in {}", repo_path.display()))
Err(anyhow!(
"Error wth git pull in {}",
repo_path.as_ref().display()
))
}
}

fn git_diff(target_dir: &Path) -> Result<bool> {
fn git_diff(target_dir: impl AsRef<Path>) -> Result<bool> {
let output = Command::new("git")
.arg("status")
.arg("--porcelain")
.current_dir(target_dir)
.current_dir(&target_dir)
.output()
.with_context(|| format!("Failed to execute process in {}", target_dir.display()))?;
.with_context(|| {
format!(
"Failed to execute process in {}",
target_dir.as_ref().display()
)
})?;
let stdout = str::from_utf8(&output.stdout).expect("Not valid UTF-8");

if stdout.is_empty() {
Expand Down
11 changes: 6 additions & 5 deletions tinted-builder-rust/tests/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ pub fn run_command(command_vec: Vec<String>) -> Result<(String, String), Box<dyn
}

#[allow(dead_code)]
pub fn write_to_file(path: &Path, contents: &str) -> Result<()> {
if path.exists() {
remove_file(path).with_context(|| format!("Unable to remove file: {}", path.display()))?;
pub fn write_to_file(path: impl AsRef<Path>, contents: &str) -> Result<()> {
if path.as_ref().exists() {
remove_file(&path)
.with_context(|| format!("Unable to remove file: {}", path.as_ref().display()))?;
}

let mut file =
File::create(path).with_context(|| format!("Unable to create file: {}", path.display()))?;
let mut file = File::create(&path)
.with_context(|| format!("Unable to create file: {}", path.as_ref().display()))?;

file.write_all(contents.as_bytes())?;

Expand Down

0 comments on commit c216652

Please sign in to comment.