Skip to content

feat(wren-launcher): introduce CLI tool for dbt integration#1827

Merged
wwwy3y3 merged 14 commits intoCanner:mainfrom
goldmedal:feat/dbt-cli-command
Jul 22, 2025
Merged

feat(wren-launcher): introduce CLI tool for dbt integration#1827
wwwy3y3 merged 14 commits intoCanner:mainfrom
goldmedal:feat/dbt-cli-command

Conversation

@goldmedal
Copy link
Copy Markdown
Collaborator

@goldmedal goldmedal commented Jul 8, 2025

Description

dbt-auto-convert command

I implement a new command for wren-launcher:

$> ./wren-launcher --help                                                                                                                     
 INFO  Usage of Wren launcher:
 INFO  
 INFO  Commands:
 INFO    (default)                                        Launch Wren AI service
 INFO    dbt-auto-convert --path --output [--profile] [--target]    Auto-convert dbt project to WrenDataSource and Wren MDL
 INFO  
 INFO  Flags:
  -disable-telemetry
        Disable telemetry if set to true
  -enable-dbt
        Enable dbt support if set to true
  -experimental-engine-rust-version
        Use the experimental Rust version of the Wren Engine (default true)
  -llm-provider string
        The LLM provider to use, valid values are: openai, custom
  -openai-api-key string
        The OPENAI API key
  -openai-generation-model string
        The OPENAI generation model, valid values are: gpt-4.1, gpt-4.1-mini, gpt-4.1-nano
  -platform string
        The platform to use, valid values are: linux/amd64, linux/arm64 (default "linux/arm64")
 INFO  
 INFO  Examples:
 INFO    wren-launcher                                              # Launch Wren AI
 INFO    wren-launcher dbt-auto-convert --path /path/to/dbt --output ./output    # Auto-convert dbt project
 INFO    wren-launcher dbt-auto-convert --path /path/to/dbt --output ./output --profile my_profile --target dev # Convert with specific profile/target

dbt-auto-convert can accept a path of a DBT project and generate the required files in a specific output-dir:

  • wren-mdl.json
  • wren-datasource.json

Requirement for DBT project

To ensure the DBT project is qualified and generates the required files, we should execute the following command in the DBT project home:

dbt build
dbt docs generate

They will generate catalog.json and manifest.json for your DBT project, which is required for the conversion.

Another required file is profile.yml, which defines the destination of your DBT project. It will be used to generate the connection info for Wren AI.

New step for the launcher if enabled dbt mode

If we start the launcher with the flag, it will show an extra step for dbt integration.

./wren-launcher --enable-dbt

New step:

Please provide the dbt project path you want to convert
This should be the root directory of your dbt project containing dbt_project.yml
Press Enter to ignore this step if you don't have a dbt project to convert.
✔ dbt project path (leave empty to skip): █

Currently, this step only generates the required files in the project directory and mounts the path if required. The user can just skip the step for now.

Supported Database

  • DuckDB
  • Postgres

Currently, it's not mature. I only convert the common type and configs for now.

How to build and test

The following command can build the binary and run the test cases.

cd wren-launcher
go build
go test ./...

Changed Summary

  • Implement dbt-auto-convert command.
  • Add a launching step for dbt integration (ignore it if no DBT project is used)
  • Modify the docker-compose.yaml and .env.example files to mount the local path for accessing local storage.
  • Add the unit tests
  • Add the doc for supporting the new database

TODO

  • More database
  • wren-ui should accept the MDL and connection info file for onboarding.

Summary by CodeRabbit

  • New Features

    • Added interactive support for converting dbt projects into Wren-compatible formats during the launch process.
    • Introduced new commands and options for dbt project conversion via the command-line interface.
    • Enabled persistent or shared storage configuration for the Wren Engine using a new environment variable.
    • Enhanced help output with detailed usage instructions and subcommand descriptions.
  • Documentation

    • Added comprehensive documentation for extending dbt project conversion to new data sources.
  • Bug Fixes

    • Improved validation and error handling for dbt project paths and profiles.
  • Tests

    • Introduced unit tests for dbt profile and data source conversion logic.
  • Chores

    • Minor formatting and comment cleanup in configuration files.
    • Updated dependency annotations in module files.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 8, 2025

Walkthrough

This update introduces a comprehensive dbt project conversion feature to the Wren launcher, enabling users to convert dbt projects into Wren-compatible formats via both CLI and interactive flows. It adds new Go packages for parsing dbt profiles, converting data sources, and generating Wren MDL manifests, along with integration into Docker configurations for local storage support.

Changes

Files / Group Change Summary
wren-launcher/commands/dbt.go, wren-launcher/commands/dbt/converter.go,
wren-launcher/commands/dbt/data_source.go, wren-launcher/commands/dbt/profiles.go,
wren-launcher/commands/dbt/profiles_analyzer.go, wren-launcher/commands/dbt/utils.go,
wren-launcher/commands/dbt/wren_mdl.go
Added new Go source files implementing dbt project parsing, profile analysis, data source conversion,
and Wren MDL manifest generation. Introduced core logic for dbt-to-Wren conversion.
wren-launcher/commands/dbt/data_source_test.go Added comprehensive tests for dbt profile conversion and data source validation logic.
wren-launcher/commands/dbt/README.md Added documentation explaining how to extend dbt converter for new data sources.
wren-launcher/commands/launch.go Integrated interactive dbt project conversion flow into the launch sequence.
wren-launcher/main.go Added subcommand support for dbt-auto-convert and improved help output.
wren-launcher/utils/docker.go Updated Docker file preparation to support and propagate LOCAL_STORAGE environment variable.
docker/.env.example Added LOCAL_STORAGE environment variable for Wren Engine local storage configuration.
docker/docker-compose.yaml Added volume mount for ibis-server using the LOCAL_STORAGE variable.
wren-launcher/config/config.go Added enableDbt flag with CLI option to enable dbt support; minor comment whitespace cleanup.
wren-launcher/go.mod Removed // indirect comment from gopkg.in/yaml.v3 dependency.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Launcher
    participant DbtConverter
    participant DockerUtils

    User->>Launcher: Run launch command
    Launcher->>User: Prompt for dbt project path
    User->>Launcher: Provide dbt project path (or skip)
    alt dbt project provided
        Launcher->>User: Prompt for profile and target
        User->>Launcher: Provide profile/target (or skip)
        Launcher->>DbtConverter: Convert dbt project to Wren format
        DbtConverter-->>Launcher: Return local storage path
    else no dbt project
        Launcher-->>Launcher: Use default local storage path
    end
    Launcher->>DockerUtils: Prepare Docker files with local storage path
    DockerUtils-->>Launcher: Docker files prepared
    Launcher-->>User: Launch complete
