strata-cli 0.1.2.beta → 0.1.4.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 +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +3 -28
- data/lib/strata/cli/ai/services/table_generator.rb +8 -4
- data/lib/strata/cli/configuration.rb +1 -2
- data/lib/strata/cli/generators/table.rb +5 -0
- data/lib/strata/cli/generators/templates/table.table_name.yml +6 -0
- data/lib/strata/cli/helpers/datasource_helper.rb +94 -1
- data/lib/strata/cli/helpers/project_helper.rb +28 -0
- data/lib/strata/cli/sub_commands/datasource.rb +5 -15
- data/lib/strata/cli/sub_commands/deploy.rb +42 -13
- data/lib/strata/cli/ui/field_editor.rb +4 -0
- data/lib/strata/cli/utils/deployment_monitor.rb +1 -1
- data/lib/strata/cli/version.rb +1 -1
- metadata +100 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2ea80c6d9e3c9d9db1f592e8fc07470b23fecafe6a31052aecd69b948f1bdec7
|
|
4
|
+
data.tar.gz: 57af64d1411a970716f5be79db6ac93b9c54b4f76c0f0dd1265a372ff1c28607
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b4de4eb2ce818ce0fe851b79f3fe0d82b2540257246638052c034506d605256bd98ca3cbe7a61dac0e4b240258f39bd6b4cadfeb3681a59038851d2257e68266
|
|
7
|
+
data.tar.gz: 9db418cf2a36236856cafda813885684ad3e9a558ab4bd44ce60f52d57a202f77124b69270b044fd940ef58d95db3f6edfdb9ca36efbaa078e073bc20f6cb68a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.1.4.beta] - 2026-02-26
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Table generator**: Support synonyms for fields in generated tables.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **Server configuration**: Refactored server config handling and improved `project.yml` persistence.
|
|
12
|
+
- **Datasource helper**: Read-only mode support for file-based databases.
|
|
13
|
+
|
|
14
|
+
## [0.1.3.beta] - 2026-01-28
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **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.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- **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.
|
|
23
|
+
- **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.
|
|
24
|
+
|
|
3
25
|
## [0.1.2.beta] - 2025-01-27
|
|
4
26
|
|
|
5
27
|
### 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
|
|
|
@@ -466,8 +440,9 @@ Release a new version:
|
|
|
466
440
|
|
|
467
441
|
1. Update version in `lib/strata/cli/version.rb`
|
|
468
442
|
2. Update `CHANGELOG.md` with the new version and changes
|
|
469
|
-
3. Commit
|
|
470
|
-
4. Run
|
|
443
|
+
3. Commit and merge to `master`: `git add lib/strata/cli/version.rb CHANGELOG.md && git commit -m "Bump version to X.Y.Z"` (then open a PR and merge)
|
|
444
|
+
4. **Via GitHub Actions (recommended):** In the repo go to **Actions → Release → Run workflow**, choose the branch (e.g. `master`), optionally enable "Build and test only" for a dry run, then **Run workflow**. Ensure the repo secret `RUBYGEMS_API_KEY` is set (RubyGems API key with push permission).
|
|
445
|
+
5. **Via console:** From a checkout of `master` after the version-bump merge, run `bundle exec rake release` (builds gem, creates git tag, pushes tag and gem to RubyGems).
|
|
471
446
|
|
|
472
447
|
## Contributing
|
|
473
448
|
|
|
@@ -20,6 +20,9 @@ module Strata
|
|
|
20
20
|
- schema_type: "dimension" for categorical/text, "measure" for numeric aggregations
|
|
21
21
|
- data_type: string, integer, bigint, decimal, date, date_time, boolean
|
|
22
22
|
- expression: SQL expression (for measures include aggregation like "sum(amount)")
|
|
23
|
+
- synonyms: Array of 2-4 alternative names users might use to refer to this field.
|
|
24
|
+
These help AI search and natural language queries find the right field.
|
|
25
|
+
Example: "Customer ID" → ["cust id", "client id", "buyer id"]
|
|
23
26
|
|
|
24
27
|
Output ONLY valid JSON array, no explanations.
|
|
25
28
|
PROMPT
|
|
@@ -120,8 +123,8 @@ module Strata
|
|
|
120
123
|
|
|
121
124
|
#{column_list}#{context_section}#{user_context_section}
|
|
122
125
|
|
|
123
|
-
Return JSON array with objects containing: name, description, schema_type, data_type, expression
|
|
124
|
-
Example: [{"name": "Order ID", "description": "Primary key", "schema_type": "dimension", "data_type": "bigint", "expression": "id"}]
|
|
126
|
+
Return JSON array with objects containing: name, description, schema_type, data_type, expression, synonyms
|
|
127
|
+
Example: [{"name": "Order ID", "description": "Primary key", "schema_type": "dimension", "data_type": "bigint", "expression": "id", "synonyms": ["order number", "order key"]}]
|
|
125
128
|
PROMPT
|
|
126
129
|
end
|
|
127
130
|
|
|
@@ -153,7 +156,7 @@ module Strata
|
|
|
153
156
|
#{column_list}#{context_section}
|
|
154
157
|
|
|
155
158
|
Based on the user's request, regenerate or modify the field definitions.
|
|
156
|
-
Return JSON array with objects containing: name, description, schema_type, data_type, expression
|
|
159
|
+
Return JSON array with objects containing: name, description, schema_type, data_type, expression, synonyms
|
|
157
160
|
PROMPT
|
|
158
161
|
end
|
|
159
162
|
|
|
@@ -207,7 +210,8 @@ module Strata
|
|
|
207
210
|
description: "",
|
|
208
211
|
schema_type: is_measure ? "measure" : "dimension",
|
|
209
212
|
data_type: map_data_type(type),
|
|
210
|
-
expression: is_measure ? "sum(#{name})" : name
|
|
213
|
+
expression: is_measure ? "sum(#{name})" : name,
|
|
214
|
+
synonyms: []
|
|
211
215
|
}
|
|
212
216
|
end
|
|
213
217
|
end
|
|
@@ -108,6 +108,11 @@ module Strata
|
|
|
108
108
|
"data_type" => normalized[:data_type]
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
synonyms = normalized[:synonyms]
|
|
112
|
+
if synonyms.is_a?(Array) && !synonyms.empty?
|
|
113
|
+
field_hash["synonyms"] = synonyms
|
|
114
|
+
end
|
|
115
|
+
|
|
111
116
|
# Build expression with proper nested format
|
|
112
117
|
expr = normalized[:expression]
|
|
113
118
|
field_hash["expression"] = {
|
|
@@ -96,6 +96,12 @@ fields:
|
|
|
96
96
|
# array: true|false (optional)
|
|
97
97
|
# sql: my_field_column (Required)
|
|
98
98
|
#
|
|
99
|
+
# # Optional: Alternative names for this field. Helps AI and search
|
|
100
|
+
# # find this field when users refer to it by different names.
|
|
101
|
+
# synonyms:
|
|
102
|
+
# - alt name one
|
|
103
|
+
# - alt name two
|
|
104
|
+
#
|
|
99
105
|
# # Optional: Exclude certain dimnesions from the group by/filter
|
|
100
106
|
# exclusion_type: exclude|exclude_all_except|exclude_all
|
|
101
107
|
# exclusions: # (Required when exclusion type is set and isnt exclude_all)
|
|
@@ -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,61 @@ module Strata
|
|
|
29
40
|
|
|
30
41
|
def create_adapter(ds_key)
|
|
31
42
|
config = ds_config(ds_key).merge(Credentials.fetch(ds_key))
|
|
32
|
-
|
|
43
|
+
adapter_sym = config["adapter"].to_sym
|
|
44
|
+
ensure_adapter_driver_gems!(adapter_sym)
|
|
45
|
+
|
|
46
|
+
# CLI only performs read operations (test, tables, metadata).
|
|
47
|
+
# Use read-only mode for file-based databases to avoid lock conflicts.
|
|
48
|
+
apply_readonly_mode(adapter_sym, config)
|
|
49
|
+
|
|
50
|
+
DWH.create(adapter_sym, config)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def apply_readonly_mode(adapter_sym, config)
|
|
54
|
+
case adapter_sym
|
|
55
|
+
when :duckdb
|
|
56
|
+
config["duck_config"] ||= {}
|
|
57
|
+
config["duck_config"]["access_mode"] = "READ_ONLY"
|
|
58
|
+
when :sqlite
|
|
59
|
+
config["readonly"] = true
|
|
60
|
+
end
|
|
61
|
+
# Client-server databases (postgres, mysql, snowflake, etc.)
|
|
62
|
+
# don't need special handling - no file lock issues
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def ensure_adapter_driver_gems!(adapter_sym)
|
|
66
|
+
required = ADAPTER_DRIVER_GEMS.fetch(adapter_sym, [])
|
|
67
|
+
return if required.empty?
|
|
68
|
+
|
|
69
|
+
missing = required.reject { gem_installed?(it) }
|
|
70
|
+
return if missing.empty?
|
|
71
|
+
|
|
72
|
+
if respond_to?(:say)
|
|
73
|
+
say "Required gem(s) for '#{adapter_sym}' not found (#{missing.join(", ")}). Attempting to install...",
|
|
74
|
+
:yellow
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
missing.each do |gem_name|
|
|
78
|
+
system("gem", "install", gem_name, "-q", "--no-document")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
still_missing = missing.reject { gem_installed?(it) }
|
|
82
|
+
return if still_missing.empty?
|
|
83
|
+
|
|
84
|
+
details = adapter_driver_gem_help(adapter_sym, still_missing)
|
|
85
|
+
|
|
86
|
+
msg = <<~MSG
|
|
87
|
+
Missing required gem(s) for adapter '#{adapter_sym}': #{still_missing.join(", ")}
|
|
88
|
+
|
|
89
|
+
This adapter can't be used until the driver gem(s) are installed.
|
|
90
|
+
|
|
91
|
+
Install manually:
|
|
92
|
+
|
|
93
|
+
gem install #{still_missing.join(" ")}
|
|
94
|
+
|
|
95
|
+
#{details}
|
|
96
|
+
MSG
|
|
97
|
+
raise Strata::CommandError, msg
|
|
33
98
|
end
|
|
34
99
|
|
|
35
100
|
def ds_config(ds_key)
|
|
@@ -57,6 +122,34 @@ module Strata
|
|
|
57
122
|
{}
|
|
58
123
|
end
|
|
59
124
|
end
|
|
125
|
+
|
|
126
|
+
def gem_installed?(name)
|
|
127
|
+
Gem::Specification.find_by_name(name)
|
|
128
|
+
true
|
|
129
|
+
rescue Gem::MissingSpecError
|
|
130
|
+
false
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def adapter_driver_gem_help(adapter_sym, missing)
|
|
134
|
+
case adapter_sym
|
|
135
|
+
when :postgres, :redshift
|
|
136
|
+
"Notes:\n- 'pg' requires PostgreSQL client libraries (libpq) installed on your system. See https://www.postgresql.org/download/"
|
|
137
|
+
when :mysql
|
|
138
|
+
"Notes:\n- 'mysql2' requires MySQL client libraries installed on your system. See https://dev.mysql.com/downloads/"
|
|
139
|
+
when :sqlserver
|
|
140
|
+
"Notes:\n- 'tiny_tds' requires FreeTDS and (often) OpenSSL installed on your system. See https://www.freetds.org/"
|
|
141
|
+
when :sqlite
|
|
142
|
+
"Notes:\n- 'sqlite3' requires SQLite development libraries installed on your system."
|
|
143
|
+
when :athena
|
|
144
|
+
"Notes:\n- AWS SDK gems are pure Ruby; no system libraries required."
|
|
145
|
+
when :trino
|
|
146
|
+
"Notes:\n- 'trino-client' is pure Ruby; no system libraries required."
|
|
147
|
+
when :duckdb
|
|
148
|
+
"Notes:\n- See https://github.com/suketa/ruby-duckdb"
|
|
149
|
+
else
|
|
150
|
+
"Notes:\n- Install missing gems: #{missing.join(", ")}"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
60
153
|
end
|
|
61
154
|
end
|
|
62
155
|
end
|
|
@@ -46,6 +46,34 @@ module Strata
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
# Persists server URL to project.yml (updates existing or appends)
|
|
50
|
+
def persist_server_to_project_yml(server, project_yml_path: "project.yml")
|
|
51
|
+
return false unless server && !server.to_s.strip.empty?
|
|
52
|
+
return false unless File.exist?(project_yml_path)
|
|
53
|
+
|
|
54
|
+
project_yml_content = File.read(project_yml_path)
|
|
55
|
+
|
|
56
|
+
begin
|
|
57
|
+
if /^server:\s*.+$/m.match?(project_yml_content)
|
|
58
|
+
updated_content = project_yml_content.gsub(/^(\s*)server:\s*.+$/, "\\1server: #{server}")
|
|
59
|
+
File.write(project_yml_path, updated_content)
|
|
60
|
+
else
|
|
61
|
+
File.open(project_yml_path, "a") do |f|
|
|
62
|
+
f.puts "\n" unless project_yml_content.end_with?("\n")
|
|
63
|
+
f.puts "server: #{server}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
true
|
|
68
|
+
rescue Errno::EACCES => e
|
|
69
|
+
raise Strata::CommandError, "Permission denied writing to #{project_yml_path}: #{e.message}"
|
|
70
|
+
rescue Errno::ENOSPC => e
|
|
71
|
+
raise Strata::CommandError, "Disk full: #{e.message}"
|
|
72
|
+
rescue => e
|
|
73
|
+
raise Strata::CommandError, "Failed to write to #{project_yml_path}: #{e.message}"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
49
77
|
# Persists git URL to project.yml file if missing
|
|
50
78
|
def persist_git_url_if_missing(project_yml_path: "project.yml")
|
|
51
79
|
return false unless File.exist?(project_yml_path)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require_relative "../guard"
|
|
2
2
|
require_relative "../credentials"
|
|
3
3
|
require_relative "../terminal"
|
|
4
|
+
require_relative "../utils/git"
|
|
4
5
|
require "tty-prompt"
|
|
5
6
|
require_relative "../helpers/datasource_helper"
|
|
6
7
|
require_relative "../helpers/description_helper"
|
|
@@ -15,18 +16,6 @@ module Strata
|
|
|
15
16
|
include DatasourceHelper
|
|
16
17
|
extend Helpers::DescriptionHelper
|
|
17
18
|
|
|
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
19
|
desc "adapters", "Lists supported data warehouse adapters"
|
|
31
20
|
def adapters
|
|
32
21
|
say "\n\tSupported Adapters\n\n", :yellow
|
|
@@ -247,10 +236,9 @@ module Strata
|
|
|
247
236
|
private
|
|
248
237
|
|
|
249
238
|
def adapter_gem_status
|
|
250
|
-
|
|
251
|
-
gems = gem_spec.split(/,\s*/)
|
|
239
|
+
DatasourceHelper::ADAPTER_DRIVER_GEMS.to_h do |adapter, gems|
|
|
252
240
|
installed = gems.all? { |g| gem_installed?(g) }
|
|
253
|
-
[adapter, {gem:
|
|
241
|
+
[adapter, {gem: gems.join(", "), installed: installed}]
|
|
254
242
|
end
|
|
255
243
|
end
|
|
256
244
|
|
|
@@ -382,6 +370,8 @@ module Strata
|
|
|
382
370
|
strata_file = Configuration::STRATA_CONFIG_FILE
|
|
383
371
|
File.chmod(0o600, strata_file) if File.exist?(strata_file)
|
|
384
372
|
|
|
373
|
+
Utils::Git.commit_file(Configuration::STRATA_CONFIG_FILE, "[Strata-CLI] Add AI config to .strata", Dir.pwd) if Utils::Git.git_repo?
|
|
374
|
+
|
|
385
375
|
say "\n✔ AI configured with #{provider}", :green
|
|
386
376
|
say " Note: API key is stored securely in .strata (not committed to repo)", :cyan
|
|
387
377
|
end
|
|
@@ -122,7 +122,7 @@ module Strata
|
|
|
122
122
|
|
|
123
123
|
def validate_deployment_configuration(config)
|
|
124
124
|
ensure_api_key(config)
|
|
125
|
-
|
|
125
|
+
ensure_server(config)
|
|
126
126
|
ensure_git_url_populated
|
|
127
127
|
ensure_project_id(config)
|
|
128
128
|
end
|
|
@@ -133,14 +133,36 @@ module Strata
|
|
|
133
133
|
config["api_key"] = collect_api_key_interactively
|
|
134
134
|
end
|
|
135
135
|
|
|
136
|
-
def
|
|
137
|
-
|
|
138
|
-
return if server_url && !server_url.to_s.strip.empty?
|
|
136
|
+
def ensure_server(config)
|
|
137
|
+
return if config["server"] && !config["server"].to_s.strip.empty?
|
|
139
138
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
139
|
+
config["server"] = collect_server_interactively
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def collect_server_interactively
|
|
143
|
+
prompt = TTY::Prompt.new
|
|
144
|
+
|
|
145
|
+
say "\nServer URL not found (not in project.yml)", :yellow
|
|
146
|
+
say "You can add it to project.yml or enter it now here\n", :cyan
|
|
147
|
+
|
|
148
|
+
server = prompt.ask("Enter Strata server URL:") do |q|
|
|
149
|
+
q.required true
|
|
150
|
+
q.validate(/\S+/, "Server URL cannot be empty")
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
server = server.strip.sub(%r{/\z}, "") # normalize: remove trailing slash
|
|
154
|
+
|
|
155
|
+
with_spinner("Saving server URL to project.yml") do
|
|
156
|
+
save_server_to_project_yml(server)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
server
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def save_server_to_project_yml(server)
|
|
163
|
+
Helpers::ProjectHelper.persist_server_to_project_yml(server, project_yml_path: File.join(project_path, Configuration::PROJECT_CONFIG_FILE))
|
|
164
|
+
CLI.config.reload!
|
|
165
|
+
Utils::Git.commit_file(Configuration::PROJECT_CONFIG_FILE, "[Strata-CLI] Add server URL to project.yml", project_path) if Utils::Git.git_repo?
|
|
144
166
|
end
|
|
145
167
|
|
|
146
168
|
def ensure_git_url_populated
|
|
@@ -182,37 +204,43 @@ module Strata
|
|
|
182
204
|
save_api_key_to_strata(api_key)
|
|
183
205
|
end
|
|
184
206
|
|
|
207
|
+
Utils::Git.commit_file(Configuration::STRATA_CONFIG_FILE, "[Strata-CLI] Save API key to .strata", project_path) if Utils::Git.git_repo?
|
|
208
|
+
|
|
185
209
|
api_key
|
|
186
210
|
end
|
|
187
211
|
|
|
188
212
|
def save_api_key_to_strata(api_key)
|
|
213
|
+
save_key_to_strata("api_key", api_key)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def save_key_to_strata(key, value)
|
|
189
217
|
strata_file = Configuration::STRATA_CONFIG_FILE
|
|
190
218
|
|
|
191
219
|
# Read existing content if file exists
|
|
192
220
|
existing_content = File.exist?(strata_file) ? File.read(strata_file) : ""
|
|
193
221
|
|
|
194
222
|
begin
|
|
195
|
-
if
|
|
196
|
-
updated_content = existing_content.gsub(/^(\s*)
|
|
223
|
+
if /^#{Regexp.escape(key)}:\s*.+$/m.match?(existing_content)
|
|
224
|
+
updated_content = existing_content.gsub(/^(\s*)#{Regexp.escape(key)}:\s*.+$/, "\\1#{key}: #{value}")
|
|
197
225
|
File.write(strata_file, updated_content)
|
|
198
226
|
else
|
|
199
227
|
File.open(strata_file, "a") do |f|
|
|
200
228
|
f.puts "\n" unless existing_content.empty? || existing_content.end_with?("\n")
|
|
201
|
-
f.puts "
|
|
229
|
+
f.puts "#{key}: #{value}"
|
|
202
230
|
end
|
|
203
231
|
end
|
|
204
232
|
|
|
205
233
|
# Set restrictive permissions (read/write for owner only)
|
|
206
234
|
File.chmod(0o600, strata_file) if File.exist?(strata_file)
|
|
207
235
|
|
|
208
|
-
# Reload config to pick up the new
|
|
236
|
+
# Reload config to pick up the new value
|
|
209
237
|
CLI.config.reload!
|
|
210
238
|
rescue Errno::EACCES => e
|
|
211
239
|
raise Strata::CommandError, "Permission denied writing to #{strata_file}: #{e.message}"
|
|
212
240
|
rescue Errno::ENOSPC => e
|
|
213
241
|
raise Strata::CommandError, "Disk full: #{e.message}"
|
|
214
242
|
rescue => e
|
|
215
|
-
raise Strata::CommandError, "Failed to write
|
|
243
|
+
raise Strata::CommandError, "Failed to write #{key} to #{strata_file}: #{e.message}"
|
|
216
244
|
end
|
|
217
245
|
end
|
|
218
246
|
|
|
@@ -405,6 +433,7 @@ module Strata
|
|
|
405
433
|
with_spinner("Persisting project ID to project.yml") do
|
|
406
434
|
Helpers::ProjectHelper.persist_project_id_to_yml(project_id)
|
|
407
435
|
end
|
|
436
|
+
Utils::Git.commit_file(Configuration::PROJECT_CONFIG_FILE, "[Strata-CLI] Persist project ID to project.yml", project_path) if Utils::Git.git_repo?
|
|
408
437
|
end
|
|
409
438
|
|
|
410
439
|
def refresh_external_imports
|
|
@@ -143,6 +143,10 @@ module Strata
|
|
|
143
143
|
return if field[:expression] == "back"
|
|
144
144
|
|
|
145
145
|
field[:schema_type] = prompt.select(" Type:", %w[dimension measure], default: field[:schema_type])
|
|
146
|
+
|
|
147
|
+
current_synonyms = (field[:synonyms] || []).join(", ")
|
|
148
|
+
synonyms_input = prompt.ask(" Synonyms (comma-separated):", default: current_synonyms)
|
|
149
|
+
field[:synonyms] = synonyms_input.to_s.split(",").map(&:strip).reject(&:empty?)
|
|
146
150
|
rescue TTY::Reader::InputInterrupt
|
|
147
151
|
# User pressed Ctrl+C, go back without saving
|
|
148
152
|
nil
|
|
@@ -127,7 +127,7 @@ module Strata
|
|
|
127
127
|
rescue Interrupt
|
|
128
128
|
stop_all_spinners
|
|
129
129
|
say "\n\n Monitoring interrupted. Deployment continues in background.", ColorHelper.warning
|
|
130
|
-
say "
|
|
130
|
+
say " Check server for deployment status with command `strata deploy status`.\n", ColorHelper.info
|
|
131
131
|
nil
|
|
132
132
|
rescue => e
|
|
133
133
|
stop_all_spinners
|
data/lib/strata/cli/version.rb
CHANGED
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.
|
|
4
|
+
version: 0.1.4.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
|
|
@@ -232,7 +330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
232
330
|
- !ruby/object:Gem::Version
|
|
233
331
|
version: '0'
|
|
234
332
|
requirements: []
|
|
235
|
-
rubygems_version: 3.6.
|
|
333
|
+
rubygems_version: 3.6.7
|
|
236
334
|
specification_version: 4
|
|
237
335
|
summary: Command-line interface for the Strata Semantic Analytics System
|
|
238
336
|
test_files: []
|