fastlane-plugin-wpmreleasetoolkit 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2f92b2b90c9f077ad4ea0ae25c5c84f0345ca2fb5e186d1c0cdfab70ea40770
4
- data.tar.gz: 0c919f8e9ca2af18c3488898efe2fe48f4ca5a3a4c0464991e000681cc6c9546
3
+ metadata.gz: 87b7167d8eeecefac13e31850447419c88d3e2ceca851a89782df561846f4b7b
4
+ data.tar.gz: 72b18c319cfbac6d39ea939c33cd801f1e777b79996ee617ea0649c0c3bfb420
5
5
  SHA512:
6
- metadata.gz: f0c0797c28da54495d995d856edb238631b70bf0126ae1516638a75e300717dd51a7f97f6fedd5cc3f9e7eef4e9cf328043c9fffcd34233a057338da8055307d
7
- data.tar.gz: 17c8536dc94ab2ea0f3b394d3d9768c248683ba78fa4558d7c10ed1cc7fe81fc0aebd1390691282db601297b6f48e67af2dbd546daa3b0a13d16ffacd8c34f4c
6
+ metadata.gz: 96c46a423eb4eaf0868bc5a6cecb6558a99dcf9f5f7b788bdc4255a2380aea4ed8adbd92d81476feaad00fc394182c70257aa140e7281920348b3ba8878bafba
7
+ data.tar.gz: 5329bbb8827fd617af2d43dd1c770e2cf9a23e6adce430bf658f2ee68fe11cda3ac1e5d52f76ced293c28f23df3a9315a882cce14ad7f7918c370ed1be07b2e0
@@ -0,0 +1,112 @@
1
+ require 'fastlane/action'
2
+ require 'digest/sha1'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ module SharedValues
7
+ S3_UPLOADED_FILE_PATH = :S3_UPLOADED_FILE_PATH
8
+ end
9
+
10
+ class UploadToS3Action < Action
11
+ def self.run(params)
12
+ file_path = params[:file]
13
+ file_name = File.basename(file_path)
14
+
15
+ bucket = params[:bucket]
16
+ key = params[:key] || file_name
17
+
18
+ if params[:auto_prefix] == true
19
+ file_name_hash = Digest::SHA1.hexdigest(file_name)
20
+ key = [file_name_hash, key].join('/')
21
+ end
22
+
23
+ UI.user_error!("File already exists in S3 bucket #{bucket} at #{key}") if file_is_already_uploaded?(bucket, key)
24
+
25
+ UI.message("Uploading #{file_path} to: #{key}")
26
+
27
+ File.open(file_path, 'rb') do |file|
28
+ Aws::S3::Client.new().put_object(
29
+ body: file,
30
+ bucket: bucket,
31
+ key: key
32
+ )
33
+ rescue Aws::S3::Errors::ServiceError => e
34
+ UI.crash!("Unable to upload file to S3: #{e.message}")
35
+ end
36
+
37
+ UI.success('Upload Complete')
38
+
39
+ Actions.lane_context[SharedValues::S3_UPLOADED_FILE_PATH] = key
40
+
41
+ return key
42
+ end
43
+
44
+ def self.file_is_already_uploaded?(bucket, key)
45
+ response = Aws::S3::Client.new().head_object(
46
+ bucket: bucket,
47
+ key: key
48
+ )
49
+ return response[:content_length].positive?
50
+ rescue Aws::S3::Errors::NotFound
51
+ return false
52
+ end
53
+
54
+ def self.description
55
+ 'Uploads a given file to S3'
56
+ end
57
+
58
+ def self.authors
59
+ ['Automattic']
60
+ end
61
+
62
+ def self.return_value
63
+ 'Returns the object\'s derived S3 key'
64
+ end
65
+
66
+ def self.details
67
+ 'Uploads a file to S3, and makes a pre-signed URL available in the lane context'
68
+ end
69
+
70
+ def self.available_options
71
+ [
72
+ FastlaneCore::ConfigItem.new(
73
+ key: :bucket,
74
+ description: 'The bucket that will store the file',
75
+ optional: false,
76
+ type: String,
77
+ verify_block: proc { |bucket| UI.user_error!('You must provide a valid bucket name') if bucket.empty? }
78
+ ),
79
+ FastlaneCore::ConfigItem.new(
80
+ key: :key,
81
+ description: 'The path to the file within the bucket. If `nil`, will default to the `file\'s basename',
82
+ optional: true,
83
+ type: String,
84
+ verify_block: proc { |key|
85
+ next if key.is_a?(String) && !key.empty?
86
+
87
+ UI.user_error!('The provided key must not be empty. Use nil instead if you want to default to the file basename')
88
+ }
89
+ ),
90
+ FastlaneCore::ConfigItem.new(
91
+ key: :file,
92
+ description: 'The path to the local file on disk',
93
+ optional: false,
94
+ type: String,
95
+ verify_block: proc { |f| UI.user_error!("Path `#{f}` does not exist.") unless File.file?(f) }
96
+ ),
97
+ FastlaneCore::ConfigItem.new(
98
+ key: :auto_prefix,
99
+ description: 'Generate a derived prefix based on the filename that makes it harder to guess the URL of the uploaded object',
100
+ optional: true,
101
+ default_value: true,
102
+ type: Boolean
103
+ ),
104
+ ]
105
+ end
106
+
107
+ def self.is_supported?(platform)
108
+ true
109
+ end
110
+ end
111
+ end
112
+ end
@@ -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
@@ -108,7 +108,7 @@ module Fastlane
108
108
  xml.comment('Warning: Auto-generated file, do not edit.')
109
109
  xml.plist(version: '1.0') do
110
110
  xml.dict do
111
- translations.each do |k, v|
111
+ translations.sort.each do |k, v| # NOTE: use `sort` just in order to be deterministic over various runs
112
112
  xml.key(k.to_s)
113
113
  xml.string(v.to_s)
114
114
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Wpmreleasetoolkit
3
- VERSION = '3.0.0'
3
+ VERSION = '3.1.0'
4
4
  end
5
5
  end
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: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lorenzo Mattei
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-09 00:00:00.000000000 Z
11
+ date: 2022-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -401,6 +401,7 @@ files:
401
401
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/removebranchprotection_action.rb
402
402
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/setbranchprotection_action.rb
403
403
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/setfrozentag_action.rb
404
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb
404
405
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_add_files_to_copy_action.rb
405
406
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_apply_action.rb
406
407
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/configure/configure_download_action.rb
@@ -421,6 +422,7 @@ files:
421
422
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_completecodefreeze_prechecks.rb
422
423
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_current_branch_is_hotfix.rb
423
424
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_download_strings_files_from_glotpress.rb
425
+ - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_extract_keys_from_strings_files.rb
424
426
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_final_tag.rb
425
427
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_finalize_prechecks.rb
426
428
  - lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb