Skip to content

feat: implement set -a (allexport) #793

@chaliy

Description

@chaliy

Problem

set -a (allexport) is parsed and the flag SHOPT_a is stored, but the behavior is not implemented:

  1. option_name_to_var() in builtins/vars.rs:37-48 does not map "allexport", so set -o allexport is silently ignored
  2. Nothing checks SHOPT_a during variable assignment — new/modified variables are never auto-exported

This is used by frameworks like wedow/harness to load session environment files:

set -a
source "${HARNESS_SESSION}/.env"
set +a

Expected behavior

When set -a is active, every variable assignment (via =, read, for loop variable, etc.) should also mark the variable as exported. set +a disables this. set -o allexport and set +o allexport should work as aliases.

Test cases

Basic allexport

set -a
FOO="bar"
BAZ="qux"
set +a

AFTER="not-exported"

# Check export status
env_output="$(env)"
echo "${env_output}" | grep -c "^FOO=bar$"
echo "${env_output}" | grep -c "^BAZ=qux$"
echo "${env_output}" | grep -c "^AFTER="
# Expected stdout:
#   1
#   1
#   0

allexport with source

cat > /tmp/vars.env <<'EOF'
DB_HOST=localhost
DB_PORT=5432
EOF

set -a
source /tmp/vars.env
set +a

cat > /tmp/check-env.sh <<'SCRIPT'
#!/usr/bin/env bash
echo "host=${DB_HOST:-unset}"
echo "port=${DB_PORT:-unset}"
SCRIPT
chmod +x /tmp/check-env.sh

/tmp/check-env.sh
# Expected stdout:
#   host=localhost
#   port=5432

set -o allexport / set +o allexport

set -o allexport
X="hello"
set +o allexport
Y="world"

export -p | grep -c "declare -x X="
export -p | grep -c "declare -x Y="
# Expected stdout:
#   1
#   0

Short flag in combined options

set -eau
MY_VAR="test"
set +a

export -p | grep -c "declare -x MY_VAR="
# Expected stdout: 1

allexport applies to read builtin

set -a
echo "value" | read -r MY_READ_VAR
set +a

# MY_READ_VAR should be exported
export -p | grep "MY_READ_VAR" | head -1
# Expected stdout: declare -x MY_READ_VAR="value"

allexport applies to for loop variable

set -a
for item in alpha beta; do
  : # item should be exported on each iteration
done
set +a

export -p | grep -c "declare -x item="
# Expected stdout: 1

Variables assigned before set -a are not retroactively exported

BEFORE="exists"
set -a
DURING="new"
set +a

export -p | grep -c "declare -x BEFORE="
export -p | grep -c "declare -x DURING="
# Expected stdout:
#   0
#   1

Implementation hint

  1. Add "allexport" => Some("SHOPT_a") to option_name_to_var() in builtins/vars.rs
  2. Add "allexport" entry to SET_O_OPTIONS array for display
  3. In variable assignment paths, check if SHOPT_a is "1" and if so, also insert into self.env (the export set)
    • Key locations: process_command_assignments, execute_local_builtin, for loop variable assignment, read builtin side effects

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions