From 85b5f98515823cf2509b802c5eed22a5b7bf1bd2 Mon Sep 17 00:00:00 2001 From: "roux g. buciu" Date: Thu, 12 Feb 2026 15:50:41 -0500 Subject: [PATCH] add fork setup --- Sources/fxios/Commands/Setup.swift | 36 +++++++++++++++++++++++++----- Tests/fxiosTests/SetupTests.swift | 7 ++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/Sources/fxios/Commands/Setup.swift b/Sources/fxios/Commands/Setup.swift index 86fb548..87739d1 100644 --- a/Sources/fxios/Commands/Setup.swift +++ b/Sources/fxios/Commands/Setup.swift @@ -10,8 +10,20 @@ struct Setup: ParsableCommand { abstract: "Clone and bootstrap the firefox-ios repository." ) - @Flag(name: .long, help: "Use HTTPS URL for cloning (https://github.com/...) instead of SSH.") - var https = false + enum CloneProtocol: EnumerableFlag { + case https + case ssh + + static func name(for value: CloneProtocol) -> NameSpecification { + .long + } + } + + @Flag(help: "Protocol to use for git URLs.") + var cloneProtocol: CloneProtocol + + @Option(name: .long, help: "Full URL of your fork. Clones the fork as 'origin' and adds mozilla-mobile as 'upstream'.") + var withFork: String? @Option(name: .long, help: "Directory path (absolute or relative) to clone into. Defaults to current directory.") var location: String? @@ -28,11 +40,12 @@ struct Setup: ParsableCommand { try ToolChecker.requireNode() try ToolChecker.requireNpm() - let repoURL = https + let mozillaURL = cloneProtocol == .https ? "https://github.com/mozilla-mobile/firefox-ios.git" : "git@github.com:mozilla-mobile/firefox-ios.git" - // Determine the clone destination + // Determine the clone URL and destination + let cloneURL = withFork ?? mozillaURL let cloneDir: String if let location = location { cloneDir = location @@ -40,7 +53,7 @@ struct Setup: ParsableCommand { cloneDir = "firefox-ios" } - var arguments = ["clone", repoURL] + var arguments = ["clone", cloneURL] if let location = location { arguments.append(location) } @@ -55,6 +68,16 @@ struct Setup: ParsableCommand { throw SetupError.failedToChangeDirectory(clonePath.path) } + // If using a fork, add the mozilla-mobile repo as upstream + if withFork != nil { + Herald.declare("Adding mozilla-mobile as upstream remote...") + do { + try ShellRunner.run("git", arguments: ["remote", "add", "upstream", mozillaURL]) + } catch { + throw SetupError.failedToAddUpstreamRemote + } + } + Herald.declare("Running bootstrap in \(clonePath.path)...") // Run bootstrap @@ -67,11 +90,14 @@ struct Setup: ParsableCommand { enum SetupError: Error, CustomStringConvertible { case failedToChangeDirectory(String) + case failedToAddUpstreamRemote var description: String { switch self { case .failedToChangeDirectory(let path): return "Failed to change directory to \(path)." + case .failedToAddUpstreamRemote: + return "Failed to add upstream remote for mozilla-mobile/firefox-ios." } } } diff --git a/Tests/fxiosTests/SetupTests.swift b/Tests/fxiosTests/SetupTests.swift index cd858f1..7292342 100644 --- a/Tests/fxiosTests/SetupTests.swift +++ b/Tests/fxiosTests/SetupTests.swift @@ -14,6 +14,13 @@ struct SetupTests { #expect(error.description.contains("/some/path")) #expect(error.description.contains("Failed to change directory")) } + + @Test("SetupError.failedToAddUpstreamRemote has correct description") + func failedToAddUpstreamRemoteDescription() { + let error = SetupError.failedToAddUpstreamRemote + #expect(error.description.contains("upstream")) + #expect(error.description.contains("Failed to add")) + } } @Suite("ToolChecker Tests")