Class: Exwiw::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/exwiw/cli.rb

Constant Summary collapse

KNOWN_SUBCOMMANDS =
%w[export explain].freeze
DEFAULT_CONFIG_PATHS =

Config file loaded automatically when --config is omitted, if one exists in the current directory. Kept at the project root (rather than under exwiw/) so that config-relative paths like schema_dir: exwiw/schema read naturally. Both extensions are accepted; .yml wins when both are present.

%w[exwiw.yml exwiw.yaml].freeze
ALLOWED_CONFIG_KEYS =

Keys accepted in the config file. Anything outside this set is rejected so a typo surfaces immediately instead of being silently ignored. These mirror the non-connection CLI options (plus adapter).

%w[
  adapter
  schema_dir
  output_dir
  output_format
  insert_only
  after_insert_hook
  log_level
  target_table
  target_collection
  ids
  ids_field
  scope_column
  parallel_workers
  explain_verbosity
].freeze
EXPLAIN_VERBOSITIES =

MongoDB explain verbosity levels (passed through to the server's explain command). queryPlanner only plans the query and is the safe default — the query is not executed; the other two run it to gather runtime stats.

%w[queryPlanner executionStats allPlansExecution].freeze
DEFAULT_EXPLAIN_VERBOSITY =
"queryPlanner"
REJECTED_CONNECTION_KEYS =

Database connection settings are environment-specific (and sometimes secret-adjacent), so they must be passed via CLI/env, never the committed config file. adapter is the one connection-ish key allowed in config.

%w[host port user database uri password].freeze
EXPORT_ONLY_CONFIG_KEYS =

Keys that only make sense for export. They are skipped when merging config for explain so a shared config file does not trip validate_explain_only!.

%w[output_dir output_format insert_only after_insert_hook parallel_workers].freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ CLI

Returns a new instance of CLI.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/exwiw/cli.rb', line 61

def initialize(argv)
  @argv = argv.dup

  @subcommand =
    if !@argv.empty? && !@argv.first.start_with?("-") && KNOWN_SUBCOMMANDS.include?(@argv.first)
      @argv.shift
    else
      "export"
    end

  @help = @argv.empty?

  @database_host = nil
  @database_port = nil
  @database_user = nil
  @database_password = ENV["DATABASE_PASSWORD"]
  @connection_uri = nil
  @output_dir = nil
  @schema_dir = nil
  @config_file_path = nil
  @database_adapter = nil
  @database_name = nil
  @target_table_name = nil
  @target_collection_name = nil
  @ids = []
  @ids_field = nil
  @scope_column = nil
  @output_format = nil
  @insert_only = nil
  @after_insert_hook_path = nil
  @parallel_workers = nil
  @explain_verbosity = nil
  # nil (not :info) so we can tell "user passed --log-level" from the default,
  # letting a config-file value fill in; the :info default is applied later.
  @log_level = nil

  parser.parse!(@argv)
end

Class Method Details

.start(argv) ⇒ Object



57
58
59
# File 'lib/exwiw/cli.rb', line 57

def self.start(argv)
  new(argv).run
end

Instance Method Details

#runObject



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/exwiw/cli.rb', line 100

def run
  if @help
    puts parser.help
    return
  end

  validate_options!

  connection_config = ConnectionConfig.new(
    adapter: @database_adapter,
    host: @database_host,
    port: @database_port,
    user: @database_user,
    password: @database_password,
    database_name: @database_name,
    uri: @connection_uri,
  )

  dump_target = DumpTarget.new(
    table_name: @target_table_name,
    ids: @ids,
    ids_field: @ids_field,
    scope_column: @scope_column,
  )

  logger = build_logger

  case @subcommand
  when "export"
    confirm_output_dir_clear!
    Runner.new(
      connection_config: connection_config,
      output_dir: @output_dir,
      schema_dir: @schema_dir,
      dump_target: dump_target,
      output_format: @output_format,
      insert_only: @insert_only,
      after_insert_hook_path: @after_insert_hook_path,
      parallel_workers: @parallel_workers,
      cli_options: build_cli_options_hash,
      logger: logger,
    ).run
  when "explain"
    ExplainRunner.new(
      connection_config: connection_config,
      schema_dir: @schema_dir,
      dump_target: dump_target,
      logger: logger,
      io: $stdout,
      explain_verbosity: @explain_verbosity,
    ).run
  end
end