Class: CreateRubyGem::Wizard

Inherits:
Object
  • Object
show all
Defined in:
lib/create_ruby_gem/wizard.rb

Overview

Step-by-step interactive prompt loop for choosing bundle gem options.

Walks through each supported option in Options::Catalog::ORDER, presenting only the options supported by the detected Bundler version. Supports back-navigation via CtrlB+.

See Also:

  • CLI#run_interactive_wizard!

Constant Summary collapse

BACK =

Sentinel returned by the prompter when the user presses Ctrl+B.

Object.new.freeze
BUNDLER_DEFAULT =

Sentinel indicating the user wants Bundler’s built-in default.

Object.new.freeze
LABELS =

Human-readable labels for each option key.

Returns:

  • (Hash{Symbol => String})
{
  exe: 'Create executable',
  coc: 'Add CODE_OF_CONDUCT.md',
  changelog: 'Add CHANGELOG.md',
  ext: 'Native extension',
  git: 'Initialize git',
  github_username: 'GitHub username',
  mit: 'Include MIT license',
  test: 'Test framework',
  ci: 'CI provider',
  linter: 'Linter',
  edit: 'Editor command',
  bundle_install: 'Run bundle install'
}.freeze
HELP_TEXT =

Short explanations shown below each wizard step.

Returns:

  • (Hash{Symbol => String})
{
  exe: 'Adds an executable file in exe/ so users can run your gem as a command.',
  coc: 'Adds a code of conduct template for contributors.',
  changelog: 'Adds CHANGELOG.md to track release notes.',
  ext: 'Sets up native extension scaffolding for C, Go, or Rust.',
  git: 'Initializes a git repository for the new gem.',
  github_username: 'Used in links and metadata for your GitHub account.',
  mit: 'Adds the MIT license file.',
  test: 'Chooses which test framework files to generate.',
  ci: 'Chooses CI pipeline config to include.',
  linter: 'Chooses linting setup for style and quality checks.',
  edit: 'Sets your preferred command for opening files.',
  bundle_install: 'Runs bundle install after generating the gem.'
}.freeze
CHOICE_HELP =

Per-choice hints displayed next to enum/string choices.

Returns:

  • (Hash{Symbol => Hash{String => String}})
{
  ext: {
    'c' => 'classic native extension path',
    'go' => 'Go-based extension via FFI/tooling',
    'rust' => 'Rust extension path',
    'none' => 'no native extension'
  },
  test: {
    'minitest' => 'small built-in Ruby test style',
    'rspec' => 'popular behavior-style testing',
    'test-unit' => 'xUnit-style test framework',
    'none' => 'no test framework files'
  },
  ci: {
    'circle' => 'CircleCI config',
    'github' => 'GitHub Actions workflow',
    'gitlab' => 'GitLab CI pipeline',
    'none' => 'no CI config'
  },
  linter: {
    'rubocop' => 'full-featured Ruby linting',
    'standard' => 'zero-config style linting',
    'none' => 'no linter config'
  },
  github_username: {
    'set' => 'enter a value now',
    'none' => 'leave unset'
  },
  edit: {
    'set' => 'enter a value now',
    'none' => 'leave unset'
  }
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(compatibility_entry:, defaults:, prompter:, bundler_defaults: {}) ⇒ Wizard

Returns a new instance of Wizard.

Parameters:

  • compatibility_entry (Compatibility::Matrix::Entry)
  • defaults (Hash{Symbol => Object})

    initial default values (e.g. last-used)

  • prompter (UI::Prompter)
  • bundler_defaults (Hash{Symbol => Object}) (defaults to: {})

    Bundler’s own defaults



95
96
97
98
99
100
# File 'lib/create_ruby_gem/wizard.rb', line 95

def initialize(compatibility_entry:, defaults:, prompter:, bundler_defaults: {})
  @compatibility_entry = compatibility_entry
  @bundler_defaults = symbolize_keys(bundler_defaults)
  @prompter = prompter
  @values = sanitize_defaults(defaults)
end

Instance Method Details

#runHash{Symbol => Object}

Runs the wizard and returns the selected options.

Returns:

  • (Hash{Symbol => Object})


105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/create_ruby_gem/wizard.rb', line 105

def run
  keys = Options::Catalog::ORDER.select { |key| @compatibility_entry.supports_option?(key) }
  index = 0
  while index < keys.length
    key = keys[index]
    answer = ask_for(key, index:, total: keys.length)
    case answer
    when BACK
      index -= 1 if index.positive?
    else
      assign_value(key, answer)
      index += 1
    end
  end
  @values.dup
end