From b48eb77f7b9abbd682b6bec4ec14f3bae42b3dcb Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Thu, 16 May 2024 00:31:16 +0900 Subject: [PATCH 1/2] print watch log where it is done --- Sources/CartonCLI/Commands/Dev.swift | 3 --- Sources/CartonKit/Server/Server.swift | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/CartonCLI/Commands/Dev.swift b/Sources/CartonCLI/Commands/Dev.swift index 1fd6e33b..e86b3425 100644 --- a/Sources/CartonCLI/Commands/Dev.swift +++ b/Sources/CartonCLI/Commands/Dev.swift @@ -100,9 +100,6 @@ struct Dev: AsyncParsableCommand { if !verbose { terminal.revertCursorAndClear() } - terminal.write("\nWatching these directories for changes:\n", inColor: .green) - paths.forEach { terminal.logLookup("", $0) } - terminal.write("\n") let server = try await Server( .init( diff --git a/Sources/CartonKit/Server/Server.swift b/Sources/CartonKit/Server/Server.swift index 3cdaeb7c..f3d31e31 100644 --- a/Sources/CartonKit/Server/Server.swift +++ b/Sources/CartonKit/Server/Server.swift @@ -165,6 +165,12 @@ public actor Server { } if !builder.pathsToWatch.isEmpty { + let terminal = configuration.terminal + + terminal.write("\nWatching these directories for changes:\n", inColor: .green) + builder.pathsToWatch.forEach { terminal.logLookup("", $0) } + terminal.write("\n") + watcher = FSWatch(paths: builder.pathsToWatch, latency: 0.1) { [weak self] changes in guard let self = self, !changes.isEmpty else { return } Task { try await self.onChange(changes, configuration) } From 93dcdf519e105f16bff935ea023fba017c8d5e1d Mon Sep 17 00:00:00 2001 From: omochimetaru Date: Thu, 16 May 2024 00:55:40 +0900 Subject: [PATCH 2/2] Make watch pipes optional --- Sources/CartonCLI/Commands/Dev.swift | 58 +++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/Sources/CartonCLI/Commands/Dev.swift b/Sources/CartonCLI/Commands/Dev.swift index e86b3425..b6e63295 100644 --- a/Sources/CartonCLI/Commands/Dev.swift +++ b/Sources/CartonCLI/Commands/Dev.swift @@ -18,6 +18,22 @@ import CartonKit import Foundation struct Dev: AsyncParsableCommand { + enum Error: Swift.Error & CustomStringConvertible { + case noBuildRequestOption + case noBuildResponseOption + case failedToOpenBuildRequestPipe + case failedToOpenBuildResponsePipe + + var description: String { + switch self { + case .noBuildRequestOption: "--build-request option is necessary if you want to watch, but has not been specified." + case .noBuildResponseOption: "--build-response option is necessary if you want to watch, but has not been specified." + case .failedToOpenBuildRequestPipe: "failed to open build request pipe" + case .failedToOpenBuildResponsePipe: "failed to open build response pipe" + } + } + } + static let entrypoint = Entrypoint(fileName: "dev.js", content: StaticResource.dev) @Option(help: "Specify name of an executable product in development.") @@ -68,7 +84,7 @@ struct Dev: AsyncParsableCommand { visibility: .private ) ) - var buildRequest: String + var buildRequest: String? @Option( help: ArgumentHelp( @@ -76,7 +92,7 @@ struct Dev: AsyncParsableCommand { visibility: .private ) ) - var buildResponse: String + var buildResponse: String? @Option( help: ArgumentHelp( @@ -90,24 +106,46 @@ struct Dev: AsyncParsableCommand { abstract: "Watch the current directory, host the app, rebuild on change." ) - func run() async throws { - let terminal = InteractiveWriter.stdout + private func makeBuilderIfNeed() throws -> SwiftPMPluginBuilder? { + guard !watchPaths.isEmpty else { + return nil + } + + guard let buildRequest else { + throw Error.noBuildRequestOption + } + guard let buildResponse else { + throw Error.noBuildResponseOption + } - let paths = try watchPaths.map { + let pathsToWatch = try watchPaths.map { try AbsolutePath(validating: $0, relativeTo: localFileSystem.currentWorkingDirectory!) } + guard let buildRequest = FileHandle(forWritingAtPath: buildRequest) else { + throw Error.failedToOpenBuildRequestPipe + } + guard let buildResponse = FileHandle(forReadingAtPath: buildResponse) else { + throw Error.failedToOpenBuildResponsePipe + } + + return SwiftPMPluginBuilder( + pathsToWatch: pathsToWatch, + buildRequest: buildRequest, + buildResponse: buildResponse + ) + } + + func run() async throws { + let terminal = InteractiveWriter.stdout + if !verbose { terminal.revertCursorAndClear() } let server = try await Server( .init( - builder: SwiftPMPluginBuilder( - pathsToWatch: paths, - buildRequest: FileHandle(forWritingAtPath: buildRequest)!, - buildResponse: FileHandle(forReadingAtPath: buildResponse)! - ), + builder: try makeBuilderIfNeed(), mainWasmPath: AbsolutePath( validating: mainWasmPath, relativeTo: localFileSystem.currentWorkingDirectory!), verbose: verbose,