diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/XCResource-Package.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/XCResource-Package.xcscheme index 8c947f1..9e528c2 100644 --- a/.swiftpm/xcode/xcshareddata/xcschemes/XCResource-Package.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/XCResource-Package.xcscheme @@ -376,6 +376,16 @@ ReferencedContainer = "container:"> + + + + [String] { + var result: [String] = [] + + var argExtractor = ArgumentExtractor(pluginArguments) + + func appendManifestPath(_ manifestPath: String) { + result.append(contentsOf: ["--\(OptionName.manifestPath)", manifestPath]) + } + + if let manifestPath = argExtractor.extractOption(named: OptionName.manifestPath).first { + appendManifestPath(manifestPath) + } else if let manifestPath = manifestPath(inDirectory: context.package.directory) { + appendManifestPath(manifestPath) + } + + return result + } + + private func manifestPath(inDirectory directory: Path) -> String? { + let filename = "xcresource.json" + + let candidates: [String] = [ + "Configs/\(filename)", + "Scripts/\(filename)", + ] + + for candidate in candidates { + let path = directory.appending(subpath: candidate) + let url = URL(fileURLWithPath: path.string) + + if (try? url.checkResourceIsReachable()) ?? false { + return path.string + } + } + + return nil + } +} diff --git a/Samples/XCResourceSample.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Samples/XCResourceSample.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..3c151f3 --- /dev/null +++ b/Samples/XCResourceSample.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,41 @@ +{ + "pins" : [ + { + "identity" : "strix", + "kind" : "remoteSourceControl", + "location" : "https://github.com/nearfri/Strix", + "state" : { + "revision" : "2e309dbea51da14c4ba74b3abb3debb8ea4a7529", + "version" : "2.4.5" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser", + "state" : { + "revision" : "c8ed701b513cf5177118a175d85fbbbcd707ab41", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-syntax", + "state" : { + "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d", + "version" : "509.1.1" + } + } + ], + "version" : 2 +} diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Package.swift b/Samples/XCResourceSample/XCResourceSampleLib/Package.swift index a115abc..f6a0ac9 100644 --- a/Samples/XCResourceSample/XCResourceSampleLib/Package.swift +++ b/Samples/XCResourceSample/XCResourceSampleLib/Package.swift @@ -8,99 +8,29 @@ let package = Package( defaultLocalization: "en", platforms: [.iOS(.v15), .macCatalyst(.v15), .macOS(.v12)], products: [ - .library( - name: "XCResourceSampleLib", - targets: ["View", "Resource"]), - .plugin( - name: "StringsToSwiftPlugin", - targets: ["StringsToSwiftPlugin"]), - .plugin( - name: "StringsToCSVPlugin", - targets: ["StringsToCSVPlugin"]), - .plugin( - name: "CSVToStringsPlugin", - targets: ["CSVToStringsPlugin"]), + .library(name: "XCResourceSampleLib", targets: ["View", "Resource"]), ], dependencies: [ // .package(url: /* package url */, from: "1.0.0"), + .package(path: "../../../"), ], targets: [ - // MARK: - View + // MARK: - Core Modules .target( name: "View", dependencies: ["Resource"]), - // MARK: - Resource - .target( name: "Resource", dependencies: [], resources: [.copy("Resources/Fonts")], - plugins: [.plugin(name: "XCResourcePlugin")]), + plugins: []), + + // MARK: - Tests .testTarget( name: "ResourceTests", dependencies: ["Resource"]), - - // MARK: - XCResourcePlugin - - .plugin( - name: "XCResourcePlugin", - capability: .buildTool(), - dependencies: ["xcresource"]), - - // MARK: - StringsToSwiftPlugin - - .plugin( - name: "StringsToSwiftPlugin", - capability: .command( - intent: .custom(verb: "strings2swift", description: "Convert strings to swift"), - permissions: [ - .writeToPackageDirectory(reason: "Converts strings to swift") - ]), - dependencies: ["xcresource"]), - - // MARK: - StringsdictToSwiftPlugin - - .plugin( - name: "StringsdictToSwiftPlugin", - capability: .command( - intent: .custom(verb: "stringsdict2swift", - description: "Convert stringsdict to swift"), - permissions: [ - .writeToPackageDirectory(reason: "Converts stringsdict to swift") - ]), - dependencies: ["xcresource"]), - - // MARK: - StringsToCSVPlugin - - .plugin( - name: "StringsToCSVPlugin", - capability: .command( - intent: .custom(verb: "strings2csv", description: "Convert strings to csv"), - permissions: [ - .writeToPackageDirectory(reason: "Converts strings to csv") - ]), - dependencies: ["xcresource"]), - - // MARK: - CSVToStringsPlugin - - .plugin( - name: "CSVToStringsPlugin", - capability: .command( - intent: .custom(verb: "csv2strings", description: "Convert csv to strings"), - permissions: [ - .writeToPackageDirectory(reason: "Converts csv to strings") - ]), - dependencies: ["xcresource"]), - - // MARK: - xcresource - - .binaryTarget( - name: "xcresource", - url: "https://github.com/nearfri/XCResource/releases/download/0.9.25/xcresource.artifactbundle.zip", - checksum: "b4a297dea6b6c8df93dc7149d7d548e38ec699cdcfd2477b33c013da52fd7249" - ), ] ) diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/CSVToStringsPlugin/CSVToStringsPlugin.swift b/Samples/XCResourceSample/XCResourceSampleLib/Plugins/CSVToStringsPlugin/CSVToStringsPlugin.swift deleted file mode 100644 index 48eb3bc..0000000 --- a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/CSVToStringsPlugin/CSVToStringsPlugin.swift +++ /dev/null @@ -1,79 +0,0 @@ -import Foundation -import PackagePlugin - -protocol PackagePluginContext { - func tool(named name: String) throws -> PackagePlugin.PluginContext.Tool -} - -extension PluginContext: PackagePluginContext {} - -@main -struct CSVToStringsPlugin: CommandPlugin { - /// This entry point is called when operating on a Swift package. - func performCommand(context: PluginContext, arguments: [String]) throws { - let scriptsDir = context.package.directory.appending(subpath: "Scripts") - - try performStringsToCSV(context: context, directoryPath: scriptsDir) - } - - private func performStringsToCSV(context: PackagePluginContext, directoryPath: Path) throws { - let xcresource = try context.tool(named: "xcresource") - - let process = Process() - process.currentDirectoryURL = URL(fileURLWithPath: directoryPath.string) - process.executableURL = URL(fileURLWithPath: xcresource.path.string) - - let arguments = """ - csv2strings \ - --csv-path ./XCResourceSample-localizations.csv \ - --header-style long-en \ - --resources-path ../Sources/Resource/Resources \ - --empty-encoding #EMPTY - """ - process.arguments = arguments.split(separator: " ").map(String.init) - - try process.run() - process.waitUntilExit() - - guard process.terminationReason == .exit && process.terminationStatus == 0 else { - Diagnostics.error("StringsToCSV failed.") - return - } - } - - // try performShellCommand("make strings2csv", at: scriptsDir) - private func performShellCommand(_ command: String, at directoryPath: Path) throws { - let process = Process() - process.currentDirectoryURL = URL(fileURLWithPath: directoryPath.string) - process.executableURL = URL(fileURLWithPath: "/bin/zsh") - process.arguments = ["-c", command] - process.environment = ["PATH": "/usr/bin:~/.mint/bin"] - - try process.run() - process.waitUntilExit() - - guard process.terminationReason == .exit && process.terminationStatus == 0 else { - let problem = "\(process.terminationReason):\(process.terminationStatus)" - Diagnostics.error("'\(command)' failed: \(problem)") - return - } - } -} - -#if canImport(XcodeProjectPlugin) - -import XcodeProjectPlugin - -extension XcodePluginContext: PackagePluginContext {} - -extension CSVToStringsPlugin: XcodeCommandPlugin { - /// This entry point is called when operating on an Xcode project. - func performCommand(context: XcodePluginContext, arguments: [String]) throws { - let projectDir = context.xcodeProject.directory - let scriptsDir = projectDir.appending(subpath: "XCResourceSampleLib/Scripts") - - try performStringsToCSV(context: context, directoryPath: scriptsDir) - } -} - -#endif diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsToCSVPlugin/StringsToCSVPlugin.swift b/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsToCSVPlugin/StringsToCSVPlugin.swift deleted file mode 100644 index 4d1b679..0000000 --- a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsToCSVPlugin/StringsToCSVPlugin.swift +++ /dev/null @@ -1,63 +0,0 @@ -import Foundation -import PackagePlugin - -protocol PackagePluginContext { - func tool(named name: String) throws -> PackagePlugin.PluginContext.Tool -} - -extension PluginContext: PackagePluginContext {} - -@main -struct StringsToCSVPlugin: CommandPlugin { - /// This entry point is called when operating on a Swift package. - func performCommand(context: PluginContext, arguments: [String]) throws { - let scriptsDir = context.package.directory.appending(subpath: "Scripts") - - try performStringsToCSV(context: context, directoryPath: scriptsDir) - } - - private func performStringsToCSV(context: PackagePluginContext, directoryPath: Path) throws { - let xcresource = try context.tool(named: "xcresource") - - let process = Process() - process.currentDirectoryURL = URL(fileURLWithPath: directoryPath.string) - process.executableURL = URL(fileURLWithPath: xcresource.path.string) - - let arguments = """ - strings2csv \ - --resources-path ../Sources/Resource/Resources \ - --development-language en \ - --csv-path ./XCResourceSample-localizations.csv \ - --header-style long-en \ - --empty-encoding #EMPTY \ - --write-bom - """ - process.arguments = arguments.split(separator: " ").map(String.init) - - try process.run() - process.waitUntilExit() - - guard process.terminationReason == .exit && process.terminationStatus == 0 else { - Diagnostics.error("StringsToCSV failed.") - return - } - } -} - -#if canImport(XcodeProjectPlugin) - -import XcodeProjectPlugin - -extension XcodePluginContext: PackagePluginContext {} - -extension StringsToCSVPlugin: XcodeCommandPlugin { - /// This entry point is called when operating on an Xcode project. - func performCommand(context: XcodePluginContext, arguments: [String]) throws { - let projectDir = context.xcodeProject.directory - let scriptsDir = projectDir.appending(subpath: "XCResourceSampleLib/Scripts") - - try performStringsToCSV(context: context, directoryPath: scriptsDir) - } -} - -#endif diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsToSwiftPlugin/StringsToSwiftPlugin.swift b/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsToSwiftPlugin/StringsToSwiftPlugin.swift deleted file mode 100644 index c2d54e2..0000000 --- a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsToSwiftPlugin/StringsToSwiftPlugin.swift +++ /dev/null @@ -1,60 +0,0 @@ -import Foundation -import PackagePlugin - -protocol PackagePluginContext { - func tool(named name: String) throws -> PackagePlugin.PluginContext.Tool -} - -extension PluginContext: PackagePluginContext {} - -@main -struct StringsToSwiftPlugin: CommandPlugin { - /// This entry point is called when operating on a Swift package. - func performCommand(context: PluginContext, arguments: [String]) throws { - let scriptsDir = context.package.directory.appending(subpath: "Scripts") - - try performStringsToSwift(context: context, directoryPath: scriptsDir) - } - - private func performStringsToSwift(context: PackagePluginContext, directoryPath: Path) throws { - let xcresource = try context.tool(named: "xcresource") - - let process = Process() - process.currentDirectoryURL = URL(fileURLWithPath: directoryPath.string) - process.executableURL = URL(fileURLWithPath: xcresource.path.string) - - let arguments = """ - strings2swift \ - --resources-path ../Sources/Resource/Resources \ - --language en \ - --swift-path ../Sources/Resource/Keys/StringKey.swift - """ - process.arguments = arguments.split(separator: " ").map(String.init) - - try process.run() - process.waitUntilExit() - - guard process.terminationReason == .exit && process.terminationStatus == 0 else { - Diagnostics.error("StringsToSwift failed.") - return - } - } -} - -#if canImport(XcodeProjectPlugin) - -import XcodeProjectPlugin - -extension XcodePluginContext: PackagePluginContext {} - -extension StringsToSwiftPlugin: XcodeCommandPlugin { - /// This entry point is called when operating on an Xcode project. - func performCommand(context: XcodePluginContext, arguments: [String]) throws { - let projectDir = context.xcodeProject.directory - let scriptsDir = projectDir.appending(subpath: "XCResourceSampleLib/Scripts") - - try performStringsToSwift(context: context, directoryPath: scriptsDir) - } -} - -#endif diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsdictToSwiftPlugin/StringsdictToSwiftPlugin.swift b/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsdictToSwiftPlugin/StringsdictToSwiftPlugin.swift deleted file mode 100644 index 4f33fdb..0000000 --- a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/StringsdictToSwiftPlugin/StringsdictToSwiftPlugin.swift +++ /dev/null @@ -1,60 +0,0 @@ -import Foundation -import PackagePlugin - -protocol PackagePluginContext { - func tool(named name: String) throws -> PackagePlugin.PluginContext.Tool -} - -extension PluginContext: PackagePluginContext {} - -@main -struct StringsdictToSwiftPlugin: CommandPlugin { - /// This entry point is called when operating on a Swift package. - func performCommand(context: PluginContext, arguments: [String]) throws { - let scriptsDir = context.package.directory.appending(subpath: "Scripts") - - try perform(context: context, directoryPath: scriptsDir) - } - - private func perform(context: PackagePluginContext, directoryPath: Path) throws { - let xcresource = try context.tool(named: "xcresource") - - let process = Process() - process.currentDirectoryURL = URL(fileURLWithPath: directoryPath.string) - process.executableURL = URL(fileURLWithPath: xcresource.path.string) - - let arguments = """ - stringsdict2swift \ - --resources-path ../Sources/Resource/Resources \ - --language en \ - --swift-path ../Sources/Resource/Keys/StringKey.swift - """ - process.arguments = arguments.split(separator: " ").map(String.init) - - try process.run() - process.waitUntilExit() - - guard process.terminationReason == .exit && process.terminationStatus == 0 else { - Diagnostics.error("StringsToSwift failed.") - return - } - } -} - -#if canImport(XcodeProjectPlugin) - -import XcodeProjectPlugin - -extension XcodePluginContext: PackagePluginContext {} - -extension StringsdictToSwiftPlugin: XcodeCommandPlugin { - /// This entry point is called when operating on an Xcode project. - func performCommand(context: XcodePluginContext, arguments: [String]) throws { - let projectDir = context.xcodeProject.directory - let scriptsDir = projectDir.appending(subpath: "XCResourceSampleLib/Scripts") - - try perform(context: context, directoryPath: scriptsDir) - } -} - -#endif diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/XCResourcePlugin/XCResourcePlugin.swift b/Samples/XCResourceSample/XCResourceSampleLib/Plugins/XCResourcePlugin/XCResourcePlugin.swift deleted file mode 100644 index 7475e4a..0000000 --- a/Samples/XCResourceSample/XCResourceSampleLib/Plugins/XCResourcePlugin/XCResourcePlugin.swift +++ /dev/null @@ -1,21 +0,0 @@ -import Foundation -import PackagePlugin - -@main -struct XCResourcePlugin: BuildToolPlugin { - func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] { - let xcresource = try context.tool(named: "xcresource").path - - return [ - .prebuildCommand( - displayName: "Run xcresource", - executable: Path("/usr/bin/make"), - arguments: [ - "-C", "\(context.package.directory)/Scripts", - "XCRESOURCE=\(xcresource)", - ], - environment: ["PATH": "/usr/bin"], - outputFilesDirectory: context.pluginWorkDirectory), - ] - } -} diff --git a/Samples/XCResourceSample/XCResourceSampleLib/Scripts/xcresource.json b/Samples/XCResourceSample/XCResourceSampleLib/Scripts/xcresource.json index 413951a..ad4f348 100644 --- a/Samples/XCResourceSample/XCResourceSampleLib/Scripts/xcresource.json +++ b/Samples/XCResourceSample/XCResourceSampleLib/Scripts/xcresource.json @@ -3,42 +3,42 @@ { "commandName": "xcassets2swift", "xcassetsPaths": [ - "../Sources/Resource/Resources/Assets.xcassets" + "Sources/Resource/Resources/Assets.xcassets" ], "assetTypes": ["imageset"], - "swiftPath": "../Sources/Resource/Keys/ImageKey.swift", + "swiftPath": "Sources/Resource/Keys/ImageKey.swift", "keyTypeName": "ImageKey", "accessLevel": "public" }, { "commandName": "xcassets2swift", "xcassetsPaths": [ - "../Sources/Resource/Resources/Assets.xcassets" + "Sources/Resource/Resources/Assets.xcassets" ], "assetTypes": ["colorset"], - "swiftPath": "../Sources/Resource/Keys/ColorKey.swift", + "swiftPath": "Sources/Resource/Keys/ColorKey.swift", "keyTypeName": "ColorKey", "accessLevel": "public" }, { "commandName": "fonts2swift", - "fontsPath": "../Sources/Resource/Resources/Fonts", - "swiftPath": "../Sources/Resource/Keys/FontKey.swift", + "fontsPath": "Sources/Resource/Resources/Fonts", + "swiftPath": "Sources/Resource/Keys/FontKey.swift", "keyTypeName": "FontKey", "accessLevel": "public" }, { "commandName": "key2form", - "keyFilePath": "../Sources/Resource/Keys/StringKey.swift", - "formFilePath": "../Sources/Resource/Keys/StringForm.swift", + "keyFilePath": "Sources/Resource/Keys/StringKey.swift", + "formFilePath": "Sources/Resource/Keys/StringForm.swift", "formTypeName": "StringForm", "issueReporter": "xcode", "accessLevel": "public" }, { "commandName": "swift2strings", - "swiftPath": "../Sources/Resource/Keys/StringKey.swift", - "resourcesPath": "../Sources/Resource/Resources", + "swiftPath": "Sources/Resource/Keys/StringKey.swift", + "resourcesPath": "Sources/Resource/Resources", "configurationsByLanguage": { "ko": { "mergeStrategy": "comment", @@ -52,8 +52,8 @@ }, { "commandName": "swift2stringsdict", - "swiftPath": "../Sources/Resource/Keys/StringKey.swift", - "resourcesPath": "../Sources/Resource/Resources", + "swiftPath": "Sources/Resource/Keys/StringKey.swift", + "resourcesPath": "Sources/Resource/Resources", "configurationsByLanguage": { "ko": { "mergeStrategy": "comment"