fastlane-plugin-localize 0.1.0 → 1.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
- SHA1:
3
- metadata.gz: b9abc2c961cdbb0dfb43d435da11531ce84445d6
4
- data.tar.gz: 7e560ea153fb1b19fd10da4c506592e5c8de9513
2
+ SHA256:
3
+ metadata.gz: 44a29020ea890b0cd1af66e88acec9b82365c57e3dfffc3c2947bef6d2ff243b
4
+ data.tar.gz: ed5be6c7cd95fa51aaf26c4f84d3b974ab4e51903984be214302f3d70be965fc
5
5
  SHA512:
6
- metadata.gz: 374ea985d1bfe90ac4b9d3490979781657d3b41ae735af02e1d4a51f7e8ef9b1823868187ba475fc8aae3561de611662d8ee199b86b85135959bd748a8f1a285
7
- data.tar.gz: 705afb57d00e194c0e957876069cfdb39f2fbb1aa29741d5fe38a1fd8bae01a547420706d57a35723ecc2f432507b2805adfc075a0cfa49c68b5ee2783d70660
6
+ metadata.gz: 112308493533f28118e0622beac78952c48a65897f637b174e119b3462f9a94ad5d0cb8b17d2d5118a4e47cde633604120a628ac441649e18a5a449525263d12
7
+ data.tar.gz: 44e950b5735531cc135183e5d1321eabce0c42badbed3589618126e2ed38b8a3d0a9ecce517a4199b4a03e127af235f151eaa97b1507f48f797fe5588dec7991
data/README.md CHANGED
@@ -14,13 +14,38 @@ fastlane add_plugin localize
14
14
 
15
15
  Searches the code for extractable strings and allows interactive extraction to .strings file.
16
16
 