Loading

Suggested labels

wren-ai-service, deployment

Poem

🐇 In fields of code where data flows,
A rabbit hops where dbt grows.
It reads the profiles, maps each source,
Converts the models with gentle force.
Local storage set, Docker aligned,
Wren and dbt now intertwined!
🚀✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 171e71c and b37759f.

📒 Files selected for processing (4)
  • wren-launcher/commands/dbt/data_source.go (1 hunks)
  • wren-launcher/commands/launch.go (5 hunks)
  • wren-launcher/config/config.go (4 hunks)
  • wren-launcher/utils/docker.go (5 hunks)
✅ Files skipped from review due to trivial changes (1)
  • wren-launcher/utils/docker.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • wren-launcher/config/config.go
  • wren-launcher/commands/launch.go
  • wren-launcher/commands/dbt/data_source.go
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • 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 auto-generate unit tests to generate unit tests for 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: 5

🧹 Nitpick comments (10)
wren-launcher/config/config.go (1)

42-46: Handle Windows on ARM to future-proof the helper
GetPlatform special-cases windows but hard-codes linux/amd64, ignoring the possibility of Windows on ARM machines. Consider mirroring the darwin / linux branches:

 case "windows":
-    return "linux/amd64" // Windows typically uses amd64
+    if runtime.GOARCH == "arm64" {
+        return "linux/arm64"
+    }
+    return "linux/amd64" // Default to amd64

This keeps the public contract unchanged for x86-64 systems while adding graceful support for ARM laptops such as Surface Pro X.

wren-launcher/main.go (1)

41-55: Consider improving help output formatting.

The help function provides good information but could benefit from better formatting and consistency.

Consider this improvement for better readability:

 func showHelp() {
-	pterm.Info.Println("Usage of Wren launcher:")
-	pterm.Info.Println("")
-	pterm.Info.Println("Commands:")
-	pterm.Info.Println("  (default)                                        Launch Wren AI service")
-	pterm.Info.Println("  dbt-auto-convert --path --output [--profile] [--target]    Auto-convert dbt project to WrenDataSource and Wren MDL")
-	pterm.Info.Println("")
-	pterm.Info.Println("Flags:")
+	pterm.Info.Println("Usage of Wren launcher:\n")
+	pterm.Info.Println("Commands:")
+	pterm.Info.Println("  (default)           Launch Wren AI service")
+	pterm.Info.Println("  dbt-auto-convert    Auto-convert dbt project to WrenDataSource and Wren MDL")
+	pterm.Info.Println("                      Required: --path, --output")
+	pterm.Info.Println("                      Optional: --profile, --target")
+	pterm.Info.Println("\nFlags:")
 	flag.PrintDefaults()
-	pterm.Info.Println("")
-	pterm.Info.Println("Examples:")
+	pterm.Info.Println("\nExamples:")
 	pterm.Info.Println("  wren-launcher                                              # Launch Wren AI")
 	pterm.Info.Println("  wren-launcher dbt-auto-convert --path /path/to/dbt --output ./output    # Auto-convert dbt project")
 	pterm.Info.Println("  wren-launcher dbt-auto-convert --path /path/to/dbt --output ./output --profile my_profile --target dev # Convert with specific profile/target")
 }
wren-launcher/commands/dbt/profiles_analyzer.go (1)

173-176: Remove redundant conditional logic.

Both Windows and non-Windows cases return the same path. The conditional check is unnecessary.

-	if runtime.GOOS == "windows" {
-		return filepath.Join(homeDir, ".dbt", "profiles.yml")
-	}
	return filepath.Join(homeDir, ".dbt", "profiles.yml")
wren-launcher/commands/dbt/README.md (2)

22-22: Fix markdown heading punctuation.

Remove trailing colons from headings to follow markdown best practices.

-### Steps:
+### Steps

-### Example:
+### Example

-### Steps:
+### Steps

-### Example:
+### Example

Also applies to: 51-51, 81-81, 86-86


57-67: Replace hard tabs with spaces in code blocks.

Use consistent indentation with spaces instead of tabs for better rendering across different platforms.

Convert the tab characters to spaces (typically 4 spaces per tab level) in the Go code examples.

Also applies to: 92-112

wren-launcher/commands/dbt.go (1)

31-31: Extract duplicated usage message to reduce code duplication.

The same usage message appears twice. Consider extracting it to a constant or helper function.

