diff --git a/.gitignore b/.gitignore index 04fcf3e..495de42 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ target/ .history # End of https://www.toptal.com/developers/gitignore/api/rust,visualstudiocode +gitice.lock \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index b09c3dd..c2534b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.13.11" +version = "0.13.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e094214efbc7fdbbdee952147e493b00e99a4e52817492277e98967ae918165" +checksum = "ca6f1a0238d7f8f8fd5ee642f4ebac4dbc03e03d1f78fbe7a3ede35dcf7e2224" dependencies = [ "bitflags", "libc", @@ -89,6 +89,8 @@ dependencies = [ "anyhow", "clap", "git2", + "serde", + "serde_derive", "toml", "walkdir", ] @@ -130,9 +132,9 @@ checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743" [[package]] name = "libgit2-sys" -version = "0.12.13+1.0.1" +version = "0.12.14+1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069eea34f76ec15f2822ccf78fe0cdb8c9016764d0a12865278585a74dbdeae5" +checksum = "8f25af58e6495f7caf2919d08f212de550cfa3ed2f5e744988938ea292b9f549" dependencies = [ "cc", "libc", @@ -210,9 +212,27 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pkg-config" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33" +checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" + +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] [[package]] name = "same-file" @@ -225,9 +245,23 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "b88fa983de7720629c9387e9f517353ed404164b1e482c970a90c1a4aaf7dc1a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd1ae72adb44aab48f325a02444a5fc079349a8d804c1fc922aed3f7454c74e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "strsim" @@ -235,6 +269,17 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "syn" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9c5432ff16d6152371f808fb5a871cd67368171b09bb21b43df8e4a47a3556" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -283,6 +328,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + [[package]] name = "url" version = "2.1.1" diff --git a/Cargo.toml b/Cargo.toml index 27448a4..a982f37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,8 @@ readme = "README.md" anyhow = "1.0.32" clap = { version = "2.33.3", default-features = false, features = ["suggestions", "color"] } git2 = "0.13.11" +serde = {version = "1.0.116", default-features = false, features = ["derive"] } +serde_derive = "1.0.116" toml = "0.5.7" walkdir = "2.3.1" diff --git a/src/main.rs b/src/main.rs index 5df6857..09b3e6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,14 @@ use git2::Repository; -use std::path::Path; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, fs, path::Path}; use walkdir::WalkDir; +#[derive(Debug, Serialize, Deserialize)] +struct PersistableRepo { + pub(crate) remote_url: String, + pub(crate) head: String, +} + fn main() -> anyhow::Result<()> { let dir = match std::env::args().nth(1) { Some(d) => d, @@ -10,25 +17,46 @@ fn main() -> anyhow::Result<()> { return Ok(()); } }; - let mut items: Vec = Vec::new(); - for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) { + + let mut repos: HashMap = HashMap::new(); + for entry in WalkDir::new(dir.clone()).into_iter().filter_map(|e| e.ok()) { if entry.file_type().is_dir() { let path = format!("{}/.git", entry.path().display()); let git_dir = Path::new(&path); + if git_dir.exists() { let repo = Repository::open(git_dir)?; if repo.is_empty()? { continue; } - items.push(format!( - "{} = {}", - entry.path().to_string_lossy().to_string(), - repo.head()?.name().unwrap_or("None") - )); + let head = repo.head()?; + if let Some(head) = head.name() { + if let Ok(upstream) = repo.branch_upstream_name(head) { + if let Ok(remote) = repo.find_remote( + // This is a rather ugly hack, but not sure how else to get the required name + // doesn't seem to work with the full name such as `refs/remotes/origin/master` + upstream.as_str().unwrap().split('/').collect::>()[2], + ) { + let path = entry + .path() + .to_string_lossy() + .strip_prefix(&dir) + .unwrap() + .to_string(); + repos.insert( + path, + PersistableRepo { + remote_url: remote.url().unwrap_or("None").to_owned(), + head: head.to_owned(), + }, + ); + } + } + }; } }; } - println!("{:#x?}", items); + fs::write("gitice.lock", toml::to_string(&repos)?).expect("could not write to lockfile!"); Ok(()) }