Skip to content

Commit 293ebc4

Browse files
committed
feat(migrate): Add an option to convert NuGet IDs to the namespace format
Signed-off-by: Sebastian Schuberth <[email protected]>
1 parent dc32462 commit 293ebc4

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

plugins/commands/migrate/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ plugins {
2525
dependencies {
2626
api(project(":plugins:commands:command-api"))
2727

28+
implementation(project(":plugins:package-curation-providers:ort-config-package-curation-provider"))
29+
implementation(project(":plugins:package-managers:nuget-package-manager"))
2830
implementation(project(":utils:common-utils"))
2931

3032
implementation(libs.clikt)
33+
implementation(libs.jacksonModuleKotlin)
3134
}

plugins/commands/migrate/src/main/kotlin/MigrateCommand.kt

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,25 @@
1919

2020
package org.ossreviewtoolkit.plugins.commands.migrate
2121

22+
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator
23+
2224
import com.github.ajalt.clikt.parameters.options.convert
2325
import com.github.ajalt.clikt.parameters.options.option
2426
import com.github.ajalt.clikt.parameters.types.file
2527

28+
import java.io.File
29+
30+
import org.ossreviewtoolkit.model.FileFormat
31+
import org.ossreviewtoolkit.model.PackageCuration
32+
import org.ossreviewtoolkit.model.config.PackageConfiguration
33+
import org.ossreviewtoolkit.model.readValue
34+
import org.ossreviewtoolkit.model.yamlMapper
2635
import org.ossreviewtoolkit.plugins.commands.api.OrtCommand
36+
import org.ossreviewtoolkit.plugins.packagecurationproviders.ortconfig.toCurationPath
37+
import org.ossreviewtoolkit.plugins.packagemanagers.nuget.utils.getIdentifierWithNamespace
2738
import org.ossreviewtoolkit.utils.common.expandTilde
39+
import org.ossreviewtoolkit.utils.common.getCommonParentFile
40+
import org.ossreviewtoolkit.utils.common.safeMkdirs
2841

2942
class MigrateCommand : OrtCommand(
3043
name = "migrate",
@@ -36,10 +49,88 @@ class MigrateCommand : OrtCommand(
3649
).convert { it.expandTilde() }
3750
.file(mustExist = true, canBeFile = true, canBeDir = false, mustBeWritable = false, mustBeReadable = true)
3851

52+
private val nuGetIds by option(
53+
"--nuget-ids",
54+
help = "Convert NuGet package IDs in curations and configurations to the new format that includes a namespace."
55+
).convert { it.expandTilde() }
56+
.file(mustExist = true, canBeFile = false, canBeDir = true, mustBeWritable = true, mustBeReadable = true)
57+
3958
override fun run() {
4059
hoconToYaml?.run {
4160
echo(convertHoconToYaml(readText()))
4261
}
62+
63+
nuGetIds?.run {
64+
migrateNuGetIds(this)
65+
}
66+
}
67+
68+
private fun migrateNuGetIds(configDir: File) {
69+
val configYamlMapper = yamlMapper.copy()
70+
.enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE)
71+
.disable(YAMLGenerator.Feature.SPLIT_LINES)
72+
.disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)
73+
74+
val candidateFiles = FileFormat.findFilesWithKnownExtensions(configDir).toMutableList()
75+
76+
val pkgCurationFiles = candidateFiles.mapNotNull { file ->
77+
runCatching {
78+
file.readValue<List<PackageCuration>>()
79+
}.getOrNull()?.let {
80+
file to it
81+
}
82+
}.toMap()
83+
84+
val curationsDir = getCommonParentFile(pkgCurationFiles.keys)
85+
candidateFiles -= pkgCurationFiles.keys
86+
87+
val pkgConfigFiles = candidateFiles.mapNotNull { file ->
88+
runCatching {
89+
file.readValue<PackageConfiguration>()
90+
}.getOrNull()?.let {
91+
file to it
92+
}
93+
}.toMap()
94+
95+
candidateFiles -= pkgConfigFiles.keys
96+
echo("Skipping ${candidateFiles.size} files of unknown format.")
97+
98+
echo("Processing ${pkgCurationFiles.size} package curation files...")
99+
pkgCurationFiles.forEach { (file, curations) ->
100+
val curationsWithFixedIds = curations.map {
101+
if (it.id.type == "NuGet") {
102+
it.copy(id = getIdentifierWithNamespace(it.id.type, it.id.name, it.id.version))
103+
} else {
104+
it
105+
}
106+
}
107+
108+
if (curationsWithFixedIds != curations) {
109+
val oldPath = file.relativeTo(curationsDir).path
110+
val newPath = curationsWithFixedIds.first().id.toCurationPath()
111+
112+
// TODO: Maybe make this optional to support layouts that do not follow ort-config conventions.
113+
if (newPath != oldPath) {
114+
curationsDir.resolve(oldPath).delete()
115+
}
116+
117+
val newFile = curationsDir.resolve(newPath).apply { parentFile.safeMkdirs() }
118+
configYamlMapper.writeValue(newFile, curationsWithFixedIds)
119+
}
120+
}
121+
122+
echo("Processing ${pkgConfigFiles.size} package configuration files...")
123+
pkgConfigFiles.forEach { (file, config) ->
124+
val configWithFixedId = if (config.id.type == "NuGet") {
125+
config.copy(id = getIdentifierWithNamespace(config.id.type, config.id.name, config.id.version))
126+
} else {
127+
config
128+
}
129+
130+
if (configWithFixedId != config) {
131+
configYamlMapper.writeValue(file, configWithFixedId)
132+
}
133+
}
43134
}
44135
}
45136

0 commit comments

Comments
 (0)