+const dbtAutoConvertUsage = "Usage: wren-launcher dbt-auto-convert --path /path/to/dbt/project --output /path/to/output"
+
 func DbtAutoConvert() {
 	// ... flag definitions ...
 	
 	// Validate required parameters
 	if opts.ProjectPath == "" {
 		pterm.Error.Println("Error: --path parameter is required")
-		pterm.Info.Println("Usage: wren-launcher dbt-auto-convert --path /path/to/dbt/project --output /path/to/output")
+		pterm.Info.Println(dbtAutoConvertUsage)
 		os.Exit(1)
 	}
 
 	if opts.OutputDir == "" {
 		pterm.Error.Println("Error: --output parameter is required")
-		pterm.Info.Println("Usage: wren-launcher dbt-auto-convert --path /path/to/dbt/project --output /path/to/output")
+		pterm.Info.Println(dbtAutoConvertUsage)
 		os.Exit(1)
 	}

Also applies to: 37-37

wren-launcher/commands/dbt/data_source_test.go (1)

274-375: Good test coverage, but consider adding tests for missing scenarios.

The existing tests are well-structured and cover the main functionality. However, consider adding tests for:

  1. MapType functionality for both PostgreSQL and LocalFile data sources
  2. File path handling edge cases (absolute vs relative paths with/without dbt_home)
  3. DefaultDataSource implementation

Would you like me to generate additional test cases for these missing scenarios?

wren-launcher/commands/dbt/converter.go (3)

144-149: Consider making the container mount path configurable.

The hard-coded path "/usr/src/app/data" could be made configurable for flexibility.

Consider adding a constant or configuration option:

const DefaultContainerDataPath = "/usr/src/app/data"

299-308: Consider making staging model filtering configurable.

The code automatically excludes staging models (containing ".stg_" or ".staging_"), which might be too restrictive for some users who want to include these models in their Wren setup.

Consider adding an option to include/exclude staging models rather than hard-coding the exclusion.


423-427: Column sorting may not preserve dbt's intended order.

The code sorts columns alphabetically, but dbt models often have a specific column order that might be meaningful (e.g., primary keys first). Consider preserving the original order or making sorting configurable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5633d23 and 4ccf0c6.

📒 Files selected for processing (16)
  • docker/.env.example (1 hunks)
  • docker/docker-compose.yaml (1 hunks)
  • wren-launcher/commands/dbt.go (1 hunks)
  • wren-launcher/commands/dbt/README.md (1 hunks)
  • wren-launcher/commands/dbt/converter.go (1 hunks)
  • wren-launcher/commands/dbt/data_source.go (1 hunks)
  • wren-launcher/commands/dbt/data_source_test.go (1 hunks)
  • wren-launcher/commands/dbt/profiles.go (1 hunks)
  • wren-launcher/commands/dbt/profiles_analyzer.go (1 hunks)
  • wren-launcher/commands/dbt/utils.go (1 hunks)
  • wren-launcher/commands/dbt/wren_mdl.go (1 hunks)
  • wren-launcher/commands/launch.go (5 hunks)
  • wren-launcher/config/config.go (1 hunks)
  • wren-launcher/go.mod (1 hunks)
  • wren-launcher/main.go (1 hunks)
  • wren-launcher/utils/docker.go (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: cyyeh
PR: Canner/WrenAI#1293
File: wren-ai-service/pyproject.toml:38-38
Timestamp: 2025-02-12T22:05:37.109Z
Learning: The qdrant-client package version in wren-ai-service must match the Qdrant server version (1.11.0) to maintain compatibility.
docker/docker-compose.yaml (1)
Learnt from: paopa
PR: Canner/WrenAI#976
File: wren-ai-service/tools/dev/.env:17-17
Timestamp: 2025-02-03T06:25:14.605Z
Learning: The IBIS server version sha-ce21e44 refers to a commit in the internal wren-engine repository (https://github.com/Canner/wren-engine), not the upstream ibis-project/ibis repository. This version includes fixes for server startup issues.
🧬 Code Graph Analysis (6)
wren-launcher/main.go (2)
wren-launcher/config/config.go (1)
  • InitFlags (17-24)
wren-launcher/commands/dbt.go (1)
  • DbtAutoConvert (13-56)
wren-launcher/commands/dbt/profiles_analyzer.go (2)
wren-launcher/commands/dbt/profiles.go (3)
  • DbtProfiles (4-7)
  • DbtProfile (10-13)
  • DbtConnection (16-39)
wren-launcher/commands/dbt/utils.go (1)
  • FileExists (30-36)
wren-launcher/commands/dbt.go (1)
wren-launcher/commands/dbt/converter.go (3)
  • ConvertOptions (15-22)
  • ConvertDbtProjectCore (33-230)
  • ConvertResult (25-29)
wren-launcher/commands/dbt/data_source_test.go (2)
wren-launcher/commands/dbt/profiles.go (3)
  • DbtProfiles (4-7)
  • DbtProfile (10-13)
  • DbtConnection (16-39)
wren-launcher/commands/dbt/data_source.go (6)
  • FromDbtProfiles (18-40)
  • WrenPostgresDataSource (166-172)
  • WrenLocalFileDataSource (122-125)
  • GetActiveDataSources (204-242)
  • GetDataSourceByType (245-259)
  • ValidateAllDataSources (262-284)
wren-launcher/commands/launch.go (1)
wren-launcher/commands/dbt.go (1)
  • DbtConvertProject (60-71)
wren-launcher/commands/dbt/data_source.go (1)
wren-launcher/commands/dbt/profiles.go (2)
  • DbtProfiles (4-7)
  • DbtConnection (16-39)
🪛 LanguageTool
wren-launcher/commands/dbt/README.md

[grammar] ~1-~1: Use proper spacing conventions.
Context: # How to Support a New Data Source This document outlines the steps require...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~3-~3: Use proper spacing conventions.
Context: ...ata source to the dbt project converter. The target data source must be supported...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~5-~5: There might be a mistake here.
Context: ... by both dbt and the Wren engine: - [dbt supported databases](https://docs.getdbt...

(QB_NEW_EN_OTHER)


[grammar] ~6-~6: There might be a mistake here.
Context: ...supported-data-platforms) - [Wren engine supported data sources](https://docs.get...

(QB_NEW_EN_OTHER)


[grammar] ~6-~6: Use proper spacing conventions.
Context: ...s) - Wren engine supported data sources ## 1. Implement the DataSource Interface T...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~8-~8: Place a period at the end of declarative sentences.
Context: ...## 1. Implement the DataSource Interface The first step is to define a new struct...

(QB_NEW_EN_OTHER_ERROR_IDS_000178)


[grammar] ~10-~10: Use proper spacing conventions.
Context: ...interface defined indata_source.go. The DataSource` interface is as follows...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~12-~12: Use proper spacing conventions.
Context: ...he DataSource interface is as follows: go type DataSource interface { GetType() string Validate() error MapType(sourceType string) string } ### Steps: 1. Define Your Struct: Crea...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~22-~22: Use proper spacing conventions.
Context: ...rceType string) string } ``` ### Steps: 1. Define Your Struct: Create a new struc...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~24-~24: Use proper spacing conventions.
Context: ...nectionInfo) for the target data source. For example, to add support for `Snowfla...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~26-~26: Use proper spacing conventions.
Context: ..., you would define the following struct: go type WrenSnowflakeDataSource struct { Account string `json:"account"` User string `json:"user"` Password string `json:"password"` Database string `json:"database"` Warehouse string `json:"warehouse"` // ... other properties } 2. Implement GetType(): This method sho...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~39-~39: Use proper spacing conventions.
Context: ... data source type (e.g., "snowflake"). 3. Implement Validate(): This method sh...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~41-~41: Use proper spacing conventions.
Context: ...id. Return an error if validation fails. 4. Implement MapType(): This method is ...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~43-~43: Use proper spacing conventions.
Context: ....g., integer, varchar, timestamp). ## 2. Add Conversion Logic in `data_source....

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~45-~45: Use proper spacing conventions.
Context: ...stamp). ## 2. Add Conversion Logic in data_source.go` After implementing the interface, you ne...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~47-~47: Use proper spacing conventions.
Context: ...ataSourcefunction indata_source.go. Add a new caseto theswitch` stateme...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~49-~49: Use proper spacing conventions.
Context: ... struct from the dbt connection details. ### Example: ```go // in data_source.go fu...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~51-~51: Use proper spacing conventions.
Context: ...he dbt connection details. ### Example: go // in data_source.go func convertConnectionToDataSource(conn DbtConnection, dbt_home_path, profileName, outputName string) (DataSource, error) { switch strings.ToLower(conn.Type) { case "postgres", "postgresql": return convertToPostgresDataSource(conn) case "duckdb": return convertToLocalFileDataSource(conn, dbt_home_path) // Add your new case here case "snowflake": return convertToSnowflakeDataSource(conn) // Implement this function default: // ... } } // Implement the conversion function func convertToSnowflakeDataSource(conn DbtConnection) (*WrenSnowflakeDataSource, error) { // Logic to extract snowflake properties from conn // and return a new *WrenSnowflakeDataSource } ## 3. Handle the New Data Source in `Conver...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~77-~77: Use proper spacing conventions.
Context: ...`` ## 3. Handle the New Data Source in ConvertDbtProjectCore The `ConvertDbtProjectCore` function in ...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~79-~79: Use proper spacing conventions.
Context: ...on to ensure it is correctly serialized. ### Steps: 1. **Locate the switch statem...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~81-~81: Use proper spacing conventions.
Context: ... it is correctly serialized. ### Steps: 1. Locate the switch statement: Find th...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~83-~83: Use proper spacing conventions.
Context: ...)block insideConvertDbtProjectCore. 2. **Add a new case**: Add a new case` for...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~84-~84: Use proper spacing conventions.
Context: ...ith the correct type and properties. ### Example: ```go // in converter.go's Con...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~86-~86: Use proper spacing conventions.
Context: ...t type and properties. ### Example: go // in converter.go's ConvertDbtProjectCore function // ... switch typedDS := ds.(type) { case *WrenPostgresDataSource: // ... case *WrenLocalFileDataSource: // ... // Add your new case here case *WrenSnowflakeDataSource: wrenDataSource = map[string]interface{}{ "type": "snowflake", "properties": map[string]interface{}{ "account": typedDS.Account, "user": typedDS.User, "password": typedDS.Password, "database": typedDS.Database, "warehouse": typedDS.Warehouse, // ... other properties }, } default: // ... } // ... Note on File-Based Data Sources: If yo...

