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'
VERSION_CODE =

The key used in internal version Hash objects to hold the versionCode value

'code'
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-'
RC_SUFFIX =

The suffix used in the versionName for RC (beta) versions

'-rc'

Class Method Summary collapse

Class Method Details

.bump_version_releaseString

Prints the current and next release version names to stdout, then returns the next release version

Returns:

  • (String)

    The next release version name to use after bumping the currently used release version.



283
284
285
286
287
288
289
290
291
292
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 283

def self.bump_version_release
  # Bump release
  current_version = self.get_release_version
  UI.message("Current version: #{current_version[VERSION_NAME]}")
  new_version = calc_next_release_base_version(current_version)
  UI.message("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.

Parameters:

  • beta_version (Hash)

    The version hash for the beta, containing values for keys “name” and “code”

  • alpha_version (Hash)

    The version hash for the alpha, containing values for keys “name” and “code”, or ‘nil` if no alpha version to consider.

Returns:

  • (Hash)

    A version hash with keys “name” and “code”, containing the version name and code to use for final release.



128
129
130
131
132
133
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 128

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.

Parameters:

  • version (Hash)

    The version hash for the current beta or release, containing values for keys “name” and “code”

  • alpha_version (Hash)

    The version hash for the current alpha (defaultConfig), containing values for keys “name” and “code”

Returns:

  • (Hash)

    A version hash with keys “name” and “code”, containing the version name and code to use for final release.



145
146
147
148
149
150
151
152
153
154
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 145

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.

Examples:

calc_next_beta_version({"name": "1.2.3", "code": 456}) #=> {"name": "1.2.3-rc-1", "code": 457}
calc_next_beta_version({"name": "1.2.3-rc-2", "code": 456}) #=> {"name": "1.2.3-rc-3", "code": 457}
calc_next_beta_version({"name": "1.2.3", "code": 456}, {"name": "alpha-1.2.3", "code": 457}) #=> {"name": "1.2.3-rc-1", "code": 458}

Parameters:

  • version (Hash)

    The version hash for the current beta or release, containing values for keys “name” and “code”

  • alpha_version (Hash) (defaults to: nil)

    The version hash for the alpha, containing values for keys “name” and “code”, or ‘nil` if no alpha version to consider.

Returns:

  • (Hash)

    A hash with keys ‘“name”` and `“code”` containing the next beta version name and code.



173
174
175
176
177
178
179
180
181
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 173

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.

Parameters:

  • hotfix_version_name (String)

    The next version name we want for the hotfix

  • hotfix_version_code (String)

    The next version code we want for the hotfix

Returns:

  • (Hash)

    The predicted next hotfix version, as a Hash containing the keys ‘“name”` and `“code”`



239
240
241
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 239

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.

Parameters:

  • version (Hash)

    A version hash, with keys ‘“name”` and `“code”`, containing the version to increment

Returns:

  • (Hash)

    Hash containing the next release version name (“X.Y”) and code.



203
204
205
206
207
208
209
210
211
212
213
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 203

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”`).

Parameters:

  • version (String)

    The version name (string) to increment

Returns:

  • (String)

    The version name for the next release



189
190
191
192
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 189

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`

Examples:

calc_next_release_version({"name": "1.2", "code": 456}) #=> {"name":"1.3-rc-1", "code": 457}
calc_next_release_version({"name": "1.2.3", "code": 456}) #=> {"name":"1.3-rc-1", "code": 457}
calc_next_release_version({"name": "1.2", "code": 456}, {"name":"alpha-1.2", "code": 457}) #=> {"name":"1.3-rc-1", "code": 458}

Parameters:

  • version (Hash)

    The current version hash, with keys ‘“name”` and `“code”`

  • alpha_version (Hash) (defaults to: nil)

    The current alpha version hash, with keys ‘“name”` and `“code”`, or nil if no alpha version

Returns:

  • (Hash)

    The hash containing the version name and code to use after release cut



227
228
229
230
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 227

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.

Parameters:

  • version_name (String)

    The current version name we want to decrement

Returns:

  • (String)

    The predicted previous hotfix version, in the form of “X.Y.Z”, or “X.Y” if Z is 0. Corresponds to decrementing the 3rd component Z of the version, stripping it if it ends up being zero.



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

Examples:

calc_prev_release_version("1.2") => "1.1"
calc_prev_release_version("1.2.3") => "1.1"
calc_prev_release_version("3.0") => "2.9"

Parameters:

  • version (String)

    The version string to decrement

Returns:

  • (String)

    A 2-parts version string “X.Y” corresponding to the guessed previous release version.



254
255
256
257
258
259
260
261
262
263
264
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 254

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_versionHash

Extract the version name and code from the ‘version.properties` file in the project root

