fastlane-plugin-wpmreleasetoolkit 9.0.0 → 9.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_update_metadata_source_action.rb +7 -5
  3. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/copy_branch_protection_action.rb +80 -0
  4. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_update_metadata_source.rb +3 -1
  5. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/{removebranchprotection_action.rb → remove_branch_protection_action.rb} +24 -17
  6. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/set_branch_protection_action.rb +153 -0
  7. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +49 -4
  8. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata/metadata_block.rb +20 -0
  9. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata/release_note_metadata_block.rb +72 -0
  10. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata/release_note_short_metadata_block.rb +23 -0
  11. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata/standard_metadata_block.rb +47 -0
  12. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata/unknown_metadata_block.rb +13 -0
  13. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata/whats_new_metadata_block.rb +53 -0
  14. data/lib/fastlane/plugin/wpmreleasetoolkit/models/app_version.rb +36 -0
  15. data/lib/fastlane/plugin/wpmreleasetoolkit/models/build_code.rb +27 -0
  16. data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
  17. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/calculators/abstract_version_calculator.rb +85 -0
  18. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/calculators/date_build_code_calculator.rb +32 -0
  19. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/calculators/date_version_calculator.rb +37 -0
  20. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/calculators/marketing_version_calculator.rb +26 -0
  21. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/calculators/semantic_version_calculator.rb +21 -0
  22. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/calculators/simple_build_code_calculator.rb +22 -0
  23. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/files/android_version_file.rb +76 -0
  24. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/files/ios_version_file.rb +64 -0
  25. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/abstract_version_formatter.rb +27 -0
  26. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/derived_build_code_formatter.rb +33 -0
  27. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/four_part_build_code_formatter.rb +22 -0
  28. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/four_part_version_formatter.rb +35 -0
  29. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/rc_notation_version_formatter.rb +65 -0
  30. data/lib/fastlane/plugin/wpmreleasetoolkit/versioning/formatters/simple_build_code_formatter.rb +20 -0
  31. data/lib/fastlane/plugin/wpmreleasetoolkit.rb +1 -1
  32. metadata +41 -6
  33. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/setbranchprotection_action.rb +0 -63
  34. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/an_metadata_update_helper.rb +0 -152
  35. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/metadata_update_helper.rb +0 -182
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 423e3fa0c8f65af81619e52a547d87a491b532bbab62680b5b5cba1ccfd72d10
4
- data.tar.gz: 94974b14aba25d84ffd22d5a6139bf9a0354cd4b61087acd9b8feef28a104fe4
3
+ metadata.gz: e26f9a48b802c79f4ac19eafc0f3da18b717202ab42d01ca2b2735df4b4abd5d
4
+ data.tar.gz: ee567a664e7831629f4a0886fc574eec192ef214c47468211a99aa679e98685b
5
5
  SHA512:
6
- metadata.gz: c340386d587df81c06aa77158d6e37ceb7f9959953f3c853c9766e77ba4d1054e6304615e4625611374bd11591e4b53437413b694c93a4315721c2b6cd74727b
7
- data.tar.gz: b9f1fc5e641b5f6d67fc42a803f035fdc1ebd93bd36f376f6da09b74d8282d42c233d8c7d87636837a5e5d3122188083367695e30a8ee8ae01623ef2c379fabe
6
+ metadata.gz: 993ef98974907a12d687e1558f9134038bf9e746a24c98e35dec4d230c87971e3342cd485d398b80076a20d03626ae4bf3b4c8b09f8f4fed316fc4ec7dcd0f8c
7
+ data.tar.gz: 3c6bebdb6b77966315088ea774e9a9275035b35abf87fcbf53b3ddfdadcdbd604c59a3ea2fe0d63082a6e572ead59e96cef851c0ec3c8d6187ed6f36326fb6e4
@@ -1,5 +1,7 @@
1
1
  require 'fastlane/action'
2
- require_relative '../../helper/an_metadata_update_helper'
2
+ require_relative '../../helper/metadata/release_note_metadata_block'
3
+ require_relative '../../helper/metadata/release_note_short_metadata_block'
4
+ require_relative '../../helper/metadata/whats_new_metadata_block'
3
5
 
