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.
- checksums.yaml +4 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_localize_libs_action.rb +8 -3
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_betabuild_prechecks.rb +8 -2
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_release.rb +11 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_codefreeze_prechecks.rb +10 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/buildkite_trigger_build_action.rb +90 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_downloadmetadata_action.rb +1 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/upload_to_s3.rb +112 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_betabuild_prechecks.rb +8 -2
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_release.rb +10 -5
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_codefreeze_prechecks.rb +10 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_download_strings_files_from_glotpress.rb +113 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_extract_keys_from_strings_files.rb +118 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb +1 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_lint_localizations.rb +5 -5
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_localize_project.rb +2 -2
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_merge_strings_files.rb +75 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_git_helper.rb +0 -20
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_localize_helper.rb +8 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/git_helper.rb +3 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_git_helper.rb +3 -2
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_helper.rb +108 -173
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/ios/ios_l10n_linter_helper.rb +207 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/promo_screenshots_helper.rb +3 -3
- data/lib/fastlane/plugin/wpmreleasetoolkit/models/file_reference.rb +1 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
- metadata +25 -39
- data/bin/drawText +0 -20
- data/ext/drawText/drawText/Assets/style.css +0 -1
- data/ext/drawText/drawText/CoreTextStack.swift +0 -113
- data/ext/drawText/drawText/Helpers/CommandLineHelpers.swift +0 -36
- data/ext/drawText/drawText/Helpers/Extensions.swift +0 -27
- data/ext/drawText/drawText/Helpers/FileSystemHelper.swift +0 -24
- data/ext/drawText/drawText/Stylesheet.swift +0 -48
- data/ext/drawText/drawText/TextImage.swift +0 -100
- data/ext/drawText/drawText/main.swift +0 -61
- data/ext/drawText/drawText Tests/DigitParsingTests.swift +0 -21
- data/ext/drawText/drawText Tests/ExtensionsTests.swift +0 -5
- data/ext/drawText/drawText Tests/Info.plist +0 -22
- data/ext/drawText/drawText Tests/StylesheetTests.swift +0 -31
- data/ext/drawText/drawText Tests/Test Cases/default-stylesheet.txt +0 -10
- data/ext/drawText/drawText Tests/Test Cases/external-styles-sample.css +0 -3
- data/ext/drawText/drawText Tests/Test Cases/external-styles-test.txt +0 -13
- data/ext/drawText/drawText Tests/Test Cases/large-text-block.txt +0 -1
- data/ext/drawText/drawText Tests/Test Cases/regular-text-block.txt +0 -2
- data/ext/drawText/drawText Tests/Test Cases/rtl-text-block.txt +0 -2
- data/ext/drawText/drawText Tests/Test Cases/text-size-adjustment-test.txt +0 -10
- data/ext/drawText/drawText Tests/TextImageTests.swift +0 -99
- data/ext/drawText/drawText Tests/drawText_Tests.swift +0 -14
- data/ext/drawText/drawText.xcodeproj/project.pbxproj +0 -508
- data/ext/drawText/drawText.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/ext/drawText/drawText.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText Tests.xcscheme +0 -57
- data/ext/drawText/drawText.xcodeproj/xcshareddata/xcschemes/drawText.xcscheme +0 -109
- data/ext/drawText/extconf.rb +0 -36
- data/ext/drawText/makefile.example +0 -8
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_merge_translators_strings.rb +0 -106
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_update_metadata.rb +0 -52
- 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
|
data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb
CHANGED
@@ -36,7 +36,7 @@ module Fastlane
|
|
36
36
|
#####################################################
|
37
37
|
|
38
38
|
def self.description
|
39
|
-
'Generate the
|
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/
|
21
|
-
helper = Fastlane::Helper::Ios::
|
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::
|
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::
|
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::
|
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
|
19
|
+
'Gathers the strings to localise. Deprecated'
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.details
|
23
|
-
'Gathers the
|
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
|
-
# @
|
39
|
-
#
|
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")
|