This repository has been archived by the owner on May 10, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 441
/
LeoAssetsPlugin.swift
129 lines (118 loc) · 5.19 KB
/
LeoAssetsPlugin.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2023 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
import PackagePlugin
import Foundation
/// Creates an asset catalog filled with Brave's Leo SF Symbols
@main
struct LeoAssetsPlugin: BuildToolPlugin {
func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] {
// Check to make sure we have pulled down the icons correctly
let fileManager = FileManager.default
let leoSymbolsDirectory = context.package.directory.appending("node_modules/leo-sf-symbols")
let leoColorsDirectory = context.package.directory.appending("node_modules/leo")
if !fileManager.fileExists(atPath: leoSymbolsDirectory.string) ||
!fileManager.fileExists(atPath: leoColorsDirectory.string) {
Diagnostics.error("Required Leo assets not found: \(FileManager.default.currentDirectoryPath)")
return []
}
// Check to make sure the plugin is being used correctly in SPM
guard let target = target as? SourceModuleTarget else {
Diagnostics.error("Attempted to use `LeoAssetsPlugin` on an unsupported module target")
return []
}
let assetCatalogs = Array(target.sourceFiles(withSuffix: "xcassets").map(\.path))
if assetCatalogs.isEmpty {
Diagnostics.error("No asset catalogs found in the target")
return []
}
// The command that will create an asset catalog full of leo sf symbols
let copySFSymbolsCommand: Command = try {
let scriptPath = context.package.directory.appending("Plugins/LeoAssetsPlugin/make_asset_catalog.sh")
let outputDirectory = context.pluginWorkDirectory.appending("LeoAssets.xcassets")
// Running a macOS tool while archiving a iOS build is unfortunately broken in Xcode 14. It attempts to
// run the macOS tool from the wrong directory and fails to find it. One way around this is to use a
// precompiled version of this tool instead, but it will mean building and uploading them somewhere
// so for now the tool will be replaced by a bash script. We can uncomment this and add back the dep on
// `LeoAssetCatalogGenerator` once this is fixed in Xcode.
// return [
// .buildCommand(
// displayName: "Create Asset Catalog",
// executable: try context.tool(named: "LeoAssetCatalogGenerator").path,
// arguments: assetCatalogs + [leoSymbolsDirectory, outputDirectory.string],
// inputFiles: assetCatalogs + [leoSymbolsDirectory.appending("package.json")],
// outputFiles: [outputDirectory]
// ),
// ]
let icons = try assetCatalogs.flatMap {
try symbolSets(in: URL(fileURLWithPath: $0.string))
}.joined(separator: ",")
return .buildCommand(
displayName: "Create Asset Catalog",
executable: Path("/bin/zsh"),
arguments: [
scriptPath.string,
"-l", leoSymbolsDirectory.string,
"-i", icons,
"-o", context.pluginWorkDirectory.string
],
inputFiles: assetCatalogs + [leoSymbolsDirectory.appending("package.json"),
scriptPath],
outputFiles: [outputDirectory]
)
}()
let copyColorsCommand: Command = {
let tokensPath = leoColorsDirectory.appending("tokens/ios-swift")
let outputDirectory = context.pluginWorkDirectory.appending("LeoColors")
return .buildCommand(
displayName: "Copy Leo Colors",
executable: Path("/bin/zsh"),
arguments: [
"-c", "cp -R \"\(tokensPath.string)/.\" \"\(outputDirectory)\""
],
inputFiles: [
tokensPath.appending("Colors.xcassets"),
tokensPath.appending("Gradients.swift"),
tokensPath.appending("ColorSetAccessors.swift"),
],
outputFiles: [
outputDirectory.appending("Colors.xcassets"),
outputDirectory.appending("Gradients.swift"),
outputDirectory.appending("ColorSetAccessors.swift"),
]
)
}()
return [
copySFSymbolsCommand,
copyColorsCommand
]
}
}
extension LeoAssetsPlugin {
fileprivate func symbolSets(in catalog: URL) throws -> [String] {
let fileManager = FileManager.default
var symbols: [String] = []
guard let enumerator = fileManager.enumerator(
at: catalog,
includingPropertiesForKeys: [.isDirectoryKey, .nameKey],
options: [.skipsHiddenFiles, .skipsSubdirectoryDescendants]
) else { return [] }
while let fileURL = enumerator.nextObject() as? URL {
guard
let values = try? fileURL.resourceValues(forKeys: [.isDirectoryKey, .nameKey]),
let isDirectory = values.isDirectory,
let name = values.name,
isDirectory,
name.hasPrefix("leo"),
name.hasSuffix(".symbolset"),
!(try fileManager.contentsOfDirectory(atPath: fileURL.path)
.contains(where: { $0.hasSuffix("svg") }))
else {
continue
}
symbols.append(fileURL.deletingPathExtension().lastPathComponent)
}
return symbols
}
}