4
6
  module Fastlane
5
7
  module Actions
@@ -71,17 +73,17 @@ module Fastlane
71
73
  @blocks = []
72
74
 
73
75
  # Inits default handler
74
- @blocks.push Fastlane::Helper::AnUnknownMetadataBlock.new
76
+ @blocks.push Fastlane::Helper::UnknownMetadataBlock.new
75
77
 
76
78
  # Init special handlers
77
79
  block_files.each do |key, file_path|
78
80
  case key
79
81
  when :release_note
80
- @blocks.push Fastlane::Helper::AnReleaseNoteMetadataBlock.new(key, file_path, release_version)
82
+ @blocks.push Fastlane::Helper::ReleaseNoteMetadataBlock.new(key, file_path, release_version)
81
83
  when :release_note_short
82
- @blocks.push Fastlane::Helper::AnReleaseNoteShortMetadataBlock.new(key, file_path, release_version)
84
+ @blocks.push Fastlane::Helper::ReleaseNoteShortMetadataBlock.new(key, file_path, release_version)
83
85
  else
84
- @blocks.push Fastlane::Helper::AnStandardMetadataBlock.new(key, file_path)
86
+ @blocks.push Fastlane::Helper::StandardMetadataBlock.new(key, file_path)
85
87
  end
86
88
  end
87
89
 
@@ -0,0 +1,80 @@
1
+ require 'fastlane/action'
2
+ require_relative '../../helper/github_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ class CopyBranchProtectionAction < Action
7
+ def self.run(params)
8
+ repository = params[:repository]
9
+ from_branch = params[:from_branch]
10
+ to_branch = params[:to_branch]
11
+
12
+ github_helper = Fastlane::Helper::GithubHelper.new(github_token: params[:github_token])
13
+
14
+ response = begin
15
+ github_helper.get_branch_protection(
16
+ repository: repository,
17
+ branch: from_branch
18
+ )
19
+ rescue Octokit::NotFound
20
+ UI.user_error!("Branch `#{from_branch}` of repository `#{repository}` was not found.")
21
+ end
22
+ UI.user_error!("Branch `#{from_branch}` does not have any branch protection set up.") if response.nil?
23
+ settings = Fastlane::Helper::GithubHelper.branch_protection_api_response_to_normalized_hash(response)
24
+
25
+ response = begin
26
+ github_helper.set_branch_protection(
27
+ repository: repository,
28
+ branch: to_branch,
29
+ **settings
30
+ )
31
+ rescue Octokit::NotFound
32
+ UI.user_error!("Branch `#{to_branch}` of repository `#{repository}` was not found.")
33
+ end
34
+
35
+ Fastlane::Helper::GithubHelper.branch_protection_api_response_to_normalized_hash(response)
36
+ end
37
+
38
+ def self.description
39
+ 'Copies the branch protection settings of one branch onto another branch'
40
+ end
41
+
42
+ def self.details
43
+ description
44
+ end
45
+
46
+ def self.return_value
47
+ 'The hash corresponding to the response returned by the API request, and containing the applied protection settings'
48
+ end
49
+
50
+ def self.available_options
51
+ [
52
+ FastlaneCore::ConfigItem.new(key: :repository,
53
+ env_name: 'GHHELPER_REPOSITORY',
54
+ description: 'The remote path of the GH repository on which we work',
55
+ optional: false,
56
+ type: String),
57
+ FastlaneCore::ConfigItem.new(key: :from_branch,
58
+ env_name: 'GHHELPER_FROM_BRANCH',
59
+ description: 'The branch to copy the protection settings from',
60
+ optional: false,
61
+ type: String),
62
+ FastlaneCore::ConfigItem.new(key: :to_branch,
63
+ env_name: 'GHHELPER_TO_BRANCH',
64
+ description: 'The branch to copy the protection settings to',
65
+ optional: false,
66
+ type: String),
67
+ Fastlane::Helper::GithubHelper.github_token_config_item,
68
+ ]
69
+ end
70
+
71
+ def self.authors
72
+ ['Automattic']
73
+ end
74
+
75
+ def self.is_supported?(platform)
76
+ true
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,4 +1,6 @@
1
- require_relative '../../helper/metadata_update_helper'
1
+ require_relative '../../helper/metadata/release_note_metadata_block'
2
+ require_relative '../../helper/metadata/release_note_short_metadata_block'
3
+ require_relative '../../helper/metadata/whats_new_metadata_block'
2
4
 
