strata-cli 0.1.4.beta → 0.1.5.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/lib/strata/cli/api/client.rb +4 -4
  4. data/lib/strata/cli/api/connection_error_handler.rb +1 -1
  5. data/lib/strata/cli/configuration.rb +3 -1
  6. data/lib/strata/cli/credentials.rb +2 -0
  7. data/lib/strata/cli/descriptions/create/migration.txt +10 -0
  8. data/lib/strata/cli/descriptions/create/relation.txt +6 -0
  9. data/lib/strata/cli/descriptions/create/table.txt +13 -0
  10. data/lib/strata/cli/descriptions/datasource/add.txt +6 -0
  11. data/lib/strata/cli/descriptions/datasource/meta.txt +5 -0
  12. data/lib/strata/cli/descriptions/datasource/tables.txt +6 -0
  13. data/lib/strata/cli/descriptions/datasource/test.txt +5 -0
  14. data/lib/strata/cli/descriptions/deploy/deploy.txt +13 -0
  15. data/lib/strata/cli/descriptions/deploy/status.txt +3 -0
  16. data/lib/strata/cli/descriptions/init.txt +6 -0
  17. data/lib/strata/cli/error_reporter.rb +70 -0
  18. data/lib/strata/cli/generators/datasource.rb +4 -1
  19. data/lib/strata/cli/generators/group.rb +14 -8
  20. data/lib/strata/cli/generators/migration.rb +1 -1
  21. data/lib/strata/cli/generators/project.rb +146 -130
  22. data/lib/strata/cli/generators/table.rb +1 -3
  23. data/lib/strata/cli/guard.rb +2 -0
  24. data/lib/strata/cli/helpers/command_context.rb +23 -4
  25. data/lib/strata/cli/helpers/datasource_helper.rb +17 -1
  26. data/lib/strata/cli/helpers/description_helper.rb +2 -0
  27. data/lib/strata/cli/helpers/prompts.rb +2 -0
  28. data/lib/strata/cli/main.rb +5 -1
  29. data/lib/strata/cli/sub_commands/audit.rb +19 -5
  30. data/lib/strata/cli/sub_commands/create.rb +41 -19
  31. data/lib/strata/cli/sub_commands/datasource.rb +9 -3
  32. data/lib/strata/cli/sub_commands/deploy.rb +40 -26
  33. data/lib/strata/cli/sub_commands/project.rb +4 -6
  34. data/lib/strata/cli/sub_commands/table.rb +1 -1
  35. data/lib/strata/cli/terminal.rb +2 -0
  36. data/lib/strata/cli/ui/autocomplete.rb +2 -0
  37. data/lib/strata/cli/ui/field_editor.rb +2 -0
  38. data/lib/strata/cli/utils/archive.rb +1 -3
  39. data/lib/strata/cli/utils/deployment_monitor.rb +26 -24
  40. data/lib/strata/cli/utils/git.rb +10 -7
  41. data/lib/strata/cli/utils/import_manager.rb +21 -23
  42. data/lib/strata/cli/utils/test_reporter.rb +16 -25
  43. data/lib/strata/cli/utils/version_checker.rb +4 -6
  44. data/lib/strata/cli/utils/yaml_import_resolver.rb +5 -2
  45. data/lib/strata/cli/utils.rb +2 -0
  46. data/lib/strata/cli/version.rb +1 -1
  47. data/lib/strata/cli.rb +8 -0
  48. metadata +29 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ea80c6d9e3c9d9db1f592e8fc07470b23fecafe6a31052aecd69b948f1bdec7
4
- data.tar.gz: 57af64d1411a970716f5be79db6ac93b9c54b4f76c0f0dd1265a372ff1c28607
3
+ metadata.gz: 5403cff806c306ec60ff5dedfe1a2dfc9a39ac27ff8613d2076dc2103b2b9a3b
4
+ data.tar.gz: e84bb6ada3d20b0120ce1d4ce73160d8c197151134c71ae69a42ef153581bc89
5
5
  SHA512:
