fastlane-plugin-wpmreleasetoolkit 9.0.0 → 9.1.0

Sign up to get free protection for your applications and to get access to all the features.
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