fastlane-plugin-wpmreleasetoolkit 2.2.0 → 3.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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_localize_libs_action.rb +8 -3
  3. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_betabuild_prechecks.rb +8 -2
  4. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_release.rb +11 -4
  5. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_codefreeze_prechecks.rb +10 -4
  6. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/buildkite_trigger_build_action.rb +90 -0
  7. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_downloadmetadata_action.rb +1 -1
  8. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb +112 -0
  9. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_betabuild_prechecks.rb +8 -2
  10. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_release.rb +10 -5
  11. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_codefreeze_prechecks.rb +10 -4
  12. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_download_strings_files_from_glotpress.rb +113 -0
  13. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_extract_keys_from_strings_files.rb +118 -0
  14. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb +1 -1
  15. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_lint_localizations.rb +5 -5
  16. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_localize_project.rb +2 -2
  17. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_strings_files.rb +75 -0
  18. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_git_helper.rb +0 -20
  19. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_localize_helper.rb +8 -0
  20. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb +3 -0
  21. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_git_helper.rb +3 -2
  22. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_helper.rb +108 -173
  23. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_linter_helper.rb +207 -0
  24. data/lib/fastlane/plugin/wpmreleasetoolkit/helper/promo_screenshots_helper.rb +3 -3
  25. data/lib/fastlane/plugin/wpmreleasetoolkit/models/file_reference.rb +1 -4
  26. data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
  27. metadata +25 -39
  28. data/bin/drawText +0 -20
  29. data/ext/drawText/drawText/Assets/style.css +0 -1
  30. data/ext/drawText/drawText/CoreTextStack.swift +0 -113
  31. data/ext/drawText/drawText/Helpers/CommandLineHelpers.swift +0 -36
  32. data/ext/drawText/drawText/Helpers/Extensions.swift +0 -27
  33. data/ext/drawText/drawText/Helpers/FileSystemHelper.swift +0 -24
  34. data/ext/drawText/drawText/Stylesheet.swift +0 -48
  35. data/ext/drawText/drawText/TextImage.swift +0 -100
  36. data/ext/drawText/drawText/main.swift +0 -61
  37. data/ext/drawText/drawText Tests/DigitParsingTests.swift +0 -21
  38. data/ext/drawText/drawText Tests/ExtensionsTests.swift +0 -5
  39. data/ext/drawText/drawText Tests/Info.plist +0 -22
  40. data/ext/drawText/drawText Tests/StylesheetTests.swift +0 -31
  41. data/ext/drawText/drawText Tests/Test Cases/default-stylesheet.txt +0 -10
  42. data/ext/drawText/drawText Tests/Test Cases/external-styles-sample.css +0 -3
  43. data/ext/drawText/drawText Tests/Test Cases/external-styles-test.txt +0 -13
  44. data/ext/drawText/drawText Tests/Test Cases/large-text-block.txt +0 -1
  45. data/ext/drawText/drawText Tests/Test Cases/regular-text-block.txt +0 -2
  46. data/ext/drawText/drawText Tests/Test Cases/rtl-text-block.txt +0 -2
  47. data/ext/drawText/drawText Tests/Test Cases/text-size-adjustment-test.txt +0 -10
  48. data/ext/drawText/drawText Tests/TextImageTests.swift +0 -99
  49. data/ext/drawText/drawText Tests/drawText_Tests.swift +0 -14
  50. data/ext/drawText/drawText.xcodeproj/project.pbxproj +0 -508
  51. data/ext/drawText/drawText.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  52. data/ext/drawText/drawText.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  53. data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText Tests.xcscheme +0 -57
  54. data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText.xcscheme +0 -109
  55. data/ext/drawText/extconf.rb +0 -36
  56. data/ext/drawText/makefile.example +0 -8
  57. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_merge_translators_strings.rb +0 -106
  58. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_metadata.rb +0 -52
  59. data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_translators_strings.rb +0 -93
