mirror of
https://github.com/NVIDIA-NeMo/DataDesigner
synced 2026-05-24 09:48:29 +00:00
* feat: add preview, create, and validate CLI commands Add three new top-level CLI commands for the data-designer workflow: - `data-designer preview` - generate preview datasets for fast iteration - `data-designer create` - create full datasets and save to disk - `data-designer validate` - validate configuration files Also includes: - Move wait_for_navigation_key() UI primitive from preview.py to ui.py - Add KeyPressEvent type annotations to all key binding handlers in ui.py - Refactor cli/utils.py into cli/utils/ package with config_loader module - Comprehensive test coverage for all new commands * fix: update pythonjsonlogger import and clean up dev dependencies - Update pythonjsonlogger import to use newer JsonFormatter API - Consolidate dev-dependencies into [dependency-groups] dev section - Remove unnecessary test cli/utils __init__.py * small E * address greptile feedback * organize CLI commands into rich help panels Group top-level commands under "Generation" and "Setup" panels for clearer help output. * refactor config loader to parse files directly and auto-detect config format - Parse YAML/JSON files into dicts before passing to from_config, providing format-specific error messages for parse failures - Auto-detect DataDesignerConfig format (columns at top level) and wrap it into BuilderConfig so users can provide either format - Clean up Python module loading with try/except/finally for reliable sys.modules and sys.path cleanup - Add comprehensive tests for parsing, validation, and auto-wrapping * fix sys.path cleanup in config loader and simplify tests - Use pop(0) instead of remove() to precisely undo the insert(0, ...) and avoid accidentally removing a different matching path entry - Replace MagicMock with real DataDesignerConfigBuilder in tests * move config format auto-detection into from_config Centralize the shorthand DataDesignerConfig detection (columns at top level without a data_designer wrapper) in DataDesignerConfigBuilder.from_config so all callers benefit, not just the CLI config loader. Simplify config_loader to delegate file parsing and format normalization entirely to from_config. * extract GenerationController from CLI commands Move shared generation logic (preview, validate, create) out of the individual Typer command functions into a dedicated GenerationController, matching the existing controller pattern (DownloadController, etc.). The command functions now delegate to the controller, keeping them as thin entry points. Tests updated accordingly — command tests verify delegation while controller tests cover the full behavior. * harden sys.path cleanup and add explanatory comments Use sys.path.remove() instead of checking sys.path[0] so cleanup succeeds even when exec_module inserts entries at index 0. Drop unnecessary spec=DataDesignerConfigBuilder from test mocks. * check stdout TTY in preview interactive mode detection Previously only stdin was checked, so piping stdout (e.g. `dd preview cfg.yaml | head`) would still attempt interactive browsing. Now both stdin and stdout must be a TTY.
35 lines
1.4 KiB
Python
35 lines
1.4 KiB
Python
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from data_designer.cli.commands.validate import validate_command
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# validate_command delegation tests
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
@patch("data_designer.cli.commands.validate.GenerationController")
|
|
def test_validate_command_delegates_to_controller(mock_ctrl_cls: MagicMock) -> None:
|
|
"""Test validate_command delegates to GenerationController.run_validate."""
|
|
mock_ctrl = MagicMock()
|
|
mock_ctrl_cls.return_value = mock_ctrl
|
|
|
|
validate_command(config_source="config.yaml")
|
|
|
|
mock_ctrl_cls.assert_called_once()
|
|
mock_ctrl.run_validate.assert_called_once_with(config_source="config.yaml")
|
|
|
|
|
|
@patch("data_designer.cli.commands.validate.GenerationController")
|
|
def test_validate_command_passes_python_module_source(mock_ctrl_cls: MagicMock) -> None:
|
|
"""Test validate_command passes a .py source to the controller."""
|
|
mock_ctrl = MagicMock()
|
|
mock_ctrl_cls.return_value = mock_ctrl
|
|
|
|
validate_command(config_source="my_config.py")
|
|
|
|
mock_ctrl.run_validate.assert_called_once_with(config_source="my_config.py")
|