(QB_NEW_EN_OTHER_ERROR_IDS_000007)


[grammar] ~116-~116: Use proper spacing conventions.
Context: ...ren engine where to find the data files.

(QB_NEW_EN_OTHER_ERROR_IDS_000007)

🪛 markdownlint-cli2 (0.17.2)
wren-launcher/commands/dbt/README.md

22-22: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


51-51: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


57-57: Hard tabs
Column: 1

(MD010, no-hard-tabs)


58-58: Hard tabs
Column: 1

(MD010, no-hard-tabs)


59-59: Hard tabs
Column: 1

(MD010, no-hard-tabs)


60-60: Hard tabs
Column: 1

(MD010, no-hard-tabs)


61-61: Hard tabs
Column: 1

(MD010, no-hard-tabs)


63-63: Hard tabs
Column: 1

(MD010, no-hard-tabs)


64-64: Hard tabs
Column: 1

(MD010, no-hard-tabs)


65-65: Hard tabs
Column: 1

(MD010, no-hard-tabs)


66-66: Hard tabs
Column: 1

(MD010, no-hard-tabs)


67-67: Hard tabs
Column: 1

(MD010, no-hard-tabs)


81-81: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


86-86: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


92-92: Hard tabs
Column: 1

(MD010, no-hard-tabs)


93-93: Hard tabs
Column: 1

(MD010, no-hard-tabs)


94-94: Hard tabs
Column: 1

(MD010, no-hard-tabs)


95-95: Hard tabs
Column: 1

(MD010, no-hard-tabs)


96-96: Hard tabs
Column: 1

(MD010, no-hard-tabs)


98-98: Hard tabs
Column: 1

(MD010, no-hard-tabs)


99-99: Hard tabs
Column: 1

(MD010, no-hard-tabs)


100-100: Hard tabs
Column: 1

(MD010, no-hard-tabs)


101-101: Hard tabs
Column: 1

(MD010, no-hard-tabs)


102-102: Hard tabs
Column: 1

(MD010, no-hard-tabs)


103-103: Hard tabs
Column: 1

(MD010, no-hard-tabs)


104-104: Hard tabs
Column: 1

(MD010, no-hard-tabs)


105-105: Hard tabs
Column: 1

(MD010, no-hard-tabs)


107-107: Hard tabs
Column: 1

(MD010, no-hard-tabs)


108-108: Hard tabs
Column: 1

(MD010, no-hard-tabs)


109-109: Hard tabs
Column: 1

(MD010, no-hard-tabs)


110-110: Hard tabs
Column: 1

(MD010, no-hard-tabs)


111-111: Hard tabs
Column: 1

(MD010, no-hard-tabs)


112-112: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (29)
wren-launcher/go.mod (1)

218-218: Consider tidying go.mod to stabilise YAML dependencies

gopkg.in/yaml.v3 v3.0.1 is now promoted to a direct dependency while gopkg.in/yaml.v2 v2.4.0 // indirect remains earlier in the file. Having both major versions is legal, but it is worth confirming that:

  1. All new code really imports gopkg.in/yaml.v3, not v2, otherwise builds may still compile against the older API via transitive deps.
  2. Nothing accidentally still relies on yaml.v2 that could instead migrate to v3, which simplifies the tree and reduces binary size.

A quick go mod tidy after the change will drop any truly-unused version and ensure the module graph reflects reality.

