diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/ComponentInfoCuratorImpl.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/ComponentInfoCuratorImpl.java index b89ce6c5..a0b2e74d 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/ComponentInfoCuratorImpl.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/ComponentInfoCuratorImpl.java @@ -43,7 +43,7 @@ public ComponentInfoCuratorImpl(CurationProvider curationProvider, /** * Checks for the existence of curation for the given package via the {@link CurationProvider}. If curations exist - * then a new curated {@link ComponentInfo} instance will be created from the incoming uncurated {@link ComponentInfo} + * then a new curated {@link ComponentInfo} instance will be created from the incoming filtered {@link ComponentInfo} * and the curation. * * @param componentInfo the componentInfo to curate diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/CuratingComponentInfoAdapter.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/CuratingComponentInfoAdapter.java index 4061aa54..ceafa745 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/CuratingComponentInfoAdapter.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/CuratingComponentInfoAdapter.java @@ -5,26 +5,26 @@ import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; /** - * A {@link ComponentInfoAdapter} which takes uncurated {@link ComponentInfo} data from the configuret - * {@link UncuratedComponentInfoProvider} and curates it via the given {@link ComponentInfoCurator}. + * A {@link ComponentInfoAdapter} which takes filtered {@link ComponentInfo} data from the configuret + * {@link FilteredComponentInfoProvider} and curates it via the given {@link ComponentInfoCurator}. * */ public class CuratingComponentInfoAdapter implements ComponentInfoAdapter { - private UncuratedComponentInfoProvider uncuratedComponentInfoProvider; + private FilteredComponentInfoProvider filteredComponentInfoProvider; private ComponentInfoCurator componentInfoCurator; /** * The constructor. * - * @param uncuratedComponentInfoProvider the provider of the uncurated {@link ComponentInfo} data + * @param filteredComponentInfoProvider the provider of the filtered {@link ComponentInfo} data * @param componentInfoCurator the curator to take */ - public CuratingComponentInfoAdapter(UncuratedComponentInfoProvider uncuratedComponentInfoProvider, + public CuratingComponentInfoAdapter(FilteredComponentInfoProvider filteredComponentInfoProvider, ComponentInfoCurator componentInfoCurator) { - this.uncuratedComponentInfoProvider = uncuratedComponentInfoProvider; + this.filteredComponentInfoProvider = filteredComponentInfoProvider; this.componentInfoCurator = componentInfoCurator; } @@ -46,7 +46,7 @@ public ComponentInfo getComponentInfo(String packageUrl, String curationDataSele if (isFeatureActive()) { - ComponentInfo componentInfo = this.uncuratedComponentInfoProvider.getComponentInfo(packageUrl, + ComponentInfo componentInfo = this.filteredComponentInfoProvider.getComponentInfo(packageUrl, curationDataSelector); if (componentInfo == null) { return null; diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/FilteredComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/FilteredComponentInfoProvider.java new file mode 100644 index 00000000..08bc4a3a --- /dev/null +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/FilteredComponentInfoProvider.java @@ -0,0 +1,14 @@ +package com.devonfw.tools.solicitor.componentinfo.curation; + +import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoProvider; + +/** + * A {@link ComponentInfoProvider} which provides filtered {@link ComponentInfo}s. This is {@link ComponentInfo} which + * is not yet fully curated but data is already filtered to remove information which applies to portions of the original + * scanned code which should be disregarded. + * + */ +public interface FilteredComponentInfoProvider extends ComponentInfoProvider { + +} \ No newline at end of file diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/UncuratedComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/UncuratedComponentInfoProvider.java deleted file mode 100644 index 3c0bf998..00000000 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/UncuratedComponentInfoProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.devonfw.tools.solicitor.componentinfo.curation; - -import com.devonfw.tools.solicitor.componentinfo.ComponentInfo; -import com.devonfw.tools.solicitor.componentinfo.ComponentInfoProvider; - -/** - * A {@link ComponentInfoProvider} which provides uncurated {@link ComponentInfo}s. - * - */ -public interface UncuratedComponentInfoProvider extends ComponentInfoProvider { - -} \ No newline at end of file diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/model/ComponentInfoCuration.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/model/ComponentInfoCuration.java index bd84c95f..94e85453 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/model/ComponentInfoCuration.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/curation/model/ComponentInfoCuration.java @@ -21,6 +21,8 @@ public class ComponentInfoCuration { private List licenses; + private List excludedPaths; + /** * The constructor. */ @@ -108,4 +110,20 @@ public void setLicenses(List licenses) { this.licenses = licenses; } + /** + * @return excluded paths + */ + public List getExcludedPaths() { + + return this.excludedPaths; + } + + /** + * @param excludedPaths new value of {@link #getExcludedPaths}. + */ + public void setExcludedPaths(List excludedPaths) { + + this.excludedPaths = excludedPaths; + } + } diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/doc-files/componentinfo_classes.drawio.svg b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/doc-files/componentinfo_classes.drawio.svg index 07283864..1408ed23 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/doc-files/componentinfo_classes.drawio.svg +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/doc-files/componentinfo_classes.drawio.svg @@ -1,3 +1,3 @@ -
Curation data
Curation data
ComponentInfo data
ComponentInfo da...
«interface»
ComponentInfo
«interface»...
«interface»
LicenseInfo
«interface»...
DefaultComponentInfoImpl
DefaultComponentInfoImpl
DefaultLicenseInfoImpl
DefaultLicenseInfoImpl

<<Interface>>
ComponentInfoProvider


+ getComponentInfo(packageUrl): ComponentInfo


<<Interface>>...
«interface»
ComponentInfoAdapter
«interface»...
Extends
Extends
use
use


ComponentInfoInventoryProcessor

ComponentInfoInventoryProcessor
«interface»
UncuratedComponentInfoProvider
«interface»...
Extends
Extends


CuratingComponentInfoAdapter

CuratingComponentInfoAdapter

<<Interface>>
ComponentInfoCurator


+ curate(componentInfo): ComponentInfo

<<Interface>>...
Use
Use
Use
Use


ComponentInfoCuratorImpl

ComponentInfoCuratorImpl

<<Interface>>
CurationProvider


+ findCuration(packageUrl): ComponentInfoCuration

<<Interface>>...
Use
Use


SingleFileCurationProvider

SingleFileCurationProvider


ComponentInfoCuration

ComponentInfoCuration


LicenseInfoCuration

LicenseInfoCuration


ScancodeComponentInfoAdapter

ScancodeComponentInfoAdapter
Extends
Extends


UncuratedScancodeComponentInfoProvider

UncuratedScancodeComponentInfoProvider
Use
Use

<<Interface>>
ScancodeRawComponentInfoProvider


+ readScancodeData(packageUrl): ScancodeRawComponentInfo

+ pkgContentUriFromPath(packageUrl, path): String

+ isLocalContentPath(packageUrl, path): boolean

<<Interface>>...


FileScancodeRawComponentInfoProvider

FileScancodeRawComponentInfoProvider...
ScancodeComponentInfo
ScancodeComponentInfo
ScancodeLicenseInfo
ScancodeLicenseInfo
Package:
com.devonfw.tools.solictor.componentinfo.scancode
Package:com.devonfw.tools.solictor.componentinfo.sc...
Package:
com.devonfw.tools.solictor.componentinfo
Package:com.devonfw.tools.solictor.compo...
Package:
com.devonfw.tools.solictor.componentinfo.curation(.model)
Package:com.devonfw.tools.solictor.componentinfo.curatio...
Classes with thick line are instantiated as beans
Classes with thick line are instantiated as b...

<<Interface>>
ComponentContentProvider


+ retrieveContent(packageUrl, path) : String

<<Interface>>...
Extends
Extends
Use
Use
Viewer does not support full SVG 1.1
\ No newline at end of file +
Curation data
Curation data
ComponentInfo data
ComponentInfo da...
«interface»
ComponentInfo
«interface»...
«interface»
LicenseInfo
«interface»...
DefaultComponentInfoImpl
DefaultComponentInfoImpl
DefaultLicenseInfoImpl
DefaultLicenseInfoImpl

<<Interface>>
ComponentInfoProvider


+ getComponentInfo(packageUrl): ComponentInfo


<<Interface>>...
«interface»
ComponentInfoAdapter
«interface»...
Extends
Extends
use
use


ComponentInfoInventoryProcessor

ComponentInfoInventoryProcessor
«interface»
FilteredComponentInfoProvider
«interface»...
Extends
Extends


CuratingComponentInfoAdapter

CuratingComponentInfoAdapter

<<Interface>>
ComponentInfoCurator


+ curate(componentInfo): ComponentInfo

<<Interface>>...
Use
Use
Use
Use


ComponentInfoCuratorImpl

ComponentInfoCuratorImpl

<<Interface>>
CurationProvider


+ findCuration(packageUrl): ComponentInfoCuration

<<Interface>>...
Use
Use


SingleFileCurationProvider

SingleFileCurationProvider


ComponentInfoCuration

ComponentInfoCuration


LicenseInfoCuration

LicenseInfoCuration


ScancodeComponentInfoAdapter

ScancodeComponentInfoAdapter
Extends
Extends


FilteredScancodeComponentInfoProvider

FilteredScancodeComponentInfoProvider
Use
Use

<<Interface>>
ScancodeRawComponentInfoProvider


+ readScancodeData(packageUrl): ScancodeRawComponentInfo

+ pkgContentUriFromPath(packageUrl, path): String

+ isLocalContentPath(packageUrl, path): boolean

<<Interface>>...


FileScancodeRawComponentInfoProvider

FileScancodeRawComponentInfoProvider...
ScancodeComponentInfo
ScancodeComponentInfo
ScancodeLicenseInfo
ScancodeLicenseInfo
Package:
com.devonfw.tools.solictor.componentinfo.scancode
Package:com.devonfw.tools.solictor.componentinfo.sc...
Package:
com.devonfw.tools.solictor.componentinfo
Package:com.devonfw.tools.solictor.compo...
Package:
com.devonfw.tools.solictor.componentinfo.curation(.model)
Package:com.devonfw.tools.solictor.componentinfo.curatio...
Classes with thick line are instantiated as beans
Classes with thick line are instantiated as b...

<<Interface>>
ComponentContentProvider


+ retrieveContent(packageUrl, path) : String

<<Interface>>...
Extends
Extends
Use
Use
Use
Use
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java index dcd7fd79..75ad03c9 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FileScancodeRawComponentInfoProvider.java @@ -24,7 +24,7 @@ * */ @Component -public class FileScancodeRawComponentInfoProvider implements ScancodeRawComponentInfoPovider { +public class FileScancodeRawComponentInfoProvider implements ScancodeRawComponentInfoProvider { /** * The directory within the component root directory which contains the sources / the content diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/UncuratedScancodeComponentInfoProvider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProvider.java similarity index 78% rename from core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/UncuratedScancodeComponentInfoProvider.java rename to core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProvider.java index c4a95aba..59017573 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/UncuratedScancodeComponentInfoProvider.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProvider.java @@ -1,6 +1,7 @@ package com.devonfw.tools.solicitor.componentinfo.scancode; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.slf4j.Logger; @@ -12,7 +13,9 @@ import com.devonfw.tools.solicitor.common.LogMessages; import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler; import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; -import com.devonfw.tools.solicitor.componentinfo.curation.UncuratedComponentInfoProvider; +import com.devonfw.tools.solicitor.componentinfo.curation.CurationProvider; +import com.devonfw.tools.solicitor.componentinfo.curation.FilteredComponentInfoProvider; +import com.devonfw.tools.solicitor.componentinfo.curation.model.ComponentInfoCuration; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -20,18 +23,16 @@ import com.github.packageurl.PackageURL; /** - * {@link UncuratedComponentInfoProvider} which delivers data based on scancode data. + * {@link FilteredComponentInfoProvider} which delivers data based on scancode data. * */ @Component -public class UncuratedScancodeComponentInfoProvider implements UncuratedComponentInfoProvider { +public class FilteredScancodeComponentInfoProvider implements FilteredComponentInfoProvider { - private static final Logger LOG = LoggerFactory.getLogger(UncuratedScancodeComponentInfoProvider.class); + private static final Logger LOG = LoggerFactory.getLogger(FilteredScancodeComponentInfoProvider.class); private static final ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT); - private String repoBasePath; - private double minLicenseScore; private int minLicensefileNumberOfLines; @@ -40,34 +41,28 @@ public class UncuratedScancodeComponentInfoProvider implements UncuratedComponen private AllKindsPackageURLHandler packageURLHandler; - private ScancodeRawComponentInfoPovider fileScancodeRawComponentInfoProvider; + private ScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; + + private CurationProvider curationProvider; /** * The constructor. * * @param fileScancodeRawComponentInfoProvider the provide for the raw scancode data * @param packageURLHandler the handler for dealing with {@link PackageURL}s. + * @param curationProvider for getting the filter information used for filtering findings based on the paths in the + * code */ @Autowired - public UncuratedScancodeComponentInfoProvider(ScancodeRawComponentInfoPovider fileScancodeRawComponentInfoProvider, - AllKindsPackageURLHandler packageURLHandler) { + public FilteredScancodeComponentInfoProvider(ScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider, + AllKindsPackageURLHandler packageURLHandler, CurationProvider curationProvider) { this.fileScancodeRawComponentInfoProvider = fileScancodeRawComponentInfoProvider; this.packageURLHandler = packageURLHandler; + this.curationProvider = curationProvider; } - /** - * Sets repoBasePath. - * - * @param repoBasePath new value of repoBasePath. - */ - @Value("${solicitor.scancode.repo-base-path}") - public void setRepoBasePath(String repoBasePath) { - - this.repoBasePath = repoBasePath; - } - /** * Sets minLicenseScore. * @@ -109,7 +104,8 @@ public ScancodeComponentInfo getComponentInfo(String packageUrl, String curation return null; } - ScancodeComponentInfo componentScancodeInfos = parseAndMapScancodeJson(packageUrl, rawScancodeData); + ScancodeComponentInfo componentScancodeInfos = parseAndMapScancodeJson(packageUrl, rawScancodeData, + curationDataSelector); addSupplementedData(rawScancodeData, componentScancodeInfos); LOG.debug("Scancode info for package {}: {} license, {} copyrights, {} NOTICE files", packageUrl, componentScancodeInfos.getLicenses().size(), componentScancodeInfos.getCopyrights().size(), @@ -135,13 +131,22 @@ private void addSupplementedData(ScancodeRawComponentInfo rawScancodeData, * @return * @throws ComponentInfoAdapterException */ - private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, ScancodeRawComponentInfo rawScancodeData) - throws ComponentInfoAdapterException { + private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, ScancodeRawComponentInfo rawScancodeData, + String curationDataSelector) throws ComponentInfoAdapterException { ScancodeComponentInfo componentScancodeInfos = new ScancodeComponentInfo(this.minLicenseScore, this.minLicensefileNumberOfLines); componentScancodeInfos.setPackageUrl(packageUrl); + // Get the curation for a given packageUrl + ComponentInfoCuration componentInfoCuration = this.curationProvider.findCurations(packageUrl, curationDataSelector); + + // Get all excludedPaths in this curation + List excludedPaths = null; + if (componentInfoCuration != null) { + excludedPaths = componentInfoCuration.getExcludedPaths(); + } + JsonNode scancodeJson; try { scancodeJson = mapper.readTree(rawScancodeData.rawScancodeResult); @@ -149,14 +154,18 @@ private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, Scancod throw new ComponentInfoAdapterException("Could not parse Scancode JSON", e); } + // Skip all files, whose path have a prefix which is in the excluded path list for (JsonNode file : scancodeJson.get("files")) { + String path = file.get("path").asText(); + if (isExcluded(path, excludedPaths)) { + continue; + } if ("directory".equals(file.get("type").asText())) { continue; } - if (file.get("path").asText().contains("/NOTICE")) { - componentScancodeInfos.addNoticeFileUrl( - this.fileScancodeRawComponentInfoProvider.pkgContentUriFromPath(packageUrl, file.get("path").asText()), - 100.0); + if (path.contains("/NOTICE")) { + componentScancodeInfos + .addNoticeFileUrl(this.fileScancodeRawComponentInfoProvider.pkgContentUriFromPath(packageUrl, path), 100.0); } double licenseTextRatio = file.get("percentage_of_license_text").asDouble(); boolean takeCompleteFile = licenseTextRatio >= this.licenseToTextRatioToTakeCompleteFile; @@ -216,7 +225,7 @@ private ScancodeComponentInfo parseAndMapScancodeJson(String packageUrl, Scancod String licenseDefaultUrl = li.get("scancode_text_url").asText(); licenseDefaultUrl = normalizeLicenseUrl(packageUrl, licenseDefaultUrl); double score = li.get("score").asDouble(); - String licenseUrl = file.get("path").asText(); + String licenseUrl = path; int startLine = li.get("start_line").asInt(); int endLine = li.get("end_line").asInt(); if (!takeCompleteFile) { @@ -267,4 +276,22 @@ private String normalizeLicenseUrl(String packageUrl, String licenseUrl) { return adjustedLicenseUrl; } + /** + * Check if the given path prefix is excluded in the curation. + * + * @param path in the scancode data + * @param excludedPaths all excluded paths defined in the curation + * @return true if path prefix is excluded in curation + */ + private boolean isExcluded(String path, List excludedPaths) { + + if (excludedPaths != null) { + for (String excludedPath : excludedPaths) { + if (path.startsWith(excludedPath)) { + return true; + } + } + } + return false; + } } diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java index 92cebae3..151acd8c 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapter.java @@ -29,14 +29,14 @@ public class ScancodeComponentInfoAdapter extends CuratingComponentInfoAdapter { /** * The constructor. * - * @param uncuratedScancodeComponentInfoProvider provider for uncurated data originating from scancode data + * @param filteredScancodeComponentInfoProvider provider for filtered data originating from scancode data * @param componentInfoCurator the curator to use */ @Autowired - public ScancodeComponentInfoAdapter(UncuratedScancodeComponentInfoProvider uncuratedScancodeComponentInfoProvider, + public ScancodeComponentInfoAdapter(FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider, ComponentInfoCurator componentInfoCurator) { - super(uncuratedScancodeComponentInfoProvider, componentInfoCurator); + super(filteredScancodeComponentInfoProvider, componentInfoCurator); } /** diff --git a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeRawComponentInfoPovider.java b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeRawComponentInfoProvider.java similarity index 95% rename from core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeRawComponentInfoPovider.java rename to core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeRawComponentInfoProvider.java index 3bfc8ad6..46725130 100644 --- a/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeRawComponentInfoPovider.java +++ b/core/src/main/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeRawComponentInfoProvider.java @@ -7,7 +7,7 @@ * Provider for {@link ScancodeRawComponentInfo} * */ -public interface ScancodeRawComponentInfoPovider extends ComponentContentProvider { +public interface ScancodeRawComponentInfoProvider extends ComponentContentProvider { /** * Retrieve the {@link ScancodeRawComponentInfo} for the package given by its PackageURL. diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProviderTests.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProviderTests.java new file mode 100644 index 00000000..59fdb2a5 --- /dev/null +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/FilteredScancodeComponentInfoProviderTests.java @@ -0,0 +1,129 @@ +package com.devonfw.tools.solicitor.componentinfo.scancode; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.devonfw.tools.solicitor.common.content.web.DirectUrlWebContentProvider; +import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler; +import com.devonfw.tools.solicitor.componentinfo.ComponentInfoAdapterException; +import com.devonfw.tools.solicitor.componentinfo.curation.SingleFileCurationProvider; + +/** + * This class contains JUnit test methods for the {@link FilteredScancodeComponentInfoProvider} class. + */ +public class FilteredScancodeComponentInfoProviderTests { + + // the object under test + FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider; + + FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; + + SingleFileCurationProvider singleFileCurationProvider; + + @BeforeEach + public void setup() { + + AllKindsPackageURLHandler packageURLHandler = Mockito.mock(AllKindsPackageURLHandler.class); + + Mockito.when(packageURLHandler.pathFor("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0")) + .thenReturn("pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0"); + DirectUrlWebContentProvider contentProvider = new DirectUrlWebContentProvider(false); + + this.fileScancodeRawComponentInfoProvider = new FileScancodeRawComponentInfoProvider(contentProvider, + packageURLHandler); + this.fileScancodeRawComponentInfoProvider.setRepoBasePath("src/test/resources/scancodefileadapter/Source/repo"); + + this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + + this.filteredScancodeComponentInfoProvider = new FilteredScancodeComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, packageURLHandler, this.singleFileCurationProvider); + + } + + /** + * Test the {@link FilteredScancodeComponentInfoProvider#getComponentInfo(String,String)} method when no curations + * file exists + * + * @throws ComponentInfoAdapterException if something goes wrong + */ + @Test + public void testGetComponentInfoWithoutCurations() throws ComponentInfoAdapterException { + + // given + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/nonexisting.yaml"); + + // when + ScancodeComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", "someCurationSelector"); + + // then + assertNotNull(scancodeComponentInfo); + assertEquals("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + scancodeComponentInfo.getPackageUrl()); + assertEquals("This is a dummy notice file for testing. Code is under Apache-2.0.", + scancodeComponentInfo.getNoticeFileContent()); + assertEquals(1, scancodeComponentInfo.getCopyrights().size()); + assertEquals("Copyright 2023 devonfw", scancodeComponentInfo.getCopyrights().toArray()[0]); + } + + /** + * Test the {@link ScancodeComponentInfoAdapter#getComponentInfo(String,String)} method when the /src directory is + * excluded + * + * @throws ComponentInfoAdapterException if something goes wrong + */ + @Test + public void testGetComponentInfoWithCurationsAndExclusions() throws ComponentInfoAdapterException { + + // given + this.singleFileCurationProvider + .setCurationsFileName("src/test/resources/scancodefileadapter/curations_with_exclusions.yaml"); + // when + ScancodeComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", "someCurationSelector"); + + // then + assertNotNull(scancodeComponentInfo); + assertEquals("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + scancodeComponentInfo.getPackageUrl()); + assertEquals("This is a dummy notice file for testing. Code is under Apache-2.0.", + scancodeComponentInfo.getNoticeFileContent()); + assertEquals(0, scancodeComponentInfo.getCopyrights().size()); // since the copyright is found under + // /src/../SampleClass.java1, it will be excluded + } + + /** + * Test the {@link ScancodeComponentInfoAdapter#getComponentInfo(String,String)} method when curations exist but no + * paths are excluded + * + * @throws ComponentInfoAdapterException if something goes wrong + */ + @Test + public void testGetComponentInfoWithCurationsAndWithoutExclusions() throws ComponentInfoAdapterException { + + // given + this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + + // when + ScancodeComponentInfo scancodeComponentInfo = this.filteredScancodeComponentInfoProvider.getComponentInfo( + "pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", "someCurationSelector"); + + // then + assertNotNull(scancodeComponentInfo); + assertEquals("pkg:maven/com.devonfw.tools/test-project-for-deep-license-scan@0.1.0", + scancodeComponentInfo.getPackageUrl()); + assertEquals("This is a dummy notice file for testing. Code is under Apache-2.0.", + scancodeComponentInfo.getNoticeFileContent()); + assertEquals(1, scancodeComponentInfo.getCopyrights().size()); + assertEquals("Copyright 2023 devonfw", scancodeComponentInfo.getCopyrights().toArray()[0]); // The copyright + // curation does not + // apply on the + // scancodeComponentInfo + // object. + } +} diff --git a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java index 4d30fdcf..a090f35e 100644 --- a/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java +++ b/core/src/test/java/com/devonfw/tools/solicitor/componentinfo/scancode/ScancodeComponentInfoAdapterTest.java @@ -31,7 +31,7 @@ class ScancodeComponentInfoAdapterTest { // the object under test ScancodeComponentInfoAdapter scancodeComponentInfoAdapter; - UncuratedScancodeComponentInfoProvider uncuratedScancodeComponentInfoProvider; + FilteredScancodeComponentInfoProvider filteredScancodeComponentInfoProvider; FileScancodeRawComponentInfoProvider fileScancodeRawComponentInfoProvider; @@ -52,19 +52,18 @@ public void setup() { packageURLHandler); this.fileScancodeRawComponentInfoProvider.setRepoBasePath("src/test/resources/scancodefileadapter/Source/repo"); - this.uncuratedScancodeComponentInfoProvider = new UncuratedScancodeComponentInfoProvider( - this.fileScancodeRawComponentInfoProvider, packageURLHandler); - this.uncuratedScancodeComponentInfoProvider.setMinLicensefileNumberOfLines(5); - this.uncuratedScancodeComponentInfoProvider.setMinLicenseScore(90.0); - this.uncuratedScancodeComponentInfoProvider.setRepoBasePath("src/test/resources/scancodefileadapter/Source/repo"); - this.singleFileCurationProvider = new SingleFileCurationProvider(packageURLHandler); this.singleFileCurationProvider.setCurationsFileName("src/test/resources/scancodefileadapter/curations.yaml"); + this.filteredScancodeComponentInfoProvider = new FilteredScancodeComponentInfoProvider( + this.fileScancodeRawComponentInfoProvider, packageURLHandler, this.singleFileCurationProvider); + this.filteredScancodeComponentInfoProvider.setMinLicensefileNumberOfLines(5); + this.filteredScancodeComponentInfoProvider.setMinLicenseScore(90.0); + this.componentInfoCuratorImpl = new ComponentInfoCuratorImpl(this.singleFileCurationProvider, this.fileScancodeRawComponentInfoProvider); - this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter(this.uncuratedScancodeComponentInfoProvider, + this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter(this.filteredScancodeComponentInfoProvider, this.componentInfoCuratorImpl); this.scancodeComponentInfoAdapter.setFeatureFlag(true); @@ -152,7 +151,7 @@ public void testGetComponentCheckCurationDataSelector() throws ComponentInfoAdap this.componentInfoCuratorImpl = new ComponentInfoCuratorImpl(curationProvider, this.fileScancodeRawComponentInfoProvider); - this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter(this.uncuratedScancodeComponentInfoProvider, + this.scancodeComponentInfoAdapter = new ScancodeComponentInfoAdapter(this.filteredScancodeComponentInfoProvider, this.componentInfoCuratorImpl); this.scancodeComponentInfoAdapter.setFeatureFlag(true); diff --git a/core/src/test/resources/scancodefileadapter/curations_with_exclusions.yaml b/core/src/test/resources/scancodefileadapter/curations_with_exclusions.yaml new file mode 100644 index 00000000..3290c21a --- /dev/null +++ b/core/src/test/resources/scancodefileadapter/curations_with_exclusions.yaml @@ -0,0 +1,10 @@ +artifacts: +- name: "pkg/maven/com/devonfw/tools/test-project-for-deep-license-scan/0.1.0" + note: "some note on the curation" + url: "http://some/url" + licenses: + - license: MIT + url: https://some/license/url + excludedPaths: + - "sources/src" + - "foo" \ No newline at end of file diff --git a/documentation/master-solicitor.asciidoc b/documentation/master-solicitor.asciidoc index 16dbf29c..4cf1903e 100644 --- a/documentation/master-solicitor.asciidoc +++ b/documentation/master-solicitor.asciidoc @@ -1439,7 +1439,9 @@ artifacts: copyrights: <6> - (c) 2021 Donald Duck <7> - "(c) 2019 Mickey Mouse " <8> - - name: pkg/npm/@anotherscope/anotherpackage/4.5.6 <9> + excludedPaths: <9> + - "sources/src" <10> + - name: pkg/npm/@anotherscope/anotherpackage/4.5.6 <11> . . . @@ -1452,7 +1454,9 @@ artifacts: <6> Copyrights to set. Optional. If defined then all found copyrights will be replaced by the list of copyrights given here. <7> A single copyright. <8> Another copyright. Note that due to YAML syntax any string containing `:` needs to be enclosed with parentheses -<9> Further packages to follow. +<9> Excluded paths to be set. Optional. If defined then all scanned files, whose path prefix contain any given string here, are excluded from the ScanCode information. +<10> A single path prefix. All scanned files starting with this path prefix are excluded from the Scancode information. +<11> Further packages to follow. ==== Decision table rules As for license information obtained from the Readers the license information from ScanCode can also be altered using decision table rules. A new attribute `origin` was introduced in the `RawLicense` entity as well as condition field in decision table `LicenseAssignmentV2*.xls/csv`. The `origin` attribute in `Rawlicense` either contains the string `scancode` if the license information came from ScanCode or it contains the (lowercase) class name of the used Reader. @@ -1610,7 +1614,7 @@ Spring beans implementing this interface will be called at certain points in the [appendix] == Release Notes Changes in 1.15.0:: - +* https://github.com/devonfw/solicitor/issues/207: Add a new feature allowing the exclusion of paths and files of scanned artifacts from the Scancode information. Changes in 1.14.0:: * https://github.com/devonfw/solicitor/issues/202: Include parameter in CurationProvider.findCurations() to allow getting curation from alternative locations. * https://github.com/devonfw/solicitor/issues/190: Deprecate `repoType` attribute in configuration of readers.