mac: honor local relay path

This commit is contained in:
Peter Steinberger
2025-12-09 17:40:44 +00:00
parent 67f2bc1385
commit a4d5b68134

View File

@@ -73,6 +73,8 @@ enum RelayEnvironment {
static func check() -> RelayEnvironmentStatus { static func check() -> RelayEnvironmentStatus {
let expected = self.expectedRelayVersion() let expected = self.expectedRelayVersion()
let projectRoot = CommandResolver.projectRoot()
let projectEntrypoint = CommandResolver.relayEntrypoint(in: projectRoot)
switch RuntimeLocator.resolve(searchPaths: CommandResolver.preferredPaths()) { switch RuntimeLocator.resolve(searchPaths: CommandResolver.preferredPaths()) {
case let .failure(err): case let .failure(err):
@@ -83,7 +85,9 @@ enum RelayEnvironment {
requiredRelay: expected?.description, requiredRelay: expected?.description,
message: RuntimeLocator.describeFailure(err)) message: RuntimeLocator.describeFailure(err))
case let .success(runtime): case let .success(runtime):
guard let relayBin = CommandResolver.clawdisExecutable() else { let relayBin = CommandResolver.clawdisExecutable()
if relayBin == nil, projectEntrypoint == nil {
return RelayEnvironmentStatus( return RelayEnvironmentStatus(
kind: .missingRelay, kind: .missingRelay,
nodeVersion: runtime.version.description, nodeVersion: runtime.version.description,
@@ -92,7 +96,9 @@ enum RelayEnvironment {
message: "clawdis CLI not found in PATH; install the global package.") message: "clawdis CLI not found in PATH; install the global package.")
} }
let installedRelay = self.readRelayVersion(binary: relayBin) let installedRelay = relayBin.flatMap { self.readRelayVersion(binary: $0) }
?? self.readLocalRelayVersion(projectRoot: projectRoot)
if let expected, let installed = installedRelay, !installed.compatible(with: expected) { if let expected, let installed = installedRelay, !installed.compatible(with: expected) {
return RelayEnvironmentStatus( return RelayEnvironmentStatus(
kind: .incompatible(found: installed.description, required: expected.description), kind: .incompatible(found: installed.description, required: expected.description),
@@ -102,24 +108,42 @@ enum RelayEnvironment {
message: "Relay version \(installed.description) is incompatible with app \(expected.description); install/update the global package.") message: "Relay version \(installed.description) is incompatible with app \(expected.description); install/update the global package.")
} }
let relayLabel = relayBin != nil ? "global" : "local"
let relayVersionText = installedRelay?.description ?? "unknown"
return RelayEnvironmentStatus( return RelayEnvironmentStatus(
kind: .ok, kind: .ok,
nodeVersion: runtime.version.description, nodeVersion: runtime.version.description,
relayVersion: installedRelay?.description, relayVersion: relayVersionText,
requiredRelay: expected?.description, requiredRelay: expected?.description,
message: "Node \(runtime.version.description); relay \(installedRelay?.description ?? "unknown")") message: "Node \(runtime.version.description); relay \(relayVersionText) (\(relayLabel))")
} }
} }
static func resolveGatewayCommand() -> RelayCommandResolution { static func resolveGatewayCommand() -> RelayCommandResolution {
let projectRoot = CommandResolver.projectRoot()
let projectEntrypoint = CommandResolver.relayEntrypoint(in: projectRoot)
let status = self.check() let status = self.check()
guard case .ok = status.kind, let relayBin = CommandResolver.clawdisExecutable() else { let relayBin = CommandResolver.clawdisExecutable()
let runtime = RuntimeLocator.resolve(searchPaths: CommandResolver.preferredPaths())
guard case .ok = status.kind else {
return RelayCommandResolution(status: status, command: nil) return RelayCommandResolution(status: status, command: nil)
} }
let port = self.gatewayPort() let port = self.gatewayPort()
let cmd = [relayBin, "gateway", "--port", "\(port)"] if let relayBin {
return RelayCommandResolution(status: status, command: cmd) let cmd = [relayBin, "gateway", "--port", "\(port)"]
return RelayCommandResolution(status: status, command: cmd)
}
if let entry = projectEntrypoint,
case let .success(resolvedRuntime) = runtime
{
let cmd = [resolvedRuntime.path, entry, "gateway", "--port", "\(port)"]
return RelayCommandResolution(status: status, command: cmd)
}
return RelayCommandResolution(status: status, command: nil)
} }
static func installGlobal(version: Semver?, statusHandler: @escaping @Sendable (String) -> Void) async { static func installGlobal(version: Semver?, statusHandler: @escaping @Sendable (String) -> Void) async {
@@ -159,4 +183,14 @@ enum RelayEnvironment {
return nil return nil
} }
} }
private static func readLocalRelayVersion(projectRoot: URL) -> Semver? {
let pkg = projectRoot.appendingPathComponent("package.json")
guard let data = try? Data(contentsOf: pkg) else { return nil }
guard
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let version = json["version"] as? String
else { return nil }
return Semver.parse(version)
}
} }