From 8d39e25d43dae91a6035300e45978dc1277d2f7c Mon Sep 17 00:00:00 2001 From: Naohide Sano Date: Thu, 19 Dec 2024 21:31:36 +0900 Subject: [PATCH] initial imports --- .github/workflows/codeql.yml | 81 +++++++++++++ .github/workflows/maven.yml | 35 ++++++ README.md | 43 +++++++ jitpack.yml | 2 + pom.xml | 96 +++++++++++++++ .../vavi/maven/careless/CarelessMojo.java | 46 ++++++++ .../java/vavi/maven/careless/Processor.java | 111 ++++++++++++++++++ src/main/java/vavi/maven/careless/Target.java | 70 +++++++++++ .../java/vavi/maven/careless/TestCase.java | 45 +++++++ src/test/resources/logging.properties | 7 ++ 10 files changed, 536 insertions(+) create mode 100644 .github/workflows/codeql.yml create mode 100644 .github/workflows/maven.yml create mode 100644 README.md create mode 100644 jitpack.yml create mode 100644 pom.xml create mode 100644 src/main/java/vavi/maven/careless/CarelessMojo.java create mode 100644 src/main/java/vavi/maven/careless/Processor.java create mode 100644 src/main/java/vavi/maven/careless/Target.java create mode 100644 src/test/java/vavi/maven/careless/TestCase.java create mode 100644 src/test/resources/logging.properties diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..2bb7e20 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,81 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] +# schedule: +# - cron: '19 18 * * 0' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'java' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + # - name: Autobuild + # uses: github/codeql-action/autobuild@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + + # server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + # settings-path: ${{ github.workspace }} # location for the settings.xml file + + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏ī¸ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + - name: Build with Maven + run: mvn -B package --file pom.xml -DskipTests + #run: mvn package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml -DskipTests + #env: + # GITHUB_TOKEN: ${{ github.token }} + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..814fdc7 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,35 @@ +name: Java CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Check w/o SNAPSHOT when "bump version" + if: ${{ contains(github.event.head_commit.message, 'bump version') }} + run: grep "" pom.xml | head -1 | grep -v SNAPSHOT + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + cache: maven + #server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + #settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Build with Maven + run: mvn -B package --file pom.xml + #run: mvn package -s $GITHUB_WORKSPACE/settings.xml --file pom.xml + #env: + # GITHUB_TOKEN: ${{ github.token }} diff --git a/README.md b/README.md new file mode 100644 index 0000000..41652f1 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +[![GitHub Packages](https://github.com/umjammer/careless-maven-plugin/actions/workflows/maven-publish.yml/badge.svg)](https://github.com/umjammer?tab=packages&repo_name=careless-maven-plugin) +[![Release](https://jitpack.io/v/umjammer/careless-maven-plugin.svg)](https://jitpack.io/#umjammer/careless-maven-plugin) +[![Java CI](https://github.com/umjammer/careless-maven-plugin/actions/workflows/maven.yml/badge.svg)](https://github.com/umjammer/careless-maven-plugin/actions/workflows/maven.yml) +[![CodeQL](https://github.com/umjammer/careless-maven-plugin/actions/workflows/codeql.yml/badge.svg)](https://github.com/umjammer/careless-maven-plugin/actions/workflows/codeql.yml) +![Java](https://img.shields.io/badge/Java-17-b07219) + +# careless-maven-plugin + + ⚠ī¸ eliminates human errors. + +## Install + + * [maven](https://jitpack.io/#umjammer/careless-maven-plugin) + +## Usage + +```xml + + + + + + + + + + +``` + + * where + * file is xml(.xml) ... xpath + * file is yaml(.yml) ... yaml-path + * prefix (prefix:...) + * grep:regex + +## Preference + + * https://github.com/yaml-path/YamlPath + * https://github.com/snakeyaml/snakeyaml + +## TODO + + * checkstyle diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000..efde7bf --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - openjdk17 diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6620c31 --- /dev/null +++ b/pom.xml @@ -0,0 +1,96 @@ + + 4.0.0 + + vavi + careless-maven-plugin + 0.0.1-SNAPSHOT + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.12.1 + + 17 + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + -Djava.util.logging.config.file=${project.build.testOutputDirectory}/logging.properties + + false + + + + + + + + jitpack.io + https://jitpack.io + + + + + + + org.junit + junit-bom + 5.10.3 + pom + import + + + + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.12.0 + provided + + + org.apache.maven + maven-plugin-api + 3.9.9 + provided + + + + io.github.yaml-path + yaml-path + 0.0.12 + + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-commons + test + + + + com.github.umjammer + vavi-commons + 1.1.14 + test + + + diff --git a/src/main/java/vavi/maven/careless/CarelessMojo.java b/src/main/java/vavi/maven/careless/CarelessMojo.java new file mode 100644 index 0000000..9155347 --- /dev/null +++ b/src/main/java/vavi/maven/careless/CarelessMojo.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024 by Naohide Sano, All rights reserved. + * + * Programmed by Naohide Sano + */ + +package vavi.maven.careless; + +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + + +/** + * CarelessMojo. + * + * @author Naohide Sano (nsano) + * @version 0.00 2024-09-07 nsano initial version
+ */ +@Mojo(name = "careless") +public class CarelessMojo implements org.apache.maven.plugin.Mojo { + + private Log log; + + + @Parameter(property = "constantName", required = true) + private String constantName; + + @Parameter(property = "expectedValue", required = true) + private String expectedValue; + + @Override + public void execute() { + log.info("Hello, world"); + } + + @Override + public void setLog(Log log) { + this.log = log; + } + + @Override + public Log getLog() { + return log; + } +} diff --git a/src/main/java/vavi/maven/careless/Processor.java b/src/main/java/vavi/maven/careless/Processor.java new file mode 100644 index 0000000..8e84ad1 --- /dev/null +++ b/src/main/java/vavi/maven/careless/Processor.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2024 by Naohide Sano, All rights reserved. + * + * Programmed by Naohide Sano + */ + +package vavi.maven.careless; + +import java.io.InputStream; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; + +import io.github.yamlpath.YamlPath; +import org.xml.sax.InputSource; + +import static java.lang.System.getLogger; + + +/** + * Processor. + * + * @author Naohide Sano (nsano) + * @version 0.00 2024-12-19 nsano initial version
+ */ +public class Processor { + + private static final Logger logger = getLogger(Processor.class.getName()); + + static XPath xPath = XPathFactory.newInstance().newXPath(); + + // + // matches | negative | result + // ----------+----------+---------- + // true true ERROR + // false true OK + // true false OK + // false false ERROR + // + private static String m(boolean ok) { + return ok ? "matched" : "not matched"; + } + + public void process(Target target) { + String ext = target.path.substring(target.path.lastIndexOf('.') + 1); +//logger.log(Level.DEBUG, "ext: " + ext); + switch (ext) { + case "pom", "xml" -> { + try { + InputSource is = new InputSource(Files.newInputStream(Path.of(target.path))); + String actual = (String) xPath.evaluate(target.ri, is, XPathConstants.STRING); + boolean m = actual.matches(target.value); +//logger.log(Level.DEBUG, ext + ": " + target.value + ", actual: " + actual + ", matches: " + m); + if (target.negative == m) + System.out.println("NG: " + ext + ": " + m(m) + ": required: " + target.value + ", actual: " + actual); + else + System.err.println("OK: " + ext + ": " + m(m) + ": for " + target); + } catch (Exception e) { + logger.log(Level.ERROR, e.getMessage() + ":" + target, e); + } + } + case "yml" -> { + try { + InputStream is = Files.newInputStream(Path.of(target.path)); + String actual = YamlPath.from(is).readSingle(target.ri); + boolean m = actual != null && actual.matches(target.value); + if (target.negative == m) + System.out.println("NG: " + ext + ": " + m(m) + ": required: " + target.value + ", actual: " + actual); + else + System.err.println("OK: " + ext + ": " + m(m) + ": for " + target); + } catch (Exception e) { + logger.log(Level.ERROR, e.getMessage() + ":" + target, e); + } + } + default -> { + try { + Pattern p = Pattern.compile(target.ri); + List r = new ArrayList<>(); + AtomicInteger l = new AtomicInteger(); + Files.readAllLines(Path.of(target.path)).forEach(line -> { + Matcher m = p.matcher(line); +//logger.log(Level.DEBUG, ext + ": find: " + p + ": " + m.find() + ": " + line); + if (m.find()) { + String actual = m.group(1); + if (target.value.matches(actual)) + r.add(l.get()); + } + l.incrementAndGet(); + }); + boolean m = !r.isEmpty(); +//logger.log(Level.DEBUG, ext + ": " + target.value + ", matches: " + m); + if (!target.negative == m) + System.err.println("OK: " + ext + ": " + m(m) + ": for " + target + ", lines: " + r); + else + System.out.println("NG: " + ext + ": " + m(m) + ": for " + target + ", lines: " + r); + } catch (Exception e) { + logger.log(Level.ERROR, e.getMessage() + ":" + target, e); + } + } + } + } +} diff --git a/src/main/java/vavi/maven/careless/Target.java b/src/main/java/vavi/maven/careless/Target.java new file mode 100644 index 0000000..1c94ab0 --- /dev/null +++ b/src/main/java/vavi/maven/careless/Target.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 by Naohide Sano, All rights reserved. + * + * Programmed by Naohide Sano + */ + +package vavi.maven.careless; + +import java.util.StringJoiner; + + +/** + * Target. + * + * @author Naohide Sano (nsano) + * @version 0.00 2024-12-19 nsano initial version
+ */ +public class Target { + + /** target path */ + String path; + + /** + * resource indicator. + * scheme is assumed implicitly like, + *
    + *
  1. .xml, .pom -> xpath
  2. + *
  3. .json -> jsonpath (WIP)
  4. + *
  5. .yml -> ymlpath
  6. + *
  7. .txt -> regexed line and location
  8. + *
+ */ + String ri; + + String value; + + boolean negative; + + public Target path(String path) { + this.path = path; + return this; + } + + /** + * resource indicator + * + */ + public Target ri(String ri) { + this.ri = ri; + return this; + } + + public Target value(String value) { + this.value = value; + return this; + } + + public Target negative(boolean negative) { + this.negative = negative; + return this; + } + + @Override public String toString() { + return new StringJoiner(", ", Target.class.getSimpleName() + "[", "]") + .add("path='" + path + "'") + .add("ri='" + ri + "'") + .add("value='" + value + "'") + .toString(); + } +} diff --git a/src/test/java/vavi/maven/careless/TestCase.java b/src/test/java/vavi/maven/careless/TestCase.java new file mode 100644 index 0000000..522f3c7 --- /dev/null +++ b/src/test/java/vavi/maven/careless/TestCase.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 by Naohide Sano, All rights reserved. + * + * Programmed by Naohide Sano + */ + +package vavi.maven.careless; + +import java.util.List; + +import org.junit.jupiter.api.Test; + + +/** + * TestCase. + * + * @author Naohide Sano (nsano) + * @version 0.00 07 nsano initial version
+ */ +class TestCase { + + // + // WTF java still has not supported xpath 2.0 + // use saxon for xpath 2.0 + // + @Test + void test1() throws Exception { + String javaVersion = "17"; + var targets = List.of( + // version check + new Target().path(".github/workflows/codeql.yml").ri("jobs.analyze.steps[2].name").value("Set up JDK " + javaVersion), + new Target().path(".github/workflows/codeql.yml").ri("jobs.analyze.steps[2].with.java-version").value(javaVersion), + new Target().path(".github/workflows/maven.yml").ri("jobs.build.steps[2].name").value("Set up JDK " + javaVersion), + new Target().path(".github/workflows/maven.yml").ri("jobs.build.steps[2].with.java-version").value(javaVersion), + new Target().path("pom.xml").ri("//*[local-name()='artifactId' and text()='maven-compiler-plugin']/..//*[local-name()='release' or local-name()='source']/text()").value(javaVersion), + new Target().path("jitpack.yml").ri("jdk[0]").value("openjdk" + javaVersion), + new Target().path("README.md").ri("img\\.shields\\.io\\/badge\\/Java-(\\d+?)-b07219").value(javaVersion), + // SNAPSHOT check + new Target().path("pom.xml").ri("//*[local-name()='project']/*[local-name()='version']/text()").value(".*-SNAPSHOT").negative(true) + ); + + Processor p = new Processor(); + targets.forEach(p::process); + } +} diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties new file mode 100644 index 0000000..fd51dfc --- /dev/null +++ b/src/test/resources/logging.properties @@ -0,0 +1,7 @@ +handlers=java.util.logging.ConsoleHandler +.level=INFO +java.util.logging.ConsoleHandler.level=ALL +java.util.logging.ConsoleHandler.formatter=vavi.util.logging.VaviFormatter + +#vavi.util.level=FINE +vavi.maven.careless.level=ALL