Skip to content

feat(sdm-cli): add new args --manifest-path and --components-path to SDM CLI#556

Merged
Christo Grabowski (ChristoGrab) merged 13 commits intomainfrom
christo/sdm-cli-manifest-path
May 19, 2025
Merged

feat(sdm-cli): add new args --manifest-path and --components-path to SDM CLI#556
Christo Grabowski (ChristoGrab) merged 13 commits intomainfrom
christo/sdm-cli-manifest-path

Conversation

@ChristoGrab
Copy link
Copy Markdown
Collaborator

@ChristoGrab Christo Grabowski (ChristoGrab) commented May 19, 2025

What

Adds two new optional args to the source-declarative-manifest CLI tool:

  1. --manifest-path: expects a string representing the relative path to a local manifest to inject
  2. --components-path: expects a string representing the relative path to a source's custom components module

This allows a user to pass a valid remote (local from a dev perspective) manifest file to be serialized and injected into the provided config when running check, discover and read, as well as dynamically load any custom components from the designated components file.

Both arguments are optional and only have an effect when a local YAML source is not detected by the CLI (ie, not a built connector image)

Note on spec

Spec is handled slightly differently than the other interfaces, and is currently hard-coded to spit out the SDM spec when run outside of a built image. I intend to add --manifest-path to the spec command as well in a follow up PR.

Issue to add this is here: https://github.com/airbytehq/airbyte-internal-issues/issues/13052

For now, this update allows devs to test check, discover and read interfaces on manifest-only connectors locally.

How to test

From the root of the airbyte-python-cdk repo:

python -m venv .venv
source .venv/bin/activate
pip install -e .

You can now pass the arguments in SDM commands, ie:

# Run check against a remote manifest
source-declarative-manifest check --config path/to/config.json --manifest-path path/to/manifest.yaml

# Run read against a remote manifest with components
source-declarative-manifest read --config path/to/config.json --catalog path/to/catalog.json --manifest-path path/to/manifest.yaml --components-path path/to/components.py

Summary by CodeRabbit

  • New Features
    • Added support for injecting an external declarative manifest and custom Python components via new CLI arguments (--manifest-path and --components-path) for relevant commands.
  • Bug Fixes
    • Improved error reporting when loading and validating external manifest files.
  • Tests
    • Added and updated tests to verify manifest and component file loading, as well as argument parsing for new CLI options.
  • Refactor
    • Updated configuration handling to use mutable mappings for improved flexibility.

@github-actions github-actions bot added the enhancement New feature or request label May 19, 2025
@ChristoGrab Christo Grabowski (ChristoGrab) marked this pull request as ready for review May 19, 2025 18:19
Copilot AI review requested due to automatic review settings May 19, 2025 18:19
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds two optional arguments (--manifest-path and --components-path) to the SDM CLI tool to support remote manifest injection and loading of custom components. Key changes include:

  • Updates to the argument parser and tests to handle the new CLI options.
  • Enhancements in the source creation logic to inject the manifest and register components.
  • Minor type-hint adjustments in the connector-related modules.

Reviewed Changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
unit_tests/test_entrypoint.py Updated tests to validate new CLI arguments.
unit_tests/source_declarative_manifest/test_source_declarative_w_custom_components.py Added tests for registering custom components from file.
unit_tests/source_declarative_manifest/test_source_declarative_remote_manifest.py Added tests for parsing a manifest file.
unit_tests/source_declarative_manifest/conftest.py Introduced helper functions for component verification and temporary file management.
airbyte_cdk/entrypoint.py Updated argument parsers to include new optional arguments.
airbyte_cdk/connector.py Modified type hints for improved clarity.
airbyte_cdk/cli/source_declarative_manifest/_run.py Integrated new argument handling and adjusted parsing/injection logic for manifests and components.

Comment thread airbyte_cdk/cli/source_declarative_manifest/_run.py Outdated
Comment thread airbyte_cdk/cli/source_declarative_manifest/_run.py
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented May 19, 2025

📝 Walkthrough

Walkthrough

