Skip to content

Commit

Permalink
Add an "unpack" task to the stager-maven-plugin (#1073)
Browse files Browse the repository at this point in the history
Download an unpack an archive from a URL.
  • Loading branch information
romain-grecourt authored Oct 7, 2024
1 parent 5b67c5a commit 53bd7fc
Show file tree
Hide file tree
Showing 14 changed files with 338 additions and 51 deletions.
13 changes: 11 additions & 2 deletions common/common/src/main/java/io/helidon/build/common/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public final class FileUtils {
*/
public static Path requiredDirectoryFromProperty(String systemPropertyName, boolean createIfRequired) {
final String path = Requirements.requireNonNull(System.getProperty(systemPropertyName),
"Required system property %s not set", systemPropertyName);
"Required system property %s not set", systemPropertyName);
return requiredDirectory(path, createIfRequired);
}

Expand Down Expand Up @@ -1006,7 +1006,16 @@ public static Path resourceAsPath(String path, Class<?> clazz) throws IllegalArg
* @return extension or {@code null}
*/
public static String fileExt(Path file) {
String filename = file.getFileName().toString();
return fileExt(file.getFileName().toString());
}

/**
* Get the file extension for the given file name.
*
* @param filename file name
* @return extension or {@code null}
*/
public static String fileExt(String filename) {
int index = filename.lastIndexOf(".");
return index < 0 ? null : filename.substring(index + 1);
}
Expand Down
23 changes: 22 additions & 1 deletion maven-plugins/stager-maven-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,33 @@ The above parameters are mapped to user properties of the form `stager.PROPERTY`
<!-- ... -->
</unpack-artifacts>

<!-- unpacks is a container of unpack tasks -->
<unpacks>

<!-- a task to download and unpack a file (.jar, .zip) -->
<unpack-artifact
url="https://download.acme.com/{version}/acme-site.jar"
target="docs/{version}"
>
<!-- iterators can be nested under any task to create a loop -->
<iterators>
<variables>
<!-- the version variable is referenced using {version} in the task definition -->
<variable name="version">
<value>1.2.3</value>
</variable>
</variables>
</iterators>
</unpack-artifact>
<!-- ... -->
</unpacks>

<!-- downloads is a container of download tasks -->
<downloads>

<!-- a task to download files -->
<download
url="http://download.acme.com/{version}/cli-{platform}-amd64"
url="https://download.acme.com/{version}/cli-{platform}-amd64"
target="cli/{version}/{platform}/acme"
>
<iterators>
Expand Down
8 changes: 7 additions & 1 deletion maven-plugins/stager-maven-plugin/etc/spotbugs/exclude.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2022 Oracle and/or its affiliates.
Copyright (c) 2022, 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -58,4 +58,10 @@
<Bug pattern="PATH_TRAVERSAL_IN"/>
</Match>

<Match>
<!-- This API reads a file whose location might be specified by user input -->
<Class name="io.helidon.build.maven.stager.StagingContext"/>
<Bug pattern="PATH_TRAVERSAL_IN"/>
</Match>

</FindBugsFilter>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!--
Copyright (c) 2020, 2022 Oracle and/or its affiliates.
Copyright (c) 2020, 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -22,7 +22,7 @@
<groupId>io.helidon.build-tools.stager.tests</groupId>
<artifactId>unpack</artifactId>
<version>@project.version@</version>
<name>Test Stager Unpack task</name>
<name>Test Stager Unpack Artifact task</name>
<packaging>pom</packaging>

<properties>
Expand Down
73 changes: 73 additions & 0 deletions maven-plugins/stager-maven-plugin/src/it/projects/unpack/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!--
Copyright (c) 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.helidon.build-tools.stager.tests</groupId>
<artifactId>unpack</artifactId>
<version>@project.version@</version>
<name>Test Stager Unpack task</name>
<packaging>pom</packaging>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>io.helidon.build-tools</groupId>
<artifactId>helidon-stager-maven-plugin</artifactId>
<version>${project.version}</version>
<configuration>
<directories>
<directory target="${project.build.directory}/stage">
<unpacks>
<unpack url="https://repo1.maven.org/maven2/io/helidon/helidon-project/{version}/helidon-project-{version}-site.jar"
excludes="META-INF/**"
target="docs/{version}">
<iterators>
<variables>
<variable name="version">
<value>3.2.10</value>
<value>3.2.9</value>
</variable>
</variables>
</iterators>
</unpack>
</unpacks>
</directory>
</directories>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>io.helidon.build-tools</groupId>
<artifactId>helidon-stager-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<goals>
<goal>stage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import io.helidon.build.common.test.utils.JUnitLauncher
import io.helidon.build.maven.stager.ProjectsTestIT

//noinspection GroovyAssignabilityCheck,GrUnresolvedAccess
JUnitLauncher.builder()
.select(ProjectsTestIT.class, "testUnpack", String.class)
.parameter("basedir", basedir.getAbsolutePath())
.reportsDir(basedir)
.outputFile(new File(basedir, "test.log"))
.suiteId("stager-unpack-it-test")
.suiteDisplayName("Stager Unpack Integration Test")
.build()
.launch()
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,24 @@ protected CompletableFuture<Void> execBody(StagingContext ctx, Path dir, Map<Str

@Override
protected void doExecute(StagingContext ctx, Path dir, Map<String, String> vars) throws IOException {
download(ctx, dir, vars);
}

private void download(StagingContext ctx, Path dir, Map<String, String> vars) throws IOException {
String path = resolveVar(target(), vars);
Path file = dir.resolve(path).normalize();
ensureDirectory(file.getParent());
URL url = new URL(resolveVar(this.url, vars));
download(ctx, url, file);
}

/**
* Download a file.
*
* @param ctx staging context
* @param url url
* @param file target file
* @throws IOException if an IO error occurs
*/
static void download(StagingContext ctx, URL url, Path file)
throws IOException {

try (BufferedInputStream bis = new BufferedInputStream(open(url, ctx))) {
try (OutputStream fos = Files.newOutputStream(file)) {
int n;
Expand All @@ -86,19 +96,19 @@ private void download(StagingContext ctx, Path dir, Map<String, String> vars) th
totalTime = (currentTime - startTime) / 1000;
progressTime = currentTime;
ctx.logInfo("Downloading %s to %s (%s at %s/s)",
url, path, measuredSize(totalSize), measuredSize(totalSize / totalTime));
url, file, measuredSize(totalSize), measuredSize(totalSize / totalTime));
}
}
if (currentTime - progressTime >= 1000) {
totalTime = (currentTime - startTime) / 1000;
}
ctx.logInfo("Downloaded %s to %s (%s at %s/s)",
url, path, measuredSize(totalSize), measuredSize(totalSize / totalTime));
url, file, measuredSize(totalSize), measuredSize(totalSize / totalTime));
}
}
}