If both versions are genuinely required, no action needed beyond documenting the rationale (e.g., comment on the v2 line).

wren-launcher/config/config.go (1)

43-46: No-op change looks good
Only trailing-whitespace removed; functional behavior untouched.

docker/.env.example (1)

49-52: LGTM! Well-documented environment variable addition.

The addition of LOCAL_STORAGE environment variable is properly documented and positioned in the appropriate section. The default value of "." is sensible for local development scenarios.

docker/docker-compose.yaml (1)

44-45: LGTM! Proper volume mount configuration.

The volume mount syntax is correct and follows Docker Compose best practices. The use of ${LOCAL_STORAGE:-.} provides a sensible default while allowing environment customization.

wren-launcher/main.go (1)

15-27: Fix potential index out of bounds issue in argument handling.

The current argument manipulation logic assumes os.Args has at least 2 elements, which could cause a panic if the slice is shorter.

Apply this diff to add bounds checking:

 // Check if we have subcommands
 if len(os.Args) > 1 {
 	switch os.Args[1] {
 	case "dbt-auto-convert":
-		// Remove the subcommand from args so flag.Parse() works correctly
-		os.Args = append([]string{os.Args[0]}, os.Args[2:]...)
+		// Remove the subcommand from args so flag.Parse() works correctly
+		if len(os.Args) > 2 {
+			os.Args = append([]string{os.Args[0]}, os.Args[2:]...)
+		} else {
+			os.Args = []string{os.Args[0]}
+		}
 		commands.DbtAutoConvert()
 		return
 	case "help", "-h", "--help":
 		showHelp()
 		return
 	}
 }

Likely an incorrect or invalid review comment.

wren-launcher/commands/dbt/utils.go (1)

1-37: LGTM! Well-structured utility functions.

The implementation is clean and follows Go best practices:

  • Proper error handling with os.IsNotExist
  • Clear function names and logic flow
  • Appropriate validation for dbt project structure
  • Good separation of concerns between the utility functions
wren-launcher/commands/dbt/wren_mdl.go (1)

1-57: LGTM! Well-designed data structures for Wren MDL.

The struct definitions are well-thought-out with:

  • Consistent and appropriate JSON tags
  • Proper use of omitempty for optional fields
  • Good type choices for each field
  • Logical hierarchy for representing MDL manifests
  • Flexible Properties maps for extensibility
wren-launcher/commands/dbt/profiles_analyzer.go (2)

90-121: Well-designed helper functions for safe type conversion.

The getString, getInt, and getBool helper functions provide robust type assertion with fallback defaults, preventing runtime panics from type mismatches.


179-198: Excellent search strategy and error reporting.

The function searches profiles.yml in logical priority order and provides comprehensive error messages listing all attempted paths.

wren-launcher/commands/dbt/README.md (1)

1-117: Excellent developer documentation.

This README provides clear, comprehensive instructions for extending the dbt converter with new data sources. The step-by-step approach with concrete examples makes it easy for developers to follow.

wren-launcher/utils/docker.go (1)

39-39: Clean integration of LOCAL_STORAGE support.

The changes follow the established pattern for environment variable replacement and integrate seamlessly with the existing Docker configuration functionality. The default value of "." for local storage is appropriate.

Also applies to: 81-86, 243-243, 283-283

wren-launcher/commands/dbt.go (1)

41-48: Well-designed separation of CLI and wrapper functionality.

The distinction between DbtAutoConvert (strict CLI requiring catalog.json) and DbtConvertProject (flexible wrapper allowing optional catalog.json) provides appropriate interfaces for different use cases.

Also applies to: 61-68

wren-launcher/commands/dbt/profiles.go (1)

3-39: Excellent data structure design for dbt profiles.

The struct definitions are comprehensive and well-organized:

  • Clear separation of concerns between profiles, individual profile, and connection
  • Proper YAML/JSON tag annotations for serialization
  • Good coverage of database-specific fields (BigQuery, Snowflake, Postgres, DuckDB)
  • Flexible Additional field for extensibility
wren-launcher/commands/dbt/data_source_test.go (5)

7-66: LGTM! Comprehensive test for PostgreSQL data source conversion.

The test thoroughly validates field mapping, type conversion, and validation for PostgreSQL connections.


116-141: LGTM! Good edge case testing for unsupported database types.

The test correctly verifies that unsupported connection types are ignored without errors.


143-149: LGTM! Essential nil check test.

Good defensive programming practice to test nil input handling.


151-206: LGTM! Excellent table-driven test for PostgreSQL validation.

Well-structured test that covers all validation scenarios including edge cases for required fields and port range validation.


208-272: LGTM! Thorough test coverage for active data source retrieval.

The test comprehensively covers default selection, explicit selection, and error cases for profile and target retrieval.

wren-launcher/commands/launch.go (4)

125-186: LGTM! Well-structured user prompt functions.

The new prompt functions follow the existing patterns and provide clear instructions for users, properly handling empty inputs for optional parameters.


467-485: LGTM! Smart conditional prompting logic.

Good design decision to skip target prompt when profile is empty, avoiding unnecessary user interaction.


487-521: LGTM! Well-implemented dbt project processing.

The function properly handles user input, creates necessary directories, and integrates cleanly with the dbt conversion logic. Good use of filepath.Join for cross-platform path handling.


299-316: LGTM! Clean integration of dbt processing into launch flow.

The dbt project processing is properly integrated with appropriate error handling and the local storage path is correctly passed to Docker file preparation.

wren-launcher/commands/dbt/data_source.go (4)

9-40: LGTM! Well-designed interface and conversion logic.

The DataSource interface provides a clean abstraction, and FromDbtProfiles properly handles the nested profile structure with appropriate error handling.


122-164: LGTM! Clean implementation of local file data source.

The type mapping is comprehensive and validation logic is appropriate.


196-199: Verify if PostgreSQL MapType implementation is intentional.

The MapType method returns the input unchanged, unlike the LocalFileDataSource implementation which performs actual type mapping. Is this intentional because PostgreSQL handles its own type mapping, or should it provide similar type normalization?


244-315: LGTM! Well-implemented utility functions and default data source.

The filtering, validation aggregation, and default type mapping are all properly implemented.

wren-launcher/commands/dbt/converter.go (3)

14-46: LGTM! Well-structured conversion options and proper initialization.