Returns:

  • (Hash)

    A hash with 2 keys ‘“name”` and `“code”` containing the extracted version name and code, respectively, or `nil` if `$HAS_ALPHA_VERSION` is not defined.



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 83

def self.get_alpha_version
  return get_version_from_properties(is_alpha: true) if File.exist?(version_properties_file)

  return nil if ENV['HAS_ALPHA_VERSION'].nil?

  section = 'defaultConfig'
  gradle_path = self.gradle_path
  name = get_version_name_from_gradle_file(gradle_path, section)
  code = get_version_build_from_gradle_file(gradle_path, section)
  return { VERSION_NAME => name, VERSION_CODE => code }
end

.get_library_version_from_gradle_config(import_key:) ⇒ String

Extract the value of a import key from build.gradle

Parameters:

  • import_key (String)

    The key to look for

Returns:

  • (String)

    The value of the key, or nil if not found



340
341
342
343
344
345
346
347
348
349
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 340

def self.get_library_version_from_gradle_config(import_key:)
  gradle_file_path = File.join(ENV['PROJECT_ROOT_FOLDER'] || '.', 'build.gradle')

  return nil unless File.exist?(gradle_file_path)

  File.open(gradle_file_path, 'r') do |f|
    text = f.read
    text.match(/^\s*(?:\w*\.)?#{Regexp.escape(import_key)}\s*=\s*['"](.*?)["']/m)&.captures&.first
  end
end

.get_public_versionString

Returns the public-facing version string.

Examples:

"1.2" # Assuming build.gradle contains versionName "1.2"
"1.2" # Assuming build.gradle contains versionName "1.2.0"
"1.2.3" # Assuming build.gradle contains versionName "1.2.3"

Returns:

  • (String)

    The public-facing version number, extracted from the ‘versionName` of the `build.gradle` file.

    • If this version is a hotfix (more than 2 parts and 3rd part is non-zero), returns the “X.Y.Z” formatted string

    • Otherwise (not a hotfix / 3rd part of version is 0), returns “X.Y” formatted version number



33
34
35
36
37
38
39
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 33

def self.get_public_version
  version = get_release_version
  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_versionHash

Extract the version name and code from the release version of the app from ‘version.properties file`

Returns:

  • (Hash)

    A hash with 2 keys “name” and “code” containing the extracted version name and code, respectively



45
46
47
48
49
50
51
52
53
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 45

def self.get_release_version
  return get_version_from_properties() if File.exist?(version_properties_file)

  section = ENV['HAS_ALPHA_VERSION'].nil? ? 'defaultConfig' : 'vanilla {'
  gradle_path = self.gradle_path
  name = get_version_name_from_gradle_file(gradle_path, section)
  code = get_version_build_from_gradle_file(gradle_path, section)
  return { VERSION_NAME => name, VERSION_CODE => code }
end

.get_version_from_properties(is_alpha: false) ⇒ Hash

Extract the version name and code from the ‘version.properties` file in the project root

Parameters:

  • is_alpha (Boolean) (defaults to: false)

    true if the alpha version should be returned, false otherwise

Returns:

  • (Hash)

    A hash with 2 keys “name” and “code” containing the extracted version name and code, respectively



65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 65

def self.get_version_from_properties(is_alpha: false)
  return nil unless File.exist?(version_properties_file)

  version_name_key = is_alpha ? 'alpha.versionName' : 'versionName'
  version_code_key = is_alpha ? 'alpha.versionCode' : 'versionCode'

  text = File.read(version_properties_file)
  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

.is_alpha_version?(version) ⇒ Bool

Determines if a version name corresponds to an alpha version (starts with ‘“alpha-”“ prefix)

Parameters:

  • version (String)

    The version name to check

Returns:

  • (Bool)

    true if the version name starts with the ‘ALPHA_PREFIX`, false otherwise.



103
104
105
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 103

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

Parameters:

  • version (String)

    The versionName string to check for

Returns:

  • (Bool)

    True if the version string contains ‘-rc`, indicating it is a beta version.



113
114
115
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 113

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

Parameters:

  • version (String)

    The version number to test

Returns:

  • (Bool)

    True if the version number has a non-zero 3rd component, meaning that it is a hotfix version.



272
273
274
275
276
277
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 272

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

.update_versions(new_version_beta, new_version_alpha) ⇒ Object

Update the ‘version.properties` file with new `versionName` and `versionCode` values

Parameters:

  • new_version_beta (Hash)

    The version hash for the beta, containing values for keys “name” and “code”

  • new_version_alpha (Hash)

    The version hash for the alpha , containing values for keys “name” and “code”



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)
  if File.exist?(version_properties_file)
    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_file)
    content.gsub!(/^(.*) ?=.*$/) do |line|
      key = Regexp.last_match(1).to_sym
      value = replacements[key]
      value.nil? ? line : "#{key}=#{value}"
    end
    File.write(version_properties_file, 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

.version_properties_fileObject



55
56
57
# File 'lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb', line 55

def self.version_properties_file
  File.join(ENV['PROJECT_ROOT_FOLDER'] || '.', 'version.properties')
end