Skip to content

Commit

Permalink
Feature/support r (#296)
Browse files Browse the repository at this point in the history
* add CranPackageURLHandlerImpl and test

* test/java/com/devonfw/tools/solicitor/common/packageurl/impl/CranPackageURLHandlerTests.java

* adapt

* improve java doc

* adaopt asciidoc

* adapt application.properties

* return URL of source archive also for the package url

---------

Co-authored-by: ohecker <[email protected]>
  • Loading branch information
mahmoudAlkam and ohecker authored Jan 6, 2025
1 parent ba468a4 commit 4873da9
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,25 @@ public static PackageURL fromPyPICoordinates(String name, String version) {
"The given PyPI coordinates '" + name + "'/'" + version + "' could not be converted to a package URL", e);
}
}

/**
* Create a {@link PackageURL} for the CRAN coordinates.
*
* @param name the package name
* @param version the version
* @return the created Package URL
*/
public static PackageURL fromCranCoordinates(String name, String version) {

PackageURLBuilder builder = PackageURLBuilder.aPackageURL().withType("cran");
builder.withName(name);
builder.withVersion(version);

try {
return builder.build();
} catch (MalformedPackageURLException e) {
throw new SolicitorRuntimeException(
"The given CRAN coordinates '" + name + "'/'" + version + "' could not be converted to a package URL", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.devonfw.tools.solicitor.common.packageurl.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.github.packageurl.PackageURL;

/**
* Specific handling of packageURLs of "cran" type.
*/
@Component
public class CranPackageURLHandlerImpl extends AbstractSingleKindPackageURLHandler {
private String repoBaseUrl;

/**
* The constructor.
*
* @param repoBaseUrl the repository base url
*/
@Autowired
public CranPackageURLHandlerImpl(@Value("${packageurls.cran.repobaseurl}") String repoBaseUrl) {

super();
// Sicherstellen, dass repoBaseUrl mit einem "/" endet
if (!repoBaseUrl.endsWith("/")) {
repoBaseUrl += "/";
}
this.repoBaseUrl = repoBaseUrl;
}

/**
* Determines if this handler can handle the given package URL.
*
* @param packageURL the package URL to check.
* @return true if the handler can handle the URL, false otherwise.
*/
@Override
public boolean canHandle(PackageURL packageURL) {

return "cran".equalsIgnoreCase(packageURL.getType());
}

/**
* Returns the source download URL for CRAN packages.
*
* @param purl the package URL.
* @return the source download URL.
*/
@Override
protected String doSourceDownloadUrlFor(PackageURL purl) {

StringBuilder sb = new StringBuilder(this.repoBaseUrl);
sb.append("src/contrib/");
sb.append(purl.getName());
sb.append("_").append(purl.getVersion());
sb.append(".tar.gz");
return sb.toString();
}

/**
* Returns the package download URL for CRAN packages.
*
* @param purl the package URL.
* @return the package download URL. This will return the archive of sources (same as
* {@link #doSourceDownloadUrlFor(PackageURL)}. There are pre-compiled binaries available on the server, but
* those are OS and version specific, so no universal binary.
*/
@Override
protected String doPackageDownloadUrlFor(PackageURL purl) {

StringBuilder sb = new StringBuilder(this.repoBaseUrl);
sb.append("src/contrib/");
sb.append(purl.getName());
sb.append("_").append(purl.getVersion());
sb.append(".tar.gz");
return sb.toString();
}

/**
* Returns the suffix for source archive files for CRAN packages.
*
* @param purl the package URL.
* @return the suffix for the source archive (".tar.gz").
*/
@Override
protected String doSourceArchiveSuffixFor(PackageURL purl) {

return "tar.gz";
}
}
2 changes: 2 additions & 0 deletions core/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ packageurls.npm.repobaseurl=https://registry.npmjs.org/
packageurls.pypi.repobaseurl=https://pypi.io/packages/
# Base URL for accessing nuget packages
packageurls.nuget.repobaseurl=https://www.nuget.org/api/v2/package/
# Base URL for accessing cran packages
packageurls.cran.repobaseurl=http://cran.r-project.org/

# the URL of the base config file
solicitor.base-config-url=classpath:com/devonfw/tools/solicitor/config/solicitor_base.cfg
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.devonfw.tools.solicitor.common.packageurl.impl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

/**
* Tests for {@link CranPackageURLHandlerImpl}
*
*/
class CranPackageURLHandlerTests {

@Test
void testSourceDownloadUrlFor() {

CranPackageURLHandlerImpl handler = new CranPackageURLHandlerImpl("http://test/");
assertEquals("http://test/src/contrib/someprod_4.5.35.tar.gz",
handler.sourceDownloadUrlFor("pkg:cran/[email protected]"));

}

@Test
void testPackageDownloadUrlFor() {

CranPackageURLHandlerImpl handler = new CranPackageURLHandlerImpl("http://test/");
assertEquals("http://test/src/contrib/someprod_4.5.35.tar.gz",
handler.packageDownloadUrlFor("pkg:cran/[email protected]"));

}

@Test
void testCanHandle() {

CranPackageURLHandlerImpl handler = new CranPackageURLHandlerImpl("http://test/");
assertTrue(handler.canHandle(handler.parse("pkg:cran/a@1")));
assertFalse(handler.canHandle(handler.parse("pkg:crana/a@1")));
}

@Test
void testSourceArchiveSuffixFor() {

CranPackageURLHandlerImpl handler = new CranPackageURLHandlerImpl("http://test/");
assertEquals("tar.gz", handler.sourceArchiveSuffixFor("pkg:cran/[email protected]"));
}

@Test
void testPathFor() {

CranPackageURLHandlerImpl handler = new CranPackageURLHandlerImpl("http://test/");
assertEquals("pkg/cran/someprod/4.5.35", handler.pathFor("pkg:cran/[email protected]"));
}
}
3 changes: 2 additions & 1 deletion documentation/master-solicitor.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -1033,7 +1033,7 @@ In Solicitor, the data is read with the following part of the config
} ]
----

NOTE: Currently, Solicitor only has packageUrlHandlers for maven, npm and pip. For all other package types, Solicitor will ignore the packageUrl.
NOTE: Currently, Solicitor only has packageUrlHandlers for maven, npm, R and pip. For all other package types, Solicitor will ignore the packageUrl.

== Working with Decision Tables

Expand Down Expand Up @@ -2155,6 +2155,7 @@ Spring beans implementing this interface will be called at certain points in the
[appendix]
== Release Notes
Changes in 1.31.0::
* https://github.com/devonfw/solicitor/issues/295: Add PackageUrlHandler for cran packages.

Changes in 1.30.0::
* https://github.com/devonfw/solicitor/pull/292: Improved the extraction of spdxids from spdx expressions when parsing ScanCode V32 result files. Previously the result might have contained empty strings to be returned as spdxids.
Expand Down

0 comments on commit 4873da9

Please sign in to comment.