Skip to content
Draft
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
4 changes: 1 addition & 3 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
**/*.pb.swift linguist-generated=true
**/*.grpc.swift linguist-generated=true
Coder-Desktop/VPNLib/FileSync/MutagenSDK/*.proto linguist-generated=true
Coder-Desktop/Proto/Sources/MutagenProto/*.proto linguist-generated=true
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ jobs:
test:
name: test
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-26' || 'macos-26'}}
env:
# Depot's Xcode compilation caching remaps DerivedData to /^dd, which
# breaks the path swift-protobuf's protoc uses to find the well-known
# type protos (google/protobuf/*.proto) during codegen.
# See https://github.com/apple/swift-protobuf/pull/2060
DEPOT_XCODE_CACHE_ENABLED: 0
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ jobs:
contents: write
# for GCP auth
id-token: write
env:
# See the test job in ci.yml.
DEPOT_XCODE_CACHE_ENABLED: 0
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ Package.resolved
*.xcodeproj
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
# hence it is not needed unless you have added a package configuration file to your project
# .swiftpm
.swiftpm

.build/

Expand Down
3 changes: 0 additions & 3 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
# TODO: Remove this once the grpc-swift-protobuf generator adds a lint disable comment
excluded:
- "**/*.pb.swift"
- "**/*.grpc.swift"
- "**/.build/"
1 change: 0 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ Here are some useful `make` commands for working with the project:
- `make lint`: Lint Swift files using SwiftLint.
- `make test`: Run all tests using `xcodebuild`.
- `make clean`: Clean the Xcode project.
- `make proto`: Generate Swift files from protobufs.
- `make help`: Display all available `make` commands with descriptions.

For continuous development, you can also use:
Expand Down
1 change: 0 additions & 1 deletion Coder-Desktop/.swiftformat
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
--selfrequired log,info,error,debug,critical,fault
--exclude **.pb.swift,**.grpc.swift
--condassignment always
--disable unusedArguments,wrapIfStatementBodies,wrapPropertyBodies
5 changes: 3 additions & 2 deletions Coder-Desktop/Coder-Desktop/UpdaterService.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Sparkle
import SwiftUI

