Module: Fastlane::Helper::Android::VersionHelper
- Defined in:
- lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb
Overview
A module containing helper methods to manipulate/extract/bump Android version strings in gradle files
Constant Summary collapse
- VERSION_NAME =
The key used in internal version Hash objects to hold the versionName value
'name'.freeze
- VERSION_CODE =
The key used in internal version Hash objects to hold the versionCode value
'code'.freeze
- MAJOR_NUMBER =
The index for the major version number part
0
- MINOR_NUMBER =
The index for the minor version number part
1
- HOTFIX_NUMBER =
The index for the hotfix version number part
2
- ALPHA_PREFIX =
The prefix used in front of the versionName for alpha versions
'alpha-'.freeze
- RC_SUFFIX =
The suffix used in the versionName for RC (beta) versions
'-rc'.freeze
Class Method Summary collapse
-
.bump_version_release(build_gradle_path:, version_properties_path:) ⇒ String
Prints the current and next release version names to stdout, then returns the next release version.
-
.calc_final_release_version(beta_version, alpha_version) ⇒ Hash
Returns the version name and code to use for the final release.
-
.calc_next_alpha_version(version, alpha_version) ⇒ Hash
Returns the version name and code to use for the next alpha.
-
.calc_next_beta_version(version, alpha_version = nil) ⇒ Hash
Compute the version name and code to use for the next beta (‘X.Y.Z-rc-N`).
-
.calc_next_hotfix_version(hotfix_version_name, hotfix_version_code) ⇒ Hash
Compute the name and code of the next hotfix version.
-
.calc_next_release_base_version(version) ⇒ Hash
Compute the next release version name for the given version, without incrementing the version code.
-
.calc_next_release_short_version(version) ⇒ String
Compute the version name to use for the next release (‘“X.Y”`).
-
.calc_next_release_version(version, alpha_version = nil) ⇒ Hash
Compute the name of the next version to use after code freeze, by incrementing the current version name and making it a ‘-rc-1`.
-
.calc_prev_hotfix_version_name(version_name) ⇒ String
Compute the name of the previous hotfix version.
-
.calc_prev_release_version(version) ⇒ String
Compute the name of the previous release version, by decrementing the minor version number.
-
.get_alpha_version(build_gradle_path:, version_properties_path:) ⇒ Hash
Extract the version name and code from the ‘version.properties` file in the project root.
-
.get_keyword_from_gradle_file(file_path, section, keyword) ⇒ String
Extract the value for a specific keyword in a specific section of a ‘.gradle` file.
-
.get_library_version_from_gradle_config(build_gradle_path:, import_key:) ⇒ String
Extract the value of a import key from build.gradle.
-
.get_public_version(build_gradle_path:, version_properties_path:) ⇒ String
Returns the public-facing version string.
-
.get_release_version(build_gradle_path:, version_properties_path:) ⇒ Hash
Extract the version name and code from the release version of the app from ‘version.properties file`.
-
.get_version_build_from_gradle_file(file_path, section) ⇒ String
Extract the versionCode rom a build.gradle file.
-
.get_version_from_properties(version_properties_path:, is_alpha: false) ⇒ Hash
Extract the version name and code from the ‘version.properties` file in the project root.
-
.get_version_name_from_gradle_file(file_path, section) ⇒ String
Extract the versionName from a build.gradle file.
-
.get_version_parts(version) ⇒ Array<Int>
Split a version string into its individual integer parts.
-
.is_alpha_version?(version) ⇒ Bool
Determines if a version name corresponds to an alpha version (starts with ‘“alpha-”“ prefix).
-
.is_beta_version?(version) ⇒ Bool
Check if this versionName corresponds to a beta, i.e.
-
.is_hotfix?(version) ⇒ Bool
Determines if a version name corresponds to a hotfix.
-
.is_int?(string) ⇒ Bool
Check if a string is an integer.
-
.remove_beta_suffix(version) ⇒ String
Remove the beta suffix (part after the ‘-`) from a version string.
-
.update_version(version, section, build_gradle_path:) ⇒ Object
Update both the versionName and versionCode of the build.gradle file to the specified version.
-
.update_versions(new_version_beta, new_version_alpha, version_properties_path:) ⇒ Object
Update the ‘version.properties` file with new `versionName` and `versionCode` values.
-
.verify_version(version) ⇒ String
Ensure that a version string is correctly formatted (that is, each of its parts is a number) and returns the 2-parts version number.
Class Method Details
.bump_version_release(build_gradle_path:, version_properties_path:) ⇒ String
Prints the current and next release version names to stdout, then returns the next release version
280 281 282 283 284 285 286 287 288 289 290 291 292 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 280 def self.bump_version_release(build_gradle_path:, version_properties_path:) # Bump release current_version = self.get_release_version( build_gradle_path: build_gradle_path, version_properties_path: version_properties_path ) UI.("Current version: #{current_version[VERSION_NAME]}") new_version = calc_next_release_base_version(current_version) UI.("New version: #{new_version[VERSION_NAME]}") verified_version = verify_version(new_version[VERSION_NAME]) return verified_version end |
.calc_final_release_version(beta_version, alpha_version) ⇒ Hash
Returns the version name and code to use for the final release.
-
The final version name corresponds to the beta’s versionName, without the ‘-rc` suffix
-
The final version code corresponds to the versionCode for the alpha (or for the beta if alpha_version is nil) incremented by one.
125 126 127 128 129 130 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 125 def self.calc_final_release_version(beta_version, alpha_version) version_name = beta_version[VERSION_NAME].split('-')[0] version_code = alpha_version.nil? ? beta_version[VERSION_CODE] + 1 : alpha_version[VERSION_CODE] + 1 { VERSION_NAME => version_name, VERSION_CODE => version_code } end |
.calc_next_alpha_version(version, alpha_version) ⇒ Hash
Returns the version name and code to use for the next alpha.
-
The next version name corresponds to the ‘alpha_version`’s name incremented by one (alpha-42 => alpha-43)
-
The next version code corresponds to the ‘version`’s code incremented by one.
142 143 144 145 146 147 148 149 150 151 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 142 def self.calc_next_alpha_version(version, alpha_version) # Bump alpha name alpha_number = alpha_version[VERSION_NAME].sub(ALPHA_PREFIX, '') alpha_name = "#{ALPHA_PREFIX}#{alpha_number.to_i + 1}" # Bump alpha code alpha_code = version[VERSION_CODE] + 1 { VERSION_NAME => alpha_name, VERSION_CODE => alpha_code } end |
.calc_next_beta_version(version, alpha_version = nil) ⇒ Hash
Compute the version name and code to use for the next beta (‘X.Y.Z-rc-N`).
-
The next version name corresponds to the ‘version`’s name with the value after the ‘-rc-` suffix incremented by one,
or with `-rc-1` added if there was no previous rc suffix (if `version` was not a beta but a release)
-
The next version code corresponds to the ‘alpha_version`’s (or ‘version`’s if ‘alpha_version` is nil) code, incremented by one.
170 171 172 173 174 175 176 177 178 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 170 def self.calc_next_beta_version(version, alpha_version = nil) # Bump version name beta_number = is_beta_version?(version) ? version[VERSION_NAME].split('-')[2].to_i + 1 : 1 version_name = "#{version[VERSION_NAME].split('-')[0]}#{RC_SUFFIX}-#{beta_number}" # Bump version code version_code = alpha_version.nil? ? version[VERSION_CODE] + 1 : alpha_version[VERSION_CODE] + 1 { VERSION_NAME => version_name, VERSION_CODE => version_code } end |
.calc_next_hotfix_version(hotfix_version_name, hotfix_version_code) ⇒ Hash
Compute the name and code of the next hotfix version.
236 237 238 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 236 def self.calc_next_hotfix_version(hotfix_version_name, hotfix_version_code) { VERSION_NAME => hotfix_version_name, VERSION_CODE => hotfix_version_code } end |
.calc_next_release_base_version(version) ⇒ Hash
Compute the next release version name for the given version, without incrementing the version code
- The version name sees its minor version part incremented by one (and carried to next major if it reaches 10)
- The version code is unchanged. This method is intended to be called internally by other methods taking care of the version code bump.
200 201 202 203 204 205 206 207 208 209 210 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 200 def self.calc_next_release_base_version(version) version_name = remove_beta_suffix(version[VERSION_NAME]) vp = get_version_parts(version_name) vp[MINOR_NUMBER] += 1 if vp[MINOR_NUMBER] == 10 vp[MAJOR_NUMBER] += 1 vp[MINOR_NUMBER] = 0 end { VERSION_NAME => "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}", VERSION_CODE => version[VERSION_CODE] } end |
.calc_next_release_short_version(version) ⇒ String
Compute the version name to use for the next release (‘“X.Y”`).
186 187 188 189 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 186 def self.calc_next_release_short_version(version) v = self.calc_next_release_base_version(VERSION_NAME => version, VERSION_CODE => nil) return v[VERSION_NAME] end |
.calc_next_release_version(version, alpha_version = nil) ⇒ Hash
Compute the name of the next version to use after code freeze, by incrementing the current version name and making it a ‘-rc-1`
224 225 226 227 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 224 def self.calc_next_release_version(version, alpha_version = nil) nv = calc_next_release_base_version(VERSION_NAME => version[VERSION_NAME], VERSION_CODE => alpha_version.nil? ? version[VERSION_CODE] : [version[VERSION_CODE], alpha_version[VERSION_CODE]].max) calc_next_beta_version(nv) end |
.calc_prev_hotfix_version_name(version_name) ⇒ String
Compute the name of the previous hotfix version.
327 328 329 330 331 332 333 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 327 def self.calc_prev_hotfix_version_name(version_name) vp = get_version_parts(version_name) vp[HOTFIX_NUMBER] -= 1 unless vp[HOTFIX_NUMBER] == 0 return "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}.#{vp[HOTFIX_NUMBER]}" unless vp[HOTFIX_NUMBER] == 0 "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}" end |
.calc_prev_release_version(version) ⇒ String
Compute the name of the previous release version, by decrementing the minor version number
251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 251 def self.calc_prev_release_version(version) vp = get_version_parts(version) if vp[MINOR_NUMBER] == 0 vp[MAJOR_NUMBER] -= 1 vp[MINOR_NUMBER] = 9 else vp[MINOR_NUMBER] -= 1 end "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}" end |
.get_alpha_version(build_gradle_path:, version_properties_path:) ⇒ Hash
Extract the version name and code from the ‘version.properties` file in the project root
81 82 83 84 85 86 87 88 89 90 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 81 def self.get_alpha_version(build_gradle_path:, version_properties_path:) return get_version_from_properties(version_properties_path: version_properties_path, is_alpha: true) if File.exist?(version_properties_path) return nil if ENV['HAS_ALPHA_VERSION'].nil? section = 'defaultConfig' name = get_version_name_from_gradle_file(build_gradle_path, section) code = get_version_build_from_gradle_file(build_gradle_path, section) return { VERSION_NAME => name, VERSION_CODE => code } end |
.get_keyword_from_gradle_file(file_path, section, keyword) ⇒ String
Extract the value for a specific keyword in a specific section of a ‘.gradle` file
@todo: This implementation is very fragile. This should be done parsing the file in a proper way.
Leveraging gradle itself is probably the easiest way.
443 444 445 446 447 448 449 450 451 452 453 454 455 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 443 def self.get_keyword_from_gradle_file(file_path, section, keyword) found_section = false File.open(file_path, 'r') do |file| file.each_line do |line| if found_section return line.split[1] if line.include?(keyword) && !line.include?("\"#{keyword}\"") && !line.include?("P#{keyword}") elsif line.include?(section) found_section = true end end end return nil end |
.get_library_version_from_gradle_config(build_gradle_path:, import_key:) ⇒ String
Extract the value of a import key from build.gradle
340 341 342 343 344 345 346 347 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 340 def self.get_library_version_from_gradle_config(build_gradle_path:, import_key:) return nil unless File.exist?(build_gradle_path) File.open(build_gradle_path, 'r') do |f| text = f.read text.match(/^\s*(?:\w*\.)?#{Regexp.escape(import_key)}\s*=\s*['"](.*?)["']/m)&.captures&.first end end |
.get_public_version(build_gradle_path:, version_properties_path:) ⇒ String
Returns the public-facing version string.
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 33 def self.get_public_version(build_gradle_path:, version_properties_path:) version = get_release_version( build_gradle_path: build_gradle_path, version_properties_path: version_properties_path ) vp = get_version_parts(version[VERSION_NAME]) return "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}" unless is_hotfix?(version) "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}.#{vp[HOTFIX_NUMBER]}" end |
.get_release_version(build_gradle_path:, version_properties_path:) ⇒ Hash
Extract the version name and code from the release version of the app from ‘version.properties file`
48 49 50 51 52 53 54 55 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 48 def self.get_release_version(build_gradle_path:, version_properties_path:) return get_version_from_properties(version_properties_path: version_properties_path) if File.exist?(version_properties_path) section = ENV['HAS_ALPHA_VERSION'].nil? ? 'defaultConfig' : 'vanilla {' name = get_version_name_from_gradle_file(build_gradle_path, section) code = get_version_build_from_gradle_file(build_gradle_path, section) return { VERSION_NAME => name, VERSION_CODE => code } end |
.get_version_build_from_gradle_file(file_path, section) ⇒ String
Extract the versionCode rom a build.gradle file
427 428 429 430 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 427 def self.get_version_build_from_gradle_file(file_path, section) res = get_keyword_from_gradle_file(file_path, section, 'versionCode') return res.to_i end |
.get_version_from_properties(version_properties_path:, is_alpha: false) ⇒ Hash
Extract the version name and code from the ‘version.properties` file in the project root
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 63 def self.get_version_from_properties(version_properties_path:, is_alpha: false) return nil unless File.exist?(version_properties_path) version_name_key = is_alpha ? 'alpha.versionName' : 'versionName' version_code_key = is_alpha ? 'alpha.versionCode' : 'versionCode' text = File.read(version_properties_path) name = text.match(/#{version_name_key}=(\S*)/m)&.captures&.first code = text.match(/#{version_code_key}=(\S*)/m)&.captures&.first return name.nil? || code.nil? ? nil : { VERSION_NAME => name, VERSION_CODE => code.to_i } end |
.get_version_name_from_gradle_file(file_path, section) ⇒ String
Extract the versionName from a build.gradle file
414 415 416 417 418 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 414 def self.get_version_name_from_gradle_file(file_path, section) res = get_keyword_from_gradle_file(file_path, section, 'versionName') res = res.tr('\"', '') unless res.nil? return res end |
.get_version_parts(version) ⇒ Array<Int>
Split a version string into its individual integer parts
370 371 372 373 374 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 370 def self.get_version_parts(version) parts = version.split('.').map(&:to_i) parts.fill(0, parts.length...3) # add 0 if needed to ensure array has at least 3 components return parts end |
.is_alpha_version?(version) ⇒ Bool
Determines if a version name corresponds to an alpha version (starts with ‘“alpha-”“ prefix)
100 101 102 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 100 def self.is_alpha_version?(version) version[VERSION_NAME].start_with?(ALPHA_PREFIX) end |
.is_beta_version?(version) ⇒ Bool
Check if this versionName corresponds to a beta, i.e. contains some ‘-rc` suffix
110 111 112 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 110 def self.is_beta_version?(version) version[VERSION_NAME].include?(RC_SUFFIX) end |
.is_hotfix?(version) ⇒ Bool
Determines if a version name corresponds to a hotfix
269 270 271 272 273 274 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 269 def self.is_hotfix?(version) return false if is_alpha_version?(version) vp = get_version_parts(version[VERSION_NAME]) return (vp.length > 2) && (vp[HOTFIX_NUMBER] != 0) end |
.is_int?(string) ⇒ Bool
Check if a string is an integer.
399 400 401 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 399 def self.is_int?(string) true if Integer(string) rescue false end |
.remove_beta_suffix(version) ⇒ String
Remove the beta suffix (part after the ‘-`) from a version string
359 360 361 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 359 def self.remove_beta_suffix(version) version.split('-')[0] end |
.update_version(version, section, build_gradle_path:) ⇒ Object
This implementation is very fragile. This should be done parsing the file in a proper way. Leveraging gradle itself is probably the easiest way.
Update both the versionName and versionCode of the build.gradle file to the specified version.
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 465 def self.update_version(version, section, build_gradle_path:) temp_file = Tempfile.new('fastlaneIncrementVersion') found_section = false version_updated = 0 File.open(build_gradle_path, 'r') do |file| file.each_line do |line| if found_section if version_updated < 2 if line.include?('versionName') && !line.include?('"versionName"') && !line.include?('PversionName') version_name = line.split[1].tr('\"', '') line.sub!(version_name, version[VERSION_NAME].to_s) version_updated += 1 end if line.include? 'versionCode' version_code = line.split[1] line.sub!(version_code, version[VERSION_CODE].to_s) version_updated += 1 end end temp_file.puts line else temp_file.puts line found_section = true if line.include? section end end file.close end temp_file.rewind temp_file.close FileUtils.mv(temp_file.path, build_gradle_path) temp_file.unlink end |
.update_versions(new_version_beta, new_version_alpha, version_properties_path:) ⇒ Object
Update the ‘version.properties` file with new `versionName` and `versionCode` values
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 299 def self.update_versions(new_version_beta, new_version_alpha, version_properties_path:) if File.exist?(version_properties_path) replacements = { versionName: (new_version_beta || {})[VERSION_NAME], versionCode: (new_version_beta || {})[VERSION_CODE], 'alpha.versionName': (new_version_alpha || {})[VERSION_NAME], 'alpha.versionCode': (new_version_alpha || {})[VERSION_CODE] } content = File.read(version_properties_path) content.gsub!(/^(.*) ?=.*$/) do |line| key = Regexp.last_match(1).to_sym value = replacements[key] value.nil? ? line : "#{key}=#{value}" end File.write(version_properties_path, content) else self.update_version(new_version_beta, ENV['HAS_ALPHA_VERSION'].nil? ? 'defaultConfig' : 'vanilla {') self.update_version(new_version_alpha, 'defaultConfig') unless new_version_alpha.nil? end end |
.verify_version(version) ⇒ String
Ensure that a version string is correctly formatted (that is, each of its parts is a number) and returns the 2-parts version number
383 384 385 386 387 388 389 390 391 |
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 383 def self.verify_version(version) v_parts = get_version_parts(version) v_parts.each do |part| UI.user_error!('Version value can only contains numbers.') unless is_int?(part) end "#{v_parts[MAJOR_NUMBER]}.#{v_parts[MINOR_NUMBER]}" end |