6
- metadata.gz: b4de4eb2ce818ce0fe851b79f3fe0d82b2540257246638052c034506d605256bd98ca3cbe7a61dac0e4b240258f39bd6b4cadfeb3681a59038851d2257e68266
7
- data.tar.gz: 9db418cf2a36236856cafda813885684ad3e9a558ab4bd44ce60f52d57a202f77124b69270b044fd940ef58d95db3f6edfdb9ca36efbaa078e073bc20f6cb68a
6
+ metadata.gz: a92d6f909d5121689d9e075b7c9af688bc9814d567a4a98ad56ebd172fd155fef9e40890a6005f0e443716ba6f88717ac6ba836f492bc42620ccac49bc6d2c30
7
+ data.tar.gz: 9df769a491dd6fd6f9237f4f7fcab984828094c3d5cca121ede4ef6a919188db9e811bcebe1a1b2395b6cd41a092c1a5993ace231e340cae1faba14cc2681f8e
data/.rubocop.yml ADDED
@@ -0,0 +1,3 @@
1
+ inherit_gem:
2
+ standard: config/base.yml
3
+
@@ -125,10 +125,10 @@ module Strata
125
125
  # Check if it's an HTML error page (Rails error page)
126
126
  if body.is_a?(String) && body.include?("<!DOCTYPE html>")
127
127
  # Try to extract error message from HTML
128
- if body =~ /<h1[^>]*>(.*?)<\/h1>/
129
- return "Server error: #{$1.strip}"
130
- elsif body =~ /<title[^>]*>(.*?)<\/title>/
131
- return "Server error: #{$1.strip}"
128
+ if body =~ %r{<h1[^>]*>(.*?)</h1>}
129
+ return "Server error: #{::Regexp.last_match(1).strip}"
130
+ elsif body =~ %r{<title[^>]*>(.*?)</title>}
131
+ return "Server error: #{::Regexp.last_match(1).strip}"
132
132
  else
133
133
  return "Server returned an HTML error page. Check server logs for details."
134
134
  end
@@ -29,7 +29,7 @@ module Strata
29
29
 
30
30
  private
31
31
 
32
- def handle_connection_error(server_url, error, timeout: false)
32
+ def handle_connection_error(server_url, _error, timeout: false)
33
33
  server_display = server_url
34
34
 
35
35
  message = "\n"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
 
3
5
  module Strata
@@ -111,7 +113,7 @@ module Strata
111
113
  root_config
112
114
  end
113
115
 
114
- def is_environment_key?(key, value)
116
+ def is_environment_key?(_key, value)
115
117
  return false unless value.is_a?(Hash)
116
118
 
117
119
  value.key?("api_key") || value.key?("server")
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "yaml"
2
4
  require "tty-prompt"
3
5
 
@@ -1,25 +1,35 @@
1
1
  Create migration files for renaming or swapping entities in your Strata project.
2
2
 
3
3
  Migration subcommands:
4
+
4
5
  rename Create a migration to rename an entity (dimension, measure, table, datasource)
6
+
5
7
  swap Create a migration to swap entity references (dimension, measure, table)
6
8
 
7
9
  Options:
10
+
8
11
  -e, --entity TYPE Entity type: dimension, measure, table, or datasource (required)
12
+
9
13
  -f, --from NAME Current/source entity name (required)
14
+
10
15
  -t, --to NAME New/target entity name (required)
11
16
 
12
17
  Examples:
18
+
13
19
  # Rename a dimension
20
+
14
21
  strata create migration rename -e dimension -f old_name -t new_name
15
22
 
16
23
  # Rename a table
24
+
17
25
  strata create migration rename -e table -f old_table -t new_table
18
26
 
19
27
  # Swap two measures
