Skip to content

Commit 9c8cd12

Browse files
authored
Improve removal script performance (#892)
Cleanup
1 parent b40964a commit 9c8cd12

File tree

4 files changed

+45
-37
lines changed

4 files changed

+45
-37
lines changed

ios/remove-unused-fluent-icons/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ xed .
1414

1515
Build the binary and commit it to the repo
1616

17+
```
18+
cd ios/remove-unused-fluent-icons
19+
```
20+
1721
```
1822
swift build -c release
1923
yes | cp .build/release/remove-unused-fluent-icons run

ios/remove-unused-fluent-icons/Sources/RemoveUnusedIcons/Grep.swift

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,16 @@ enum Language {
3030
case objc
3131
}
3232

33-
func searchForCodeReferences(in path: String, language: Language, weights: Set<String>, excludingFileName: String) -> [String] {
33+
func searchForCodeReferences(in path: String, language: Language, weights: Set<String>, excludingFileName: String) -> Set<String> {
3434
let include: String
35-
let regex: String
35+
let regexPattern: String
3636
switch language {
3737
case .swift:
3838
include = "--include=\"*.swift\""
39-
regex = "\\.[a-zA-Z0-9]+[0-9]{2}(\(weights.map { $0.capitalized }.joined(separator: "|")))"
39+
regexPattern = "\\.([a-zA-Z0-9]+[0-9]{2}(\(weights.map { $0.capitalized }.joined(separator: "|"))))"
4040
case .objc:
4141
include = "--include=\"*.m\" --include=\"*.h\""
42-
regex = "\(excludingFileName)[a-zA-Z0-9]+[0-9]{2}(\(weights.map { $0.uppercased() }.joined(separator: "|")))"
42+
regexPattern = "(\(excludingFileName)[a-zA-Z0-9]+[0-9]{2}(\(weights.map { $0.uppercased() }.joined(separator: "|"))))"
4343
}
4444

4545
// Newer versions of grep (on macOS 12+) appear to apply the include/exclude arguments in order, so exclude must come last
@@ -50,9 +50,29 @@ func searchForCodeReferences(in path: String, language: Language, weights: Set<S
5050
--extended-regexp \
5151
\(include) \
5252
--exclude=\"\(excludingFileName).swift\" \
53-
\"\(regex)\" \(path)
53+
\"\(regexPattern)\" \(path)
5454
"""
55+
5556
print(command)
5657

57-
return shell(command).mapToLines()
58+
let regex: NSRegularExpression
59+
do {
60+
regex = try NSRegularExpression(pattern: regexPattern, options: [])
61+
} catch {
62+
fatalError("Invalid regex pattern: \(error) \(regexPattern)")
63+
}
64+
65+
let text = shell(command)
66+
67+
// The grep command returns the full line of code so we need to extract the icon names from each line
68+
var output = Set<String>()
69+
let matches = regex.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))
70+
for match in matches {
71+
let groupRange = match.range(at: 1)
72+
if groupRange.location != NSNotFound,
73+
let range = Range(groupRange, in: text) {
74+
output.insert(String(text[range]))
75+
}
76+
}
77+
return output
5878
}

ios/remove-unused-fluent-icons/Sources/RemoveUnusedIcons/RemoveUnusedIcons.swift

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,61 +33,45 @@ public func removeUnusedAssets(libraryName: String, assetCatalogName: String, pa
3333
var fileName = libraryName
3434
_ = fileName.removeLast() // Remove trailing "s"
3535

36-
let result = try getAllIconNames(pathToFluentIconSource: pathToFluentIconSource, libraryName: libraryName, fileName: fileName)
36+
let (allIconNames, weights) = try getAllIconNames(pathToFluentIconSource: pathToFluentIconSource, libraryName: libraryName, fileName: fileName)
3737

3838
print("Searching for possible swift icon references")
3939
let allPossibleSwiftIconReferences = searchForCodeReferences(
4040
in: pathToSourceCode,
4141
language: .swift,
42-
weights: result.weights,
42+
weights: weights,
4343
excludingFileName: fileName
4444
)
4545

4646
print("Searching for possible objc icon references")
4747
let allPossibleObjcIconReferences = searchForCodeReferences(
4848
in: pathToSourceCode,
4949
language: .objc,
50-
weights: result.weights,
50+
weights: weights,
5151
excludingFileName: fileName
5252
)
5353

54-
var listOfIconsToKeep: [String] = []
54+
var listOfIconsToKeep = Set<String>()
5555
if let pathToListOfIconsToKeep = pathToListOfIconsToKeep {
5656
for path in pathToListOfIconsToKeep.split(separator: ",") {
5757
let fileContents = try String(contentsOfFile: String(path), encoding: .utf8)
58-
listOfIconsToKeep.append(contentsOf: fileContents.mapToLines())
58+
for line in fileContents.mapToLines() {
59+
listOfIconsToKeep.insert(line)
60+
}
5961
}
6062
}
6163

62-
let allPossibleIconReferences = allPossibleSwiftIconReferences + allPossibleObjcIconReferences + listOfIconsToKeep
63-
64-
let allIconNames = result.names
65-
6664
// Validate custom list provided to script has all valid icons
67-
var invalidIcons: [String] = []
68-
for icon in listOfIconsToKeep {
69-
if !allIconNames.contains(icon) {
70-
invalidIcons.append(icon)
71-
}
72-
}
65+
let invalidIcons = listOfIconsToKeep.subtracting(allIconNames)
7366
if !invalidIcons.isEmpty {
7467
print("List of icons provided contains invalid icons \(invalidIcons)")
7568
if exitOnIncorrectlyUsedIconName {
7669
exit(1)
7770
}
7871
}
7972

80-
let allPossibleIconReferencesLower = allPossibleIconReferences.map { $0.lowercased() }
81-
let allIconNamesLower = Set(allIconNames.map { $0.lowercased() })
82-
83-
var iconsUsed = Set<String>()
84-
for line in allPossibleIconReferencesLower {
85-
for iconName in allIconNamesLower {
86-
if line.contains(iconName) {
87-
iconsUsed.insert(iconName)
88-
}
89-
}
90-
}
73+
print("Finding used icons")
74+
let allUsedIcons = allPossibleSwiftIconReferences.union(allPossibleObjcIconReferences).union(listOfIconsToKeep)
9175

9276
let pathToFluentIconAssets = "\(pathToFluentIconSource)/ios/\(libraryName)/Assets/\(assetCatalogName).xcassets"
9377

@@ -100,13 +84,13 @@ public func removeUnusedAssets(libraryName: String, assetCatalogName: String, pa
10084
}
10185

10286
print("Removing unused assets")
103-
var count = 0
87+
var removedCount = 0
10488
for directory in directories {
105-
let iconName = getIconName(from: directory).lowercased()
106-
if !iconsUsed.contains(iconName) {
89+
let iconName = getIconName(from: directory)
90+
if !allUsedIcons.contains(iconName) {
10791
try FileManager.default.removeItem(at: directory)
108-
count += 1
92+
removedCount += 1
10993
}
11094
}
111-
print("Removed \(count) unused assets.")
95+
print("Removed \(removedCount)")
11296
}

ios/remove-unused-fluent-icons/run

-367 KB
Binary file not shown.

0 commit comments

Comments
 (0)