Skip to content

Commit 3097c99

Browse files
authored
Merge pull request #18427 from wordpress-mobile/tooling/applocalizedstring-linter
[Tooling] Add linter for AppLocalizedString not used in extension targets
2 parents a72621e + f16f06d commit 3097c99

5 files changed

Lines changed: 262 additions & 3 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'xcodeproj'
4+
5+
REPO_ROOT = Pathname.new(__dir__) + '../..'
6+
7+
def lint(file_path:, target_name:)
8+
violations_count = 0
9+
File.foreach(file_path, mode: 'rb:BOM|UTF-8').with_index do |line, line_no|
10+
next if line.match? %r(^\s*//) # Skip commented lines
11+
12+
col_no = line.index('NSLocalizedString')
13+
next if col_no.nil?
14+
15+
puts "#{file_path}:#{line_no+1}:#{col_no+1}: error: Use `AppLocalizedString` instead of `NSLocalizedString` in source files that are used in the `#{target_name}` extension target. See paNNhX-nP-p2 for more info."
16+
violations_count += 1
17+
end
18+
violations_count
19+
end
20+
21+
## Main ##
22+
23+
project = Xcodeproj::Project.open(REPO_ROOT + 'WordPress/WordPress.xcodeproj')
24+
targets_to_analyze = if ARGV.count.positive?
25+
project.targets.select { |t| t.name == ARGV.first }
26+
else
27+
project.targets.select { |t| t.is_a?(Xcodeproj::Project::Object::PBXNativeTarget) && t.extension_target_type? }
28+
end
29+
30+
violations_count = 0
31+
targets_to_analyze.each do |target|
32+
build_phase = target.build_phases.find { |p| p.is_a?(Xcodeproj::Project::Object::PBXSourcesBuildPhase) }
33+
next if build_phase.nil?
34+
35+
puts "Linting extension target #{target.name} for improper NSLocalizedString usage..."
36+
source_files = build_phase.files_references.map(&:real_path).select { |f| ['.m', '.swift'].any? { |ext| f.extname == ext } }
37+
source_files.each { |f| violations_count += lint(file_path: f, target_name: target.name) }
38+
puts "Done."
39+
end
40+
41+
exit 1 if violations_count > 0

Scripts/BuildPhases/runRubyScript

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash -eu
2+
3+
# Use this to run a Ruby script from a "Script Build Phase" from Xcode.
4+
#
5+
# Since shell scripts ran by Xcode do not source the user shell profile, typical user setups like the configurations of `rbenv` or `rvm` would not be set up properly.
6+
# This script check if either `rbenv` or `rvm` is installed on the Mac and runs the setup steps as appropriate, before running the ruby script via `bundle exec`
7+
#
8+
# Usage:
9+
# `runRubyScript <script_name.rb> <optional_args>`
10+
#
11+
# Where <script_name.rb` can be either an absolute path, or a path relative to this runRubyScript wrapper script.
12+
#
13+
# Inspiration: https://mgrebenets.github.io/xcode/2019/04/04/xcode-build-phases-and-environment
14+
#
15+
16+
# Add `rbenv` and `rvm` binaries to PATH, so that we support both
17+
export PATH="$HOME/.rbenv/shims:$HOME/.rvm/bin:$PATH"
18+
RUBY_VERSION="$(cat "${PROJECT_DIR}/../.ruby-version")"
19+
if command -v rvm; then
20+
source "$(rvm "${RUBY_VERSION}" do rvm env --path | tail -n1)"
21+
fi
22+
23+
# Run the script with bundle exec
24+
echo "Running the script using 'bundle exec' ..."
25+
cd "$(dirname "${BASH_SOURCE[0]}")"
26+
bundle exec ruby "$@"
27+
cd -

WordPress/Classes/Utility/FormattableContent/Actions/FormattableContentAction.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ public enum NotificationDeletionKind {
1212
public var legendText: String {
1313
switch self {
1414
case .deletion:
15-
return NSLocalizedString("Comment has been deleted", comment: "Displayed when a Comment is deleted")
15+
return AppLocalizedString("Comment has been deleted", comment: "Displayed when a Comment is deleted")
1616
case .spamming:
17-
return NSLocalizedString("Comment has been marked as Spam", comment: "Displayed when a Comment is spammed")
17+
return AppLocalizedString("Comment has been marked as Spam", comment: "Displayed when a Comment is spammed")
1818
}
1919
}
2020
}

WordPress/WordPress.xcodeproj/project.pbxproj

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
098B8578275FF975004D299F /* AppLocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F2656A025AF4DFA0073A832 /* AppLocalizedString.swift */; };
150150
098B8579275FFB21004D299F /* AppLocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F2656A025AF4DFA0073A832 /* AppLocalizedString.swift */; };
151151
099D768327D14B8E00F77EDE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 099D768127D14B8E00F77EDE /* InfoPlist.strings */; };
152+
09DBEA55281336E10019724E /* AppLocalizedString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F2656A025AF4DFA0073A832 /* AppLocalizedString.swift */; };
152153
1702BBDC1CEDEA6B00766A33 /* BadgeLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1702BBDB1CEDEA6B00766A33 /* BadgeLabel.swift */; };
153154
1702BBE01CF3034E00766A33 /* DomainsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1702BBDF1CF3034E00766A33 /* DomainsService.swift */; };
154155
1703D04C20ECD93800D292E9 /* Routes+Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1703D04B20ECD93800D292E9 /* Routes+Post.swift */; };
@@ -15310,6 +15311,7 @@
1531015311
buildConfigurationList = 3F526C612538CF2C0069706C /* Build configuration list for PBXNativeTarget "WordPressStatsWidgets" */;
1531115312
buildPhases = (
1531215313
0AA1A8899C01FEF3599F6FCF /* [CP] Check Pods Manifest.lock */,
15314+
09DBEA51281333610019724E /* [Lint] Check AppLocalizedString usage */,
1531315315
3F526C482538CF2A0069706C /* Sources */,
1531415316
3F526C492538CF2A0069706C /* Frameworks */,
1531515317
3F526C4A2538CF2A0069706C /* Resources */,
@@ -15350,6 +15352,7 @@
1535015352
isa = PBXNativeTarget;
1535115353
buildConfigurationList = 733F36152126197800988727 /* Build configuration list for PBXNativeTarget "WordPressNotificationContentExtension" */;
1535215354
buildPhases = (
15355+
09DBEA52281333700019724E /* [Lint] Check AppLocalizedString usage */,
1535315356
733F35FF2126197800988727 /* Sources */,
1535415357
733F36002126197800988727 /* Frameworks */,
1535515358
733F36012126197800988727 /* Resources */,
@@ -15368,6 +15371,7 @@
1536815371
buildConfigurationList = 7358E6C4210BD318002323EB /* Build configuration list for PBXNativeTarget "WordPressNotificationServiceExtension" */;
1536915372
buildPhases = (
1537015373
BAE780768320204E29A6FE5B /* [CP] Check Pods Manifest.lock */,
15374+
09DBEA53281333770019724E /* [Lint] Check AppLocalizedString usage */,
1537115375
7358E6B4210BD318002323EB /* Sources */,
1537215376
7358E6B5210BD318002323EB /* Frameworks */,
1537315377
7358E6B6210BD318002323EB /* Resources */,
@@ -15387,6 +15391,7 @@
1538715391
buildConfigurationList = 74576681202B558C00F42E40 /* Build configuration list for PBXNativeTarget "WordPressDraftActionExtension" */;
1538815392
buildPhases = (
1538915393
74CC431A202B5C73000DAE1A /* [CP] Check Pods Manifest.lock */,
15394+
09DBEA4D281333060019724E /* [Lint] Check AppLocalizedString usage */,
1539015395
7457666E202B558C00F42E40 /* Sources */,
1539115396
7457666F202B558C00F42E40 /* Frameworks */,
1539215397
74576670202B558C00F42E40 /* Resources */,
@@ -15425,6 +15430,7 @@
1542515430
buildConfigurationList = 932225B71C7CE50400443B02 /* Build configuration list for PBXNativeTarget "WordPressShareExtension" */;
1542615431
buildPhases = (
1542715432
4F4D5C2BB6478A3E90ADC3C5 /* [CP] Check Pods Manifest.lock */,
15433+
09DBEA4C281329ED0019724E /* [Lint] Check AppLocalizedString usage */,
1542815434
932225A31C7CE50300443B02 /* Sources */,
1542915435
932225A41C7CE50300443B02 /* Frameworks */,
1543015436
932225A51C7CE50300443B02 /* Resources */,
@@ -15444,6 +15450,7 @@
1544415450
buildConfigurationList = 93E5284D19A7741A003A1A9C /* Build configuration list for PBXNativeTarget "WordPressTodayWidget" */;
1544515451
buildPhases = (
1544615452
4CB8AA817C9BD74F3416B27C /* [CP] Check Pods Manifest.lock */,
15453+
09DBEA4E2813334B0019724E /* [Lint] Check AppLocalizedString usage */,
1544715454
93E5283619A7741A003A1A9C /* Sources */,
1544815455
93E5283719A7741A003A1A9C /* Frameworks */,
1544915456
93E5283819A7741A003A1A9C /* Resources */,
@@ -15463,6 +15470,7 @@
1546315470
buildConfigurationList = 98A3C2FF239997DB0048D38D /* Build configuration list for PBXNativeTarget "WordPressThisWeekWidget" */;
1546415471
buildPhases = (
1546515472
591AAEE0843D274DDFF16F69 /* [CP] Check Pods Manifest.lock */,
15473+
09DBEA50281333590019724E /* [Lint] Check AppLocalizedString usage */,
1546615474
98A3C2EB239997DA0048D38D /* Sources */,
1546715475
98A3C2EC239997DA0048D38D /* Frameworks */,
1546815476
98A3C2ED239997DA0048D38D /* Resources */,
@@ -15482,6 +15490,7 @@
1548215490
buildConfigurationList = 98D31B9E2396ED7F009CFF43 /* Build configuration list for PBXNativeTarget "WordPressAllTimeWidget" */;
1548315491
buildPhases = (
1548415492
FF1C536C9FA7489B5AAA0FC2 /* [CP] Check Pods Manifest.lock */,
15493+
09DBEA4F281333530019724E /* [Lint] Check AppLocalizedString usage */,
1548515494
98D31B8A2396ED7E009CFF43 /* Sources */,
1548615495
98D31B8B2396ED7E009CFF43 /* Frameworks */,
1548715496
98D31B8C2396ED7E009CFF43 /* Resources */,
@@ -15520,6 +15529,7 @@
1552015529
buildConfigurationList = F1F163DC25658B4D003DC13B /* Build configuration list for PBXNativeTarget "WordPressIntents" */;
1552115530
buildPhases = (
1552215531
CE51D1C75430FDDD21B27F64 /* [CP] Check Pods Manifest.lock */,
15532+
09DBEA542813337F0019724E /* [Lint] Check AppLocalizedString usage */,
1552315533
F1F163BA25658B4D003DC13B /* Sources */,
1552415534
F1F163BB25658B4D003DC13B /* Frameworks */,
1552515535
F1F163BC25658B4D003DC13B /* Resources */,
@@ -16595,6 +16605,186 @@
1659516605
shellScript = "$SRCROOT/../Scripts/BuildPhases/GenerateCredentials.sh\n";
1659616606
showEnvVarsInLog = 0;
1659716607
};
16608+
09DBEA4C281329ED0019724E /* [Lint] Check AppLocalizedString usage */ = {
16609+
isa = PBXShellScriptBuildPhase;
16610+
alwaysOutOfDate = 1;
16611+
buildActionMask = 2147483647;
16612+
files = (
16613+
);
16614+
inputFileListPaths = (
16615+
);
16616+
inputPaths = (
16617+
);
16618+
name = "[Lint] Check AppLocalizedString usage";
16619+
outputFileListPaths = (
16620+
);
16621+
outputPaths = (
16622+
);
16623+
runOnlyForDeploymentPostprocessing = 0;
16624+
shellPath = "/bin/bash -eu";
16625+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16626+
showEnvVarsInLog = 0;
16627+
};
16628+
09DBEA4D281333060019724E /* [Lint] Check AppLocalizedString usage */ = {
16629+
isa = PBXShellScriptBuildPhase;
16630+
alwaysOutOfDate = 1;
16631+
buildActionMask = 2147483647;
16632+
files = (
16633+
);
16634+
inputFileListPaths = (
16635+
);
16636+
inputPaths = (
16637+
);
16638+
name = "[Lint] Check AppLocalizedString usage";
16639+
outputFileListPaths = (
16640+
);
16641+
outputPaths = (
16642+
);
16643+
runOnlyForDeploymentPostprocessing = 0;
16644+
shellPath = "/bin/bash -eu";
16645+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16646+
showEnvVarsInLog = 0;
16647+
};
16648+
09DBEA4E2813334B0019724E /* [Lint] Check AppLocalizedString usage */ = {
16649+
isa = PBXShellScriptBuildPhase;
16650+
alwaysOutOfDate = 1;
16651+
buildActionMask = 2147483647;
16652+
files = (
16653+
);
16654+
inputFileListPaths = (
16655+
);
16656+
inputPaths = (
16657+
);
16658+
name = "[Lint] Check AppLocalizedString usage";
16659+
outputFileListPaths = (
16660+
);
16661+
outputPaths = (
16662+
);
16663+
runOnlyForDeploymentPostprocessing = 0;
16664+
shellPath = "/bin/bash -eu";
16665+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16666+
showEnvVarsInLog = 0;
16667+
};
16668+
09DBEA4F281333530019724E /* [Lint] Check AppLocalizedString usage */ = {
16669+
isa = PBXShellScriptBuildPhase;
16670+
alwaysOutOfDate = 1;
16671+
buildActionMask = 2147483647;
16672+
files = (
16673+
);
16674+
inputFileListPaths = (
16675+
);
16676+
inputPaths = (
16677+
);
16678+
name = "[Lint] Check AppLocalizedString usage";
16679+
outputFileListPaths = (
16680+
);
16681+
outputPaths = (
16682+
);
16683+
runOnlyForDeploymentPostprocessing = 0;
16684+
shellPath = "/bin/bash -eu";
16685+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16686+
showEnvVarsInLog = 0;
16687+
};
16688+
09DBEA50281333590019724E /* [Lint] Check AppLocalizedString usage */ = {
16689+
isa = PBXShellScriptBuildPhase;
16690+
alwaysOutOfDate = 1;
16691+
buildActionMask = 2147483647;
16692+
files = (
16693+
);
16694+
inputFileListPaths = (
16695+
);
16696+
inputPaths = (
16697+
);
16698+
name = "[Lint] Check AppLocalizedString usage";
16699+
outputFileListPaths = (
16700+
);
16701+
outputPaths = (
16702+
);
16703+
runOnlyForDeploymentPostprocessing = 0;
16704+
shellPath = "/bin/bash -eu";
16705+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16706+
showEnvVarsInLog = 0;
16707+
};
16708+
09DBEA51281333610019724E /* [Lint] Check AppLocalizedString usage */ = {
16709+
isa = PBXShellScriptBuildPhase;
16710+
alwaysOutOfDate = 1;
16711+
buildActionMask = 2147483647;
16712+
files = (
16713+
);
16714+
inputFileListPaths = (
16715+
);
16716+
inputPaths = (
16717+
);
16718+
name = "[Lint] Check AppLocalizedString usage";
16719+
outputFileListPaths = (
16720+
);
16721+
outputPaths = (
16722+
);
16723+
runOnlyForDeploymentPostprocessing = 0;
16724+
shellPath = "/bin/bash -eu";
16725+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16726+
showEnvVarsInLog = 0;
16727+
};
16728+
09DBEA52281333700019724E /* [Lint] Check AppLocalizedString usage */ = {
16729+
isa = PBXShellScriptBuildPhase;
16730+
alwaysOutOfDate = 1;
16731+
buildActionMask = 2147483647;
16732+
files = (
16733+
);
16734+
inputFileListPaths = (
16735+
);
16736+
inputPaths = (
16737+
);
16738+
name = "[Lint] Check AppLocalizedString usage";
16739+
outputFileListPaths = (
16740+
);
16741+
outputPaths = (
16742+
);
16743+
runOnlyForDeploymentPostprocessing = 0;
16744+
shellPath = "/bin/bash -eu";
16745+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16746+
showEnvVarsInLog = 0;
16747+
};
16748+
09DBEA53281333770019724E /* [Lint] Check AppLocalizedString usage */ = {
16749+
isa = PBXShellScriptBuildPhase;
16750+
alwaysOutOfDate = 1;
16751+
buildActionMask = 2147483647;
16752+
files = (
16753+
);
16754+
inputFileListPaths = (
16755+
);
16756+
inputPaths = (
16757+
);
16758+
name = "[Lint] Check AppLocalizedString usage";
16759+
outputFileListPaths = (
16760+
);
16761+
outputPaths = (
16762+
);
16763+
runOnlyForDeploymentPostprocessing = 0;
16764+
shellPath = "/bin/bash -eu";
16765+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16766+
showEnvVarsInLog = 0;
16767+
};
16768+
09DBEA542813337F0019724E /* [Lint] Check AppLocalizedString usage */ = {
16769+
isa = PBXShellScriptBuildPhase;
16770+
alwaysOutOfDate = 1;
16771+
buildActionMask = 2147483647;
16772+
files = (
16773+
);
16774+
inputFileListPaths = (
16775+
);
16776+
inputPaths = (
16777+
);
16778+
name = "[Lint] Check AppLocalizedString usage";
16779+
outputFileListPaths = (
16780+
);
16781+
outputPaths = (
16782+
);
16783+
runOnlyForDeploymentPostprocessing = 0;
16784+
shellPath = "/bin/bash -eu";
16785+
shellScript = "\"$SRCROOT/../Scripts/BuildPhases/runRubyScript\" \"LintAppLocalizedStringsUsage.rb\" \"${TARGET_NAME}\"\n";
16786+
showEnvVarsInLog = 0;
16787+
};
1659816788
0AA1A8899C01FEF3599F6FCF /* [CP] Check Pods Manifest.lock */ = {
1659916789
isa = PBXShellScriptBuildPhase;
1660016790
buildActionMask = 2147483647;
@@ -19187,6 +19377,7 @@
1918719377
C737554027C80F1300C6E9A1 /* String+CondenseWhitespace.swift in Sources */,
1918819378
7335AC6D21220F0F0012EF2D /* FormattableUserContent.swift in Sources */,
1918919379
7335AC6221220E690012EF2D /* FormattableContentFactory.swift in Sources */,
19380+
09DBEA55281336E10019724E /* AppLocalizedString.swift in Sources */,
1919019381
433ADC1A223B2A7D00ED9DE1 /* TextBundleWrapper.m in Sources */,
1919119382
7335AC6C21220F050012EF2D /* FormattableNoticonRange.swift in Sources */,
1919219383
73F6DD42212BA54700CE447D /* RichNotificationContentFormatter.swift in Sources */,

WordPress/WordPressNotificationServiceExtension/Sources/NotificationService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,5 +329,5 @@ private extension NotificationService {
329329
return content
330330
}
331331

332-
static let viewMilestoneTitle = NSLocalizedString("You hit a milestone 🚀", comment: "Title for a view milestone push notification")
332+
static let viewMilestoneTitle = AppLocalizedString("You hit a milestone 🚀", comment: "Title for a view milestone push notification")
333333
}

0 commit comments

Comments
 (0)