diff --git a/.my_aliases b/.my_aliases new file mode 100644 index 0000000..7dbfd59 --- /dev/null +++ b/.my_aliases @@ -0,0 +1,212 @@ +# ~/.my_aliases — portable aliases & functions for Bash/Zsh on macOS/Linux/WSL +# No network writes or package installs; everything is feature/OS-gated. + +# ----- Guards & OS detection ----- +_exists() { command -v "$1" >/dev/null 2>&1; } + +# OS flags (Darwin, Linux, WSL) +_IS_MAC=0; _IS_LINUX=0; _IS_WSL=0 +case "$(uname -s)" in + Darwin) _IS_MAC=1 ;; + Linux) + _IS_LINUX=1 + grep -qi microsoft /proc/version 2>/dev/null && _IS_WSL=1 + ;; +esac + +# Ensure we only load once per shell session +if [ -n "${_MY_ALIASES_LOADED:-}" ]; then return 0 2>/dev/null || true; fi +_MY_ALIASES_LOADED=1 + +# Prefer "command" over aliases inside functions +_command() { command "$@"; } + +# ----- ls / ll / l (BSD vs GNU safe) ----- +# Prefer GNU ls if installed as "gls" (Homebrew coreutils), else system ls. +_LS_BIN="$(_exists gls && echo gls || echo ls)" + +# Detect GNU vs BSD to set color flag +if $_LS_BIN --version 2>/dev/null | grep -qi 'gnu'; then + _LS_COLOR="--color=auto" +else + _LS_COLOR="-G" # BSD ls +fi + +# Aliases + helpers +alias ls="$_LS_BIN $_LS_COLOR -F" +ll() { $_LS_BIN -lah "$@"; } +l() { pwd; $_LS_BIN -lrtAF "$@"; } + +# ----- Quick dirs ----- +alias pd='pushd' +alias ppd='popd' + +# ----- Kubernetes shortcuts (only if kubectl exists) ----- +if _exists kubectl; then + # Context helpers + kcontext() { kubectl config get-contexts "$@"; } + kscontext() { kubectl config use-context "$@"; } + + # Exec into a pod. Usage: k8sh [namespace] + k8sh() { + local ns pod + if [ "$#" -eq 1 ]; then ns=default; pod="$1"; else ns="$1"; pod="$2"; fi + [ -z "$pod" ] && { echo "usage: k8sh [namespace] "; return 1; } + kubectl -n "$ns" exec -it "$pod" -- bash -l 2>/dev/null || \ + kubectl -n "$ns" exec -it "$pod" -- sh + } + + # Tail logs by label; optional container name + # usage: module_log app.kubernetes.io/name= [container] + module_log() { + local selector="$1" container="$2" + [ -z "$selector" ] && { echo "usage: module_log key[=value] [container]"; return 1; } + while true; do + if [ -n "$container" ]; then + kubectl logs -f -l "$selector" -c "$container" + else + kubectl logs -f -l "$selector" + fi + sleep 1 + done + } + + # kube-ps1 (optional): source if present in common paths; do not auto-install + _KPS1_CANDIDATES=" + $HOME/.kube-ps1.sh + /usr/local/etc/bash_completion.d/kube-ps1.sh + /opt/homebrew/etc/bash_completion.d/kube-ps1.sh + /usr/local/share/kube-ps1/kube-ps1.sh + /opt/homebrew/share/kube-ps1/kube-ps1.sh + /usr/share/kube-ps1/kube-ps1.sh + " + for _p in $_KPS1_CANDIDATES; do + [ -f "$_p" ] && { # shellcheck source=/dev/null + . "$_p" && break + } + done + unset _KPS1_CANDIDATES _p +fi + +# ----- JSON / CSV tooling ----- +# flatj / flatjv accept a file or read from stdin if no arg is given +if _exists jq; then + flatj() { + if [ -n "$1" ]; then jq 'paths(scalars) | map(tostring) | join(".")' "$1" + else jq 'paths(scalars) | map(tostring) | join(".")' + fi + } + flatjv() { + if [ -n "$1" ]; then + jq -r 'paths(scalars) as $p | [([ $p[]|tostring ]|join(".")), (getpath($p)|tojson)] | join(" = ")' "$1" + else + jq -r 'paths(scalars) as $p | [([ $p[]|tostring ]|join(".")), (getpath($p)|tojson)] | join(" = ")' + fi + } +fi + +# Pretty-print CSV using column(1); add -n only if supported (GNU util-linux) +pretty_csv() { + _exists column || { echo "pretty_csv: column(1) not found"; return 1; } + local extra="" + printf 'a,b\n1,2\n' | column -t -s, -n >/dev/null 2>&1 && extra="-n" + column -t -s, $extra "$@" | less -F -S -X +} + +# ----- Clipboard-friendly SSH public key copy (macOS/X11/Wayland/WSL) ----- +copyKey() { + local pub="${1:-$HOME/.ssh/id_rsa.pub}" + [ -r "$pub" ] || { echo "No readable key at: $pub"; return 1; } + if _exists pbcopy; then + cat "$pub" | pbcopy && echo "Public key copied to clipboard (pbcopy)." + elif _exists wl-copy; then + cat "$pub" | wl-copy && echo "Public key copied to clipboard (wl-copy)." + elif _exists xclip; then + cat "$pub" | xclip -selection clipboard && echo "Public key copied to clipboard (xclip)." + elif [ "$_IS_WSL" -eq 1 ] && _exists clip.exe; then + cat "$pub" | clip.exe && echo "Public key copied to clipboard (clip.exe)." + else + echo "No clipboard tool found; printing instead:" + cat "$pub" + fi +} + +# ----- AWS helpers ----- +if _exists aws; then + alias aws_user='aws sts get-caller-identity --output json' +fi + +# ----- Networking ----- +# Interface and output are optional: tcpdump_http [iface] [outfile] +tcpdump_http() { + local iface="${1:-any}" out="${2:-dump.pcap}" + _exists tcpdump || { echo "tcpdump not found"; return 1; } + sudo tcpdump -s0 -i "$iface" -vvv -w "$out" tcp port 80 +} + +# SSH tunnels to common local ports (change as needed) +# usage: tunnel [user] (defaults user=root) +tunnel() { + local host="$1" user="${2:-root}" + [ -z "$host" ] && { echo "usage: tunnel [user]"; return 1; } + sudo ssh -i "$HOME/.ssh/id_rsa" -nNT \ + -o ServerAliveInterval=15 -o ServerAliveCountMax=3 \ + -L 80:localhost:80 \ + -L 8080:localhost:8080 \ + -L 3306:localhost:3306 \ + -L 6379:localhost:6379 \ + -L 8123:localhost:8123 \ + "$user@$host" +} + +# ----- Go env quick-setup ----- +go_setup() { + if ! _exists go; then echo "Go is not installed."; return 1; fi + export GOPATH="${GOPATH:-$HOME/go}" + mkdir -p "$GOPATH"/{src,bin,pkg} "$GOPATH/src/github.com" + case ":$PATH:" in + *":$GOPATH/bin:"*) : ;; + *) export PATH="$GOPATH/bin:$PATH" ;; + esac + echo "GOPATH=$GOPATH" +} + +# ----- Safer SSH helpers ----- +if _exists ssh; then + ss() { local user="$1" host="$2"; shift 2 || true; ssh "${user}@${host}" "$@"; } + ssr() { ss root "$@"; } + ssf() { ss rf "$@"; } +fi + +# ----- SSHFS mounts (portable) ----- +if _exists sshfs; then + # usage: mount_sshfs user@host /remote/path /local/mountpoint + mount_sshfs() { + local remote="$1" rpath="$2" ldir="$3" + [ -z "$remote" ] || [ -z "$rpath" ] || [ -z "$ldir" ] && { + echo "usage: mount_sshfs user@host /remote/path /local/mountpoint"; return 1; } + mkdir -p "$ldir" + if [ "$_IS_MAC" -eq 1 ]; then + diskutil unmount "$ldir" >/dev/null 2>&1 + fi + sshfs -o reconnect \ + -o ServerAliveInterval=15 \ + -o ServerAliveCountMax=3 \ + -o auto_cache \ + -o follow_symlinks \ + "${remote}:${rpath}" "$ldir" + } + # usage: umount_sshfs /local/mountpoint + umount_sshfs() { + local ldir="$1" + [ -z "$ldir" ] && { echo "usage: umount_sshfs /local/mountpoint"; return 1; } + if [ "$_IS_MAC" -eq 1 ]; then + diskutil unmount "$ldir" + else + fusermount -u "$ldir" 2>/dev/null || umount "$ldir" + fi + } +fi + +# ----- Clean up temps ----- +unset _IS_MAC _IS_LINUX _IS_WSL _LS_BIN _LS_COLOR \ No newline at end of file diff --git a/.zshrc b/.zshrc new file mode 100644 index 0000000..8b7964c --- /dev/null +++ b/.zshrc @@ -0,0 +1,47 @@ +export PATH="/opt/homebrew/bin:/usr/local/bin:$HOME/.local/bin:$HOME/bin:$PATH" + +# ----- History ----- +HISTFILE="$HOME/.zsh_history" +HISTSIZE=20000 +SAVEHIST=20000 +setopt hist_ignore_dups hist_reduce_blanks inc_append_history share_history + +# ----- Completion ----- +autoload -Uz compinit && compinit + +# --- Git branch in prompt (green) --- +# --- Fancy Git prompt (macOS zsh) --- + +# 1) Enable substitutions in PROMPT and load helpers +setopt prompt_subst +autoload -Uz vcs_info add-zsh-hook + +# 2) Configure vcs_info for Git +zstyle ':vcs_info:*' enable git +zstyle ':vcs_info:git:*' check-for-changes true # detect dirty state +zstyle ':vcs_info:git:*' stagedstr ' +' # staged changes marker +zstyle ':vcs_info:git:*' unstagedstr ' %' # unstaged changes marker +zstyle ':vcs_info:git:*' formats '%F{yellow}(%b%c%u)%f' # (branch + staged/unstaged) +zstyle ':vcs_info:git:*' actionformats '%F{yellow}(%b%c%u|%a)%f' # rebase/merge actions + +# 3) Refresh vcs_info before each prompt +vcs_precmd() { vcs_info } +add-zsh-hook precmd vcs_precmd + +# 5) Prompt: [platform][IP] user@host (branch + dirty) : cwd with root/# or user/% ending +# Example: [platform][100.92.16.57] rajeevt@jmac (main %) : ~/workspace % +PROMPT='%F{green}%n@%m%f ${vcs_info_msg_0_} %F{blue}%~%f %(#.#.%%) ' + +# Optional right prompt: show last exit code when non-zero + time +RPROMPT='%(?..%F{red}↩ %?%f) %F{240}%*%f' + +# ----- Don’t clobber builtins on macOS ----- +export TERM=xterm-256color + +# ----- Load your aliases/functions ----- +[ -f "$HOME/.my_aliases" ] && source "$HOME/.my_aliases" + +# Optional per-tool extras (if you keep them) +for f in "$HOME/.kubectl_aliases" "$HOME/.docker_aliases" "$HOME/.git_aliases"; do + [ -f "$f" ] && source "$f" +done diff --git a/macos b/macos new file mode 100755 index 0000000..fa3b5f5 --- /dev/null +++ b/macos @@ -0,0 +1,111 @@ +#!/usr/bin/env bash +set -euo pipefail + +# -------- helpers -------- +ts() { date +"%Y%m%d-%H%M%S"; } +backup_if_exists() { + local target="$1" + if [ -e "$target" ] || [ -L "$target" ]; then + cp -a "$target" "${target}.bak.$(ts)" + fi +} + +append_once() { + # append a line to a file if it doesn't already exist (as exact match) + local file="$1" + local line="$2" + grep -Fqx "$line" "$file" 2>/dev/null || printf '%s\n' "$line" >> "$file" +} + +# -------- 1) Ensure $HOME/bin -------- +mkdir -p "$HOME/bin" + +# -------- 2) Copy dotfiles to $HOME (with backups) -------- +# .zshrc +if [ -f "./.zshrc" ]; then + backup_if_exists "$HOME/.zshrc" + cp -a "./.zshrc" "$HOME/.zshrc" + echo "Installed ~/.zshrc" +else + echo "Note: ./.zshrc not found; skipping." +fi + +# .my_aliases (support both names) +if [ -f "./.my_aliases" ]; then + backup_if_exists "$HOME/.my_aliases" + cp -a "./.my_aliases" "$HOME/.my_aliases" + echo "Installed ~/.my_aliases" +elif [ -f "./.myalias" ]; then + backup_if_exists "$HOME/.my_aliases" + cp -a "./.myalias" "$HOME/.my_aliases" + echo "Installed ~/.my_aliases (from ./.myalias)" +else + echo "Note: neither ./.my_aliases nor ./.myalias found; skipping." +fi + +# .kubectl_aliases +if [ -f "./.kubectl_aliases" ]; then + backup_if_exists "$HOME/.kubectl_aliases" + cp -a "./.kubectl_aliases" "$HOME/.kubectl_aliases" + echo "Installed ~/.kubectl_aliases" +else + echo "Note: ./.kubectl_aliases not found; skipping." +fi + +# -------- 3) Install / set up Homebrew -------- +if ! command -v brew >/dev/null 2>&1; then + echo "Homebrew not found. Installing..." + NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +else + echo "Homebrew found." +fi + +# Determine brew prefix (Apple Silicon vs Intel) +BREW_PREFIX="$(/usr/bin/env brew --prefix 2>/dev/null || true)" +if [ -z "${BREW_PREFIX}" ]; then + # Fallbacks + if [ -d /opt/homebrew ]; then + BREW_PREFIX=/opt/homebrew + elif [ -d /usr/local/Homebrew ]; then + BREW_PREFIX=/usr/local + fi +fi + +# -------- 4) Ensure PATH contains Homebrew and $HOME/bin (idempotent) -------- +# Use ~/.zprofile for login shells & ~/.zshrc for interactive shells. +touch "$HOME/.zprofile" "$HOME/.zshrc" + +if [ -n "${BREW_PREFIX:-}" ]; then + # Recommended brew shellenv line + BREW_LINE='eval "$('"$BREW_PREFIX"'/bin/brew shellenv)"' + append_once "$HOME/.zprofile" "$BREW_LINE" + append_once "$HOME/.zshrc" "$BREW_LINE" +fi + +# Ensure $HOME/bin is early in PATH +BIN_LINE='export PATH="$HOME/bin:$PATH"' +append_once "$HOME/.zprofile" "$BIN_LINE" +append_once "$HOME/.zshrc" "$BIN_LINE" + +# Apply to current session (best effort) +if [ -n "${BREW_PREFIX:-}" ] && [ -x "$BREW_PREFIX/bin/brew" ]; then + eval "$("$BREW_PREFIX/bin/brew" shellenv)" +fi +export PATH="$HOME/bin:$PATH" + +# -------- 5) Copy all x* to $HOME/bin and make executable -------- +shopt -s nullglob +copied=0 +for f in x*; do + # Only regular files + [ -f "$f" ] || continue + cp -a "$f" "$HOME/bin/" + chmod +x "$HOME/bin/$(basename "$f")" + echo "Installed $HOME/bin/$(basename "$f")" + copied=$((copied+1)) +done +shopt -u nullglob +[ "$copied" -eq 0 ] && echo "Note: no files matching 'x*' found to copy." + +echo "Done. Open a new terminal or run: source ~/.zprofile && source ~/.zshrc" + diff --git a/rfdev b/rfdev index e7321d0..173d1bb 100755 --- a/rfdev +++ b/rfdev @@ -1,88 +1,32 @@ -#!/bin/bash +#!/usr/bin/env bash +# rfdev: simple persistent tmux with mouse support +set -euo pipefail +SESSION=$(basename "$0") -session_name=$(basename "$0") +CONF="${HOME}/.config/tmux/${SESSION}.conf" +mkdir -p "$(dirname "$CONF")" -quit() { - if tmux has-session -t "${session_name}" 2>/dev/null; then - tmux kill-session -t "${session_name}" - else - echo no tmux session "${session_name}" found. - fi -} - -tmux_select_window() { - echo xxx | tee /tmp/tmux-windows.log - local windows=$(tmux list-windows -a -F "#S:#I:#W" | sed 's/:/ /g') # List all tmux windows - echo "$windows" | tee /tmp/tmux-windows.log - local window=$(echo "$windows" | fzf --height=40% --reverse | tee /tmp/fzf-output.log | awk '{print $1 ":" $2}') # Use fzf to select a window - - if [[ -n $window ]]; then - tmux select-window -t $window # Switch to the selected window - else - echo "No window selected or fzf failed" | tee /tmp/fzf-error.log - fi -} - -export -f tmux_select_window - -config() { - -cat<<'CONFIG' > /tmp/"${session_name}".tmux.conf +# minimal config with working mouse +cat >"$CONF" <<'CFG' set -g mouse on +set -g default-terminal "tmux-256color" +set -as terminal-overrides ",*:RGB" unbind C-b -set-option -g prefix C-o +set -g prefix C-o bind-key C-o send-prefix -bind-key / command-prompt -p 'Search for window:' 'choose-tree -w' -bind-key z run-shell "tmux list-windows -a -F '#S:#I' | fzf --height=40% --reverse | xargs tmux select-window -t" -bind ^ split-window -v -bind-key A command-prompt -I "#W" "rename-window '%%'" -bind-key o last-pane -unbind-key \" -bind-key \" list-windows set -g status-interval 10 -set -g status-right "L: #(cut -d ' ' -f 1-3 /proc/loadavg) | #([ -f /root/rapidfort/RF_SAAS ] && echo S || echo O) | %a %h-%d %H:%M" -CONFIG - -} - -create_windows() { - local windows=("cli" "platform" "common" "test" "log" "build") - local repos=("." "." "." "." "." ".") - # windows=("agg" "bac" "com" "doc" "facc" "fupl" "fro" "fun" "iso" "k8s" "pac" "cli" "plat" "rfp" "rfv" "run" "vul") - # repos=("aggregator" "backend" "common" "documentation" "file_access" "fileupload" "frontrow" "functional-tests" \ - # "iso-master" "k8s-rf-monitor" "package-analyzer" "rapidfort" "rapidfort-platform" "rfpubsub" "rfvdb" "runner" "vulns-db") - - for i in "${!windows[@]}"; do - if [ $i = 0 ]; then - tmux rename-window -t "${session_name}" "${windows[i]}" - tmux send-keys -t "${session_name}" "cd /root/rapidfort/${repos[i]}" C-m - else - tmux new-window -t "${session_name}" -n "${windows[i]}" - tmux send-keys -t "${session_name}":$i "cd /root/rapidfort/${repos[i]}" C-m - fi - done -} - -start() { - - if tmux has-session -t "${session_name}" 2>/dev/null; then - tmux attach-session -t "${session_name}" - else - config - tmux -f /tmp/"${session_name}".tmux.conf new-session -d -s "${session_name}" - create_windows - tmux attach-session -t "${session_name}" - fi -} - -case $1 in - quit|q|exit|x) - echo "Exiting the "${session_name}" ..." - quit - exit 0 - ;; - *) - start - ;; -esac - +set -g status-right "%a %h-%d %H:%M" +set -g set-titles on +set -g set-titles-string "#S:#W" +CFG + +# create or attach +if tmux has-session -t "$SESSION" 2>/dev/null; then + exec tmux -f "$CONF" attach -t "$SESSION" +else + tmux -f "$CONF" new-session -d -s "$SESSION" -n cli + for w in platform common test log build; do + tmux new-window -t "$SESSION" -n "$w" + done + exec tmux -f "$CONF" attach -t "$SESSION" +fi \ No newline at end of file