Skip to content

Commit 1a76f6a

Browse files
fcourtialnfcampos
andauthored
🐛 [CLI] Generate one --build-context argument for each dependency in the docker build command. (langchain-ai#4962)
* Generate one `--build-context` for each dependency in the `docker build` command. * Try and fix test --------- Co-authored-by: Nuno Campos <nuno@langchain.dev>
1 parent aedf974 commit 1a76f6a

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

libs/cli/langgraph_cli/cli.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,8 @@ def _build(
318318
)
319319
# add additional_contexts
320320
if additional_contexts:
321-
additional_contexts_str = ",".join(
322-
f"{k}={v}" for k, v in additional_contexts.items()
323-
)
324-
args.extend(["--build-context", additional_contexts_str])
321+
for k, v in additional_contexts.items():
322+
args.extend(["--build-context", f"{k}={v}"])
325323
# run docker build
326324
runner.run(
327325
subp_exec(

libs/cli/tests/unit_tests/cli/test_cli.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222

2323

2424
@contextmanager
25-
def temporary_config_folder(config_content: dict):
25+
def temporary_config_folder(config_content: dict, levels: int = 0):
2626
# Create a temporary directory
2727
temp_dir = tempfile.mkdtemp()
2828
try:
2929
# Define the path for the config.json file
30-
config_path = Path(temp_dir) / "config.json"
30+
config_path = Path(temp_dir) / f"{'a/' * levels}config.json"
31+
# Ensure the parent directory exists
32+
config_path.parent.mkdir(parents=True, exist_ok=True)
3133

3234
# Write the provided dictionary content to config.json
3335
with open(config_path, "w", encoding="utf-8") as config_file:
@@ -532,3 +534,38 @@ def test_build_command_shows_wolfi_warning() -> None:
532534
assert "Wolfi Linux" in result.output
533535
assert "image_distro" in result.output
534536
assert "wolfi" in result.output
537+
538+
539+
def test_build_generate_proper_build_context():
540+
runner = CliRunner()
541+
config_content = {
542+
"python_version": "3.11",
543+
"graphs": {"agent": "agent.py:graph"},
544+
"dependencies": [".", "../../..", "../.."],
545+
"image_distro": "wolfi",
546+
}
547+
548+
with temporary_config_folder(config_content, levels=3) as temp_dir:
549+
agent_path = temp_dir / "agent.py"
550+
agent_path.touch()
551+
552+
# Mock docker command since we don't want to actually build
553+
with runner.isolated_filesystem():
554+
result = runner.invoke(
555+
cli,
556+
[
557+
"build",
558+
"--tag",
559+
"test-image",
560+
"--config",
561+
str(temp_dir / "config.json"),
562+
],
563+
catch_exceptions=True,
564+
)
565+
566+
build_context_pattern = re.compile(r"--build-context\s+(\w+)=([^\s]+)")
567+
568+
build_contexts = re.findall(build_context_pattern, result.output)
569+
assert (
570+
len(build_contexts) == 2
571+
), f"Expected 2 build contexts, but found {len(build_contexts)}"

0 commit comments

Comments
 (0)