Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bin/wt-add
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ if [[ $# -eq 0 ]]; then
exit 1
fi

# Show context banner if contexts are configured
wt_show_context_banner

# 1. Validate and cd into the main repo
if [[ ! -d "$WT_MAIN_REPO_ROOT" ]]; then
error "WT_MAIN_REPO_ROOT does not exist: $WT_MAIN_REPO_ROOT"
Expand Down
3 changes: 3 additions & 0 deletions bin/wt-cd
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ if [[ $# -eq 1 ]]; then
esac
fi

# Show context banner if contexts are configured (output to stderr)
wt_show_context_banner

#
# Pick target worktree (interactive or from argument)
#
Expand Down
210 changes: 210 additions & 0 deletions bin/wt-context
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
#!/usr/bin/env bash
#
# wt-context — Manage repository contexts for multi-repo support
# ==============================================================
#
# This command allows switching between multiple repository configurations.
# Each context represents a different git repository with its own worktree
# setup, metadata location, and default branch.
#
# Usage:
# wt context # Interactive: pick context from menu
# wt context <name> # Switch to named context
# wt context --list # List all contexts without switching
# wt context add # Add a new repository context
# wt context add <path> # Add context for repository at path
# wt context add <name> <path> # Add context with specific name
#
# Examples:
# wt context # Shows menu to pick from java, go, frontend
# wt context java # Switch to java context
# wt context -l # List all contexts
# wt context add ~/code/myrepo # Add new context (prompts for name)
#

set -euo pipefail

# Resolve script and lib directories
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIB_DIR="$SCRIPT_DIR/../lib"

# Bootstrap: source wt-common from lib/
if [[ -f "$LIB_DIR/wt-common" ]]; then
. "$LIB_DIR/wt-common"
elif [[ -f "$HOME/.wt/lib/wt-common" ]]; then
. "$HOME/.wt/lib/wt-common"
else
echo "Error: Cannot find wt-common" >&2
exit 1
fi

# Source wt-context library
wt_source wt-context

# Source wt-context-setup library for add command
wt_source wt-context-setup

usage() {
cat <<EOF
Usage: $(basename "$0") [OPTIONS] [CONTEXT_NAME]
$(basename "$0") add [NAME] [PATH]

Manage repository contexts for multi-repo support.

Options:
-l, --list List all contexts without switching
-h, --help Show this help message

Subcommands:
add Add a new repository context

Examples:
$(basename "$0") # Interactive selection
$(basename "$0") java # Switch to 'java' context
$(basename "$0") --list # List all contexts
$(basename "$0") add # Add new context (interactive)
$(basename "$0") add ~/repo # Add context for repository
$(basename "$0") add myname ~/repo # Add context with specific name
EOF
}

# ─────────────────────────────────────────────────────────────────────────────
# Add context subcommand - runs full setup flow
# ─────────────────────────────────────────────────────────────────────────────

add_context() {
local repo_path=""
local context_name=""

# Parse add subcommand arguments
case $# in
0)
# Interactive: wt_setup_context will prompt for both
;;
1)
# Just path provided
repo_path="$1"
;;
2)
# Both name and path provided (name first for non-interactive use)
context_name="$1"
repo_path="$2"
;;
*)
error "Too many arguments for 'add' subcommand"
usage
exit 1
;;
esac

# Run the full setup flow from wt-context-setup library
wt_setup_context "$repo_path" "$context_name"
}

# ─────────────────────────────────────────────────────────────────────────────
# List contexts
# ─────────────────────────────────────────────────────────────────────────────

