Skip to content

Commit 016c9f4

Browse files
authored
Move UpdateFirebasePod to Swift's ArgumentParser library. (#4993)
* Move UpdateFirebasePod to Swift's ArgumentParser library. This was introduced in URL, leaving a nice clean way to provide command line arguments. Example output: ``` $ swift run UpdateFirebasePod Error: Missing expected argument '--git-root <git-root>' Usage: firebase-pod-updater --git-root <git-root> --current-release <current-release> ``` * Removed unnecessary file. * Fixed formatting. * Use existing argument name for currentRelease. * Sorted package dependencies. * Pin to exact version. * Rename UpdateFirebasePod to firebase-pod-updater This sticks with convention expected by the tooling. Future PRs will change the `ReleasePackager` and other tools as well.
1 parent d4b0109 commit 016c9f4

File tree

4 files changed

+106
-242
lines changed

4 files changed

+106
-242
lines changed

ZipBuilder/Package.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,23 @@ import PackageDescription
2222
let package = Package(
2323
name: "ZipBuilder",
2424
products: [
25+
.executable(name: "firebase-pod-updater", targets: ["firebase-pod-updater"]),
2526
.executable(name: "ReleasePackager", targets: ["ZipBuilder"]),
26-
.executable(name: "UpdateFirebasePod", targets: ["UpdateFirebasePod"]),
2727
],
2828
dependencies: [
29+
.package(url: "https://github.com/apple/swift-argument-parser", .exact("0.0.1")),
2930
// Keep the generated protos in sync with the version below.
3031
// See https://github.com/firebase/firebase-ios-sdk/tree/master/ZipBuilder#updating-protobuf-generated-swift-files.
3132
.package(url: "https://github.com/apple/swift-protobuf.git", .exact("1.7.0")),
3233
],
3334
targets: [
3435
.target(
35-
name: "UpdateFirebasePod",
36-
dependencies: ["ManifestReader"]
36+
name: "firebase-pod-updater",
37+
dependencies: ["ArgumentParser", "ManifestReader"]
3738
),
3839
.target(
3940
name: "ZipBuilder",
40-
dependencies: ["ManifestReader"]
41+
dependencies: ["ArgumentParser", "ManifestReader"]
4142
),
4243
.target(
4344
name: "ManifestReader",

ZipBuilder/Sources/UpdateFirebasePod/FirebasePod.swift

Lines changed: 0 additions & 46 deletions
This file was deleted.

ZipBuilder/Sources/UpdateFirebasePod/LaunchArgs.swift

Lines changed: 0 additions & 112 deletions
This file was deleted.

ZipBuilder/Sources/UpdateFirebasePod/main.swift

Lines changed: 101 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -16,99 +16,120 @@
1616

1717
import Foundation
1818

19+
import ArgumentParser
1920
import ManifestReader
2021

21-
// Get the launch arguments, parsed by user defaults.
22-
let args = LaunchArgs.shared
22+
struct FirebasePodUpdater: ParsableCommand {
23+
/// The root of the Firebase git repo.
24+
@Option(help: "The root of the firebase-ios-sdk checked out git repo.",
25+
transform: URL.init(fileURLWithPath:))
26+
var gitRoot: URL
2327

24-
// Keep timing for how long it takes to change the Firebase pod versions.
25-
let buildStart = Date()
26-
var cocoaPodsUpdateMessage: String = ""
28+
/// A file URL to a textproto with the contents of a `FirebasePod_Release` object. Used to verify
29+
/// expected version numbers.
30+
@Option(name: .customLong("releasing-pods"),
31+
help: "The file path to a textproto file containing all the releasing Pods, of type `FirebasePod_Release`.",
32+
transform: URL.init(fileURLWithPath:))
33+
var currentRelease: URL
2734

28-
var paths = FirebasePod.FilesystemPaths(currentReleasePath: args.currentReleasePath,
29-
gitRootPath: args.gitRootPath)
30-
31-
/// Assembles the expected versions based on the release manifest passed in.
32-
/// Returns an array with the pod name as the key and version as the value,
33-
private func getExpectedVersions() -> [String: String] {
34-
// Merge the versions from the current release and the known public versions.
35-
var releasingVersions: [String: String] = [:]
35+
mutating func validate() throws {
36+
guard FileManager.default.fileExists(atPath: gitRoot.path) else {
37+
throw ValidationError("git-root does not exist: \(gitRoot.path)")
38+
}
3639

37-
// Override any of the expected versions with the current release manifest, if it exists.
38-
let currentRelease = ManifestReader.loadCurrentRelease(fromTextproto: paths.currentReleasePath)
39-
print("Overriding the following Pod versions, taken from the current release manifest:")
40-
for pod in currentRelease.sdk {
41-
releasingVersions[pod.sdkName] = pod.sdkVersion
42-
print("\(pod.sdkName): \(pod.sdkVersion)")
40+
guard FileManager.default.fileExists(atPath: currentRelease.path) else {
41+
throw ValidationError("current-release does not exist: \(currentRelease.path). Do you need " +
42+
"to run `prodaccess`?")
43+
}
4344
}
4445

45-
if !releasingVersions.isEmpty {
46-
print("Updating Firebase Pod in git installation at \(paths.gitRootPath)) " +
47-
"with the following versions: \(releasingVersions)")
46+
func run() throws {
47+
// Keep timing for how long it takes to change the Firebase pod versions.
48+
let buildStart = Date()
49+
50+
let newVersions = getExpectedVersions()
51+
updateFirebasePod(newVersions: newVersions)
52+
print("Updating Firebase pod for version \(String(describing: newVersions["Firebase"]!))")
53+
54+
// Get the time since the tool start.
55+
let secondsSinceStart = -Int(buildStart.timeIntervalSinceNow)
56+
print("""
57+
Time profile:
58+
It took \(secondsSinceStart) seconds (~\(secondsSinceStart / 60)m) to update the Firebase pod.
59+
""")
4860
}
4961

50-
return releasingVersions
51-
}
62+
/// Assembles the expected versions based on the release manifest passed in.
63+
/// Returns an array with the pod name as the key and version as the value,
64+
private func getExpectedVersions() -> [String: String] {
65+
// Merge the versions from the current release and the known public versions.
66+
var releasingVersions: [String: String] = [:]
5267

53-
private func updateFirebasePod(newVersions: [String: String]) {
54-
let podspecFile = paths.gitRootPath + "/Firebase.podspec"
55-
var contents = ""
56-
do {
57-
contents = try String(contentsOfFile: podspecFile, encoding: .utf8)
58-
} catch {
59-
fatalError("Could not read Firebase podspec. \(error)")
68+
// Override any of the expected versions with the current release manifest, if it exists.
69+
let loadedRelease = ManifestReader.loadCurrentRelease(fromTextproto: currentRelease)
70+
print("Overriding the following Pod versions, taken from the current release manifest:")
71+
for pod in loadedRelease.sdk {
72+
releasingVersions[pod.sdkName] = pod.sdkVersion
73+
print("\(pod.sdkName): \(pod.sdkVersion)")
74+
}
75+
76+
if !releasingVersions.isEmpty {
77+
print("Updating Firebase Pod in git installation at \(gitRoot.path)) " +
78+
"with the following versions: \(releasingVersions)")
79+
}
80+
81+
return releasingVersions
6082
}
61-
for (pod, version) in newVersions {
62-
if pod == "Firebase" {
63-
// Replace version in string like s.version = '6.9.0'
64-
guard let range = contents.range(of: "s.version") else {
65-
fatalError("Could not find version of Firebase pod in podspec at \(podspecFile)")
66-
}
67-
var versionStartIndex = contents.index(range.upperBound, offsetBy: 1)
68-
while contents[versionStartIndex] != "'" {
69-
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
70-
}
71-
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
72-
while contents[versionEndIndex] != "'" {
73-
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
74-
}
75-
contents.removeSubrange(versionStartIndex ... versionEndIndex)
76-
contents.insert(contentsOf: "'" + version + "'", at: versionStartIndex)
77-
} else {
78-
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0'
79-
guard let range = contents.range(of: pod) else {
80-
// This pod is not a top-level Firebase pod dependency.
81-
continue
82-
}
83-
var versionStartIndex = contents.index(range.upperBound, offsetBy: 2)
84-
while !contents[versionStartIndex].isWholeNumber {
85-
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
86-
}
87-
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
88-
while contents[versionEndIndex] != "'" {
89-
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
83+
84+
private func updateFirebasePod(newVersions: [String: String]) {
85+
let podspecFile = gitRoot.appendingPathComponent("Firebase.podspec")
86+
var contents = ""
87+
do {
88+
contents = try String(contentsOfFile: podspecFile.path, encoding: .utf8)
89+
} catch {
90+
fatalError("Could not read Firebase podspec. \(error)")
91+
}
92+
for (pod, version) in newVersions {
93+
if pod == "Firebase" {
94+
// Replace version in string like s.version = '6.9.0'
95+
guard let range = contents.range(of: "s.version") else {
96+
fatalError("Could not find version of Firebase pod in podspec at \(podspecFile)")
97+
}
98+
var versionStartIndex = contents.index(range.upperBound, offsetBy: 1)
99+
while contents[versionStartIndex] != "'" {
100+
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
101+
}
102+
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
103+
while contents[versionEndIndex] != "'" {
104+
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
105+
}
106+
contents.removeSubrange(versionStartIndex ... versionEndIndex)
107+
contents.insert(contentsOf: "'" + version + "'", at: versionStartIndex)
108+
} else {
109+
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0'
110+
guard let range = contents.range(of: pod) else {
111+
// This pod is not a top-level Firebase pod dependency.
112+
continue
113+
}
114+
var versionStartIndex = contents.index(range.upperBound, offsetBy: 2)
115+
while !contents[versionStartIndex].isWholeNumber {
116+
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
117+
}
118+
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
119+
while contents[versionEndIndex] != "'" {
120+
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
121+
}
122+
contents.removeSubrange(versionStartIndex ... versionEndIndex)
123+
contents.insert(contentsOf: version + "'", at: versionStartIndex)
90124
}
91-
contents.removeSubrange(versionStartIndex ... versionEndIndex)
92-
contents.insert(contentsOf: version + "'", at: versionStartIndex)
93125
}
94-
}
95-
do {
96-
try contents.write(toFile: podspecFile, atomically: false, encoding: String.Encoding.utf8)
97-
} catch {
98-
fatalError("Failed to write \(podspecFile). \(error)")
126+
do {
127+
try contents.write(to: podspecFile, atomically: false, encoding: .utf8)
128+
} catch {
129+
fatalError("Failed to write \(podspecFile.path). \(error)")
130+
}
99131
}
100132
}
101133

102-
do {
103-
let newVersions = getExpectedVersions()
104-
updateFirebasePod(newVersions: newVersions)
105-
print("Updating Firebase pod for version \(String(describing: newVersions["Firebase"]!))")
106-
107-
// Get the time since the tool start.
108-
let secondsSinceStart = -Int(buildStart.timeIntervalSinceNow)
109-
print("""
110-
Time profile:
111-
It took \(secondsSinceStart) seconds (~\(secondsSinceStart / 60)m) to update the Firebase pod.
112-
\(cocoaPodsUpdateMessage)
113-
""")
114-
}
134+
// Start the parsing and run the tool.
135+
FirebasePodUpdater.main()

0 commit comments

Comments
 (0)