Class: Gemchain::CLI

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

Constant Summary collapse

CONFIG_FILENAME =
"cascade.yml"

Instance Method Summary collapse

Instance Method Details

#checkObject



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/gemchain/cli.rb', line 10

def check
  workspace = load_workspace
  return unless workspace

  cascade = Cascade.new(workspace)
  result = cascade.check

  puts "\n๐Ÿ“Š Gem Ecosystem Status\n#{'=' * 50}"

  result[:gems].each do |info|
    dep_count = info[:dependent_count]
    icon = dep_count > 0 ? "โคท" : "  "
    puts "\n#{info[:name]} (#{info[:version]}) #{icon} #{dep_count} #{dep_count == 1 ? 'dependent' : 'dependents'}"

    info[:dependencies].each do |dep_name, constraint|
      puts "    #{dep_name} (#{constraint})"
    end
  end

  total = result[:gems].size
  puts "\n#{'โ”€' * 50}"
  puts "#{total} #{total == 1 ? 'gem' : 'gems'} in workspace\n\n"
end

#guard(gem_name = nil) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/gemchain/cli.rb', line 35

def guard(gem_name = nil)
  unless gem_name
    puts "Usage: gemchain guard GEM_NAME"
    puts "  e.g. gemchain guard ask-core"
    return
  end

  workspace = load_workspace
  return unless workspace

  cascade = Cascade.new(workspace)
  result = cascade.guard(gem_name)

  unless result
    puts "โœ– Gem '#{gem_name}' not found in workspace."
    return
  end

  gem = result[:gem]
  puts "\nโš   Pre-release Guard: #{gem.name} v#{gem.version}\n#{'=' * 50}"

  if result[:dependents].empty?
    puts "  No gems in the workspace depend on #{gem.name}."
    puts "  Safe to release without cascade."
  else
    puts "  #{result[:direct_dependents]} gem(s) directly depend on #{gem.name}:"
    result[:dependents].each do |dep|
      deps_str = dep.dependencies.map { |n, c| "#{n} #{c}" }.join(", ")
      puts "    โ€ข #{dep.name} (#{dep.version}) โ€” requires: #{deps_str}"
    end

    puts "\n  Before releasing #{gem.name}, make sure these gems still work:"
    result[:all_downstream].each do |g|
      puts "    โฌœ #{g.name} (#{g.version})"
    end

    puts "\n  Run: gemchain update #{gem_name} <new-version>"
    puts "  to cascade the update automatically."
  end
  puts
end


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/gemchain/cli.rb', line 133

def link
  workspace = load_workspace
  return unless workspace

  cascade = Cascade.new(workspace)
  content = cascade.link_content(workspace: Dir.pwd)

  puts "\n๐Ÿ”— Gemfile Local Path References\n#{'=' * 50}"
  puts
  puts content
  puts
  puts "Add the block above to each gem's Gemfile to use local copies"
  puts "during development instead of published versions."
  puts
end

#update(gem_name = nil, new_version = nil) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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
# File 'lib/gemchain/cli.rb', line 81

def update(gem_name = nil, new_version = nil)
  unless gem_name && new_version
    puts "Usage: gemchain update GEM_NAME NEW_VERSION"
    puts "  e.g. gemchain update ask-core 0.8.0"
    puts "  e.g. gemchain update ask-core 0.8.0 --dry-run"
    puts "  e.g. gemchain update ask-core 0.8.0 --test-only"
    return
  end

  dry_run = !!options[:"dry-run"]
  test_only = !!options[:"test-only"]
  workspace = load_workspace
  return unless workspace

  cascade = Cascade.new(workspace)
  plan = cascade.update(gem_name, new_version, dry_run: dry_run, test_only: test_only)

  unless plan[:success] != false
    puts "โœ– #{plan[:message]}"
    return
  end

  puts "\n๐Ÿ“‹ Cascade Plan for #{gem_name} โ†’ #{new_version}\n#{'=' * 50}"

  if dry_run
    puts "  (dry run โ€” no changes will be made)\n"
    render_steps(plan[:steps])
    puts "\n  โœ… Dry run complete. Run without --dry-run to execute."
  else
    executor = Executor.new(workspace: workspace, steps: plan[:steps],
                            yes: options[:yes], bump: workspace.config.bump)
    result = executor.run

    if result.success
      puts "\n  โœ… Released: #{result.released.join(', ')}" unless result.released.empty?
      puts "  โญ Skipped: #{result.skipped.join(', ')}" unless result.skipped.empty?
      if result.released.empty? && result.skipped.empty?
        puts "\n  No releases needed โ€” dependents verified."
      else
        puts "\n  Cascade complete."
      end
    else
      gem, message = result.failed.first
      puts "\n  โœ– Cascade stopped at #{gem}:"
      puts "     #{message}"
      puts "  Released so far: #{result.released.join(', ')}" unless result.released.empty?
    end
  end
  puts
end

#versionObject



150
151
152
# File 'lib/gemchain/cli.rb', line 150

def version
  puts "gemchain #{Gemchain::VERSION}"
end