Skip to content

Commit

Permalink
fix(bazel): MODULE.bazel files from a local registry should be ignored
Browse files Browse the repository at this point in the history
`MODULE.bazel` files present in the local registry should not be considered
as definition files.

Fixes #9076.

Signed-off-by: Nicolas Nobelis <nicolas.nobelis@bosch.com>
  • Loading branch information
nnobelis authored and sschuberth committed Sep 18, 2024
1 parent 8cbbb57 commit 2ac103a
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import kotlinx.serialization.json.decodeFromStream
import org.apache.logging.log4j.kotlin.logger

private const val BAZEL_MODULES_DIR = "modules"
const val METADATA_JSON = "metadata.json"
const val SOURCE_JSON = "source.json"

/**
* A Bazel registry which is located on the local file system.
Expand Down Expand Up @@ -71,15 +73,15 @@ class LocalBazelModuleRegistryService(directory: File) : BazelModuleRegistryServ
}

override suspend fun getModuleMetadata(name: String): ModuleMetadata {
val metadataJson = moduleDirectory.resolve(name).resolve("metadata.json")
val metadataJson = moduleDirectory.resolve(name).resolve(METADATA_JSON)
require(metadataJson.isFile)
return metadataJson.inputStream().use {
JSON.decodeFromStream<ModuleMetadata>(it)
}
}

override suspend fun getModuleSourceInfo(name: String, version: String): ModuleSourceInfo {
val sourceJson = moduleDirectory.resolve(name).resolve(version).resolve("source.json")
val sourceJson = moduleDirectory.resolve(name).resolve(version).resolve(SOURCE_JSON)
require(sourceJson.isFile)
return sourceJson.inputStream().use {
JSON.decodeFromStream<ModuleSourceInfo>(it)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
repository:
vcs:
type: "Git"
url: "<REPLACE_URL>"
revision: "<REPLACE_REVISION>"
path: "plugins/package-managers/bazel/src/funTest/assets/projects/synthetic/bazel-local-registry2"
vcs_processed:
type: "Git"
url: "<REPLACE_URL_PROCESSED>"
revision: "<REPLACE_REVISION>"
path: "plugins/package-managers/bazel/src/funTest/assets/projects/synthetic/bazel-local-registry2"
config: {}
analyzer:
start_time: "1970-01-01T00:00:00Z"
end_time: "1970-01-01T00:00:00Z"
environment:
ort_version: "HEAD"
build_jdk: "<REPLACE_JDK>"
java_version: "<REPLACE_JAVA>"
os: "<REPLACE_OS>"
processors: "<REPLACE_PROCESSORS>"
max_memory: "<REPLACE_MAX_MEMORY>"
variables: {}
tool_versions: {}
config:
allow_dynamic_versions: false
skip_excluded: false
result:
projects:
- id: "Bazel::plugins/package-managers/bazel/src/funTest/assets/projects/synthetic/bazel-local-registry2/MODULE.bazel:"
definition_file_path: "<REPLACE_DEFINITION_FILE_PATH>"
declared_licenses: []
declared_licenses_processed: {}
vcs:
type: "Git"
url: "<REPLACE_URL_PROCESSED>"
revision: "<REPLACE_REVISION>"
path: "<REPLACE_PATH>"
vcs_processed:
type: "Git"
url: "<REPLACE_URL_PROCESSED>"
revision: "<REPLACE_REVISION>"
path: "<REPLACE_PATH>"
homepage_url: ""
scopes:
- name: "main"
dependencies:
- id: "Bazel::module_a:0.0.1"
linkage: "STATIC"
dependencies:
- id: "Bazel::module_b:0.0.1"
linkage: "STATIC"
packages:
- id: "Bazel::module_a:0.0.1"
purl: "pkg:generic/module_a@0.0.1"
declared_licenses: []
declared_licenses_processed: {}
description: ""
homepage_url: ""
binary_artifact:
url: ""
hash:
value: ""
algorithm: ""
source_artifact:
url: "https://example.com/module_a-0.0.1.zip"
hash:
value: "562c4be7507dc6fb4997ecd648bf935d84efe17b54715fa5cfbddac05279f668"
algorithm: "SHA-256"
vcs:
type: "Git"
url: ""
revision: ""
path: ""
vcs_processed:
type: "Git"
url: ""
revision: ""
path: ""
- id: "Bazel::module_b:0.0.1"
purl: "pkg:generic/module_b@0.0.1"
declared_licenses: []
declared_licenses_processed: {}
description: ""
homepage_url: ""
binary_artifact:
url: ""
hash:
value: ""
algorithm: ""
source_artifact:
url: "https://example.com/module_b-0.0.1.zip"
hash:
value: "562c4be7507dc6fb4997ecd648bf935d84efe17b54715fa5cfbddac05279f668"
algorithm: "SHA-256"
vcs:
type: "Git"
url: ""
revision: ""
path: ""
vcs_processed:
type: "Git"
url: ""
revision: ""
path: ""
scanner: null
advisor: null
evaluator: null
resolved_configuration: {}
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,25 @@

package org.ossreviewtoolkit.plugins.packagemanagers.bazel

import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.nulls.shouldNotBeNull
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.should

import org.ossreviewtoolkit.analyzer.analyze
import org.ossreviewtoolkit.model.toYaml
import org.ossreviewtoolkit.utils.test.getAssetFile
import org.ossreviewtoolkit.utils.test.matchExpectedResult
import org.ossreviewtoolkit.utils.test.patchActualResult

class BazelDetectionTest : StringSpec({
"MODULE.bazel files present in a local registry should not be considered as definition files" {
val definitionFile = getAssetFile("projects/synthetic/bazel-local-registry2/MODULE.bazel")
val expectedResultFile = getAssetFile("projects/synthetic/bazel-expected-output-local-registry2.yml")

val exception = shouldThrow<IllegalArgumentException> {
analyze(definitionFile.parentFile, packageManagers = listOf(Bazel.Factory()))
}
val result = analyze(definitionFile.parentFile, packageManagers = listOf(Bazel.Factory()))

exception.shouldNotBeNull {
// Running the Analyzer on a project depending on packages present in a local registry currently fails
// with this message (issue #9076). This is because the "MODULE.bazel" files present in the local
// registry should not be considered as definition files.
message shouldContain
"Unable to create the AnalyzerResult as it contains packages and projects with the same ids"
}
patchActualResult(result.toYaml(), patchStartAndEndTime = true) should matchExpectedResult(
expectedResultFile,
definitionFile
)
}
})
17 changes: 17 additions & 0 deletions plugins/package-managers/bazel/src/main/kotlin/Bazel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ import org.ossreviewtoolkit.analyzer.PackageManager
import org.ossreviewtoolkit.clients.bazelmoduleregistry.ArchiveOverride
import org.ossreviewtoolkit.clients.bazelmoduleregistry.BazelModuleRegistryService
import org.ossreviewtoolkit.clients.bazelmoduleregistry.LocalBazelModuleRegistryService
import org.ossreviewtoolkit.clients.bazelmoduleregistry.METADATA_JSON
import org.ossreviewtoolkit.clients.bazelmoduleregistry.ModuleMetadata
import org.ossreviewtoolkit.clients.bazelmoduleregistry.ModuleSourceInfo
import org.ossreviewtoolkit.clients.bazelmoduleregistry.RemoteBazelModuleRegistryService
import org.ossreviewtoolkit.clients.bazelmoduleregistry.SOURCE_JSON
import org.ossreviewtoolkit.downloader.VersionControlSystem
import org.ossreviewtoolkit.model.Hash
import org.ossreviewtoolkit.model.HashAlgorithm
Expand All @@ -55,6 +57,7 @@ import org.ossreviewtoolkit.model.createAndLogIssue
import org.ossreviewtoolkit.model.orEmpty
import org.ossreviewtoolkit.utils.common.CommandLineTool
import org.ossreviewtoolkit.utils.common.ProcessCapture
import org.ossreviewtoolkit.utils.common.alsoIfNull
import org.ossreviewtoolkit.utils.common.collectMessages
import org.ossreviewtoolkit.utils.common.withoutPrefix
import org.ossreviewtoolkit.utils.ort.createOrtTempFile
Expand Down Expand Up @@ -86,6 +89,20 @@ class Bazel(

override fun command(workingDir: File?) = "bazel"

/**
* To avoid processing the module files in a local registry as definition files, ignore them if they are aside a
* source.json file and under a directory with a metadata.json file. This simple metric avoids parsing the .bazelrc
* in the top directory of the project to find out if a MODULE.bazel file is part of a local registry or not.
*/
override fun mapDefinitionFiles(definitionFiles: List<File>): List<File> =
definitionFiles.mapNotNull { file ->
file.takeUnless {
it.resolveSibling(SOURCE_JSON).isFile && it.parentFile.resolveSibling(METADATA_JSON).isFile
}.alsoIfNull {
logger.info { "Ignoring definition file '$file' as it is a module of a local registry." }
}
}

override fun run(vararg args: CharSequence, workingDir: File?, environment: Map<String, String>): ProcessCapture =
super.run(
args = args,
Expand Down

0 comments on commit 2ac103a

Please sign in to comment.