diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonConstants.java b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonConstants.java new file mode 100644 index 0000000000..5db78ae74c --- /dev/null +++ b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonConstants.java @@ -0,0 +1,7 @@ +package com.blackduck.integration.detectable.detectables.meson; + +import com.blackduck.integration.bdio.model.Forge; + +public class MesonConstants { + public static final Forge MESON_FORGE = new Forge("/", "meson"); +} diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonDetectable.java b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonDetectable.java new file mode 100644 index 0000000000..3d150101d3 --- /dev/null +++ b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonDetectable.java @@ -0,0 +1,61 @@ +package com.blackduck.integration.detectable.detectables.meson; + +import java.io.File; + +import com.blackduck.integration.common.util.finder.FileFinder; +import com.blackduck.integration.detectable.Detectable; +import com.blackduck.integration.detectable.DetectableEnvironment; +import com.blackduck.integration.detectable.detectable.DetectableAccuracyType; +import com.blackduck.integration.detectable.detectable.Requirements; +import com.blackduck.integration.detectable.detectable.annotation.DetectableInfo; +import com.blackduck.integration.detectable.detectable.result.DetectableResult; +import com.blackduck.integration.detectable.detectable.result.FilesNotFoundDetectableResult; +import com.blackduck.integration.detectable.detectable.result.PassedDetectableResult; +import com.blackduck.integration.detectable.extraction.Extraction; +import com.blackduck.integration.detectable.extraction.ExtractionEnvironment; + +@DetectableInfo(name = "Meson", language = "C/C++", forge = "meson", accuracy = DetectableAccuracyType.HIGH, requirementsMarkdown = "Files: meson.build, intro-projectinfo.json, intro-dependencies.json") +public class MesonDetectable extends Detectable { + public static final String MESON_BUILD_FILENAME = "meson.build"; + private static final String INTROSPECT_PROJECT_FILENAME = "intro-projectinfo.json"; + private static final String INTROSPECT_DEPENDENCIES_FILENAME = "intro-dependencies.json"; + + private final FileFinder fileFinder; + private final MesonExtractor mesonExtractor; + + private File projectInfoFile; + private File dependenciesFile; + + public MesonDetectable(DetectableEnvironment environment, FileFinder fileFinder, MesonExtractor mesonExtractor) { + super(environment); + this.fileFinder = fileFinder; + this.mesonExtractor = mesonExtractor; + } + + @Override + public DetectableResult applicable() { + Requirements requirements = new Requirements(fileFinder, environment); + requirements.file(MESON_BUILD_FILENAME); + if (requirements.isAlreadyFailed()) { + return requirements.result(); + } + projectInfoFile = fileFinder.findFile(environment.getDirectory(), INTROSPECT_PROJECT_FILENAME, false, 2); + dependenciesFile = fileFinder.findFile(environment.getDirectory(), INTROSPECT_DEPENDENCIES_FILENAME, false, 2); + if (projectInfoFile == null || dependenciesFile == null) { + return new FilesNotFoundDetectableResult(INTROSPECT_PROJECT_FILENAME, INTROSPECT_DEPENDENCIES_FILENAME); + } + requirements.explainFile(projectInfoFile); + requirements.explainFile(dependenciesFile); + return requirements.result(); + } + + @Override + public DetectableResult extractable() { + return new PassedDetectableResult(); + } + + @Override + public Extraction extract(ExtractionEnvironment extractionEnvironment) { + return mesonExtractor.extract(projectInfoFile, dependenciesFile); + } +} diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonExtractor.java b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonExtractor.java new file mode 100644 index 0000000000..a3b0821d33 --- /dev/null +++ b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/MesonExtractor.java @@ -0,0 +1,70 @@ +package com.blackduck.integration.detectable.detectables.meson; + +import java.io.BufferedReader; +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.blackduck.integration.bdio.graph.DependencyGraph; +import com.blackduck.integration.detectable.detectable.codelocation.CodeLocation; +import com.blackduck.integration.detectable.detectables.meson.parse.MesonDependencyFileParser; +import com.blackduck.integration.detectable.detectables.meson.parse.MesonProjectFileParser; +import com.blackduck.integration.detectable.extraction.Extraction; +import com.blackduck.integration.util.NameVersion; +import com.google.gson.Gson; + +public class MesonExtractor { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final MesonProjectFileParser mesonProjectFileParser; + private final MesonDependencyFileParser mesonDependencyFileParser; + private final Gson gson; + + public MesonExtractor( + MesonProjectFileParser mesonProjectFileParser, + MesonDependencyFileParser mesonDependencyFileParser, + Gson gson + ) { + this.mesonProjectFileParser = mesonProjectFileParser; + this.mesonDependencyFileParser = mesonDependencyFileParser; + this.gson = gson; + } + + public Extraction extract(File projectInfoFile, File dependenciesFile) { + try { + logger.debug("Parsing Meson project info: {}", projectInfoFile.getAbsolutePath()); + NameVersion nameVersion = determineProjectNameVersion(projectInfoFile); + + logger.debug("Parsing Meson dependencies: {}", dependenciesFile.getAbsolutePath()); + try (BufferedReader reader = Files.newBufferedReader(dependenciesFile.toPath(), StandardCharsets.UTF_8)) { + DependencyGraph dependencyGraph = mesonDependencyFileParser.parseProjectDependencies(gson, reader); + CodeLocation codeLocation = new CodeLocation(dependencyGraph); + + return new Extraction.Builder() + .success(codeLocation) + .projectName(nameVersion.getName()) + .projectVersion(nameVersion.getVersion()) + .build(); + } + + } catch (Exception e) { + logger.error("Failed to extract Meson dependencies", e); + return new Extraction.Builder().exception(e).build(); + } + } + + private NameVersion determineProjectNameVersion(File projectInfoFile) { + final String defaultProjectName = ""; + final String defaultProjectVersion = ""; + + try (BufferedReader reader = Files.newBufferedReader(projectInfoFile.toPath(), StandardCharsets.UTF_8)) { + return mesonProjectFileParser.getProjectNameVersion(gson, reader, defaultProjectName, defaultProjectVersion); + } catch (Exception e) { + logger.warn("Failed to parse Meson introspect, using defaults", e); + } + + return new NameVersion(defaultProjectName, defaultProjectVersion); + } +} diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/parse/MesonDependencyFileParser.java b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/parse/MesonDependencyFileParser.java new file mode 100644 index 0000000000..8e29aba789 --- /dev/null +++ b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/parse/MesonDependencyFileParser.java @@ -0,0 +1,77 @@ +package com.blackduck.integration.detectable.detectables.meson.parse; + +import java.io.BufferedReader; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.blackduck.integration.bdio.graph.BasicDependencyGraph; +import com.blackduck.integration.bdio.graph.DependencyGraph; +import com.blackduck.integration.bdio.model.dependency.Dependency; +import com.blackduck.integration.bdio.model.externalid.ExternalId; +import com.blackduck.integration.bdio.model.externalid.ExternalIdFactory; +import com.blackduck.integration.detectable.detectables.meson.MesonConstants; +import com.google.gson.Gson; + +public class MesonDependencyFileParser { + private static final String INTERNAL_DEPENDENCY_TYPE = "internal"; + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final ExternalIdFactory externalIdFactory; + + public MesonDependencyFileParser(ExternalIdFactory externalIdFactory) { + this.externalIdFactory = externalIdFactory; + } + + public DependencyGraph parseProjectDependencies(Gson gson, BufferedReader reader) { + DependencyGraph graph = new BasicDependencyGraph(); + + try { + MesonDependency[] dependencies = gson.fromJson(reader, MesonDependency[].class); + + if (dependencies == null) { + logger.warn("Failed to parse Meson dependencies - gson returned null"); + return graph; + } + + logger.debug("Found {} Meson dependencies", dependencies.length); + + for (MesonDependency dep : dependencies) { + if (!INTERNAL_DEPENDENCY_TYPE.equals(dep.getType()) + && StringUtils.isNotBlank(dep.getName()) + && StringUtils.isNotBlank(dep.getVersion())) { + + ExternalId dependencyExternalId = externalIdFactory.createNameVersionExternalId(MesonConstants.MESON_FORGE, dep.getName(), dep.getVersion()); + Dependency dependency = new Dependency(dep.getName(), dep.getVersion(), dependencyExternalId); + logger.trace("Adding dependency: {}", dependency.getExternalId()); + graph.addDirectDependency(dependency); + } else { + logger.debug("Skipping dependency - name: '{}', type: '{}', version: '{}'", dep.getName(), dep.getType(), dep.getVersion()); + } + } + } catch (Exception e) { + logger.warn("Failed to parse Meson dependency JSON", e); + } + + return graph; + } + + private static class MesonDependency { + private String name; + private String type; + private String version; + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public String getVersion() { + return version; + } + } +} diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/parse/MesonProjectFileParser.java b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/parse/MesonProjectFileParser.java new file mode 100644 index 0000000000..3d66d17561 --- /dev/null +++ b/detectable/src/main/java/com/blackduck/integration/detectable/detectables/meson/parse/MesonProjectFileParser.java @@ -0,0 +1,55 @@ +package com.blackduck.integration.detectable.detectables.meson.parse; + +import java.io.BufferedReader; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.blackduck.integration.util.NameVersion; +import com.google.gson.Gson; + +public class MesonProjectFileParser { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public MesonProjectFileParser() { + } + + public NameVersion getProjectNameVersion(Gson gson, BufferedReader reader, String defaultProjectName, + String defaultProjectVersion) { + try { + MesonProjectInfo projectInfo = gson.fromJson(reader, MesonProjectInfo.class); + + String projectName = defaultProjectName; + String projectVersion = defaultProjectVersion; + + if (StringUtils.isNotBlank(projectInfo.getDescriptiveName())) { + projectName = projectInfo.getDescriptiveName(); + logger.debug("Extracted project name: {}", projectName); + } + + if (StringUtils.isNotBlank(projectInfo.getVersion())) { + projectVersion = projectInfo.getVersion(); + logger.debug("Extracted project version: {}", projectVersion); + } + + return new NameVersion(projectName, projectVersion); + } catch (Exception e) { + logger.warn("Failed to parse Meson project JSON, using defaults", e); + return new NameVersion(defaultProjectName, defaultProjectVersion); + } + } + + private static class MesonProjectInfo { + private String version; + private String descriptive_name; + + public String getVersion() { + return version; + } + + public String getDescriptiveName() { + return descriptive_name; + } + } +} diff --git a/detectable/src/main/java/com/blackduck/integration/detectable/factory/DetectableFactory.java b/detectable/src/main/java/com/blackduck/integration/detectable/factory/DetectableFactory.java index 00b3eb96af..e698052be0 100644 --- a/detectable/src/main/java/com/blackduck/integration/detectable/factory/DetectableFactory.java +++ b/detectable/src/main/java/com/blackduck/integration/detectable/factory/DetectableFactory.java @@ -176,6 +176,10 @@ import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomDetectable; import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomWrapperDetectable; import com.blackduck.integration.detectable.detectables.maven.parsing.MavenProjectInspectorDetectable; +import com.blackduck.integration.detectable.detectables.meson.MesonDetectable; +import com.blackduck.integration.detectable.detectables.meson.MesonExtractor; +import com.blackduck.integration.detectable.detectables.meson.parse.MesonDependencyFileParser; +import com.blackduck.integration.detectable.detectables.meson.parse.MesonProjectFileParser; import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliDetectable; import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliExtractor; import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliExtractorOptions; @@ -396,6 +400,13 @@ public ClangDetectable createClangDetectable(DetectableEnvironment environment, ); } + public MesonDetectable createMesonDetectable(DetectableEnvironment environment) { + MesonProjectFileParser mesonProjectFileParser = new MesonProjectFileParser(); + MesonDependencyFileParser mesonDependencyFileParser = new MesonDependencyFileParser(externalIdFactory); + MesonExtractor mesonExtractor = new MesonExtractor(mesonProjectFileParser, mesonDependencyFileParser, gson); + return new MesonDetectable(environment, fileFinder, mesonExtractor); + } + public ComposerLockDetectable createComposerDetectable(DetectableEnvironment environment, ComposerLockDetectableOptions composerLockDetectableOptions) { PackagistParser packagistParser = new PackagistParser(externalIdFactory, composerLockDetectableOptions.getDependencyTypeFilter()); ComposerLockExtractor composerLockExtractor = new ComposerLockExtractor(packagistParser); diff --git a/detectable/src/test/java/com/blackduck/integration/detectable/detectables/meson/functional/MesonDependencyFileParserTest.java b/detectable/src/test/java/com/blackduck/integration/detectable/detectables/meson/functional/MesonDependencyFileParserTest.java new file mode 100644 index 0000000000..6f3d4db1bb --- /dev/null +++ b/detectable/src/test/java/com/blackduck/integration/detectable/detectables/meson/functional/MesonDependencyFileParserTest.java @@ -0,0 +1,55 @@ +package com.blackduck.integration.detectable.detectables.meson.functional; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; + +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Assertions; + +import com.blackduck.integration.detectable.Detectable; +import com.blackduck.integration.detectable.DetectableEnvironment; +import com.blackduck.integration.detectable.extraction.Extraction; +import com.blackduck.integration.detectable.detectables.meson.MesonConstants; +import com.blackduck.integration.detectable.functional.DetectableFunctionalTest; +import com.blackduck.integration.detectable.util.graph.NameVersionGraphAssert; + +public class MesonDependencyFileParserTest extends DetectableFunctionalTest { + public MesonDependencyFileParserTest() throws IOException { + super("meson"); + } + + @Override + protected void setup() throws IOException { + Path root = addDirectory(Paths.get(".")); + Path builddir = addDirectory(Paths.get("builddir/meson-info")); + addFile( + root.resolve("meson.build"), + "project('hello','cpp',default_options: ['cpp_std=c++20', 'default_library=shared'],version : '0.1',)", + "deps = [dependency('boost'),dependency('libcurl'),]", + "exe = executable('hello', 'hello.cpp', install : true)" + ); + addFile( + builddir.resolve("intro-projectinfo.json"), + "{\"version\": \"0.1\", \"descriptive_name\": \"hello\", \"subproject_dir\": \"subprojects\", \"subprojects\": []}" + ); + addFile(builddir.resolve("intro-dependencies.json"), + "[{\"name\": \"boost\", \"type\": \"system\", \"version\": \"1.83.0\", \"compile_args\": [\"-I/usr/include\", \"-DBOOST_ALL_NO_LIB\"], \"link_args\": [], \"include_directories\": [], \"sources\": [], \"extra_files\": [], \"dependencies\": [], \"depends\": [], \"meson_variables\": []}, {\"name\": \"libcurl\", \"type\": \"pkgconfig\", \"version\": \"8.5.0\", \"compile_args\": [\"-I/usr/include/x86_64-linux-gnu\"], \"link_args\": [\"/usr/lib/x86_64-linux-gnu/libcurl.so\"], \"include_directories\": [], \"sources\": [], \"extra_files\": [], \"dependencies\": [], \"depends\": [], \"meson_variables\": []}]" + ); + } + + @NotNull + @Override + public Detectable create(@NotNull DetectableEnvironment detectableEnvironment) { + return detectableFactory.createMesonDetectable(detectableEnvironment); + } + + @Override + public void assertExtraction(@NotNull Extraction extraction) { + Assertions.assertEquals(1, extraction.getCodeLocations().size()); + NameVersionGraphAssert graphAssert = new NameVersionGraphAssert(MesonConstants.MESON_FORGE, extraction.getCodeLocations().get(0).getDependencyGraph()); + graphAssert.hasRootSize(2); + graphAssert.hasRootDependency("boost", "1.83.0"); + graphAssert.hasRootDependency("libcurl", "8.5.0"); + } +} diff --git a/detectable/src/test/java/com/blackduck/integration/detectable/detectables/meson/unit/MesonDetectableTest.java b/detectable/src/test/java/com/blackduck/integration/detectable/detectables/meson/unit/MesonDetectableTest.java new file mode 100644 index 0000000000..3c7793bcfa --- /dev/null +++ b/detectable/src/test/java/com/blackduck/integration/detectable/detectables/meson/unit/MesonDetectableTest.java @@ -0,0 +1,45 @@ +package com.blackduck.integration.detectable.detectables.meson.unit; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; + +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.blackduck.integration.common.util.finder.FileFinder; +import com.blackduck.integration.detectable.DetectableEnvironment; +import com.blackduck.integration.detectable.detectables.meson.MesonDetectable; +import com.blackduck.integration.detectable.detectables.meson.MesonExtractor; +import com.blackduck.integration.detectable.util.MockDetectableEnvironment; + +public class MesonDetectableTest { + + @Test + public void testApplicable() { + DetectableEnvironment environment = MockDetectableEnvironment.empty(); + File envDir = environment.getDirectory(); + + FileFinder fileFinder = Mockito.mock(FileFinder.class); + Mockito.when(fileFinder.findFile(envDir, "meson.build")).thenReturn(new File("meson.build")); + Mockito.when(fileFinder.findFile(envDir, "intro-projectinfo.json", false, 2)).thenReturn(new File("builddir/meson-info/intro-projectinfo.json")); + Mockito.when(fileFinder.findFile(envDir, "intro-dependencies.json", false, 2)).thenReturn(new File("builddir/meson-info/intro-dependencies.json")); + MesonExtractor mesonExtractor = new MesonExtractor(null, null, null); + MesonDetectable detectable = new MesonDetectable(environment, fileFinder, mesonExtractor); + + assertTrue(detectable.applicable().getPassed()); + } + + @Test + public void testNotApplicable() { + DetectableEnvironment environment = MockDetectableEnvironment.empty(); + FileFinder fileFinder = Mockito.mock(FileFinder.class); + File envDir = environment.getDirectory(); + Mockito.when(fileFinder.findFile(envDir, "meson.build", true, 0)).thenReturn(new File("meson.build")); + MesonExtractor mesonExtractor = new MesonExtractor(null, null, null); + MesonDetectable detectable = new MesonDetectable(environment, fileFinder, mesonExtractor); + + assertFalse(detectable.applicable().getPassed()); + } +} diff --git a/detector/src/main/java/com/blackduck/integration/detector/base/DetectorType.java b/detector/src/main/java/com/blackduck/integration/detector/base/DetectorType.java index 9568e12023..7c67ba7fa3 100644 --- a/detector/src/main/java/com/blackduck/integration/detector/base/DetectorType.java +++ b/detector/src/main/java/com/blackduck/integration/detector/base/DetectorType.java @@ -26,6 +26,7 @@ public enum DetectorType { // TODO: 8.0.0 Rename DetectorTypes IVY, LERNA, MAVEN, + MESON, NPM, NUGET, // MSBUILD PACKAGIST, diff --git a/documentation/src/main/markdown/components/detectors.dita b/documentation/src/main/markdown/components/detectors.dita index 0eb1a5be98..ecd4f2063e 100644 --- a/documentation/src/main/markdown/components/detectors.dita +++ b/documentation/src/main/markdown/components/detectors.dita @@ -562,6 +562,28 @@ LOW + + + MESON + + + + + + + + + + Meson + C++ + Generic + + File: meson.build + File: */meson-info/intro-project.json + File: */meson-info/intro-dependencies.json + + HIGH + NPM diff --git a/src/main/java/com/blackduck/integration/detect/configuration/enumeration/DetectGroup.java b/src/main/java/com/blackduck/integration/detect/configuration/enumeration/DetectGroup.java index c89d382045..653e60ead4 100644 --- a/src/main/java/com/blackduck/integration/detect/configuration/enumeration/DetectGroup.java +++ b/src/main/java/com/blackduck/integration/detect/configuration/enumeration/DetectGroup.java @@ -51,6 +51,7 @@ public enum DetectGroup implements Group { HEX("hex", DETECTORS), LERNA("lerna", DETECTORS), MAVEN("maven", DETECTORS), + MESON("meson", DETECTORS), NPM("npm", DETECTORS), NUGET("nuget", DETECTORS), PACKAGIST("packagist", DETECTORS), diff --git a/src/main/java/com/blackduck/integration/detect/tool/detector/DetectorRuleFactory.java b/src/main/java/com/blackduck/integration/detect/tool/detector/DetectorRuleFactory.java index d3b7b00741..9c0f29ac02 100644 --- a/src/main/java/com/blackduck/integration/detect/tool/detector/DetectorRuleFactory.java +++ b/src/main/java/com/blackduck/integration/detect/tool/detector/DetectorRuleFactory.java @@ -29,6 +29,7 @@ import com.blackduck.integration.detectable.detectables.lerna.LernaDetectable; import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomDetectable; import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomWrapperDetectable; +import com.blackduck.integration.detectable.detectables.meson.MesonDetectable; import com.blackduck.integration.detectable.detectables.maven.parsing.MavenProjectInspectorDetectable; import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliDetectable; import com.blackduck.integration.detectable.detectables.npm.lockfile.NpmPackageLockDetectable; @@ -304,6 +305,11 @@ public DetectorRuleSet createRules(DetectDetectableFactory detectableFactory) { .search().defaults(); }); + rules.addDetector(DetectorType.MESON, detector -> { + detector.entryPoint(MesonDetectable.class) + .search().defaults(); + }); + rules.addDetector(DetectorType.OPAM, detector -> { detector.entryPoint(OpamBuildDetectable.class) .search().defaults(); diff --git a/src/main/java/com/blackduck/integration/detect/tool/detector/factory/DetectDetectableFactory.java b/src/main/java/com/blackduck/integration/detect/tool/detector/factory/DetectDetectableFactory.java index 4d10ebdc3d..01e52c360c 100644 --- a/src/main/java/com/blackduck/integration/detect/tool/detector/factory/DetectDetectableFactory.java +++ b/src/main/java/com/blackduck/integration/detect/tool/detector/factory/DetectDetectableFactory.java @@ -37,6 +37,7 @@ import com.blackduck.integration.detectable.detectables.ivy.IvyParseDetectable; import com.blackduck.integration.detectable.detectables.lerna.LernaDetectable; import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomDetectable; +import com.blackduck.integration.detectable.detectables.meson.MesonDetectable; import com.blackduck.integration.detectable.detectables.maven.cli.MavenPomWrapperDetectable; import com.blackduck.integration.detectable.detectables.maven.parsing.MavenProjectInspectorDetectable; import com.blackduck.integration.detectable.detectables.npm.cli.NpmCliDetectable; @@ -137,6 +138,10 @@ public ClangDetectable createClangDetectable(DetectableEnvironment environment) return detectableFactory.createClangDetectable(environment, detectableOptionFactory.createClangDetectableOptions()); } + public MesonDetectable createMesonDetectable(DetectableEnvironment environment) { + return detectableFactory.createMesonDetectable(environment); + } + public ComposerLockDetectable createComposerDetectable(DetectableEnvironment environment) { return detectableFactory.createComposerDetectable(environment, detectableOptionFactory.createComposerLockDetectableOptions()); }
File: meson.build
File: */meson-info/intro-project.json
File: */meson-info/intro-dependencies.json