CLI: Small fixups for implicit envvars (#1014)

We should only inherit from the host if there's no =. Additionally
document the flag a little more to show that we can inherit from the
host.
This commit is contained in:
Danny Canter
2026-01-04 10:51:20 -08:00
committed by GitHub
parent df368b790e
commit 020949ea2b
3 changed files with 51 additions and 6 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors.
// Copyright © 2025-2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -29,7 +29,7 @@ public struct Flags {
public struct Process: ParsableArguments {
public init() {}
@Option(name: .shortAndLong, help: "Set environment variables (format: key=value)")
@Option(name: .shortAndLong, help: "Set environment variables (key=value, or just key to inherit from host)")
public var env: [String] = []
@Option(
+4 -3
View File
@@ -1,5 +1,5 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors.
// Copyright © 2025-2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -192,8 +192,9 @@ public struct Parser {
var envVar: [String] = []
for env in envList {
var env = env
let parts = env.split(separator: "=", maxSplits: 2)
if parts.count == 1 {
// Only inherit from host if no "=" is present (e.g., "--env VAR")
// "VAR=" should set an explicit empty value, not inherit.
if !env.contains("=") {
guard let val = ProcessInfo.processInfo.environment[env] else {
continue
}
+45 -1
View File
@@ -1,5 +1,5 @@
//===----------------------------------------------------------------------===//
// Copyright © 2025 Apple Inc. and the container project authors.
// Copyright © 2025-2026 Apple Inc. and the container project authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -423,6 +423,50 @@ struct ParserTest {
}
}
// MARK: - Environment Variable Tests
@Test
func testEnvExplicitValue() throws {
let result = Parser.env(envList: ["FOO=bar", "BAZ=qux"])
#expect(result == ["FOO=bar", "BAZ=qux"])
}
@Test
func testEnvImplicitInheritance() throws {
guard let homeValue = ProcessInfo.processInfo.environment["PATH"] else {
Issue.record("PATH environment variable not set")
return
}
let result = Parser.env(envList: ["PATH"])
#expect(result == ["PATH=\(homeValue)"])
}
@Test
func testEnvImplicitUndefinedVariable() throws {
// A variable that doesn't exist should be silently skipped
let result = Parser.env(envList: ["THIS_VAR_DEFINITELY_DOES_NOT_EXIST_12345"])
#expect(result.isEmpty)
}
@Test
func testEnvMixedExplicitAndImplicit() throws {
guard let homeValue = ProcessInfo.processInfo.environment["HOME"] else {
Issue.record("HOME environment variable not set")
return
}
let result = Parser.env(envList: ["FOO=bar", "HOME", "BAZ=qux"])
#expect(result == ["FOO=bar", "HOME=\(homeValue)", "BAZ=qux"])
}
@Test
func testEnvEmptyValue() throws {
// Explicit empty value should be preserved
let result = Parser.env(envList: ["EMPTY="])
#expect(result == ["EMPTY="])
}
private func tmpFileWithContent(_ content: String) throws -> URL {
let tempDir = FileManager.default.temporaryDirectory
let tempFile = tempDir.appendingPathComponent("envfile-test-\(UUID().uuidString)")