Good validation, directory creation, and informative logging.


47-77: LGTM! Flexible file handling with helpful user guidance.

The code properly handles missing files with appropriate warnings and hints, while providing flexibility through the RequireCatalog option.


232-242: LGTM! Smart handling of localhost for container environments.

The function correctly addresses the common Docker networking challenge with clear documentation.

@goldmedal goldmedal force-pushed the feat/dbt-cli-command branch from f345e06 to f21fbc5 Compare July 9, 2025 02:25
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 (4)
wren-launcher/commands/dbt/profiles_analyzer.go (1)

145-150: The "path" field issue has been resolved.

The past review comment about the missing "path" field in the knownFields map has been addressed. I can see that "path": true is correctly included in the knownFields map on line 149, ensuring that the path field extracted on line 142 is properly recognized as a known field.

wren-launcher/commands/dbt/data_source.go (3)

43-55: Parameter naming conventions have been addressed.

The past review comments about fixing parameter naming from dbt_home_path to dbtHomePath have been resolved. The function signature and all usages now correctly follow Go naming conventions.


204-242: Parameter naming conventions have been addressed.

The past review comment about renaming dbt_home_path to dbtHomePath has been resolved. The parameter is correctly named and used throughout the function.


82-107: Refactor duplicated path resolution logic.

The path resolution logic is duplicated between handling conn.Path and conn.Additional["file"]. This creates maintenance overhead and potential for inconsistency.

Extract the path resolution logic into a helper function:

+func resolvePath(path, dbtHome string) string {
+	if filepath.IsAbs(path) {
+		return filepath.Dir(path)
+	}
+	relativeDir := filepath.Dir(path)
+	if dbtHome != "" {
+		return filepath.Join(dbtHome, relativeDir)
+	}
+	return relativeDir
+}
+
 func convertToLocalFileDataSource(conn DbtConnection, dbtHome string) (*WrenLocalFileDataSource, error) {
 	var url, format string
 
 	// Try to get file path from different fields
 	if conn.Path != "" {
-		if filepath.IsAbs(conn.Path) {
-			url = filepath.Dir(conn.Path)
-		} else {
-			relativeDir := filepath.Dir(conn.Path)
-			if dbtHome != "" {
-				url = filepath.Join(dbtHome, relativeDir)
-			} else {
-				url = relativeDir
-			}
-		}
+		url = resolvePath(conn.Path, dbtHome)
 	} else if file, exists := conn.Additional["file"]; exists {
 		if fileStr, ok := file.(string); ok {
-			if filepath.IsAbs(fileStr) {
-				url = filepath.Dir(fileStr)
-			} else {
-				relativeDir := filepath.Dir(fileStr)
-				if dbtHome != "" {
-					url = filepath.Join(dbtHome, relativeDir)
-				} else {
-					url = relativeDir
-				}
-			}
+			url = resolvePath(fileStr, dbtHome)
 		}
 	}
🧹 Nitpick comments (2)
wren-launcher/commands/dbt/README.md (1)

1-117: Address markdown formatting issues to improve readability.

The static analysis tools have identified several formatting issues that should be addressed:

  1. Trailing punctuation in headings (lines 22, 51, 81, 86): Remove colons from heading text
  2. Hard tabs in code blocks: Replace tabs with spaces for consistent formatting
  3. Grammar and spacing issues: Minor corrections needed throughout

Apply these formatting improvements:

-### Steps:
+### Steps

-### Example:
+### Example

-### Steps:
+### Steps

-### Example:
+### Example

Also, ensure consistent spacing after code blocks and replace hard tabs with spaces in the code examples.

wren-launcher/commands/dbt/profiles_analyzer.go (1)

173-177: Redundant platform-specific logic in GetDefaultProfilesPath.

The Windows and non-Windows paths are identical, making the platform check unnecessary.

	if runtime.GOOS == "windows" {
		return filepath.Join(homeDir, ".dbt", "profiles.yml")
	}
-	return filepath.Join(homeDir, ".dbt", "profiles.yml")
+	return filepath.Join(homeDir, ".dbt", "profiles.yml")

Since both paths are the same, you can simplify to:

func GetDefaultProfilesPath() string {
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return ""
	}
-
-	if runtime.GOOS == "windows" {
-		return filepath.Join(homeDir, ".dbt", "profiles.yml")
-	}
	return filepath.Join(homeDir, ".dbt", "profiles.yml")
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4ccf0c6 and f21fbc5.

📒 Files selected for processing (16)
  • docker/.env.example (1 hunks)
  • docker/docker-compose.yaml (1 hunks)
  • wren-launcher/commands/dbt.go (1 hunks)
  • wren-launcher/commands/dbt/README.md (1 hunks)
  • wren-launcher/commands/dbt/converter.go (1 hunks)
  • wren-launcher/commands/dbt/data_source.go (1 hunks)
  • wren-launcher/commands/dbt/data_source_test.go (1 hunks)
  • wren-launcher/commands/dbt/profiles.go (1 hunks)
  • wren-launcher/commands/dbt/profiles_analyzer.go (1 hunks)
  • wren-launcher/commands/dbt/utils.go (1 hunks)
  • wren-launcher/commands/dbt/wren_mdl.go (1 hunks)
  • wren-launcher/commands/launch.go (5 hunks)
  • wren-launcher/config/config.go (1 hunks)
  • wren-launcher/go.mod (1 hunks)
  • wren-launcher/main.go (1 hunks)
  • wren-launcher/utils/docker.go (5 hunks)
✅ Files skipped from review due to trivial changes (2)
  • wren-launcher/go.mod
  • wren-launcher/commands/dbt/wren_mdl.go
🚧 Files skipped from review as they are similar to previous changes (11)
  • wren-launcher/config/config.go
  • docker/.env.example
  • docker/docker-compose.yaml
  • wren-launcher/main.go
  • wren-launcher/commands/dbt/utils.go
  • wren-launcher/commands/dbt.go
  • wren-launcher/commands/dbt/profiles.go
  • wren-launcher/commands/launch.go
  • wren-launcher/utils/docker.go
  • wren-launcher/commands/dbt/converter.go
  • wren-launcher/commands/dbt/data_source_test.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: cyyeh
PR: Canner/WrenAI#1293
File: wren-ai-service/pyproject.toml:38-38
Timestamp: 2025-02-12T22:05:37.109Z
Learning: The qdrant-client package version in wren-ai-service must match the Qdrant server version (1.11.0) to maintain compatibility.
wren-launcher/commands/dbt/profiles_analyzer.go (1)
Learnt from: andreashimin
PR: Canner/WrenAI#1414
File: wren-ui/src/apollo/server/utils/error.ts:0-0
Timestamp: 2025-03-18T10:28:10.593Z
Learning: The typo in error code enum names ("IDENTIED_AS_GENERAL" and "IDENTIED_AS_MISLEADING_QUERY" instead of "IDENTIFIED_AS_GENERAL" and "IDENTIFIED_AS_MISLEADING_QUERY") in wren-ui/src/apollo/server/utils/error.ts was recognized but intentionally not fixed as it was considered out of scope for PR #1414.
🪛 LanguageTool
wren-launcher/commands/dbt/README.md

[grammar] ~1-~1: Use correct spacing
Context: # How to Support a New Data Source This document outlines the steps requir...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~5-~5: Use hyphens correctly
Context: ...ted by both dbt and the Wren engine: - [dbt supported databases](https://docs.getdbt...

(QB_NEW_EN_OTHER_ERROR_IDS_29)


[grammar] ~6-~6: Use hyphens correctly
Context: .../docs/supported-data-platforms) - [Wren engine supported data sources](https://docs.get...

(QB_NEW_EN_OTHER_ERROR_IDS_29)


[grammar] ~6-~6: Use correct spacing
Context: ...latforms) - Wren engine supported data sources ## 1. Implement the DataSource Interface ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~8-~8: There might be a mistake here.
Context: ...onInfo) ## 1. Implement the DataSource Interface The first step is to define a new struc...

