Skip to content

Commit

Permalink
Also look for Package.resolved in .xcworkspace when performing versio…
Browse files Browse the repository at this point in the history
…n check (#3048)

Co-authored-by: Zach FettersMoore <[email protected]>
  • Loading branch information
alexdeem and BobaFetters authored Jul 26, 2023
1 parent a47a8af commit fa28628
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 22 deletions.
70 changes: 48 additions & 22 deletions Sources/CodegenCLI/Extensions/VersionChecker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,42 +40,68 @@ enum VersionChecker {
return fileManager.base.contents(atPath: path)
}

// When using SPM via Xcode, the `Package.resolved` file is nested inside the `.xcproject`
// package. Since we don't know the name of your Xcode project, we just look for the first
// `.xcproject` file in project's root directory that depends on Apollo. This may not be
// 100% fool-proof, but it should be accurate in almost all cases.
func findInXcodeProject(named projectFileName: String) -> Data? {
let projectPackagePath =
"\(projectFileName)/project.xcworkspace/xcshareddata/swiftpm/\(Package_resolved)"

// When using SPM via Xcode, the `Package.resolved` file is nested inside either the
// `.xcworkspace` or the `.xcproject` package. Since we don't know the name of your project,
// we just look for the first workspace or project that depends on Apollo, prioritising
// workspaces. This may not be 100% fool-proof, but it should be accurate in almost all cases.
func findInXcode(
fileSuffix: String,
packagePath: String,
excludeFilePathComponents: [String] = []
) -> PackageResolvedModel? {
let projectEnumerator = fileManager.base.enumerator(atPath: projectRootURL?.path ?? ".")
enumeratorLoop: while let file = projectEnumerator?.nextObject() as? String {
if file.hasSuffix(fileSuffix) {
//check if this file should be ignored
for component in excludeFilePathComponents {
if file.contains(component) {
continue enumeratorLoop
}
}

let projectPackagePath = "\(file)\(packagePath)"
if let package = apolloDependantPackage(atPath: projectPackagePath) {
return package
}
}
}
return nil
}

func apolloDependantPackage(atPath projectPackagePath: String) -> PackageResolvedModel? {
let path: String
if let projectRootURL {
path = projectRootURL.appendingPathComponent(projectPackagePath, isDirectory: false).path
} else {
path = projectPackagePath
}

return fileManager.base.contents(atPath: path)
if let packageResolvedData = fileManager.base.contents(atPath: path),
var packageModel = try? PackageResolvedModel(data: packageResolvedData),
packageModel.apolloVersion != nil {
return packageModel
}
return nil
}


if let packageResolvedData = findInProjectRoot() {
return try PackageResolvedModel(data: packageResolvedData)
}

} else {
// Find in Xcode Projects
let projectEnumerator = fileManager.base.enumerator(atPath: projectRootURL?.path ?? ".")

while let file = projectEnumerator?.nextObject() as? String {
if file.hasSuffix(".xcodeproj") {
if let packageResolvedData = findInXcodeProject(named: file),
var packageModel = try PackageResolvedModel(data: packageResolvedData),
packageModel.apolloVersion != nil {
if let packageModel = findInXcode(
fileSuffix: ".xcworkspace",
packagePath: "/xcshareddata/swiftpm/\(Package_resolved)",
excludeFilePathComponents: [".xcodeproj/project.xcworkspace"]
) {
return packageModel
}

return packageModel
}
}
}
if let packageModel = findInXcode(
fileSuffix: ".xcodeproj",
packagePath: "/project.xcworkspace/xcshareddata/swiftpm/\(Package_resolved)"
) {
return packageModel
}

return nil
Expand Down
59 changes: 59 additions & 0 deletions Tests/CodegenCLITests/VersionCheckerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,41 @@ class VersionCheckerTests: XCTestCase {
expect(result).to(equal(.versionMismatch(cliVersion: Constants.CLIVersion, apolloVersion: apolloVersion)))
}

func test__matchCLIVersionToApolloVersion__givenPackageResolvedFileInXcodeWorkspace_withVersion2FileFormat_hasMatchingVersion_returns_versionMatch() throws {
// given
try fileManager.createFile(
body: version2PackageResolvedFileBody(apolloVersion: Constants.CLIVersion),
named: "Package.resolved",
inDirectory: "MyProject.xcworkspace/xcshareddata/swiftpm"
)

// when
let result = try VersionChecker.matchCLIVersionToApolloVersion(
projectRootURL: fileManager.directoryURL
)

// then
expect(result).to(equal(.versionMatch))
}

func test__matchCLIVersionToApolloVersion__givenPackageResolvedFileInXcodeWorkspace_withVersion2FileFormat_hasNonMatchingVersion_returns_versionMismatch() throws {
// given
let apolloVersion = "1.0.0.test-1"
try fileManager.createFile(
body: version2PackageResolvedFileBody(apolloVersion: apolloVersion),
named: "Package.resolved",
inDirectory: "MyProject.xcworkspace/xcshareddata/swiftpm"
)

// when
let result = try VersionChecker.matchCLIVersionToApolloVersion(
projectRootURL: fileManager.directoryURL
)

// then
expect(result).to(equal(.versionMismatch(cliVersion: Constants.CLIVersion, apolloVersion: apolloVersion)))
}

func test__matchCLIVersionToApolloVersion__givenPackageResolvedFileInXcodeProject_withVersion2FileFormat_hasMatchingVersion_returns_versionMatch() throws {
// given
try fileManager.createFile(
Expand Down Expand Up @@ -220,6 +255,30 @@ class VersionCheckerTests: XCTestCase {
// then
expect(result).to(equal(.versionMismatch(cliVersion: Constants.CLIVersion, apolloVersion: apolloVersion)))
}

func test__matchCLIVersionToApolloVersion__givenPackageResolvedFileInXcodeWorkspaceAndProject_withVersion2FileFormat_hasMatchingVersion_returns_versionMatch_fromWorkspace() throws {
// given
try fileManager.createFile(
body: version2PackageResolvedFileBody(apolloVersion: Constants.CLIVersion),
named: "Package.resolved",
inDirectory: "MyProject.xcworkspace/xcshareddata/swiftpm"
)

let apolloProjectVersion = "1.0.0.test-1"
try fileManager.createFile(
body: version2PackageResolvedFileBody(apolloVersion: apolloProjectVersion),
named: "Package.resolved",
inDirectory: "MyProject.xcodeproj/project.xcworkspace/xcshareddata/swiftpm"
)

// when
let result = try VersionChecker.matchCLIVersionToApolloVersion(
projectRootURL: fileManager.directoryURL
)

// then
expect(result).to(equal(.versionMatch))
}

}

Expand Down

0 comments on commit fa28628

Please sign in to comment.