The changes introduce support for injecting external declarative manifests and Python component files into the Airbyte CLI via new --manifest-path and --components-path arguments. Argument parsing is refactored for consistency, and type hints are updated to require mutable mappings for configurations. Additional helpers and tests are added for manifest and component file loading.

Changes

File(s) Change Summary
airbyte_cdk/cli/source_declarative_manifest/_run.py Refactored argument parsing to use AirbyteEntrypoint.parse_args. Added support for --manifest-path and --components-path CLI arguments. Implemented helpers for loading YAML manifests and Python components from files. Updated config type hints to MutableMapping. Enhanced error handling for manifest validation.
airbyte_cdk/entrypoint.py Added --manifest-path and --components-path as optional arguments to the check, discover, and read subcommands in the CLI argument parser.
airbyte_cdk/connector.py Changed read_config method's return type and runtime check from Mapping to MutableMapping in BaseConnector. Updated imports accordingly.
unit_tests/source_declarative_manifest/conftest.py Introduced sample Python components as a string, a helper to verify dynamic component loading, and a pytest fixture to create and clean up temporary component files for tests.
unit_tests/source_declarative_manifest/test_source_declarative_remote_manifest.py Added a test for _parse_manifest_from_file, mocking file reading to validate manifest loading logic.
unit_tests/source_declarative_manifest/test_source_declarative_w_custom_components.py Updated to import shared test utilities for components. Added a test for _register_components_from_file using the new fixture and verification helper.
unit_tests/test_entrypoint.py Extended tests to check for presence and correct default values of new CLI arguments. Added parameterized tests to verify correct parsing of the new arguments when provided.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant _run.py
    participant ManifestLoader
    participant ComponentsLoader

    User->>CLI: airbyte check/discover/read --manifest-path X --components-path Y
    CLI->>_run.py: parse_args()
    _run.py->>ManifestLoader: _parse_manifest_from_file(X)
    ManifestLoader-->>_run.py: Manifest dict
    _run.py->>ComponentsLoader: _register_components_from_file(Y)
    ComponentsLoader-->>_run.py: Components registered
    _run.py->>_run.py: Insert manifest into config
    _run.py->>_run.py: Continue with processing (e.g., create source)
Loading

Would you like me to help draft some additional tests for edge cases in manifest loading or component registration, wdyt?

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between a0abfe7 and ae6d955.

