Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove singleton patterns #815

Merged
merged 1 commit into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .mise/tasks/lint
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ set -euo pipefail

cd $MISE_PROJECT_ROOT

swiftformat --quiet --strict
swiftformat --quiet --strict .
swiftlint lint --quiet --strict
5 changes: 3 additions & 2 deletions Sources/Frontend/Commands/CheckUpdateCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ struct CheckUpdateCommand: FrontendCommand {
)

func run() throws {
let logger = Logger()
let checker = UpdateChecker()
let configuration = Configuration()
let logger = Logger(configuration: configuration)
let checker = UpdateChecker(logger: logger, configuration: configuration)
DispatchQueue.global().async { checker.run() }
let latestVersion = try checker.wait().get()
if latestVersion.isVersion(greaterThan: PeripheryVersion) {
Expand Down
5 changes: 4 additions & 1 deletion Sources/Frontend/Commands/ClearCacheCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ struct ClearCacheCommand: FrontendCommand {
)

func run() throws {
try Shell.shared.exec(["rm", "-rf", Constants.cachePath().string])
let configuration = Configuration()
let logger = Logger(configuration: configuration)
let shell = Shell(logger: logger)
try shell.exec(["rm", "-rf", Constants.cachePath().string])
}
}
20 changes: 12 additions & 8 deletions Sources/Frontend/Commands/ScanBehavior.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ import SystemPackage
final class ScanBehavior {
private let configuration: Configuration
private let logger: Logger
private let shell: Shell
private let swiftVersion: SwiftVersion

required init(configuration: Configuration = .shared, logger: Logger = .init()) {
required init(configuration: Configuration, logger: Logger, shell: Shell, swiftVersion: SwiftVersion) {
self.configuration = configuration
self.logger = logger
self.shell = shell
self.swiftVersion = swiftVersion
}

func setup(_ configPath: FilePath?) -> Result<Void, PeripheryError> {
do {
try configuration.load(from: configPath)
try configuration.load(from: configPath, logger: logger)
} catch let error as PeripheryError {
return .failure(error)
} catch {
Expand All @@ -30,21 +34,21 @@ final class ScanBehavior {
let project: Project

do {
logger.debug(SwiftVersion.current.fullVersion)
try SwiftVersion.current.validateVersion()
logger.debug(swiftVersion.fullVersion)
try swiftVersion.validateVersion()

if configuration.guidedSetup {
project = try GuidedSetup().perform()
project = try GuidedSetup(configuration: configuration, shell: shell, logger: logger).perform()
} else {
project = try Project.identify()
project = try Project(configuration: configuration, shell: shell, logger: logger)
}
} catch let error as PeripheryError {
return .failure(error)
} catch {
return .failure(.underlyingError(error))
}

let updateChecker = UpdateChecker()
let updateChecker = UpdateChecker(logger: logger, configuration: configuration)
updateChecker.run()

let results: [ScanResult]
Expand All @@ -60,7 +64,7 @@ final class ScanBehavior {
baseline = try JSONDecoder().decode(Baseline.self, from: data)
}

let filteredResults = try OutputDeclarationFilter().filter(results, with: baseline)
let filteredResults = try OutputDeclarationFilter(configuration: configuration, logger: logger).filter(results, with: baseline)

if let baselinePath = configuration.writeBaseline {
let usrs = filteredResults
Expand Down
13 changes: 10 additions & 3 deletions Sources/Frontend/Commands/ScanCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,16 @@ struct ScanCommand: FrontendCommand {
private static let defaultConfiguration = Configuration()

func run() throws {
let scanBehavior = ScanBehavior()
let configuration = Configuration()
let logger = Logger(configuration: configuration)
let shell = Shell(logger: logger)
let swiftVersion = SwiftVersion(shell: shell)
let scanBehavior = ScanBehavior(configuration: configuration, logger: logger, shell: shell, swiftVersion: swiftVersion)

if !setup {
try scanBehavior.setup(config).get()
}

let configuration = Configuration.shared
configuration.guidedSetup = setup
configuration.apply(\.$project, project)
configuration.apply(\.$schemes, schemes)
Expand Down Expand Up @@ -184,7 +187,11 @@ struct ScanCommand: FrontendCommand {
configuration.apply(\.$bazelFilter, bazelFilter)

try scanBehavior.main { project in
try Scan().perform(project: project)
try Scan(
configuration: configuration,
logger: logger,
swiftVersion: swiftVersion
).perform(project: project)
}.get()
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Frontend/CommonSetupGuide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Shared
final class CommonSetupGuide: SetupGuideHelpers {
private let configuration: Configuration

required init(configuration: Configuration = .shared) {
required init(configuration: Configuration) {
self.configuration = configuration
super.init()
}
Expand Down
16 changes: 10 additions & 6 deletions Sources/Frontend/GuidedSetup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ import Shared
#endif

final class GuidedSetup: SetupGuideHelpers {
required init(configuration: Configuration = .shared) {
private let configuration: Configuration
private let shell: Shell
private let logger: Logger

required init(configuration: Configuration, shell: Shell, logger: Logger) {
self.configuration = configuration
self.shell = shell
self.logger = logger
}

private let configuration: Configuration

func perform() throws -> Project {
print(colorize("Welcome to Periphery!", .boldGreen))
print("This guided setup will help you select the appropriate configuration for your project.\n")
Expand All @@ -23,7 +27,7 @@ final class GuidedSetup: SetupGuideHelpers {
}

#if canImport(XcodeSupport)
if let guide = XcodeProjectSetupGuide.detect() {
if let guide = XcodeProjectSetupGuide(configuration: configuration, shell: shell, logger: logger) {
projectGuides.append(guide)
}
#endif
Expand All @@ -46,9 +50,9 @@ final class GuidedSetup: SetupGuideHelpers {
print(colorize("*", .boldGreen) + " Inspecting project...")

let kind = try projectGuide.perform()
let project = Project(kind: kind)
let project = Project(kind: kind, configuration: configuration, shell: shell, logger: logger)

let commonGuide = CommonSetupGuide()
let commonGuide = CommonSetupGuide(configuration: configuration)
try commonGuide.perform()

let options = projectGuide.commandLineOptions + commonGuide.commandLineOptions
Expand Down
60 changes: 46 additions & 14 deletions Sources/Frontend/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,74 @@ import Shared
import SystemPackage

final class Project {
static func identify() throws -> Self {
let configuration = Configuration.shared
let kind: ProjectKind

private let configuration: Configuration
private let shell: Shell
private let logger: Logger

convenience init(
configuration: Configuration,
shell: Shell,
logger: Logger
) throws {
var kind: ProjectKind?

if let path = configuration.project {
return self.init(kind: .xcode(projectPath: path))
kind = .xcode(projectPath: path)
} else if let path = configuration.genericProjectConfig {
return self.init(kind: .generic(genericProjectConfig: path))
kind = .generic(genericProjectConfig: path)
} else if BazelProjectDriver.isSupported, configuration.bazel {
return self.init(kind: .bazel)
kind = .bazel
} else if SPM.isSupported {
return self.init(kind: .spm)
kind = .spm
}

throw PeripheryError.usageError("Failed to identify project in the current directory. For Xcode projects use the '--project' option, and for SPM projects change to the directory containing the Package.swift.")
}
guard let kind else {
throw PeripheryError.usageError("Failed to identify project in the current directory. For Xcode projects use the '--project' option, and for SPM projects change to the directory containing the Package.swift.")
}

let kind: ProjectKind
self.init(kind: kind, configuration: configuration, shell: shell, logger: logger)
}

init(kind: ProjectKind) {
init(
kind: ProjectKind,
configuration: Configuration,
shell: Shell,
logger: Logger
) {
self.kind = kind
self.configuration = configuration
self.shell = shell
self.logger = logger
}

func driver() throws -> ProjectDriver {
switch kind {
case let .xcode(projectPath):
#if canImport(XcodeSupport)
return try XcodeProjectDriver.build(projectPath: projectPath)
return try XcodeProjectDriver(
projectPath: projectPath,
configuration: configuration,
shell: shell,
logger: logger
)
#else
fatalError("Xcode projects are not supported on this platform.")
#endif
case .spm:
return try SPMProjectDriver.build()
return try SPMProjectDriver(configuration: configuration, shell: shell, logger: logger)
case .bazel:
return try BazelProjectDriver.build()
return try BazelProjectDriver.build(
configuration: configuration,
shell: shell,
logger: logger
)
case let .generic(genericProjectConfig):
return try GenericProjectDriver.build(genericProjectConfig: genericProjectConfig)
return try GenericProjectDriver(
genericProjectConfig: genericProjectConfig,
configuration: configuration
)
}
}
}
16 changes: 12 additions & 4 deletions Sources/Frontend/Scan.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import SourceGraph
final class Scan {
private let configuration: Configuration
private let logger: Logger
private let graph = SourceGraph.shared
private let graph: SourceGraph
private let swiftVersion: SwiftVersion

required init(configuration: Configuration = .shared, logger: Logger = .init()) {
required init(configuration: Configuration, logger: Logger, swiftVersion: SwiftVersion) {
self.configuration = configuration
self.logger = logger
self.swiftVersion = swiftVersion
graph = SourceGraph(configuration: configuration)
}

func perform(project: Project) throws -> [ScanResult] {
Expand Down Expand Up @@ -71,7 +74,7 @@ final class Scan {
let indexLogger = logger.contextualized(with: "index")
let plan = try driver.plan(logger: indexLogger)
let syncSourceGraph = SynchronizedSourceGraph(graph: graph)
let pipeline = IndexPipeline(plan: plan, graph: syncSourceGraph, logger: indexLogger)
let pipeline = IndexPipeline(plan: plan, graph: syncSourceGraph, logger: indexLogger, configuration: configuration)
try pipeline.perform()
logger.endInterval(indexInterval)
}
Expand All @@ -84,7 +87,12 @@ final class Scan {
logger.info("\(asterisk) Analyzing...")
}

try SourceGraphMutatorRunner.perform(graph: graph)
try SourceGraphMutatorRunner(
graph: graph,
logger: logger,
configuration: configuration,
swiftVersion: swiftVersion
).perform()
logger.endInterval(analyzeInterval)
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Frontend/UpdateChecker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final class UpdateChecker {
private let semaphore: DispatchSemaphore
private var error: Error?

required init(logger: Logger = .init(), configuration: Configuration = .shared) {
required init(logger: Logger, configuration: Configuration) {
self.logger = logger
debugLogger = logger.contextualized(with: "update-check")
self.configuration = configuration
Expand Down
5 changes: 3 additions & 2 deletions Sources/Frontend/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ struct PeripheryCommand: FrontendCommand {
}

signal(SIGINT) { _ in
let logger = Logger()
let logger = Logger(configuration: Configuration())
logger.warn(
"Termination can result in a corrupt index. Try the '--clean-build' flag if you get erroneous results such as false-positives and incorrect source file locations.",
newlinePrefix: true // Print a newline after ^C
)
Shell.shared.interruptRunning()
let shell = Shell(logger: logger)
shell.interruptRunning()
exit(0)
}

Expand Down
35 changes: 29 additions & 6 deletions Sources/Indexer/IndexPipeline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,57 @@ public struct IndexPipeline {
private let plan: IndexPlan
private let graph: SynchronizedSourceGraph
private let logger: ContextualLogger
private let configuration: Configuration

public init(plan: IndexPlan, graph: SynchronizedSourceGraph, logger: ContextualLogger) {
public init(plan: IndexPlan, graph: SynchronizedSourceGraph, logger: ContextualLogger, configuration: Configuration) {
self.plan = plan
self.graph = graph
self.logger = logger
self.configuration = configuration
}

public func perform() throws {
try SwiftIndexer(
sourceFiles: plan.sourceFiles,
graph: graph,
logger: logger
logger: logger,
configuration: configuration
).perform()

if !plan.plistPaths.isEmpty {
try InfoPlistIndexer(infoPlistFiles: plan.plistPaths, graph: graph).perform()
try InfoPlistIndexer(
infoPlistFiles: plan.plistPaths,
graph: graph,
logger: logger,
configuration: configuration
).perform()
}

if !plan.xibPaths.isEmpty {
try XibIndexer(xibFiles: plan.xibPaths, graph: graph).perform()
try XibIndexer(
xibFiles: plan.xibPaths,
graph: graph,
logger: logger,
configuration: configuration
).perform()
}

if !plan.xcDataModelPaths.isEmpty {
try XCDataModelIndexer(files: plan.xcDataModelPaths, graph: graph).perform()
try XCDataModelIndexer(
files: plan.xcDataModelPaths,
graph: graph,
logger: logger,
configuration: configuration
).perform()
}

if !plan.xcMappingModelPaths.isEmpty {
try XCMappingModelIndexer(files: plan.xcMappingModelPaths, graph: graph).perform()
try XCMappingModelIndexer(
files: plan.xcMappingModelPaths,
graph: graph,
logger: logger,
configuration: configuration
).perform()
}

graph.indexingComplete()
Expand Down
Loading
Loading