diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 21eb269c..65a551b4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,6 @@ [versions] junit5-version = '5.11.0' +picocli-version = "4.7.5" slf4j-version = '2.0.16' [libraries] @@ -7,6 +8,8 @@ commons-validator = 'commons-validator:commons-validator:1.9.0' jsoup = 'org.jsoup:jsoup:1.18.1' junit-vintage = { module = 'org.junit.vintage:junit-vintage-engine', version.ref = 'junit5-version' } lombok = 'org.projectlombok:lombok:1.18.34' +picocli-impl = { module = 'info.picocli:picocli', version.ref = "picocli-version" } +picocli-annotationprocessor = { module = 'info.picocli:picocli-codegen', version.ref = "picocli-version" } slf4j-api = { module = 'org.slf4j:slf4j-api', version.ref = 'slf4j-version' } slf4j-nop = { module = 'org.slf4j:slf4j-nop', version.ref = 'slf4j-version' } spock = 'org.spockframework:spock-bom:2.3-groovy-3.0' diff --git a/htmlSanityCheck-cli/build.gradle b/htmlSanityCheck-cli/build.gradle new file mode 100644 index 00000000..24a43f93 --- /dev/null +++ b/htmlSanityCheck-cli/build.gradle @@ -0,0 +1,23 @@ +plugins { + id 'application' +} + +dependencies { + implementation libs.picocli.impl + annotationProcessor libs.picocli.annotationprocessor + + implementation libs.slf4j.api + implementation libs.slf4j.simple + implementation libs.groovy.all + + implementation project(":htmlSanityCheck-core") +} + +compileGroovy { + options.compilerArgs += ["-Aproject=${project.group}/${project.name}"] +} + +application { + mainClass = 'org.aim42.htmlsanitycheck.cli.Main' + applicationName = 'hsc' +} \ No newline at end of file diff --git a/htmlSanityCheck-cli/src/main/groovy/org/aim42/htmlsanitycheck/cli/Main.groovy b/htmlSanityCheck-cli/src/main/groovy/org/aim42/htmlsanitycheck/cli/Main.groovy new file mode 100644 index 00000000..96a01866 --- /dev/null +++ b/htmlSanityCheck-cli/src/main/groovy/org/aim42/htmlsanitycheck/cli/Main.groovy @@ -0,0 +1,88 @@ +package org.aim42.htmlsanitycheck.cli + +import org.aim42.htmlsanitycheck.AllChecksRunner +import org.aim42.htmlsanitycheck.Configuration +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import picocli.CommandLine +import picocli.CommandLine.Parameters +import picocli.CommandLine.Command +import picocli.CommandLine.Option + +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +// see end-of-file for license information + +@Command(name = "hsc", mixinStandardHelpOptions = true, version = "hsc 2.0.0", + description = "Check HTML files for Sanity") +class Main implements Runnable { + private static final Logger logger = LoggerFactory.getLogger(Main.class) + + @Option(names = ["-r", "--resultsDir"], description = "Results Directory") + String resultsDirectoryName = "/tmp/results" + + @Parameters(arity = "1", description = "base directory", index = "0") + File srcDir + + @Parameters(arity = "0..*", description = "at least one File", index = "1..*") + File[] files + + static void main(String[] args) { + Main app = new Main() + CommandLine cmd = new CommandLine(app) + cmd.execute(args) + } + + private static List findFiles(File directory) throws IOException { + Files.walk(Paths.get(directory.getPath())) + .filter(Files::isRegularFile) + .filter({ path -> path.toString().endsWith(".html") || path.toString().endsWith(".htm")}) + .collect { it.toFile() } + } + + void run() { + var configuration = new Configuration() + + var resultsDirectory = new File(resultsDirectoryName) + + configuration.addConfigurationItem(Configuration.ITEM_NAME_sourceDir, srcDir) + configuration.addConfigurationItem(Configuration.ITEM_NAME_sourceDocuments, + files ?: findFiles(srcDir) + ) + configuration.addConfigurationItem((Configuration.ITEM_NAME_checkingResultsDir), resultsDirectory) + + if (configuration.isValid()) { + // create output directory for checking results + resultsDirectory.mkdirs() + + // create an AllChecksRunner... + var allChecksRunner = new AllChecksRunner(configuration) + + // ... and perform the actual checks + var allChecks = allChecksRunner.performAllChecks() + + // check for findings and fail build if requested + var nrOfFindingsOnAllPages = allChecks.nrOfFindingsOnAllPages() + logger.debug("Found ${nrOfFindingsOnAllPages} error(s) on all checked pages") + } + } +} + +/*======================================================================== + Copyright Gerd Aschemann and aim42 contributors + + 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. + ========================================================================*/ diff --git a/htmlSanityCheck-core/src/main/groovy/org/aim42/htmlsanitycheck/Configuration.groovy b/htmlSanityCheck-core/src/main/groovy/org/aim42/htmlsanitycheck/Configuration.groovy new file mode 100644 index 00000000..e69de29b diff --git a/settings.gradle b/settings.gradle index 3a8d011c..7b98b7b0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -23,4 +23,5 @@ develocity { rootProject.name = 'htmlSanityCheck' include('htmlSanityCheck-core') -include('htmlSanityCheck-gradle-plugin') \ No newline at end of file +include('htmlSanityCheck-gradle-plugin') +include('htmlSanityCheck-cli') \ No newline at end of file