Skip to content

Commit

Permalink
Issue checkstyle#219: Support of config bundles with extra configurat…
Browse files Browse the repository at this point in the history
…ion files
  • Loading branch information
piyush kumar sadangi authored and piyush kumar sadangi committed Jan 15, 2025
1 parent 93fded4 commit c93226e
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 31 deletions.
18 changes: 18 additions & 0 deletions Header/Example2/java.header
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
// Copyright (C) 2001-2025 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///////////////////////////////////////////////////////////////////////////////////////////////
18 changes: 18 additions & 0 deletions Header/Example4/java.header
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
// Copyright (C) 2001-2025 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///////////////////////////////////////////////////////////////////////////////////////////////
6 changes: 5 additions & 1 deletion diff-java-tool/src/main/resources/pom_template.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<sevntu-checkstyle.version>1.44.1</sevntu-checkstyle.version>
<checkstyle.config.location>https://raw.githubusercontent.com/checkstyle/checkstyle/master/src/main/resources/google_checks.xml</checkstyle.config.location>
<checkstyle.failsOnError>true</checkstyle.failsOnError>
<config.folder>${project.basedir}/config</config.folder>
</properties>

<build>
Expand Down Expand Up @@ -62,10 +63,13 @@
<configuration>
<enableFilesSummary>false</enableFilesSummary>
<failsOnError>${checkstyle.failsOnError}</failsOnError>
<propertyExpansion>
config.folder=${config.folder}
</propertyExpansion>
</configuration>
</plugin>

</plugins>
</reporting>

</project>
</project>
16 changes: 16 additions & 0 deletions extractor/config/pmd/pmd-ruleset.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,31 @@
<!-- SignatureDeclareThrowsException is excluded as the project needs flexibility
in specifying exceptions for certain methods, particularly those interacting with external APIs. -->
<exclude name="SignatureDeclareThrowsException"/>

<!-- GodClass is excluded as some classes necessarily manage complex functionalities,
and attempts to refactor would decrease cohesion and increase coupling. -->
<exclude name="GodClass"/>

<!-- TooManyMethods is excluded because some classes require multiple methods
due to the breadth of their responsibilities, particularly in utility or service classes. -->
<exclude name="TooManyMethods"/>

<!-- AvoidCatchingGenericException is excluded to allow for broad exception handling
in certain scenarios where specific exceptions are not easily anticipated. -->
<exclude name="AvoidCatchingGenericException"/>

<!-- CognitiveComplexity is excluded as some methods, particularly those handling file processing
and configuration generation, require multiple conditional checks and error handling paths.
While we strive to keep complexity low, certain core processing methods necessarily have
higher complexity to maintain proper validation and error handling. -->
<exclude name="CognitiveComplexity"/>

<!-- CyclomaticComplexity is excluded because certain methods, especially those dealing with
file processing and configuration validation, require multiple decision points and
conditional branches. These methods need to handle various edge cases, validate inputs,
and manage different file processing scenarios, making a higher cyclomatic complexity
unavoidable for maintaining robust and reliable functionality. -->
<exclude name="CyclomaticComplexity"/>
</rule>

