strata-cli 0.1.2.beta → 0.1.3.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e48bdd7d5b0d81f037b663bb1a1467b040eea4bc5de99c8be04fab7fd04f92a
4
- data.tar.gz: 43d4d14d7a45fb456e8a5b3b23133d01aa298762915ff2f145bf124d60b63ae3
3
+ metadata.gz: 0dc0377469e1bfb8d12c50f839b1f530d2104b1b894e5623d0f009081e60f1e5
4
+ data.tar.gz: f4595f187e23891e5b1d64ef384ae48b1d3e73bd34a5ab8afefab9886b95f5ad
5
5
  SHA512:
6
- metadata.gz: 4bfce443a4352e0d0298bdc04aac43a64be83aec1de6698cf94a2df5fecb37f3c85c63da3cc9eb641cede6bfed8505d1546f2e4414e9c78f3a846655fa77944e
7
- data.tar.gz: b66964975faf6e3074af3f7fcf6e63417e0ed09aaac756c9f4fdcc6b1b77271ecce3f6f6c18ab9faac2be5ae4b2268f71c87453f77bdf4393e709e3519ca3a2a
6
+ metadata.gz: b13368ec18b1d53316d3eb01f42f869ff81e8297b2f5451c337073cf0fed8400694a629136c3bbc8bec9b3bfd1affd786a9b1343a4b9b6f3561089d5aba86e9c
7
+ data.tar.gz: c47cfbdd8e1d54dda6b9b92b3e6385bf14f8d0e03c608721436dafeb70177fe2f51893003721edd1bebb757bbd8f0eefc3164c6c9287707ffc8ee3f86d2175f1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.3.beta] - 2026-01-28
4
+
5
+ ### Added
6
+
7
+ - **Runtime adapter driver checks**: When a datasource is used, the CLI now verifies that required driver gems (pg, mysql2, tiny_tds, sqlite3, aws-sdk-*, trino-client, duckdb) are installed, and surfaces adapter-specific guidance if they are not.
8
+
9
+ ### Changed
10
+
11
+ - **Adapter installation behavior**: On first use of any adapter, the CLI will attempt to install any missing driver gem once; if installation still fails, it raises a clear `Strata::CommandError` with likely causes and manual install instructions.
12
+ - **DuckDB handling**: DuckDB now follows the same “try install once, then explain” pattern as other adapters, with extra hints for DuckDB’s native build and header/library requirements. DuckDB is still not a default dependency.
13
+
3
14
  ## [0.1.2.beta] - 2025-01-27
4
15
 
5
16
  ### Added
data/README.md CHANGED
@@ -10,28 +10,6 @@ Command-line interface for the Strata Semantic Analytics System. Create, manage,
10
10
  gem install strata-cli