@MainActor
final class UpdaterService: NSObject, ObservableObject {
/// The auto-updater can be entirely disabled by setting the
/// `disableUpdater` UserDefaults key to `true`. This is designed for use in
Expand Down Expand Up @@ -87,7 +88,7 @@ extension UpdaterService: SPUUpdaterDelegate {
}

extension UpdaterService: SUVersionDisplay {
func formatUpdateVersion(
nonisolated func formatUpdateVersion(
fromUpdate update: SUAppcastItem,
andBundleDisplayVersion inOutBundleDisplayVersion: AutoreleasingUnsafeMutablePointer<NSString>,
withBundleVersion bundleVersion: String
Expand All @@ -102,7 +103,7 @@ extension UpdaterService: SUVersionDisplay {
}

extension UpdaterService: SPUStandardUserDriverDelegate {
func standardUserDriverRequestsVersionDisplayer() -> (any SUVersionDisplay)? {
nonisolated func standardUserDriverRequestsVersionDisplayer() -> (any SUVersionDisplay)? {
self
}
}
1 change: 1 addition & 0 deletions Coder-Desktop/Coder-Desktop/VPN/MenuState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Foundation
import SwiftProtobuf
import SwiftUI
import VPNLib
import VPNProto

struct Agent: Identifiable, Equatable, Comparable, Hashable {
let id: UUID
Expand Down
1 change: 1 addition & 0 deletions Coder-Desktop/Coder-Desktop/VPN/VPNService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import NetworkExtension
import os
import SwiftUI
import VPNLib
import VPNProto

@MainActor
protocol VPNService: ObservableObject {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import CoderSDK
import Foundation
import os
import VPNLib
import VPNProto

/// This listener handles XPC connections from the Coder Desktop System Network
/// Extension (`com.coder.Coder-Desktop.VPN`).
Expand Down
1 change: 1 addition & 0 deletions Coder-Desktop/Coder-DesktopHelper/Manager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import CoderSDK
import NetworkExtension
import os
import VPNLib
import VPNProto

actor Manager {
let cfg: ManagerConfig
Expand Down
2 changes: 0 additions & 2 deletions Coder-Desktop/Coder-DesktopTests/FileSyncDaemonTests.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
@testable import Coder_Desktop
import Foundation
import GRPC
import NIO
import Subprocess
import Testing
import VPNLib
Expand Down
1 change: 1 addition & 0 deletions Coder-Desktop/Coder-DesktopTests/VPNMenuStateTests.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@testable import Coder_Desktop
import Testing
@testable import VPNLib
import VPNProto

@MainActor
struct VPNMenuStateTests {
Expand Down
46 changes: 46 additions & 0 deletions Coder-Desktop/Proto/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// swift-tools-version: 6.0

// The protocol definitions used by Coder Desktop. The Swift code for each
// target is generated at build time from its .proto files, as configured by its
// grpc-swift-proto-generator-config.json.
//
// Coder Desktop pins the exact dependency versions in project.yml.

import PackageDescription

let generator = Target.PluginUsage.plugin(name: "GRPCProtobufGenerator", package: "grpc-swift-protobuf")

let package = Package(
name: "Proto",
platforms: [.macOS(.v15)],
products: [
.library(name: "VPNProto", targets: ["VPNProto"]),
.library(name: "MutagenProto", targets: ["MutagenProto"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-protobuf.git", from: "1.39.0"),
.package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.4.4"),
.package(url: "https://github.com/grpc/grpc-swift-protobuf.git", from: "2.5.0"),
],
targets: [
// Messages for the tunnel protocol shared with coder/coder.
.target(
name: "VPNProto",
dependencies: [
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
],
plugins: [generator]
),
// Messages and gRPC clients for the Mutagen daemon, vendored by
// scripts/mutagen-proto.sh.
.target(
name: "MutagenProto",
dependencies: [
.product(name: "SwiftProtobuf", package: "swift-protobuf"),
.product(name: "GRPCCore", package: "grpc-swift-2"),
.product(name: "GRPCProtobuf", package: "grpc-swift-protobuf"),
],
plugins: [generator]
),
]
)
3 changes: 3 additions & 0 deletions Coder-Desktop/Proto/Sources/MutagenProto/MutagenProto.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// The Swift code for this module is generated at build time from the .proto
// files in this directory. SwiftPM refuses to load a target with no Swift
// sources, and generated sources don't count, so this file must exist.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"generate": {
"clients": true,
"servers": false,
"messages": true
},
"generatedSource": {
"accessLevel": "public"
}
}
3 changes: 3 additions & 0 deletions Coder-Desktop/Proto/Sources/VPNProto/VPNProto.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// The Swift code for this module is generated at build time from the .proto
// files in this directory. SwiftPM refuses to load a target with no Swift
// sources, and generated sources don't count, so this file must exist.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"generate": {
"clients": false,
"servers": false,
"messages": true
},
"generatedSource": {
"accessLevel": "public"
}
}
1 change: 1 addition & 0 deletions Coder-Desktop/VPN/NEHelperXPCClient.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Foundation
import os
import VPNLib
import VPNProto

final class HelperXPCClient: @unchecked Sendable {
var ptp: PacketTunnelProvider?
Expand Down
1 change: 1 addition & 0 deletions Coder-Desktop/VPN/PacketTunnelProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import CoderSDK
import NetworkExtension
import os
import VPNLib
import VPNProto

/** From <sys/kern_control.h> */
let CTLIOCGINFO: UInt = 0xC064_4E03
Expand Down
15 changes: 11 additions & 4 deletions Coder-Desktop/VPNLib/CoderRouter.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import CasePaths
import Foundation
import URLRouting

Expand All @@ -7,11 +8,16 @@ public struct CoderRouter: ParserPrinter {
public init() {}

public var body: some ParserPrinter<URLRequestData, CoderRoute> {
Route(.case(CoderRoute.open(workspace:agent:route:))) {
Route(.case(\CoderRoute.Cases.open)) {
Scheme("coder")
// v0/open/ws/<workspace>/agent/<agent>/<openType>
Path { "v0"; "open"; "ws"; Parse(.string); "agent"; Parse(.string) }
openRouter
Parse(.convert(
apply: { (workspace: $0, agent: $1, route: $2) },
unapply: { ($0.workspace, $0.agent, $0.route) }
)) {
// v0/open/ws/<workspace>/agent/<agent>/<openType>
Path { "v0"; "open"; "ws"; Parse(.string); "agent"; Parse(.string) }
openRouter
}
}
}

Expand Down Expand Up @@ -74,6 +80,7 @@ public enum OpenError: Error {
public var localizedDescription: String { description }
}

@CasePathable
public enum CoderRoute: Equatable, Sendable {
case open(workspace: String, agent: String, route: OpenRoute)
}
Expand Down
18 changes: 18 additions & 0 deletions Coder-Desktop/VPNLib/FileSync/DaemonClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
internal import MutagenProto
import GRPCCore
import GRPCNIOTransportHTTP2Posix

struct DaemonClient {
let mgmt: Daemon_Daemon.Client<HTTP2ClientTransport.Posix>
let sync: Synchronization_Synchronization.Client<HTTP2ClientTransport.Posix>
let prompt: Prompting_Prompting.Client<HTTP2ClientTransport.Posix>
}

extension CallOptions {
static func timeout(_ timeout: Duration, waitForReady: Bool? = nil) -> Self {
var options = Self.defaults
options.timeout = timeout
options.waitForReady = waitForReady
return options
}
}
Loading
Loading