This is an automated email from the ASF dual-hosted git repository. vy pushed a commit to branch LOG4J2-3628 in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 83e99b8d885401c20a2b68de14bf4efa1b0285a5 Author: Volkan Yazıcı <[email protected]> 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)