@@ -0,0 +1,118 @@
1
+ module Fastlane
2
+ module Actions
3
+ class IosExtractKeysFromStringsFilesAction < Action
4
+ def self.run(params)
5
+ source_parent_dir = params[:source_parent_dir]
6
+ target_original_files = params[:target_original_files]
7
+ keys_to_extract_per_target_file = keys_list_per_target_file(target_original_files)
8
+
9
+ # For each locale, extract the right translations from `<source_tablename>.strings` into each target `.strings` file
10
+ Dir.glob('*.lproj', base: source_parent_dir).each do |lproj_dir_name|
11
+ source_strings_file = File.join(source_parent_dir, lproj_dir_name, "#{params[:source_tablename]}.strings")
12
+ translations = Fastlane::Helper::Ios::L10nHelper.read_strings_file_as_hash(path: source_strings_file)
13
+
14
+ target_original_files.each do |target_original_file|
15
+ target_strings_file = File.join(File.dirname(File.dirname(target_original_file)), lproj_dir_name, File.basename(target_original_file))
16
+ next if target_strings_file == target_original_file # do not generate/overwrite the original locale itself
17
+
18
+ keys_to_extract = keys_to_extract_per_target_file[target_original_file]
19
+ UI.message("Extracting #{keys_to_extract.count} keys into #{target_strings_file}...")
20
+
21
+ extracted_translations = translations.slice(*keys_to_extract)
22
+ FileUtils.mkdir_p(File.dirname(target_strings_file)) # Ensure path up to parent dir exists, create it if not.
23
+ Fastlane::Helper::Ios::L10nHelper.generate_strings_file_from_hash(translations: extracted_translations, output_path: target_strings_file)
24
+ rescue StandardError => e
25
+ UI.user_error!("Error while writing extracted translations to `#{target_strings_file}`: #{e.message}")
26
+ end
27
+ rescue StandardError => e
28
+ UI.user_error!("Error while reading the translations from source file `#{source_strings_file}`: #{e.message}")
29
+ end
30
+ end
31
+
32
+ # Pre-load the list of keys to extract for each target file.
33
+ #
34
+ # @param [Array<String>] original_files array of paths to the originals of target files
35
+ # @return [Hash<String, Array<String>>] The hash listing the keys to extract for each target file
36
+ #
37
+ def self.keys_list_per_target_file(original_files)
38
+ original_files.map do |original_file|
39
+ keys = Fastlane::Helper::Ios::L10nHelper.read_strings_file_as_hash(path: original_file).keys
40
+ [original_file, keys]
41
+ end.to_h
42
+ rescue StandardError => e
43
+ UI.user_error!("Failed to read the keys to extract from originals file: #{e.message}")
44
+ end
45
+
46
+ #####################################################
47
+ # @!group Documentation
48
+ #####################################################
49
+
50
+ def self.description
51
+ 'Extracts a subset of keys from a `.strings` file into separate `.strings` file(s)'
52
+ end
53
+
54
+ def self.details
55
+ <<~DETAILS
56
+ Extracts a subset of keys from a `.strings` file into separate `.strings` file(s), for each `*.lproj` subdirectory.
57
+
58
+ This is especially useful to extract, for each locale, the translations for files like `InfoPlist.strings` or
59
+ `<SomeIntentDefinitionFile>.strings` from the `Localizable.strings` file that we exported/downloaded back from GlotPress.
60
+
61
+ Since we typically merge all `*.strings` original files (e.g. `en.lproj/Localizable.strings` + `en.lproj/InfoPlist.strings` + …)
62
+ via `ios_merge_strings_file` before sending the originals to translations, we then need to extract the relevant keys and
63
+ translations back into the `*.lproj/InfoPlist.strings` after we pull those translations back from GlotPress
64
+ (`ios_download_strings_files_from_glotpress`). This is what this `ios_extract_keys_from_strings_files` action is for.
65
+ DETAILS
66
+ end
67
+
68
+ def self.available_options
69
+ [
70
+ FastlaneCore::ConfigItem.new(key: :source_parent_dir,
71
+ env_name: 'FL_IOS_EXTRACT_KEYS_FROM_STRINGS_FILES_SOURCE_PARENT_DIR',
72
+ description: 'The parent directory containing all the `*.lproj` subdirectories in which the source `.strings` files reside',
73
+ type: String,
74
+ verify_block: proc do |value|
75
+ UI.user_error!("`source_parent_dir` should be a path to an existing directory, but found `#{value}`.") unless File.directory?(value)
76
+ UI.user_error!("`source_parent_dir` should contain at least one `.lproj` subdirectory, but `#{value}` does not contain any.") if Dir.glob('*.lproj', base: value).empty?
77
+ end),
78
+ FastlaneCore::ConfigItem.new(key: :source_tablename,
79
+ env_name: 'FL_IOS_EXTRACT_KEYS_FROM_STRINGS_FILES_SOURCE_TABLENAME',
80
+ description: 'The basename of the `.strings` file (without the extension) to extract the keys and translations from for each locale',
81
+ type: String,
82
+ default_value: 'Localizable'),
83
+ FastlaneCore::ConfigItem.new(key: :target_original_files,
84
+ env_name: 'FL_IOS_EXTRACT_KEYS_FROM_STRINGS_FILES_TARGET_ORIGINAL_FILES',
85
+ description: 'The path(s) to the `<base-locale>.lproj/<target-tablename>.strings` file(s) for which we want to extract the keys to. ' \
86
+ + 'Each of those files should containing the original strings (typically `en` or `Base` locale) and will be used to determine which keys to extract from the `source_tablename`. ' \
87
+ + 'For each of those, the path(s) in which the translations will be extracted will be the files with the same basename in each of the other `*.lproj` sibling folders',
88
+ type: Array,
89
+ verify_block: proc do |values|
90
+ UI.user_error!('`target_original_files` must contain at least one path to an original `.strings` file.') if values.empty?
91
+ values.each do |v|
92
+ UI.user_error!("Path `#{v}` (found in `target_original_files`) does not exist.") unless File.exist?(v)
93
+ UI.user_error! "Expected `#{v}` (found in `target_original_files`) to be a path ending in a `*.lproj/*.strings`." unless File.extname(v) == '.strings' && File.extname(File.dirname(v)) == '.lproj'
94
+ end
95
+ end),
96
+ ]
97
+ end
98
+
99
+ def self.return_type
100
+ # Describes what type of data is expected to be returned
101
+ # see RETURN_TYPES in https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/action.rb
102
+ nil
103
+ end
104
+
105
+ def self.return_value
106
+ # Freeform textual description of the return value
107
+ end
108
+
109
+ def self.authors
110
+ ['Automattic']
111
+ end
112
+
113
+ def self.is_supported?(platform)
114
+ [:ios, :mac].include?(platform)
115
+ end
116
+ end
117
+ end
118
+ end
@@ -36,7 +36,7 @@ module Fastlane
36
36
  #####################################################
