diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParser.java b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParser.java index fe857d9d5f..c35a474ad5 100644 --- a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParser.java +++ b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParser.java @@ -3,6 +3,7 @@ import java.util.EnumSet; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.Map; import java.util.HashMap; @@ -20,18 +21,32 @@ public class CargoTomlParser { private static final String NAME_KEY = "name"; private static final String VERSION_KEY = "version"; private static final String PACKAGE_KEY = "package"; + private static final String WORKSPACE_KEY = "workspace"; private static final String NORMAL_DEPENDENCIES_KEY = "dependencies"; private static final String BUILD_DEPENDENCIES_KEY = "build-dependencies"; private static final String DEV_DEPENDENCIES_KEY = "dev-dependencies"; public Optional parseNameVersionFromCargoToml(String tomlFileContents) { TomlParseResult cargoTomlObject = Toml.parse(tomlFileContents); - if (cargoTomlObject.contains(PACKAGE_KEY)) { - return Optional.ofNullable(cargoTomlObject.getTable(PACKAGE_KEY)) - .filter(info -> info.contains(NAME_KEY)) - .map(info -> new NameVersion(info.getString(NAME_KEY), info.getString(VERSION_KEY))); + TomlTable packageTable = cargoTomlObject.getTable(PACKAGE_KEY); + if (packageTable == null || !packageTable.contains(NAME_KEY)) { + return Optional.empty(); } - return Optional.empty(); + + String name = packageTable.getString(NAME_KEY); + String version = null; + Object versionObj = packageTable.get(VERSION_KEY); + + if (versionObj instanceof String) { + version = (String) versionObj; + } else if (versionObj instanceof TomlTable && Boolean.TRUE.equals(((TomlTable) versionObj).getBoolean(WORKSPACE_KEY))) { + TomlTable workspacePackage = cargoTomlObject.getTable(WORKSPACE_KEY) != null ? Objects.requireNonNull(cargoTomlObject.getTable(WORKSPACE_KEY)).getTable(PACKAGE_KEY) : null; + if (workspacePackage != null) { + version = workspacePackage.getString(VERSION_KEY); + } + } + + return Optional.of(new NameVersion(name, version)); } public boolean hasDependencySections(String tomlFileContents) { diff --git a/detectable/src/test/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParserTest.java b/detectable/src/test/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParserTest.java index 77ad9c0900..c10d244673 100644 --- a/detectable/src/test/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParserTest.java +++ b/detectable/src/test/java/com/blackduck/integration/detectable/detectables/cargo/parse/CargoTomlParserTest.java @@ -1,6 +1,5 @@ package com.blackduck.integration.detectable.detectables.cargo.parse; -import com.blackduck.integration.detectable.detectables.cargo.parse.CargoTomlParser; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNull; @@ -15,6 +14,25 @@ class CargoTomlParserTest { + private static final String WORKSPACE_TOML = String.join("\n", + "[workspace]", + "members = [\"extra-lib\"]", + "resolver = \"2\"", + "", + "[workspace.package]", + "version = \"0.5.0\"", + "edition = \"2021\"", + "repository = \"https://github.com/example/repo\"", + "license = \"CLOSED\"", + "", + "[package]", + "name = \"root-app\"", + "version.workspace = true", + "edition.workspace = true", + "repository.workspace = true", + "license.workspace = true" + ); + @Test void extractNameVersion() { Optional nameVersion = parseCargoTomlLines( @@ -60,6 +78,17 @@ void extractNoPackage() { assertFalse(nameVersion.isPresent()); } + @Test + void extractNameVersionFromWorkspacePackage() { + CargoTomlParser parser = new CargoTomlParser(); + + Optional nameVersion = parser.parseNameVersionFromCargoToml(WORKSPACE_TOML); + + assertTrue(nameVersion.isPresent()); + assertEquals("root-app", nameVersion.get().getName()); + assertEquals("0.5.0", nameVersion.get().getVersion()); + } + private Optional parseCargoTomlLines(String... lines) { CargoTomlParser parser = new CargoTomlParser(); String cargoTomlContents = StringUtils.joinWith(System.lineSeparator(), (Object[]) lines);