28
+
20
29
  strata create migration swap -e measure -f measure_a -t measure_b
21
30
 
22
31
  # Rename a datasource
32
+
23
33
  strata create migration rename -e datasource -f old_ds -t new_ds
24
34
 
25
35
  Note: Swap operation does not support 'datasource' entity type.
@@ -1,14 +1,20 @@
1
1
  Create a relation YAML file for defining joins between tables.
2
2
 
3
3
  RELATION_PATH is the path where the relation file will be created.
4
+
4
5
  If RELATION_PATH contains a /, the file will be created at models/<RELATION_PATH>/rel.<last_part>.yml
6
+
5
7
  If RELATION_PATH has no /, the file will be created at models/rel.<RELATION_PATH>.yml
8
+
6
9
  The relation name is derived from the last part of the path.
7
10
 
8
11
  Examples:
12
+
9
13
  strata create relation customer/orders # Creates models/customer/rel.orders.yml
14
+
10
15
  strata create relation customer # Creates models/rel.customer.yml
11
16
 
12
17
  This will create a template relation file with examples and comments.
18
+
13
19
  You can then edit it to define your joins.
14
20
 
@@ -1,23 +1,36 @@
1
1
  Create a semantic table model from a datasource table.
2
2
 
3
3
  TABLE_PATH can be:
4
+
4
5
  - Simple: call_center
6
+
5
7
  - Nested: games/event_details
8
+
6
9
  - With schema: contact/dse.call_center_d
10
+
7
11
  - Deep nested: contact/help_center/visits
8
12
 
9
13
  Examples:
14
+
10
15
  strata create table call_center
16
+
11
17
  strata create table games/event_details
18
+
12
19
  strata create table contact/dse.call_center_d
20
+
13
21
  strata create table contact/help_center/visits
14
22
 
15
23
  If no argument is provided, you'll be prompted to search and select a table.
16
24
 
17
25
  The command will:
26
+
18
27
  1. Check if the table exists in the datasource
28
+
19
29
  2. Fetch column metadata from the database
30
+
20
31
  3. Analyze columns with AI to suggest field definitions
32
+
21
33
  4. Allow you to review and edit fields interactively
34
+
22
35
  5. Generate the model YAML file at models/<TABLE_PATH>/tbl.<table_name>.yml
23
36
 
@@ -1,15 +1,21 @@
1
1
  Add a new datasource interactively. This command will guide you through:
2
2
 
3
3
  1. Selecting a data warehouse adapter (PostgreSQL, MySQL, Snowflake, etc.)
4
+
4
5
  2. Configuring connection settings (host, port, database, etc.)
6
+
5
7
  3. Setting up authentication credentials
8
+
6
9
  4. Optionally configuring AI features for table generation
7
10
 
8
11
  ADAPTER is optional - if not provided, you'll be prompted to select one.
9
12
 
10
13
  Examples:
14
+
11
15
  strata datasource add # Interactive mode - select adapter
16
+
12
17
  strata datasource add postgres # Directly add PostgreSQL datasource
18
+
13
19
  strata datasource add snowflake # Directly add Snowflake datasource
14
20
 
15
21
  Supported adapters: postgres, mysql, sqlserver, snowflake, athena, trino, duckdb, druid
@@ -2,10 +2,15 @@ Show the schema/structure of a specific table in the datasource.
2
2
  Displays column names, data types, and other metadata.
3
3
 
4
4
  Options:
5
+
5
6
  -c, --catalog CATALOG Override catalog from datasource config
7
+
6
8
  -s, --schema SCHEMA Override schema from datasource config
7
9
 
8
10
  Examples:
11
+
9
12
  strata datasource meta my_db customers # Show customers table structure
13
+
10
14
  strata datasource meta my_db dbo.orders # Show orders table in dbo schema
15
+
11
16
  strata datasource meta my_db sales.customers -s sales # Explicitly specify schema
