summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlcan <[email protected]>2025-05-02 12:04:22 -0700
committerGitHub <[email protected]>2025-05-02 12:04:22 -0700
commitf237082c37a10db1bf9d7daddf039bf4e002ec61 (patch)
tree6a6cd58a8f77226dae77943bc2c41e74a0a2fbd8
parentb9da7290e1cafca8fb197b8412843c91d0ce9f1f (diff)
pass PATH and PYTHONPATH into sandbox, let sandbox scripts recognize user settings for sandbox (#247)
-rw-r--r--packages/cli/src/utils/sandbox.ts39
-rwxr-xr-xscripts/sandbox_command.sh10
2 files changed, 47 insertions, 2 deletions
diff --git a/packages/cli/src/utils/sandbox.ts b/packages/cli/src/utils/sandbox.ts
index 40fca09c..85cf6c1a 100644
--- a/packages/cli/src/utils/sandbox.ts
+++ b/packages/cli/src/utils/sandbox.ts
@@ -103,7 +103,7 @@ export async function start_sandbox(sandbox: string) {
// run init binary inside container to forward signals & reap zombies
const args = ['run', '-it', '--rm', '--init', '--workdir', workdir];
- // mount current directory as ${workdir} inside container
+ // mount current directory as working directory in sandbox (set via --workdir)
args.push('--volume', `${process.cwd()}:${workdir}`);
// mount user settings directory inside container, after creating if missing
@@ -195,6 +195,32 @@ export async function start_sandbox(sandbox: string) {
args.push('--env', `COLORTERM=${process.env.COLORTERM}`);
}
+ // copy any paths in PATH that are under working directory in sandbox
+ // note we can't just pass these as --env since that would override base PATH
+ // instead we construct a suffix and append as part of bashCmd below
+ let pathSuffix = '';
+ if (process.env.PATH) {
+ const paths = process.env.PATH.split(':');
+ for (const path of paths) {
+ if (path.startsWith(workdir)) {
+ pathSuffix += `:${path}`;
+ }
+ }
+ }
+
+ // copy any paths in PYTHONPATH that are under working directory in sandbox
+ // note we can't just pass these as --env since that would override base PYTHONPATH
+ // instead we construct a suffix and append as part of bashCmd below
+ let pythonPathSuffix = '';
+ if (process.env.PYTHONPATH) {
+ const paths = process.env.PYTHONPATH.split(':');
+ for (const path of paths) {
+ if (path.startsWith(workdir)) {
+ pythonPathSuffix += `:${path}`;
+ }
+ }
+ }
+
// copy additional environment variables from SANDBOX_ENV
if (process.env.SANDBOX_ENV) {
for (let env of process.env.SANDBOX_ENV.split(',')) {
@@ -230,9 +256,18 @@ export async function start_sandbox(sandbox: string) {
nodeArgs.push(`--inspect-brk=0.0.0.0:${debugPort}`);
}
+ // set up bash command to be run inside container
+ // start with setting up PATH and PYTHONPATH with optional suffixes from host
+ let bashCmd = '';
+ if (pathSuffix) {
+ bashCmd += `export PATH="$PATH${pathSuffix}"; `; // suffix includes leading ':'
+ }
+ if (pythonPathSuffix) {
+ bashCmd += `export PYTHONPATH="$PYTHONPATH${pythonPathSuffix}"; `; // suffix includes leading ':'
+ }
+
// open additional ports if SANDBOX_PORTS is set
// also set up redirects (via socat) so servers can listen on localhost instead of 0.0.0.0
- let bashCmd = '';
if (process.env.SANDBOX_PORTS) {
for (let port of process.env.SANDBOX_PORTS.split(',')) {
if ((port = port.trim())) {
diff --git a/scripts/sandbox_command.sh b/scripts/sandbox_command.sh
index fab94b52..f527292c 100755
--- a/scripts/sandbox_command.sh
+++ b/scripts/sandbox_command.sh
@@ -31,6 +31,16 @@ while getopts ":q" opt; do
done
shift $((OPTIND - 1))
+# if GEMINI_CODE_SANDBOX is not set, see if it is set in user settings
+# note it can be string or boolean, and if missing jq will return null
+USER_SETTINGS_FILE=~/.gemini/settings.json
+if [ -z "${GEMINI_CODE_SANDBOX:-}" ] && [ -f "$USER_SETTINGS_FILE" ]; then
+ USER_SANDBOX_SETTING=$(jq -r '.sandbox' "$USER_SETTINGS_FILE")
+ if [ "$USER_SANDBOX_SETTING" != null ]; then
+ GEMINI_CODE_SANDBOX=$USER_SANDBOX_SETTING
+ fi
+fi
+
# if GEMINI_CODE_SANDBOX is not set, try to source .env in case set there
# allow .env to be in any ancestor directory (same as findEnvFile in config.ts)
if [ -z "${GEMINI_CODE_SANDBOX:-}" ]; then