private InputStream open(URL url, StagingContext context) throws IOException {
private static InputStream open(URL url, StagingContext context) throws IOException {
NetworkConnection.Builder builder = NetworkConnection.builder().url(url);
int readTimeout = context.readTimeout();
if (readTimeout > 0) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
* Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -101,6 +101,17 @@ default Path createTempDirectory(String prefix) throws IOException {
return Files.createTempDirectory(prefix);
}

/**
* Create a temporary file.
*
* @param suffix suffix
* @return created file
* @throws IOException if an IO error occurs
*/
default Path createTempFile(String suffix) throws IOException {
return Files.createTempFile(null, suffix);
}

/**
* Log an info message.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates.
* Copyright (c) 2022, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -80,17 +80,17 @@ final class StagingContextImpl implements StagingContext {
this.archiverManager = Objects.requireNonNull(archiverManager, "archiverManager is null");
this.executor = executor;
this.readTimeout = Optional.ofNullable(propertyResolver.apply(StagingContext.READ_TIMEOUT_PROP))
.map(Integer::parseInt)
.orElse(-1);
.map(Integer::parseInt)
.orElse(-1);
this.connectTimeout = Optional.ofNullable(propertyResolver.apply(StagingContext.CONNECT_TIMEOUT_PROP))
.map(Integer::parseInt)
.orElse(-1);
.map(Integer::parseInt)
.orElse(-1);
this.taskTimeout = Optional.ofNullable(propertyResolver.apply(StagingContext.TASK_TIMEOUT_PROP))
.map(Integer::parseInt)
.orElse(-1);
.map(Integer::parseInt)
.orElse(-1);
this.maxRetries = Optional.ofNullable(propertyResolver.apply(StagingContext.MAX_RETRIES))
.map(Integer::parseInt)
.orElse(-1);
.map(Integer::parseInt)
.orElse(-1);
}

@Override
Expand All @@ -110,7 +110,7 @@ public void unpack(Path archive, Path target, String excludes, String includes)
unArchiver.setSourceFile(archiveFile);
unArchiver.setDestDirectory(target.toFile());
if (StringUtils.isNotEmpty(excludes) || StringUtils.isNotEmpty(includes)) {
IncludeExcludeFileSelector[] selectors = new IncludeExcludeFileSelector[]{
IncludeExcludeFileSelector[] selectors = new IncludeExcludeFileSelector[] {
new IncludeExcludeFileSelector()
};
if (StringUtils.isNotEmpty(excludes)) {
Expand Down Expand Up @@ -177,6 +177,11 @@ public Path createTempDirectory(String prefix) throws IOException {
return Files.createTempDirectory(outputDir.toPath(), prefix);
}

@Override
public Path createTempFile(String suffix) throws IOException {
return Files.createTempFile(outputDir.toPath(), null, suffix);
}

@Override
public void logInfo(String msg, Object... args) {
log.info(String.format(msg, args));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class StagingElementFactory {
FileTask.ELEMENT_NAME,
SymlinkTask.ELEMENT_NAME,
TemplateTask.ELEMENT_NAME,
UnpackTask.ELEMENT_NAME,
UnpackArtifactTask.ELEMENT_NAME,
ListFilesTask.ELEMENT_NAME);

Expand Down Expand Up @@ -98,6 +99,8 @@ StagingAction createAction(String name,
switch (name) {
case StagingDirectory.ELEMENT_NAME:
return new StagingDirectory(filterChildren(children, StagingAction.class), attrs);
case UnpackTask.ELEMENT_NAME:
return new UnpackTask(iterators.get(), attrs);
case UnpackArtifactTask.ELEMENT_NAME:
return new UnpackArtifactTask(iterators.get(), attrs);
case CopyArtifactTask.ELEMENT_NAME:
Expand Down
Loading

0 comments on commit 53bd7fc

Please sign in to comment.