37
37
 
38
38
  def self.description
39
- 'Generate the .strings files from your Objective-C and Swift code'
39
+ 'Generate the `.strings` files from your Objective-C and Swift code'
40
40
  end
41
41
 
42
42
  def self.details
@@ -17,8 +17,8 @@ module Fastlane
17
17
  def self.run_linter(params)
18
18
  UI.message 'Linting localizations for parameter placeholders consistency...'
19
19
 
20
- require_relative '../../helper/ios/ios_l10n_helper'
21
- helper = Fastlane::Helper::Ios::L10nHelper.new(
20
+ require_relative '../../helper/ios/ios_l10n_linter_helper'
21
+ helper = Fastlane::Helper::Ios::L10nLinterHelper.new(
22
22
  install_path: resolve_path(params[:install_path]),
23
23
  version: params[:version]
24
24
  )
@@ -92,7 +92,7 @@ module Fastlane
92
92
  description: 'The path where to install the SwiftGen tooling needed to run the linting process. If a relative path, should be relative to your repo_root',
93
93
  type: String,
94
94
  optional: true,
95
- default_value: "vendor/swiftgen/#{Fastlane::Helper::Ios::L10nHelper::SWIFTGEN_VERSION}"
95
+ default_value: "vendor/swiftgen/#{Fastlane::Helper::Ios::L10nLinterHelper::SWIFTGEN_VERSION}"
96
96
  ),
