init
This commit is contained in:
commit
5802b1104c
5 changed files with 541 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
276
Cargo.lock
generated
Normal file
276
Cargo.lock
generated
Normal file
|
@ -0,0 +1,276 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.6.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "3.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b230ab84b0ffdf890d5a10abdbc8b83ae1c4918275daea1ab8801f71536b2651"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
|
||||||
|
dependencies = [
|
||||||
|
"csv-core",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "csv-core"
|
||||||
|
version = "0.1.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "giterator"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"csv",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.78"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.35"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.197"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.197"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.114"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.52"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.52.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.52.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8"
|
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "giterator"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { version = "4.5.2", features = ["cargo"] }
|
||||||
|
csv = "1.3.0"
|
||||||
|
serde_json = "1.0.114"
|
46
src/args.rs
Normal file
46
src/args.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
use clap::{arg, command, ArgMatches};
|
||||||
|
|
||||||
|
pub fn get_args() -> ArgMatches {
|
||||||
|
command!()
|
||||||
|
.about("Iterate over Git commits and run commands")
|
||||||
|
.arg(arg!([command] "Command to run for each commit").required(true))
|
||||||
|
.arg(
|
||||||
|
arg!([repository] "Git Repository")
|
||||||
|
.required(false)
|
||||||
|
.default_value("."),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
clap::Arg::new("allow-dirty")
|
||||||
|
.long("allow-dirty")
|
||||||
|
.help("Allow working with unclean repository")
|
||||||
|
.num_args(0)
|
||||||
|
.required(false),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
clap::Arg::new("script_file")
|
||||||
|
.short('s')
|
||||||
|
.long("script")
|
||||||
|
.help("Use the content of a script file as command")
|
||||||
|
.num_args(0)
|
||||||
|
.required(false),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
clap::Arg::new("json")
|
||||||
|
.short('j')
|
||||||
|
.long("json")
|
||||||
|
.conflicts_with("csv")
|
||||||
|
.help("Output as JSON")
|
||||||
|
.num_args(0)
|
||||||
|
.required(false),
|
||||||
|
)
|
||||||
|
.arg(
|
||||||
|
clap::Arg::new("csv")
|
||||||
|
.short('c')
|
||||||
|
.long("csv")
|
||||||
|
.conflicts_with("json")
|
||||||
|
.help("Output as CSV")
|
||||||
|
.num_args(0)
|
||||||
|
.required(false),
|
||||||
|
)
|
||||||
|
.get_matches()
|
||||||
|
}
|
207
src/main.rs
Normal file
207
src/main.rs
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
use std::process::{Command, Output};
|
||||||
|
mod args;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct Commit {
|
||||||
|
repo: String,
|
||||||
|
hash: String,
|
||||||
|
datetime: String,
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct IterationOutput {
|
||||||
|
commit: Commit,
|
||||||
|
stdout: String,
|
||||||
|
stderr: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IterationOutput {
|
||||||
|
pub fn new(commit: Commit, out: Output) -> Self {
|
||||||
|
Self {
|
||||||
|
commit,
|
||||||
|
stdout: String::from_utf8(out.stdout).unwrap(),
|
||||||
|
stderr: String::from_utf8(out.stderr).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_text(&self) {
|
||||||
|
println!(
|
||||||
|
"Commit [{}] ({}): {}",
|
||||||
|
self.commit.hash, self.commit.datetime, self.commit.name
|
||||||
|
);
|
||||||
|
println!("{}", self.stdout);
|
||||||
|
if !self.stderr.is_empty() {
|
||||||
|
println!("{}", self.stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_json(&self) -> serde_json::Value {
|
||||||
|
serde_json::json!({
|
||||||
|
"repo": std::fs::canonicalize(self.commit.repo.clone()).unwrap().to_str().unwrap().to_string(),
|
||||||
|
"hash": self.commit.hash,
|
||||||
|
"datetime": self.commit.datetime,
|
||||||
|
"name": self.commit.datetime,
|
||||||
|
"stdout": self.stdout,
|
||||||
|
"stderr": self.stderr
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_csv(&self) -> Vec<String> {
|
||||||
|
vec![
|
||||||
|
self.commit.hash.clone(),
|
||||||
|
self.commit.datetime.clone(),
|
||||||
|
self.commit.name.clone(),
|
||||||
|
std::fs::canonicalize(self.commit.repo.clone())
|
||||||
|
.unwrap()
|
||||||
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
.to_string(),
|
||||||
|
self.stdout.replace('\n', "\\n"),
|
||||||
|
self.stderr.replace('\n', "\\n"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Commit {
|
||||||
|
pub fn run_command(&self, command: &str) -> IterationOutput {
|
||||||
|
checkout(&self.repo, &self.hash).unwrap();
|
||||||
|
// todo : expose env vars
|
||||||
|
let out = Command::new("sh")
|
||||||
|
.current_dir(&self.repo)
|
||||||
|
.arg("-c")
|
||||||
|
.arg(command)
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
IterationOutput::new(self.clone(), out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn checkout(repo: &str, commit: &str) -> Result<(), std::io::Error> {
|
||||||
|
let output = Command::new("git")
|
||||||
|
.current_dir(repo)
|
||||||
|
.arg("checkout")
|
||||||
|
.arg(commit)
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
if output.status.success() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"Failed to execute git command",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_commit_list(repo: &str) -> Result<Vec<Commit>, std::io::Error> {
|
||||||
|
let output = Command::new("git")
|
||||||
|
.current_dir(repo)
|
||||||
|
.arg("log")
|
||||||
|
.arg("--pretty=format:%h - %ad - %s")
|
||||||
|
.arg("--date=iso")
|
||||||
|
.output()?;
|
||||||
|
|
||||||
|
if output.status.success() {
|
||||||
|
let mut commits = Vec::new();
|
||||||
|
let out = String::from_utf8(output.stdout).unwrap();
|
||||||
|
for line in out.lines() {
|
||||||
|
let mut split = line.split(" - ");
|
||||||
|
commits.push(Commit {
|
||||||
|
repo: repo.to_string(),
|
||||||
|
hash: split.next().unwrap().to_string(),
|
||||||
|
datetime: split.next().unwrap().to_string(),
|
||||||
|
name: split.next().unwrap().to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(commits)
|
||||||
|
} else {
|
||||||
|
Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"Failed to execute git command",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_repository_clean(repo: &str) -> bool {
|
||||||
|
let output = Command::new("git")
|
||||||
|
.current_dir(repo)
|
||||||
|
.arg("status")
|
||||||
|
.arg("--porcelain")
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
String::from_utf8(output.stdout).unwrap().is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum OutMode {
|
||||||
|
Text,
|
||||||
|
Json,
|
||||||
|
Csv,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutMode {
|
||||||
|
pub const fn new(json: bool, csv: bool) -> Self {
|
||||||
|
if json {
|
||||||
|
Self::Json
|
||||||
|
} else if csv {
|
||||||
|
Self::Csv
|
||||||
|
} else {
|
||||||
|
Self::Text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args = args::get_args();
|
||||||
|
|
||||||
|
let repo = args.get_one::<String>("repository").unwrap();
|
||||||
|
let allow_dirty = args.get_flag("allow-dirty");
|
||||||
|
let command = if args.get_flag("script_file") {
|
||||||
|
std::fs::read_to_string(args.get_one::<String>("command").unwrap()).unwrap()
|
||||||
|
} else {
|
||||||
|
args.get_one::<String>("command").unwrap().clone()
|
||||||
|
};
|
||||||
|
let outmode = OutMode::new(args.get_flag("json"), args.get_flag("csv"));
|
||||||
|
|
||||||
|
let mut out = Vec::new();
|
||||||
|
|
||||||
|
if is_repository_clean(repo) || allow_dirty {
|
||||||
|
let commits = get_commit_list(repo).unwrap();
|
||||||
|
for commit in commits {
|
||||||
|
// todo : add colors
|
||||||
|
out.push(commit.run_command(&command));
|
||||||
|
}
|
||||||
|
checkout(repo, "main").unwrap();
|
||||||
|
|
||||||
|
match outmode {
|
||||||
|
OutMode::Text => {
|
||||||
|
for i in out {
|
||||||
|
i.print_text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OutMode::Json => {
|
||||||
|
let json: Vec<_> = out.into_iter().map(|x| x.as_json()).collect();
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
serde_json::to_string(&serde_json::to_value(json).unwrap()).unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
OutMode::Csv => {
|
||||||
|
let csv: Vec<Vec<String>> = out.into_iter().map(|x| x.as_csv()).collect();
|
||||||
|
let mut wtr = csv::Writer::from_writer(std::io::stdout());
|
||||||
|
|
||||||
|
wtr.write_record(["hash", "datetime", "name", "repo", "stdout", "stderr"])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
for record in csv {
|
||||||
|
wtr.write_record(&record).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
wtr.flush().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
eprintln!("Repository is not clean. If you want to allow operating over an unclean repository, pass the `--allow-dirty` flag.");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue