You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2022/12/19 10:21:16 UTC
[logging-log4j2] 10/33: LOG4J2-3628 Add releaser.
This is an automated email from the ASF dual-hosted git repository.
vy pushed a commit to branch mvn-site-simplified
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 6a235f169f3921ef2d0771c7cb7666f31e354e1a
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Wed Nov 23 19:19:57 2022 +0100
LOG4J2-3628 Add releaser.
---
.../logging/log4j/internal/util/AsciiDocUtils.java | 40 ++++++++++
.../logging/log4j/internal/util/XmlReader.java | 28 +++++++
.../internal/util/changelog/ChangelogEntry.java | 34 +++-----
.../internal/util/changelog/ChangelogFiles.java | 22 +++++
.../util/changelog/exporter/AsciiDocExporter.java | 87 ++++++++++----------
.../util/changelog/importer/MavenChanges.java | 8 +-
.../changelog/importer/MavenChangesImporter.java | 7 +-
.../util/changelog/releaser/ChangelogReleaser.java | 93 ++++++++++++++++++++++
.../ChangelogReleaserArgs.java} | 24 +++---
src/site/asciidoc/changelog/index.adoc | 1 +
src/site/asciidoc/changelog/unreleased.adoc | 35 ++++++++
11 files changed, 294 insertions(+), 85 deletions(-)
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/AsciiDocUtils.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/AsciiDocUtils.java
new file mode 100644
index 0000000000..91cfb41ac1
--- /dev/null
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/AsciiDocUtils.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * https://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.
+ */
+package org.apache.logging.log4j.internal.util;
+
+public final class AsciiDocUtils {
+
+ public static final String LICENSE_COMMENT_BLOCK = "////\n" +
+ " Licensed to the Apache Software Foundation (ASF) under one or more\n" +
+ " contributor license agreements. See the NOTICE file distributed with\n" +
+ " this work for additional information regarding copyright ownership.\n" +
+ " The ASF licenses this file to You under the Apache License, Version 2.0\n" +
+ " (the \"License\"); you may not use this file except in compliance with\n" +
+ " the License. You may obtain a copy of the License at\n" +
+ "\n" +
+ " https://www.apache.org/licenses/LICENSE-2.0\n" +
+ "\n" +
+ " Unless required by applicable law or agreed to in writing, software\n" +
+ " distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
+ " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
+ " See the License for the specific language governing permissions and\n" +
+ " limitations under the License.\n" +
+ "////\n";
+
+ private AsciiDocUtils() {}
+
+}
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/XmlReader.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/XmlReader.java
index 35650ed1ba..33c649b4cf 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/XmlReader.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/XmlReader.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.internal.util;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -27,6 +28,10 @@ import javax.xml.parsers.SAXParserFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Path;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
/**
* A SAX2-based XML reader.
@@ -64,6 +69,29 @@ public final class XmlReader {
return document;
}
+ public static Stream<Element> childElementsMatchingName(final Element parentElement, final String childElementName) {
+ final NodeList childNodes = parentElement.getChildNodes();
+ return IntStream
+ .range(0, childNodes.getLength())
+ .mapToObj(childNodes::item)
+ .filter(childNode -> childNode.getNodeType() == Node.ELEMENT_NODE && childElementName.equals(childNode.getNodeName()))
+ .map(childNode -> (Element) childNode);
+ }
+
+ public static Element childElementMatchingName(final Element parentElement, final String childElementName) {
+ final List<Element> childElements = childElementsMatchingName(parentElement, childElementName)
+ .collect(Collectors.toList());
+ final int childElementCount = childElements.size();
+ if (childElementCount != 1) {
+ throw failureAtXmlNode(
+ parentElement,
+ "was expecting a single `%s` element, found: %d",
+ childElementName,
+ childElementCount);
+ }
+ return childElements.get(0);
+ }
+
public static String requireAttribute(final Element element, final String attributeName) {
if (!element.hasAttribute(attributeName)) {
throw failureAtXmlNode(element, "missing attribute: `%s`", attributeName);
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogEntry.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogEntry.java
index fb2bac38d2..f04f2a59a4 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogEntry.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogEntry.java
@@ -19,13 +19,11 @@ package org.apache.logging.log4j.internal.util.changelog;
import org.apache.logging.log4j.internal.util.XmlReader;
import org.apache.logging.log4j.internal.util.XmlWriter;
import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
import java.nio.file.Path;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
-import java.util.stream.IntStream;
import static org.apache.logging.log4j.internal.util.StringUtils.trimNullable;
@@ -165,12 +163,9 @@ public final class ChangelogEntry {
}
// Read the `issue` elements.
- final NodeList issueElements = entryElement.getElementsByTagName("issue");
- final int issueCount = issueElements.getLength();
- final List<Issue> issues = IntStream
- .range(0, issueCount)
- .mapToObj(issueIndex -> {
- final Element issueElement = (Element) issueElements.item(issueIndex);
+ final List<Issue> issues = XmlReader
+ .childElementsMatchingName(entryElement, "issue")
+ .map(issueElement -> {
final String issueId = XmlReader.requireAttribute(issueElement, "id");
final String issueLink = XmlReader.requireAttribute(issueElement, "link");
return new Issue(issueId, issueLink);
@@ -178,15 +173,9 @@ public final class ChangelogEntry {
.collect(Collectors.toList());
// Read the `author` elements.
- final NodeList authorElements = entryElement.getElementsByTagName("author");
- final int authorCount = authorElements.getLength();
- if (authorCount < 1) {
- throw XmlReader.failureAtXmlNode(entryElement, "no `author` elements found");
- }
- final List<Author> authors = IntStream
- .range(0, authorCount)
- .mapToObj(authorIndex -> {
- final Element authorElement = (Element) authorElements.item(authorIndex);
+ final List<Author> authors = XmlReader
+ .childElementsMatchingName(entryElement, "author")
+ .map(authorElement -> {
final String authorId = authorElement.hasAttribute("id")
? authorElement.getAttribute("id")
: null;
@@ -196,15 +185,12 @@ public final class ChangelogEntry {
return new Author(authorId, authorName);
})
.collect(Collectors.toList());
+ if (authors.isEmpty()) {
+ throw XmlReader.failureAtXmlNode(entryElement, "no `author` elements found");
+ }
// Read the `description` element.
- final NodeList descriptionElements = entryElement.getElementsByTagName("description");
- final int descriptionCount = descriptionElements.getLength();
- if (descriptionCount != 1) {
- throw XmlReader.failureAtXmlNode(
- entryElement, "was expecting a single `description` element, found: %d", descriptionCount);
- }
- final Element descriptionElement = (Element) descriptionElements.item(0);
+ final Element descriptionElement = XmlReader.childElementMatchingName(entryElement, "description");
final String descriptionFormat = XmlReader.requireAttribute(descriptionElement, "format");
final String descriptionText = trimNullable(descriptionElement.getTextContent());
final Description description = new Description(descriptionFormat, descriptionText);
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java
index fc0b05aab6..92a2b94bef 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java
@@ -26,6 +26,28 @@ public final class ChangelogFiles {
return projectRootDirectory.resolve("changelog");
}
+ public static Path unreleasedDirectory(final Path projectRootDirectory) {
+ return changelogDirectory(projectRootDirectory).resolve(".unreleased");
+ }
+
+ public static Path releaseDirectory(
+ final Path projectRootDirectory,
+ final String releaseDate,
+ final String releaseVersion) {
+ if (!releaseDate.matches("^\\d{8}$")) {
+ final String message = String.format(
+ "was expecting release date to be formatted as `YYYYmmdd`, found: `%s`", releaseDate);
+ throw new IllegalArgumentException(message);
+ }
+ if (!releaseVersion.matches("^\\d+\\.\\d+\\.\\d+$")) {
+ final String message = String.format(
+ "was expecting release version to be formatted as `0.1.2`, found: `%s`", releaseVersion);
+ throw new IllegalArgumentException(message);
+ }
+ final String releaseDirectoryName = String.format("%s-%s", releaseDate, releaseVersion);
+ return changelogDirectory(projectRootDirectory).resolve(releaseDirectoryName);
+ }
+
public static Path releaseXmlFile(final Path releaseDirectory) {
return releaseDirectory.resolve(".release.xml");
}
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/exporter/AsciiDocExporter.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/exporter/AsciiDocExporter.java
index 3311fe78b7..380c6f8f57 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/exporter/AsciiDocExporter.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/exporter/AsciiDocExporter.java
@@ -16,6 +16,7 @@
*/
package org.apache.logging.log4j.internal.util.changelog.exporter;
+import org.apache.logging.log4j.internal.util.AsciiDocUtils;
import org.apache.logging.log4j.internal.util.changelog.ChangelogEntry;
import org.apache.logging.log4j.internal.util.changelog.ChangelogFiles;
import org.apache.logging.log4j.internal.util.changelog.ChangelogRelease;
@@ -48,23 +49,6 @@ public final class AsciiDocExporter {
}
});
- private static final String LICENSE_HEADER_ASCIIDOC = "////\n" +
- " Licensed to the Apache Software Foundation (ASF) under one or more\n" +
- " contributor license agreements. See the NOTICE file distributed with\n" +
- " this work for additional information regarding copyright ownership.\n" +
- " The ASF licenses this file to You under the Apache License, Version 2.0\n" +
- " (the \"License\"); you may not use this file except in compliance with\n" +
- " the License. You may obtain a copy of the License at\n" +
- "\n" +
- " https://www.apache.org/licenses/LICENSE-2.0\n" +
- "\n" +
- " Unless required by applicable law or agreed to in writing, software\n" +
- " distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
- " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
- " See the License for the specific language governing permissions and\n" +
- " limitations under the License.\n" +
- "////\n";
-
private static final String AUTO_GENERATION_WARNING_ASCIIDOC = "////\n" +
"*DO NOT EDIT THIS FILE!!*\n" +
"This file is automatically generated from the release changelog directory!\n" +
@@ -80,6 +64,7 @@ public final class AsciiDocExporter {
// Find release directories.
final Path changelogDirectory = ChangelogFiles.changelogDirectory(args.projectRootDirectory);
final List<Path> releaseDirectories = findAdjacentFiles(changelogDirectory)
+ .filter(file -> file.toFile().isDirectory())
.sorted()
.collect(Collectors.toList());
final int releaseDirectoryCount = releaseDirectories.size();
@@ -121,6 +106,9 @@ public final class AsciiDocExporter {
}
+ // Export unreleased.
+ exportUnreleased(args.projectRootDirectory);
+
// Export the release index.
exportReleaseIndex(args.projectRootDirectory, changelogReleases);
@@ -164,24 +152,14 @@ public final class AsciiDocExporter {
final Path projectRootDirectory,
final Path releaseDirectory,
final ChangelogRelease changelogRelease) {
-
- // Read the changelog intro.
final String introAsciiDoc = readIntroAsciiDoc(releaseDirectory);
-
- // Read the changelog entries.
- final List<ChangelogEntry> changelogEntries = findAdjacentFiles(releaseDirectory)
- .sorted(FILE_MODIFICATION_TIME_COMPARATOR)
- .map(ChangelogEntry::readFromXmlFile)
- .collect(Collectors.toList());
-
- // Export the release.
+ final List<ChangelogEntry> changelogEntries = readChangelogEntries(releaseDirectory);
try {
exportRelease(projectRootDirectory, changelogRelease, introAsciiDoc, changelogEntries);
} catch (final IOException error) {
final String message = String.format("failed exporting release from directory `%s`", releaseDirectory);
throw new UncheckedIOException(message, error);
}
-
}
private static String readIntroAsciiDoc(final Path releaseDirectory) {
@@ -218,6 +196,13 @@ public final class AsciiDocExporter {
}
+ private static List<ChangelogEntry> readChangelogEntries(final Path releaseDirectory) {
+ return findAdjacentFiles(releaseDirectory)
+ .sorted(FILE_MODIFICATION_TIME_COMPARATOR)
+ .map(ChangelogEntry::readFromXmlFile)
+ .collect(Collectors.toList());
+ }
+
private static void exportRelease(
final Path projectRootDirectory,
final ChangelogRelease release,
@@ -242,17 +227,24 @@ public final class AsciiDocExporter {
// Write the header.
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder
- .append(LICENSE_HEADER_ASCIIDOC)
+ .append(AsciiDocUtils.LICENSE_COMMENT_BLOCK)
.append('\n')
.append(AUTO_GENERATION_WARNING_ASCIIDOC)
.append('\n')
- .append("= ")
- .append(release.version)
- .append(" (")
- .append(release.date)
- .append(")\n")
- .append(introAsciiDoc)
- .append("\n");
+ .append("= ");
+ if (release.version != null) {
+ stringBuilder
+ .append(release.version)
+ .append(" (")
+ .append(release.date)
+ .append(")\n")
+ .append(introAsciiDoc)
+ .append("\n");
+ } else {
+ stringBuilder
+ .append("Unreleased\n\n")
+ .append("Changes staged for the next version that is yet to be released.\n\n");
+ }
if (!entries.isEmpty()) {
@@ -376,12 +368,24 @@ public final class AsciiDocExporter {
}
}
+ private static void exportUnreleased(final Path projectRootDirectory) {
+ final Path unreleasedDirectory = ChangelogFiles.unreleasedDirectory(projectRootDirectory);
+ final List<ChangelogEntry> changelogEntries = readChangelogEntries(unreleasedDirectory);
+ final ChangelogRelease changelogRelease = new ChangelogRelease(null, null);
+ try {
+ exportRelease(projectRootDirectory, changelogRelease, null, changelogEntries);
+ } catch (final IOException error) {
+ throw new UncheckedIOException("failed exporting unreleased changes", error);
+ }
+ }
+
private static void exportReleaseIndex(
final Path projectRootDirectory,
final List<ChangelogRelease> changelogReleases) {
final String asciiDoc = exportReleaseIndexToAsciiDoc(changelogReleases);
final byte[] asciiDocBytes = asciiDoc.getBytes(StandardCharsets.UTF_8);
final Path asciiDocFile = projectRootDirectory.resolve(TARGET_RELATIVE_DIRECTORY).resolve("index.adoc");
+ System.out.format("exporting release index to `%s`%n", asciiDocFile);
try {
Files.write(asciiDocFile, asciiDocBytes);
} catch (final IOException error) {
@@ -392,10 +396,11 @@ public final class AsciiDocExporter {
private static String exportReleaseIndexToAsciiDoc(final List<ChangelogRelease> changelogReleases) {
final StringBuilder stringBuilder = new StringBuilder();
stringBuilder
- .append(LICENSE_HEADER_ASCIIDOC)
+ .append(AsciiDocUtils.LICENSE_COMMENT_BLOCK)
.append('\n')
.append(AUTO_GENERATION_WARNING_ASCIIDOC)
- .append("\n= Release changelogs\n\n");
+ .append("\n= Release changelogs\n\n")
+ .append("* [????-??-??] xref:unreleased.adoc[Unreleased]\n");
for (int releaseIndex = changelogReleases.size() - 1; releaseIndex >= 0; releaseIndex--) {
final ChangelogRelease changelogRelease = changelogReleases.get(releaseIndex);
final String asciiDocFilename = changelogReleaseAsciiDocFilename(changelogRelease);
@@ -410,8 +415,10 @@ public final class AsciiDocExporter {
}
private static String changelogReleaseAsciiDocFilename(final ChangelogRelease changelogRelease) {
- // Using only the version (that is, avoiding the date) in the filename so that one can determine the link to the changelog of a particular release with only version information.
- return String.format("%s.adoc", changelogRelease.version);
+ return changelogRelease.version == null
+ ? "unreleased.adoc"
+ // Using only the version (that is, avoiding the date) in the filename so that one can determine the link to the changelog of a particular release with only version information.
+ : String.format("%s.adoc", changelogRelease.version);
}
}
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChanges.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChanges.java
index d107fcc314..5af2afd0b0 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChanges.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChanges.java
@@ -46,13 +46,7 @@ final class MavenChanges {
final Element documentElement = readXmlFileRootElement(xmlPath, "document");
// Read the `body` element.
- final NodeList bodyElements = documentElement.getElementsByTagName("body");
- final int bodyElementCount = bodyElements.getLength();
- if (bodyElementCount != 1) {
- throw XmlReader.failureAtXmlNode(
- documentElement, "was expecting a single `body` element, found: %d", bodyElementCount);
- }
- final Node bodyElement = bodyElements.item(0);
+ final Element bodyElement = XmlReader.childElementMatchingName(documentElement, "body");
// Read releases.
final List<Release> releases = new ArrayList<>();
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChangesImporter.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChangesImporter.java
index 660bc4a516..15d16901db 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChangesImporter.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/importer/MavenChangesImporter.java
@@ -52,9 +52,10 @@ public final class MavenChangesImporter {
private static void writeReleased(final Path projectRootDirectory, final MavenChanges.Release release) {
// Determine the directory for this particular release.
- final Path releaseDirectory = ChangelogFiles
- .changelogDirectory(projectRootDirectory)
- .resolve(String.format("%s-%s", release.date.replaceAll("-", ""), release.version));
+ final Path releaseDirectory = ChangelogFiles.releaseDirectory(
+ projectRootDirectory,
+ release.date.replaceAll("-", ""),
+ release.version);
// Write release information.
final Path releaseFile = ChangelogFiles.releaseXmlFile(releaseDirectory);
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/releaser/ChangelogReleaser.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/releaser/ChangelogReleaser.java
new file mode 100644
index 0000000000..5865e5970c
--- /dev/null
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/releaser/ChangelogReleaser.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ * https://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.
+ */
+package org.apache.logging.log4j.internal.util.changelog.releaser;
+
+import org.apache.logging.log4j.internal.util.AsciiDocUtils;
+import org.apache.logging.log4j.internal.util.XmlReader;
+import org.apache.logging.log4j.internal.util.changelog.ChangelogFiles;
+import org.apache.logging.log4j.internal.util.changelog.ChangelogRelease;
+import org.w3c.dom.Element;
+
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.time.LocalDate;
+
+import static java.time.format.DateTimeFormatter.BASIC_ISO_DATE;
+import static org.apache.logging.log4j.internal.util.StringUtils.isBlank;
+import static org.apache.logging.log4j.internal.util.StringUtils.trimNullable;
+import static org.apache.logging.log4j.internal.util.changelog.ChangelogFiles.releaseDirectory;
+
+public final class ChangelogReleaser {
+
+ private ChangelogReleaser() {}
+
+ public static void main(final String[] mainArgs) throws Exception {
+
+ // Read arguments.
+ final ChangelogReleaserArgs args = ChangelogReleaserArgs.fromMainArgs(mainArgs);
+
+ // Read the release date and version.
+ final String releaseDate = BASIC_ISO_DATE.format(LocalDate.now());
+ final String releaseVersion = readReleaseVersion(args.projectRootDirectory);
+ System.out.format(
+ "using `%s` and `%s` for release date and version, respectively%n",
+ releaseDate, releaseVersion);
+
+ // Move unreleased directory to a release directory.
+ final Path releaseDirectory = releaseDirectory(args.projectRootDirectory, releaseDate, releaseVersion);
+ final Path unreleasedDirectory = ChangelogFiles.unreleasedDirectory(args.projectRootDirectory);
+ if (!Files.exists(unreleasedDirectory)) {
+ final String message = String.format(
+ "`%s` does not exist! A release without any changelogs don't make sense!",
+ unreleasedDirectory);
+ throw new IllegalStateException(message);
+ }
+ System.out.format("moving `%s` to `%s`%n", unreleasedDirectory, releaseDirectory);
+ Files.move(unreleasedDirectory, releaseDirectory);
+ Files.createDirectories(unreleasedDirectory);
+
+ // Write the release information.
+ final Path releaseXmlFile = ChangelogFiles.releaseXmlFile(releaseDirectory);
+ System.out.format("writing release information to `%s`%n", releaseXmlFile);
+ final ChangelogRelease changelogRelease = new ChangelogRelease(releaseVersion, releaseDate);
+ changelogRelease.writeToXmlFile(releaseXmlFile);
+
+ // Write the release introduction.
+ final Path introAsciiDocFile = ChangelogFiles.introAsciiDocFile(releaseDirectory);
+ Files.write(introAsciiDocFile, AsciiDocUtils.LICENSE_COMMENT_BLOCK.getBytes(StandardCharsets.UTF_8));
+ System.out.format("created intro file at `%s`%n", introAsciiDocFile);
+
+ }
+
+ private static String readReleaseVersion(final Path projectRootDirectory) {
+
+ // Read the root `project` element.
+ final Path rootPomFile = projectRootDirectory.resolve("pom.xml");
+ final Element projectElement = XmlReader.readXmlFileRootElement(rootPomFile, "project");
+
+ // Read the `version` element.
+ final Element versionElement = XmlReader.childElementMatchingName(projectElement, "version");
+ final String version = trimNullable(versionElement.getTextContent());
+ if (isBlank(version)) {
+ throw XmlReader.failureAtXmlNode(versionElement, "blank `version`: %s", version);
+ }
+ return version;
+
+ }
+
+}
diff --git a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/releaser/ChangelogReleaserArgs.java
similarity index 55%
copy from log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java
copy to log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/releaser/ChangelogReleaserArgs.java
index fc0b05aab6..df89934424 100644
--- a/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/ChangelogFiles.java
+++ b/log4j-internal-util/src/main/java/org/apache/logging/log4j/internal/util/changelog/releaser/ChangelogReleaserArgs.java
@@ -14,24 +14,26 @@
* See the license for the specific language governing permissions and
* limitations under the license.
*/
-package org.apache.logging.log4j.internal.util.changelog;
+package org.apache.logging.log4j.internal.util.changelog.releaser;
import java.nio.file.Path;
+import java.nio.file.Paths;
-public final class ChangelogFiles {
+final class ChangelogReleaserArgs {
- private ChangelogFiles() {}
+ final Path projectRootDirectory;
- public static Path changelogDirectory(final Path projectRootDirectory) {
- return projectRootDirectory.resolve("changelog");
+ private ChangelogReleaserArgs(final Path projectRootDirectory) {
+ this.projectRootDirectory = projectRootDirectory;
}
- public static Path releaseXmlFile(final Path releaseDirectory) {
- return releaseDirectory.resolve(".release.xml");
- }
-
- public static Path introAsciiDocFile(final Path releaseDirectory) {
- return releaseDirectory.resolve(".intro.adoc");
+ static ChangelogReleaserArgs fromMainArgs(final String[] args) {
+ if (args.length != 1) {
+ final String s = String.format("invalid number of arguments: %d, was expecting: <projectRootPath>", args.length);
+ throw new IllegalArgumentException(s);
+ }
+ final Path projectRootPath = Paths.get(args[0]);
+ return new ChangelogReleaserArgs(projectRootPath);
}
}
diff --git a/src/site/asciidoc/changelog/index.adoc b/src/site/asciidoc/changelog/index.adoc
index 1f5e926824..f695267463 100644
--- a/src/site/asciidoc/changelog/index.adoc
+++ b/src/site/asciidoc/changelog/index.adoc
@@ -22,6 +22,7 @@ This file is automatically generated from the release changelog directory!
= Release changelogs
+* xref:unreleased.adoc[Unreleased]
* [2022-09-09] xref:2.19.0.adoc[2.19.0]
* [2022-06-28] xref:2.18.0.adoc[2.18.0]
* [2022-02-23] xref:2.17.2.adoc[2.17.2]
diff --git a/src/site/asciidoc/changelog/unreleased.adoc b/src/site/asciidoc/changelog/unreleased.adoc
new file mode 100644
index 0000000000..20c6697be8
--- /dev/null
+++ b/src/site/asciidoc/changelog/unreleased.adoc
@@ -0,0 +1,35 @@
+////
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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
+
+ https://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.
+////
+
+////
+*DO NOT EDIT THIS FILE!!*
+This file is automatically generated from the release changelog directory!
+////
+
+= Unreleased
+
+Changes staged for the next version that is yet to be released.
+
+== Changes
+
+=== Changed
+
+* Add LogEvent timestamp to ProducerRecord in KafkaAppender. (for https://issues.apache.org/jira/browse/LOG4J2-2678[LOG4J2-2678] by `pkarwasz`, Federico D'Ambrosio)
+
+=== Fixed
+
+* Fix `Configurator#setLevel` for internal classes. (for https://issues.apache.org/jira/browse/LOG4J2-3631[LOG4J2-3631] by `pkarwasz`, Jeff Thomas)