fastlane-plugin-wpmreleasetoolkit 2.2.0 → 3.1.0

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