From a7feabf2b8720d0ef65bac03d4777a1ef6296c99 Mon Sep 17 00:00:00 2001 From: arnie Date: Wed, 16 Jul 2025 10:10:23 +0200 Subject: [PATCH] Refactor zsh, add aws-sharable-url shell alias --- home-manager/common.nix | 110 +----------- home-manager/programs/zsh.nix | 159 ++++++++++++++++++ .../common => programs/zsh}/00-colors.zsh | 0 .../common => programs/zsh}/00-locale.zsh | 0 .../common => programs/zsh}/01-setopt.zsh | 0 .../common => programs/zsh}/03-completion.zsh | 0 .../common => programs/zsh}/03-manydots.zsh | 0 .../common => programs/zsh}/04-bindkeys.zsh | 0 .../common => programs/zsh}/05-functions.zsh | 0 .../common => programs/zsh}/07-zsh_hooks.zsh | 0 .../zsh}/09-zsh_aliases.zsh | 0 .../common => programs/zsh}/10-adminer.zsh | 0 home-manager/zsh/common/06-history.zsh | 6 - 13 files changed, 160 insertions(+), 115 deletions(-) create mode 100644 home-manager/programs/zsh.nix rename home-manager/{zsh/common => programs/zsh}/00-colors.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/00-locale.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/01-setopt.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/03-completion.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/03-manydots.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/04-bindkeys.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/05-functions.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/07-zsh_hooks.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/09-zsh_aliases.zsh (100%) rename home-manager/{zsh/common => programs/zsh}/10-adminer.zsh (100%) delete mode 100755 home-manager/zsh/common/06-history.zsh diff --git a/home-manager/common.nix b/home-manager/common.nix index 6813980..3ba7719 100644 --- a/home-manager/common.nix +++ b/home-manager/common.nix @@ -3,17 +3,12 @@ pkgs, ... }: -let - zshSourceCommon = ./zsh/common; - - isDarwin = pkgs.stdenv.hostPlatform.isDarwin; - isLinux = pkgs.stdenv.hostPlatform.isLinux; -in { imports = [ (import ./nix-init-scripts.nix { inherit lib pkgs; }) + ./programs/zsh.nix ]; home.packages = with pkgs; [ @@ -112,109 +107,6 @@ in }; }; - programs.zsh = { - enable = true; - - autocd = lib.mkDefault true; - - shellAliases = - { - # use eval $(aws-export-credentials) to expose them to environment - aws-export-credentials = lib.mkDefault "${pkgs.awscli2}/bin/aws configure export-credentials --format env --profile"; - - aws-export-assume-role = lib.mkDefault "${pkgs.writeShellScript "aws-export-assume-role" '' - [[ -z "$1" || -z "$2" ]] && echo "Usage: aws-export-assume-role " && exit 1 - ${pkgs.coreutils}/bin/printf 'export AWS_ACCESS_KEY_ID=%s\nexport AWS_SECRET_ACCESS_KEY=%s\nexport AWS_SESSION_TOKEN=%s' $(${pkgs.awscli2}/bin/aws --profile "$1" sts assume-role --role-arn "$2" --role-session-name lcech --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text) - ''}"; - - aws-s3-cp-public = lib.mkDefault '' - ${pkgs.awscli2}/bin/aws s3 cp --acl "public-read" --expires "$(${pkgs.coreutils}/bin/date '+%a, %d %b %Y 00:00:00 GMT' -d "$(${pkgs.coreutils}/bin/date +%Y-%m-%d) + 365 day")" --cache-control "max-age=31536000" --metadata-directive REPLACE - ''; - - bcrypt = lib.mkDefault "${pkgs.writeShellScript "bcrypt" '' - if [[ -z "$1" ]]; then - echo "Usage: bcrypt [cost]" - exit 1 - fi - - echo -n "$1" | ${pkgs.apacheHttpd}/bin/htpasswd -i -nB -C ''${2:-12} "" | tr -d ':' - ''}"; - - cat = lib.mkDefault "${pkgs.bat}/bin/bat --paging=never"; - - # use curl-aws --aws-sigv4 "aws:amz:region:service" - curl-aws = lib.mkDefault "${pkgs.curl}/bin/curl -H \"X-Amz-Security-Token: $AWS_SESSION_TOKEN\" --user \"$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY\""; - - curl-timing = lib.mkDefault "${pkgs.curl}/bin/curl -w \" time_namelookup: %{time_namelookup}s\n time_connect: %{time_connect}s\n time_appconnect: %{time_appconnect}s\n time_pretransfer: %{time_pretransfer}s\n time_redirect: %{time_redirect}s\n time_starttransfer: %{time_starttransfer}s\n ----------\n time_total: %{time_total}s\n\" -o /dev/null"; - - dbase64 = lib.mkDefault "${pkgs.writeShellScript "dbase64" "echo -n \"$1\" | base64 -d"}"; - - git-sync-remote = lib.mkDefault "git remote update origin --prune"; - - klogs = lib.mkDefault "${pkgs.writeShellScript "klogs" '' - ctx="$1" - shift - namespace="$1" - shift - label="$1" - shift - - if [[ "$ctx" == "" || "$namespace" == "" || "$label" == "" ]]; then - echo "Usage: klogs context namespace label" - echo "${"\n"}Contexts:" - kubectl config get-contexts -o name | sed 's/^/\t/g' - - echo "Label examples:" - echo "${"\t"}app.kubernetes.io/name=..." - echo "${"\t"}eks.amazonaws.com/component=..." - exit 1 - fi - - kubectl --context "$ctx" logs -f -n "$namespace" -l "$label" $@ - ''}"; - - nixfix = lib.mkDefault "nix fmt ./**/*.nix"; - - # Git - a = "git add"; - c = "git commit -m"; - d = "git diff"; - d-s = "git diff --staged"; - gtag = "${pkgs.writeShellScript "gtag" "git tag -a $1 -m '$2'"}"; - gtag-replace = "${pkgs.writeShellScript "gtag" '' - msg=$(git tag -l -n9 $1 | sed "s/$1\s\+//g") - git tag -d $1 && \ - git push origin :refs/tags/$1 && \ - git tag -a $1 -m "$msg" && \ - git push origin $1 - ''}"; - gtagl = "git fetch --tags && git tag -l -n9 --sort=-v:refname"; - s = "git status"; - } - // ( - if isDarwin then - { - hm-switch = lib.mkDefault "darwin-rebuild switch --flake ~/.config/nix"; - } - else if isLinux then - { - hm-switch = lib.mkDefault "home-manager switch --impure --flake ~/.config/nix"; - } - else - { } - ); - - initContent = lib.mkBefore '' - for file in ${zshSourceCommon}/*.zsh; do - source "$file" - done - - # [Ctrl-RightArrow] - move forward one word - bindkey '^[[1;3C' forward-word - # [Ctrl-LeftArrow] - move backward one word - bindkey '^[[1;3D' backward-word - ''; - }; programs.starship = { enable = true; diff --git a/home-manager/programs/zsh.nix b/home-manager/programs/zsh.nix new file mode 100644 index 0000000..ea831ac --- /dev/null +++ b/home-manager/programs/zsh.nix @@ -0,0 +1,159 @@ +{ + lib, + pkgs, + ... +}: +let + isDarwin = pkgs.stdenv.hostPlatform.isDarwin; + isLinux = pkgs.stdenv.hostPlatform.isLinux; +in +{ + programs.zsh = { + enable = true; + + autocd = lib.mkDefault true; + + history = { + expireDuplicatesFirst = true; + ignoreDups = true; + save = 10000; + share = false; + size = 10000; + }; + + shellAliases = + { + # use eval $(aws-export-credentials) to expose them to environment + aws-export-credentials = lib.mkDefault "${pkgs.awscli2}/bin/aws configure export-credentials --format env --profile"; + + aws-export-assume-role = lib.mkDefault "${pkgs.writeShellScript "aws-export-assume-role" '' + [[ -z "$1" || -z "$2" ]] && echo "Usage: aws-export-assume-role " && exit 1 + ${pkgs.coreutils}/bin/printf 'export AWS_ACCESS_KEY_ID=%s\nexport AWS_SECRET_ACCESS_KEY=%s\nexport AWS_SESSION_TOKEN=%s' $(${pkgs.awscli2}/bin/aws --profile "$1" sts assume-role --role-arn "$2" --role-session-name lcech --query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" --output text) + ''}"; + + # https://docs.aws.amazon.com/singlesignon/latest/userguide/createshortcutlink.html + aws-sharable-url = lib.mkDefault "${pkgs.writeShellScript "aws-sharable-url" '' + set -e + + URL=$1 + [[ -z "$URL" ]] && read -p "Enter URL: " URL + + # Strip schema + URL="''${URL#https://}" + + # Parse Account ID from multi-session URL + ACCOUNT_ID="''${URL%%-*}" + + # Strip account ID and hash up to the region part + URL="''${URL#*\.}" + + PROFILE=$(${pkgs.coreutils}/bin/grep "sso_account_id = $ACCOUNT_ID" ~/.aws/config -B 5 | ${pkgs.coreutils}/bin/grep "\[profile" | ${pkgs.coreutils}/bin/tail -n 1 | ${pkgs.coreutils}/bin/tr -d '[]') + PROFILE="''${PROFILE#profile }" + + ROLE_NAME=$(${pkgs.awscli2}/bin/aws configure get profile.$PROFILE.sso_role_name) + SSO_SESSION=$(${pkgs.awscli2}/bin/aws configure get profile.$PROFILE.sso_session) + + SSO_URL=$(${pkgs.coreutils}/bin/grep "\[sso-session $SSO_SESSION" ~/.aws/config -A5 | ${pkgs.coreutils}/bin/grep sso_start_url | ${pkgs.coreutils}/bin/head -n 1) + SSO_URL="''${SSO_URL#sso_start_url = }" + # Strip trailing slash from SSO_URL if present + SSO_URL="''${SSO_URL%/}" + + SHARABLE_URL="$SSO_URL/#/console?account_id=$ACCOUNT_ID&role_name=$ROLE_NAME&destination=$(${pkgs.urlencode}/bin/urlencode "https://$URL")" + + ${if isDarwin then '' + echo -n "$SHARABLE_URL" | pbcopy + '' else '' + echo -n "$SHARABLE_URL" | ${pkgs.xclip}/bin/xclip -selection clipboard + ''} + echo "URL copied to clipboard" + ''}"; + + aws-s3-cp-public = lib.mkDefault '' + ${pkgs.awscli2}/bin/aws s3 cp --acl "public-read" --expires "$(${pkgs.coreutils}/bin/date '+%a, %d %b %Y 00:00:00 GMT' -d "$(${pkgs.coreutils}/bin/date +%Y-%m-%d) + 365 day")" --cache-control "max-age=31536000" --metadata-directive REPLACE + ''; + + bcrypt = lib.mkDefault "${pkgs.writeShellScript "bcrypt" '' + if [[ -z "$1" ]]; then + echo "Usage: bcrypt [cost]" + exit 1 + fi + + echo -n "$1" | ${pkgs.apacheHttpd}/bin/htpasswd -i -nB -C ''${2:-12} "" | tr -d ':' + ''}"; + + cat = lib.mkDefault "${pkgs.bat}/bin/bat --paging=never"; + + # use curl-aws --aws-sigv4 "aws:amz:region:service" + curl-aws = lib.mkDefault "${pkgs.curl}/bin/curl -H \"X-Amz-Security-Token: $AWS_SESSION_TOKEN\" --user \"$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY\""; + + curl-timing = lib.mkDefault "${pkgs.curl}/bin/curl -w \" time_namelookup: %{time_namelookup}s\n time_connect: %{time_connect}s\n time_appconnect: %{time_appconnect}s\n time_pretransfer: %{time_pretransfer}s\n time_redirect: %{time_redirect}s\n time_starttransfer: %{time_starttransfer}s\n ----------\n time_total: %{time_total}s\n\" -o /dev/null"; + + dbase64 = lib.mkDefault "${pkgs.writeShellScript "dbase64" "echo -n \"$1\" | base64 -d"}"; + + git-sync-remote = lib.mkDefault "git remote update origin --prune"; + + klogs = lib.mkDefault "${pkgs.writeShellScript "klogs" '' + ctx="$1" + shift + namespace="$1" + shift + label="$1" + shift + + if [[ "$ctx" == "" || "$namespace" == "" || "$label" == "" ]]; then + echo "Usage: klogs context namespace label" + echo "${"\n"}Contexts:" + kubectl config get-contexts -o name | sed 's/^/\t/g' + + echo "Label examples:" + echo "${"\t"}app.kubernetes.io/name=..." + echo "${"\t"}eks.amazonaws.com/component=..." + exit 1 + fi + + kubectl --context "$ctx" logs -f -n "$namespace" -l "$label" $@ + ''}"; + + nixfix = lib.mkDefault "nix fmt ./**/*.nix"; + + # Git + a = "git add"; + c = "git commit -m"; + d = "git diff"; + d-s = "git diff --staged"; + gtag = "${pkgs.writeShellScript "gtag" "git tag -a $1 -m '$2'"}"; + gtag-replace = "${pkgs.writeShellScript "gtag" '' + msg=$(git tag -l -n9 $1 | sed "s/$1\s\+//g") + git tag -d $1 && \ + git push origin :refs/tags/$1 && \ + git tag -a $1 -m "$msg" && \ + git push origin $1 + ''}"; + gtagl = "git fetch --tags && git tag -l -n9 --sort=-v:refname"; + s = "git status"; + } + // ( + if isDarwin then + { + hm-switch = lib.mkDefault "sudo darwin-rebuild switch --flake ~/.config/nix"; + } + else if isLinux then + { + hm-switch = lib.mkDefault "home-manager switch --impure --flake ~/.config/nix"; + } + else + { } + ); + + initContent = lib.mkBefore '' + for file in ${./zsh}/*.zsh; do + source "$file" + done + + # [Ctrl-RightArrow] - move forward one word + bindkey '^[[1;3C' forward-word + # [Ctrl-LeftArrow] - move backward one word + bindkey '^[[1;3D' backward-word + ''; + }; +} diff --git a/home-manager/zsh/common/00-colors.zsh b/home-manager/programs/zsh/00-colors.zsh similarity index 100% rename from home-manager/zsh/common/00-colors.zsh rename to home-manager/programs/zsh/00-colors.zsh diff --git a/home-manager/zsh/common/00-locale.zsh b/home-manager/programs/zsh/00-locale.zsh similarity index 100% rename from home-manager/zsh/common/00-locale.zsh rename to home-manager/programs/zsh/00-locale.zsh diff --git a/home-manager/zsh/common/01-setopt.zsh b/home-manager/programs/zsh/01-setopt.zsh similarity index 100% rename from home-manager/zsh/common/01-setopt.zsh rename to home-manager/programs/zsh/01-setopt.zsh diff --git a/home-manager/zsh/common/03-completion.zsh b/home-manager/programs/zsh/03-completion.zsh similarity index 100% rename from home-manager/zsh/common/03-completion.zsh rename to home-manager/programs/zsh/03-completion.zsh diff --git a/home-manager/zsh/common/03-manydots.zsh b/home-manager/programs/zsh/03-manydots.zsh similarity index 100% rename from home-manager/zsh/common/03-manydots.zsh rename to home-manager/programs/zsh/03-manydots.zsh diff --git a/home-manager/zsh/common/04-bindkeys.zsh b/home-manager/programs/zsh/04-bindkeys.zsh similarity index 100% rename from home-manager/zsh/common/04-bindkeys.zsh rename to home-manager/programs/zsh/04-bindkeys.zsh diff --git a/home-manager/zsh/common/05-functions.zsh b/home-manager/programs/zsh/05-functions.zsh similarity index 100% rename from home-manager/zsh/common/05-functions.zsh rename to home-manager/programs/zsh/05-functions.zsh diff --git a/home-manager/zsh/common/07-zsh_hooks.zsh b/home-manager/programs/zsh/07-zsh_hooks.zsh similarity index 100% rename from home-manager/zsh/common/07-zsh_hooks.zsh rename to home-manager/programs/zsh/07-zsh_hooks.zsh diff --git a/home-manager/zsh/common/09-zsh_aliases.zsh b/home-manager/programs/zsh/09-zsh_aliases.zsh similarity index 100% rename from home-manager/zsh/common/09-zsh_aliases.zsh rename to home-manager/programs/zsh/09-zsh_aliases.zsh diff --git a/home-manager/zsh/common/10-adminer.zsh b/home-manager/programs/zsh/10-adminer.zsh similarity index 100% rename from home-manager/zsh/common/10-adminer.zsh rename to home-manager/programs/zsh/10-adminer.zsh diff --git a/home-manager/zsh/common/06-history.zsh b/home-manager/zsh/common/06-history.zsh deleted file mode 100755 index fe27e9e..0000000 --- a/home-manager/zsh/common/06-history.zsh +++ /dev/null @@ -1,6 +0,0 @@ -# HISTORY -HISTSIZE=10000 -SAVEHIST=10000 -HISTFILE=~/.zsh_history - -# bindkey '^R' zaw-history