diff --git a/Package.swift b/Package.swift index 1f5c5742d..bd29c24c7 100644 --- a/Package.swift +++ b/Package.swift @@ -20,22 +20,28 @@ dependencies.append( ) #endif -var frontendDependencies: [PackageDescription.Target.Dependency] = [ - .target(name: "Shared"), - .target(name: "SourceGraph"), - .target(name: "PeripheryKit"), - .product(name: "ArgumentParser", package: "swift-argument-parser"), - .product(name: "FilenameMatcher", package: "swift-filename-matcher") +var projectDriverDependencies: [PackageDescription.Target.Dependency] = [ + .target(name: "SourceGraph"), + .target(name: "Shared"), + .target(name: "Indexer"), ] #if os(macOS) -frontendDependencies.append(.target(name: "XcodeSupport")) +projectDriverDependencies.append(.target(name: "XcodeSupport")) #endif + var targets: [PackageDescription.Target] = [ .executableTarget( name: "Frontend", - dependencies: frontendDependencies + dependencies: [ + .target(name: "Shared"), + .target(name: "SourceGraph"), + .target(name: "PeripheryKit"), + .target(name: "ProjectDrivers"), + .product(name: "ArgumentParser", package: "swift-argument-parser"), + .product(name: "FilenameMatcher", package: "swift-filename-matcher") + ] ), .target( name: "PeripheryKit", @@ -59,6 +65,10 @@ var targets: [PackageDescription.Target] = [ .product(name: "SwiftIndexStore", package: "swift-indexstore") ] ), + .target( + name: "ProjectDrivers", + dependencies: projectDriverDependencies + ), .target( name: "SyntaxAnalysis", dependencies: [ @@ -85,7 +95,8 @@ var targets: [PackageDescription.Target] = [ .target( name: "TestShared", dependencies: [ - .target(name: "PeripheryKit") + .target(name: "PeripheryKit"), + .target(name: "ProjectDrivers") ], path: "Tests/Shared" ), @@ -128,9 +139,9 @@ targets.append(contentsOf: [ .testTarget( name: "XcodeTests", dependencies: [ + .target(name: "ProjectDrivers"), .target(name: "TestShared"), .target(name: "PeripheryKit"), - .target(name: "XcodeSupport") ], exclude: ["UIKitProject", "SwiftUIProject"] ) diff --git a/Sources/Frontend/Project.swift b/Sources/Frontend/Project.swift index 12f00df83..296640363 100644 --- a/Sources/Frontend/Project.swift +++ b/Sources/Frontend/Project.swift @@ -1,12 +1,8 @@ import Foundation -import PeripheryKit +import ProjectDrivers import Shared import SystemPackage -#if canImport(XcodeSupport) -import XcodeSupport -#endif - final class Project { static func identify() throws -> Self { let configuration = Configuration.shared diff --git a/Sources/Frontend/SPMProjectSetupGuide.swift b/Sources/Frontend/SPMProjectSetupGuide.swift index b5525f63a..8d2e7c5ec 100644 --- a/Sources/Frontend/SPMProjectSetupGuide.swift +++ b/Sources/Frontend/SPMProjectSetupGuide.swift @@ -1,5 +1,4 @@ import Foundation -import PeripheryKit import Shared import SystemPackage diff --git a/Sources/Frontend/Scan.swift b/Sources/Frontend/Scan.swift index c5452b00a..8a54abc1b 100644 --- a/Sources/Frontend/Scan.swift +++ b/Sources/Frontend/Scan.swift @@ -1,4 +1,5 @@ import Foundation +import ProjectDrivers import Indexer import PeripheryKit import Shared diff --git a/Sources/PeripheryKit/Generic/GenericProjectDriver.swift b/Sources/ProjectDrivers/GenericProjectDriver.swift similarity index 100% rename from Sources/PeripheryKit/Generic/GenericProjectDriver.swift rename to Sources/ProjectDrivers/GenericProjectDriver.swift diff --git a/Sources/PeripheryKit/ProjectDriver.swift b/Sources/ProjectDrivers/ProjectDriver.swift similarity index 100% rename from Sources/PeripheryKit/ProjectDriver.swift rename to Sources/ProjectDrivers/ProjectDriver.swift diff --git a/Sources/PeripheryKit/SPM/SPMProjectDriver.swift b/Sources/ProjectDrivers/SPMProjectDriver.swift similarity index 100% rename from Sources/PeripheryKit/SPM/SPMProjectDriver.swift rename to Sources/ProjectDrivers/SPMProjectDriver.swift diff --git a/Sources/XcodeSupport/XcodeProjectDriver.swift b/Sources/ProjectDrivers/XcodeProjectDriver.swift similarity index 99% rename from Sources/XcodeSupport/XcodeProjectDriver.swift rename to Sources/ProjectDrivers/XcodeProjectDriver.swift index 3ce56ef03..81fbdd00a 100644 --- a/Sources/XcodeSupport/XcodeProjectDriver.swift +++ b/Sources/ProjectDrivers/XcodeProjectDriver.swift @@ -1,6 +1,7 @@ +#if os(macOS) import Foundation +import XcodeSupport import Indexer -import PeripheryKit import Shared import SourceGraph import SystemPackage @@ -123,3 +124,4 @@ extension XcodeProjectDriver: ProjectDriver { ) } } +#endif diff --git a/Sources/PeripheryKit/SPM/SPM.swift b/Sources/Shared/SPM.swift similarity index 88% rename from Sources/PeripheryKit/SPM/SPM.swift rename to Sources/Shared/SPM.swift index 1bc22e32b..b6fb65594 100644 --- a/Sources/PeripheryKit/SPM/SPM.swift +++ b/Sources/Shared/SPM.swift @@ -1,5 +1,4 @@ import Foundation -import Shared import SystemPackage public enum SPM { @@ -10,22 +9,24 @@ public enum SPM { } public struct Package { - let path: FilePath = .current + public let path: FilePath = .current let configuration: Configuration = .shared + + public init() { } var exists: Bool { path.appending(packageFile).exists } - func clean() throws { + public func clean() throws { try Shell.shared.exec(["swift", "package", "clean"]) } - func build(additionalArguments: [String]) throws { + public func build(additionalArguments: [String]) throws { try Shell.shared.exec(["swift", "build", "--build-tests"] + additionalArguments) } - func testTargetNames() throws -> Set { + public func testTargetNames() throws -> Set { let description = try load() return description.targets.filter(\.isTestTarget).mapSet(\.name) } diff --git a/Sources/XcodeSupport/XcodeProject.swift b/Sources/XcodeSupport/XcodeProject.swift index a406c7351..6d1464c83 100644 --- a/Sources/XcodeSupport/XcodeProject.swift +++ b/Sources/XcodeSupport/XcodeProject.swift @@ -2,7 +2,8 @@ import Foundation import Shared import SystemPackage import XcodeProj -final class XcodeProject: XcodeProjectlike { + +public final class XcodeProject: XcodeProjectlike { private static var cache: [FilePath: XcodeProject] = [:] static func build(path: FilePath, referencedBy refPath: FilePath) throws -> XcodeProject? { @@ -23,17 +24,18 @@ final class XcodeProject: XcodeProjectlike { return try self.init(path: path) } - let type: String = "project" - let path: FilePath - let sourceRoot: FilePath - let xcodeProject: XcodeProj - let name: String + public let type: String = "project" + public let path: FilePath + public let sourceRoot: FilePath + public let name: String + public private(set) var targets: Set = [] + let xcodeProject: XcodeProj + private let xcodebuild: Xcodebuild - private(set) var targets: Set = [] - required init(path: FilePath, xcodebuild: Xcodebuild = .init(), logger: Logger = .init()) throws { + public required init(path: FilePath, xcodebuild: Xcodebuild = .init(), logger: Logger = .init()) throws { logger.contextualized(with: "xcode:project").debug("Loading \(path)") self.path = path @@ -65,19 +67,19 @@ final class XcodeProject: XcodeProjectlike { .union(subProjects.flatMapSet { $0.targets }) } - func schemes(additionalArguments: [String]) throws -> Set { + public func schemes(additionalArguments: [String]) throws -> Set { try xcodebuild.schemes(project: self, additionalArguments: additionalArguments) } } extension XcodeProject: Hashable { - func hash(into hasher: inout Hasher) { + public func hash(into hasher: inout Hasher) { hasher.combine(path.lexicallyNormalized().string) } } extension XcodeProject: Equatable { - static func == (lhs: XcodeProject, rhs: XcodeProject) -> Bool { + public static func == (lhs: XcodeProject, rhs: XcodeProject) -> Bool { lhs.path == rhs.path } } diff --git a/Sources/XcodeSupport/XcodeProjectlike.swift b/Sources/XcodeSupport/XcodeProjectlike.swift index 90ca1b887..f3b07191e 100644 --- a/Sources/XcodeSupport/XcodeProjectlike.swift +++ b/Sources/XcodeSupport/XcodeProjectlike.swift @@ -1,7 +1,7 @@ import Foundation import SystemPackage -protocol XcodeProjectlike: AnyObject { +public protocol XcodeProjectlike: AnyObject { var path: FilePath { get } var targets: Set { get } var type: String { get } @@ -11,7 +11,7 @@ protocol XcodeProjectlike: AnyObject { func schemes(additionalArguments: [String]) throws -> Set } -extension XcodeProjectlike { +public extension XcodeProjectlike { var name: String { path.lastComponent?.stem ?? "" } diff --git a/Sources/XcodeSupport/XcodeTarget.swift b/Sources/XcodeSupport/XcodeTarget.swift index 407b22384..c3302597c 100644 --- a/Sources/XcodeSupport/XcodeTarget.swift +++ b/Sources/XcodeSupport/XcodeTarget.swift @@ -3,7 +3,7 @@ import SourceGraph import SystemPackage import XcodeProj -final class XcodeTarget { +public final class XcodeTarget { let project: XcodeProject private let target: PBXTarget @@ -14,15 +14,15 @@ final class XcodeTarget { self.target = target } - var isTestTarget: Bool { + public var isTestTarget: Bool { target.productType?.rawValue.contains("test") ?? false } - var name: String { + public var name: String { target.name } - func identifyFiles() throws { + public func identifyFiles() throws { let sourcesBuildPhases = project.xcodeProject.pbxproj.sourcesBuildPhases let resourcesBuildPhases = project.xcodeProject.pbxproj.resourcesBuildPhases @@ -32,7 +32,7 @@ final class XcodeTarget { try identifyInfoPlistFiles() } - func files(kind: ProjectFileKind) -> Set { + public func files(kind: ProjectFileKind) -> Set { files[kind, default: []] } @@ -75,13 +75,13 @@ final class XcodeTarget { } extension XcodeTarget: Hashable { - func hash(into hasher: inout Hasher) { + public func hash(into hasher: inout Hasher) { hasher.combine(target.name) } } extension XcodeTarget: Equatable { - static func == (lhs: XcodeTarget, rhs: XcodeTarget) -> Bool { + public static func == (lhs: XcodeTarget, rhs: XcodeTarget) -> Bool { lhs.name == rhs.name } } diff --git a/Sources/XcodeSupport/XcodeWorkspace.swift b/Sources/XcodeSupport/XcodeWorkspace.swift index fdf280b31..e0c223097 100644 --- a/Sources/XcodeSupport/XcodeWorkspace.swift +++ b/Sources/XcodeSupport/XcodeWorkspace.swift @@ -2,18 +2,19 @@ import Foundation import Shared import SystemPackage import XcodeProj -final class XcodeWorkspace: XcodeProjectlike { - let type: String = "workspace" - let path: FilePath - let sourceRoot: FilePath + +public final class XcodeWorkspace: XcodeProjectlike { + public let type: String = "workspace" + public let path: FilePath + public let sourceRoot: FilePath private let xcodebuild: Xcodebuild private let configuration: Configuration private let xcworkspace: XCWorkspace - private(set) var targets: Set = [] + public private(set) var targets: Set = [] - required init(path: FilePath, xcodebuild: Xcodebuild = .init(), configuration: Configuration = .shared, logger: Logger = .init()) throws { + public required init(path: FilePath, xcodebuild: Xcodebuild = .init(), configuration: Configuration = .shared, logger: Logger = .init()) throws { logger.contextualized(with: "xcode:workspace").debug("Loading \(path)") self.path = path @@ -35,7 +36,7 @@ final class XcodeWorkspace: XcodeProjectlike { } } - func schemes(additionalArguments: [String]) throws -> Set { + public func schemes(additionalArguments: [String]) throws -> Set { try xcodebuild.schemes(project: self, additionalArguments: additionalArguments) } diff --git a/Sources/XcodeSupport/Xcodebuild.swift b/Sources/XcodeSupport/Xcodebuild.swift index d533b48c1..bfb56b265 100644 --- a/Sources/XcodeSupport/Xcodebuild.swift +++ b/Sources/XcodeSupport/Xcodebuild.swift @@ -32,7 +32,7 @@ public final class Xcodebuild { } @discardableResult - func build(project: XcodeProjectlike, scheme: String, allSchemes: [String], additionalArguments: [String] = []) throws -> String { + public func build(project: XcodeProjectlike, scheme: String, allSchemes: [String], additionalArguments: [String] = []) throws -> String { let args = [ "-\(project.type)", "'\(project.path.lexicallyNormalized().string)'", "-scheme", "'\(scheme)'", @@ -54,11 +54,11 @@ public final class Xcodebuild { return try shell.exec(["/bin/sh", "-c", xcodebuild]) } - func removeDerivedData(for project: XcodeProjectlike, allSchemes: [String]) throws { + public func removeDerivedData(for project: XcodeProjectlike, allSchemes: [String]) throws { try shell.exec(["rm", "-rf", try derivedDataPath(for: project, schemes: allSchemes).string]) } - func indexStorePath(project: XcodeProjectlike, schemes: [String]) throws -> FilePath { + public func indexStorePath(project: XcodeProjectlike, schemes: [String]) throws -> FilePath { let derivedDataPath = try derivedDataPath(for: project, schemes: schemes) let pathsToTry = ["Index.noindex/DataStore", "Index/DataStore"] .map { derivedDataPath.appending($0) } diff --git a/Tests/Shared/SPMSourceGraphTestCase.swift b/Tests/Shared/SPMSourceGraphTestCase.swift index ce834aeac..b1f2a70c7 100644 --- a/Tests/Shared/SPMSourceGraphTestCase.swift +++ b/Tests/Shared/SPMSourceGraphTestCase.swift @@ -1,6 +1,6 @@ import Foundation -import PeripheryKit import Shared +import ProjectDrivers import SystemPackage class SPMSourceGraphTestCase: SourceGraphTestCase { diff --git a/Tests/XcodeTests/XcodeSourceGraphTestCase.swift b/Tests/XcodeTests/XcodeSourceGraphTestCase.swift index 0676891c0..0b5036605 100644 --- a/Tests/XcodeTests/XcodeSourceGraphTestCase.swift +++ b/Tests/XcodeTests/XcodeSourceGraphTestCase.swift @@ -1,8 +1,8 @@ import Foundation import Shared +import ProjectDrivers import SystemPackage @testable import TestShared -import XcodeSupport class XcodeSourceGraphTestCase: SourceGraphTestCase { static func build(projectPath: FilePath) {