3
5
  module Fastlane
4
6
  module Actions
@@ -3,42 +3,34 @@ require_relative '../../helper/github_helper'
3
3
 
4
4
  module Fastlane
5
5
  module Actions
6
- class RemovebranchprotectionAction < Action
6
+ class RemoveBranchProtectionAction < Action
7
7
  def self.run(params)
8
8
  repository = params[:repository]
9
9
  branch_name = params[:branch]
10
10
 
11
- branch_url = "https://api.github.com/repos/#{repository}/branches/#{branch_name}"
12
- restrictions = { url: "#{branch_url}/protection/restrictions", users_url: "#{branch_url}/protection/restrictions/users", teams_url: "#{branch_url}/protection/restrictions/teams", users: [], teams: [] }
13
- required_pull_request_reviews = { url: "#{branch_url}/protection/required_pull_request_reviews", dismiss_stale_reviews: false, require_code_owner_reviews: false }
14
-
15
11
  github_helper = Fastlane::Helper::GithubHelper.new(github_token: params[:github_token])
16
12
  github_helper.remove_branch_protection(
17
13
  repository: repository,
18
- branch: branch_name,
19
- restrictions: restrictions,
20
- enforce_admins: nil,
21
- required_pull_request_reviews: required_pull_request_reviews
14
+ branch: branch_name
22
15
  )
16
+ rescue Octokit::NotFound
17
+ UI.user_error!("Branch `#{branch_name}` of repository `#{repository}` was not found.")
18
+ rescue Octokit::BranchNotProtected
19
+ UI.message("Note: Branch `#{branch_name}` was not protected in the first place.")
23
20
  end
24
21
 
25
22
  def self.description
26
- "Removes the 'release branch' protection state for the specified branch"
23
+ 'Removes the protection settings for the specified branch'
27
24
  end
28
25
 
29
- def self.authors
30
- ['Automattic']
26
+ def self.details
27
+ description
31
28
  end
32
29
 
33
30
  def self.return_value
34
31
  # If your method provides a return value, you can describe here what it does
35
32
  end
36
33
 
37
- def self.details
38
- # Optional:
39
- "Sets the 'release branch' protection state for the specified branch"
40
- end
41
-
42
34
  def self.available_options