97
97
  FastlaneCore::ConfigItem.new(
98
98
  key: :version,
@@ -100,7 +100,7 @@ module Fastlane
100
100
  description: 'The version of SwiftGen to install and use for linting',
101
101
  type: String,
102
102
  optional: true,
103
- default_value: Fastlane::Helper::Ios::L10nHelper::SWIFTGEN_VERSION
103
+ default_value: Fastlane::Helper::Ios::L10nLinterHelper::SWIFTGEN_VERSION
104
104
  ),
105
105
  FastlaneCore::ConfigItem.new(
106
106
  key: :input_dir,
@@ -115,7 +115,7 @@ module Fastlane
115
115
  description: 'The language that should be used as the base language that every other language will be compared against',
116
116
  type: String,
117
117
  optional: true,
118
- default_value: Fastlane::Helper::Ios::L10nHelper::DEFAULT_BASE_LANG
118
+ default_value: Fastlane::Helper::Ios::L10nLinterHelper::DEFAULT_BASE_LANG
119
119
  ),
120
120
  FastlaneCore::ConfigItem.new(
121
121
  key: :only_langs,
@@ -16,11 +16,11 @@ module Fastlane
16
16
  #####################################################
17
17
 
18
18
  def self.description
19
- 'Gathers the string to localise'
19
+ 'Gathers the strings to localise. Deprecated'
20
20
  end
21
21
 
22
22
  def self.details
23
- 'Gathers the string to localise. Deprecated in favor of the new `ios_generate_strings_file_from_code`'
23
+ 'Gathers the strings to localise. Deprecated in favor of the new `ios_generate_strings_file_from_code`'
24
24
  end
25
25
 
26
26
  def self.category
@@ -0,0 +1,75 @@
1
+ module Fastlane
2
+ module Actions
3
+ class IosMergeStringsFilesAction < Action
4
+ def self.run(params)
5
+ UI.message "Merging strings files: #{params[:paths].inspect}"
6
+
7
+ duplicates = Fastlane::Helper::Ios::L10nHelper.merge_strings(paths: params[:paths], output_path: params[:destination])
8
+ duplicates.each do |dup_key|
9
+ UI.important "Duplicate key found while merging the `.strings` files: `#{dup_key}`"
10
+ end
11
+ duplicates
12
+ end
13
+
14
+ #####################################################
15
+ # @!group Documentation
16
+ #####################################################
17
+
18
+ def self.description
19
+ 'Merge multiple `.strings` files into one'
20
+ end
21
+
22
+ def self.details
23
+ <<~DETAILS
24
+ Merge multiple `.strings` files into one.
25
+
26
+ Especially useful to prepare a single `.strings` file merging strings from both `Localizable.strings` from
27
+ the app code — typically previously extracted from `ios_generate_strings_file_from_code` —
28
+ and string files like `InfoPlist.strings` — which values may not be generated from the codebase but
29
+ manually maintained by developers.
30
+
31
+ The action only supports merging files which are in the OpenStep (`"key" = "value";`) text format (which is
32
+ the most common format for `.strings` files, and the one generated by `genstrings`), but can handle the case
33
+ of different files using different encodings (UTF8 vs UTF16) and is able to detect and report duplicates.
34
+ It does not handle `.strings` files in XML or binary-plist formats (which are valid but more rare)
35
+ DETAILS
36
+ end
37
+
38
+ def self.available_options
39
+ [
40
+ FastlaneCore::ConfigItem.new(
41
+ key: :paths,
42
+ env_name: 'FL_IOS_MERGE_STRINGS_FILES_PATHS',
43
+ description: 'The paths of all the `.strings` files to merge together',
44
+ type: Array,
45
+ optional: false
46
+ ),
47
+ FastlaneCore::ConfigItem.new(
48
+ key: :destination,
49
+ env_name: 'FL_IOS_MERGE_STRINGS_FILES_DESTINATION',
50
+ description: 'The path of the merged `.strings` file to generate. If nil, the merge will happen in-place in the first file in the `paths:` list',
51
+ type: String,
52
+ optional: true,
53
+ default_value: nil
54
+ ),
55
+ ]
56
+ end
57
+
58
+ def self.return_type
59
+ :array_of_strings
60
+ end
61
+
62
+ def self.return_value
63
+ 'The list of duplicate keys found while merging the various `.strings` files'
64
+ end
65
+
66
+ def self.authors
67
+ ['automattic']
68
+ end
69
+
70
+ def self.is_supported?(platform)
71
+ [:ios, :mac].include? platform
72
+ end
73
+ end
74
+ end
75
+ end
@@ -27,26 +27,6 @@ module Fastlane
27
27
  )
