Rewrite: prettify_bash_history

This commit is contained in:
Akemi Izuko 2023-12-23 20:14:05 -07:00
parent eadebe8d33
commit b0a2631193
Signed by: akemi
GPG key ID: 8DE0764E1809E9FC
4 changed files with 185 additions and 1 deletions

2
bin/rewritten_in_rust/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
Cargo.lock
target/

View file

@ -0,0 +1,16 @@
[package]
name = "config_scripts"
version = "0.1.0"
edition = "2021"
authors = ["Akemi Izuko"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[[bin]]
name = "prettify_bash_history"
path = "src/prettify_bash_history.rs"
[dependencies]
clap = { version = "4", features = ["derive"] }
chrono = "0.4"
regex = "1"

View file

@ -0,0 +1,101 @@
use chrono::NaiveDateTime;
use clap::{Parser, ValueEnum};
use regex::Regex;
use std::fs::File;
use std::io::{self, BufRead, Write};
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "prettify_bash_history", author, version = "0.1.0", long_about = None)]
/// Prints a prettier version of the bash-history with unix timestamps
///
/// Converts the unix-timestamped lines to human-readable dates and indents everything else
struct Args {
/// Path to bash history file
#[arg(value_name = "FILE")]
history_file: PathBuf,
/// Type of formatting for the output
#[arg(value_enum)]
style: Style,
}
#[derive(Debug, Copy, Clone, ValueEnum)]
enum Style {
/// Plain text. Readable in vim
Plain,
/// With markdown code blocks
Markdown,
/// With pretty html code blocks
Html,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
let timestamp = Regex::new(r"^#[0-9]{8,}$")?;
let mut wb = io::BufWriter::new(io::stdout());
let mut is_first = true;
let history = File::open(args.history_file)?;
let lines = io::BufReader::new(history).lines().map(|l| l.expect("File is readable"));
for line in lines {
if timestamp.is_match(&line) {
let time = NaiveDateTime::from_timestamp_opt(line[1..].parse()?, 0).unwrap();
let fmttime = format!("{}", time);
let start_line = starting_for_command_line(args.style);
let time_line = format_time_line(&fmttime, args.style);
let end_line = ending_for_command_line(args.style);
if is_first {
writeln!(&mut wb, "{}{}", time_line, start_line)?;
} else {
writeln!(&mut wb, "{}{}{}", end_line, time_line, start_line)?;
}
is_first = false;
} else if is_first {
panic!("Improper file format. Must start with unix timestamp comment line");
} else {
writeln!(&mut wb, "{}", format_command_line(&line, args.style))?;
}
}
writeln!(&mut wb, "{}", ending_for_command_line(args.style))?;
wb.flush()?;
Ok(())
}
fn format_time_line(time: &str, style: Style) -> String {
match style {
Style::Plain => format!("{}", time),
Style::Markdown => format!("## {}\n", time),
Style::Html => format!("<h2>{}</h2>\n", time),
}
}
fn starting_for_command_line(style: Style) -> &'static str {
match style {
Style::Plain => "",
Style::Markdown => "```bash",
Style::Html => "<code>",
}
}
fn ending_for_command_line(style: Style) -> &'static str {
match style {
Style::Plain => "",
Style::Markdown => "```\n\n",
Style::Html => "</code>\n\n",
}
}
fn format_command_line(line: &str, style: Style) -> String {
match style {
Style::Plain => format!(" {}", line),
Style::Markdown => format!("{}", line),
Style::Html => format!("{}", line),
}
}

View file

@ -9,6 +9,7 @@ for a more complete explanation
ARGS:
help Print this menu and exit
status Checks the status of additional installation steps. May need sudo
build Compiles additonal binaries
HELP
}
@ -36,7 +37,6 @@ configs_pointer_is_setup() {
swayland_checks() {
check_sway_wallpaper
check_swaylock_wallpaper
check_swaytree_compilation
check_sway_sounds
}
@ -408,6 +408,68 @@ check_sshdconfig() {
return $return_code
}
####################
# Rust binaries
####################
russy_checks() {
check_for_russy_bins
}
check_for_russy_bins() {
local -i return_code=0
local -a bin_names
bin_names=($(awk '/name =/ { split($0, a, "\""); print a[2] }' ~/.configs_pointer/bin/rewritten_in_rust/Cargo.toml))
if [[ $? -eq 0 ]]; then
for (( i = 1; i < "${#bin_names[@]}"; i++ )); do
local name="${bin_names[i]}"
if ! [[ -L "${HOME}/.configs_pointer/bin/${name}" ]] && [[ -e "${HOME}/.configs_pointer/bin/${name}" ]]; then
printf 'ERR: Conflicting file with rust binary `%s` in bin\n' "$name"
printf '\tRemove the conflicting file and rerun this script with `build`\n'
return_code=1
elif ! [[ -L "${HOME}/.configs_pointer/bin/${name}" ]]; then
printf 'ERR: Missing rust binary `%s` in bin\n' "$name"
printf '\tInstall rust and rerun this script with the `build` argument\n'
return_code=1
fi
done
fi
return $return_code
}
russy_build() {
if command -v cargo &>/dev/null; then
if cargo build --release --manifest-path="$HOME/.configs_pointer/bin/rewritten_in_rust/Cargo.toml"; then
local name
for exe in $(fd -d1 -tx . ~/.configs_pointer/bin/rewritten_in_rust/target/release); do
name="$(basename "$exe")"
(
cd ~/.configs_pointer/bin || return 1
if ! [[ -e "$name" ]]; then
ln -s "./rewritten_in_rust/target/release/$name" "./$name"
elif ! [[ -L "$name" ]]; then
printf 'ERR: Failed to link rust binary \`%s\`\n' "$name"
printf '\tRemove the conflicting file\n'
fi
)
done
else
printf 'ERR: Failed to compile rust binaries\n'
printf '\tInstall rust to compile additional scripts\n'
return 1
fi
else
printf 'ERR: No rust compiler found\n'
printf '\tInstall rust to compile additional scripts\n'
return 1
fi
}
if [[ "$1" == 'status' && "$(uname -s)" == 'Linux' ]]; then
configs_pointer_is_setup || exit 1
@ -422,6 +484,9 @@ if [[ "$1" == 'status' && "$(uname -s)" == 'Linux' ]]; then
aerc_checks
git_checks
ssh_checks
russy_checks
elif [[ "$1" == 'build' ]]; then
russy_build
else
print_help
fi