@@ -2,11 +2,17 @@ List all tables available in the specified datasource. If DS_KEY is not provided
2
2
  you'll be prompted to select from available datasources.
3
3
 
4
4
  Options:
5
+
5
6
  -p, --pattern PATTERN Filter tables by regex pattern
7
+
6
8
  -c, --catalog CATALOG Override catalog from datasource config
9
+
7
10
  -s, --schema SCHEMA Override schema from datasource config
8
11
 
9
12
  Examples:
13
+
10
14
  strata datasource tables my_db # List all tables
15
+
11
16
  strata datasource tables my_db -p user # List tables matching "user"
17
+
12
18
  strata datasource tables my_db -s dbo # List tables in "dbo" schema
@@ -1,8 +1,13 @@
1
1
  Test the connection to a datasource. This verifies that:
2
+
2
3
  - The datasource configuration is valid
4
+
3
5
  - Credentials are correct
6
+
4
7
  - The connection can be established
5
8
 
6
9
  Examples:
10
+
7
11
  strata datasource test my_db # Test connection to my_db datasource
12
+
8
13
  strata ds test postgres_db # Using alias
@@ -1,9 +1,13 @@
1
1
  Deploys your Strata project to the configured server. This command will:
2
2
 
3
3
  1. Run pre-deployment audit checks (unless --skip-audit is used)
4
+
4
5
  2. Check git repository status and ensure all changes are committed
6
+
5
7
  3. Create an archive of changed files since the last deployment
8
+
6
9
  4. Upload the archive to the Strata server
10
+
7
11
  5. Monitor deployment progress and display results
8
12
 
9
13
  The deployment includes all YAML files in your project (models, datasources, tests).
@@ -11,14 +15,23 @@ Only files that have changed since the last successful deployment are included,
11
15
  unless --force is used to deploy all files.
12
16
 
13
17
  Options:
18
+
14
19
  -e, --environment ENV Deploy to specific environment (dev, staging, prod)
20
+
15
21
  --skip-audit Skip pre-deployment audit checks
22
+
16
23
  --yes, -y Skip confirmation prompts (useful for CI/CD)
24
+
17
25
  -f, --force Force deploy even if no files have changed
18
26
 
19
27
  Examples:
28
+
20
29
  strata deploy # Deploy to default environment
30
+
21
31
  strata deploy -e production # Deploy to production environment
32
+
22
33
  strata deploy --skip-audit # Skip pre-deployment checks
34
+
23
35
  strata deploy --force # Force deploy even if no changes
36
+
24
37
  strata deploy --yes # Skip confirmation prompts
@@ -2,8 +2,11 @@ Displays the current deployment status for the active git branch.
2
2
  Shows deployment stage, status (succeeded/failed/in_progress), and test results if available.
3
3
 
4
4
  Options:
5
+
5
6
  -e, --environment ENV Check status for specific environment
6
7
 
7
8
  Examples:
9
+
8
10
  strata deploy status # Show status for current branch
11
+
9
12
  strata deploy status -e production # Show status for production environment
@@ -4,11 +4,17 @@ PROJECT_NAME is optional when using --source option. If provided, creates a new
4
4
  with that name. If using --source, clones the existing project from the URL.
5
5
 
6
6
  Options:
7
+
7
8
  -d, --datasource ADAPTER Add one or more datasource adapters (repeatable)
9
+
8
10
  -s, --source URL URL of existing project to clone
11
+
9
12
  -a, --api-key KEY API key (required when using --source)
10
13
 
11
14
  Examples:
15
+
12
16
  strata init my-project
17
+
13
18
  strata init my-project -d postgres -d snowflake
