Skip to content
Merged
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
9 changes: 5 additions & 4 deletions ZipBuilder/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,23 @@ import PackageDescription
let package = Package(
name: "ZipBuilder",
products: [
.executable(name: "firebase-pod-updater", targets: ["firebase-pod-updater"]),
.executable(name: "ReleasePackager", targets: ["ZipBuilder"]),
.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"]
name: "firebase-pod-updater",
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()