strata-cli 0.1.1.beta → 0.1.2.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: d9887ae6b4d871118361a7ef0b90c6b07a5095c59f8b7acc812aefc4ef8e5a58
4
- data.tar.gz: e2fba95feba89bb6193d563f7b2dba3e594ea57915c56700f9228b29783c942a
3
+ metadata.gz: 0e48bdd7d5b0d81f037b663bb1a1467b040eea4bc5de99c8be04fab7fd04f92a
4
+ data.tar.gz: 43d4d14d7a45fb456e8a5b3b23133d01aa298762915ff2f145bf124d60b63ae3
5
5
  SHA512:
6
- metadata.gz: d131c145bc2cf2aab4c532266f2d7bd8df1026053ff3b0cce4734867132ec6f2500147b645aecf28fe1e2a3d3d99803d26ce02e7484f6f0d4c9a399fa9ccd8e0
7
- data.tar.gz: a7c089088c80acbc89e9de821de1ab482a4d51f685ac3a06089f1e0469945e05720fdebdb09ea9d114c14cf7c7768c0073d5b3a26bcf357a45ba7fbc474723ce
6
+ metadata.gz: 4bfce443a4352e0d0298bdc04aac43a64be83aec1de6698cf94a2df5fecb37f3c85c63da3cc9eb641cede6bfed8505d1546f2e4414e9c78f3a846655fa77944e
7
+ data.tar.gz: b66964975faf6e3074af3f7fcf6e63417e0ed09aaac756c9f4fdcc6b1b77271ecce3f6f6c18ab9faac2be5ae4b2268f71c87453f77bdf4393e709e3519ca3a2a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.2.beta] - 2025-01-27
4
+
5
+ ### Added
6
+
7
+ - **Version checker**: Notifies when a newer strata-cli is available on Rubygems. Uses a 24-hour cache; set `STRATA_SKIP_VERSION_CHECK=true` to disable. Skipped for `version` and `help` commands.
8
+ - **Git requirement check**: Exits with a clear error when Git is not installed (required for deploy and other features). Skipped for `version` and `help` commands.
9
+
10
+ ### Changed
11
+
12
+ - **Ruby requirement**: `required_ruby_version` set to `>= 3.4.4` (aligned with dwh gem).
13
+ - **CI**: Test on Ruby 3.4.4 and 3.4.5.
14
+ - **README**: Document Ruby and dwh requirements (>= 3.4.4), native dependencies (pg, mysql2, tiny_tds) with install hints, and installation troubleshooting.
15
+
3
16
  ## [0.1.1.beta] - 2025-01-22
4
17
 
5
18
  - Initial release
data/README.md CHANGED
@@ -4,15 +4,48 @@ Command-line interface for the Strata Semantic Analytics System. Create, manage,
4
4
 
5
5
  ## Installation
6
6
 
7
+ ### Basic Installation
8
+
7
9
  ```bash
8
10
  gem install strata-cli
9
11
  ```
10
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
+
11
35
  ## Requirements
12
36
 
13
37
  - Ruby >= 3.4.4
14
38
  - Git (for deployment features)
15
- - Access to a Strata server
39
+
40
+ ## Dependencies
41
+
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
+
46
+ ### Adapter Gems and System Libraries
47
+
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.
16
49
 
17
50
  ## Commands Overview
18
51
 
@@ -54,6 +87,9 @@ strata project link 12345
54
87
  ### `strata datasource adapters`
55
88
  List all supported data warehouse adapters.
56
89
 
90
+ ### `strata datasource check`
91
+ Check which database adapter gems are installed.
92
+
57
93
  ### `strata datasource list`
58
94
  List all configured datasources with their keys and display names.
59
95
 
@@ -256,6 +292,9 @@ strata a models # Validate models only
256
292
  ### `strata version`
257
293
  Print the CLI version.
258
294
 
295
+ ### `strata check`
296
+ Check which database adapter gems are installed (no project required).
297
+
259
298
  ### `strata adapters`
260
299
  List all supported data warehouse adapters.
261
300
 
@@ -8,7 +8,8 @@ module Strata
8
8
  adapters
9
9
  version
10
10
  deploy
11
- ]
11
+ ].freeze
12
+
12
13
  def invoke_command(command, *args)
13
14
  Utils.exit_error_if_not_strata! unless ALLOWED_COMMANDS.include?(command.name)
14
15
  super
@@ -15,6 +15,18 @@ 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
+
18
30
  desc "adapters", "Lists supported data warehouse adapters"
19
31
  def adapters
20
32
  say "\n\tSupported Adapters\n\n", :yellow
@@ -23,6 +35,17 @@ module Strata
23
35
  end
24
36
  end
25
37
 
38
+ desc "check", "Check which database adapter gems are installed"
39
+ def check
40
+ rows = adapter_gem_status.map do |adapter, info|
41
+ status = info[:installed] ? "✔" : "✗"
42
+ [adapter.to_s, info[:gem], status]
43
+ end
44
+ say "\n Adapter gem status:\n\n", :yellow
45
+ print_table(rows, headers: %w[Adapter Gem Installed], color: :magenta)
46
+ say "\n Install missing gems with: gem install <gem_name>", :cyan
47
+ end
48
+
26
49
  desc "list", "List current configured datasources by key and name"