11
11
  ```
12
12
 
13
- ### Install Database Adapters
14
-
15
- Database adapter gems are optional. Install only the adapters you need:
16
-
17
- | Database | Gem | System Libraries |
18
- |----------|-----|------------------|
19
- | PostgreSQL | `gem install pg` | [PostgreSQL](https://www.postgresql.org/download/) |
20
- | MySQL | `gem install mysql2` | [MySQL](https://dev.mysql.com/downloads/) |
21
- | SQL Server | `gem install tiny_tds` | [FreeTDS](https://www.freetds.org/) |
22
- | Snowflake | No additional gem needed | None |
23
- | Athena | `gem install aws-sdk-athena aws-sdk-s3` | None |
24
- | Trino | `gem install trino-client` | None |
25
- | DuckDB | `gem install duckdb` | None |
26
-
27
- Example for PostgreSQL users:
28
-
29
- ```bash
30
- gem install strata-cli pg
31
- ```
32
-
33
- If you use an adapter without its gem installed, the CLI will show an error with installation instructions.
34
-
35
13
  ## Requirements
36
14
 
37
15
  - Ruby >= 3.4.4
@@ -39,13 +17,9 @@ If you use an adapter without its gem installed, the CLI will show an error with
39
17
 
40
18
  ## Dependencies
41
19
 
42
- ### Core Dependency: dwh
43
-
44
- The `strata-cli` depends on the [`dwh`](https://github.com/stratasite/dwh) gem (`~> 0.1.0`), which provides the core data warehouse abstraction layer. This gem handles connections, query execution, and introspection across all supported data warehouse adapters. The `dwh` gem requires Ruby >= 3.4.4.
45
20
 
46
21
  ### Adapter Gems and System Libraries
47
22
 
48
- Adapter gems that use native extensions (`pg`, `mysql2`, `tiny_tds`) require system libraries before `gem install`. Install from the official docs linked in the table above, then run `gem install <adapter-gem>`. If you see **"Failed to build gem native extension"**, the system libraries or build tools for your platform are missing—use the official installation guide for your OS.
49
23
 
50
24
  ## Commands Overview
51
25
 
@@ -3,6 +3,17 @@
3
3
  module Strata
4
4
  module CLI
5
5
  module DatasourceHelper
6
+ ADAPTER_DRIVER_GEMS = {
7
+ postgres: %w[pg],
8
+ redshift: %w[pg],
9
+ mysql: %w[mysql2],
10
+ sqlserver: %w[tiny_tds],
11
+ athena: %w[aws-sdk-athena aws-sdk-s3],
12
+ trino: %w[trino-client],
13
+ sqlite: %w[sqlite3],
14
+ duckdb: %w[duckdb]
15
+ }.freeze
16
+
6
17
  def resolve_datasource(ds_key_arg = nil, prompt: TTY::Prompt.new)
7
18
  # 1. Use argument if provided
8
19
  return validate_datasource(ds_key_arg) if ds_key_arg
@@ -29,7 +40,44 @@ module Strata
29
40
 
30
41
  def create_adapter(ds_key)
31
42
  config = ds_config(ds_key).merge(Credentials.fetch(ds_key))
32
- DWH.create(config["adapter"].to_sym, config)
43
+ adapter_sym = config["adapter"].to_sym
44
+ ensure_adapter_driver_gems!(adapter_sym)
45
+ DWH.create(adapter_sym, config)
46
+ end
47
+
48
+ def ensure_adapter_driver_gems!(adapter_sym)
49
+ required = ADAPTER_DRIVER_GEMS.fetch(adapter_sym, [])
50
+ return if required.empty?
51
+
52
+ missing = required.reject { gem_installed?(it) }
53
+ return if missing.empty?
54
+
55
+ if respond_to?(:say)
56
+ say "Required gem(s) for '#{adapter_sym}' not found (#{missing.join(", ")}). Attempting to install...",
57
+ :yellow
58
+ end
59
+
60
+ missing.each do |gem_name|
61
+ system("gem", "install", gem_name, "-q", "--no-document")
62
+ end
63
+
64
+ still_missing = missing.reject { gem_installed?(it) }
65
+ return if still_missing.empty?
66
+
67
+ details = adapter_driver_gem_help(adapter_sym, still_missing)
68
+
69
+ msg = <<~MSG
70
+ Missing required gem(s) for adapter '#{adapter_sym}': #{still_missing.join(", ")}
71
+
72
+ This adapter can't be used until the driver gem(s) are installed.
73
+
74
+ Install manually:
75
+
76
+ gem install #{still_missing.join(" ")}
77
+
78
+ #{details}
79
+ MSG
80
+ raise Strata::CommandError, msg
33
81
  end
34
82
 
35
83
  def ds_config(ds_key)
@@ -57,6 +105,34 @@ module Strata
57
105
  {}
58
106
  end
59
107
  end
108
+
109
+ def gem_installed?(name)
110
+ Gem::Specification.find_by_name(name)
111
+ true
112
+ rescue Gem::MissingSpecError
113
+ false
114
+ end
115
+
116
+ def adapter_driver_gem_help(adapter_sym, missing)
117
+ case adapter_sym
118
+ when :postgres, :redshift
119
+ "Notes:\n- 'pg' requires PostgreSQL client libraries (libpq) installed on your system. See https://www.postgresql.org/download/"
120
+ when :mysql
121
+ "Notes:\n- 'mysql2' requires MySQL client libraries installed on your system. See https://dev.mysql.com/downloads/"
122
+ when :sqlserver
123
+ "Notes:\n- 'tiny_tds' requires FreeTDS and (often) OpenSSL installed on your system. See https://www.freetds.org/"
124
+ when :sqlite
125
+ "Notes:\n- 'sqlite3' requires SQLite development libraries installed on your system."
126
+ when :athena
127
+ "Notes:\n- AWS SDK gems are pure Ruby; no system libraries required."
128
+ when :trino
129
+ "Notes:\n- 'trino-client' is pure Ruby; no system libraries required."
130
+ when :duckdb
131
+ "Notes:\n- See https://github.com/suketa/ruby-duckdb"
132
+ else
133
+ "Notes:\n- Install missing gems: #{missing.join(", ")}"
134
+ end
135
+ end
60
136
  end
61
137
  end
62
138
  end
@@ -15,18 +15,6 @@ module Strata
15
15
  include DatasourceHelper
16
16
  extend Helpers::DescriptionHelper
17
17
 
18
- # Adapters that require a separate gem. Built-in (snowflake, druid) use dwh's faraday/jwt.
19
- ADAPTER_GEMS = {
20
- postgres: "pg",
21
- redshift: "pg",
22
- mysql: "mysql2",
23
- sqlserver: "tiny_tds",
24
- athena: "aws-sdk-athena, aws-sdk-s3",
25
- trino: "trino-client",
26
- duckdb: "duckdb",
27
- sqlite: "sqlite3"
28
- }.freeze
29
-
30
18
  desc "adapters", "Lists supported data warehouse adapters"
31
19
  def adapters
32
20
  say "\n\tSupported Adapters\n\n", :yellow
@@ -247,10 +235,9 @@ module Strata
247
235
  private
248
236
 
249
237
  def adapter_gem_status
250
- ADAPTER_GEMS.to_h do |adapter, gem_spec|
251
- gems = gem_spec.split(/,\s*/)
238
+ DatasourceHelper::ADAPTER_DRIVER_GEMS.to_h do |adapter, gems|
252
239
  installed = gems.all? { |g| gem_installed?(g) }
253
- [adapter, {gem: gem_spec, installed: installed}]
240
+ [adapter, {gem: gems.join(", "), installed: installed}]
254
241
  end
255
242
  end
256
243
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Strata
4
4
  module CLI
5
- VERSION = "0.1.2.beta"
5
+ VERSION = "0.1.3.beta"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strata-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.beta
4
+ version: 0.1.3.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajo Abraham
@@ -24,6 +24,90 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mysql2
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.5'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: tiny_tds
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: trino-client
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: aws-sdk-athena
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: aws-sdk-s3
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
27
111
  - !ruby/object:Gem::Dependency
28
112
  name: faraday
29
113
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +122,20 @@ dependencies:
38
122
  - - "~>"
39
123
  - !ruby/object:Gem::Version
40
124
  version: '2.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sqlite3
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '2.0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '2.0'
41
139
  - !ruby/object:Gem::Dependency
42
140
  name: pastel
43
141
  requirement: !ruby/object:Gem::Requirement