fastlane-plugin-wpmreleasetoolkit 11.0.1 → 11.0.3
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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7eae107cbe0b856fbe2c3292db7b84bc7ba57ec98da3717e7872243923e63b1d
|
4
|
+
data.tar.gz: 9576cd4c24122685ab6447fcdd64a2751e44fc36b368b9b22b623e5fe34353c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2f85f419598ad21a97f91767bd264303cd4ce47514f61648bceb482214fbab0dc379704aa15dc9d189743ff31220c6e9c61b283826c453ab088594f3886fa3f
|
7
|
+
data.tar.gz: 4486133931d4c775ff8ec0a084bce9eba9309cebf85f06f9e9aa3182a5974b34d07cb598b48fc30834fb09f8e23a40c0d98aa0c08cc12d982ddea468f4a93c1a
|
@@ -14,9 +14,9 @@ module Fastlane
|
|
14
14
|
commit: params[:commit],
|
15
15
|
env: params[:environment].merge(pipeline_name),
|
16
16
|
message: params[:message],
|
17
|
-
# Buildkite will not trigger a build if the GitHub activity for that branch is turned off
|
18
|
-
# We want API triggers to work regardless of the GitHub activity settings, so this option is necessary
|
19
|
-
# https://forum.buildkite.community/t/request-build-error-branches-have-been-disabled-for-this-pipeline/1463/2
|
17
|
+
# Buildkite will not trigger a build if the GitHub activity for that branch is turned off.
|
18
|
+
# We want API triggers to work regardless of the GitHub activity settings, so this option is necessary.
|
19
|
+
# See https://forum.buildkite.community/t/request-build-error-branches-have-been-disabled-for-this-pipeline/1463/2
|
20
20
|
ignore_pipeline_branch_filters: true
|
21
21
|
}.compact # remove entries with `nil` values from the Hash, if any
|
22
22
|
|
@@ -27,11 +27,15 @@ module Fastlane
|
|
27
27
|
options
|
28
28
|
)
|
29
29
|
|
30
|
+
build_url = response.web_url
|
31
|
+
|
30
32
|
if response.state == 'scheduled'
|
31
|
-
UI.success("Successfully scheduled new build. You can see it at '#{
|
33
|
+
UI.success("Successfully scheduled new build. You can see it at '#{build_url}'")
|
32
34
|
else
|
33
|
-
UI.crash!("Failed to start
|
35
|
+
UI.crash!("Failed to start build.\nError: [#{response}]")
|
34
36
|
end
|
37
|
+
|
38
|
+
build_url
|
35
39
|
end
|
36
40
|
|
37
41
|
#####################################################
|
@@ -39,7 +43,8 @@ module Fastlane
|
|
39
43
|
#####################################################
|
40
44
|
|
41
45
|
def self.description
|
42
|
-
|
46
|
+
# https://buildkite.com/docs/pipelines/glossary#build
|
47
|
+
'Triggers a build on Buildkite'
|
43
48
|
end
|
44
49
|
|
45
50
|
def self.available_options
|
@@ -99,6 +104,10 @@ module Fastlane
|
|
99
104
|
['Automattic']
|
100
105
|
end
|
101
106
|
|
107
|
+
def self.return_value
|
108
|
+
'The web URL of the build the action started.'
|
109
|
+
end
|
110
|
+
|
102
111
|
def self.is_supported?(platform)
|
103
112
|
true
|
104
113
|
end
|
@@ -152,6 +152,13 @@ module Fastlane
|
|
152
152
|
(added_count + updated_count) != 0
|
153
153
|
end
|
154
154
|
|
155
|
+
########
|
156
|
+
# @!group Verify diff of library vs main strings matches
|
157
|
+
#
|
158
|
+
# @note This set of methods is used by `an_validate_lib_strings_action`
|
159
|
+
# (which doesn't seem to be used by any of our Android projects nowadays?)
|
160
|
+
########
|
161
|
+
|
155
162
|
def self.verify_diff(diff_string, main_strings, lib_strings, library)
|
156
163
|
return unless diff_string.start_with?('name=')
|
157
164
|
|
@@ -198,6 +205,8 @@ module Fastlane
|
|
198
205
|
end
|
199
206
|
end
|
200
207
|
|
208
|
+
# @!endgroup
|
209
|
+
|
201
210
|
########
|
202
211
|
# @!group Downloading translations from GlotPress
|
203
212
|
########
|
@@ -223,7 +232,7 @@ module Fastlane
|
|
223
232
|
#
|
224
233
|
# @param [String] res_dir The relative path to the `…/src/main/res` directory.
|
225
234
|
# @param [String] glotpress_project_url The base URL to the glotpress project to download the strings from.
|
226
|
-
# @param [Hash{
|
235
|
+
# @param [Hash{Symbol=>String}, Array] glotpress_filters
|
227
236
|
# The filters to apply when exporting strings from GlotPress.
|
228
237
|
# Typical examples include `{ status: 'current' }` or `{ status: 'review' }`.
|
229
238
|
# If an array of Hashes is provided instead of a single Hash, this method will perform as many
|
@@ -235,10 +244,8 @@ module Fastlane
|
|
235
244
|
def self.download_from_glotpress(res_dir:, glotpress_project_url:, locales_map:, glotpress_filters: { status: 'current' })
|
236
245
|
glotpress_filters = [glotpress_filters] unless glotpress_filters.is_a?(Array)
|
237
246
|
|
238
|
-
attributes_to_copy = %w[formatted] # Attributes that we want to replicate into translated `string.xml` files
|
239
247
|
orig_file = File.join(res_dir, 'values', 'strings.xml')
|
240
248
|
orig_xml = File.open(orig_file) { |f| Nokogiri::XML(f, nil, Encoding::UTF_8.to_s) }
|
241
|
-
orig_attributes = orig_xml.xpath('//string').to_h { |tag| [tag['name'], tag.attributes.select { |k, _| attributes_to_copy.include?(k) }] }
|
242
249
|
|
243
250
|
locales_map.each do |lang_codes|
|
244
251
|
all_xml_documents = glotpress_filters.map do |filters|
|
@@ -250,13 +257,7 @@ module Fastlane
|
|
250
257
|
# Merge all XMLs together
|
251
258
|
merged_xml = merge_xml_documents(all_xml_documents)
|
252
259
|
|
253
|
-
|
254
|
-
merged_xml.xpath('//string').each do |string_tag|
|
255
|
-
apply_substitutions(string_tag)
|
256
|
-
orig_attributes[string_tag['name']]&.each { |k, v| string_tag[k] = v }
|
257
|
-
quick_lint(string_tag, lang_codes[:android])
|
258
|
-
end
|
259
|
-
merged_xml.xpath('//string-array/item').each { |item_tag| apply_substitutions(item_tag) }
|
260
|
+
post_process_xml!(merged_xml, locale_code: lang_codes[:android], original_xml: orig_xml)
|
260
261
|
|
261
262
|
# Save
|
262
263
|
lang_dir = File.join(res_dir, "values-#{lang_codes[:android]}")
|
@@ -266,8 +267,10 @@ module Fastlane
|
|
266
267
|
end
|
267
268
|
end
|
268
269
|
|
270
|
+
# @!endgroup
|
271
|
+
|
269
272
|
#####################
|
270
|
-
# Private Helpers
|
273
|
+
# @!group Private Helpers
|
271
274
|
#####################
|
272
275
|
|
273
276
|
# Downloads the export from GlotPress for a given locale and given filters
|
@@ -276,7 +279,7 @@ module Fastlane
|
|
276
279
|
# @param [String] locale The GlotPress locale code to download strings for.
|
277
280
|
# @param [Hash{Symbol=>String}] filters The hash of filters to apply when exporting from GlotPress.
|
278
281
|
# Typical examples include `{ status: 'current' }` or `{ status: 'review' }`.
|
279
|
-
# @return [Nokogiri::XML] the download XML document, parsed as a Nokogiri::XML object
|
282
|
+
# @return [Nokogiri::XML::Document] the download XML document, parsed as a Nokogiri::XML object
|
280
283
|
#
|
281
284
|
def self.download_glotpress_export_file(project_url:, locale:, filters:)
|
282
285
|
query_params = filters.transform_keys { |k| "filters[#{k}]" }.merge(format: 'android')
|
@@ -297,6 +300,9 @@ module Fastlane
|
|
297
300
|
|
298
301
|
# Merge multiple Nokogiri::XML `strings.xml` documents together
|
299
302
|
#
|
303
|
+
# Used especially when we provided multiple GlotPress filters to `download_from_glotpress`,
|
304
|
+
# as in this case we'd trigger one export per filter, then merge the result in a single XML
|
305
|
+
#
|
300
306
|
# @param [Array<Nokogiri::XML::Document>] all_xmls Array of the Nokogiri XML documents to merge together
|
301
307
|
# @return [Nokogiri::XML::Document] The merged document.
|
302
308
|
#
|
@@ -323,11 +329,53 @@ module Fastlane
|
|
323
329
|
end
|
324
330
|
private_class_method :merge_xml_documents
|
325
331
|
|
326
|
-
#
|
332
|
+
# Process a downloaded XML (in-place), to apply the following
|
333
|
+
# - replicate attributes from the nodes of the original XML (`translatable`, `tools:ignore`, …) to the translated XML
|
334
|
+
# - text substitutions for common special characters
|
335
|
+
# - quick-lint string by searching for common issue patterns (using `%%` in a `formatted=false` string, etc)
|
336
|
+
#
|
337
|
+
# @param [Nokogiri::XML::Document] translated_xml The downloaded XML to post-process
|
338
|
+
# @param [String] locale_code The android locale code associated with the translated_xml
|
339
|
+
# @param [Nokogiri::XML::Document] original_xml The original `values/strings.xml` to use as reference
|
340
|
+
#
|
341
|
+
def self.post_process_xml!(translated_xml, locale_code:, original_xml:)
|
342
|
+
copy_orig_attributes = lambda do |node, xpath|
|
343
|
+
orig_attributes = original_xml.xpath(xpath)&.first&.attribute_nodes&.to_h do |attr|
|
344
|
+
[[attr.namespace&.prefix, attr.name].compact.join(':'), attr.value]
|
345
|
+
end
|
346
|
+
orig_attributes&.each { |k, v| node[k] = v unless k == 'name' }
|
347
|
+
end
|
348
|
+
|
349
|
+
# 1. Replicate namespaces on the document (especially `xmlns:tools` if present)
|
350
|
+
original_xml.namespaces.each { |k, v| translated_xml.root&.add_namespace(k.delete_prefix('xmlns:'), v) }
|
351
|
+
# 2. Replicate attributes on any node with `@name` attribute (`string`, `string-array`, `plurals`)
|
352
|
+
translated_xml.xpath('//*[@name]').each do |node|
|
353
|
+
copy_orig_attributes.call(node, "//#{node.name}[@name = '#{node['name']}']")
|
354
|
+
end
|
355
|
+
# 3. Process copies for `string` nodes
|
356
|
+
translated_xml.xpath('//string[@name]').each do |string_node|
|
357
|
+
apply_substitutions!(string_node)
|
358
|
+
quick_lint(string_node, locale_code)
|
359
|
+
end
|
360
|
+
# 4. Process copies for `string-array/item` nodes
|
361
|
+
translated_xml.xpath('//string-array[@name]/item').each do |item_node|
|
362
|
+
apply_substitutions!(item_node)
|
363
|
+
quick_lint(item_node, locale_code)
|
364
|
+
end
|
365
|
+
# 5. Replicate attributes + Process copies for `plurals/item` nodes
|
366
|
+
translated_xml.xpath('//plurals[@name]/item[@quantity]').each do |item_node|
|
367
|
+
copy_orig_attributes.call(item_node, "//plurals[@name = '#{item_node.parent['name']}']/item[@quantity = '#{item_node['quantity']}']")
|
368
|
+
apply_substitutions!(item_node)
|
369
|
+
quick_lint(item_node, locale_code)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
private_class_method :post_process_xml!
|
373
|
+
|
374
|
+
# Apply some common text substitutions to tag contents, like `... => …` or en-dash instead of regular dash for ranges of numbers
|
327
375
|
#
|
328
376
|
# @param [Nokogiri::XML::Node] tag The XML tag/node to apply substitutions to
|
329
377
|
#
|
330
|
-
def self.apply_substitutions(tag)
|
378
|
+
def self.apply_substitutions!(tag)
|
331
379
|
tag.content = tag.content.gsub('...', '…')
|
332
380
|
|
333
381
|
# Typography en-dash
|
@@ -339,17 +387,28 @@ module Fastlane
|
|
339
387
|
is_negative_number ? str : "#{match[1]}\u{2013}#{match[2]}"
|
340
388
|
end
|
341
389
|
end
|
342
|
-
private_class_method :apply_substitutions
|
390
|
+
private_class_method :apply_substitutions!
|
343
391
|
|
344
|
-
# Perform some quick basic checks about an individual `<string>` tag and print warnings accordingly
|
392
|
+
# Perform some quick basic checks about an individual `<string>` tag and print warnings accordingly:
|
393
|
+
# - detect the use of `%%` in the string even if `formatted=false` is set
|
394
|
+
# - detect the presence of `\@string/` in translated XML, which suggests the original key that referenced `@string/…` did not set `translatable=false`
|
395
|
+
# and thus that `@string/…` copy was sent to GlotPress for translation, then escaped during exporting it back.
|
345
396
|
#
|
346
|
-
# @param [Nokogiri::XML::Node]
|
397
|
+
# @param [Nokogiri::XML::Node] node The XML tag/node to check the content of
|
347
398
|
# @param [String] lang The language we are currently processing. Used for providing context during logging / warning message
|
348
399
|
#
|
349
|
-
def self.quick_lint(
|
350
|
-
|
351
|
-
|
352
|
-
|
400
|
+
def self.quick_lint(node, lang)
|
401
|
+
named_node = node.has_attribute?('name') ? node : node.parent
|
402
|
+
if named_node['formatted'] == 'false' && node.content.include?('%%')
|
403
|
+
UI.important "Warning: [#{lang}] translation for '#{named_node['name']}' has attribute formatted=false, but still contains escaped '%%' in translation."
|
404
|
+
end
|
405
|
+
# rubocop:disable Style/GuardClause
|
406
|
+
if node.content.include?('\\@string/')
|
407
|
+
UI.important "Warning: [#{lang}] exported translation for '#{named_node['name']}' contains `\\@string/`. This is a sign that this entry was not marked as `translatable=false` " \
|
408
|
+
+ 'in the original `values/strings.xml`, and was thus sent to GlotPress, which added the backslash when exporting it back.'
|
409
|
+
node.content = node.content.gsub('\\@string/', '@string/')
|
410
|
+
end
|
411
|
+
# rubocop:enable Style/GuardClause
|
353
412
|
end
|
354
413
|
private_class_method :quick_lint
|
355
414
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-wpmreleasetoolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 11.0.
|
4
|
+
version: 11.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Automattic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|