diff --git a/Cargo.lock b/Cargo.lock index e7ca88e..e41dc7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,7 +197,7 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "kignore" -version = "0.2.4" +version = "0.3.0" dependencies = [ "clap", "console", diff --git a/README.md b/README.md index 8f18bdd..8291f74 100644 --- a/README.md +++ b/README.md @@ -27,24 +27,22 @@ Cargo will only pull the `kignore` command and won't add a subcommand to `git. ```bash $ cargo install kignore +$ cargo binstall kignore # binstall will warn that git.front.kjuulh.io isn't a valid repo, it is still installable though + ``` #### Post install To get the `git ignore` subcommand working you will need to have the file -git-ignore available on your path, either add it yourself using -`git-alias/git-ignore` as a template or: +git-ignore available on your path ``` -git clone https://github.com/kjuulh/gitignore -./scripts/install-git-alias.sh # only tested on mac and linux -``` - -### Homebrew - -Added in HomebrewFormula - -```bash -$ brew tap kjuulh/gitignore https://github.com/kjuulh/gitignore -$ brew install kjuulh/gitignore/kignore-bin +# zsh +eval "kignore init zsh" + +# shell +eval "kignore init sh" + +# bash +eval "kignore init bash" ``` diff --git a/crates/kignore/src/main.rs b/crates/kignore/src/main.rs index 902d7bc..849773a 100644 --- a/crates/kignore/src/main.rs +++ b/crates/kignore/src/main.rs @@ -7,29 +7,55 @@ use std::{env::current_dir, io::Read, path::PathBuf}; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; +const ZSH_FILE_CONTENTS: &[u8] = b"#!/usr/bin/env zsh +set -e + +kignore $@ +"; + const SH_FILE_CONTENTS: &[u8] = b"#!/usr/bin/env sh set -e kignore $@ "; +const BASH_FILE_CONTENTS: &[u8] = b"#!/usr/bin/env bash +set -e + +kignore $@ +"; + pub fn main() -> eyre::Result<()> { let matches = Command::new("gitignore") .version("0.1") .author("Kasper J. Hermansen ") .about("Easily ignore items and remove from git state") - .long_about("git ignore is a utility tool for easily adding patterns to your .gitignore file. -Easily add patterns using `git ignore ` this will by default also help you remove committed code violating these patterns - ") + .long_about( + "git ignore is a utility tool for easily adding patterns to your .gitignore file. +Easily add patterns using `git ignore ` this will by default +also help you remove committed code violating these patterns + ", + ) .propagate_version(true) .arg( Arg::new("pattern") .help("the pattern you want to ignore") - .long_help("the pattern you want to ignore in the nearest .gitignore file") - ).arg( - Arg::new("log-level").long("log-level").default_value("warn").help("choose a log level and get more messages").long_help("Choose a log level and get more message, defaults to [warn]") + .long_help("the pattern you want to ignore in the nearest .gitignore file"), + ) + .arg( + Arg::new("log-level") + .long("log-level") + .default_value("warn") + .help("choose a log level and get more messages") + .long_help("Choose a log level and get more message, defaults to [warn]"), + ) + .subcommand( + clap::Command::new("init") + .subcommand_required(true) + .subcommand(Command::new("zsh")) + .subcommand(Command::new("sh")) + .subcommand(Command::new("bash")), ) - .subcommand(clap::Command::new("init").subcommand_required(true).subcommand(Command::new("zsh"))) .get_matches(); match matches.subcommand() { @@ -37,40 +63,9 @@ Easily add patterns using `git ignore ` this will by default also help .subcommand() .expect("should never be able to call on init") { - ("zsh", _) => { - let bin_dir = dirs::executable_dir().ok_or_eyre("failed to find executable dir")?; - - let alias_script = bin_dir.join("git-ignore"); - if let Ok(existing_file) = std::fs::read(&alias_script) { - if existing_file == SH_FILE_CONTENTS { - return Ok(()); - } - } else { - std::fs::create_dir_all(&bin_dir).context("failed to create bin dir")?; - } - - let mut file = std::fs::OpenOptions::new() - .write(true) - .create(true) - .truncate(true) - .open(&alias_script)?; - - file.write_all(SH_FILE_CONTENTS)?; - file.flush()?; - - // Set the file to be executable - let metadata = file.metadata()?; - let mut permissions = metadata.permissions(); - permissions.set_mode(0o755); // rwxr-xr-x - file.set_permissions(permissions)?; - - println!( - "successfully wrote alias to {}", - style(alias_script.display()).green() - ); - - Ok(()) - } + ("zsh", _) => init_script(ShellType::Zsh), + ("bash", _) => init_script(ShellType::Bash), + ("sh", _) => init_script(ShellType::Shell), (subcommand, _) => { panic!("cannot call on subcommand: {}", subcommand); } @@ -305,3 +300,50 @@ fn search_for_dotgitignore(path: &PathBuf) -> eyre::Result { search_for_dotgitignore(&upwards_par) } + +enum ShellType { + Bash, + Shell, + Zsh, +} + +fn init_script(shell: ShellType) -> eyre::Result<()> { + let bin_dir = dirs::executable_dir().ok_or_eyre("failed to find executable dir")?; + + let script = match shell { + ShellType::Bash => BASH_FILE_CONTENTS, + ShellType::Shell => SH_FILE_CONTENTS, + ShellType::Zsh => ZSH_FILE_CONTENTS, + }; + + let alias_script = bin_dir.join("git-ignore"); + if let Ok(existing_file) = std::fs::read(&alias_script) { + if existing_file == script { + return Ok(()); + } + } else { + std::fs::create_dir_all(&bin_dir).context("failed to create bin dir")?; + } + + let mut file = std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(&alias_script)?; + + file.write_all(script)?; + file.flush()?; + + // Set the file to be executable + let metadata = file.metadata()?; + let mut permissions = metadata.permissions(); + permissions.set_mode(0o755); // rwxr-xr-x + file.set_permissions(permissions)?; + + println!( + "successfully wrote alias to {}", + style(alias_script.display()).green() + ); + + Ok(()) +}