list_contexts() {
local repos_dir current_context
repos_dir="$(wt_get_repos_dir)"
current_context="$(wt_get_current_context)"

if [[ ! -d "$repos_dir" ]] || ! compgen -G "$repos_dir/*.conf" >/dev/null 2>&1; then
echo "No contexts configured."
echo "Run 'wt context add' to add a repository."
return 0
fi

echo

for conf in "$repos_dir"/*.conf; do
[[ -f "$conf" ]] || continue
local name path prefix
name="$(basename "$conf" .conf)"
path="$(wt_get_context_repo_root "$name")"

if [[ "$name" == "$current_context" ]]; then
prefix="${GREEN}*${NC} "
else
prefix=" "
fi

printf "%s%-15s %s" "$prefix" "$name" "$path"
if [[ "$name" == "$current_context" ]]; then
printf " ${GREEN}(current)${NC}"
fi
echo
done

echo
}

# ─────────────────────────────────────────────────────────────────────────────
# Switch context
# ─────────────────────────────────────────────────────────────────────────────

switch_context() {
local target_context="$1"

if [[ -z "$target_context" ]]; then
# Interactive selection
target_context="$(select_context)" || exit 1
fi

if ! wt_context_exists "$target_context"; then
error "Context not found: $target_context"
echo "Available contexts:"
wt_list_contexts | while read -r ctx; do
echo " $ctx"
done
exit 1
fi

wt_set_current_context "$target_context"
success "Switched to: $target_context"
}

# ─────────────────────────────────────────────────────────────────────────────
# Main
# ─────────────────────────────────────────────────────────────────────────────

main() {
local list_only=false
local target_context=""

while [[ $# -gt 0 ]]; do
case "$1" in
-l|--list)
list_only=true
shift
;;
-h|--help)
usage
exit 0
;;
add)
shift
add_context "$@"
exit $?
;;
-*)
error "Unknown option: $1"
usage
exit 1
;;
*)
target_context="$1"
shift
;;
esac
done

if [[ "$list_only" == "true" ]]; then
list_contexts
else
switch_context "$target_context"
fi
}

main "$@"
3 changes: 3 additions & 0 deletions bin/wt-list
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ while [[ $# -gt 0 ]]; do
esac
done

# Show context banner if contexts are configured
wt_show_context_banner

# Validate main repo exists
if [[ ! -d "$WT_MAIN_REPO_ROOT" ]]; then
error "WT_MAIN_REPO_ROOT does not exist: $WT_MAIN_REPO_ROOT"
Expand Down
5 changes: 4 additions & 1 deletion bin/wt-metadata-export
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ if [[ ! -d "$TARGET_DIR" ]]; then
exit 1
fi

# Show context banner if contexts are configured
wt_show_context_banner

# Check if any patterns are configured
if [[ -z "${WT_METADATA_PATTERNS:-}" ]]; then
warn "No metadata patterns configured (WT_METADATA_PATTERNS is empty)"
Expand Down Expand Up @@ -180,7 +183,7 @@ find_all_metadata_dirs() {
[[ -z "$path" ]] && continue
local dominated=false

for kept in "${kept_paths[@]}"; do
for kept in ${kept_paths[@]+"${kept_paths[@]}"}; do
# Check if $path is inside $kept (kept is a prefix of path)
if [[ "$path" == "$kept/"* ]]; then
dominated=true
Expand Down
4 changes: 3 additions & 1 deletion bin/wt-metadata-import
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
# wt-metadata-import # Interactive: pick target worktree
# wt-metadata-import ~/dev/worktrees/feature-x # Import to specific worktree
# wt-metadata-import ~/dev/vault ~/dev/worktree # Explicit source and target
#

set -euo pipefail

Expand Down Expand Up @@ -137,6 +136,9 @@ esac
SOURCE_DIR="$(cd "$SOURCE_DIR" && pwd)"
TARGET_DIR="$(cd "$TARGET_DIR" && pwd)"

# Show context banner if contexts are configured
wt_show_context_banner

# Check if any patterns are configured
if [[ -z "${WT_METADATA_PATTERNS:-}" ]]; then
warn "No metadata patterns configured (WT_METADATA_PATTERNS is empty)"
Expand Down
3 changes: 3 additions & 0 deletions bin/wt-remove
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ while [[ $# -gt 0 ]]; do
esac
done

# Show context banner if contexts are configured
wt_show_context_banner

# Safety check: get absolute path of main repo
MAIN_REPO_ABS="$(cd "$WT_MAIN_REPO_ROOT" && pwd)"

Expand Down
3 changes: 3 additions & 0 deletions bin/wt-switch
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ if [[ $# -eq 1 ]]; then
esac
fi

# Show context banner if contexts are configured
wt_show_context_banner

# Resolve link path from config
LINK_PATH="$WT_ACTIVE_WORKTREE"
if [[ -d "$(dirname "$LINK_PATH")" ]]; then
Expand Down
44 changes: 44 additions & 0 deletions completion/wt.bash
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,49 @@ _wt_cd_complete() {
COMPREPLY+=( $(compgen -d -- "$cur") )
}

# --- Helper: get context list ---
_wt_context_list() {
local repos_dir="$HOME/.wt/repos"

[[ ! -d "$repos_dir" ]] && return 0

for conf in "$repos_dir"/*.conf; do
[[ -f "$conf" ]] || continue
local name="${conf##*/}"
name="${name%.conf}"
printf '%s\n' "$name"
done
}

# --- Completion for wt-context ---
_wt_context_complete() {
local cur prev cword
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cword=$COMP_CWORD

# First argument after wt-context
if [[ $cword -eq 1 ]]; then
# Options and subcommands
if [[ "$cur" == -* ]]; then
COMPREPLY+=( $(compgen -W "-l --list -h --help" -- "$cur") )
else
# Context names and 'add' subcommand
local contexts
contexts="$(_wt_context_list)"
COMPREPLY+=( $(compgen -W "add $contexts" -- "$cur") )
fi
return 0
fi

# After 'add' subcommand
if [[ "${COMP_WORDS[1]}" == "add" ]]; then
COMPREPLY+=( $(compgen -d -- "$cur") )
return 0
fi
}

# --- Completion for wt-metadata-export: directories ---
_wt_metadata_export_complete() {
local cur
Expand Down Expand Up @@ -306,5 +349,6 @@ type wt-add >/dev/null 2>&1 && complete -F _wt_add_complete wt-add
type wt-switch >/dev/null 2>&1 && complete -F _wt_switch_complete wt-switch
type wt-remove >/dev/null 2>&1 && complete -F _wt_remove_complete wt-remove
type wt-cd >/dev/null 2>&1 && complete -F _wt_cd_complete wt-cd
type wt-context >/dev/null 2>&1 && complete -F _wt_context_complete wt-context
type wt-metadata-export >/dev/null 2>&1 && complete -F _wt_metadata_export_complete wt-metadata-export
type wt-metadata-import >/dev/null 2>&1 && complete -F _wt_metadata_import_complete wt-metadata-import
Loading