Skip to content

Commit 1fa3c85

Browse files
stager-maven-plugin: list-files task
1 parent db58709 commit 1fa3c85

File tree

19 files changed

+663
-284
lines changed

19 files changed

+663
-284
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.helidon.build.common;
17+
18+
import java.util.Set;
19+
import java.util.regex.Pattern;
20+
import java.util.stream.Collectors;
21+
22+
/**
23+
* {@link Pattern} utility.
24+
*/
25+
public final class Patterns {
26+
27+
private static final Pattern NAMED_GROUP_PATTERN = Pattern.compile("\\(\\?<([^!=].*?)>");
28+
29+
private Patterns() {
30+
// cannot be instanciated
31+
}
32+
33+
/**
34+
* Get the group names defined in a regular expression.
35+
*
36+
* @param regex regular expression
37+
* @return group names
38+
*/
39+
public static Set<String> groupNames(String regex) {
40+
return NAMED_GROUP_PATTERN.matcher(regex)
41+
.results()
42+
.map(r -> r.group(1))
43+
.collect(Collectors.toSet());
44+
}
45+
}

common/common/src/main/java/io/helidon/build/common/SourcePath.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import java.util.Objects;
3232
import java.util.stream.Collectors;
3333

34+
import static io.helidon.build.common.Strings.normalizePath;
35+
3436
/**
3537
* Utility class to parse and match path segments.
3638
*/
@@ -62,7 +64,16 @@ public SourcePath(File dir, File file) {
6264
* @param file the filed contained in the directory
6365
*/
6466
public SourcePath(Path dir, Path file) {
65-
segments = parseSegments(getRelativePath(dir, file));
67+
this(dir.relativize(file));
68+
}
69+
70+
/**
71+
* Create a new {@link SourcePath} instance for the given path.
72+
*
73+
* @param path the path to use
74+
*/
75+
public SourcePath(Path path) {
76+
this(normalizePath(path));
6677
}
6778

6879
/**
@@ -95,10 +106,6 @@ public SourcePath(List<String> paths) {
95106
.toArray(String[]::new);
96107
}
97108

98-
private static String getRelativePath(Path sourceDir, Path source) {
99-
return Strings.normalizePath(sourceDir.relativize(source));
100-
}
101-
102109
/**
103110
* Parse a {@code '/'} separated path into segments. Collapses empty or {@code '.'} only segments.
104111
*

maven-plugins/stager-maven-plugin/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<packaging>maven-plugin</packaging>
3232

3333
<properties>
34+
<maven.compiler.release>17</maven.compiler.release>
3435
<spotbugs.exclude>etc/spotbugs/exclude.xml</spotbugs.exclude>
3536
</properties>
3637

maven-plugins/stager-maven-plugin/src/it/projects/file/pom.xml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!--
22
3-
Copyright (c) 2020, 2022 Oracle and/or its affiliates.
3+
Copyright (c) 2020, 2023 Oracle and/or its affiliates.
44
55
Licensed under the Apache License, Version 2.0 (the "License");
66
you may not use this file except in compliance with the License.
@@ -43,6 +43,24 @@
4343
<files>
4444
<file target="CNAME">${cname}</file>
4545
<file target="cli-data/latest">${cli.data.latest.version}</file>
46+
<file target="docs/v4/index.html"/>
47+
<file target="docs/v4/apidocs/index.html"/>
48+
<file target="docs/v4/images/foo.svg"/>
49+
<file target="sitemap.txt">
50+
<list-files dir=".">
51+
<includes>
52+
<include>**/docs/**</include>
53+
</includes>
54+
<excludes>
55+
<exclude>**/images/**</exclude>
56+
</excludes>
57+
<substitutions>
58+
<substitution
59+
match="^(?&lt;path&gt;([^/]+/)*)index.html$"
60+
replace="{path}" />
61+
</substitutions>
62+
</list-files>
63+
</file>
4664
</files>
4765
</directory>
4866
</directories>

maven-plugins/stager-maven-plugin/src/main/java/io/helidon/build/maven/stager/ConfigReader.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,10 +16,10 @@
1616
package io.helidon.build.maven.stager;
1717

1818
import java.util.ArrayDeque;
19+
import java.util.ArrayList;
1920
import java.util.Deque;
2021
import java.util.HashMap;
2122
import java.util.LinkedHashMap;
22-
import java.util.LinkedList;
2323
import java.util.List;
2424
import java.util.Map;
2525

@@ -62,28 +62,26 @@ public void visitNode(PlexusConfigNode node) {
6262

6363
@Override
6464
public void postVisitNode(PlexusConfigNode node) {
65-
PlexusConfigNode nodeParent = node.parent();
66-
String nodeName = node.name();
65+
PlexusConfigNode parent = node.parent();
66+
String name = node.name();
6767
mappings.computeIfAbsent(node, n -> new LinkedHashMap<>());
68-
mappings.computeIfAbsent(nodeParent, n -> new LinkedHashMap<>());
68+
mappings.computeIfAbsent(parent, n -> new LinkedHashMap<>());
6969
Scope scope = scopes.peek();
7070
if (scope == null) {
7171
throw new IllegalStateException("Scope is not available");
7272
}
73-
StagingElement element = factory.create(
74-
nodeName,
75-
node.attributes(),
76-
mappings.get(node),
77-
node.value(),
78-
scope);
79-
if (element instanceof Variables) {
80-
for (Variable variable : ((Variables) element)) {
73+
StagingElement element = factory.create(name, node.attributes(), mappings.get(node), node.value(), scope);
74+
if (element instanceof Variables variables) {
75+
for (Variable variable : variables) {
8176
scope.parent.variables.put(variable.name(), variable);
8277
}
8378
}
84-
mappings.get(nodeParent)
85-
.computeIfAbsent(nodeName, n -> new LinkedList<>())
86-
.add(element);
79+
List<StagingElement> siblings = mappings.get(parent).computeIfAbsent(name, n -> new ArrayList<>());
80+
if (element instanceof StagingElements elements) {
81+
siblings.addAll(elements.nested());
82+
} else {
83+
siblings.add(element);
84+
}
8785
scopes.pop();
8886
}
8987

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.helidon.build.maven.stager;
17+
18+
/**
19+
* Exclude.
20+
*/
21+
record Exclude(String value) implements StagingElement {
22+
23+
static final String ELEMENT_NAME = "exclude";
24+
25+
@Override
26+
public String elementName() {
27+
return ELEMENT_NAME;
28+
}
29+
}

maven-plugins/stager-maven-plugin/src/main/java/io/helidon/build/maven/stager/FileTask.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,9 +15,11 @@
1515
*/
1616
package io.helidon.build.maven.stager;
1717

18+
import java.io.BufferedWriter;
1819
import java.io.IOException;
1920
import java.nio.file.Files;
2021
import java.nio.file.Path;
22+
import java.util.List;
2123
import java.util.Map;
2224

2325
/**
@@ -30,8 +32,8 @@ final class FileTask extends StagingTask {
3032
private final String content;
3133
private final String source;
3234

33-
FileTask(ActionIterators iterators, Map<String, String> attrs, String content) {
34-
super(ELEMENT_NAME, null, iterators, attrs);
35+
FileTask(ActionIterators iterators, List<TextAction> nested, Map<String, String> attrs, String content) {
36+
super(ELEMENT_NAME, nested, iterators, attrs);
3537
this.content = content;
3638
this.source = attrs.get("source");
3739
}
@@ -50,10 +52,16 @@ String source() {
5052
*
5153
* @return content, may be {@code null}
5254
*/
53-
public String content() {
55+
String content() {
5456
return content;
5557
}
5658

59+
@Override
60+
@SuppressWarnings("unchecked")
61+
List<TextAction> tasks() {
62+
return (List<TextAction>) super.tasks();
63+
}
64+
5765
@Override
5866
protected void doExecute(StagingContext ctx, Path dir, Map<String, String> vars) throws IOException {
5967
String resolvedTarget = resolveVar(target(), vars);
@@ -72,6 +80,12 @@ protected void doExecute(StagingContext ctx, Path dir, Map<String, String> vars)
7280
Files.createFile(targetFile);
7381
if (resolvedContent != null && !resolvedContent.isEmpty()) {
7482
Files.writeString(targetFile, resolvedContent);
83+
} else {
84+
try (BufferedWriter writer = Files.newBufferedWriter(targetFile)) {
85+
for (TextAction task : tasks()) {
86+
writer.write(task.text());
87+
}
88+
}
7589
}
7690
}
7791
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.helidon.build.maven.stager;
17+
18+
/**
19+
* Include.
20+
*/
21+
record Include(String value) implements StagingElement {
22+
23+
static final String ELEMENT_NAME = "include";
24+
25+
@Override
26+
public String elementName() {
27+
return ELEMENT_NAME;
28+
}
29+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.helidon.build.maven.stager;
17+
18+
import java.nio.file.Path;
19+
import java.util.List;
20+
import java.util.Map;
21+
import java.util.function.BiFunction;
22+
23+
import io.helidon.build.common.Lists;
24+
import io.helidon.build.common.SourcePath;
25+
26+
import static io.helidon.build.common.FileUtils.walk;
27+
import static io.helidon.build.common.Strings.normalizePath;
28+
29+
/**
30+
* List files in a directory.
31+
*/
32+
final class ListFilesTask extends StagingTask implements TextAction {
33+
34+
static final String ELEMENT_NAME = "list-files";
35+
36+
private final List<String> includes;
37+
private final List<String> excludes;
38+
private final List<Substitution> substitutions;
39+
private final List<BiFunction<String, Map<String, String>, String>> chain;
40+
private final String dirName;
41+
private final StringBuilder buf = new StringBuilder();
42+
43+
ListFilesTask(ActionIterators iterators,
44+
List<Include> includes,
45+
List<Exclude> excludes,
46+
List<Substitution> substitutions,
47+
Map<String, String> attrs) {
48+
49+
super(ELEMENT_NAME, null, iterators, attrs);
50+
this.includes = Lists.map(includes, Include::value);
51+
this.excludes = Lists.map(excludes, Exclude::value);
52+
this.substitutions = substitutions;
53+
this.chain = Lists.map(substitutions, Substitution::function);
54+
this.dirName = attrs.getOrDefault("dir", ".");
55+
}
56+
57+
@Override
58+
public String text() {
59+
return buf.toString();
60+
}
61+
62+
List<String> includes() {
63+
return includes;
64+
}
65+
66+
List<String> excludes() {
67+
return excludes;
68+
}
69+
70+
List<Substitution> substitutions() {
71+
return substitutions;
72+
}
73+
74+
@Override
75+
protected void doExecute(StagingContext ctx, Path dir, Map<String, String> vars) {
76+
Path resolved = dir.resolve(dirName);
77+
List<Path> files = walk(resolved, (p, a) -> p.equals(resolved) || new SourcePath(p).matches(includes, excludes));
78+
for (Path file : files) {
79+
String entry = normalizePath(dir.relativize(file));
80+
for (var function : chain) {
81+
entry = function.apply(entry, vars);
82+
}
83+
buf.append(entry).append("\n");
84+
}
85+
}
86+
}

0 commit comments

Comments
 (0)