17
- **Note to author:** Add a more detailed description about this plugin here. If your plugin contains multiple actions, make sure to mention them here.
17
+ - Whitelists non-extracted strings for further runs
18
+ - Extracts as `NSLocalizedString` by default
19
+ - Support for [Swiftgen](https://github.com/SwiftGen/SwiftGen) by supplying `use_swiftgen:true`
18
20
 
19
- ## Example
21
+ ![Example Gif](https://github.com/num42/fastlane-plugin-localize/raw/master/Localize.gif)
20
22
 
21
- Check out the [example `Fastfile`](fastlane/Fastfile) to see how to use this plugin. Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
23
+ ## Run from Commandline
22
24
 
23
- **Note to author:** Please set up a sample project to make it easy for users to explore what your plugin does. Provide everything that is necessary to try out the plugin in this project (including a sample Xcode/Android project if necessary)
25
+ To show all options:
26
+
27
+ ```bash
28
+ fastlane action localize
29
+ ```
30
+
31
+ Example:
32
+
33
+ ```bash
34
+ fastlane run localize strings_file:"Sources/Base/Supporting Files/en.lproj/Localizable.strings" file_filter:"Swiftgen,Sourcery" use_swiftgen:"true"
35
+ ```
36
+
37
+ ## Run from Fastfile
38
+
39
+ ```ruby
40
+ desc "Search for localizable strings"
41
+ lane :localize_strings do
42
+ localize(
43
+ strings_file: "Sources/Base/Supporting Files/en.lproj/Localizable.strings",
44
+ file_filter: "Swiftgen,Sourcery", # filters files with these words in their path
45
+ use_swiftgen: "true" # remove to use NSLocalizableString instead
46
+ )
47
+ end
48
+ ```
24
49
 
25
50
  ## Run tests for this plugin
26
51
 
@@ -1,12 +1,13 @@
1
- require 'fastlane/action'
2
- require_relative '../helper/localize_helper'
1
+ require "fastlane/action"
2
+ require_relative "../helper/localize_helper"
3
3
 
4
4
  module Fastlane
5
5
  module Actions
6
6
  class LocalizeAction < Action
7
7
  def self.run(params)
8
8
  project = Helper::LocalizeHelper.getProject(params)
9
- target = Helper::LocalizeHelper.getTarget(project)
9
+
10
+ target = Helper::LocalizeHelper.getTarget(params)
10
11
 
11
12
  files = Helper::LocalizeHelper.codeFiles(target, params)
12
13
 
@@ -14,7 +15,6 @@ module Fastlane
14
15
  Helper::LocalizeHelper.stringsFromFile(file)
15
16
  end
16
17
 
17
-
18
18
  matchHash = {}
19
19
 
20
20
  matches.each do |match|
@@ -22,27 +22,29 @@ module Fastlane
22
22
  matchHash[match[0]] << match
23
23
  end
24
24
 
25
-
26
25
  whitelist = Helper::LocalizeHelper.getWhitelist
27
26
 
28
27
  matchHash.keys
29
- .map { |match|
28
+ .map { |match|
30
29
  match.gsub(/^\\"/, "\"").gsub(/\\"$/, "\"")
31
30
  }
32
- .reject { |match|
31
+ .reject { |match|
33
32
  whitelist.include? match
34
33
  }
35
- .each { |match|
36
-
37
- files.flat_map do |file|
38
- Helper::LocalizeHelper.showStringOccurrencesFromFile(file, match)
39
- end
40
-
41
- if UI.confirm "Extract #{match}?"
42
- key = UI.input "Enter key for localization:"
43
- Helper::LocalizeHelper.localize_string(match, key, files, params)
34
+ .each { |match|
35
+ if params[:lint_only]
36
+ puts "warning: #{match} is not localized"
44
37
  else
45
- Helper::LocalizeHelper.addToWhitelist(match)
38
+ files.flat_map do |file|
39
+ Helper::LocalizeHelper.showStringOccurrencesFromFile(file, match)
40
+ end
41
+
42
+ if UI.confirm "Extract #{match}?"
43
+ key = UI.input "Enter key for localization:"
44
+ Helper::LocalizeHelper.localize_string(match, key, files, params)
45
+ else
46
+ Helper::LocalizeHelper.addToWhitelist(match)
47
+ end
46
48
  end
47
49
  }
48
50
  end
@@ -67,29 +69,40 @@ module Fastlane
67
69
  def self.available_options
68
70
  [
69
71
  FastlaneCore::ConfigItem.new(key: :localize_project,
70
- env_name: "FL_LOCALIZE_PROJECT", # The name of the environment variable
71
- description: "The project to localize", # a short description of this parameter
72
- is_string: true, # true: verifies the input is a string, false: every kind of value
73
- default_value: Helper::LocalizeHelper.getProject(nil).path # the default value if the user didn't provide one
74
- ),
72
+ env_name: "FL_LOCALIZE_PROJECT", # The name of the environment variable
73
+ description: "The project to localize", # a short description of this parameter
74
+ is_string: true, # true: verifies the input is a string, false: every kind of value
75
+ default_value: Helper::LocalizeHelper.getProject(nil).path # the default value if the user didn't provide one
76
+ ),
77
+ FastlaneCore::ConfigItem.new(key: :localize_target,
78
+ env_name: "FL_LOCALIZE_TARGET", # The name of the environment variable
79
+ description: "The target to localize", # a short description of this parameter
80
+ is_string: true, # true: verifies the input is a string, false: every kind of value
81
+ default_value: Helper::LocalizeHelper.getTargetName(nil) # the default value if the user didn't provide one
82
+ ),
75
83
  FastlaneCore::ConfigItem.new(key: :use_swiftgen,
76
84
  env_name: "FL_LOCALIZE_USE_SWIFTGEN", # The name of the environment variable
77
85
  description: "Localize using Swiftgens L10n ", # a short description of this parameter
78
86
  is_string: false, # true: verifies the input is a string, false: every kind of value
79
87
  default_value: false # the default value if the user didn't provide one
80
- ),
88
+ ),
81
89
  FastlaneCore::ConfigItem.new(key: :strings_file,
82
90
  env_name: "FL_LOCALIZE_STRINGS_FILE",
83
91
  description: "The stringsfile to write to",
84
92
  is_string: true, # true: verifies the input is a string, false: every kind of value
85
93
  default_value: "Localizable.strings" # the default value if the user didn't provide one,
86
- ),
87
- FastlaneCore::ConfigItem.new(key: :file_filter,
88
- env_name: "FL_LOCALIZE_FILE_FILTER",
89
- description: "Filter strings for file paths to ignore, separated by commas",
90
- optional: true,
91
- is_string: false
92
- )
94
+ ),
95
+ FastlaneCore::ConfigItem.new(key: :file_filter,
96
+ env_name: "FL_LOCALIZE_FILE_FILTER",
97
+ description: "Filter strings for file paths to ignore, separated by commas",
98
+ optional: true,
99
+ is_string: false),
100
+ FastlaneCore::ConfigItem.new(key: :lint_only,
101
+ env_name: "FL_LOCALIZE_LINT_ONLY", # The name of the environment variable
102
+ description: "Only lint and print warnings for unlocalized strings. ", # a short description of this parameter
103
+ is_string: false, # true: verifies the input is a string, false: every kind of value
104
+ default_value: false # the default value if the user didn't provide one
105
+ ),
93
106
  ]
94
107
  end
95
108
 
@@ -1,4 +1,4 @@
1
- require 'fastlane_core/ui/ui'
1
+ require "fastlane_core/ui/ui"
2
2
 
3
3
  module Fastlane
4
4
  UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
@@ -9,8 +9,7 @@ module Fastlane
9
9
  # as `Helper::LocalizeHelper.your_method`
10
10
  #
11
11
 
12
-
13
- def self.getProject(options)
12
+ def self.getProjectPath(options)
14
13
  projectPath = nil
15
14
 
16
15
  unless options.nil?
@@ -22,52 +21,72 @@ module Fastlane
22
21
  end
23
22
 
24
23
  if projectPath.nil?
25
- projectPath = Dir.entries('.').select { |f| f.end_with?(".xcodeproj") }.first
24
+ projectPath = Dir.entries(".").select { |f| f.end_with?(".xcodeproj") }.first
26
25
  end
27
26
 
28
27
  if projectPath.nil?
29
28
  fail "no xcodeproject found"
30
29
  end
31
30
 
32
- project = Xcodeproj::Project.open(projectPath)
31
+ projectPath
32
+ end
33
+
34
+ def self.getProject(options)
35
+ project = Xcodeproj::Project.open(self.getProjectPath(options))
33
36
 
34
37
  project
35
38
  end
36
39
 
37
- def self.getTarget(project)
40
+ def self.getTargetName(options)
41
+ project = self.getProject(options)
42
+
38
43
  targetName = nil
39
44
 
40
- # if options[:localize_target].nil?
41
- # targetName = ENV["TARGETNAME"]
42
- # end
45
+ unless options.nil?
46
+ targetName = options[:localize_target]
47
+ end
48
+
49
+ if targetName.nil?
50
+ targetName = ENV["TARGET_NAME"]
51
+ end
43
52
 
44
53
  if targetName.nil?
45
- targetName = project.targets.first.name
54
+ targetName = project.targets.map { |target| target.name.to_s }.first
46
55
  end
47
56
 
48
57
  if targetName.nil?
49
58
  fail "no target found"
50
59
  end
51
60
 
61
+ targetName
62
+ end
63
+
64
+ def self.getTarget(options)
65
+ project = self.getProject(options)
66
+ targetName = self.getTargetName(options)
67
+
52
68
  target = project.targets.select { |target| target.name.eql? targetName }.first
53
69
 
54
70
  if target.nil?
55
- fail 'no target'
71
+ fail "no target"
56
72
  end
57
73
 
58
74
  target
59
75
  end
60
76
 
61
77
  def self.codeFiles(target, options)
78
+ if options[:file_filter].nil?
79
+ filter = []
80
+ else
81
+ filter = (options[:file_filter]).split(",")
82
+ end
62
83
 
63
- filter = options[:file_filter].split(",")
64
-
65
- codeFiles = target.source_build_phase.files.to_a.map do |pbx_build_file|
66
- pbx_build_file.file_ref.real_path.to_s
84
+ codeFiles = target.source_build_phase.files.to_a.map do |pbx_build_file|
85
+ pbx_build_file.file_ref.real_path.to_s
67
86
  end.select do |path|
68
- path.end_with?(".swift")
87
+ path.end_with?(".swift")
69
88
  end.select do |path|
70
- bool = true
89
+ bool = true
71
90
 
72
91
  filter.each { |filter|
73
92
  if path.include? filter
@@ -77,28 +96,24 @@ module Fastlane
77
96
 
78
97
  next bool
79
98
  end.select do |path|
80
- File.exists?(path)
81
- end
99
+ File.exists?(path)
100
+ end
82
101
 
83
102
  codeFiles
84
103
  end
85
104
 
86
105
  def self.stringsFromFile(file)
87
-
88
106
  strings = File.readlines(file).to_s.enum_for(:scan,
89
- /(?<!\#imageLiteral\(resourceName:|\#imageLiteral\(resourceName: |NSLocalizedString\()\\"[^\\"\r\n]*\\"/
90
- ).flat_map {Regexp.last_match}
107
+ /(?<!\#imageLiteral\(resourceName:|\#imageLiteral\(resourceName: |NSLocalizedString\()\\"[^\\"\r\n]*\\"/).flat_map { Regexp.last_match }
91
108
  return strings
92
109
  end
93
110
 
94
111
  def self.showStringOccurrencesFromFile(file, string)
95
-
96
112
  line_array = File.readlines(file)
97
113
 
98
114
  File.open(file).each_with_index { |line, index|
99
- if line =~ /(?<!\#imageLiteral\(resourceName:|\#imageLiteral\(resourceName: |NSLocalizedString\()#{string}/
100
- then
101
- hits = line_array[index-2 .. index-1] + [line_array[index].green] + line_array[index+1 .. index+2]
115
+ if line =~ /(?<!\#imageLiteral\(resourceName:|\#imageLiteral\(resourceName: |NSLocalizedString\()#{Regexp.escape(string)}/
116
+ hits = line_array[index - 2..index - 1] + [line_array[index].green] + line_array[index + 1..index + 2]
102
117
  UI.message "In file #{file} (line #{index}): \n\n#{hits.join()}"
103
118
  end
104
119
  }
@@ -109,8 +124,8 @@ module Fastlane
109
124
  end
110
125
 
111
126
  def self.addToWhitelist(string)
112
- open(whitelistFilename, 'a') { |f|
113
- f.puts string
127
+ open(whitelistFilename, "a") { |f|
128
+ f.puts string
114
129
  }
115
130
  UI.message "Added \"#{string}\" to #{whitelistFilename}"
116
131
  end
@@ -124,15 +139,15 @@ module Fastlane
124
139
  end
125
140
 
126
141
  def self.localize_string(string, key, files, params)
127
- open(params[:strings_file], 'a') { |f|
128
- f.puts "\"#{key}\" = #{string};"
142
+ open(params[:strings_file], "a") { |f|
143
+ f.puts "\"#{key}\" = #{string};"
129
144
  }
130
145
  files.each do |file_name|
131
146
  text = File.read(file_name)
132
147
 
133
148
  new_contents = text.gsub(string, replacementString(key, params))
134
149
 
135
- File.open(file_name, "w") {|file| file.puts new_contents }
150
+ File.open(file_name, "w") { |file| file.puts new_contents }
136
151
  end
137
152
 
138
153
  UI.message "Replaced \"#{string}\" with \"#{replacementString(key, params)}\""
@@ -140,7 +155,14 @@ module Fastlane
140
155
 
141
156
  def self.replacementString(key, params)
142
157
  if params[:use_swiftgen]
143
- return "L10n.#{key.gsub("." , "_").split("_").inject { |m, p| m + p.capitalize }}"
158
+ swiftgenKey = key.gsub(".", "_").split("_").inject { |m, p|
159
+ letters = p.split("")
160
+ letters.first.upcase!
161
+ p2 = letters.join
162
+ m + p2
163
+ }
164
+
165
+ return "L10n.#{swiftgenKey}"
144
166
  else
145
167
  return "NSLocalizedString(\"#{key}\")"
146
168
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Localize
3
- VERSION = "0.1.0"
3
+ VERSION = "1.1.0"
4
4
  end
5
5
  end
@@ -1,10 +1,10 @@
1
- require 'fastlane/plugin/localize/version'
1
+ require "fastlane/plugin/localize/version"
2
2
 
3
3
  module Fastlane
4
4
  module Localize
5
5
  # Return all .rb files inside the "actions" and "helper" directory
6
6
  def self.all_classes
7
- Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
7
+ Dir[File.expand_path("**/{actions,helper}/*.rb", File.dirname(__FILE__))]
8
8
  end
9
9
  end
10
10
  end
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-localize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wolfgang Lutz
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-19 00:00:00.000000000 Z
11
+ date: 2022-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: pry
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -25,7 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: fastlane
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.204.3
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.204.3
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - ">="
@@ -39,7 +53,7 @@ dependencies:
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
- name: rspec
56
+ name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
59
  - - ">="
@@ -53,7 +67,7 @@ dependencies:
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
- name: rspec_junit_formatter
70
+ name: rspec
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - ">="
@@ -67,7 +81,7 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: rake
84
+ name: rspec_junit_formatter
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
87
  - - ">="
@@ -86,16 +100,16 @@ dependencies:
86
100
  requirements:
87
101
  - - '='
88
102
  - !ruby/object:Gem::Version
89
- version: 0.49.1
103
+ version: 1.12.1
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - '='
95
109
  - !ruby/object:Gem::Version
96
- version: 0.49.1
110
+ version: 1.12.1
97
111
  - !ruby/object:Gem::Dependency
98
- name: rubocop-require_tools
112
+ name: rubocop-performance
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -109,7 +123,7 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: simplecov
126
+ name: rubocop-require_tools
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -123,20 +137,20 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
- name: fastlane
140
+ name: simplecov
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - ">="
130
144
  - !ruby/object:Gem::Version
131
- version: 2.81.0
145
+ version: '0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - ">="
137
151
  - !ruby/object:Gem::Version
138
- version: 2.81.0
139
- description:
152
+ version: '0'
153
+ description:
140
154
  email: wlut@num42.de
141
155
  executables: []
142
156
  extensions: []
@@ -152,7 +166,7 @@ homepage: https://github.com/num42/fastlane-plugin-localize
152
166
  licenses:
153
167
  - MIT
154
168
  metadata: {}
155
- post_install_message:
169
+ post_install_message:
156
170
  rdoc_options: []
157
171
  require_paths:
158
172
  - lib
@@ -160,16 +174,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
160
174
  requirements:
161
175
  - - ">="
162
176
  - !ruby/object:Gem::Version
163
- version: '0'
177
+ version: '2.5'
164
178
  required_rubygems_version: !ruby/object:Gem::Requirement
165
179
  requirements:
166
180
  - - ">="
167
181
  - !ruby/object:Gem::Version
168
182
  version: '0'
169
183
  requirements: []
170
- rubyforge_project:
171
- rubygems_version: 2.5.2.1
172
- signing_key:
184
+ rubygems_version: 3.2.32
185
+ signing_key:
173
186
  specification_version: 4
174
187
  summary: Searches the code for extractable strings and allows interactive extraction
175
188
  to .strings file.