<rule ref="category/java/documentation.xml">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,45 +72,49 @@ public final class CheckstyleExampleExtractor {
private static final String PROJ_YML_PROP_FILE_PATH =
"src/main/resources/" + PROJ_YML_PROP_FILENAME;

/** The regular expression pattern for excluded file paths. */
private static final String EXCLUDED_FILE_PATTERN =
"src/xdocs-examples/resources/com/puppycrawl/tools/checkstyle/checks/regexp/"
+ "regexpmultiline/Example7.txt";

/** The regular expression pattern for example files. */
private static final String EXAMPLE_FILE_PATTERN = "Example\\d+\\.(java|txt)";

/** The subfolder name for all-in-one examples. */
private static final String ALL_IN_ONE_SUBFOLDER = "all-examples-in-one";

/**
* Number of expected arguments when processing a single input file.
*/
/** The filename for the Java header file. */
private static final String JAVA_HEADER_FILENAME = "java.header";

/** The name of the resources directory. */
private static final String RESOURCES_FOLDER = "resources";

/** The name of the source directory. */
private static final String SRC_FOLDER = "src";

/** The name of the main directory. */
private static final String MAIN_FOLDER = "main";

/** The name of the Example2 directory. */
private static final String EXAMPLE2_DIR = "Example2";

/** The name of the Example4 directory. */
private static final String EXAMPLE4_DIR = "Example4";

/** The name of the Header directory. */
private static final String HEADER_DIR = "Header";

/** Number of expected arguments when processing a single input file. */
private static final int SINGLE_INPUT_FILE_ARG_COUNT = 5;

/**
* Index of the "--input-file" flag in the argument array.
*/
/** Index of the "--input-file" flag in the argument array. */
private static final int INPUT_FILE_FLAG_INDEX = 1;

/**
* Index of the input file path in the argument array.
*/
/** Index of the input file path in the argument array. */
private static final int INPUT_FILE_PATH_INDEX = 2;

/**
* Index of the output file path in the argument array.
*/
/** Index of the output file path in the argument array. */
private static final int OUTPUT_FILE_PATH_INDEX = 3;

/**
* Index of the output file path in the argument array.
*/
/** Index of the output file path in the argument array. */
private static final int PROJECT_OUTPUT_PATH_INDEX = 4;

/**
* The buffer size for reading and writing files.
*/
/** The buffer size for reading and writing files. */
private static final int BUFFER_SIZE = 1024;

/**
Expand Down Expand Up @@ -376,7 +380,6 @@ public static String processDirectory(final String inputDir) throws Exception {
final List<Path> exampleFiles = paths
.filter(Files::isRegularFile)
.filter(path -> path.getFileName().toString().matches(EXAMPLE_FILE_PATTERN))
.filter(path -> !path.toString().endsWith(EXCLUDED_FILE_PATTERN))
.collect(Collectors.toList());

if (!exampleFiles.isEmpty()) {
Expand Down Expand Up @@ -418,18 +421,18 @@ private static void processExampleFile(

/**
* Processes an example file and generates its configuration, properties, and README.
* Also copies any known extra files if present in the same folder.
*
* @param exampleFile The path to the example file.
* @param outputPath The path where the generated content will be stored.
* @param exampleFile The path to the example file (.java or .txt).
* @param outputPath The path where the generated content (config.xml, etc.) will be stored.
* @throws Exception If an unexpected error occurs.
*/
private static void processFile(
final String exampleFile,
final Path outputPath)
throws Exception {
if (exampleFile != null
&& outputPath != null
&& !exampleFile.endsWith(EXCLUDED_FILE_PATTERN)) {
&& outputPath != null) {
try {
final String templateFilePath = getTemplateFilePathForExamples(exampleFile);
if (templateFilePath != null) {
Expand All @@ -438,6 +441,23 @@ private static void processFile(
writeConfigFile(outputPath, generatedContent);
copyPropertiesFile(outputPath);
generateReadme(outputPath);

// Check if we need to copy java.header for Header/Example2 or Header/Example4
final Path parentDir = outputPath.getParent();
final String parentName = Optional.ofNullable(parentDir)
.map(Path::getFileName)
.map(Path::toString)
.orElse("");

final String folderName = Optional.ofNullable(outputPath.getFileName())
.map(Path::toString)
.orElse("");

if (HEADER_DIR.equals(parentName)
&& (EXAMPLE2_DIR.equals(folderName)
|| EXAMPLE4_DIR.equals(folderName))) {
copyJavaHeaderIfNeeded(outputPath);
}
}
else {
LOGGER.log(Level.WARNING,
Expand All @@ -453,6 +473,29 @@ private static void processFile(
}
}

/**
* Copies java.header from src/main/resources into the output folder
* (next to config.xml) if it exists.
*
* @param outputPath The folder where config.xml is placed.
* @throws IOException if an I/O error occurs.
*/
private static void copyJavaHeaderIfNeeded(final Path outputPath) throws IOException {
final Path resourcesDir =
Paths.get(SRC_FOLDER, MAIN_FOLDER, RESOURCES_FOLDER).toAbsolutePath();
final Path source = resourcesDir.resolve(JAVA_HEADER_FILENAME);

if (Files.exists(source)) {
Files.copy(source,
outputPath.resolve(JAVA_HEADER_FILENAME),
StandardCopyOption.REPLACE_EXISTING);
LOGGER.info("Copied " + JAVA_HEADER_FILENAME + " from " + source + " to " + outputPath);
}
else {
LOGGER.info("No " + JAVA_HEADER_FILENAME + " found in resources folder. Skipping.");
}
}

/**
* Writes the serialized configuration content to a config.xml.
*
Expand Down Expand Up @@ -554,7 +597,6 @@ private static List<String> getAllExampleFiles(final List<Path> exampleDirs)
paths.filter(Files::isRegularFile)
.filter(path -> path.getFileName().toString().matches(EXAMPLE_FILE_PATTERN))
.map(Path::toString)
.filter(file -> !file.endsWith(EXCLUDED_FILE_PATTERN))
.forEach(allExampleFiles::add);
}
}
Expand Down Expand Up @@ -709,7 +751,6 @@ private static void generateReadmes(
try (Stream<Path> paths = Files.list(dir)) {
paths.filter(Files::isRegularFile)
.filter(path -> path.getFileName().toString().matches(EXAMPLE_FILE_PATTERN))
.filter(path -> !path.toString().endsWith(EXCLUDED_FILE_PATTERN))
.forEach(exampleFile -> {
generateIndividualReadme(exampleFile, outputPath, moduleName);
});
Expand Down
18 changes: 18 additions & 0 deletions extractor/src/main/resources/java.header
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
// Copyright (C) 2001-2025 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///////////////////////////////////////////////////////////////////////////////////////////////

0 comments on commit c93226e

Please sign in to comment.