Skip to main content

git_set_attr/
exe.rs

1use crate::{SetAttr, cli::Cli};
2use std::path::PathBuf;
3
4/// Resolve the `.gitattributes` path to write to.
5///
6/// If the user supplied `--file`, that path is used as-is.  Otherwise we
7/// default to `<cwd>/.gitattributes`, falling back to `<workdir>/.gitattributes`
8/// if the current directory is outside the repository's working tree.
9fn resolve_gitattributes_path(
10    repo: &crate::Repository,
11    explicit: Option<&std::path::Path>,
12) -> Result<PathBuf, Box<dyn std::error::Error>> {
13    if let Some(path) = explicit {
14        return Ok(path.to_path_buf());
15    }
16
17    let workdir = repo
18        .workdir()
19        .ok_or("repository has no working directory")?;
20
21    let cwd = std::env::current_dir()?;
22
23    if let Ok(relative) = cwd.strip_prefix(workdir) {
24        Ok(workdir.join(relative).join(".gitattributes"))
25    } else {
26        Ok(workdir.join(".gitattributes"))
27    }
28}
29
30pub fn run(cli: &Cli) -> Result<(), Box<dyn std::error::Error>> {
31    let repo = crate::Repository::open(".")?;
32
33    let gitattributes = resolve_gitattributes_path(&repo, cli.file.as_deref())?;
34    let attributes: Vec<&str> = cli.attributes.iter().map(|s| s.as_str()).collect();
35
36    repo.set_attr(&cli.pattern, &attributes, &gitattributes)?;
37
38    Ok(())
39}