Skip to content

improve error message when Package.resolved cannot be loaded #3721

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

Merged
merged 2 commits into from
Sep 8, 2021
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
11 changes: 9 additions & 2 deletions Sources/Basics/FileSystem+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ extension FileSystem {
}
}


// MARK: - cache

extension FileSystem {
Expand Down Expand Up @@ -119,7 +118,15 @@ extension FileSystem {
return try Data(self.readFileContents(path).contents)
}

public func readFileContents(_ path: AbsolutePath) throws -> String {
return try String(decoding: self.readFileContents(path), as: UTF8.self)
}

public func writeFileContents(_ path: AbsolutePath, data: Data) throws {
return try self.writeFileContents(path, bytes: ByteString(data))
return try self.writeFileContents(path, bytes: .init(data))
}

public func writeFileContents(_ path: AbsolutePath, string: String) throws {
return try self.writeFileContents(path, bytes: .init(encodingAsUTF8: string))
}
}
2 changes: 1 addition & 1 deletion Sources/PackageGraph/PinsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ fileprivate struct PinsStorage {
partial[iterator.packageRef.identity] = iterator
}
default:
throw InternalError("unknown RepositoryManager version: \(version)")
throw StringError("unknown 'PinsStorage' version '\(version.version)' at '\(self.path)'.")
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/SourceControl/RepositoryManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public class RepositoryManager {
// Make sure destination is free.
try? self.fileSystem.removeFileTree(repositoryPath)
let isCached = self.cachePath.map{ self.fileSystem.exists($0.appending(handle.subpath)) } ?? false

// Inform delegate.
queue.async {
let details = FetchDetails(fromCache: isCached, updatedCache: false)
Expand Down Expand Up @@ -469,7 +469,7 @@ fileprivate struct RepositoryManagerStorage {
let v1 = try self.decoder.decode(path: self.path, fileSystem: self.fileSystem, as: V1.self)
return try v1.object.repositories.mapValues{ try .init($0, manager: manager) }
default:
throw InternalError("unknown RepositoryManager version: \(version)")
throw StringError("unknown 'RepositoryManagerStorage' version '\(version.version)' at '\(self.path)'")
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Workspace/WorkspaceState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ fileprivate struct WorkspaceStateStorage {
let artifacts = v4.object.artifacts.map{ Workspace.ManagedArtifact($0) }
return (dependencies: .init(dependencyMap: dependencyMap), artifacts: .init(artifacts))
default:
throw InternalError("unknown RepositoryManager version: \(version)")
throw StringError("unknown 'WorkspaceStateStorage' version '\(version.version)' at '\(self.path)'")
}
}
}
Expand Down
116 changes: 88 additions & 28 deletions Tests/WorkspaceTests/PinsStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,40 +106,100 @@ final class PinsStoreTests: XCTestCase {
let fs = InMemoryFileSystem()
let pinsFile = AbsolutePath("/pinsfile.txt")

try fs.writeFileContents(pinsFile) {
$0 <<< """
{
"object": {
"pins": [
{
"package": "Clang_C",
"repositoryURL": "https://github.com/something/Clang_C.git",
"state": {
"branch": null,
"revision": "90a9574276f0fd17f02f58979423c3fd4d73b59e",
"version": "1.0.2",
}
},
{
"package": "Commandant",
"repositoryURL": "https://github.com/something/Commandant.git",
"state": {
"branch": null,
"revision": "c281992c31c3f41c48b5036c5a38185eaec32626",
"version": "0.12.0"
}
}
]
try fs.writeFileContents(pinsFile, string:
"""
{
"version": 1,
"object": {
"pins": [
{
"package": "Clang_C",
"repositoryURL": "https://github.com/something/Clang_C.git",
"state": {
"branch": null,
"revision": "90a9574276f0fd17f02f58979423c3fd4d73b59e",
"version": "1.0.2",
}
},
"version": 1
}
"""
}
{
"package": "Commandant",
"repositoryURL": "https://github.com/something/Commandant.git",
"state": {
"branch": null,
"revision": "c281992c31c3f41c48b5036c5a38185eaec32626",
"version": "0.12.0"
}
}
]
}
}
"""
)

let store = try PinsStore(pinsFile: pinsFile, workingDirectory: .root, fileSystem: fs, mirrors: .init())
XCTAssertEqual(store.pinsMap.keys.map { $0.description }.sorted(), ["clang_c", "commandant"])
}

func testLoadingSchema2() throws {
let fs = InMemoryFileSystem()
let pinsFile = AbsolutePath("/pinsfile.txt")

try fs.writeFileContents(pinsFile, string:
"""
{
"version": 2,
"pins": [
{
"identity": "clang_c",
"location": "https://github.com/something/Clang_C.git",
"state": {
"branch": null,
"revision": "90a9574276f0fd17f02f58979423c3fd4d73b59e",
"version": "1.0.2",
}
},
{
"identity": "commandant",
"location": "https://github.com/something/Commandant.git",
"state": {
"branch": null,
"revision": "c281992c31c3f41c48b5036c5a38185eaec32626",
"version": "0.12.0"
}
}
]
}
"""
)

let store = try PinsStore(pinsFile: pinsFile, workingDirectory: .root, fileSystem: fs, mirrors: .init())
XCTAssertEqual(store.pinsMap.keys.map { $0.description }.sorted(), ["clang_c", "commandant"])
}

func testLoadingUnknownSchemaVersion() throws {
let fs = InMemoryFileSystem()
let pinsFile = AbsolutePath("/pinsfile.txt")

let version = -1
try fs.writeFileContents(pinsFile, string: "{ \"version\": \(version) }");

XCTAssertThrowsError(try PinsStore(pinsFile: pinsFile, workingDirectory: .root, fileSystem: fs, mirrors: .init()), "error expected", { error in
XCTAssertEqual("\(error)", "Package.resolved file is corrupted or malformed; fix or delete the file to continue: unknown 'PinsStorage' version '\(version)' at '\(pinsFile)'.")
})

}

func testLoadingBadFormat() throws {
let fs = InMemoryFileSystem()
let pinsFile = AbsolutePath("/pinsfile.txt")

try fs.writeFileContents(pinsFile, string: "boom")

XCTAssertThrowsError(try PinsStore(pinsFile: pinsFile, workingDirectory: .root, fileSystem: fs, mirrors: .init()), "error expected", { error in
XCTAssertMatch("\(error)", .contains("Package.resolved file is corrupted or malformed; fix or delete the file to continue"))
})
}

func testEmptyPins() throws {
let fs = InMemoryFileSystem()
let pinsFile = AbsolutePath("/pinsfile.txt")
Expand Down