Class: Rake::GemMaintenance::UpgradeTask

Inherits:
TaskLib
  • Object
show all
Defined in:
lib/rake/gem/maintenance/upgrade_task.rb

Overview

Defines Rake tasks for upgrading gem dependencies and publishing to multiple repositories.

Creates: upgrade, upgrade:auto, upgrade:branch, upgrade:gems, upgrade:commit, upgrade:prepare_version, upgrade:push rubocop:disable Metrics/ClassLength, Metrics/MethodLength

Direct Known Subclasses

DualUpgradeTask, InternalUpgradeTask

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = :upgrade) {|_self| ... } ⇒ UpgradeTask

Returns a new instance of UpgradeTask.

Yields:

  • (_self)

Yield Parameters:



23
24
25
26
27
28
29
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 23

def initialize(name = :upgrade)
  super()
  apply_default_configuration(name)

  yield self if block_given?
  define_tasks
end

Instance Attribute Details

#auto_pipelineObject

Returns the value of attribute auto_pipeline.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def auto_pipeline
  @auto_pipeline
end

#commit_messageObject

Returns the value of attribute commit_message.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def commit_message
  @commit_message
end

#files_to_commitObject

Returns the value of attribute files_to_commit.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def files_to_commit
  @files_to_commit
end

#gem_nameObject

Returns the value of attribute gem_name.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def gem_name
  @gem_name
end

#gem_publisher_classObject

Returns the value of attribute gem_publisher_class.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def gem_publisher_class
  @gem_publisher_class
end

#gem_repositoriesObject

Returns the value of attribute gem_repositories.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def gem_repositories
  @gem_repositories
end

#gem_versionObject

Returns the value of attribute gem_version.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def gem_version
  @gem_version
end

#main_branchObject

Returns the value of attribute main_branch.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def main_branch
  @main_branch
end

#nameObject

Returns the value of attribute name.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def name
  @name
end

#release_taskObject

Returns the value of attribute release_task.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def release_task
  @release_task
end

#run_bundle_auditObject

Returns the value of attribute run_bundle_audit.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def run_bundle_audit
  @run_bundle_audit
end

#update_gemsObject

Returns the value of attribute update_gems.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def update_gems
  @update_gems
end

#update_rubygemsObject

Returns the value of attribute update_rubygems.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def update_rubygems
  @update_rubygems
end

#upgrade_branchObject

Returns the value of attribute upgrade_branch.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def upgrade_branch
  @upgrade_branch
end

#verification_taskObject

Returns the value of attribute verification_task.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def verification_task
  @verification_task
end

#version_bump_taskObject

Returns the value of attribute version_bump_task.



17
18
19
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 17

def version_bump_task
  @version_bump_task
end

Instance Method Details

#apply_default_configuration(name) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 31

def apply_default_configuration(name)
  @name = name
  @main_branch = "main"
  @upgrade_branch = "upgrade/gems"
  @commit_message = "chore(deps): upgrade gems"
  @files_to_commit = %w[Gemfile Gemfile.lock]
  @verification_task = :verify
  @release_task = :release
  @version_bump_task = "version:bump"
  @update_rubygems = true
  @update_gems = true
  @run_bundle_audit = true
  @auto_pipeline = nil
  @gem_repositories = Repos.rubygems
  @gem_publisher_class = GemPublisher
  @gem_name = detect_gem_name
  @gem_version = detect_gem_version
end

#check_version_on_repositoriesObject

rubocop:disable Metrics/AbcSize



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 220

def check_version_on_repositories
  unless gem_name && gem_version
    puts "[ERROR] No gemspec found - cannot check version/upgrade"
    abort
  end

  publisher = gem_publisher_class.new(gem_repositories)
  gemspec_repos = gem_repositories.select { |repo| repo_available?(repo) }

  if gemspec_repos.empty?
    puts "[ERROR] No repositories available. Cannot check version."
    abort
  end

  publisher.check_all_repositories(gem_name)

  print_failed_repository_warnings(publisher)
  version = gem_version
  next_ver = publisher.next_version(gem_name, version)

  if next_ver == version
    puts "[INFO] Version #{version} not found on any repository - will publish"
  else
    puts "[INFO] Version #{version} already published to all repositories"
    puts "[INFO] Next available version: #{next_ver}"
  end

  handle_partial_publish_warning(publisher, version)
end

#commit_changesObject



210
211
212
213
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 210

def commit_changes
  sh "git add #{files_to_commit.join(' ')}"
  sh "git commit -m '#{commit_message}'"
end

#create_upgrade_branchObject



195
196
197
198
199
200
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 195

def create_upgrade_branch
  sh "git checkout #{main_branch}"
  sh "git pull"
  sh "git branch -D #{upgrade_branch}" unless `git branch --list #{upgrade_branch}`.chomp.empty?
  sh "git checkout -b #{upgrade_branch}"
end

#define_auto_taskObject



149
150
151
152
153
154
155
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 149