(QB_NEW_EN_OTHER)


[grammar] ~10-~10: Use correct spacing
Context: ...t the DataSource interface defined in data_source.go. The DataSource interface is as follow...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~12-~12: There might be a problem here.
Context: ....go. The DataSource` interface is as follows: go type DataSource interface { GetType() string Validate() error MapType(sourceType string) string } ### Steps: 1. Define Your Struct: Create a new stru...

(QB_NEW_EN_MERGED_MATCH)


[grammar] ~24-~24: Use correct spacing
Context: ...lakeConnectionInfo) for the target data source. For example, to add support for `Snowfl...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~26-~26: Use correct spacing
Context: ...wflake, you would define the following struct: ```go type WrenSnowflakeDataSource struct { Account string json:"account" User stringjson:"user" Password stringjson:"password" Database stringjson:"database" Warehouse stringjson:"warehouse" // ... other properties } ``` 2. **ImplementGetType()`**: This method sh...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~39-~39: Use correct spacing
Context: ...identifies your data source type (e.g., "snowflake"). 3. Implement Validate(): This method s...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~41-~41: Use correct spacing
Context: ...nd valid. Return an error if validation fails. 4. Implement MapType(): This method is...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~43-~43: Use correct spacing
Context: ...data types (e.g., integer, varchar, timestamp). ## 2. Add Conversion Logic in `data_source...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~45-~45: Use correct spacing
Context: ...imestamp). ## 2. Add Conversion Logic in data_source.go` After implementing the interface, you ...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~47-~47: Use correct spacing
Context: ...vertConnectionToDataSourcefunction indata_source.go. Add a new caseto theswitch` statem...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~49-~49: There might be a problem here.
Context: ...a source struct from the dbt connection details. ### Example: go // in data_source.go func convertConnectionToDataSource(conn DbtConnection, dbtHomePath, profileName, outputName string) (DataSource, error) { switch strings.ToLower(conn.Type) { case "postgres", "postgresql": return convertToPostgresDataSource(conn) case "duckdb": return convertToLocalFileDataSource(conn, dbtHomePath) // Add your new case here case "snowflake": return convertToSnowflakeDataSource(conn) // Implement this function default: // ... } } // Implement the conversion function func convertToSnowflakeDataSource(conn DbtConnection) (*WrenSnowflakeDataSource, error) { // Logic to extract snowflake properties from conn // and return a new *WrenSnowflakeDataSource } ## 3. Handle the New Data Source in `Conve...

(QB_NEW_EN_MERGED_MATCH)


[grammar] ~77-~77: Use correct spacing
Context: ...} ``` ## 3. Handle the New Data Source in ConvertDbtProjectCore The `ConvertDbtProjectCore` function i...

(QB_NEW_EN_OTHER_ERROR_IDS_5)


[grammar] ~79-~79: There might be a problem here.
Context: ...this function to ensure it is correctly serialized. ### Steps: 1. Locate the switch statement: Find t...

(QB_NEW_EN_MERGED_MATCH)


[grammar] ~84-~84: There might be a problem here.
Context: ...Sourcemap with the correcttypeandproperties`. ### Example: go // in converter.go's ConvertDbtProjectCore function // ... switch typedDS := ds.(type) { case *WrenPostgresDataSource: // ... case *WrenLocalFileDataSource: // ... // Add your new case here case *WrenSnowflakeDataSource: wrenDataSource = map[string]interface{}{ "type": "snowflake", "properties": map[string]interface{}{ "account": typedDS.Account, "user": typedDS.User, "password": typedDS.Password, "database": typedDS.Database, "warehouse": typedDS.Warehouse, // ... other properties }, } default: // ... } // ... Note on File-Based Data Sources: If y...

(QB_NEW_EN_MERGED_MATCH)

🪛 markdownlint-cli2 (0.17.2)
wren-launcher/commands/dbt/README.md

22-22: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


51-51: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


57-57: Hard tabs
Column: 1

(MD010, no-hard-tabs)


58-58: Hard tabs
Column: 1

(MD010, no-hard-tabs)


59-59: Hard tabs
Column: 1

(MD010, no-hard-tabs)


60-60: Hard tabs
Column: 1

(MD010, no-hard-tabs)


61-61: Hard tabs
Column: 1

(MD010, no-hard-tabs)


63-63: Hard tabs
Column: 1

(MD010, no-hard-tabs)


64-64: Hard tabs
Column: 1

(MD010, no-hard-tabs)


65-65: Hard tabs
Column: 1

(MD010, no-hard-tabs)


