From 83f1dd7eaaea7e59e6f2290269b5ba8ea226740d Mon Sep 17 00:00:00 2001 From: rockname <8536870+rockname@users.noreply.github.com> Date: Sat, 5 Apr 2025 13:08:26 +0900 Subject: [PATCH] Refactor SwordCommand using PathKit --- .../xcshareddata/swiftpm/Package.resolved | 18 ++++++ .../xcshareddata/swiftpm/Package.resolved | 18 ++++++ .../xcshareddata/swiftpm/Package.resolved | 18 ++++++ Package.resolved | 20 ++++++- Package.swift | 5 ++ Sources/SwordCommand/SwordCommand.swift | 58 +++++++------------ 6 files changed, 100 insertions(+), 37 deletions(-) diff --git a/Examples/SwiftPMBased/SNS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/SwiftPMBased/SNS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2f88bd1..aac1894 100644 --- a/Examples/SwiftPMBased/SNS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/SwiftPMBased/SNS.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,24 @@ { "originHash" : "a3fa290bcbfce4d4f9bf3405c71e02a2db942ac20aceb37135febb23e97a43e3", "pins" : [ + { + "identity" : "pathkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/PathKit.git", + "state" : { + "revision" : "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", + "version" : "1.0.1" + } + }, + { + "identity" : "spectre", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/Spectre.git", + "state" : { + "revision" : "26cc5e9ae0947092c7139ef7ba612e34646086c7", + "version" : "0.10.1" + } + }, { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", diff --git a/Examples/Xcode+SwiftPM/VoiceMemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/Xcode+SwiftPM/VoiceMemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index faa3e85..a3b153e 100644 --- a/Examples/Xcode+SwiftPM/VoiceMemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/Xcode+SwiftPM/VoiceMemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,24 @@ { "originHash" : "3d988b5313662882e23270f9255e3e9c96e39c59eb2d601b7cd7c5d84f7e530d", "pins" : [ + { + "identity" : "pathkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/PathKit.git", + "state" : { + "revision" : "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", + "version" : "1.0.1" + } + }, + { + "identity" : "spectre", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/Spectre.git", + "state" : { + "revision" : "26cc5e9ae0947092c7139ef7ba612e34646086c7", + "version" : "0.10.1" + } + }, { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", diff --git a/Examples/XcodeBased/Todos.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/XcodeBased/Todos.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index b18bfdd..f4a7d60 100644 --- a/Examples/XcodeBased/Todos.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/XcodeBased/Todos.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,6 +1,24 @@ { "originHash" : "8a90503551e47a4964a58e60e43b85cb8de3e169516624cd0b3f0f70f8660f1a", "pins" : [ + { + "identity" : "pathkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/PathKit.git", + "state" : { + "revision" : "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", + "version" : "1.0.1" + } + }, + { + "identity" : "spectre", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/Spectre.git", + "state" : { + "revision" : "26cc5e9ae0947092c7139ef7ba612e34646086c7", + "version" : "0.10.1" + } + }, { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", diff --git a/Package.resolved b/Package.resolved index dd8c75d..7fdc869 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,6 +1,24 @@ { - "originHash" : "9d38a79cc2441c1dc09089d58e953b2d3202489089fb3c3851c037bf6cfeadc2", + "originHash" : "0b30adf96b64ec74d227e0d4e109975a5b7d80b408caaf2548faddadc605935d", "pins" : [ + { + "identity" : "pathkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/PathKit.git", + "state" : { + "revision" : "3bfd2737b700b9a36565a8c94f4ad2b050a5e574", + "version" : "1.0.1" + } + }, + { + "identity" : "spectre", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kylef/Spectre.git", + "state" : { + "revision" : "26cc5e9ae0947092c7139ef7ba612e34646086c7", + "version" : "0.10.1" + } + }, { "identity" : "swift-argument-parser", "kind" : "remoteSourceControl", diff --git a/Package.swift b/Package.swift index 8a0f68b..7c933be 100644 --- a/Package.swift +++ b/Package.swift @@ -27,6 +27,10 @@ let package = Package( url: "https://github.com/davecom/SwiftGraph", from: "3.1.0" ), + .package( + url: "https://github.com/kylef/PathKit.git", + exact: "1.0.1" + ), ], targets: [ .target( @@ -60,6 +64,7 @@ let package = Package( name: "SwordCommand", dependencies: [ "SwordGenerator", + "PathKit", .product(name: "SwiftSyntax", package: "swift-syntax"), .product(name: "SwiftParser", package: "swift-syntax"), .product(name: "ArgumentParser", package: "swift-argument-parser"), diff --git a/Sources/SwordCommand/SwordCommand.swift b/Sources/SwordCommand/SwordCommand.swift index 295ea9c..ed73af0 100644 --- a/Sources/SwordCommand/SwordCommand.swift +++ b/Sources/SwordCommand/SwordCommand.swift @@ -1,5 +1,6 @@ import ArgumentParser import Foundation +import PathKit import SwiftParser import SwiftSyntax import SwordGenerator @@ -18,14 +19,23 @@ struct SwordCommand: AsyncParsableCommand { try loadLocalPackagesIfNeeded() // Parse files in current working directory if no inputs were specified. - let allInputs = inputs.isEmpty ? [""] : inputs - let sourceFiles = try allInputs.flatMap { input in - paths(in: input) + let allInputs = inputs.isEmpty ? ["."] : inputs + let sourceFilePaths = try allInputs.flatMap { input -> [URL] in + let path = Path(input) + return if path.isFile { + [path.absolute().url] + } else { + try path.recursiveChildren().compactMap { child in + guard child.extension == "swift" else { return nil } + + return child.absolute().url + } + } } - .map { url in - let source = try String(contentsOf: url) + let sourceFiles = try sourceFilePaths.map { sourceFilePath in + let source = try String(contentsOf: sourceFilePath, encoding: .utf8) return SourceFile( - path: url.path(), + path: sourceFilePath.path(), tree: Parser.parse(source: source) ) } @@ -47,43 +57,19 @@ struct SwordCommand: AsyncParsableCommand { } mutating private func loadLocalPackagesIfNeeded() throws { - let fileManager = FileManager.default - let configurationFilePath = URL(filePath: fileManager.currentDirectoryPath).appending(path: ".sword.yml") + let configurationPath = Path.current + ".sword.yml" + guard configurationPath.exists else { return } - guard fileManager.fileExists(atPath: configurationFilePath.path()) else { return } - - let data = try Data(contentsOf: configurationFilePath) + let data = try configurationPath.read() let configuration = try YAMLDecoder().decode(Configuration.self, from: data) for localPackage in configuration.localPackages { targets.append(contentsOf: localPackage.targets) - let inputPath = URL(filePath: fileManager.currentDirectoryPath) - .appending(path: localPackage.path) - .appending(path: "Sources") - if let enumerator = fileManager.enumerator(atPath: inputPath.path()) { - for case let filePath as String in enumerator { - if filePath.hasSuffix(".swift") { - let fullFilePath = inputPath.appending(path: filePath) - inputs.append(fullFilePath.path()) - } - } + let sourcesPath = Path.current + localPackage.path + "Sources" + for swiftFile in sourcesPath.glob("**/*.swift") { + inputs.append(swiftFile.string) } } } - - private func paths(in path: String) -> [URL] { - if path.isFile { - return [URL(filePath: path)] - } - - let fileManager = FileManager.default - let absolutePath = URL(filePath: fileManager.currentDirectoryPath).appending(path: path) - return fileManager.subpaths(atPath: absolutePath.path())?.compactMap { element -> URL? in - guard element.hasSuffix(".swift") else { return nil } - - let elementAbsolutePath = absolutePath.appending(path: element) - return elementAbsolutePath.path().isFile ? elementAbsolutePath : nil - } ?? [] - } }