@@ -2,6 +2,38 @@ import Foundation
22import Regex
33import SwiftShell
44
5+ protocol ErrorHandling : Error {
6+ var message : String { get }
7+ }
8+
9+ enum FileError : Error , ErrorHandling {
10+ case fileNotFound( String )
11+ case unknownFile( String )
12+
13+ var message : String {
14+ switch self {
15+ case . fileNotFound( let file) :
16+ return " File not found: \( file) "
17+ case . unknownFile( let file) :
18+ return " Unknown file: \( file) "
19+ }
20+ }
21+ }
22+
23+ enum VersionError : Error , ErrorHandling {
24+ case versionNotFound( String )
25+ case versionMismatch( String , String )
26+
27+ var message : String {
28+ switch self {
29+ case . versionNotFound( let file) :
30+ return " No version found for \( file) "
31+ case . versionMismatch( let file, let versionFound) :
32+ return " Unexpected version \( versionFound) found for file \( file) "
33+ }
34+ }
35+ }
36+
537let fromVersionFile = " ./Sentry.podspec "
638
739let files = [
@@ -17,7 +49,7 @@ let files = [
1749// This will enable publishing apps with SDK beta version.
1850let restrictFiles = [
1951 " ./Sources/Configuration/SDK.xcconfig " ,
20- " ./Sources/Configuration/Versioning.xcconfig " ,
52+ " ./Sources/Configuration/Versioning.xcconfig " ,
2153 " ./Sources/Configuration/SentrySwiftUI.xcconfig " ,
2254 " ./Samples/Shared/Config/Versioning.xcconfig "
2355]
@@ -26,27 +58,37 @@ let args = CommandLine.arguments
2658
2759let semver : StaticString = " ([0-9]+) \\ .([0-9]+) \\ .([0-9]+)(?:-([0-9A-Za-z-]+(?: \\ .[0-9A-Za-z-]+)*))?(?: \\ +[0-9A-Za-z-]+)? "
2860let regex = Regex ( semver)
29- if regex. firstMatch ( in: args [ 1 ] ) == nil {
61+ if regex. firstMatch ( in: args [ 2 ] ) == nil {
3062 exit ( errormessage: " version number must fit x.x.x format " )
3163}
3264
33- let fromVersionFileHandler = try open ( fromVersionFile)
34- let fromFileContent : String = fromVersionFileHandler. read ( )
65+ if args [ 1 ] == " --verify " {
66+ let expectedVersion = args [ 2 ]
67+ try verifyVersionInFiles ( expectedVersion)
68+ } else if args [ 1 ] == " --update " {
69+ try updateVersionInFiles ( )
70+ }
3571
36- if let match = Regex ( semver , options : [ . dotMatchesLineSeparators ] ) . firstMatch ( in : fromFileContent ) {
37- var fromVersion = match . matchedString
38- var toVersion = args [ 1 ]
72+ func updateVersionInFiles ( ) throws {
73+ let fromVersionFileHandler = try open ( fromVersionFile )
74+ let fromFileContent : String = fromVersionFileHandler . read ( )
3975
40- for file in files {
41- try updateVersion ( file, fromVersion, toVersion)
42- }
43-
44- fromVersion = extractVersionOnly ( fromVersion)
45- toVersion = extractVersionOnly ( toVersion)
46-
47- for file in restrictFiles {
48- try updateVersion ( file, fromVersion, toVersion)
76+ if let match = Regex ( semver, options: [ . dotMatchesLineSeparators] ) . firstMatch ( in: fromFileContent) {
77+ var fromVersion = match. matchedString
78+ var toVersion = args [ 2 ]
79+
80+ for file in files {
81+ try updateVersion ( file, fromVersion, toVersion)
82+ }
83+
84+ fromVersion = extractVersionOnly ( fromVersion)
85+ toVersion = extractVersionOnly ( toVersion)
86+
87+ for file in restrictFiles {
88+ try updateVersion ( file, fromVersion, toVersion)
89+ }
4990 }
91+ print ( " Successfuly updated version numbers " )
5092}
5193
5294func updateVersion( _ file: String , _ fromVersion: String , _ toVersion: String ) throws {
@@ -62,3 +104,86 @@ func extractVersionOnly(_ version: String) -> String {
62104 guard let indexOfHypen = version. firstIndex ( of: " - " ) else { return version }
63105 return String ( version. prefix ( upTo: indexOfHypen) )
64106}
107+
108+ func verifyVersionInFiles( _ expectedVersion: String ) throws {
109+ var errors : [ String ] = [ ]
110+ let expectedVersion = args [ 2 ]
111+
112+ for file in files {
113+ do {
114+ try verifyFile ( file, expectedVersion)
115+ } catch let error as ErrorHandling {
116+ errors. append ( error. message)
117+ }
118+ }
119+
120+ let exactVersion = extractVersionOnly ( expectedVersion)
121+ for file in restrictFiles {
122+ do {
123+ try verifyRestrictedFile ( file, expectedVersion: exactVersion)
124+ } catch let error as ErrorHandling {
125+ errors. append ( error. message)
126+ }
127+ }
128+
129+ if !errors. isEmpty {
130+ exit ( errormessage: " Could not validate all files: \n \( errors. joined ( separator: " \n " ) ) " )
131+ }
132+
133+ print ( " Successfully validated files version number " )
134+ }
135+
136+ func verifyFile( _ file: String , _ expectedVersion: String ) throws {
137+ guard let fileHandler = try ? open ( file) else {
138+ throw FileError . fileNotFound ( file)
139+ }
140+
141+ let fileContent = fileHandler. read ( )
142+ let regexString = try getRegexString ( for: file)
143+ let match = try ? Regex ( string: regexString, options: [ . dotMatchesLineSeparators] ) . firstMatch ( in: fileContent)
144+
145+ guard let version = match? . captures [ 0 ] else {
146+ throw VersionError . versionNotFound ( file)
147+ }
148+
149+ guard version == expectedVersion else {
150+ throw VersionError . versionMismatch ( file, version)
151+ }
152+
153+ print ( " \( file) validated to have the correct version: \( version) " )
154+ }
155+
156+ func verifyRestrictedFile( _ file: String , expectedVersion: String ) throws {
157+ guard let fileHandler = try ? open ( file) else {
158+ throw FileError . fileNotFound ( file)
159+ }
160+
161+ let fileContent = fileHandler. read ( )
162+ let marketingRegex = try ? Regex ( string: " MARKETING_VERSION \\ s= \\ s(?<version>[a-zA-z0-9 \\ . \\ -]+) " , options: [ . dotMatchesLineSeparators] )
163+ let currentProjectRegex = try ? Regex ( string: " CURRENT_PROJECT_VERSION \\ s= \\ s(?<version>[a-zA-z0-9 \\ . \\ -]+) " , options: [ . dotMatchesLineSeparators] )
164+ let match = marketingRegex? . firstMatch ( in: fileContent) ?? currentProjectRegex? . firstMatch ( in: fileContent)
165+
166+ guard let version = match? . captures [ 0 ] else {
167+ throw VersionError . versionNotFound ( file)
168+ }
169+
170+ guard version == expectedVersion else {
171+ throw VersionError . versionMismatch ( file, version)
172+ }
173+
174+ print ( " \( file) validated to have the correct version: \( version) " )
175+ }
176+
177+ func getRegexString( for file: String ) throws -> String {
178+ if file. hasSuffix ( " .podspec " ) {
179+ if file == " ./Tests/HybridSDKTest/HybridPod.podspec " {
180+ return " s \\ .dependency \\ s \" Sentry \\ /HybridSDK \" , \\ s \" (?<version>[a-zA-z0-9 \\ . \\ -]+) \" "
181+ }
182+ return " \\ ss \\ .version \\ s+= \\ s \" (?<version>[a-zA-z0-9 \\ . \\ -]+) \" "
183+ } else if file == " ./Package.swift " {
184+ return " https: \\ / \\ /github \\ .com \\ /getsentry \\ /sentry-cocoa \\ /releases \\ /download \\ /(?<version>[a-zA-z0-9 \\ . \\ -]+) \\ /Sentry "
185+ } else if file == " ./Sources/Sentry/SentryMeta.m " {
186+ return " static NSString \\ *versionString = @ \" (?<version>[a-zA-z0-9 \\ . \\ -]+) \" "
187+ }
188+ throw FileError . unknownFile ( file)
189+ }
0 commit comments