Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<NameVersion> 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do we want to do for conditions when versionObj is null, I have seen examples in python where version is not specified, do we have similar concept in Cargo?

Copy link
Collaborator Author

@zahidblackduck zahidblackduck Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an interesting question which I didn't think of earlier. I'll explore further whether there is any possibility of an version section being null and if so, then how cargo declares / handles this.


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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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> nameVersion = parseCargoTomlLines(
Expand Down Expand Up @@ -60,6 +78,17 @@ void extractNoPackage() {
assertFalse(nameVersion.isPresent());
}

@Test
void extractNameVersionFromWorkspacePackage() {
CargoTomlParser parser = new CargoTomlParser();

Optional<NameVersion> nameVersion = parser.parseNameVersionFromCargoToml(WORKSPACE_TOML);

assertTrue(nameVersion.isPresent());
assertEquals("root-app", nameVersion.get().getName());
assertEquals("0.5.0", nameVersion.get().getVersion());
}

private Optional<NameVersion> parseCargoTomlLines(String... lines) {
CargoTomlParser parser = new CargoTomlParser();
String cargoTomlContents = StringUtils.joinWith(System.lineSeparator(), (Object[]) lines);
Expand Down