From d3730fdff5230544d44a0a70b9951c797431a0fa Mon Sep 17 00:00:00 2001 From: Michal Date: Sun, 24 Jul 2022 22:54:55 +0100 Subject: [PATCH] Implemented second delimiter as rev spec in repo mode --- docs/COMMON_FEATURES.md | 20 +++---- examples/repository/mlc.toml | 4 +- examples/workspace/mlc.toml | 4 +- src/internal/read.rs | 14 +---- src/internal/structs.rs | 4 +- src/operations/clone.rs | 111 +++++++++++++++++++++++++++-------- 6 files changed, 104 insertions(+), 53 deletions(-) diff --git a/docs/COMMON_FEATURES.md b/docs/COMMON_FEATURES.md index 48a3776..cc97717 100644 --- a/docs/COMMON_FEATURES.md +++ b/docs/COMMON_FEATURES.md @@ -16,14 +16,9 @@ Without further ado, let's take a look at this example config file. mode = "workspace" smart_pull = true -[mode.repository] -name = "" -build_on_update = false - -[mode.repository.signing] -enabled = false -key = "" -on_gen = false +[mode.workspace] +git_info = true +colorblind = true [repositories] repos = [ @@ -93,8 +88,8 @@ repos = [ ] [repositories.urls] -foo = "https://example.org/%repo%.git" -bar = "https://example.org/other/%repo%.git" +foo = "https://example.org/{}.git" +bar = "https://example.org/other/{}.git" ``` The way this works is simple: @@ -108,7 +103,10 @@ The way this works is simple: I'm glad you asked! - If you want to clone a specific branch, simply use the `/` delimiter. To clone repository `foo` on branch `bar`, use `id:foo/bar`. - If you want a specific package to build first, use instances of `!` to set priority. This is explained later in the [Repository Mode](REPOSITORY_MODE.md) page -- If you want to clone the repository with a specific depth, for example, in the case of a large git repository like `nixpkgs`, you can add a 2nd `:` delimiter and the integer after that will be used as the depth + +The last `:` delimiter is entirely optional, and behaves differently depending on the mode: +- In Repository mode, it defines the desired commit hash/rev/tag to checkout on repository clone +- In Workspace mode, it defines the desired depth to clone the repository, useful with large git repositories, such as `nixpkgs`. That's literally it! diff --git a/examples/repository/mlc.toml b/examples/repository/mlc.toml index 99387b0..3b9a0f4 100644 --- a/examples/repository/mlc.toml +++ b/examples/repository/mlc.toml @@ -13,10 +13,12 @@ on_gen = true [repositories] repos = [ - "crs:malachite/development", + "crs:malachite/development:0a5bdc9", + "mic:apod:v.1.1.2", "pkg:pfetch!", ] [repositories.urls] crs = "https://github.com/crystal-linux/{}" pkg = "https://github.com/crystal-linux/pkgbuild.{}" +mic = "https://git.tar.black/michal/{}" diff --git a/examples/workspace/mlc.toml b/examples/workspace/mlc.toml index 7023d69..27d2bed 100644 --- a/examples/workspace/mlc.toml +++ b/examples/workspace/mlc.toml @@ -11,12 +11,10 @@ repos = [ "crs:amethyst", "crs:malachite/development!", "aur:notop-git", - "nms:appendage", - "nix:nixpkgs/nixos-unstable:ass", + "nix:nixpkgs/nixos-unstable:1", ] [repositories.urls] crs = "https://github.com/crystal-linux/{}" aur = "https://aur.archlinux.org/{}" -nms = "https://github.com/not-my-segfault/{}" nix = "https://github.com/nixos/{}" diff --git a/src/internal/read.rs b/src/internal/read.rs index 9147655..749c81e 100644 --- a/src/internal/read.rs +++ b/src/internal/read.rs @@ -47,21 +47,13 @@ pub fn parse_cfg(verbose: bool) -> Config { SplitRepo { id: split[0].parse().unwrap(), name: split[1].parse().unwrap(), - depth: Some(split[2].parse().unwrap_or_else(|e| { - crash!( - AppExitCode::ConfigParseError, - "Depth must be an integer: {}", - e - ); - // This is unreachable, but rustc complains about it otherwise - std::process::exit(1); - })), + extra: Some(split[2].parse().unwrap()), } } else { SplitRepo { id: split[0].parse().unwrap(), name: split[1].parse().unwrap(), - depth: None, + extra: None, } }; log!(verbose, "Split repo: {:?}", split_struct); @@ -108,7 +100,7 @@ pub fn parse_cfg(verbose: bool) -> Config { name, url, branch, - depth: split_struct.depth, + extra: split_struct.extra, priority: *priority, }; log!(verbose, "Expanded repo: {:?}", repo); diff --git a/src/internal/structs.rs b/src/internal/structs.rs index 9e18d32..59cb8b3 100755 --- a/src/internal/structs.rs +++ b/src/internal/structs.rs @@ -68,7 +68,7 @@ pub struct Repo { pub name: String, pub url: String, pub branch: Option, - pub depth: Option, + pub extra: Option, pub priority: usize, } @@ -76,7 +76,7 @@ pub struct Repo { pub struct SplitRepo { pub id: String, pub name: String, - pub depth: Option, + pub extra: Option, } //// Build operation structs diff --git a/src/operations/clone.rs b/src/operations/clone.rs index 3a48a52..75db48b 100644 --- a/src/operations/clone.rs +++ b/src/operations/clone.rs @@ -1,3 +1,4 @@ +use std::env; use std::process::Command; use crate::{info, log}; @@ -47,40 +48,100 @@ pub fn clone(verbose: bool) { // Clone all diff repos for r in repo_diff { - let depth = if r.depth.is_some() { - format!("{}", r.depth.as_ref().unwrap()) - } else { - "".to_string() - }; - log!(verbose, "Depth: {:?}", r.depth); + log!(verbose, "Depth: {:?}", r.extra); log!(verbose, "Cloning {}", r.name); - if r.depth.is_some() { + if r.extra.is_some() && config.base.mode == "workspace" { info!( - "Cloning ({} mode): {} - Depth: {}", + "Cloning ({} mode): {} at depth: {}", config.base.mode, r.name, - r.depth.unwrap() + r.extra.as_ref().unwrap() + ); + } else if r.extra.is_some() && config.base.mode == "repository" { + info!( + "Cloning ({} mode): {} at {}", + config.base.mode, + r.name, + r.extra.as_ref().unwrap() ); } else { info!("Cloning ({} mode): {}", config.base.mode, r.name); } - Command::new("git") - .args(&["clone", &r.url, &r.name]) - // If a branch is specified, clone that specific branch - .args(if r.branch.is_some() { - vec!["-b", r.branch.as_ref().unwrap()] - } else { - vec![] - }) - .args(if depth.is_empty() { - vec![] + + if r.extra.is_some() && config.base.mode == "workspace" { + // Clone with specified extra depth + Command::new("git") + .args(&["clone", &r.url, &r.name]) + // If a branch is specified, clone that specific branch + .args(if r.branch.is_some() { + vec!["-b", r.branch.as_ref().unwrap()] + } else { + vec![] + }) + .args(if r.extra.is_some() { + vec!["--depth", r.extra.as_ref().unwrap()] + } else { + vec![] + }) + .spawn() + .unwrap() + .wait() + .unwrap(); + } else if config.base.mode == "repository" { + // Clone and checkout specified hash + // Create an empty directory with repo.name and enter it + let root_dir = env::current_dir().unwrap(); + + // Git clone the repo with the `-n` flag to not immediately checkout the files + Command::new("git") + .args(&["clone", &r.url, &r.name, "-n"]) + .args(if r.branch.is_some() { + vec!["-b", r.branch.as_ref().unwrap()] + } else { + vec![] + }) + .spawn() + .unwrap() + .wait() + .unwrap(); + + std::env::set_current_dir(&r.name).unwrap(); + log!(verbose, "Entered directory: {}", r.name); + + // Git checkout the PKGBUILD from the hash + if r.extra.is_some() { + Command::new("git") + .args(&["checkout", r.extra.as_ref().unwrap(), "PKGBUILD"]) + .spawn() + .unwrap() + .wait() + .unwrap(); } else { - vec!["--depth", &depth] - }) - .spawn() - .unwrap() - .wait() - .unwrap(); + Command::new("git") + .args(&["checkout", "HEAD", "PKGBUILD"]) + .spawn() + .unwrap() + .wait() + .unwrap(); + } + + // Return to the root directory + std::env::set_current_dir(root_dir).unwrap(); + log!(verbose, "Returned to root directory"); + } else { + // Clone normally + Command::new("git") + .args(&["clone", &r.url, &r.name]) + .args(if r.branch.is_some() { + vec!["-b", r.branch.as_ref().unwrap()] + } else { + vec![] + }) + .spawn() + .unwrap() + .wait() + .unwrap(); + } } } }