Skip to content

Commit

Permalink
feat(swiftpm): Support lockfile format version 2
Browse files Browse the repository at this point in the history
The data class is quite similar to the one for version 1. However, it
makes sense to have separated code paths, so that things remain simple
as soon as the logic gets extended. For example, the `kind` attribute
may need to be considered in case the implementation gets extended to
handle local dependencies.

Signed-off-by: Frank Viernau <[email protected]>
  • Loading branch information
fviernau committed Jan 23, 2024
1 parent 2f7723a commit b9016e3
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
project:
id: "SwiftPM::src/funTest/assets/projects/synthetic/lockfile-v2/Package.resolved:<REPLACE_REVISION>"
definition_file_path: "<REPLACE_DEFINITION_FILE_PATH>"
declared_licenses: []
declared_licenses_processed: {}
vcs:
type: ""
url: ""
revision: ""
path: ""
vcs_processed:
type: "Git"
url: "<REPLACE_URL_PROCESSED>"
revision: "<REPLACE_REVISION>"
path: "<REPLACE_PATH>"
homepage_url: ""
packages:
- id: "Swift::github.com/alamofire/alamofire:5.4.4"
purl: "pkg:swift/github.com%2Falamofire%[email protected]"
declared_licenses: []
declared_licenses_processed: {}
description: ""
homepage_url: ""
binary_artifact:
url: ""
hash:
value: ""
algorithm: ""
source_artifact:
url: ""
hash:
value: ""
algorithm: ""
vcs:
type: "Git"
url: "https://github.com/Alamofire/Alamofire.git"
revision: "d120af1e8638c7da36c8481fd61a66c0c08dc4fc"
path: ""
vcs_processed:
type: "Git"
url: "https://github.com/Alamofire/Alamofire.git"
revision: "d120af1e8638c7da36c8481fd61a66c0c08dc4fc"
path: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"pins" : [
{
"identity" : "alamofire",
"kind" : "remoteSourceControl",
"location" : "https://github.com/Alamofire/Alamofire.git",
"state" : {
"revision" : "d120af1e8638c7da36c8481fd61a66c0c08dc4fc",
"version" : "5.4.4"
}
}
],
"version" : 2
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ class SwiftPmFunTest : WordSpec({
}
}

"Analyzing a lockfile with file format version 2" should {
"return the correct result" {
val definitionFile = getAssetFile("projects/synthetic/lockfile-v2/Package.resolved")
val expectedResultFile = getAssetFile("projects/synthetic/expected-output-lockfile-v2.yml")

val result = create(PROJECT_TYPE).resolveSingleProject(definitionFile)

result.toYaml() should matchExpectedResult(expectedResultFile, definitionFile)
}
}

"Analyzing a lockfile with unsupported file format version 3" should {
"return " {
val definitionFile = getAssetFile("projects/synthetic/lockfile-v3/Package.resolved")
Expand Down
6 changes: 6 additions & 0 deletions plugins/package-managers/swiftpm/src/main/kotlin/SwiftPm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,12 @@ private fun parseLockfile(packageResolvedFile: File): Result<Set<Package>> =
pins.mapTo(mutableSetOf()) { it.toPackage() }
}

"2" -> {
val pinsJson = root["pins"]
val pins = pinsJson?.let { json.decodeFromJsonElement<List<PinV2>>(it) }.orEmpty()
pins.mapTo(mutableSetOf()) { it.toPackage() }
}

else -> {
throw IOException(
"Could not parse lockfile '${packageResolvedFile.invariantSeparatorsPath}'. Unknown file format " +
Expand Down
46 changes: 46 additions & 0 deletions plugins/package-managers/swiftpm/src/main/kotlin/SwiftPmModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,23 @@ data class PinV1(
)
}

/**
* See https://github.com/apple/swift-package-manager/blob/3ef830dddff459e569d6e49c186c3ded33c39bcc/Sources/PackageGraph/PinsStore.swift#L387-L462.
*/
@Serializable
data class PinV2(
val identity: String,
val state: State?,
val location: String
) {
@Serializable
data class State(
val version: String? = null,
val revision: String? = null,
val branch: String? = null
)
}

internal val SwiftPackage.Dependency.id: Identifier
get() = Identifier(
type = PACKAGE_TYPE,
Expand Down Expand Up @@ -115,6 +132,35 @@ internal fun PinV1.toPackage(): Package {
return createPackage(id, vcsInfo)
}

internal fun PinV2.toPackage(): Package {
val id = Identifier(
type = PACKAGE_TYPE,
namespace = "",
name = getCanonicalName(location),
version = state?.run {
when {
!version.isNullOrBlank() -> version
!revision.isNullOrBlank() -> "revision-$revision"
!branch.isNullOrBlank() -> "branch-$branch"
else -> ""
}
}.orEmpty()
)

val vcsInfoFromUrl = VcsHost.parseUrl(location)
val vcsInfo = if (vcsInfoFromUrl.revision.isBlank() && state != null) {
when {
!state.revision.isNullOrBlank() -> vcsInfoFromUrl.copy(revision = state.revision)
!state.version.isNullOrBlank() -> vcsInfoFromUrl.copy(revision = state.version)
else -> vcsInfoFromUrl
}
} else {
vcsInfoFromUrl
}

return createPackage(id, vcsInfo)
}

private fun createPackage(id: Identifier, vcsInfo: VcsInfo) =
Package(
vcs = vcsInfo,
Expand Down

0 comments on commit b9016e3

Please sign in to comment.