28
28
  end
29
29
  end
30
-
31
- # Calls the `tools/update-translations.sh` script from the project repo, then lint them using the provided gradle task
32
- #
33
- # Deprecated. Use the `android_download_translations` action instead.
34
- #
35
- # @env PROJECT_ROOT_FOLDER The path to the git root of the project
36
- # @env PROJECT_NAME The name of the directory containing the project code (especially containing the `build.gradle` file)
37
- #
38
- # @param [String] validate_translation_command The name of the gradle task to run to validate the translations
39
- #
40
- # @todo Remove this once every client has migrated to `android_download_translations` and we got rid of that legacy action.
41
- #
42
- def self.update_metadata(validate_translation_command)
43
- Action.sh('./tools/update-translations.sh')
44
- Action.sh('git', 'submodule', 'update', '--init', '--recursive')
45
- Action.sh('./gradlew', validate_translation_command)
46
-
47
- res_dir = File.join(ENV['PROJECT_ROOT_FOLDER'], ENV['PROJECT_NAME'], 'src', 'main', 'res')
48
- Fastlane::Helper::GitHelper.commit(message: 'Update translations', files: res_dir, push: true)
49
- end
50
30
  end
51
31
  end
52
32
  end
@@ -92,6 +92,14 @@ module Fastlane
92
92
  UI.user_error!("String #{string_name} [#{string_content}] was found in library #{library[:library]} but not in the main file.")
93
93
  end
94
94
 
95
+ # Merge strings from a library into the strings.xml of the main app
96
+ #
97
+ # @param [String] main Path to the main strings.xml file (something like `…/res/values/strings.xml`)
98
+ # @param [Hash] library Hash describing the library to merge. The Hash should contain the following keys:
99
+ # - `:library`: The human readable name of the library, used to display in console messages
100
+ # - `:strings_path`: The path to the strings.xml file of the library to merge into the main one
101
+ # - `:exclusions`: An array of strings keys to exclude during merge. Any of those keys from the library's `strings.xml` will be skipped and won't be merged into the main one.
102
+ # @return [Boolean] True if at least one string from the library has been added to (or has updated) the main strings file.
95
103
  def self.merge_lib(main, library)
96
104
  UI.message("Merging #{library[:library]} strings into #{main}")
97
105
  main_strings = File.open(main) { |f| Nokogiri::XML(f, nil, Encoding::UTF_8.to_s) }
@@ -5,6 +5,9 @@ module Fastlane
5
5
  # Helper methods to execute git-related operations
6
6
  #
7
7
  module GitHelper
8
+ # Fallback default branch of the client repository.
9
+ DEFAULT_GIT_BRANCH = 'trunk'.freeze
10
+
8
11
  # Checks if the given path, or current directory if no path is given, is
9
12
  # inside a Git repository
10
13
  #
@@ -35,8 +35,9 @@ module Fastlane
35
35
  # @env PROJECT_ROOT_FOLDER The path to the git root of the project
36
36
  # @env PROJECT_NAME The name of the directory containing the project code (especially containing the `build.gradle` file)
37
37
  #
38
- # @todo Migrate the scripts, currently in each host repo and called by this method, to be helpers and actions
39
- # in the release-toolkit instead, and move this code away from `ios_git_helper`.
38
+ # @deprecated This method is only used by the `ios_localize_project` action, which is itself deprecated
39
+ # in favor of the new `ios_generate_strings_file_from_code` action
40
+ # @todo [Next Major] Remove this method once we fully remove `ios_localize_project`
40
41
  #
41
42
  def self.localize_project
42
43
  Action.sh("cd #{get_from_env!(key: 'PROJECT_ROOT_FOLDER')} && ./Scripts/localize.py")