Repository: CodeEditApp/CodeEdit
File: CodeEdit/Features/Git/Client/GitClient+Remote.swift (Swift)

Code before:
        let command = "remote -v"
        let output = try await run(command)
        let remotes = parseGitRemotes(from: output)

        return remotes
    }

    /// Add existing remote to local git
    /// - Parameter name: Name for remote
    /// - Parameter location: URL string for remote location
    func addRemote(name: String, location: String) async throws {
        _ = try await run("remote add \(name) \(location)")
    }

    /// Remove remote from local git
    /// - Parameter name: Name for remote to remove
    func removeRemote(name: String) async throws {
        _ = try await run("remote rm \(name)")
    }

    /// Get the URL of the remote
    /// > Note: If a git repository has multiple remotes, by default the `origin` remote
    /// > will be used, unless there’s an upstream branch configured for the current branch.
    /// > (Reference: https://git-scm.com/docs/git-ls-remote, https://git-scm.com/docs/git-fetch)
    /// - Returns: A URL if a remote is configured, nil otherwise
    func getRemoteURL() async -> URL? {
        do {
            let remote = try await run("ls-remote --get-url")
            return URL(string: remote.trimmingCharacters(in: .whitespacesAndNewlines))
        } catch {
            return nil
        }
    }
}

func parseGitRemotes(from output: String) -> [GitRemote] {
    var remotes: [String: (fetch: String?, push: String?)] = [:]

    output.split(separator: "\n").forEach { line in
        let components = line.split { $0 == " " || $0 == "\t" }
        guard components.count == 3 else { return }

        let name = String(components[0])
        let location = String(components[1])
        let type = components[2].contains("(fetch)") ? "fetch" : "push"

        if var remote = remotes[name] {
            if type == "fetch" {
                remote.fetch = location
            } else {
                remote.push = location

Review comment (suggestion):
I'm definitely open to comments on this function. A few things I'm not 100% on:

1. Is my approach idiomatic Swift? Would a seasoned Swift programmer do it differently? (I am not a seasoned Swift programmer!) For example, the explicit `do / catch` construct feels a bit old skool; maybe you'd prefer `guard let remote = try? await ...` instead?
2. The other functions in this extension all `throw`. I chose not to do that here, because in my experience throwing in a function that returns an optional leads to less readable code; there are two, different non-happy-path states for callers to reason about. But I believe equally (more?) strongly that it's important for codebases to be consistent. So I'm eager to hear your thoughts on this.

Code after:
        let command = "remote -v"
        let output = try await run(command)
        let remotes = parseGitRemotes(from: output)

        return remotes
    }

    /// Add existing remote to local git
    /// - Parameter name: Name for remote
    /// - Parameter location: URL string for remote location
    func addRemote(name: String, location: String) async throws {
        _ = try await run("remote add \(name) \(location)")
    }

    /// Remove remote from local git
    /// - Parameter name: Name for remote to remove
    func removeRemote(name: String) async throws {
        _ = try await run("remote rm \(name)")
    }

    /// Get the URL of the remote
    /// > Note: If a git repository has multiple remotes, by default the `origin` remote
    /// > will be used, unless there’s an upstream branch configured for the current branch.
    /// > (Reference: https://git-scm.com/docs/git-ls-remote, https://git-scm.com/docs/git-fetch)
    /// - Returns: A URL if a remote is configured, nil otherwise
    /// - Throws: `GitClientError.outputError` if the underlying git command fails unexpectedly
    func getRemoteURL() async throws -> URL? {
        do {
            let remote = try await run("ls-remote --get-url")
            return URL(string: remote.trimmingCharacters(in: .whitespacesAndNewlines))
        } catch GitClientError.noRemoteConfigured {
            return nil
        } catch {
            throw error
        }
    }
}

func parseGitRemotes(from output: String) -> [GitRemote] {
    var remotes: [String: (fetch: String?, push: String?)] = [:]

    output.split(separator: "\n").forEach { line in
        let components = line.split { $0 == " " || $0 == "\t" }
        guard components.count == 3 else { return }

        let name = String(components[0])
        let location = String(components[1])
        let type = components[2].contains("(fetch)") ? "fetch" : "push"

        if var remote = remotes[name] {
            if type == "fetch" {