Replace `pijul_repository::init_dot_ignore` with `pijul_config::Config::dot_ignore_contents`

finchie
Jul 27, 2025, 2:58 PM
2ZKE4XMJ3Z3IBFJCJCXQ6E76T3QEVBB2VEZCY7ZD4EMRJ2BHKBTQC

Dependencies

  • [2] HGJETVAN Create `pijul_config::global_config_directory()`
  • [3] U2KAO5VI Replace `pijul_repository::init_default_config` with `pijul_config::Local::{new, write}`
  • [4] HM6QW3CY Handle missing configurations in `pijul_config`
  • [5] BZSC7VMY address clippy lints
  • [6] CB7UPUQF Customizable ignore_kinds (and a fix of .write())
  • [7] OPC2VAZD Writing an initial config file at initialisation
  • [8] H72JG6HL Init feature; specific .ignore configs
  • [9] Q7CHNDXN Init repo with default .ignore file
  • [10] V447GFPI DEFAULT_IGNORE.iter() (compatibility with different versions of Rust?)
  • [11] GKSVBEUW Refactor Repository constructors to take Option<&Path> instead of Option<PathBuf>
  • [12] SXEYMYF7 Fixing the bad changes in history (unfortunately, by rebooting).
  • [13] 4RV7T4SR Migrate from `pijul::config` to `pijul-config`
  • [14] QCPIBC6M Make the default remote configurable through the cli
  • [15] OMTQVGUE Adjust pijul init to not modify existing .ignore files
  • [16] TYAKEAJL A better estimate of the maximum number of open patches we can keep (Unix-only at the moment)
  • [17] CCLLB7OI Upgrading to Sanakirja 0.15 + version bump
  • [18] YW6NICQV Migrate codebase to refactored `pijul_config` crate
  • [19] UAXGGNAZ Improve command feedback
  • [20] Z4PPQZUG Refactor `pijul-config` to support layered configuration
  • [*] GYGLQPVX Migrate from `pijul::current_dir` to `std::env::current_dir`
  • [*] L4JXJHWX pijul/*: reorganize imports and remove extern crate
  • [*] 7UU3TV5W Refactor `pijul::config` into new crate

Change contents

  • edit in pijul-repository/src/lib.rs at line 3
    [22.27]
    [4.23]
    use std::fs::File;
    use std::io::Write;
  • edit in pijul-repository/src/lib.rs at line 22
    [4.136][4.136:176](),[4.176][4.0:60](),[4.60][4.0:57](),[4.57][4.118:346](),[4.118][4.118:346]()
    pub const CONFIG_FILE: &str = "config";
    const DEFAULT_IGNORE: [&[u8]; 2] = [b".git", b".DS_Store"];
    // Static KV map of names for project kinds |-> elements
    // that should go in the `.ignore` file by default.
    const IGNORE_KINDS: &[(&[&str], &[&[u8]])] = &[
    (&["rust"], &[b"/target", b"Cargo.lock"]),
    (&["node", "nodejs"], &[b"node_modules"]),
    (&["lean"], &[b"/build"]),
    ];
  • edit in pijul-repository/src/lib.rs at line 100
    [4.476][4.0:29]()
    use std::io::Write;
  • replacement in pijul-repository/src/lib.rs at line 110
    [4.24728][4.40:90]()
    init_dot_ignore(config, &cur, kind)?;
    [4.24728]
    [3.33]
    let dot_ignore_path = cur.join(".ignore");
    // Initialize the `.ignore` file, if it doesn't already exist
    if !dot_ignore_path.exists() {
    let mut dot_ignore_file = File::create_new(&dot_ignore_path)?;
    let file_contents = config.dot_ignore_contents(kind)?;
    dot_ignore_file.write_all(file_contents.as_bytes())?;
    }
  • edit in pijul-repository/src/lib.rs at line 141
    [4.7902][4.25342:25358](),[4.25342][4.25342:25358](),[4.217][4.25358:25360](),[4.25358][4.25358:25360](),[4.25360][4.464:465](),[4.558][4.465:608](),[4.465][4.465:608](),[4.608][4.91:225](),[4.225][4.689:713](),[4.642][4.689:713](),[4.660][4.689:713](),[4.989][4.689:713](),[4.689][4.689:713](),[4.713][4.990:1043](),[4.1043][4.833:834](),[4.833][4.833:834](),[4.834][4.0:287](),[4.287][4.983:984](),[4.983][4.983:984](),[4.984][4.288:435]()
    }
    }
    }
    /// Create and populate an initial `.ignore` file for the repository.
    /// The default elements are defined in the constant [`DEFAULT_IGNORE`].
    fn init_dot_ignore(
    config: &pijul_config::Config,
    base_path: &Path,
    kind: Option<&str>,
    ) -> Result<(), anyhow::Error> {
    use std::io::Write;
    let dot_ignore_path = base_path.join(".ignore");
    // Don't replace/modify an existing `.ignore` file.
    if dot_ignore_path.exists() {
    Ok(())
    } else {
    let mut dot_ignore = std::fs::OpenOptions::new()
    .read(true)
    .write(true)
    .create(true)
    .open(dot_ignore_path)?;
    for default_ignore in DEFAULT_IGNORE.iter() {
    dot_ignore.write_all(default_ignore)?;
    dot_ignore.write_all(b"\n")?;
  • edit in pijul-repository/src/lib.rs at line 142
    [4.445][4.226:281]()
    ignore_specific(config, &mut dot_ignore, kind)
  • edit in pijul-repository/src/lib.rs at line 144
    [4.688][4.688:833](),[4.833][4.282:317](),[4.317][4.833:869](),[4.833][4.833:869](),[4.869][4.661:685](),[4.685][4.896:984](),[4.896][4.896:984](),[4.984][4.318:471](),[4.471][4.493:507](),[4.493][4.493:507](),[4.507][4.472:499](),[4.499][4.507:517](),[4.507][4.507:517](),[4.517][4.984:1220](),[4.984][4.984:1220](),[4.1220][4.518:602](),[4.602][4.1296:1312](),[4.1296][4.1296:1312](),[4.1312][4.1110:1123](),[4.1110][4.1110:1123]()
    /// if `kind` matches any of the known project kinds, add the associated
    /// .ignore entries to the default `.ignore` file.
    fn ignore_specific(
    config: &pijul_config::Config,
    dot_ignore: &mut std::fs::File,
    kind: Option<&str>,
    ) -> Result<(), anyhow::Error> {
    use std::io::Write;
    if let Some(kind) = kind {
    if let Some(kinds) = config.ignore_kinds.get(kind) {
    for entry in kinds.iter() {
    writeln!(dot_ignore, "{}", entry)?;
    }
    return Ok(());
    }
    let entries = IGNORE_KINDS
    .iter()
    .find(|(names, _)| names.iter().any(|x| kind.eq_ignore_ascii_case(x)))
    .into_iter()
    .flat_map(|(_, v)| v.iter());
    for entry in entries {
    dot_ignore.write_all(entry)?;
    dot_ignore.write_all(b"\n")?;
    }
    }
    Ok(())
    }
  • edit in pijul-config/src/lib.rs at line 12
    [4.4507][4.0:15]()
    use log::warn;
  • edit in pijul-config/src/lib.rs at line 21
    [4.4643]
    [23.976]
    use log::warn;
  • edit in pijul-config/src/lib.rs at line 24
    [23.1021]
    [4.4644]
    pub const DEFAULT_CONFIG: &str = include_str!("defaults.toml");
  • replacement in pijul-config/src/lib.rs at line 90
    [4.58][4.58:86]()
    // 1. Global config
    [4.58]
    [2.332]
    // 1. Included defaults (defaults.toml)
    layers = layers.merge(Toml::string(DEFAULT_CONFIG));
    // 2. Global config
  • replacement in pijul-config/src/lib.rs at line 115
    [4.673][4.673:700]()
    // 2. Local config
    [4.673]
    [4.700]
    // 3. Local config
  • edit in pijul-config/src/lib.rs at line 152
    [4.7821]
    [4.91198]
    pub fn dot_ignore_contents(&self, ignore_kind: Option<&str>) -> Result<String, anyhow::Error> {
    // The default entry is guaranteed to be present
    let default_ignore_lines = self.ignore_kinds.get("default").unwrap();
  • edit in pijul-config/src/lib.rs at line 157
    [4.91199]
    [4.7822]
    // Find any extra lines to add to the `.ignore`, if they exist
    let extra_ignore_lines = match ignore_kind {
    Some(kind) => match self.ignore_kinds.get(kind) {
    Some(extra_ignore_lines) => extra_ignore_lines.iter(),
    None => {
    return Err(anyhow::anyhow!(
    "Unable to find specific ignore kind: {kind}"
    ));
    }
    },
    None => [].iter(),
    };
    // Merge the default and specific ignore lines
    let mut ignore_lines = default_ignore_lines
    .iter()
    .chain(extra_ignore_lines)
    .map(|line| line.as_str())
    .collect::<Vec<_>>()
    .join("\n");
    // Add a newline at the end of the file
    if !ignore_lines.is_empty() {
    ignore_lines.push('\n');
    }
    Ok(ignore_lines)
    }
  • file addition: defaults.toml (----------)
    [24.41]
    # Default configuration values
    [ignore_kinds]
    default = [".git", ".DS_Store"]
    rust = ["/target", "Cargo.lock"]
    node = ["nodejs", "node_modules"]
    lean = ["/build"]