Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Pruning generated files for relative operations #2994

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ extension FileGenerator {
) throws {
let directoryPath = target.resolvePath(forConfig: config)
let filePath = URL(fileURLWithPath: directoryPath)
.resolvingSymlinksInPath()
.appendingPathComponent(fileName.firstUppercased)
.appendingPathExtension(fileExtension)
.path
Expand Down
4 changes: 4 additions & 0 deletions Sources/ApolloCodegenLib/Glob.swift
Copy link
Member Author

Choose a reason for hiding this comment

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

@calvincestari I ended up refactoring the Glob code to this so that the same code in the compactMap can handle both production and test use cases instead of checking resource keys for production and then always still resolving symlinks. So just tweaking how the path is built allows for just resolving symlinks for every path that comes through.

Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public struct Glob {
}
}

// Resolve symlinks in any included paths
includeMatches = includeMatches.compactMap({ path in
return URL(fileURLWithPath: path).resolvingSymlinksInPath().path
})
return OrderedSet<String>(includeMatches).subtracting(excludeMatches)
}

Expand Down
54 changes: 54 additions & 0 deletions Tests/ApolloCodegenTests/ApolloCodegenTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,60 @@ class ApolloCodegenTests: XCTestCase {
expect(ApolloFileManager.default.doesFileExist(atPath: testUserFileInChildPath)).to(beTrue())
expect(ApolloFileManager.default.doesFileExist(atPath: testUserFileInNestedChildPath)).to(beTrue())
}

func test__fileDeletion__inOperationRelativeDirectory__whenSymlinkIsUsed() throws {
// given
try createFile(containing: schemaData, named: "schema.graphqls")

let schemaDirectory = "SchemaModule"
let codeDirectory = "code"
let relativeSubPath = "Operations"
let operationFilename = "TestQuery.graphql"

try createOperationFile(
type: .query,
named: "TestQuery",
filename: operationFilename,
inDirectory: codeDirectory
)

let symLinkURL = directoryURL.appendingPathComponent("/\(codeDirectory)/\(relativeSubPath)/")
let symLinkDestURL = directoryURL.appendingPathComponent("\(schemaDirectory)/Sources/Operations/")
let fileValidationPath = symLinkDestURL.appendingPathComponent("\(operationFilename).swift").path

//setup symlink folder
try testFileManager.fileManager.createDirectory(at: symLinkDestURL, withIntermediateDirectories: true)
try testFileManager.fileManager.createSymbolicLink(at: symLinkURL, withDestinationURL: symLinkDestURL)

// when
let config = ApolloCodegenConfiguration.mock(
input: .init(
schemaSearchPaths: ["schema*.graphqls"],
operationSearchPaths: ["code/**/*.graphql"]
),
output: .init(
schemaTypes: .init(path: schemaDirectory,
moduleType: .swiftPackageManager),
operations: .relative(subpath: relativeSubPath)
),
options: .init(
pruneGeneratedFiles: true
)
)

// then

// running codegen multiple times to validate symlink related file creation/deletion bug
try ApolloCodegen.build(with: config, rootURL: directoryURL)
expect(ApolloFileManager.default.doesFileExist(atPath: fileValidationPath)).to(beTrue())

try ApolloCodegen.build(with: config, rootURL: directoryURL)
expect(ApolloFileManager.default.doesFileExist(atPath: fileValidationPath)).to(beTrue())
Copy link
Contributor

Choose a reason for hiding this comment

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

Just confirming here, without the code added in this PR, this test passes on the first expectation, fails the second, and passes the third, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct


try ApolloCodegen.build(with: config, rootURL: directoryURL)
expect(ApolloFileManager.default.doesFileExist(atPath: fileValidationPath)).to(beTrue())

}

func test__fileDeletion__givenGeneratedFilesExist_InOperationRelativeDirectoriesWithSubPath_deletesOnlyRelativeGeneratedFilesInOperationSearchPaths() throws {
// given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class TestIsolatedFileManager {
}

let filePath: String = fileDirectoryURL
.resolvingSymlinksInPath()
.appendingPathComponent(fileName, isDirectory: false).path

guard fileManager.createFile(atPath: filePath, contents: data) else {
Expand Down