📒 Files selected for processing (1)
  • airbyte_cdk/cli/source_declarative_manifest/_run.py (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Check: 'source-amplitude' (skip=false)
  • GitHub Check: Check: 'source-pokeapi' (skip=false)
  • GitHub Check: Check: 'source-shopify' (skip=false)
  • GitHub Check: Check: 'source-hardcoded-records' (skip=false)
  • GitHub Check: SDM Docker Image Build
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (Fast)
  • GitHub Check: Analyze (python)
🔇 Additional comments (10)
airbyte_cdk/cli/source_declarative_manifest/_run.py (10)

19-30: Import adjustments look good.

The updated imports properly support the new functionality for external manifest files (yaml) and more precise type hints (MutableMapping). The addition of argparse aligns with the more structured command-line argument handling.


59-59: Good type hint adjustment to MutableMapping.

This change is necessary since the config dictionary will be modified when injecting the manifest, especially at line 185. The immutable Mapping wouldn't allow this operation.


96-97: Improved argument parsing approach.

Using AirbyteEntrypoint.parse_args provides more consistent argument handling across the codebase. This aligns with how arguments are processed elsewhere.


168-179: Better type hints and early validation.

The improved config validation with clear error messages will help users understand what's missing when they encounter issues. I particularly like the explicit mention of the --manifest-path alternative in the error message.


181-186: New manifest path injection logic.

This is a clean implementation of the external manifest file support, checking for the argument's existence before attempting to load and inject the manifest.

Is there value in providing more specific error feedback if injected_manifest is None after parsing, rather than falling through to the more generic "manifest missing" error? Or is the current behavior intentional to maintain simplicity? wdyt?


187-192: Updated error message for missing manifest.

Good enhancement to the error message to indicate that the manifest can also be provided via the --manifest-path argument. This makes the CLI interface more user-friendly.


199-201: Components loading feature.

Nice addition to dynamically load custom components from an external file. This will be very useful for development and testing custom components without rebuilding connector images.


229-233: Updated parameter and return type annotations.

The change from raw args to parsed args and the update to MutableMapping return type provide stronger type safety and better align with how the config is actually used.


255-267: Well-structured manifest parsing function.

The manifest parsing implementation includes:

  • Proper file encoding specification
  • YAML safe loading to prevent code execution vulnerabilities
  • Validation that the manifest is not empty or invalid
  • Clear error messages with context about what went wrong

This is a well-structured helper function with appropriate error handling.


269-291: Dynamic component registration looks good.

The implementation handles the module loading process well, particularly:

  • Using Python's import machinery to properly load the module
  • Registering the module under two names to avoid dataclass resolution issues
  • Validating the module spec and loader before proceeding

Have you considered any potential security implications of dynamically loading Python code from user-provided files? Are there any validation or sandboxing measures that might be worth adding in production environments? wdyt?

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (7)
unit_tests/test_entrypoint.py (2)

120-145: Looks good – but would an explicit assertion on the new CLI defaults make the intent clearer?

The new components_path and manifest_path keys are included in expected_args with None values, which is great.
Would you consider adding an explicit assertion that these keys are absent from the generated CLI string (because _as_arglist skips falsy values) to document that we rely on the parser defaults rather than on the presence of the flags, wdyt?


187-234: Patching the class method may hide real-world regressions – could we exercise the real parser instead?

test_parse_new_args monkey-patches AirbyteEntrypoint.parse_args to return a canned Namespace. This verifies that the calling code accepts the new attributes, but it doesn’t validate that the actual parser wiring recognises --manifest-path and --components-path.

Would it be safer to call the real parser (as the earlier parametrised test does) and only patch if the parser isn’t fully initialised? That way the test would fail if someone removes the arguments from the CLI by accident, wdyt?

unit_tests/source_declarative_manifest/conftest.py (2)

60-69: Minor: consider adding a newline at EOF in the sample component string

Some linters complain when the embedded code lacks a trailing newline. Adding it keeps black/flake8 quiet, wdyt?


71-84: Why not assert the class path too?

verify_components_loaded checks the function but not the SimpleClass.
Would adding assert hasattr(components, "SimpleClass") (and maybe instantiating it) give fuller confidence that class objects also survive the double-registration trick, wdyt?

airbyte_cdk/cli/source_declarative_manifest/_run.py (3)

199-201: Component loader: should we validate file existence first?

_register_components_from_file proceeds to create a spec even if the path does not exist. spec_from_file_location will then return None, but that is detected after the more cryptic call. Pre-emptively checking components_path.exists() and raising a clear FileNotFoundError could improve UX, wdyt?


255-265: Return type can be tightened & error message clarified

  1. The function always returns a dict or raises – | None isn’t needed.
  2. The except block re-wraps every exception as ValueError, which hides the original stack trace; chaining (raise … from error) would keep context.

Would you consider:

def _parse_manifest_from_file(filepath: str) -> dict[str, Any]:
    try:
        with open(filepath, "r", encoding="utf-8") as manifest_file:
            manifest_content = yaml.safe_load(manifest_file)
        if not isinstance(manifest_content, dict):
            raise TypeError(f"Manifest must be a mapping, got {type(manifest_content).__name__}")
        return manifest_content
    except Exception as exc:
        raise ValueError(f"Failed to load manifest file {filepath}") from exc

wdyt?


267-289: Potential double-registration side-effects

Registering the same module object under two names solves the dataclass issue – nice hack!
Have we considered cleaning these entries up after the sync finishes to avoid polluting sys.modules for subsequent runs in the same interpreter (e.g. unit tests or local REPL sessions)? Maybe a finally block in run() could delete them, wdyt?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 0d05b2e and 4480416.

📒 Files selected for processing (7)
  • airbyte_cdk/cli/source_declarative_manifest/_run.py (6 hunks)
  • airbyte_cdk/connector.py (2 hunks)
  • airbyte_cdk/entrypoint.py (3 hunks)
  • unit_tests/source_declarative_manifest/conftest.py (2 hunks)
  • unit_tests/source_declarative_manifest/test_source_declarative_remote_manifest.py (2 hunks)
  • unit_tests/source_declarative_manifest/test_source_declarative_w_custom_components.py (3 hunks)
  • unit_tests/test_entrypoint.py (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
unit_tests/source_declarative_manifest/test_source_declarative_w_custom_components.py (2)
airbyte_cdk/cli/source_declarative_manifest/_run.py (1)
  • _register_components_from_file (267-288)
unit_tests/source_declarative_manifest/conftest.py (2)
  • verify_components_loaded (71-83)
  • components_file (87-103)
🔇 Additional comments (11)
unit_tests/source_declarative_manifest/test_source_declarative_remote_manifest.py (3)

5-7: New imports look good!

Clean addition of necessary imports for the new test function.


11-12: Updated imports to include new function under test.

Good practice to include the specific function being tested in the imports.


36-41: Well-implemented test for manifest parsing functionality.

The test effectively mocks file reading and validates the correct parsing behavior of _parse_manifest_from_file. Great to see proper test coverage for the new functionality.

unit_tests/source_declarative_manifest/test_source_declarative_w_custom_components.py (3)

19-21: Added import for new function being tested.

Good addition of the function to be tested in the imports list.


37-40: Good refactoring to use shared test utilities.

Moving common code to conftest.py improves maintainability. The shared utilities SAMPLE_COMPONENTS_PY_TEXT and verify_components_loaded can now be reused across tests.


289-295: Well-structured test for component loading functionality.

The test properly checks the dynamic loading and registration of components by:

  1. Using the components_file fixture
  2. Calling the function under test
  3. Verifying the components were correctly registered

This complements the manifest loading tests and provides good coverage for the new CLI arguments.

airbyte_cdk/connector.py (2)

11-11: Added MutableMapping to imports.

Good addition to support the type annotation change.


44-46: Changed config type from Mapping to MutableMapping.

This change allows for mutation of the configuration, which is necessary for the new functionality that injects manifests and components. The change is appropriately minimal and focused.

Have you considered any backward compatibility implications? Since MutableMapping is a subclass of Mapping, most existing code should continue to function properly, but it might be worth noting this change in documentation or release notes, wdyt?

airbyte_cdk/entrypoint.py (3)

87-98: Added new CLI arguments for manifest and components paths.

The implementation adds two optional arguments to the check command:

  • --manifest-path: For injecting a YAML manifest file
  • --components-path: For specifying custom components

These align well with the PR objectives and provide proper help text.


110-121: Added manifest and components path arguments to discover command.

Good consistency in adding the same arguments to the discover command with identical help text.


141-152: Added manifest and components path arguments to read command.

The arguments are consistently added to the read command, maintaining parity with the other commands.

I notice these arguments are not added to the spec command. According to the PR objectives, support for --manifest-path in the spec command will be added in a future PR, which seems like a reasonable approach.

Comment thread airbyte_cdk/cli/source_declarative_manifest/_run.py
Comment thread airbyte_cdk/cli/source_declarative_manifest/_run.py
Comment thread airbyte_cdk/cli/source_declarative_manifest/_run.py
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
airbyte_cdk/cli/source_declarative_manifest/_run.py (3)

94-99: Is AirbyteEntrypoint.parse_args guaranteed to be a classmethod?

The code is calling AirbyteEntrypoint.parse_args(args) directly as if it were a class method. From reviewing other code in the codebase, this method seems to be typically called on an instance. If it's actually an instance method, this would raise a TypeError at runtime.

Would it make sense to either:

  1. Instantiate before calling: AirbyteEntrypoint(MockSource()).parse_args(args)
  2. Or verify that parse_args is decorated with @classmethod in the AirbyteEntrypoint class?

Just want to make sure this works reliably at runtime, wdyt?

#!/bin/bash
# Verify if parse_args is a classmethod or instance method in AirbyteEntrypoint
rg "def parse_args" -A 3 -B 2 --context | grep -A 7 "class AirbyteEntrypoint"

181-186: Consider handling empty manifests explicitly.

The current code silently skips injection if injected_manifest is falsy (which happens if the YAML file is empty), which could lead to confusing "manifest missing" errors later.

Would it be more user-friendly to check specifically if injected_manifest is None after parsing and raise a clear error immediately if the manifest file is empty or invalid? This would help users identify the root cause more easily, wdyt?

-        if hasattr(parsed_args, "manifest_path") and parsed_args.manifest_path:
-            injected_manifest = _parse_manifest_from_file(parsed_args.manifest_path)
-            if injected_manifest:
-                config["__injected_declarative_manifest"] = injected_manifest
+        if hasattr(parsed_args, "manifest_path") and parsed_args.manifest_path:
+            injected_manifest = _parse_manifest_from_file(parsed_args.manifest_path)
+            if injected_manifest is None:
+                raise ValueError(f"Manifest file at {parsed_args.manifest_path} is empty or invalid")
+            config["__injected_declarative_manifest"] = injected_manifest

258-258: Good inclusion of explicit UTF-8 encoding.

The explicit file encoding specification addresses the previous review comment and ensures consistent behavior across different platforms.

🧹 Nitpick comments (1)
airbyte_cdk/cli/source_declarative_manifest/_run.py (1)

255-265: Well-implemented manifest parsing with proper error handling.

The _parse_manifest_from_file function looks good with proper error handling, validation, and explicit UTF-8 encoding.

One small suggestion: in the error message (line 264), you might want to include the specific validation error message when the manifest isn't a dictionary to help users debug more quickly.

-        raise ValueError(f"Failed to load manifest file from {filepath}: {error}")
+        if isinstance(error, ValueError) and "Manifest must be a dictionary" in str(error):
+            raise ValueError(f"Failed to load manifest file from {filepath}: {error}")
+        else:
+            raise ValueError(f"Failed to load manifest file from {filepath}: {error}. Ensure the file contains valid YAML and is a dictionary.")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 4480416 and a0abfe7.

📒 Files selected for processing (1)
  • airbyte_cdk/cli/source_declarative_manifest/_run.py (6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Analyze (python)
  • GitHub Check: Pytest (All, Python 3.11, Ubuntu)
  • GitHub Check: Pytest (All, Python 3.10, Ubuntu)
  • GitHub Check: Pytest (Fast)
  • GitHub Check: SDM Docker Image Build
🔇 Additional comments (6)
airbyte_cdk/cli/source_declarative_manifest/_run.py (6)

56-60: Consistent type change from Mapping to MutableMapping.

The change from Mapping to MutableMapping looks good. This aligns with the need to modify the config by injecting manifests.


175-179: Clear error handling for missing manifest.

Good error message that explicitly mentions the alternative --manifest-path argument. This helps users understand how to provide the manifest correctly.


267-289: Dynamic component loading looks good.

The implementation for dynamically loading Python components is well structured. The approach of registering the module under two different names (components and source_declarative_manifest.components) is a clever way to handle dataclass module resolution issues.

The previous review comment noted that hardcoding "components" as the module name might lead to conflicts, but I see this was intentionally kept as-is due to the current contract requirements. That makes sense for consistency.


172-174: Consistent argument parsing approach.

Using AirbyteEntrypoint.parse_args across the codebase provides consistency in how CLI arguments are handled. This is a good refactoring.


199-201: Components path integration is clean and concise.

The check for components_path and conditional registration is implemented in a clean and straightforward way. Good addition!


229-253: Clean refactoring of input parsing.

The refactored _parse_inputs_into_config_catalog_state function with proper typing looks good. It cleanly separates the concerns of argument parsing and input processing.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, Christo Grabowski (@ChristoGrab). Thanks for including tests. 👍

@ChristoGrab Christo Grabowski (ChristoGrab) merged commit d458e8f into main May 19, 2025
32 of 34 checks passed
@ChristoGrab Christo Grabowski (ChristoGrab) deleted the christo/sdm-cli-manifest-path branch May 19, 2025 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants