From 59bf51b37f0aedcf35c61505b166161b625f7295 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sun, 18 Oct 2020 13:11:15 +0530 Subject: [PATCH 1/9] cargo: add serde dependencies Signed-off-by: Harsh Shandilya --- Cargo.lock | 67 +++++++++++++++++++++++++++++++++++++++++++++++------- Cargo.toml | 2 ++ 2 files changed, 61 insertions(+), 8 deletions(-) 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" From 5fcba2926c2c8caee488200fdb2cb82fa9f7692e Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sun, 18 Oct 2020 13:33:11 +0530 Subject: [PATCH 2/9] Start wiring up real data Signed-off-by: Harsh Shandilya --- src/main.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index 5df6857..580cd12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,15 @@ use git2::Repository; +use serde::{Deserialize, Serialize}; use std::path::Path; use walkdir::WalkDir; +#[derive(Debug, Serialize, Deserialize)] +struct PersistableRepo { + pub(crate) path: String, + 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,7 +18,7 @@ fn main() -> anyhow::Result<()> { return Ok(()); } }; - let mut items: Vec = Vec::new(); + let mut repos: Vec = Vec::new(); for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) { if entry.file_type().is_dir() { let path = format!("{}/.git", entry.path().display()); @@ -21,14 +29,19 @@ fn main() -> anyhow::Result<()> { 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() { + repos.push(PersistableRepo { + // Ideally we wanna do this, but it moves `dir`. + // path: entry.path().to_string_lossy().strip_prefix(dir).unwrap().to_string(), + path: entry.path().to_string_lossy().to_string(), + remote_url: repo.remotes()?.get(0).unwrap_or("None").to_string(), + head: head.to_string(), + }); + }; } }; } - println!("{:#x?}", items); + println!("{:#x?}", repos); Ok(()) } From 444564a43d09a8813779e1cdb3cb1965ea18b609 Mon Sep 17 00:00:00 2001 From: ATechnoHazard Date: Mon, 19 Oct 2020 00:51:57 +0530 Subject: [PATCH 3/9] Use upstream remote URL for the currently checked out branch Signed-off-by: ATechnoHazard --- src/main.rs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index 580cd12..f448041 100644 --- a/src/main.rs +++ b/src/main.rs @@ -31,13 +31,25 @@ fn main() -> anyhow::Result<()> { let head = repo.head()?; if let Some(head) = head.name() { - repos.push(PersistableRepo { - // Ideally we wanna do this, but it moves `dir`. - // path: entry.path().to_string_lossy().strip_prefix(dir).unwrap().to_string(), - path: entry.path().to_string_lossy().to_string(), - remote_url: repo.remotes()?.get(0).unwrap_or("None").to_string(), - head: head.to_string(), - }); + 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_or("None") + .split("/") + .collect::>()[2], + ) { + repos.push(PersistableRepo { + // Ideally we wanna do this, but it moves `dir`. + // path: entry.path().to_string_lossy().strip_prefix(dir).unwrap().to_string(), + path: entry.path().to_string_lossy().to_string(), + remote_url: remote.url().unwrap_or("None").to_owned(), + head: head.to_owned(), + }); + } + } }; } }; From 05818aa25173c70ca493c4731ff912da49e57db6 Mon Sep 17 00:00:00 2001 From: ATechnoHazard Date: Mon, 19 Oct 2020 00:54:49 +0530 Subject: [PATCH 4/9] Fix clippy warnings Signed-off-by: ATechnoHazard --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index f448041..78a1a15 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,7 @@ fn main() -> anyhow::Result<()> { upstream .as_str() .unwrap_or("None") - .split("/") + .split('/') .collect::>()[2], ) { repos.push(PersistableRepo { From ed3593056213a937847dd03ef426976f251deabe Mon Sep 17 00:00:00 2001 From: ATechnoHazard Date: Mon, 19 Oct 2020 01:47:57 +0530 Subject: [PATCH 5/9] Create lockfile from scanned repos A hashmap was used instead of nested structs because I realized that this would still run into the problem of duplicate keys. Ergo, use a HashMap with the key set to a unique path Signed-off-by: ATechnoHazard --- src/main.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main.rs b/src/main.rs index 78a1a15..ec18313 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use git2::Repository; use serde::{Deserialize, Serialize}; -use std::path::Path; +use std::{collections::HashMap, fs, path::Path}; use walkdir::WalkDir; #[derive(Debug, Serialize, Deserialize)] @@ -18,11 +18,13 @@ fn main() -> anyhow::Result<()> { return Ok(()); } }; - let mut repos: Vec = Vec::new(); + + let mut repos: HashMap = HashMap::new(); for entry in WalkDir::new(dir).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()? { @@ -41,19 +43,23 @@ fn main() -> anyhow::Result<()> { .split('/') .collect::>()[2], ) { - repos.push(PersistableRepo { - // Ideally we wanna do this, but it moves `dir`. - // path: entry.path().to_string_lossy().strip_prefix(dir).unwrap().to_string(), - path: entry.path().to_string_lossy().to_string(), - remote_url: remote.url().unwrap_or("None").to_owned(), - head: head.to_owned(), - }); + let path = entry.path().to_string_lossy().to_string(); + repos.insert( + path.clone(), + PersistableRepo { + // Ideally we wanna do this, but it moves `dir`. + // path: entry.path().to_string_lossy().strip_prefix(dir).unwrap().to_string(), + path, + remote_url: remote.url().unwrap_or("None").to_owned(), + head: head.to_owned(), + }, + ); } } }; } }; } - println!("{:#x?}", repos); + fs::write("gitice.lock", toml::to_string(&repos)?).expect("could not write to lockfile!"); Ok(()) } From 7b3d457c6229f400f0d10105d30167d6d98433c3 Mon Sep 17 00:00:00 2001 From: ATechnoHazard Date: Mon, 19 Oct 2020 01:55:17 +0530 Subject: [PATCH 6/9] Unwrap upstream URL to prevent obscure panics Signed-off-by: ATechnoHazard --- gitice.lock | 19 +++++++++++++++++++ src/main.rs | 6 +----- 2 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 gitice.lock diff --git a/gitice.lock b/gitice.lock new file mode 100644 index 0000000..a8e1704 --- /dev/null +++ b/gitice.lock @@ -0,0 +1,19 @@ +["../gitice"] +path = "../gitice" +remote_url = "git@github.com:msfjarvis/gitice.git" +head = "refs/heads/persist-into-lockfile" + +["../katbin"] +path = "../katbin" +remote_url = "git@github.com:ATechnoHazard/katbin.git" +head = "refs/heads/master" + +["../rust-rocket-template"] +path = "../rust-rocket-template" +remote_url = "git@github.com:GDGVIT/rust-rocket-template.git" +head = "refs/heads/master" + +["../healthchecks-rs"] +path = "../healthchecks-rs" +remote_url = "git@github.com:ATechnoHazard/healthchecks-rs.git" +head = "refs/heads/develop" diff --git a/src/main.rs b/src/main.rs index ec18313..822c9a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,11 +37,7 @@ fn main() -> anyhow::Result<()> { 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_or("None") - .split('/') - .collect::>()[2], + upstream.as_str().unwrap().split('/').collect::>()[2], ) { let path = entry.path().to_string_lossy().to_string(); repos.insert( From bd2ca9dc31087c1b4d42cec866b74ab07f9b94f2 Mon Sep 17 00:00:00 2001 From: ATechnoHazard Date: Mon, 19 Oct 2020 02:53:34 +0530 Subject: [PATCH 7/9] add generated lockfile to gitignore Signed-off-by: ATechnoHazard --- .gitignore | 1 + gitice.lock | 19 ------------------- 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 gitice.lock 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/gitice.lock b/gitice.lock deleted file mode 100644 index a8e1704..0000000 --- a/gitice.lock +++ /dev/null @@ -1,19 +0,0 @@ -["../gitice"] -path = "../gitice" -remote_url = "git@github.com:msfjarvis/gitice.git" -head = "refs/heads/persist-into-lockfile" - -["../katbin"] -path = "../katbin" -remote_url = "git@github.com:ATechnoHazard/katbin.git" -head = "refs/heads/master" - -["../rust-rocket-template"] -path = "../rust-rocket-template" -remote_url = "git@github.com:GDGVIT/rust-rocket-template.git" -head = "refs/heads/master" - -["../healthchecks-rs"] -path = "../healthchecks-rs" -remote_url = "git@github.com:ATechnoHazard/healthchecks-rs.git" -head = "refs/heads/develop" From 444dea3e036fea14892040023bada4d9e0d7b9f6 Mon Sep 17 00:00:00 2001 From: ATechnoHazard Date: Mon, 19 Oct 2020 03:02:08 +0530 Subject: [PATCH 8/9] Strip dir path prefix without moving Signed-off-by: ATechnoHazard --- src/main.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 822c9a3..e7596a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ fn main() -> anyhow::Result<()> { }; let mut repos: HashMap = HashMap::new(); - for entry in WalkDir::new(dir).into_iter().filter_map(|e| e.ok()) { + 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); @@ -39,12 +39,15 @@ fn main() -> anyhow::Result<()> { // 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().to_string(); + let path = entry + .path() + .to_string_lossy() + .strip_prefix(&dir) + .unwrap() + .to_string(); repos.insert( path.clone(), PersistableRepo { - // Ideally we wanna do this, but it moves `dir`. - // path: entry.path().to_string_lossy().strip_prefix(dir).unwrap().to_string(), path, remote_url: remote.url().unwrap_or("None").to_owned(), head: head.to_owned(), From 3d12c9528f96f828f2ff9393faa505ecd35b7fa3 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Mon, 19 Oct 2020 10:48:28 +0530 Subject: [PATCH 9/9] Tweak lockfile output Signed-off-by: Harsh Shandilya --- src/main.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index e7596a4..09b3e6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ use walkdir::WalkDir; #[derive(Debug, Serialize, Deserialize)] struct PersistableRepo { - pub(crate) path: String, pub(crate) remote_url: String, pub(crate) head: String, } @@ -46,9 +45,8 @@ fn main() -> anyhow::Result<()> { .unwrap() .to_string(); repos.insert( - path.clone(), + path, PersistableRepo { - path, remote_url: remote.url().unwrap_or("None").to_owned(), head: head.to_owned(), },