486 lines
15 KiB
Fish
486 lines
15 KiB
Fish
|
|
# Environment management system configuration
|
|
set -g __ENV_BASE_DIR "$HOME/.config/fish/environments"
|
|
set -g __ENV_CONFIGS_DIR "$__ENV_BASE_DIR/configs"
|
|
set -g __ENV_TEMPLATES_DIR "$__ENV_BASE_DIR/templates"
|
|
|
|
function env -d "Environment management system"
|
|
set -l subcommand $argv[1]
|
|
|
|
if test -z "$subcommand"
|
|
__env_help
|
|
return 0
|
|
end
|
|
|
|
switch $subcommand
|
|
case create new
|
|
__env_create $argv[2..]
|
|
case list ls
|
|
__env_list $argv[2..]
|
|
case activate use
|
|
__env_activate $argv[2..]
|
|
case deactivate exit
|
|
__env_deactivate $argv[2..]
|
|
case remove rm delete
|
|
__env_remove $argv[2..]
|
|
case link ln
|
|
__env_link $argv[2..]
|
|
case info show
|
|
__env_info $argv[2..]
|
|
case edit
|
|
__env_edit $argv[2..]
|
|
case copy clone
|
|
__env_copy $argv[2..]
|
|
case export
|
|
__env_export $argv[2..]
|
|
case help h --help -h
|
|
__env_help $argv[2..]
|
|
case "*"
|
|
echo (set_color red)"'$subcommand': Unknown subcommand (see env help)"(set_color normal)
|
|
return 1
|
|
end
|
|
end
|
|
|
|
# Internal functions (prefixed with __ to indicate they're private)
|
|
function __env_help -d "Show help for env command"
|
|
echo (set_color blue)"Environment Management System"(set_color normal)
|
|
echo
|
|
echo "usage: env <subcommand> [options]"
|
|
echo
|
|
echo (set_color green)"Subcommands:"(set_color normal)
|
|
echo " create, new <name> [template] Create a new environment"
|
|
echo " list, ls List all environments"
|
|
echo " activate, use <name> Activate an environment"
|
|
echo " deactivate, exit Deactivate current environment"
|
|
echo " remove, rm <name> Remove an environment"
|
|
echo " link, ln <name> [dir] Link environment to directory"
|
|
echo " info, show <name> Show environment information"
|
|
echo " edit <name> Edit environment configuration"
|
|
echo " copy, clone <src> <dest> Copy an environment"
|
|
echo " export <name> [dir] Export environment to directory"
|
|
echo " help, h Show this help"
|
|
echo
|
|
echo (set_color green)"Templates:"(set_color normal)
|
|
__env_list_templates
|
|
echo
|
|
echo (set_color green)"Examples:"(set_color normal)
|
|
echo " env create myproject python # Create Python environment"
|
|
echo " env activate myproject # Activate environment"
|
|
echo " env link myproject ./myapp # Link to directory"
|
|
echo " env export myproject ./myapp # Export self-contained env to directory"
|
|
echo " env list # Show all environments"
|
|
echo " env deactivate # Deactivate current environment"
|
|
end
|
|
|
|
function __env_create -d "Create a new environment"
|
|
set -l env_name $argv[1]
|
|
set -l template_type $argv[2]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env create <name> [template]"
|
|
echo "available templates:"
|
|
__env_list_templates
|
|
return 1
|
|
end
|
|
|
|
if test -z "$template_type"
|
|
set template_type basic
|
|
end
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
set -l template_file "$__ENV_TEMPLATES_DIR/$template_type.fish"
|
|
|
|
if test -d "$env_dir"
|
|
echo (set_color yellow)"'$env_name': environment already exists"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
if not test -f "$template_file"
|
|
echo (set_color red)"'$template_type': template not found"(set_color normal)
|
|
echo "Available templates:"
|
|
__env_list_templates
|
|
return 1
|
|
end
|
|
|
|
# Create environment directory
|
|
mkdir -p "$env_dir"
|
|
|
|
# Copy template and customize
|
|
sed "s/{{ENV_NAME}}/$env_name/g" "$template_file" >"$env_dir/activate.fish"
|
|
chmod +x "$env_dir/activate.fish"
|
|
|
|
# Create environment config file
|
|
echo "# Environment: $env_name" >"$env_dir/config.toml"
|
|
echo "name = \"$env_name\"" >>"$env_dir/config.toml"
|
|
echo "template = \"$template_type\"" >>"$env_dir/config.toml"
|
|
echo "created = \"$(date --iso-8601)\"" >>"$env_dir/config.toml"
|
|
echo "# Add custom environment variables here" >>"$env_dir/config.toml"
|
|
echo "# [env]" >>"$env_dir/config.toml"
|
|
echo "# CUSTOM_VAR = \"value\"" >>"$env_dir/config.toml"
|
|
|
|
echo (set_color green)"environment '$env_name' ($template_type) created"(set_color normal)
|
|
echo "environment directory: $env_dir"
|
|
echo "to activate: env activate $env_name"
|
|
end
|
|
|
|
function __env_list -d "List all available environments"
|
|
set -l env_dir "$__ENV_CONFIGS_DIR"
|
|
|
|
if not test -d "$env_dir"
|
|
echo (set_color yellow)"no environments found"(set_color normal)
|
|
return 0
|
|
end
|
|
|
|
# Check if directory exists but is empty
|
|
set -l env_count (count $env_dir/*)
|
|
if test $env_count -eq 0
|
|
echo (set_color yellow)"no environments found"(set_color normal)
|
|
return 0
|
|
end
|
|
|
|
echo (set_color blue)"available environments:"(set_color normal)
|
|
echo
|
|
|
|
for env_path in $env_dir/*
|
|
if test -d "$env_path"
|
|
set env_name (basename "$env_path")
|
|
set config_file "$env_path/config.toml"
|
|
|
|
if test -f "$config_file"
|
|
set template (grep "template =" "$config_file" | cut -d'"' -f2)
|
|
set created (grep "created =" "$config_file" | cut -d'"' -f2)
|
|
echo (set_color green)" $env_name"(set_color normal)" (template: $template, created: $created)"
|
|
else
|
|
echo (set_color green)" $env_name"(set_color normal)" (no config found)"
|
|
end
|
|
end
|
|
end
|
|
|
|
if test -n "$CURRENT_ENV"
|
|
echo
|
|
echo (set_color cyan)"'$CURRENT_ENV': currently active"(set_color normal)
|
|
end
|
|
end
|
|
|
|
function __env_activate -d "Activate an environment"
|
|
set -l env_name $argv[1]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env activate <name>"
|
|
echo "available environments:"
|
|
__env_list
|
|
return 1
|
|
end
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
set -l activate_file "$env_dir/activate.fish"
|
|
|
|
if not test -f "$activate_file"
|
|
echo (set_color red)"'$env_name': environment not found"(set_color normal)
|
|
echo "available environments:"
|
|
__env_list
|
|
return 1
|
|
end
|
|
|
|
# Check if another environment is already active
|
|
if test -n "$CURRENT_ENV"
|
|
echo (set_color yellow)"'$CURRENT_ENV': deactivating current environment"(set_color normal)
|
|
__env_deactivate
|
|
end
|
|
|
|
echo (set_color green)"'$env_name': activating environment"(set_color normal)
|
|
source "$activate_file"
|
|
end
|
|
|
|
function __env_deactivate -d "Deactivate the current environment"
|
|
if test -z "$CURRENT_ENV"
|
|
echo (set_color yellow)"no environment currently active"(set_color normal)
|
|
return 0
|
|
end
|
|
|
|
echo (set_color blue)"'$CURRENT_ENV': deactivating environment"(set_color normal)
|
|
|
|
# Restore original prompt if it was saved
|
|
if functions -q __env_orig_prompt
|
|
# Remove current fish_prompt first, then restore the original
|
|
functions -e fish_prompt
|
|
functions -c __env_orig_prompt fish_prompt
|
|
functions -e __env_orig_prompt
|
|
end
|
|
|
|
# Clear environment-specific variables
|
|
set -e CURRENT_ENV
|
|
set -e __ENV_INITIALIZED
|
|
|
|
# Call custom deactivation function if it exists
|
|
if functions -q __env_custom_deactivate
|
|
__env_custom_deactivate
|
|
functions -e __env_custom_deactivate
|
|
end
|
|
|
|
echo (set_color green)"environment deactivated"(set_color normal)
|
|
end
|
|
|
|
function __env_remove -d "Remove an environment"
|
|
set -l env_name $argv[1]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env remove <name>"
|
|
return 1
|
|
end
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
|
|
if not test -d "$env_dir"
|
|
echo (set_color red)"'$env_name': environment not found"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
# Check if this environment is currently active
|
|
if test "$CURRENT_ENV" = "$env_name"
|
|
echo (set_color yellow)"deactivating environment before removal..."(set_color normal)
|
|
__env_deactivate
|
|
end
|
|
|
|
# Confirm removal
|
|
echo (set_color yellow)"are you sure you want to remove environment '$env_name'? [y/N]"(set_color normal)
|
|
read -l confirm
|
|
|
|
if test "$confirm" = y -o "$confirm" = Y
|
|
rm -rf "$env_dir"
|
|
echo (set_color green)"Environment '$env_name' removed"(set_color normal)
|
|
else
|
|
echo (set_color blue)"Removal cancelled"(set_color normal)
|
|
end
|
|
end
|
|
|
|
function __env_link -d "Link current directory to an environment"
|
|
set -l env_name $argv[1]
|
|
set -l target_dir $argv[2]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env link <env_name> [target_directory]"
|
|
return 1
|
|
end
|
|
|
|
if test -z "$target_dir"
|
|
set target_dir (pwd)
|
|
end
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
set -l activate_file "$env_dir/activate.fish"
|
|
|
|
if not test -f "$activate_file"
|
|
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
set -l target_activate "$target_dir/activate.fish"
|
|
|
|
if test -f "$target_activate"
|
|
echo (set_color yellow)"Warning: activate.fish already exists in $target_dir"(set_color normal)
|
|
echo "Overwrite? [y/N]"
|
|
read -l confirm
|
|
if test "$confirm" != y -a "$confirm" != Y
|
|
echo (set_color blue)"Link cancelled"(set_color normal)
|
|
return 0
|
|
end
|
|
end
|
|
|
|
ln -sf "$activate_file" "$target_activate"
|
|
echo (set_color green)"Linked environment '$env_name' to $target_dir"(set_color normal)
|
|
echo "The environment will be activated automatically when you cd into this directory"
|
|
end
|
|
|
|
function __env_info -d "Show environment information"
|
|
set -l env_name $argv[1]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env info <name>"
|
|
return 1
|
|
end
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
set -l config_file "$env_dir/config.toml"
|
|
|
|
if not test -f "$config_file"
|
|
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
echo (set_color blue)"Environment: $env_name"(set_color normal)
|
|
echo "Config file: $config_file"
|
|
echo
|
|
cat "$config_file"
|
|
end
|
|
|
|
function __env_edit -d "Edit environment configuration"
|
|
set -l env_name $argv[1]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env edit <name>"
|
|
return 1
|
|
end
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
set -l activate_file "$env_dir/activate.fish"
|
|
|
|
if not test -f "$activate_file"
|
|
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
$EDITOR "$activate_file"
|
|
end
|
|
|
|
function __env_copy -d "Copy an environment"
|
|
set -l src_name $argv[1]
|
|
set -l dest_name $argv[2]
|
|
|
|
if test -z "$src_name" -o -z "$dest_name"
|
|
echo (set_color red)"Error: Source and destination names required"(set_color normal)
|
|
echo "usage: env copy <source> <destination>"
|
|
return 1
|
|
end
|
|
|
|
set -l src_dir "$__ENV_CONFIGS_DIR/$src_name"
|
|
set -l dest_dir "$__ENV_CONFIGS_DIR/$dest_name"
|
|
|
|
if not test -d "$src_dir"
|
|
echo (set_color red)"Error: Source environment '$src_name' not found"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
if test -d "$dest_dir"
|
|
echo (set_color yellow)"Warning: Destination environment '$dest_name' already exists"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
# Copy the entire environment directory
|
|
cp -r "$src_dir" "$dest_dir"
|
|
|
|
# Update the activate.fish file to use the new name
|
|
sed -i "s/$src_name/$dest_name/g" "$dest_dir/activate.fish"
|
|
|
|
# Update the config file
|
|
sed -i "s/name = \"$src_name\"/name = \"$dest_name\"/" "$dest_dir/config.toml"
|
|
sed -i "s/# Environment: $src_name/# Environment: $dest_name/" "$dest_dir/config.toml"
|
|
echo "copied_from = \"$src_name\"" >>"$dest_dir/config.toml"
|
|
echo "copied_date = \"$(date --iso-8601)\"" >>"$dest_dir/config.toml"
|
|
|
|
echo (set_color green)"Copied environment '$src_name' to '$dest_name'"(set_color normal)
|
|
end
|
|
|
|
function __env_export -d "Export environment to a self-contained directory"
|
|
set -l env_name $argv[1]
|
|
set -l target_dir $argv[2]
|
|
|
|
if test -z "$env_name"
|
|
echo (set_color red)"environment name required"(set_color normal)
|
|
echo "usage: env export <name> [target_directory]"
|
|
return 1
|
|
end
|
|
|
|
if test -z "$target_dir"
|
|
set target_dir (pwd)
|
|
end
|
|
|
|
# Convert relative path to absolute path
|
|
set target_dir (realpath "$target_dir")
|
|
|
|
set -l env_dir "$__ENV_CONFIGS_DIR/$env_name"
|
|
set -l activate_source "$env_dir/activate.fish"
|
|
|
|
if not test -f "$activate_source"
|
|
echo (set_color red)"environment '$env_name' not found"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
if not test -d "$target_dir"
|
|
echo (set_color red)"Error: Target directory '$target_dir' does not exist"(set_color normal)
|
|
return 1
|
|
end
|
|
|
|
set -l fish_dir "$target_dir/.fish"
|
|
set -l target_activate "$fish_dir/activate.fish"
|
|
set -l target_readme "$fish_dir/README.md"
|
|
|
|
# Create .fish directory
|
|
if not test -d "$fish_dir"
|
|
mkdir -p "$fish_dir"
|
|
end
|
|
|
|
if test -f "$target_activate"
|
|
echo (set_color yellow)"Warning: .fish/activate.fish already exists in $target_dir"(set_color normal)
|
|
echo "Overwrite? [y/N]"
|
|
read -l confirm
|
|
if test "$confirm" != y -a "$confirm" != Y
|
|
echo (set_color blue)"Export cancelled"(set_color normal)
|
|
return 0
|
|
end
|
|
end
|
|
|
|
# Create a self-contained activate.fish in .fish directory
|
|
echo "# Self-contained environment: $env_name" >"$target_activate"
|
|
echo "# Exported on: $(date)" >>"$target_activate"
|
|
echo "# Original environment from: $env_dir" >>"$target_activate"
|
|
echo "" >>"$target_activate"
|
|
|
|
# Copy the original activate.fish content but make it self-contained
|
|
cat "$activate_source" | sed 's/{{ENV_NAME}}/'"$env_name"'/g' >>"$target_activate"
|
|
|
|
# Make it executable
|
|
chmod +x "$target_activate"
|
|
|
|
# Create a README from template
|
|
set -l readme_template "$__ENV_TEMPLATES_DIR/README.md"
|
|
if test -f "$readme_template"
|
|
sed "s/{{ENV_NAME}}/$env_name/g" "$readme_template" >"$target_readme"
|
|
else
|
|
echo "# Exported Fish Environment: $env_name" >"$target_readme"
|
|
echo "" >>"$target_readme"
|
|
echo "README template not found. Please create $readme_template for custom documentation." >>"$target_readme"
|
|
end
|
|
|
|
echo (set_color green)"Environment '$env_name' exported to: $target_dir"(set_color normal)
|
|
echo (set_color blue)"Files created:"(set_color normal)
|
|
echo " - $target_activate (main environment)"
|
|
echo " - $target_readme (documentation)"
|
|
echo
|
|
echo (set_color cyan)"To use this environment:"(set_color normal)
|
|
echo " cd $target_dir"
|
|
echo " source ./.fish/activate.fish"
|
|
end
|
|
|
|
function __env_list_templates -d "List available templates with descriptions"
|
|
set -l template_dir "$__ENV_TEMPLATES_DIR"
|
|
|
|
if not test -d "$template_dir"
|
|
echo " (no templates found)"
|
|
return 0
|
|
end
|
|
|
|
for template_file in "$template_dir"/*.fish
|
|
if test -f "$template_file"
|
|
set template_name (basename "$template_file" .fish)
|
|
|
|
# Extract description from first comment line (skip shebang if present)
|
|
set description "No description"
|
|
set first_comment_line (head -n 5 "$template_file" | grep -E "^#[^!]" | head -n 1 | sed 's/^# *//')
|
|
|
|
if test -n "$first_comment_line"
|
|
set description "$first_comment_line"
|
|
end
|
|
|
|
# Format with proper alignment
|
|
printf " %-12s %s\n" "$template_name" "$description"
|
|
end
|
|
end
|
|
end
|