Skip to content

Commit 6801c49

Browse files
committed
Set Fossil ignore and clean settings locally
Previously, the Fossil extension for `cargo new` would call `fossil settings [...]` in order to configure the created repository to ignore and allow cleaning the `target` build directory. However, as #9449 shows, it is ran from the CWD, which is probably outside of the repo, therefore it modifies global settings instead of local ones. This aims to fix that by writing the settings to local versioned files as the issue recommends. Signed-off-by: Paul Mabileau <paulmabileau@hotmail.fr>
1 parent db741ac commit 6801c49

File tree

2 files changed

+56
-51
lines changed

2 files changed

+56
-51
lines changed

src/cargo/ops/cargo_new.rs

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,8 @@ struct IgnoreList {
517517
ignore: Vec<String>,
518518
/// mercurial formatted entries
519519
hg_ignore: Vec<String>,
520+
/// Fossil-formatted entries.
521+
fossil_ignore: Vec<String>,
520522
}
521523

522524
impl IgnoreList {
@@ -525,22 +527,25 @@ impl IgnoreList {
525527
IgnoreList {
526528
ignore: Vec::new(),
527529
hg_ignore: Vec::new(),
530+
fossil_ignore: Vec::new(),
528531
}
529532
}
530533

531-
/// add a new entry to the ignore list. Requires two arguments with the
532-
/// entry in two different formats. One for "git style" entries and one for
533-
/// "mercurial like" entries.
534-
fn push(&mut self, ignore: &str, hg_ignore: &str) {
534+
/// Add a new entry to the ignore list. Requires three arguments with the
535+
/// entry in possibly three different formats. One for "git style" entries,
536+
/// one for "mercurial style" entries and one for "fossil style" entries.
537+
fn push(&mut self, ignore: &str, hg_ignore: &str, fossil_ignore: &str) {
535538
self.ignore.push(ignore.to_string());
536539
self.hg_ignore.push(hg_ignore.to_string());
540+
self.fossil_ignore.push(fossil_ignore.to_string());
537541
}
538542

539543
/// Return the correctly formatted content of the ignore file for the given
540544
/// version control system as `String`.
541545
fn format_new(&self, vcs: VersionControl) -> String {
542546
let ignore_items = match vcs {
543547
VersionControl::Hg => &self.hg_ignore,
548+
VersionControl::Fossil => &self.fossil_ignore,
544549
_ => &self.ignore,
545550
};
546551

@@ -557,20 +562,30 @@ impl IgnoreList {
557562

558563
let ignore_items = match vcs {
559564
VersionControl::Hg => &self.hg_ignore,
565+
VersionControl::Fossil => &self.fossil_ignore,
560566
_ => &self.ignore,
561567
};
562568

563-
let mut out = "\n\n# Added by cargo\n".to_string();
564-
if ignore_items
565-
.iter()
566-
.any(|item| existing_items.contains(item))
567-
{
568-
out.push_str("#\n# already existing elements were commented out\n");
569+
let mut out = String::new();
570+
571+
// Fossil does not support `#` comments.
572+
if vcs != VersionControl::Fossil {
573+
out.push_str("\n\n# Added by cargo\n");
574+
if ignore_items
575+
.iter()
576+
.any(|item| existing_items.contains(item))
577+
{
578+
out.push_str("#\n# already existing elements were commented out\n");
579+
}
580+
out.push('\n');
569581
}
570-
out.push('\n');
571582

572583
for item in ignore_items {
573584
if existing_items.contains(item) {
585+
if vcs == VersionControl::Fossil {
586+
// Just merge for Fossil.
587+
continue;
588+
}
574589
out.push('#');
575590
}
576591
out.push_str(item);
@@ -584,30 +599,35 @@ impl IgnoreList {
584599
/// Writes the ignore file to the given directory. If the ignore file for the
585600
/// given vcs system already exists, its content is read and duplicate ignore
586601
/// file entries are filtered out.
587-
fn write_ignore_file(
588-
base_path: &Path,
589-
list: &IgnoreList,
590-
vcs: VersionControl,
591-
) -> CargoResult<String> {
592-
let fp_ignore = match vcs {
593-
VersionControl::Git => base_path.join(".gitignore"),
594-
VersionControl::Hg => base_path.join(".hgignore"),
595-
VersionControl::Pijul => base_path.join(".ignore"),
596-
VersionControl::Fossil => return Ok("".to_string()),
597-
VersionControl::NoVcs => return Ok("".to_string()),
598-
};
602+
fn write_ignore_file(base_path: &Path, list: &IgnoreList, vcs: VersionControl) -> CargoResult<()> {
603+
// Fossil only supports project-level settings in a dedicated subdirectory.
604+
if vcs == VersionControl::Fossil {
605+
paths::create_dir_all(base_path.join(".fossil-settings"))?;
606+
}
599607

600-
let ignore: String = match paths::open(&fp_ignore) {
601-
Err(err) => match err.downcast_ref::<std::io::Error>() {
602-
Some(io_err) if io_err.kind() == ErrorKind::NotFound => list.format_new(vcs),
603-
_ => return Err(err),
604-
},
605-
Ok(file) => list.format_existing(BufReader::new(file), vcs),
606-
};
608+
for fp_ignore in match vcs {
609+
VersionControl::Git => vec![base_path.join(".gitignore")],
610+
VersionControl::Hg => vec![base_path.join(".hgignore")],
611+
VersionControl::Pijul => vec![base_path.join(".ignore")],
612+
// Fossil has a cleaning functionality configured in a separate file.
613+
VersionControl::Fossil => vec![
614+
base_path.join(".fossil-settings/ignore-glob"),
615+
base_path.join(".fossil-settings/clean-glob"),
616+
],
617+
VersionControl::NoVcs => return Ok(()),
618+
} {
619+
let ignore: String = match paths::open(&fp_ignore) {
620+
Err(err) => match err.downcast_ref::<std::io::Error>() {
621+
Some(io_err) if io_err.kind() == ErrorKind::NotFound => list.format_new(vcs),
622+
_ => return Err(err),
623+
},
624+
Ok(file) => list.format_existing(BufReader::new(file), vcs),
625+
};
607626

608-
paths::append(&fp_ignore, ignore.as_bytes())?;
627+
paths::append(&fp_ignore, ignore.as_bytes())?;
628+
}
609629

610-
Ok(ignore)
630+
Ok(())
611631
}
612632

613633
/// Initializes the correct VCS system based on the provided config.
@@ -650,12 +670,12 @@ fn mk(config: &Config, opts: &MkOptions<'_>) -> CargoResult<()> {
650670
let name = opts.name;
651671
let cfg = config.get::<CargoNewConfig>("cargo-new")?;
652672

653-
// Using the push method with two arguments ensures that the entries for
654-
// both `ignore` and `hgignore` are in sync.
673+
// Using the push method with multiple arguments ensures that the entries
674+
// for all mutually-incompatible VCS in terms of syntax are in sync.
655675
let mut ignore = IgnoreList::new();
656-
ignore.push("/target", "^target/");
676+
ignore.push("/target", "^target/", "target");
657677
if !opts.bin {
658-
ignore.push("Cargo.lock", "glob:Cargo.lock");
678+
ignore.push("Cargo.lock", "glob:Cargo.lock", "Cargo.lock,*/Cargo.lock");
659679
}
660680

661681
let vcs = opts.version_control.unwrap_or_else(|| {

src/cargo/util/vcs.rs

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,6 @@ impl FossilRepo {
9595
.arg(db_fname)
9696
.exec()?;
9797

98-
// set `target` as ignoreable and cleanable
99-
ProcessBuilder::new("fossil")
100-
.cwd(cwd)
101-
.arg("settings")
102-
.arg("ignore-glob")
103-
.arg("target")
104-
.exec()?;
105-
106-
ProcessBuilder::new("fossil")
107-
.cwd(cwd)
108-
.arg("settings")
109-
.arg("clean-glob")
110-
.arg("target")
111-
.exec()?;
112-
11398
Ok(FossilRepo)
11499
}
115100
}

0 commit comments

Comments
 (0)