27
50
  def list
28
51
  ds = begin
@@ -223,6 +246,21 @@ module Strata
223
246
 
224
247
  private
225
248
 
249
+ def adapter_gem_status
250
+ ADAPTER_GEMS.to_h do |adapter, gem_spec|
251
+ gems = gem_spec.split(/,\s*/)
252
+ installed = gems.all? { |g| gem_installed?(g) }
253
+ [adapter, {gem: gem_spec, installed: installed}]
254
+ end
255
+ end
256
+
257
+ def gem_installed?(name)
258
+ Gem::Specification.find_by_name(name)
259
+ true
260
+ rescue Gem::MissingSpecError
261
+ false
262
+ end
263
+
226
264
  def validate_file_path(file_path, project_path = Dir.pwd)
227
265
  expanded = File.expand_path(file_path, project_path)
228
266
  project_root = File.expand_path(project_path)
@@ -113,6 +113,24 @@ module Strata
113
113
  File.directory?(".git")
114
114
  end
115
115
 
116
+ def git_available?
117
+ _, _, status = Open3.capture3("git", "--version")
118
+ status.success?
119
+ rescue
120
+ false
121
+ end
122
+
123
+ def check_requirement_and_exit_if_unavailable(args)
124
+ # Allow help and version commands to work without Git
125
+ command = args.first
126
+ return if args.empty? || %w[version help].include?(command)
127
+
128
+ return if git_available?
129
+
130
+ Thor::Shell::Color.new.say_error "ERROR: Git is required but not found. Please install Git to use strata-cli.", :red
131
+ exit 1
132
+ end
133
+
116
134
  def git_remote_url(remote_name = "origin")
117
135
  return nil unless git_repo?
118
136
 
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "net/http"
4
+ require "uri"
5
+ require "json"
6
+ require "fileutils"
7
+ require "timeout"
8
+ require "thor"
9
+
10
+ module Strata
11
+ module CLI
12
+ module Utils
13
+ module VersionChecker
14
+ module_function
15
+
16
+ GEM_NAME = "strata-cli"
17
+ RUBYGEMS_API_URL = "https://rubygems.org/api/v1/gems/#{GEM_NAME}.json"
18
+ CACHE_FILE = File.join(ENV.fetch("TMPDIR", "/tmp"), "strata-cli-version-check-cache")
19
+ CACHE_DURATION = 86_400 # 24 hours in seconds
20
+
21
+ def check_and_notify(current_version)
22
+ return if skip_check?
23
+
24
+ latest_version = fetch_latest_version
25
+ return unless latest_version
26
+
27
+ if newer_version_available?(current_version, latest_version)
28
+ display_update_message(latest_version)
29
+ end
30
+
31
+ update_cache
32
+ rescue
33
+ # Silently fail - version checking should never break the CLI
34
+ # In development, you might want to log this: warn "Version check failed: #{e.message}"
35
+ nil
36
+ end
37
+
38
+ def newer_version_available?(current, latest)
39
+ return false unless current && latest
40
+
41
+ # Simple version comparison (assumes semantic versioning)
42
+ # Convert non-numeric parts (like "beta") to 0 for comparison
43
+ current_parts = current.split(".").map { |p| p.to_i }
44
+ latest_parts = latest.split(".").map { |p| p.to_i }
45
+
46
+ # Pad with zeros if needed
47
+ max_length = [current_parts.length, latest_parts.length].max
48
+ current_parts += [0] * (max_length - current_parts.length)
49
+ latest_parts += [0] * (max_length - latest_parts.length)
50
+
51
+ # Compare arrays element by element
52
+ latest_parts.zip(current_parts).each do |latest_part, current_part|
53
+ return true if latest_part > current_part
54
+ return false if latest_part < current_part
55
+ end
56
+
57
+ false # Versions are equal
58
+ end
59
+
60
+ def fetch_latest_version
61
+ uri = URI(RUBYGEMS_API_URL)
62
+ http = Net::HTTP.new(uri.host, uri.port)
63
+ http.use_ssl = true
64
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
65
+ http.open_timeout = 2 # 2 second timeout
66
+ http.read_timeout = 2
67
+
68
+ response = http.get(uri.path)
69
+ parse_version_response(response)
70
+ rescue
71
+ # Silently fail - version checking should never break the CLI
72
+ # This includes SSL errors, network errors, timeouts, etc.
73
+ nil
74
+ end
75
+
76
+ def parse_version_response(response)
77
+ return nil unless response.is_a?(Net::HTTPSuccess)
78
+
79
+ data = JSON.parse(response.body)
80
+ data["version"]
81
+ rescue JSON::ParserError
82
+ nil
83
+ end
84
+
85
+ def display_update_message(version)
86
+ require_relative "../helpers/color_helper"
87
+ colors = ColorHelper
88
+
89
+ message = "💡 Tip: A new version of #{GEM_NAME} (#{version}) is available. " \
90
+ "Update with: #{colors.info("gem update strata-cli")}"
91
+
92
+ # Use Thor's say method for consistent output
93
+ shell = Thor::Shell::Color.new
94
+ shell.say "\n#{colors.warning(message)}\n"
95
+ end
96
+
97
+ def skip_check?
98
+ return true if ENV["STRATA_SKIP_VERSION_CHECK"] == "true"
99
+ return false unless cache_valid?
100
+
101
+ # Check was done recently, skip
102
+ true
103
+ end
104
+
105
+ def cache_valid?
106
+ return false unless File.exist?(CACHE_FILE)
107
+
108
+ cache_time = File.mtime(CACHE_FILE)
109
+ (Time.now - cache_time) < CACHE_DURATION
110
+ end
111
+
112
+ def update_cache
113
+ FileUtils.touch(CACHE_FILE)
114
+ end
115
+
116
+ def check_and_notify_if_needed(current_version, args)
117
+ # Skip version check for version and help commands
118
+ command = args.first
119
+ return if args.empty? || %w[version help].include?(command)
120
+
121
+ # Early return if we should skip (avoids any work when cache is valid)
122
+ return if skip_check?
123
+
124
+ begin
125
+ # Run synchronously with timeout to ensure it completes before process exits
126
+ Timeout.timeout(3) do
127
+ check_and_notify(current_version)
128
+ end
129
+ rescue Timeout::Error
130
+ # If it takes too long, silently fail
131
+ nil
132
+ rescue
133
+ # Silently fail - version checking should never break the CLI
134
+ nil
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Strata
4
4
  module CLI
