Skip to content

Commit

Permalink
PackageManager: Fix bug preventing certain package descriptions from …
Browse files Browse the repository at this point in the history
…being parsed

This patch fixes a bug that prevented `PackageManager` from parsing certain package
description files, since it made too many assumptions about its format. The new
parsing code is simpler, and a lot more robust, by scanning the package description
line-by-line until it finds a name definition.
  • Loading branch information
JohnSundell committed Apr 29, 2017
1 parent 917e3b0 commit 8068cc3
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
24 changes: 14 additions & 10 deletions Sources/MarathonCore/PackageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,21 +233,25 @@ internal final class PackageManager {

private func nameOfPackage(in folder: Folder) throws -> String {
let packageFile = try folder.file(named: "Package.swift")
var packageDescription = try packageFile.readAsString()

guard let nameStartRange = packageDescription.range(of: "name:") else {
throw Error.failedToReadPackageFile(packageFile.nameExcludingExtension)
}
for line in try packageFile.readAsString().components(separatedBy: .newlines) {
guard let nameTokenRange = line.range(of: "name:") else {
continue
}

packageDescription = packageDescription.substring(from: nameStartRange.upperBound)
var line = line.substring(from: nameTokenRange.upperBound)

if let range = line.range(of: ",") {
line = line.substring(to: range.lowerBound)
} else if let range = line.range(of: ")") {
line = line.substring(to: range.lowerBound)
}

guard let delimiterRange = packageDescription.range(of: ",") ?? packageDescription.range(of: ")") else {
throw Error.failedToReadPackageFile(packageFile.nameExcludingExtension)
line = line.trimmingCharacters(in: .whitespacesAndNewlines)
return line.replacingOccurrences(of: "\"", with: "")
}

packageDescription = packageDescription.substring(to: delimiterRange.lowerBound)
packageDescription = packageDescription.trimmingCharacters(in: .whitespacesAndNewlines)
return packageDescription.replacingOccurrences(of: "\"", with: "")
throw Error.failedToReadPackageFile(packageFile.name)
}

private func nameOfRemotePackage(at url: URL) throws -> String {
Expand Down
26 changes: 26 additions & 0 deletions Tests/MarathonTests/MarathonTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,32 @@ class MarathonTests: XCTestCase {
try XCTAssertEqual(folder.subfolder(named: "Packages").files.count, 0)
}

func testAddingLocalPackage() throws {
let packageFolder = try folder.createSubfolder(named: "TestPackage")
try packageFolder.moveToAndPerform(command: "swift package init")

let packageDescription = "import PackageDescription\n" +
"let package = Package(name: \"TestPackage\")"

let packageFile = try packageFolder.file(named: "Package.swift")
try packageFile.write(string: packageDescription)

let gitCommand = "git init && git add . && git commit -a -m \"Commit\" && git tag 0.1.0"
try packageFolder.moveToAndPerform(command: gitCommand)

try run(with: ["add", "TestPackage"])
XCTAssertNotNil(try? folder.subfolder(named: "Packages").file(named: "TestPackage").read())

let generatedFolder = try folder.subfolder(atPath: "Packages/Generated")

let generatedPackageFile = try generatedFolder.file(named: "Package.swift")
try XCTAssertTrue(generatedPackageFile.readAsString().contains(packageFolder.path))

let packageNames = try generatedFolder.subfolder(atPath: ".build/checkouts").subfolders.names
XCTAssertEqual(packageNames.count, 1)
XCTAssertTrue(packageNames.contains { $0.hasPrefix("TestPackage-") })
}

func testAddingLocalPackageWithDependency() throws {
let packageFolder = try folder.createSubfolder(named: "TestPackage")
try packageFolder.moveToAndPerform(command: "swift package init")
Expand Down

0 comments on commit 8068cc3

Please sign in to comment.