add readme + env vars + status code

This commit is contained in:
JMARyA 2024-03-27 16:26:38 +01:00
parent bafbb58ff0
commit f8a773fa63
Signed by: jmarya
GPG key ID: 901B2ADDF27C2263
2 changed files with 64 additions and 9 deletions

41
README.md Normal file
View file

@ -0,0 +1,41 @@
# Giterator
Ever wondered why Git histories exist if we just ignore them? Giterator is a powerful command-line tool designed to simplify your Git workflow by providing seamless iteration over commit histories. Explore your project's evolution effortlessly, perform analyses, execute scripts, and generate output in various formats.
## Usage
### Count Lines of Code (LoC) Over Time
```shell
# Count lines of code in Rust files over time
giterator 'find . -type f -name "*.rs" -exec cat {} + | wc -l'
```
### Explore Commits in Another Repository
```shell
giterator command other_repo
```
### Execute Custom Script over each Commit
```shell
# Run a custom script (myscript.sh) on each commit in a repository
giterator --script myscript.sh on_my_repo
```
### Output in JSON Format
```shell
# Generate JSON output for commit analysis
giterator --json command
```
### Output in CSV Format
```shell
# Generate CSV output for commit analysis
giterator --csv command
```
## Environment Variables
When running a custom script or command with Giterator, the following environment variables are automatically exposed:
- `$GIT_REPO`: The name of the repository being iterated over.
- `$COMMIT_HASH`: The hash of the current commit being processed.
- `$COMMIT_DATETIME`: The date and time of the current commit being processed.
- `$COMMIT`: The name of the current commit being processed.
These environment variables allow your custom script or command to access important information about the repository and the current commit being iterated over. You can use these variables to customize the behavior of your script or command.

View file

@ -15,6 +15,7 @@ struct IterationOutput {
commit: Commit,
stdout: String,
stderr: String,
status: i32,
}
impl IterationOutput {
@ -23,15 +24,21 @@ impl IterationOutput {
commit,
stdout: String::from_utf8(out.stdout).unwrap(),
stderr: String::from_utf8(out.stderr).unwrap(),
status: out.status.code().unwrap(),
}
}
fn print_text(&self) {
println!(
"Commit [{}] ({}): {}",
"Commit [{}] ({}): {} {}",
Color::Green.paint(&self.commit.hash),
Color::Purple.paint(&self.commit.datetime),
Color::Blue.paint(&self.commit.name)
Color::Blue.paint(&self.commit.name),
if self.status == 0 {
Color::Red.paint(String::new())
} else {
Color::Red.paint(format!("(Command failed with {})", self.status))
}
);
println!("{}", self.stdout);
if !self.stderr.is_empty() {
@ -46,20 +53,22 @@ impl IterationOutput {
"datetime": self.commit.datetime,
"name": self.commit.datetime,
"stdout": self.stdout,
"stderr": self.stderr
"stderr": self.stderr,
"status": self.status
})
}
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.commit.hash.clone(),
self.commit.datetime.clone(),
self.commit.name.clone(),
self.status.to_string(),
self.stdout.replace('\n', "\\n"),
self.stderr.replace('\n', "\\n"),
]
@ -69,9 +78,12 @@ impl IterationOutput {
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)
.env("GIT_REPO", &self.repo)
.env("COMMIT_HASH", &self.hash)
.env("COMMIT_DATETIME", &self.datetime)
.env("COMMIT", &self.name)
.arg("-c")
.arg(command)
.output()
@ -194,7 +206,9 @@ fn main() {
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"])
wtr.write_record([
"repo", "hash", "datetime", "name", "status", "stdout", "stderr",
])
.unwrap();
for record in csv {