Skip to content

Commit 3bde4df

Browse files
authored
Fix versioning bug in release tooling (#8256)
* Fix versioning bug * Cleanup approach * Fix typo * Fix another typo
1 parent 5aaf38c commit 3bde4df

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

ReleaseTooling/Sources/FirebaseReleaser/InitializeRelease.swift

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -75,38 +75,19 @@ struct InitializeRelease {
7575
let pod = firebasePod.name
7676
let version = firebasePod.isBeta ? firebaseVersion + "-beta" : firebaseVersion
7777
if pod == "Firebase" {
78-
// TODO: This then block is redundant with the updatePodspecs function above and is left
79-
// until we decide to go with Swift or sed.
80-
// Replace version in string like s.version = '6.9.0'
78+
// TODO: This block is redundant with `updatePodspecs`. Decide to go with Swift or sed.
8179
guard let range = contents.range(of: "s.version") else {
8280
fatalError("Could not find version of Firebase pod in podspec at \(podspecFile)")
8381
}
84-
var versionStartIndex = contents.index(range.upperBound, offsetBy: 1)
85-
while contents[versionStartIndex] != "'" {
86-
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
87-
}
88-
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
89-
while contents[versionEndIndex] != "'" {
90-
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
91-
}
92-
contents.removeSubrange(versionStartIndex ... versionEndIndex)
93-
contents.insert(contentsOf: "'" + version + "'", at: versionStartIndex)
82+
// Replace version in string like s.version = '6.9.0'
83+
updateVersion(&contents, in: range, to: version)
84+
9485
} else {
95-
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0'
96-
guard let range = contents.range(of: pod) else {
97-
// This pod is not a top-level Firebase pod dependency.
98-
continue
99-
}
100-
var versionStartIndex = contents.index(range.upperBound, offsetBy: 2)
101-
while !contents[versionStartIndex].isWholeNumber {
102-
versionStartIndex = contents.index(versionStartIndex, offsetBy: 1)
86+
// Iterate through all the ranges of `pod`'s occurrences.
87+
for range in contents.ranges(of: pod) {
88+
// Replace version in string like ss.dependency 'FirebaseCore', '6.3.0'.
89+
updateVersion(&contents, in: range, to: version)
10390
}
104-
var versionEndIndex = contents.index(versionStartIndex, offsetBy: 1)
105-
while contents[versionEndIndex] != "'" {
106-
versionEndIndex = contents.index(versionEndIndex, offsetBy: 1)
107-
}
108-
contents.removeSubrange(versionStartIndex ... versionEndIndex)
109-
contents.insert(contentsOf: version + "'", at: versionStartIndex)
11091
}
11192
}
11293
do {
@@ -116,6 +97,24 @@ struct InitializeRelease {
11697
}
11798
}
11899

100+
/// Update the existing version to the given version by writing to a given string using the provided range.
101+
/// - Parameters:
102+
/// - contents: A reference to a String containing a version that will be updated.
103+
/// - range: The range containing a version substring that will be updated.
104+
/// - version: The version string to update to.
105+
private static func updateVersion(_ contents: inout String, in range: Range<String.Index>,
106+
to version: String) {
107+
var versionStartIndex = contents.index(after: range.upperBound)
108+
while !contents[versionStartIndex].isWholeNumber {
109+
versionStartIndex = contents.index(after: versionStartIndex)
110+
}
111+
var versionEndIndex = contents.index(after: versionStartIndex)
112+
while contents[versionEndIndex] != "'" {
113+
versionEndIndex = contents.index(after: versionEndIndex)
114+
}
115+
contents.replaceSubrange(versionStartIndex ..< versionEndIndex, with: version)
116+
}
117+
119118
private static func updatePodfiles(path: URL, version: String) {
120119
// Update the Podfiles across the repo.
121120
let firestorePodfile = path.appendingPathComponent("Firestore")
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import Foundation
18+
19+
/// Utilities to simplify String operations.
20+
public extension String {
21+
/// Finds and returns the ranges of all occurrences of a given string within a given range of the String, subject to given options,
22+
/// using the specified locale, if any.
23+
/// - Returns: An an optional array of ranges where each range corresponds to an occurence of the substring in the given string.
24+
func ranges<T: StringProtocol>(of substring: T, options: CompareOptions = .literal,
25+
locale: Locale? = nil) -> [Range<Index>] {
26+
var ranges: [Range<Index>] = []
27+
28+
let end = endIndex
29+
var searchRange = startIndex ..< end
30+
31+
while searchRange.lowerBound < end {
32+
guard let range = self.range(
33+
of: substring,
34+
options: options,
35+
range: searchRange,
36+
locale: locale
37+
)
38+
else { break }
39+
40+
ranges.append(range)
41+
42+
let shiftedStart = index(range.lowerBound, offsetBy: 1)
43+
searchRange = shiftedStart ..< end
44+
}
45+
46+
return ranges
47+
}
48+
}

0 commit comments

Comments
 (0)