Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
5 changes: 3 additions & 2 deletions ZipBuilder/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,19 @@ let package = Package(
.executable(name: "UpdateFirebasePod", targets: ["UpdateFirebasePod"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", .exact("0.0.1")),
// Keep the generated protos in sync with the version below.
// See https://github.com/firebase/firebase-ios-sdk/tree/master/ZipBuilder#updating-protobuf-generated-swift-files.
.package(url: "https://github.com/apple/swift-protobuf.git", .exact("1.7.0")),
],
targets: [
.target(
name: "UpdateFirebasePod",
dependencies: ["ManifestReader"]
dependencies: ["ArgumentParser", "ManifestReader"]
),
.target(
name: "ZipBuilder",
dependencies: ["ManifestReader"]
dependencies: ["ArgumentParser", "ManifestReader"]
),
.target(
name: "ManifestReader",
Expand Down
46 changes: 0 additions & 46 deletions ZipBuilder/Sources/UpdateFirebasePod/FirebasePod.swift

This file was deleted.

112 changes: 0 additions & 112 deletions ZipBuilder/Sources/UpdateFirebasePod/LaunchArgs.swift

This file was deleted.

181 changes: 101 additions & 80 deletions ZipBuilder/Sources/UpdateFirebasePod/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,99 +16,120 @@

import Foundation

import ArgumentParser
import ManifestReader

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

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

var paths = FirebasePod.FilesystemPaths(currentReleasePath: args.currentReleasePath,
gitRootPath: args.gitRootPath)

/// Assembles the expected versions based on the release manifest passed in.
/// Returns an array with the pod name as the key and version as the value,
private func getExpectedVersions() -> [String: String] {
// Merge the versions from the current release and the known public versions.
var releasingVersions: [String: String] = [:]
mutating func validate() throws {
guard FileManager.default.fileExists(atPath: gitRoot.path) else {
throw ValidationError("git-root does not exist: \(gitRoot.path)")
}

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

if !releasingVersions.isEmpty {
print("Updating Firebase Pod in git installation at \(paths.gitRootPath)) " +
"with the following versions: \(releasingVersions)")
func run() throws {
// Keep timing for how long it takes to change the Firebase pod versions.
let buildStart = Date()

let newVersions = getExpectedVersions()
updateFirebasePod(newVersions: newVersions)
print("Updating Firebase pod for version \(String(describing: newVersions["Firebase"]!))")

// Get the time since the tool start.
let secondsSinceStart = -Int(buildStart.timeIntervalSinceNow)
print("""
Time profile:
It took \(secondsSinceStart) seconds (~\(secondsSinceStart / 60)m) to update the Firebase pod.
""")
Comment on lines +48 to +59
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This moved from the bottom of the file to the run() block.

}

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

private func updateFirebasePod(newVersions: [String: String]) {
let podspecFile = paths.gitRootPath + "/Firebase.podspec"
var contents = ""
do {
contents = try String(contentsOfFile: podspecFile, encoding: .utf8)
} catch {
fatalError("Could not read Firebase podspec. \(error)")
// Override any of the expected versions with the current release manifest, if it exists.
let loadedRelease = ManifestReader.loadCurrentRelease(fromTextproto: currentRelease)
print("Overriding the following Pod versions, taken from the current release manifest:")
for pod in loadedRelease.sdk {
releasingVersions[pod.sdkName] = pod.sdkVersion
print("\(pod.sdkName): \(pod.sdkVersion)")
}

if !releasingVersions.isEmpty {
print("Updating Firebase Pod in git installation at \(gitRoot.path)) " +
"with the following versions: \(releasingVersions)")
}

return releasingVersions
}
for (pod, version) in newVersions {
if pod == "Firebase" {
// Replace version in string like s.version = '6.9.0'
guard let range = contents.range(of: "s.version") else {
fatalError("Could not find version of Firebase pod in podspec at \(podspecFile)")
}
var versionStartIndex = contents.index(range.upperBound, offsetBy: 1)
while contents[versionStartIndex] != "'" {
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
}
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
while contents[versionEndIndex] != "'" {
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
}
contents.removeSubrange(versionStartIndex ... versionEndIndex)
contents.insert(contentsOf: "'" + version + "'", at: versionStartIndex)
} else {
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0'
guard let range = contents.range(of: pod) else {
// This pod is not a top-level Firebase pod dependency.
continue
}
var versionStartIndex = contents.index(range.upperBound, offsetBy: 2)
while !contents[versionStartIndex].isWholeNumber {
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
}
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
while contents[versionEndIndex] != "'" {
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)

private func updateFirebasePod(newVersions: [String: String]) {
let podspecFile = gitRoot.appendingPathComponent("Firebase.podspec")
var contents = ""
do {
contents = try String(contentsOfFile: podspecFile.path, encoding: .utf8)
} catch {
fatalError("Could not read Firebase podspec. \(error)")
}
for (pod, version) in newVersions {
if pod == "Firebase" {
// Replace version in string like s.version = '6.9.0'
guard let range = contents.range(of: "s.version") else {
fatalError("Could not find version of Firebase pod in podspec at \(podspecFile)")
}
var versionStartIndex = contents.index(range.upperBound, offsetBy: 1)
while contents[versionStartIndex] != "'" {
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
}
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
while contents[versionEndIndex] != "'" {
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
}
contents.removeSubrange(versionStartIndex ... versionEndIndex)
contents.insert(contentsOf: "'" + version + "'", at: versionStartIndex)
} else {
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0'
guard let range = contents.range(of: pod) else {
// This pod is not a top-level Firebase pod dependency.
continue
}
var versionStartIndex = contents.index(range.upperBound, offsetBy: 2)
while !contents[versionStartIndex].isWholeNumber {
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
}
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
while contents[versionEndIndex] != "'" {
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
}
contents.removeSubrange(versionStartIndex ... versionEndIndex)
contents.insert(contentsOf: version + "'", at: versionStartIndex)
}
contents.removeSubrange(versionStartIndex ... versionEndIndex)
contents.insert(contentsOf: version + "'", at: versionStartIndex)
}
}
do {
try contents.write(toFile: podspecFile, atomically: false, encoding: String.Encoding.utf8)
} catch {
fatalError("Failed to write \(podspecFile). \(error)")
do {
try contents.write(to: podspecFile, atomically: false, encoding: .utf8)
} catch {
fatalError("Failed to write \(podspecFile.path). \(error)")
}
}
}

do {
let newVersions = getExpectedVersions()
updateFirebasePod(newVersions: newVersions)
print("Updating Firebase pod for version \(String(describing: newVersions["Firebase"]!))")

// Get the time since the tool start.
let secondsSinceStart = -Int(buildStart.timeIntervalSinceNow)
print("""
Time profile:
It took \(secondsSinceStart) seconds (~\(secondsSinceStart / 60)m) to update the Firebase pod.
\(cocoaPodsUpdateMessage)
""")
}
// Start the parsing and run the tool.
FirebasePodUpdater.main()