19
+
14
20
  strata init --source https://github.com/org/project.git --api-key YOUR_KEY
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "time"
5
+
6
+ module Strata
7
+ module CLI
8
+ module ErrorReporter
9
+ LOG_RELATIVE_PATH = ".strata_cli/logs/cli.log"
10
+
11
+ CONNECTION_ERROR_CLASS_NAMES = %w[
12
+ Faraday::ConnectionFailed
13
+ Faraday::TimeoutError
14
+ Errno::ECONNREFUSED
15
+ SocketError
16
+ Timeout::Error
17
+ Net::OpenTimeout
18
+ Net::ReadTimeout
19
+ ].freeze
20
+
21
+ module_function
22
+
23
+ def log_relative_path
24
+ LOG_RELATIVE_PATH
25
+ end
26
+
27
+ def connection_error?(error)
28
+ current_error = error
29
+
30
+ while current_error
31
+ return true if CONNECTION_ERROR_CLASS_NAMES.include?(current_error.class.name)
32
+
33
+ message = current_error.message.to_s.downcase
34
+ if message.include?("connection refused") || message.include?("failed to open tcp connection") || message.include?("timed out")
35
+ return true
36
+ end
37
+
38
+ current_error = current_error.cause
39
+ end
40
+
41
+ false
42
+ end
43
+
44
+ def user_message_for(error)
45
+ if connection_error?(error)
46
+ return "Connection failed while reaching datasource. Please check network and datasource settings."
47
+ end
48
+
49
+ msg = error.message.to_s.strip
50
+ return msg unless msg.empty?
51
+
52
+ "Unexpected error: #{error.class}"
53
+ end
54
+
55
+ def log_error(error, context: nil)
56
+ log_path = File.join(Dir.pwd, LOG_RELATIVE_PATH)
57
+ FileUtils.mkdir_p(File.dirname(log_path))
58
+
59
+ File.open(log_path, "a") do |f|
60
+ f.puts("[#{Time.now.utc.iso8601}] #{context || "Unhandled CLI error"}")
61
+ f.puts("#{error.class}: #{error.message}")
62
+ f.puts(error.backtrace.join("\n")) if error.backtrace
63
+ f.puts("")
64
+ end
65
+ rescue => e
66
+ warn "Failed to write CLI log: #{e.message}" if ENV["DEBUG"]
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "group"
2
4
  require "open3"
3
5
 
@@ -69,7 +71,8 @@ module Strata
69
71
  end
70
72
 
71
73
  def current_ds
72
- @ds ||= YAML.safe_load_file(pathify("datasources.yml"), permitted_classes: [Date, Time], aliases: true) || {}
74
+ @current_ds ||= YAML.safe_load_file(pathify("datasources.yml"), permitted_classes: [Date, Time],
75
+ aliases: true) || {}
73
76
  end
74
77
 
75
78
  def render_template(source, context: instance_eval("binding", __FILE__, __LINE__))
@@ -1,13 +1,19 @@
1
- module Strata::CLI::Generators
2
- class Group < Thor::Group
3
- include Thor::Actions
1
+ # frozen_string_literal: true
4
2
 
5
- def self.source_root
6
- File.expand_path("templates/", __dir__)
7
- end
3
+ module Strata
4
+ module CLI
5
+ module Generators
6
+ class Group < Thor::Group
7
+ include Thor::Actions
8
+
9
+ def self.source_root
10
+ File.expand_path("templates/", __dir__)
11
+ end
8
12
 
9
- def self.exit_on_failure?
10
- true
13
+ def self.exit_on_failure?
14
+ true
15
+ end
16
+ end
11
17
  end
12
18
  end
13
19
  end
@@ -50,7 +50,7 @@ module Strata
50
50
  Time.now.strftime("%Y%m%d%H%M%S")
51
51
  end
52
52
 
53
- def generate_filename(operation, entity, from, to, timestamp)
53
+ def generate_filename(operation, _entity, from, to, timestamp)
54
54
  # Generate descriptive name following server pattern: timestamp_descriptive_name.yml
55
55
  # Example: 20250101120000_rename_user_table.yml
56
56
  from_slug = slugify(from)