5
- VERSION = "0.1.1.beta"
5
+ VERSION = "0.1.2.beta"
6
6
  end
7
7
  end
data/lib/strata/cli.rb CHANGED
@@ -4,6 +4,8 @@ require_relative "cli/version"
4
4
  require_relative "cli/configuration"
5
5
  require_relative "cli/main"
6
6
  require_relative "cli/utils"
7
+ require_relative "cli/utils/git"
8
+ require_relative "cli/utils/version_checker"
7
9
 
8
10
  module Strata
9
11
  class StrataError < StandardError; end
@@ -27,10 +29,16 @@ module Strata
27
29
  end
28
30
 
29
31
  def self.start(args)
30
- Main.start(args)
31
- rescue TTY::Reader::InputInterrupt
32
- warn "\nCancelled."
33
- exit(1)
32
+ Utils::Git.check_requirement_and_exit_if_unavailable(args)
33
+
34
+ begin
35
+ Main.start(args)
36
+ rescue TTY::Reader::InputInterrupt
37
+ warn "\nCancelled."
38
+ exit(1)
39
+ end
40
+
41
+ Utils::VersionChecker.check_and_notify_if_needed(VERSION, args)
34
42
  end
35
43
  end
36
44
  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.1.beta
4
+ version: 0.1.2.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ajo Abraham
@@ -10,20 +10,6 @@ bindir: exe
10
10
  cert_chain: []
11
11
  date: 1980-01-02 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: aws-sdk-athena
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.0'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: dwh
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -52,20 +38,6 @@ dependencies:
52
38
  - - "~>"
53
39
  - !ruby/object:Gem::Version
54
40
  version: '2.0'
55
- - !ruby/object:Gem::Dependency
56
- name: mysql2
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.5'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.5'
69
41
  - !ruby/object:Gem::Dependency
70
42
  name: pastel
71
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +52,6 @@ dependencies:
80
52
  - - "~>"
81
53
  - !ruby/object:Gem::Version
82
54
  version: '0.8'
83
- - !ruby/object:Gem::Dependency
84
- name: pg
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
55
  - !ruby/object:Gem::Dependency
98
56
  name: ruby_llm
99
57
  requirement: !ruby/object:Gem::Requirement
@@ -122,34 +80,6 @@ dependencies:
122
80
  - - "~>"
123
81
  - !ruby/object:Gem::Version
124
82
  version: 1.3.2
125
- - !ruby/object:Gem::Dependency
126
- name: tiny_tds
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '3.0'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '3.0'
139
- - !ruby/object:Gem::Dependency
140
- name: trino-client
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: '2.0'
146
- type: :runtime
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: '2.0'
153
83
  - !ruby/object:Gem::Dependency
154
84
  name: tty-prompt
155
85
  requirement: !ruby/object:Gem::Requirement
@@ -279,6 +209,7 @@ files:
279
209
  - lib/strata/cli/utils/git.rb
280
210
  - lib/strata/cli/utils/import_manager.rb
281
211
  - lib/strata/cli/utils/test_reporter.rb
212
+ - lib/strata/cli/utils/version_checker.rb
282
213
  - lib/strata/cli/utils/yaml_import_resolver.rb
283
214
  - lib/strata/cli/version.rb
284
215
  - sig/strata/cli.rbs