Class: Rake::Gem::Maintenance::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

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:



33
34
35
36
37
38
39
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 33

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.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def auto_pipeline
  @auto_pipeline
end

#commit_messageObject

Returns the value of attribute commit_message.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def commit_message
  @commit_message
end

#files_to_commitObject

Returns the value of attribute files_to_commit.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def files_to_commit
  @files_to_commit
end

#gem_nameObject

Returns the value of attribute gem_name.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def gem_name
  @gem_name
end

#gem_publisher_classObject

Returns the value of attribute gem_publisher_class.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def gem_publisher_class
  @gem_publisher_class
end

#gem_repositoriesObject

Returns the value of attribute gem_repositories.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def gem_repositories
  @gem_repositories
end

#gem_versionObject

Returns the value of attribute gem_version.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def gem_version
  @gem_version
end

#main_branchObject

Returns the value of attribute main_branch.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def main_branch
  @main_branch
end

#nameObject

Returns the value of attribute name.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def name
  @name
end

#release_taskObject

Returns the value of attribute release_task.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def release_task
  @release_task
end

#renew_api_key_task_classObject



29
30
31
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 29

def renew_api_key_task_class
  @renew_api_key_task_class || RenewApiKeyTask
end

#run_bundle_auditObject

Returns the value of attribute run_bundle_audit.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def run_bundle_audit
  @run_bundle_audit
end

#update_gemsObject

Returns the value of attribute update_gems.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def update_gems
  @update_gems
end

#update_rubygemsObject

Returns the value of attribute update_rubygems.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def update_rubygems
  @update_rubygems
end

#upgrade_branchObject

Returns the value of attribute upgrade_branch.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def upgrade_branch
  @upgrade_branch
end

#verification_taskObject

Returns the value of attribute verification_task.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def verification_task
  @verification_task
end

#version_bump_taskObject

Returns the value of attribute version_bump_task.



21
22
23
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 21

def version_bump_task
  @version_bump_task
end

Instance Method Details

#apply_default_configuration(name) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 41

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



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 236

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



226
227
228
229
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 226

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

#create_upgrade_branchObject



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

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



160
161
162
163
164
165
166
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 160

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



168
169
170
171
172
173
174
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 168

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



184
185
186
187
188
189
190
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 184

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



176
177
178
179
180
181
182
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 176

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



137
138
139
140
141
142
143
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 137

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



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

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



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 101

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



129
130
131
132
133
134
135
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 129

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



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

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



192
193
194
195
196
197
198
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 192

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

#define_renew_api_key_taskObject



200
201
202
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 200

def define_renew_api_key_task
  renew_api_key_task_class.new(name)
end

#define_tasksObject



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

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
  define_renew_api_key_task
end

#define_top_level_taskObject



145
146
147
148
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 145

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

#do_upgrade_gemsObject



218
219
220
221
222
223
224
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 218

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



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

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



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

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


285
286
287
288
289
290
291
292
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 285

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



231
232
233
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 231

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

#repos_available?(publisher) ⇒ Boolean

Returns:

  • (Boolean)


278
279
280
281
282
283
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 278

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

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