43
35
  [
44
36
  FastlaneCore::ConfigItem.new(key: :repository,
@@ -55,9 +47,24 @@ module Fastlane
55
47
  ]
56
48
  end
57
49
 
50
+ def self.authors
51
+ ['Automattic']
52
+ end
53
+
58
54
  def self.is_supported?(platform)
59
55
  true
60
56
  end
61
57
  end
58
+
59
+ # For backwards compatibility
60
+ class RemovebranchprotectionAction < RemoveBranchProtectionAction
61
+ def self.category
62
+ :deprecated
63
+ end
64
+
65
+ def self.deprecated_notes
66
+ "This action has been renamed `#{superclass.action_name}`"
67
+ end
68
+ end
62
69
  end
63
70
  end
@@ -0,0 +1,153 @@
1
+ require 'fastlane/action'
2
+ require_relative '../../helper/github_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ class SetBranchProtectionAction < Action
7
+ def self.run(params)
8
+ repository = params[:repository]
9
+ branch_name = params[:branch]
10
+ github_helper = Fastlane::Helper::GithubHelper.new(github_token: params[:github_token])
11
+
12
+ settings = if params[:keep_existing_settings_unchanged]
13
+ Fastlane::Helper::GithubHelper.branch_protection_api_response_to_normalized_hash(
14
+ github_helper.get_branch_protection(repository: repository, branch: branch_name)
15
+ )
16
+ else
17
+ {}
18
+ end
19
+
20
+ # `required_status_checks` field — only override existing `checks` subfield if param provided
21
+ unless params[:required_ci_checks].nil?
22
+ if params[:required_ci_checks].empty?
23
+ settings[:required_status_checks] = nil # explicitly completely delete existing check requirement
24
+ else
25
+ settings[:required_status_checks] ||= { strict: false }
26
+ settings[:required_status_checks][:checks] = params[:required_ci_checks].map { |ctx| { context: ctx } }
27
+ end
28
+ end
29
+
30
+ # `enforce_admins` field — only override existing value if param provided
31
+ if params[:enforce_admins].nil?
32
+ settings[:enforce_admins] ||= nil # parameter is required to be provided, even if nil (aka false) value
33
+ else
34
+ settings[:enforce_admins] = params[:enforce_admins]
35
+ end
36
+
37
+ # `required_pull_request_reviews` field — only override `required_approving_review_count` subfield if param provided
38
+ settings[:required_pull_request_reviews] ||= {
39
+ dismiss_stale_reviews: false,
40
+ require_code_owner_reviews: false
41
+ }
42
+ unless params[:required_approving_review_count].nil?
43
+ settings[:required_pull_request_reviews][:required_approving_review_count] = params[:required_approving_review_count]
44
+ end
45
+
46
+ # `restrictions` field
47
+ settings[:restrictions] ||= { users: [], teams: [] }
48
+
49
+ # `allow_force_pushes` field — only override existing value if param provided
50
+ unless params[:allow_force_pushes].nil?
51
+ settings[:allow_force_pushes] = params[:allow_force_pushes]
52
+ end
53
+
54
+ # `lock_branch` field — only override existing value if param provided
55
+ unless params[:lock_branch].nil?
56
+ settings[:lock_branch] = params[:lock_branch]
57
+ end
58
+
59
+ # API Call - See https://docs.github.com/en/rest/branches/branch-protection#update-branch-protection
60
+ response = github_helper.set_branch_protection(
61
+ repository: repository,
62
+ branch: branch_name,
63
+ **settings
64
+ )
65
+
66
+ Fastlane::Helper::GithubHelper.branch_protection_api_response_to_normalized_hash(response)
67
+ rescue Octokit::NotFound => e
68
+ UI.user_error!("Branch `#{branch_name}` of repository `#{repository}` was not found.\n#{e.message}")
69
+ end
70
+
71
+ def self.description
72
+ 'Sets the protection state for the specified branch'
73
+ end
74
+
75
+ def self.details
76
+ description
77
+ end
78
+
79
+ def self.return_value
80
+ 'The hash corresponding to the response returned by the API request, and containing the applied protection settings'
81
+ end
82
+
83
+ def self.available_options
84
+ [
85
+ FastlaneCore::ConfigItem.new(key: :repository,
86
+ env_name: 'GHHELPER_REPOSITORY',
87
+ description: 'The slug of the GH repository on which we work',
88
+ optional: false,
89
+ type: String),
90
+ # NOTE: GitHub branch protection API doesn't allow wildcard characters for the branch parameter
91
+ FastlaneCore::ConfigItem.new(key: :branch,
92
+ env_name: 'GHHELPER_BRANCH',
93
+ description: 'The branch to protect',
94
+ optional: false,
95
+ type: String),
96
+ FastlaneCore::ConfigItem.new(key: :keep_existing_settings_unchanged,
97
+ description: 'If set to true, will only change the settings that are explicitly provided to the action, ' \
98
+ + 'while keeping the values of other existing protection settings (if any) unchanged. If false, it will ' \
99
+ + 'discard any existing branch protection setting if any before setting just the ones provided ' \
100
+ + '(and leaving the rest with default GitHub values)',
101
+ default_value: true,
102
+ type: Boolean),
103
+ FastlaneCore::ConfigItem.new(key: :required_ci_checks,
104
+ description: 'If provided, specifies the list of CI status checks to mark as required. If not provided (nil), will keep existing ones',
105
+ optional: true,
106
+ default_value: nil,
107
+ type: Array),
108
+ FastlaneCore::ConfigItem.new(key: :required_approving_review_count,
109
+ description: 'If not nil, change the number of approving reviews required to merge the PR. ' \
110
+ + 'Acceptable values are `nil` (do not change), 0 (disable) or a number between 1–6',
111
+ optional: true,
112
+ default_value: nil,
113
+ type: Integer),
114
+ FastlaneCore::ConfigItem.new(key: :enforce_admins,
115
+ description: 'If provided, will update the setting of whether admins can bypass restrictions (false) or not (true)',
116
+ optional: true,
117
+ default_value: nil,
118
+ type: Boolean),
119
+ FastlaneCore::ConfigItem.new(key: :allow_force_pushes,
120
+ description: 'If provided, will update the setting of whether to allow force pushes on the branch',
121
+ optional: true,
122
+ default_value: nil,
123
+ type: Boolean),
124
+ FastlaneCore::ConfigItem.new(key: :lock_branch,
125
+ description: 'If provided, will update the locked (aka readonly) state of the branch',
126
+ optional: true,
127
+ default_value: nil,
128
+ type: Boolean),
129
+ Fastlane::Helper::GithubHelper.github_token_config_item,
130
+ ]
131
+ end
132
+
133
+ def self.authors
134
+ ['Automattic']
135
+ end
136
+
137
+ def self.is_supported?(platform)
138
+ true
139
+ end
140
+ end
141
+
142
+ # For backwards compatibility
143
+ class SetbranchprotectionAction < SetBranchProtectionAction
144
+ def self.category
145
+ :deprecated
146
+ end
147
+
148
+ def self.deprecated_notes
149
+ "This action has been renamed `#{superclass.action_name}`"
150
+ end
151
+ end
152
+ end
153
+ end
@@ -244,11 +244,20 @@ module Fastlane
244
244
  #
245
245
  # @param [String] repository The repository name (including the organization)
246
246
  # @param [String] branch The branch name
247
- # @param [Hash] options A customizable set of options.
248
- # @see https://docs.github.com/en/rest/branches/branch-protection#update-branch-protection
247
+ # @see https://docs.github.com/en/rest/branches/branch-protection#delete-branch-protection
248
+ #
249
+ def remove_branch_protection(repository:, branch:)
250
+ client.unprotect_branch(repository, branch)
251
+ end
252
+
253
+ # Get the list of branch protection settings for a given branch of a repository
249
254
  #
250
- def remove_branch_protection(repository:, branch:, **options)
251
- client.unprotect_branch(repository, branch, options)
255
+ # @param [String] repository The repository name (including the organization)
256
+ # @param [String] branch The branch name
257
+ # @see https://docs.github.com/en/rest/branches/branch-protection#get-branch-protection
258
+ #
259
+ def get_branch_protection(repository:, branch:, **options)
260
+ client.branch_protection(repository, branch)
252
261
  end
253
262
 
254
263
  # Protects a single branch from a repository
@@ -262,6 +271,42 @@ module Fastlane
262
271
  client.protect_branch(repository, branch, options)
263
272
  end
264
273
 
274
+ # Convert a response from the `/branch-protection` API endpoint into a Hash
275
+ # suitable to be returned and/or reused to pass to a subsequent `/branch-protection` API request
276
+ # @param [Sawyer::Resource] response The API response returned by `#get_branch_protection` or `#set_branch_protection`
277
+ # @return [Hash] A hash representation of the API response—or an empty Hash if `response` was `nil`—
278
+ # with Boolean values normalized to true/false, and any extra values that would be refused
279
+ # if used in a subsequent API request (like legacy vs new key) removed.
280
+ # @see https://docs.github.com/en/rest/branches/branch-protection
281
+ #
282
+ def self.branch_protection_api_response_to_normalized_hash(response)
283
+ return {} if response.nil?
284
+
285
+ normalize_values = lambda do |hash|
286
+ hash.each do |k, v|
287
+ # Boolean values appear as { "enabled" => true/false } in the Response, while they must appear as true/false in Request
288
+ hash[k] = v[:enabled] if v.is_a?(Hash) && v.key?(:enabled)
289
+ # References to :users, :teams and :apps are expanded as Objects in the Response, while they must just be the login or slug in Request
290
+ hash[k] = v.map { |item| item[:login] } if k == :users && v.is_a?(Array)
291
+ hash[k] = v.map { |item| item[:slug] } if %i[teams apps].include?(k) && v.is_a?(Array)
292
+ # Response contains lots of `*url` keys that are useless in practice and makes the returned hash harder to parse visually
293
+ hash.delete(k) if k.to_s == 'url' || k.to_s.end_with?('_url')
294
+
295
+ # Recurse into Hashes and Array of Hashes
296
+ normalize_values.call(v) if v.is_a?(Hash)
297
+ v.each { |item| normalize_values.call(item) if item.is_a?(Hash) } if v.is_a?(Array)
298
+ end
299
+ end
300
+
301
+ hash = response.to_hash
302
+ normalize_values.call(hash)
303
+
304
+ # Response contains both (legacy) `:contexts` key and new `:checks` key, but only one of the two should be passed in Request
305
+ hash[:required_status_checks].delete(:contexts) unless hash.dig(:required_status_checks, :checks).nil?
306
+
307
+ hash
308
+ end
309
+
265
310
  # Creates a GithubToken Fastlane ConfigItem
266
311
  #
267
312
  # @return [FastlaneCore::ConfigItem] The Fastlane ConfigItem for GitHub OAuth access token
@@ -0,0 +1,20 @@
1
+ module Fastlane
2
+ module Helper
3
+ # Basic line handler
4
+ class MetadataBlock
5
+ attr_reader :block_key
6
+
7
+ def initialize(block_key)
8
+ @block_key = block_key
9
+ end
10
+
11
+ def handle_line(file, line)
12
+ file.puts(line) # Standard line handling: just copy
13
+ end
14
+
15
+ def is_handler_for(key)
16
+ true
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,72 @@
1
+ require_relative 'metadata_block'
2
+ require_relative 'standard_metadata_block'
3
+
4
+ module Fastlane
5
+ module Helper
6
+ class ReleaseNoteMetadataBlock < StandardMetadataBlock
7
+ attr_reader :new_key, :keep_key, :rel_note_key, :release_version
8
+
9
+ def initialize(block_key, content_file_path, release_version)
10
+ super(block_key, content_file_path)
11
+ @rel_note_key = 'release_note'
12
+ @release_version = release_version
13
+ generate_keys(release_version)
14
+ end
15
+
16
+ def generate_keys(release_version)
17
+ values = release_version.split('.')
18
+ version_major = Integer(values[0])
19
+ version_minor = Integer(values[1])
20
+ @new_key = "#{@rel_note_key}_#{version_major.to_s.rjust(2, '0')}#{version_minor}"
21
+
22
+ version_major -= 1 if version_minor.zero?
23
+ version_minor = version_minor.zero? ? 9 : version_minor - 1
24
+
25
+ @keep_key = "#{@rel_note_key}_#{version_major.to_s.rjust(2, '0')}#{version_minor}"
26
+ end
27
+
28
+ def is_handler_for(key)
29
+ values = key.split('_')
30
+ key.start_with?(@rel_note_key) && values.length == 3 && is_int?(values[2].sub(/^0*/, ''))
31
+ end
32
+
33
+ def handle_line(file, line)
34
+ # put content on block start or if copying the latest one
35
+ # and skip all the other content
36
+ if line.start_with?('msgctxt')
37
+ key = extract_key(line)
38
+ @is_copying = (key == @keep_key)
39
+ generate_block(file) if @is_copying
40
+ end
41
+
42
+ file.puts(line) if @is_copying
43
+ end
44
+
45
+ def generate_block(file)
46
+ # init
47
+ file.puts("msgctxt \"#{@new_key}\"")
48
+ file.puts('msgid ""')
49
+ file.puts("\"#{@release_version}:\\n\"")
50
+
51
+ # insert content
52
+ File.open(@content_file_path, 'r').each do |line|
53
+ file.puts("\"#{line.strip}\\n\"")
54
+ end
55
+
56
+ # close
57
+ file.puts('msgstr ""')
58
+ file.puts('')
59
+ end
60
+
61
+ def extract_key(line)
62
+ line.split[1].tr('\"', '')
63
+ end
64
+
65
+ def is_int?(value)
66
+ true if Integer(value)
67
+ rescue StandardError
68
+ false
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'release_note_metadata_block'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class ReleaseNoteShortMetadataBlock < ReleaseNoteMetadataBlock
6
+ def initialize(block_key, content_file_path, release_version)
7
+ super(block_key, content_file_path, release_version)
8
+ @rel_note_key = 'release_note_short'
9
+ @release_version = release_version
10
+ generate_keys(release_version)
11
+ end
12
+
13
+ def is_handler_for(key)
14
+ values = key.split('_')
15
+ key.start_with?(@rel_note_key) && values.length == 4 && is_int?(values[3].sub(/^0*/, ''))
16
+ end
17
+
18
+ def generate_block(file)
19
+ super(file) unless File.empty?(@content_file_path)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,47 @@
1
+ require_relative 'metadata_block'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class StandardMetadataBlock < MetadataBlock
6
+ attr_reader :content_file_path
7
+
8
+ def initialize(block_key, content_file_path)
9
+ super(block_key)
10
+ @content_file_path = content_file_path
11
+ end
12
+
13
+ def is_handler_for(key)
14
+ key == @block_key.to_s
15
+ end
16
+
17
+ def handle_line(file, line)
18
+ # put the new content on block start
19
+ # and skip all the other content
20
+ generate_block(file) if line.start_with?('msgctxt')
21
+ end
22
+
23
+ def generate_block(file)
24
+ # init
25
+ file.puts("msgctxt \"#{@block_key}\"")
26
+ line_count = File.foreach(@content_file_path).inject(0) { |c, _line| c + 1 }
27
+
28
+ if line_count <= 1
29
+ # Single line output
30
+ file.puts("msgid \"#{File.read(@content_file_path).rstrip}\"")
31
+ else
32
+ # Multiple line output
33
+ file.puts('msgid ""')
34
+
35
+ # insert content
36
+ File.open(@content_file_path, 'r').each do |line|
37
+ file.puts("\"#{line.strip}\\n\"")
38
+ end
39
+ end
40
+
41
+ # close
42
+ file.puts('msgstr ""')
43
+ file.puts('')
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'metadata_block'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class UnknownMetadataBlock < MetadataBlock
6
+ attr_reader :content_file_path
7
+
8
+ def initialize
9
+ super(nil)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ require_relative 'standard_metadata_block'
2
+
3
+ module Fastlane
4
+ module Helper
5
+ class WhatsNewMetadataBlock < StandardMetadataBlock
6
+ attr_reader :new_key, :old_key, :rel_note_key, :release_version
7
+
8
+ def initialize(block_key, content_file_path, release_version)
9
+ super(block_key, content_file_path)
10
+ @rel_note_key = 'whats_new'
11
+ @release_version = release_version
12
+ generate_keys(release_version)
13
+ end
14
+
15
+ def generate_keys(release_version)
16
+ values = release_version.split('.')
17
+ version_major = Integer(values[0])
18
+ version_minor = Integer(values[1])
19
+ @new_key = "v#{release_version}-whats-new"
20
+
21
+ version_major -= 1 if version_minor.zero?
22
+ version_minor = version_minor.zero? ? 9 : version_minor - 1
23
+
24
+ @old_key = "v#{version_major}.#{version_minor}-whats-new"
25
+ end
26
+
27
+ def is_handler_for(key)
28
+ key.start_with?('v') && key.end_with?('-whats-new')
29
+ end
30
+
31
+ def handle_line(file, line)
32
+ # put content on block start or if copying the latest one
33
+ # and skip all the other content
34
+ generate_block(file) if line.start_with?('msgctxt')
35
+ end
36
+
37
+ def generate_block(file)
38
+ # init
39
+ file.puts("msgctxt \"#{@new_key}\"")
40
+ file.puts('msgid ""')
41
+
42
+ # insert content
43
+ File.open(@content_file_path, 'r').each do |line|
44
+ file.puts("\"#{line.strip}\\n\"")
45
+ end
46
+
47
+ # close
48
+ file.puts('msgstr ""')
49
+ file.puts('')
50
+ end
51
+ end
52
+ end
53
+ end