Class: Kotoshu::Cli::Cli

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

Overview

Command-line interface for Kotoshu spell checker.

Two-stage model:

Stage 1 (slow, network): `kotoshu setup LANG` downloads/registers resources
Stage 2 (instant, cache-only): `kotoshu check FILE` uses cached resources

Exit codes:

0 — no errors found / setup succeeded
1 — spelling errors found
2 — usage error (file not found, bad flags)
3 — resource not set up / setup failure (network, integrity)

Commands raise Errors::CliError subclasses; the dispatcher in .start catches them and exits with the error's exit_status.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


302
303
304
# File 'lib/kotoshu/cli.rb', line 302

def self.exit_on_failure?
  false
end

.start(given_args = ARGV, config = {}) ⇒ Object

Dispatch entry point — bypasses Thor's start rescue so we can honor exit_status from Errors::CliError subclasses. Thor::Error still falls back to exit 1 for framework-level errors (bad flags, etc.).

ResourceNotSetupError from the strict two-stage model is intercepted here: AutoSetup asks the user once, then we retry the dispatch. In non-TTY or offline mode AutoSetup re-raises so scripts see stable behavior.



287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/kotoshu/cli.rb', line 287

def self.start(given_args = ARGV, config = {})
  config[:shell] ||= Thor::Base.shell.new
  dispatch(nil, given_args.dup, nil, config)
rescue Kotoshu::ResourceNotSetupError => e
  raise Errors::ResourceUnavailable, e.message unless AutoSetup.new.call(e)

  retry
rescue Errors::CliError => e
  warn "Error: #{e.message}"
  exit e.exit_status
rescue Thor::Error => e
  warn e.message
  exit 1
end

Instance Method Details

#check(target = nil) ⇒ Object



120
121
122
123
124
125
126
127
128
# File 'lib/kotoshu/cli.rb', line 120

def check(target = nil)
  apply_configuration!

  text, source = read_target(target)
  result = run_check(text)
  display_result(result, source)
  interactive_review(result, source) if options[:interactive] && result.failed?
  exit 1 if result.failed?
end

#fetch(*languages) ⇒ Object



234
235
236
# File 'lib/kotoshu/cli.rb', line 234

def fetch(*languages)
  setup(*languages)
end

#setup(*languages) ⇒ Object



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/kotoshu/cli.rb', line 176

def setup(*languages)
  apply_configuration!

  if options[:list] || languages.empty?
    list_setup
    return
  end

  want = (options[:want] || "spelling").split(",").map(&:strip).map(&:to_sym)
  opts = setup_source_options(languages)
  opts[:want] = want
  opts[:force] = options[:force]
  opts[:strict] = options[:strict]

  results = languages.map do |lang|
    print "Setup #{lang}... "
    begin
      result = with_progress_reporter(label: lang) do
        Kotoshu.setup(lang, **opts)
      end
      describe_setup_result(result)
      { lang: lang, ok: true }
    rescue Kotoshu::Error, ArgumentError => e
      puts "FAIL: #{e.message}"
      { lang: lang, ok: false }
    end
  end

  failed = results.reject { |r| r[:ok] }
  puts "Set up #{results.size} language(s)."
  return if failed.empty?

  raise Errors::ResourceUnavailable,
        "failed to set up: #{failed.map { |r| r[:lang] }.join(', ')}"
end

#statusObject



262
263
264
265
266
267
268
269
# File 'lib/kotoshu/cli.rb', line 262

def status
  report = StatusReport.build(version: Kotoshu::VERSION)
  if options[:json]
    puts status_json(report)
  else
    puts status_text(report)
  end
end

#versionObject



272
273
274
275
# File 'lib/kotoshu/cli.rb', line 272

def version
  puts "Kotoshu version #{Kotoshu::VERSION}"
  puts "Ruby #{RUBY_VERSION}"
end