def define_auto_task
  task_instance = self
  namespace name do
    desc "Update gems automatically (branch to push and release)"
    task auto: task_instance.send(:pipeline_tasks)
  end
end

#define_branch_taskObject



157
158
159
160
161
162
163
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 157

def define_branch_task
  task_instance = self
  namespace name do
    desc "Create a branch for the upgrade"
    task(:branch) { task_instance.send(:create_upgrade_branch) }
  end
end

#define_commit_taskObject



173
174
175
176
177
178
179
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 173

def define_commit_task
  task_instance = self
  namespace name do
    desc "Commit the upgrade branch"
    task(:commit) { task_instance.send(:commit_changes) }
  end
end

#define_gems_taskObject



165
166
167
168
169
170
171
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 165

def define_gems_task
  task_instance = self
  namespace name do
    desc "Upgrade gems, including bundler and gem"
    task(:gems) { task_instance.send(:do_upgrade_gems) }
  end
end

#define_info_name_task(task_instance) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 126

def define_info_name_task(task_instance)
  desc "Show current gem name"
  task :name do
    name = task_instance.gem_name || "unknown"
    puts "Gem name: #{name}"
  end
end

#define_info_repos_task(task_instance) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 105

def define_info_repos_task(task_instance)
  desc "Show configured gem repositories"
  task :repos do
    puts "Gem repositories:"
    task_instance.gem_repositories.each do |repo|
      available = task_instance.send(:repo_available?, repo)
      status = available ? "" : ""
      avail_text = available ? "AVAILABLE" : "NOT AVAILABLE"
      puts "  - #{repo[:name]} (#{status}) - #{avail_text}: #{repo[:url]}"
    end
  end
end

#define_info_tasksObject



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 90

def define_info_tasks
  task_instance = self
  namespace name do
    namespace :info do
      define_info_repos_task(task_instance)
      define_info_version_task(task_instance)
      define_info_name_task(task_instance)
      desc "Show all upgrade info"
      task all: %i[name version repos]
    end
    desc "Show all upgrade info"
    task info: "#{name}:info:all"
  end
end

#define_info_version_task(task_instance) ⇒ Object



118
119
120
121
122
123
124
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 118

def define_info_version_task(task_instance)
  desc "Show current gem version"
  task :version do
    ver = task_instance.gem_version || "unknown"
    puts "Current version: #{ver}"
  end
end

#define_prepare_version_taskObject



139
140
141
142
143
144
145
146
147
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 139

def define_prepare_version_task
  task_instance = self
  namespace name do
    desc "Check version on all repositories before bumping"
    task :prepare_version do
      task_instance.send(:check_version_on_repositories)
    end
  end
end

#define_push_taskObject



181
182
183
184
185
186
187
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 181

def define_push_task
  task_instance = self
  namespace name do
    desc "Push the upgrade"
    task(:push) { task_instance.send(:push_branch) }
  end
end

#define_tasksObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 79

def define_tasks
  define_top_level_task
  define_info_tasks
  define_prepare_version_task
  define_auto_task
  define_branch_task
  define_gems_task
  define_commit_task
  define_push_task
end

#define_top_level_taskObject



134
135
136
137
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 134

def define_top_level_task
  desc "Alias for #{name}:auto"
  task name => "#{name}:auto"
end

#do_upgrade_gemsObject



202
203
204
205
206
207
208
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 202

def do_upgrade_gems
  sh "gem update --system" if update_rubygems
  sh "gem update" if update_gems
  sh "bundle update --bundler"
  sh "bundle update --all"
  sh "bundle audit" if run_bundle_audit
end

#handle_partial_publish_warning(publisher, version) ⇒ Object

rubocop:enable Metrics/AbcSize



251
252
253
254
255
256
257
258
259
260
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 251

def handle_partial_publish_warning(publisher, version)
  return if publisher.successful_repos.empty?

  published = publisher.successful_repos
  total = gem_repositories.size
  return unless published.size < total

  puts "[WARN] Version #{version} was only published to #{published.size} of #{total} repositories"
  puts "[WARN] Run 'rake upgrade:prepare_version' manually to check status"
end

#pipeline_tasksObject



189
190
191
192
193
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 189

def pipeline_tasks
  return auto_pipeline if auto_pipeline

  %i[branch gems] + [verification_task, :commit, version_bump_task.to_sym, :prepare_version, release_task, :push]
end


269
270
271
272
273
274
275
276
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 269

def print_failed_repository_warnings(publisher)
  return if publisher.failed_repositories.empty?

  puts "[WARN] The following repositories were unavailable:"
  publisher.failed_repositories.each do |repo_name|
    puts "  - #{repo_name}"
  end
end

#push_branchObject



215
216
217
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 215

def push_branch
  sh "git push origin #{upgrade_branch}"
end

#repos_available?(publisher) ⇒ Boolean

Returns:

  • (Boolean)


262
263
264
265
266
267
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 262

def repos_available?(publisher)
  return true if publisher.any_available?

  puts "[ERROR] No repositories available. Cannot check version."
  abort
end