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

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:



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

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.



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

def auto_pipeline
  @auto_pipeline
end

#commit_messageObject

Returns the value of attribute commit_message.



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

def commit_message
  @commit_message
end

#files_to_commitObject

Returns the value of attribute files_to_commit.



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

def files_to_commit
  @files_to_commit
end

#gem_nameObject

Returns the value of attribute gem_name.



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

def gem_name
  @gem_name
end

#gem_publisher_classObject

Returns the value of attribute gem_publisher_class.



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

def gem_publisher_class
  @gem_publisher_class
end

#gem_repositoriesObject

Returns the value of attribute gem_repositories.



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

def gem_repositories
  @gem_repositories
end

#gem_versionObject

Returns the value of attribute gem_version.



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

def gem_version
  @gem_version
end

#main_branchObject

Returns the value of attribute main_branch.



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

def main_branch
  @main_branch
end

#nameObject

Returns the value of attribute name.



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

def name
  @name
end

#release_taskObject

Returns the value of attribute release_task.



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

def release_task
  @release_task
end

#renew_api_key_task_classObject



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

def renew_api_key_task_class
  @renew_api_key_task_class || RenewApiKeyTask
end

#run_bundle_auditObject

Returns the value of attribute run_bundle_audit.



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

def run_bundle_audit
  @run_bundle_audit
end

#update_gemsObject

Returns the value of attribute update_gems.



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

def update_gems
  @update_gems
end

#update_rubygemsObject

Returns the value of attribute update_rubygems.



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

def update_rubygems
  @update_rubygems
end

#upgrade_branchObject

Returns the value of attribute upgrade_branch.



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

def upgrade_branch
  @upgrade_branch
end

#verification_taskObject

Returns the value of attribute verification_task.



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

def verification_task
  @verification_task
end

#version_bump_taskObject

Returns the value of attribute version_bump_task.



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

def version_bump_task
  @version_bump_task
end

Instance Method Details

#apply_default_configuration(name) ⇒ Object



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

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



234
235
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
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 234

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



224
225
226
227
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 224

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

#create_upgrade_branchObject



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

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



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

def define_renew_api_key_task
  renew_api_key_task_class.new(name)
end

#define_tasksObject



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

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



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

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

#do_upgrade_gemsObject



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

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



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

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



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

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


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

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



229
230
231
# File 'lib/rake/gem/maintenance/upgrade_task.rb', line 229

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

#repos_available?(publisher) ⇒ Boolean

Returns:

  • (Boolean)


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

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

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