66-66: Hard tabs
Column: 1

(MD010, no-hard-tabs)


67-67: Hard tabs
Column: 1

(MD010, no-hard-tabs)


81-81: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


86-86: Trailing punctuation in heading
Punctuation: ':'

(MD026, no-trailing-punctuation)


92-92: Hard tabs
Column: 1

(MD010, no-hard-tabs)


93-93: Hard tabs
Column: 1

(MD010, no-hard-tabs)


94-94: Hard tabs
Column: 1

(MD010, no-hard-tabs)


95-95: Hard tabs
Column: 1

(MD010, no-hard-tabs)


96-96: Hard tabs
Column: 1

(MD010, no-hard-tabs)


98-98: Hard tabs
Column: 1

(MD010, no-hard-tabs)


99-99: Hard tabs
Column: 1

(MD010, no-hard-tabs)


100-100: Hard tabs
Column: 1

(MD010, no-hard-tabs)


101-101: Hard tabs
Column: 1

(MD010, no-hard-tabs)


102-102: Hard tabs
Column: 1

(MD010, no-hard-tabs)


103-103: Hard tabs
Column: 1

(MD010, no-hard-tabs)


104-104: Hard tabs
Column: 1

(MD010, no-hard-tabs)


105-105: Hard tabs
Column: 1

(MD010, no-hard-tabs)


107-107: Hard tabs
Column: 1

(MD010, no-hard-tabs)


108-108: Hard tabs
Column: 1

(MD010, no-hard-tabs)


109-109: Hard tabs
Column: 1

(MD010, no-hard-tabs)


110-110: Hard tabs
Column: 1

(MD010, no-hard-tabs)


111-111: Hard tabs
Column: 1

(MD010, no-hard-tabs)


112-112: Hard tabs
Column: 1

(MD010, no-hard-tabs)

🔇 Additional comments (7)
wren-launcher/commands/dbt/README.md (2)

14-20: Documentation accurately reflects the DataSource interface.

The interface definition and explanation correctly match the expected implementation pattern. The three-method interface (GetType, Validate, MapType) is well-documented with clear descriptions of each method's purpose.


24-37: Example struct definition follows Wren API conventions.

The Snowflake example struct correctly demonstrates the expected JSON tag format and field naming conventions that align with the Wren engine API documentation.

wren-launcher/commands/dbt/profiles_analyzer.go (2)

13-51: Well-structured YAML parsing with proper error handling.

The AnalyzeDbtProfiles function demonstrates good practices:

  • Proper error wrapping with contextual information
  • Clean separation of YAML parsing and structured conversion
  • Appropriate handling of optional config section

90-122: Type-safe helper functions provide robust value extraction.

The helper functions (getString, getInt, getBool) properly handle type assertions and provide sensible defaults, preventing runtime panics from type mismatches in the YAML data.

wren-launcher/commands/dbt/data_source.go (3)

9-14: Well-designed DataSource interface promotes extensibility.

The DataSource interface provides a clean abstraction with appropriate methods for type identification, validation, and type mapping. This design facilitates easy addition of new data source types as documented in the README.


166-199: Robust PostgreSQL data source implementation.

The WrenPostgresDataSource implementation includes:

  • Proper validation of required fields and port range
  • Sensible default port assignment (5432)
  • Clean struct definition with appropriate JSON tags

143-164: Comprehensive type mapping for local file sources.

The MapType implementation covers common database types and provides a fallback strategy, ensuring robust type conversion from source systems to Wren's type system.

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 (2)
wren-launcher/commands/dbt/data_source.go (2)

80-89: Document the path resolution logic.

The path resolution takes the directory of the file path rather than the full path. This behavior should be documented to clarify the intent, as it might be unexpected to users.

Add a comment explaining why filepath.Dir() is used:

	resolvePath := func(path string) string {
+		// Extract directory from file path since URL should point to the containing directory
		if filepath.IsAbs(path) {
			return filepath.Dir(path)
		}
		relativeDir := filepath.Dir(path)
		if dbtHome != "" {
			return filepath.Join(dbtHome, relativeDir)
		}
		return relativeDir
	}

189-192: Placeholder MapType implementation needs completion.

The PostgreSQL data source's MapType method is a placeholder that returns the input unchanged. This will likely cause issues when type mapping is needed.

The comment indicates this method is not used, but it's part of the required interface. Consider implementing proper PostgreSQL type mapping:

func (ds *WrenPostgresDataSource) MapType(sourceType string) string {
-	// This method is not used in WrenPostgresDataSource, but required by DataSource interface
-	return sourceType
+	// Map PostgreSQL types to standard types
+	switch strings.ToLower(sourceType) {
+	case "integer", "int", "bigint", "int8", "int4", "int2":
+		return "integer"
+	case "varchar", "text", "char", "character":
+		return "varchar"
+	case "timestamp", "timestamptz", "datetime":
+		return "timestamp"
+	case "date":
+		return "date"
+	case "double precision", "float8", "float4", "real", "numeric", "decimal":
+		return "double"
+	case "boolean", "bool":
+		return "boolean"
+	default:
+		return "string"
+	}
}

Would you like me to generate the complete PostgreSQL type mapping implementation?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f21fbc5 and 4d08781.

📒 Files selected for processing (1)
  • wren-launcher/commands/dbt/data_source.go (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: cyyeh
PR: Canner/WrenAI#1293
File: wren-ai-service/pyproject.toml:38-38
Timestamp: 2025-02-12T22:05:37.109Z
Learning: The qdrant-client package version in wren-ai-service must match the Qdrant server version (1.11.0) to maintain compatibility.
🧬 Code Graph Analysis (1)
wren-launcher/commands/dbt/data_source.go (1)
wren-launcher/commands/dbt/profiles.go (2)
  • DbtProfiles (4-7)
  • DbtConnection (16-39)
🔇 Additional comments (2)
wren-launcher/commands/dbt/data_source.go (2)

18-40: LGTM - Well-structured profile conversion.

The function properly handles the conversion of all profiles and their outputs to data sources, with good error handling and nil checks.


194-235: LGTM - Robust active data source selection.

The function provides good defaults for profile and target selection, with comprehensive error handling for missing profiles or targets.

@douenergy
Copy link
Copy Markdown
Collaborator

It works ! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants