├── .circleci └── config.yml ├── .gitattributes ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── build.yml │ └── codeql-analysis.yml ├── .gitignore ├── .java-version ├── CODEOWNERS ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── echo ├── pom.xml └── src │ ├── main │ └── java │ │ └── echo │ │ ├── CharacterOutput.java │ │ ├── EchoPlugin.java │ │ ├── MessageExtractor.java │ │ ├── exception │ │ └── FailureException.java │ │ ├── output │ │ ├── EchoOutput.java │ │ ├── EchoOutputWrapper.java │ │ ├── NewlineFormatter.java │ │ └── PluginLog.java │ │ ├── parameter │ │ ├── LineSeparator.java │ │ ├── OutputLevelType.java │ │ ├── PluginParameters.java │ │ └── PluginParametersBuilder.java │ │ └── util │ │ ├── FileUtil.java │ │ ├── FindFileInAbsolutePath.java │ │ ├── FindFileInClassPath.java │ │ └── UrlWrapper.java │ └── test │ ├── java │ └── echo │ │ ├── CharacterOutputTest.java │ │ ├── TestAppendOption.java │ │ ├── TestCharacterOutput.java │ │ ├── TestEncoding.java │ │ ├── TestForceOption.java │ │ ├── TestFromFile.java │ │ ├── TestLevel.java │ │ ├── TestLineSeparator.java │ │ ├── TestMessage.java │ │ ├── TestNewline.java │ │ └── TestToFile.java │ └── resources │ ├── messageEncoding.txt │ └── messageText.txt ├── maven-plugin ├── pom.xml └── src │ ├── it │ ├── default-configuration │ │ ├── expected.log │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── postbuild.groovy │ ├── echo-fromClassResouce │ │ ├── expected.log │ │ ├── invoker.properties │ │ ├── module1 │ │ │ ├── pom.xml │ │ │ └── src │ │ │ │ └── main │ │ │ │ └── resources │ │ │ │ └── classMessage.txt │ │ ├── module2 │ │ │ └── pom.xml │ │ ├── pom.xml │ │ └── postbuild.groovy │ ├── echo-fromFile │ │ ├── expected.log │ │ ├── fileMessage2.txt │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── postbuild.groovy │ ├── mojo-description │ │ ├── expected.log │ │ ├── invoker.properties │ │ ├── pom.xml │ │ └── postbuild.groovy │ ├── settings.xml │ └── skip-echo │ │ ├── invoker.properties │ │ ├── not-expected.log │ │ ├── pom.xml │ │ └── postbuild.groovy │ ├── main │ └── java │ │ └── echo │ │ ├── EchoMojo.java │ │ ├── exception │ │ └── ExceptionHandler.java │ │ └── output │ │ ├── MavenEchoOutput.java │ │ └── MavenPluginLog.java │ └── test │ └── java │ └── echo │ ├── EchoMojoTest.java │ ├── exception │ └── ExceptionHandlerTest.java │ └── output │ ├── MavenEchoOutputTest.java │ └── MavenPluginLogTest.java ├── misc ├── echo.png └── welcome.txt ├── pom.xml └── renovate.json /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | maven: circleci/maven@2.0.0 5 | 6 | shared: &shared 7 | steps: 8 | - checkout 9 | - restore_cache: 10 | keys: 11 | - ekryd-cache-{{ checksum "pom.xml" }} 12 | - ekryd-cache- # fallback in case previous cache key is not found 13 | - run: mvn clean verify -Dmaven.javadoc.skip=true -Dinvoker.skip=true -B -V 14 | - save_cache: 15 | paths: 16 | - ~/.m2 17 | key: ekryd-cache--{{ checksum "pom.xml" }} 18 | 19 | jobs: 20 | jdk11: 21 | docker: 22 | - image: cimg/openjdk:11.0.26 23 | <<: *shared 24 | jdk20: 25 | docker: 26 | - image: cimg/openjdk:20.0 27 | <<: *shared 28 | jdk21: 29 | docker: 30 | - image: cimg/openjdk:21.0 31 | <<: *shared 32 | jdk17: 33 | docker: 34 | - image: cimg/openjdk:17.0.14 35 | steps: 36 | - checkout 37 | - restore_cache: 38 | keys: 39 | - ekryd-cache-{{ checksum "pom.xml" }} 40 | - ekryd-cache- # fallback in case previous cache key is not found 41 | - run: mvn clean verify -DskipTests=true -Dmaven.javadoc.skip=true -Dinvoker.skip=true -B -V 42 | - run: mvn clean jacoco:prepare-agent integration-test jacoco:report -B 43 | - run: mvn coveralls:report -B -DrepoToken=$COVERALLS_REPO_TOKEN 44 | - run: mvn sonar:sonar -Dsonar.projectKey=com.github.ekryd.echo-maven-plugin:echo-plugin -Dsonar.organization=ekryd-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONARCLOUD_TOKEN 45 | - save_cache: 46 | paths: 47 | - ~/.m2 48 | key: ekryd-cache--{{ checksum "pom.xml" }} 49 | 50 | workflows: 51 | version: 2 52 | work: 53 | jobs: 54 | - jdk21 55 | - jdk20: 56 | requires: 57 | - jdk21 58 | - jdk11: 59 | requires: 60 | - jdk21 61 | - jdk17: 62 | filters: # using regex filters requires the entire branch to match 63 | branches: 64 | only: # only branches matching the below regex filters will run 65 | - master 66 | requires: 67 | - jdk11 68 | - jdk20 69 | - jdk21 70 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set default behaviour, in case users don't have core.autocrlf set. 2 | * text=auto 3 | 4 | # Declare files that will always have LF line endings on checkout. 5 | *.txt eol=lf 6 | 7 | # Don't modify line ending on xml files. 8 | *.xml -text 9 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [Ekryd] 4 | custom: ["https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=JB25X84DDG5JW&lc=SE&item_name=Encourage%20the%20development&item_number=sortpom¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted"] 5 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "maven" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | # Avoid workflow run for _merged_ `dependabot` PRs. 6 | # They were (hopefully!) already tested in PR-triggered workflow. 7 | branches-ignore: "dependabot/**" 8 | pull_request: 9 | paths-ignore: 10 | - "**.adoc" 11 | - "**.md" 12 | - "**.txt" 13 | 14 | permissions: 15 | contents: write 16 | pull-requests: write 17 | 18 | jobs: 19 | echo: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - name: "Echo environment" 23 | run: | 24 | echo "${{github.event_name}}" 25 | echo "${{github.actor}}" 26 | echo "${{github.event.pull_request.html_url}}" 27 | 28 | build: 29 | if: github.event_name == 'pull_request' 30 | runs-on: ${{ matrix.os }} 31 | needs: echo 32 | 33 | strategy: 34 | matrix: 35 | os: [ macos-latest, ubuntu-latest, windows-latest ] 36 | version: [11, 17, 21] 37 | 38 | steps: 39 | - name: Checkout repository 40 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 41 | 42 | - name: Setup JDKs 43 | uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1 44 | with: 45 | distribution: temurin 46 | java-version: ${{ matrix.version }} 47 | java-package: jdk 48 | architecture: x64 49 | cache: maven 50 | 51 | - name: Build 52 | shell: bash 53 | run: mvn --batch-mode clean verify 54 | 55 | merge: 56 | if: github.event_name == 'pull_request' && github.actor == 'dependabot[bot]' 57 | runs-on: ubuntu-latest 58 | needs: build 59 | 60 | steps: 61 | - name: "[dependabot] Fetch metadata" 62 | id: metadata 63 | uses: dependabot/fetch-metadata@v2.4.0 64 | with: 65 | github-token: "${{ secrets.GITHUB_TOKEN }}" 66 | 67 | - name: "[dependabot] Auto-merge the PR" 68 | run: gh pr merge --auto --squash "$PR_URL" 69 | env: 70 | PR_URL: ${{ github.event.pull_request.html_url }} 71 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 72 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | name: "CodeQL" 7 | 8 | on: 9 | push: 10 | branches: [master] 11 | pull_request: 12 | # The branches below must be a subset of the branches above 13 | branches: [master] 14 | schedule: 15 | - cron: '0 15 * * 6' 16 | 17 | jobs: 18 | analyze: 19 | name: Analyze 20 | runs-on: ubuntu-latest 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | # Override automatic language detection by changing the below list 26 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 27 | language: ['java'] 28 | # Learn more... 29 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 30 | 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 34 | 35 | # Initializes the CodeQL tools for scanning. 36 | - name: Initialize CodeQL 37 | uses: github/codeql-action/init@v3 38 | with: 39 | languages: ${{ matrix.language }} 40 | # If you wish to specify custom queries, you can do so here or in a config file. 41 | # By default, queries listed here will override any specified in a config file. 42 | # Prefix the list here with "+" to use these queries and those in the config file. 43 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 44 | 45 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 46 | # If this step fails, then you should remove it and run the build manually (see below) 47 | - name: Autobuild 48 | uses: github/codeql-action/autobuild@v3 49 | 50 | # ℹ️ Command-line programs to run using the OS shell. 51 | # 📚 https://git.io/JvXDl 52 | 53 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 54 | # and modify them (or add more) to build your code if your project 55 | # uses a compiled language 56 | 57 | #- run: | 58 | # make bootstrap 59 | # make release 60 | 61 | - name: Perform CodeQL Analysis 62 | uses: github/codeql-action/analyze@v3 63 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | target 4 | release.properties 5 | idea-plugin/out 6 | -------------------------------------------------------------------------------- /.java-version: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # These owners will be the default owners for everything in the repo. 5 | * @ekryd 6 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Standards 4 | 5 | Be nice to each other! 6 | 7 | * Using welcoming and inclusive language 8 | * Being respectful of differing viewpoints and experiences 9 | * Gracefully accepting constructive criticism 10 | * Focusing on what is best for the community 11 | 12 | ## Our Responsibilities 13 | 14 | We will remove any content which is not appropriate. 15 | 16 | ## Time frame 17 | 18 | This project is done during spare time. The goal is to respond as soon as possible, but patience is a virtue. 19 | 20 | ## Attribution 21 | 22 | This Code of Conduct is a shortened version of [Contributor Covenant][homepage], version 1.4, 23 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 24 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Creating issues 2 | 3 | Please add the following information. 4 | * What do you want to achieve / What is the purpose? 5 | * Which version of EchoMavenPlugin are you using (if relevant)? 6 | * What is the configuration of EchoMavenPlugin (if relevant)? 7 | 8 | ### Error issues 9 | 10 | * What was the expected output? 11 | * What was the actual output? 12 | 13 | ### Enhancements issues 14 | 15 | All suggestions are always taken into consideration. 16 | 17 | The ones that are implemented will take a little time, as this project is done during spare time. 18 | 19 | Some suggestions will be rejected. Common reasons for rejected issues: 20 | * The change is outside the scope of the plugin (e.g. can be solved by another plugin) 21 | * The issuer does not reply to questions 22 | 23 | The best way to provide a suggestion is to create a pull request 24 | 25 | ## Creating pull requests 26 | 27 | Yes, please send me pull requests! They are the best! It shows that you are interested in spending your time for a feature, rather than just spending my time. 28 | 29 | The following is likely to happen: 30 | * I will accept the new feature 31 | * I will make changes to your code to fit my mindset how the plugin works 32 | * You will make changes to your code to create the optimal feature 33 | * I will demand 100% test coverage for new code. 34 | * We will have conversations about the best design for the functionality and how to name things 35 | * Before the release, you will do the final acceptance tests for the feature. After all, you are customer 36 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Björn Ekryd 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of echo-maven-plugin nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Echo Maven Plugin ![Icon](https://raw.githubusercontent.com/Ekryd/echo-maven-plugin/master/misc/echo.png) 2 | 3 | [![Build Status](https://circleci.com/gh/Ekryd/echo-maven-plugin.svg?style=svg)](https://app.circleci.com/pipelines/github/Ekryd/echo-maven-plugin) 4 | [![Coverage Status](https://coveralls.io/repos/github/Ekryd/echo-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Ekryd/echo-maven-plugin?branch=master) 5 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.ekryd.echo-maven-plugin/echo-maven-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.ekryd.echo-maven-plugin/echo-maven-plugin) 6 | [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=com.github.ekryd.echo-maven-plugin%3Aecho-plugin&metric=alert_status)](https://sonarcloud.io/dashboard?id=com.github.ekryd.echo-maven-plugin%3Aecho-plugin) 7 | 8 | A maven plugin that lets you output text during Maven build 9 | 10 | It can be used with a file: 11 | 12 | ```xml 13 | 14 | com.github.ekryd.echo-maven-plugin 15 | echo-maven-plugin 16 | 2.0.0 17 | false 18 | 19 | 20 | welcome 21 | 22 | echo 23 | 24 | 25 | misc/welcome.txt 26 | 27 | 28 | 29 | 30 | 31 | ``` 32 | 33 | Or with a string directly (note that Maven properties can be used): 34 | 35 | ```xml 36 | 37 | com.github.ekryd.echo-maven-plugin 38 | echo-maven-plugin 39 | 2.0.0 40 | false 41 | 42 | 43 | end 44 | 45 | echo 46 | 47 | install 48 | 49 | ${line.separator} To run the plugin directly:${line.separator} mvn ${project.groupId}:${project.artifactId}:${project.version}:sort${line.separator} 50 | 51 | 52 | 53 | 54 | ``` 55 | 56 | See more in the [Cookbook](https://github.com/Ekryd/echo-maven-plugin/wiki/Cookbook) 57 | -------------------------------------------------------------------------------- /echo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | 8 | com.github.ekryd.echo-maven-plugin 9 | echo-plugin 10 | 2.1.1-SNAPSHOT 11 | 12 | 13 | 14 | echo-output 15 | jar 16 | Echo output 17 | 18 | 19 | 20 | commons-io 21 | commons-io 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/CharacterOutput.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import echo.parameter.PluginParameters; 4 | 5 | /** Converts the message content as a user-friendly character string */ 6 | class CharacterOutput { 7 | private final boolean writeOutput; 8 | 9 | private boolean firstCharacter = true; 10 | private StringBuilder outputStringBuilder; 11 | 12 | /** 13 | * Create a new instance of the CharacterOutput class 14 | * 15 | * @param pluginParameters The user-supplied plugin parameters 16 | */ 17 | public CharacterOutput(PluginParameters pluginParameters) { 18 | writeOutput = pluginParameters.isCharacterOutput(); 19 | } 20 | 21 | /** Returns message content as a debug string, ready to be output */ 22 | public String getOutput(String message) { 23 | if (!writeOutput) { 24 | return ""; 25 | } 26 | generateOutput(message.toCharArray()); 27 | 28 | return outputStringBuilder.toString(); 29 | } 30 | 31 | private void generateOutput(char[] messageChars) { 32 | outputStringBuilder = new StringBuilder(); 33 | outputStringBuilder.append("["); 34 | for (var messageChar : messageChars) { 35 | appendOneCharOutput(messageChar); 36 | } 37 | outputStringBuilder.append("]"); 38 | } 39 | 40 | private void appendOneCharOutput(char messageChar) { 41 | if (firstCharacter) { 42 | firstCharacter = false; 43 | } else { 44 | outputStringBuilder.append(","); 45 | } 46 | outputStringBuilder 47 | .append("['") 48 | .append(messageChar) 49 | .append("' , ") 50 | .append((int) messageChar) 51 | .append(" ") 52 | .append("]"); 53 | } 54 | 55 | public boolean isWriteOutput() { 56 | return writeOutput; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/EchoPlugin.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import echo.output.EchoOutput; 4 | import echo.output.EchoOutputWrapper; 5 | import echo.output.PluginLog; 6 | import echo.parameter.PluginParameters; 7 | import echo.util.FileUtil; 8 | 9 | /** 10 | * The concrete implementation of the echo plugin functionality 11 | * 12 | * @author bjorn 13 | * @since 2013-08-08 14 | */ 15 | class EchoPlugin { 16 | private final PluginLog mavenPluginLog; 17 | private final EchoOutputWrapper echoOutput; 18 | private final FileUtil fileUtil; 19 | private final MessageExtractor messageExtractor; 20 | private final CharacterOutput characterOutput; 21 | 22 | private final boolean writeMessageToFile; 23 | 24 | /** 25 | * Creates a new instance of the EchoPlugin 26 | * 27 | * @param mavenPluginLog wrapper for the maven internal plugin logger 28 | * @param pluginParameters the user-supplied plugin parameters 29 | * @param echoOutput the utility class to output to standard output (in Maven) 30 | */ 31 | public EchoPlugin( 32 | PluginLog mavenPluginLog, PluginParameters pluginParameters, EchoOutput echoOutput) { 33 | this.mavenPluginLog = mavenPluginLog; 34 | this.echoOutput = new EchoOutputWrapper(echoOutput, pluginParameters); 35 | this.fileUtil = new FileUtil(pluginParameters, mavenPluginLog); 36 | this.messageExtractor = new MessageExtractor(pluginParameters, fileUtil); 37 | this.characterOutput = new CharacterOutput(pluginParameters); 38 | 39 | this.writeMessageToFile = pluginParameters.getToFile() != null; 40 | } 41 | 42 | /** Output the message */ 43 | public void echo() { 44 | var messageWithCorrectNewlines = messageExtractor.getFormattedMessage(); 45 | 46 | if (characterOutput.isWriteOutput()) { 47 | var characterArray = characterOutput.getOutput(messageExtractor.getOriginalMessage()); 48 | mavenPluginLog.info(characterArray); 49 | } 50 | 51 | if (writeMessageToFile) { 52 | fileUtil.saveToFile(messageWithCorrectNewlines); 53 | } else { 54 | echoOutput.output(messageWithCorrectNewlines); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/MessageExtractor.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import echo.exception.FailureException; 4 | import echo.output.NewlineFormatter; 5 | import echo.parameter.PluginParameters; 6 | import echo.util.FileUtil; 7 | import java.io.IOException; 8 | 9 | /** 10 | * Retrieves the message to output either from file or as an input parameter. The message is also 11 | * formatted correctly. 12 | */ 13 | class MessageExtractor { 14 | private final FileUtil fileUtil; 15 | private final NewlineFormatter newlineFormatter; 16 | 17 | private final String message; 18 | private final String fromFile; 19 | private String originalMessage; 20 | 21 | /** 22 | * Create a new instance of the MessageExtractor 23 | * 24 | * @param pluginParameters The user-supplied plugin parameters 25 | * @param fileUtil File system interaction class 26 | */ 27 | public MessageExtractor(PluginParameters pluginParameters, FileUtil fileUtil) { 28 | this.fileUtil = fileUtil; 29 | this.newlineFormatter = new NewlineFormatter(pluginParameters); 30 | 31 | this.message = pluginParameters.getMessage(); 32 | this.fromFile = pluginParameters.getFromFile(); 33 | } 34 | 35 | /** Returns a message the is ready for output */ 36 | public String getFormattedMessage() { 37 | extractMessage(); 38 | 39 | return newlineFormatter.format(originalMessage); 40 | } 41 | 42 | private void extractMessage() { 43 | checkMissingMessage(); 44 | if (message != null) { 45 | originalMessage = message; 46 | } else { 47 | try { 48 | originalMessage = fileUtil.getFromFile(); 49 | } catch (IOException ex) { 50 | throw new FailureException(ex.getMessage(), ex); 51 | } 52 | } 53 | } 54 | 55 | private void checkMissingMessage() { 56 | if (message == null && fromFile == null) { 57 | throw new FailureException("There was nothing to output. Specify either message or fromFile"); 58 | } 59 | if (message != null && fromFile != null) { 60 | throw new FailureException("Specify either message or fromFile, not both"); 61 | } 62 | } 63 | 64 | public String getOriginalMessage() { 65 | return originalMessage; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/exception/FailureException.java: -------------------------------------------------------------------------------- 1 | package echo.exception; 2 | 3 | /** 4 | * An exception occurring during the execution of the plugin. Throwing this exception should cause a 5 | * "BUILD FAILURE" message to be displayed in Maven. 6 | */ 7 | public class FailureException extends RuntimeException { 8 | public static final String UNSUPPORTED_ENCODING = "Unsupported encoding: "; 9 | 10 | /** Create a new instance with message and what caused the failure */ 11 | public FailureException(String msg, Throwable cause) { 12 | super(msg, cause); 13 | } 14 | 15 | /** Create a new instance with a message describing what happened */ 16 | public FailureException(String msg) { 17 | super(msg); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/output/EchoOutput.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | /** Output a message to standard output with a specific level */ 4 | public interface EchoOutput { 5 | /** The message will be output with a failure level (exception will occur) */ 6 | void fail(String content); 7 | 8 | /** The message will be output with error level */ 9 | void error(String content); 10 | 11 | /** The message will be output with warning level */ 12 | void warning(String content); 13 | 14 | /** The message will be output with info level (default level) */ 15 | void info(String content); 16 | 17 | /** 18 | * The message will be output with debug level (maven debugging must be turned on to see message) 19 | */ 20 | void debug(String content); 21 | } 22 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/output/EchoOutputWrapper.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | import echo.parameter.OutputLevelType; 4 | import echo.parameter.PluginParameters; 5 | 6 | /** Will echo a message to standard output (in Maven) with the right message level. */ 7 | public class EchoOutputWrapper { 8 | private final EchoOutput echoOutput; 9 | private final OutputLevelType level; 10 | 11 | /** 12 | * Creates a new instance of the EchoOutputWrapper class 13 | * 14 | * @param echoOutput the utility class to output to standard output (in Maven) 15 | * @param pluginParameters The user-supplied plugin parameters 16 | */ 17 | public EchoOutputWrapper(EchoOutput echoOutput, PluginParameters pluginParameters) { 18 | this.echoOutput = echoOutput; 19 | this.level = pluginParameters.getLevel(); 20 | } 21 | 22 | /** Echo the content to standard output (in Maven) */ 23 | public void output(String content) { 24 | if (content.length() == 0) { 25 | return; 26 | } 27 | 28 | switch (level) { 29 | case FAIL: 30 | echoOutput.fail(content); 31 | break; 32 | case ERROR: 33 | echoOutput.error(content); 34 | break; 35 | case WARNING: 36 | echoOutput.warning(content); 37 | break; 38 | case INFO: 39 | echoOutput.info(content); 40 | break; 41 | case DEBUG: 42 | echoOutput.debug(content); 43 | break; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/output/NewlineFormatter.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | import echo.parameter.PluginParameters; 4 | 5 | /** Formats end of line characters according to desired format */ 6 | public class NewlineFormatter { 7 | private static final String NEWLINES_REG_EX = "\\r\\n|\\r|\\n"; 8 | private final String lineSeparator; 9 | 10 | /** 11 | * Creates a new instance of NewlineSeparator 12 | * 13 | * @param pluginParameters The user-supplied plugin parameters 14 | */ 15 | public NewlineFormatter(PluginParameters pluginParameters) { 16 | this.lineSeparator = pluginParameters.getLineSeparator().getFormattedLineSeparator(); 17 | } 18 | 19 | /** Format the message with the desired end of line characters */ 20 | public String format(String output) { 21 | return output.replaceAll(NEWLINES_REG_EX, lineSeparator); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/output/PluginLog.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | /** Interface for the internal Maven plugin logger */ 4 | public interface PluginLog { 5 | /** 6 | * Send a message to the log in the info level. 7 | * 8 | * @param content info message 9 | */ 10 | void info(String content); 11 | 12 | /** 13 | * Log the throwable to the debug level. 14 | * 15 | * @param throwable the "exception" to log 16 | */ 17 | void debug(Throwable throwable); 18 | 19 | /** Log the content to the debug level. */ 20 | void debug(String content); 21 | } 22 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/parameter/LineSeparator.java: -------------------------------------------------------------------------------- 1 | package echo.parameter; 2 | 3 | import echo.exception.FailureException; 4 | import java.util.Arrays; 5 | 6 | /** Encapsulates end of line character logic. */ 7 | public class LineSeparator { 8 | private final String formattedLineSeparator; 9 | private final String lineSeparatorString; 10 | 11 | /** 12 | * Creates a line separator and makes sure that it is either \n, \r or \r\n 13 | * 14 | * @param lineSeparatorString The line separator characters 15 | */ 16 | LineSeparator(final String lineSeparatorString) { 17 | this.lineSeparatorString = lineSeparatorString; 18 | this.formattedLineSeparator = lineSeparatorString.replace("\\r", "\r").replace("\\n", "\n"); 19 | } 20 | 21 | void checkLineSeparator() { 22 | if (isIllegalString()) { 23 | throw new FailureException( 24 | "LineSeparator must be either \\n, \\r or \\r\\n, but separator characters were " 25 | + Arrays.toString(lineSeparatorString.getBytes())); 26 | } 27 | } 28 | 29 | private boolean isIllegalString() { 30 | return !("\n".equalsIgnoreCase(formattedLineSeparator) 31 | || "\r".equalsIgnoreCase(formattedLineSeparator) 32 | || "\r\n".equalsIgnoreCase(formattedLineSeparator)); 33 | } 34 | 35 | public String getFormattedLineSeparator() { 36 | return formattedLineSeparator; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/parameter/OutputLevelType.java: -------------------------------------------------------------------------------- 1 | package echo.parameter; 2 | 3 | import echo.exception.FailureException; 4 | import java.util.Locale; 5 | import java.util.function.Function; 6 | 7 | /** Defines the different levels a message can be output to. INFO is the default level */ 8 | public enum OutputLevelType { 9 | FAIL(name -> "FAIL".equals(name) || "FATAL".equals(name)), 10 | ERROR("ERROR"::equals), 11 | WARNING(name -> "WARNING".equals(name) || "WARN".equals(name)), 12 | INFO("INFO"::equals), 13 | DEBUG(name -> "DEBUG".equals(name) || "TRACE".equals(name)); 14 | 15 | private final Function matchName; 16 | 17 | private static final String ERROR_LEVEL_MSG = 18 | "level must be either FAIL, ERROR, WARNING, INFO or DEBUG."; 19 | 20 | OutputLevelType(Function matchName) { 21 | this.matchName = matchName; 22 | } 23 | 24 | /** Converts a string to the corresponding context */ 25 | static OutputLevelType fromString(String level) { 26 | if (level == null) { 27 | throw new FailureException(ERROR_LEVEL_MSG + " Was: null"); 28 | } 29 | var upperCaseLevel = level.toUpperCase(Locale.getDefault()); 30 | for (var outputLevelType : values()) { 31 | if (Boolean.TRUE.equals(outputLevelType.matchName.apply(upperCaseLevel))) { 32 | return outputLevelType; 33 | } 34 | } 35 | throw new FailureException(ERROR_LEVEL_MSG + " Was: " + level); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/parameter/PluginParameters.java: -------------------------------------------------------------------------------- 1 | package echo.parameter; 2 | 3 | import java.io.File; 4 | 5 | /** Contains all parameters that are sent to the plugin */ 6 | public class PluginParameters { 7 | 8 | private final String message; 9 | private final String fromFile; 10 | private final File basePath; 11 | private final String toFile; 12 | private final boolean appendToFile; 13 | private final boolean force; 14 | private final OutputLevelType level; 15 | private final String encoding; 16 | private final LineSeparator lineSeparator; 17 | private final boolean characterOutput; 18 | 19 | /** Creates an instance of PluginParameters with user-supplied plugin parameters */ 20 | public PluginParameters( 21 | String message, 22 | String fromFile, 23 | File basePath, 24 | String toFile, 25 | boolean appendToFile, 26 | boolean force, 27 | OutputLevelType level, 28 | String encoding, 29 | LineSeparator lineSeparator, 30 | boolean characterOutput) { 31 | this.message = message; 32 | this.fromFile = fromFile; 33 | this.basePath = basePath; 34 | this.toFile = toFile; 35 | this.appendToFile = appendToFile; 36 | this.force = force; 37 | this.level = level; 38 | this.encoding = encoding; 39 | this.lineSeparator = lineSeparator; 40 | this.characterOutput = characterOutput; 41 | } 42 | 43 | public String getMessage() { 44 | return message; 45 | } 46 | 47 | public String getFromFile() { 48 | return fromFile; 49 | } 50 | 51 | public File getBasePath() { 52 | return basePath; 53 | } 54 | 55 | public String getToFile() { 56 | return toFile; 57 | } 58 | 59 | public boolean isAppendToFile() { 60 | return appendToFile; 61 | } 62 | 63 | public boolean isForce() { 64 | return force; 65 | } 66 | 67 | public OutputLevelType getLevel() { 68 | return level; 69 | } 70 | 71 | public String getEncoding() { 72 | return encoding; 73 | } 74 | 75 | public LineSeparator getLineSeparator() { 76 | return lineSeparator; 77 | } 78 | 79 | public boolean isCharacterOutput() { 80 | return characterOutput; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/parameter/PluginParametersBuilder.java: -------------------------------------------------------------------------------- 1 | package echo.parameter; 2 | 3 | import java.io.File; 4 | 5 | /** Creates a PluginParameter instance using the Builder pattern */ 6 | public class PluginParametersBuilder { 7 | private String message; 8 | private String fromFile; 9 | private File basePath; 10 | private String toFile; 11 | private boolean appendToFile; 12 | private boolean force; 13 | private OutputLevelType level = OutputLevelType.INFO; 14 | private String encoding = "UTF-8"; 15 | private LineSeparator lineSeparator = new LineSeparator("\n"); 16 | private boolean characterOutput; 17 | 18 | /** Sets input to plugin, either from message or file */ 19 | public PluginParametersBuilder setMessage(String message, String fromFile) { 20 | this.message = message; 21 | this.fromFile = fromFile; 22 | return this; 23 | } 24 | 25 | /** Sets file output for plugin */ 26 | public PluginParametersBuilder setFile( 27 | File basePath, String toFile, boolean appendToFile, boolean force) { 28 | this.basePath = basePath; 29 | this.toFile = toFile; 30 | this.appendToFile = appendToFile; 31 | this.force = force; 32 | return this; 33 | } 34 | 35 | /** Sets message level fro plugin */ 36 | public PluginParametersBuilder setLevel(String level) { 37 | this.level = OutputLevelType.fromString(level); 38 | return this; 39 | } 40 | 41 | /** Sets message formatting for plugin */ 42 | public PluginParametersBuilder setFormatting(String encoding, String lineSeparatorString) { 43 | this.encoding = encoding; 44 | this.lineSeparator = new LineSeparator(lineSeparatorString); 45 | return this; 46 | } 47 | 48 | /** Set message content debug flag for plugin */ 49 | public PluginParametersBuilder setDebug(boolean characterOutput) { 50 | this.characterOutput = characterOutput; 51 | return this; 52 | } 53 | 54 | /** Builds the PluginParameters instance */ 55 | public PluginParameters createPluginParameters() { 56 | lineSeparator.checkLineSeparator(); 57 | 58 | return new PluginParameters( 59 | message, 60 | fromFile, 61 | basePath, 62 | toFile, 63 | appendToFile, 64 | force, 65 | level, 66 | encoding, 67 | lineSeparator, 68 | characterOutput); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package echo.util; 2 | 3 | import static echo.exception.FailureException.UNSUPPORTED_ENCODING; 4 | 5 | import echo.exception.FailureException; 6 | import echo.output.PluginLog; 7 | import echo.parameter.PluginParameters; 8 | import java.io.*; 9 | import java.nio.charset.UnsupportedCharsetException; 10 | import org.apache.commons.io.FileUtils; 11 | import org.apache.commons.io.IOUtils; 12 | 13 | /** Used to interface with file system */ 14 | public class FileUtil { 15 | private static final String READING_INPUT_FROM = "Reading input from "; 16 | private final PluginLog mavenPluginLog; 17 | private final String encoding; 18 | private final String fromFile; 19 | private final File basePath; 20 | private final String toFile; 21 | private final boolean appendToFile; 22 | private final boolean forceOverwrite; 23 | 24 | /** 25 | * Create a new instance of the FileUtil 26 | * 27 | * @param parameters The user-supplied plugin parameters 28 | * @param mavenPluginLog Wrapper for Maven internal plugin logger 29 | */ 30 | public FileUtil(PluginParameters parameters, PluginLog mavenPluginLog) { 31 | this.mavenPluginLog = mavenPluginLog; 32 | this.encoding = parameters.getEncoding(); 33 | this.fromFile = parameters.getFromFile(); 34 | this.basePath = parameters.getBasePath(); 35 | this.toFile = parameters.getToFile(); 36 | this.appendToFile = parameters.isAppendToFile(); 37 | this.forceOverwrite = parameters.isForce(); 38 | } 39 | 40 | /** 41 | * Saves text output 42 | * 43 | * @param message The text to save 44 | */ 45 | public void saveToFile(final String message) { 46 | var saveFile = new File(basePath, toFile); 47 | var absolutePath = saveFile.getAbsolutePath(); 48 | mavenPluginLog.info("Saving output to " + absolutePath); 49 | 50 | try { 51 | checkForNonWritableFile(saveFile); 52 | makeFileWritable(saveFile); 53 | FileUtils.write(saveFile, message, encoding, appendToFile); 54 | } catch (UnsupportedEncodingException | UnsupportedCharsetException ex) { 55 | throw new FailureException(UNSUPPORTED_ENCODING + ex.getMessage(), ex); 56 | } catch (IOException ex) { 57 | mavenPluginLog.debug(ex); 58 | throw new FailureException("Could not save file: " + absolutePath, ex); 59 | } 60 | } 61 | 62 | private void checkForNonWritableFile(File saveFile) { 63 | if (saveFile.isDirectory()) { 64 | throw new FailureException( 65 | "File " + saveFile.getAbsolutePath() + " exists but is a directory"); 66 | } 67 | } 68 | 69 | private void makeFileWritable(File saveFile) { 70 | if (saveFile.isFile() && saveFile.exists() && !saveFile.canWrite()) { 71 | if (forceOverwrite) { 72 | var writableStatus = saveFile.setWritable(true); 73 | if (!writableStatus) { 74 | throw new FailureException("Could not make file writable " + saveFile.getAbsolutePath()); 75 | } 76 | } else { 77 | throw new FailureException("Cannot write to read-only file " + saveFile.getAbsolutePath()); 78 | } 79 | } 80 | } 81 | 82 | /** 83 | * Retrieves the message from the location in attribute fromFile 84 | * 85 | * @return Content of the default sort order file 86 | */ 87 | public String getFromFile() throws IOException { 88 | var urlWrapper = new UrlWrapper(fromFile); 89 | try (var inputStream = 90 | urlWrapper.isUrl() 91 | ? urlWrapper.openStream() 92 | : getFileFromRelativeOrClassPath(basePath, fromFile)) { 93 | return IOUtils.toString(inputStream, encoding); 94 | } catch (UnsupportedEncodingException | UnsupportedCharsetException ex) { 95 | throw new FailureException(UNSUPPORTED_ENCODING + ex.getMessage(), ex); 96 | } 97 | } 98 | 99 | private InputStream getFileFromRelativeOrClassPath(File basePath, String file) 100 | throws IOException { 101 | var findFileInAbsolutePath = new FindFileInAbsolutePath(mavenPluginLog); 102 | 103 | findFileInAbsolutePath.openFile(new File(file)); 104 | if (findFileInAbsolutePath.isFound()) { 105 | mavenPluginLog.debug(READING_INPUT_FROM + findFileInAbsolutePath.getAbsoluteFilePath()); 106 | 107 | return findFileInAbsolutePath.getInputStream(); 108 | } 109 | 110 | findFileInAbsolutePath.openFile(new File(basePath, file)); 111 | if (findFileInAbsolutePath.isFound()) { 112 | mavenPluginLog.debug(READING_INPUT_FROM + findFileInAbsolutePath.getAbsoluteFilePath()); 113 | 114 | return findFileInAbsolutePath.getInputStream(); 115 | } 116 | 117 | var findFileInClassPath = new FindFileInClassPath(mavenPluginLog); 118 | findFileInClassPath.openFile(file); 119 | if (findFileInClassPath.isFound()) { 120 | mavenPluginLog.debug(READING_INPUT_FROM + findFileInClassPath.getAbsoluteFilePath()); 121 | 122 | return findFileInClassPath.getInputStream(); 123 | } 124 | 125 | throw new FileNotFoundException( 126 | String.format( 127 | "Could not find %s, %s or %s in classpath", 128 | new File(file).getAbsolutePath(), new File(basePath, file).getAbsolutePath(), file)); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/util/FindFileInAbsolutePath.java: -------------------------------------------------------------------------------- 1 | package echo.util; 2 | 3 | import echo.output.PluginLog; 4 | import java.io.File; 5 | import java.io.FileInputStream; 6 | import java.io.FileNotFoundException; 7 | 8 | /** Try to retrieve content from an absolute file path. Example /usr/bin/content.txt */ 9 | class FindFileInAbsolutePath { 10 | 11 | private final PluginLog mavenPluginLog; 12 | 13 | private FileInputStream inputStream; 14 | private String absoluteFilePath; 15 | 16 | /** 17 | * Creates a new instance of the class 18 | * 19 | * @param mavenPluginLog Wrapper for Maven internal plugin logger 20 | */ 21 | public FindFileInAbsolutePath(PluginLog mavenPluginLog) { 22 | this.mavenPluginLog = mavenPluginLog; 23 | } 24 | 25 | /** Try to open a stream to the file location */ 26 | public void openFile(File absoluteFilePath) { 27 | try { 28 | this.inputStream = new FileInputStream(absoluteFilePath); 29 | this.absoluteFilePath = absoluteFilePath.getAbsolutePath(); 30 | } catch (FileNotFoundException fex) { 31 | mavenPluginLog.debug(fex); 32 | inputStream = null; 33 | } 34 | } 35 | 36 | /** Return true if stream is opened to file path */ 37 | public boolean isFound() { 38 | return inputStream != null; 39 | } 40 | 41 | public String getAbsoluteFilePath() { 42 | return absoluteFilePath; 43 | } 44 | 45 | /** Return stream to file path content */ 46 | public FileInputStream getInputStream() { 47 | return inputStream; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/util/FindFileInClassPath.java: -------------------------------------------------------------------------------- 1 | package echo.util; 2 | 3 | import echo.output.PluginLog; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | 7 | /** Try to retrieve content from the java class path. Usually placed under src/main/resources */ 8 | class FindFileInClassPath { 9 | 10 | private final PluginLog mavenPluginLog; 11 | 12 | private InputStream inputStream; 13 | private String absoluteFilePath; 14 | 15 | /** 16 | * Creates a new instance of the class 17 | * 18 | * @param mavenPluginLog Wrapper for Maven internal plugin logger 19 | */ 20 | public FindFileInClassPath(PluginLog mavenPluginLog) { 21 | this.mavenPluginLog = mavenPluginLog; 22 | } 23 | 24 | /** Try to open a stream to the file location in the class path */ 25 | public void openFile(String fileName) { 26 | try { 27 | var resource = this.getClass().getClassLoader().getResource(fileName); 28 | if (resource != null) { 29 | this.inputStream = resource.openStream(); 30 | this.absoluteFilePath = resource.getPath(); 31 | } 32 | } catch (IOException iex) { 33 | mavenPluginLog.debug(iex); 34 | } 35 | } 36 | 37 | /** Return true if stream is opened to file content */ 38 | public boolean isFound() { 39 | return inputStream != null; 40 | } 41 | 42 | /** Return stream to file content */ 43 | public InputStream getInputStream() { 44 | return inputStream; 45 | } 46 | 47 | public String getAbsoluteFilePath() { 48 | return absoluteFilePath; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /echo/src/main/java/echo/util/UrlWrapper.java: -------------------------------------------------------------------------------- 1 | package echo.util; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.MalformedURLException; 6 | import java.net.URL; 7 | 8 | /** 9 | * Wraps the java URL class so that it exposes methods to determine if entered values are urls or 10 | * not. 11 | */ 12 | class UrlWrapper { 13 | private final String spec; 14 | 15 | /** Creates a new UrlWrapper with a supplied url */ 16 | public UrlWrapper(String spec) { 17 | this.spec = spec; 18 | } 19 | 20 | /** Returns true if the specified string is a URL */ 21 | public boolean isUrl() { 22 | try { 23 | new URL(spec); 24 | return true; 25 | } catch (MalformedURLException e) { 26 | return false; 27 | } 28 | } 29 | 30 | /** Open an input stream to the location of the url */ 31 | public InputStream openStream() throws IOException { 32 | var url = new URL(spec); 33 | return url.openStream(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/CharacterOutputTest.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.mockito.Mockito.mock; 7 | import static org.mockito.Mockito.verify; 8 | 9 | import echo.output.EchoOutput; 10 | import echo.output.PluginLog; 11 | import echo.parameter.PluginParametersBuilder; 12 | import org.junit.jupiter.api.Test; 13 | 14 | class CharacterOutputTest { 15 | private final PluginLog pluginLog = mock(PluginLog.class); 16 | private final EchoOutput echoOutput = mock(EchoOutput.class); 17 | 18 | @Test 19 | void noDebugShouldReturnZeroString() { 20 | var characterOutput = 21 | new CharacterOutput(new PluginParametersBuilder().setDebug(false).createPluginParameters()); 22 | assertEquals("", characterOutput.getOutput("")); 23 | } 24 | 25 | @Test 26 | void emptyStringShouldBeEmptyBrackets() { 27 | var characterOutput = 28 | new CharacterOutput(new PluginParametersBuilder().setDebug(true).createPluginParameters()); 29 | assertEquals("[]", characterOutput.getOutput("")); 30 | } 31 | 32 | @Test 33 | void specialCharactersShouldBeOutput() { 34 | var pluginParameters = new PluginParametersBuilder().setDebug(true).createPluginParameters(); 35 | var characterOutput = new CharacterOutput(pluginParameters); 36 | assertThat( 37 | characterOutput.getOutput("\u00f6\u00e4\u00e5\u00d6\u00c4\u00c5"), 38 | is("[['ö' , 246 ],['ä' , 228 ],['å' , 229 ],['Ö' , 214 ],['Ä' , 196 ],['Å' , 197 ]]")); 39 | } 40 | 41 | @Test 42 | void foundFileInClassPathShouldOutputToInfo() { 43 | var parameters = 44 | new PluginParametersBuilder() 45 | .setMessage(null, "messageText.txt") 46 | .setDebug(true) 47 | .createPluginParameters(); 48 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 49 | echoPlugin.echo(); 50 | 51 | verify(pluginLog).info("[['B' , 66 ],['j' , 106 ],['ö' , 246 ],['r' , 114 ],['n' , 110 ]]"); 52 | verify(echoOutput).info("Björn"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestAppendOption.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.mockito.Mockito.*; 6 | 7 | import echo.output.EchoOutput; 8 | import echo.output.PluginLog; 9 | import echo.parameter.PluginParameters; 10 | import echo.parameter.PluginParametersBuilder; 11 | import java.io.File; 12 | import java.io.IOException; 13 | import org.apache.commons.io.FileUtils; 14 | import org.junit.jupiter.api.BeforeEach; 15 | import org.junit.jupiter.api.Test; 16 | 17 | class TestAppendOption { 18 | private final PluginLog pluginLog = mock(PluginLog.class); 19 | private final EchoOutput echoOutput = mock(EchoOutput.class); 20 | private String fileName = null; 21 | 22 | @BeforeEach 23 | void setup() { 24 | doAnswer( 25 | invocation -> { 26 | var content = invocation.getArguments()[0].toString(); 27 | if (content.startsWith("Saving output to ")) { 28 | fileName = content.substring(17); 29 | } 30 | return null; 31 | }) 32 | .when(pluginLog) 33 | .info(anyString()); 34 | } 35 | 36 | @Test 37 | void explicitAppendFlagShouldAppendToFile() throws IOException { 38 | var parameters = 39 | new PluginParametersBuilder() 40 | .setMessage("Björn", null) 41 | .setFile(new File("."), "test.txt", true, false) 42 | .createPluginParameters(); 43 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 44 | 45 | try { 46 | // Echo twice 47 | echoPlugin.echo(); 48 | echoPlugin.echo(); 49 | 50 | verifyNoInteractions(echoOutput); 51 | 52 | var output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 53 | assertThat(output, is("BjörnBjörn")); 54 | } finally { 55 | FileUtils.deleteQuietly(new File(fileName)); 56 | } 57 | } 58 | 59 | @Test 60 | void noAppendFlagShouldOverwriteFile() { 61 | PluginParameters parameters; 62 | EchoPlugin echoPlugin; 63 | String output; 64 | 65 | try { 66 | parameters = 67 | new PluginParametersBuilder() 68 | .setMessage("One", null) 69 | .setFile(new File("."), "test.txt", false, false) 70 | .createPluginParameters(); 71 | echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 72 | echoPlugin.echo(); 73 | 74 | output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 75 | assertThat(output, is("One")); 76 | 77 | parameters = 78 | new PluginParametersBuilder() 79 | .setMessage("Two", null) 80 | .setFile(new File("."), "test.txt", false, false) 81 | .createPluginParameters(); 82 | echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 83 | echoPlugin.echo(); 84 | 85 | verifyNoInteractions(echoOutput); 86 | 87 | output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 88 | assertThat(output, is("Two")); 89 | } catch (IOException e) { 90 | e.printStackTrace(); 91 | } finally { 92 | FileUtils.deleteQuietly(new File(fileName)); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestCharacterOutput.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.mockito.Mockito.mock; 4 | import static org.mockito.Mockito.verify; 5 | 6 | import echo.output.EchoOutput; 7 | import echo.output.PluginLog; 8 | import echo.parameter.PluginParametersBuilder; 9 | import org.junit.jupiter.api.Test; 10 | 11 | class TestCharacterOutput { 12 | 13 | private final PluginLog pluginLog = mock(PluginLog.class); 14 | private final EchoOutput echoOutput = mock(EchoOutput.class); 15 | 16 | @Test 17 | void characterDebugOutputShouldOutputToInfoLevel() { 18 | var parameters = 19 | new PluginParametersBuilder() 20 | .setMessage("Gurka", null) 21 | .setLevel("DEBUG") 22 | .setDebug(true) 23 | .createPluginParameters(); 24 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 25 | 26 | echoPlugin.echo(); 27 | 28 | verify(pluginLog).info("[['G' , 71 ],['u' , 117 ],['r' , 114 ],['k' , 107 ],['a' , 97 ]]"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestEncoding.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.junit.jupiter.api.Assertions.assertThrows; 7 | import static org.mockito.Mockito.*; 8 | 9 | import echo.exception.FailureException; 10 | import echo.output.EchoOutput; 11 | import echo.output.PluginLog; 12 | import echo.parameter.PluginParametersBuilder; 13 | import java.io.File; 14 | import java.io.IOException; 15 | import org.apache.commons.io.FileUtils; 16 | import org.junit.jupiter.api.BeforeEach; 17 | import org.junit.jupiter.api.Test; 18 | import org.junit.jupiter.api.function.Executable; 19 | 20 | class TestEncoding { 21 | 22 | private final PluginLog pluginLog = mock(PluginLog.class); 23 | private final EchoOutput echoOutput = mock(EchoOutput.class); 24 | 25 | private String fileName = null; 26 | 27 | @BeforeEach 28 | void setupForSaveToFile() { 29 | doAnswer( 30 | invocation -> { 31 | var content = invocation.getArguments()[0].toString(); 32 | if (content.startsWith("Saving output to ")) { 33 | fileName = content.substring(17); 34 | } 35 | return null; 36 | }) 37 | .when(pluginLog) 38 | .info(anyString()); 39 | } 40 | 41 | @Test 42 | void illegalEncodingShouldThrowExceptionWhenReadFromFile() { 43 | var parameters = 44 | new PluginParametersBuilder() 45 | .setMessage(null, "messageEncoding.txt") 46 | .setFormatting("Gurka", "\n") 47 | .createPluginParameters(); 48 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 49 | 50 | Executable testMethod = echoPlugin::echo; 51 | 52 | var thrown = assertThrows(FailureException.class, testMethod); 53 | 54 | assertThat(thrown.getMessage(), is(equalTo("Unsupported encoding: Gurka"))); 55 | } 56 | 57 | @Test 58 | void illegalEncodingShouldThrowExceptionWhenWriteToFile() { 59 | var parameters = 60 | new PluginParametersBuilder() 61 | .setMessage("TestMessage", null) 62 | .setFormatting("Gurka", "\n") 63 | .setFile(new File("."), "out.txt", false, false) 64 | .createPluginParameters(); 65 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 66 | 67 | Executable testMethod = echoPlugin::echo; 68 | 69 | var thrown = assertThrows(FailureException.class, testMethod); 70 | 71 | assertThat(thrown.getMessage(), is(equalTo("Unsupported encoding: Gurka"))); 72 | } 73 | 74 | @Test 75 | void differentEncodingShouldWorkFromFile() { 76 | var parameters = 77 | new PluginParametersBuilder() 78 | .setMessage(null, "messageEncoding.txt") 79 | .setFormatting("iso-8859-1", "\n") 80 | .createPluginParameters(); 81 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 82 | 83 | echoPlugin.echo(); 84 | 85 | verify(echoOutput).info("Björn"); 86 | } 87 | 88 | @Test 89 | void differentEncodingShouldBeIgnoredFromInput() { 90 | var parameters = 91 | new PluginParametersBuilder() 92 | .setMessage("Björn", null) 93 | .setFormatting("iso-8859-1", "\n") 94 | .createPluginParameters(); 95 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 96 | 97 | echoPlugin.echo(); 98 | 99 | verify(echoOutput).info("Björn"); 100 | } 101 | 102 | @Test 103 | void outputUtf8ShouldWorkToStdOut() { 104 | var parameters = 105 | new PluginParametersBuilder() 106 | .setMessage("ä©", null) 107 | .setFormatting("UTF-8", "\n") 108 | .createPluginParameters(); 109 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 110 | echoPlugin.echo(); 111 | 112 | verify(echoOutput).info("ä©"); 113 | } 114 | 115 | @Test 116 | void outputUtf8ShouldWorkToFile() throws IOException { 117 | var parameters = 118 | new PluginParametersBuilder() 119 | .setMessage("ä©", null) 120 | .setFile(new File("."), "test.txt", false, false) 121 | .setFormatting("UTF-8", "\n") 122 | .createPluginParameters(); 123 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 124 | 125 | try { 126 | echoPlugin.echo(); 127 | 128 | verifyNoInteractions(echoOutput); 129 | 130 | var output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 131 | assertThat(output, is("ä©")); 132 | } finally { 133 | FileUtils.deleteQuietly(new File(fileName)); 134 | } 135 | } 136 | 137 | @Test 138 | void outputUtf16ShouldWorkToFile() throws IOException { 139 | var parameters = 140 | new PluginParametersBuilder() 141 | .setMessage("©", null) 142 | .setFile(new File("."), "test.txt", false, false) 143 | .setFormatting("UTF16", "\n") 144 | .createPluginParameters(); 145 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 146 | 147 | try { 148 | echoPlugin.echo(); 149 | 150 | verifyNoInteractions(echoOutput); 151 | 152 | var output = FileUtils.readFileToString(new File(fileName), "UTF16"); 153 | assertThat(output, is("©")); 154 | } finally { 155 | FileUtils.deleteQuietly(new File(fileName)); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestForceOption.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.junit.jupiter.api.Assertions.assertThrows; 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | import static org.mockito.Mockito.*; 9 | 10 | import echo.exception.FailureException; 11 | import echo.output.EchoOutput; 12 | import echo.output.PluginLog; 13 | import echo.parameter.PluginParameters; 14 | import echo.parameter.PluginParametersBuilder; 15 | import java.io.File; 16 | import java.io.IOException; 17 | import org.apache.commons.io.FileUtils; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.function.Executable; 21 | 22 | class TestForceOption { 23 | private final PluginLog pluginLog = mock(PluginLog.class); 24 | private final EchoOutput echoOutput = mock(EchoOutput.class); 25 | private String fileName = null; 26 | 27 | @BeforeEach 28 | void setup() { 29 | doAnswer( 30 | invocation -> { 31 | var content = invocation.getArguments()[0].toString(); 32 | if (content.startsWith("Saving output to ")) { 33 | fileName = content.substring(17); 34 | } 35 | return null; 36 | }) 37 | .when(pluginLog) 38 | .info(anyString()); 39 | } 40 | 41 | @Test 42 | void explicitForceFlagShouldOverwriteReadOnlyFile() throws IOException { 43 | PluginParameters parameters; 44 | EchoPlugin echoPlugin; 45 | String output; 46 | 47 | try { 48 | parameters = 49 | new PluginParametersBuilder() 50 | .setMessage("One", null) 51 | .setFile(new File("."), "test.txt", false, true) 52 | .createPluginParameters(); 53 | echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 54 | echoPlugin.echo(); 55 | 56 | output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 57 | assertThat(output, is("One")); 58 | 59 | assertTrue(new File(fileName).setReadOnly()); 60 | 61 | parameters = 62 | new PluginParametersBuilder() 63 | .setMessage("Two", null) 64 | .setFile(new File("."), "test.txt", false, true) 65 | .createPluginParameters(); 66 | echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 67 | echoPlugin.echo(); 68 | 69 | verifyNoInteractions(echoOutput); 70 | 71 | output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 72 | assertThat(output, is("Two")); 73 | } catch (FailureException e) { 74 | assertThat(e.getMessage(), is("Cannot write to read-only file " + fileName)); 75 | } finally { 76 | FileUtils.deleteQuietly(new File(fileName)); 77 | } 78 | } 79 | 80 | @Test 81 | void noForceFlagShouldThrowExceptionForReadOnlyFile() throws IOException { 82 | 83 | try { 84 | var parameters1 = 85 | new PluginParametersBuilder() 86 | .setMessage("One", null) 87 | .setFile(new File("."), "test.txt", false, false) 88 | .createPluginParameters(); 89 | var echoPlugin1 = new EchoPlugin(pluginLog, parameters1, echoOutput); 90 | echoPlugin1.echo(); 91 | 92 | var output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 93 | assertThat(output, is("One")); 94 | 95 | assertTrue(new File(fileName).setReadOnly()); 96 | 97 | var parameters2 = 98 | new PluginParametersBuilder() 99 | .setMessage("Two", null) 100 | .setFile(new File("."), "test.txt", false, false) 101 | .createPluginParameters(); 102 | var echoPlugin2 = new EchoPlugin(pluginLog, parameters2, echoOutput); 103 | 104 | Executable testMethod = echoPlugin2::echo; 105 | 106 | var thrown = assertThrows(FailureException.class, testMethod); 107 | 108 | assertThat(thrown.getMessage(), is(equalTo("Cannot write to read-only file " + fileName))); 109 | 110 | } finally { 111 | FileUtils.deleteQuietly(new File(fileName)); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestFromFile.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.hamcrest.core.StringEndsWith.endsWith; 7 | import static org.hamcrest.core.StringStartsWith.startsWith; 8 | import static org.junit.jupiter.api.Assertions.assertAll; 9 | import static org.junit.jupiter.api.Assertions.assertThrows; 10 | import static org.mockito.Mockito.mock; 11 | import static org.mockito.Mockito.verify; 12 | 13 | import echo.exception.FailureException; 14 | import echo.output.EchoOutput; 15 | import echo.output.PluginLog; 16 | import echo.parameter.PluginParametersBuilder; 17 | import java.io.File; 18 | import java.io.IOException; 19 | import java.net.URL; 20 | import org.junit.jupiter.api.Test; 21 | import org.junit.jupiter.api.function.Executable; 22 | import org.mockito.ArgumentMatchers; 23 | 24 | class TestFromFile { 25 | 26 | private final PluginLog pluginLog = mock(PluginLog.class); 27 | private final EchoOutput echoOutput = mock(EchoOutput.class); 28 | 29 | @Test 30 | void noInputShouldThrowException() { 31 | 32 | var parameters = new PluginParametersBuilder().setMessage(null, null).createPluginParameters(); 33 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 34 | 35 | Executable testMethod = echoPlugin::echo; 36 | 37 | var thrown = assertThrows(FailureException.class, testMethod); 38 | 39 | assertThat( 40 | thrown.getMessage(), 41 | is(equalTo("There was nothing to output. Specify either message or fromFile"))); 42 | } 43 | 44 | @Test 45 | void doubleInputShouldThrowException() { 46 | 47 | var parameters = 48 | new PluginParametersBuilder().setMessage("Björn", "Gurka").createPluginParameters(); 49 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 50 | 51 | Executable testMethod = echoPlugin::echo; 52 | 53 | var thrown = assertThrows(FailureException.class, testMethod); 54 | 55 | assertThat(thrown.getMessage(), is(equalTo("Specify either message or fromFile, not both"))); 56 | } 57 | 58 | @Test 59 | void fileNotFoundShouldThrowException() { 60 | 61 | var parameters = 62 | new PluginParametersBuilder() 63 | .setMessage(null, "Gurka_doesNotExist") 64 | .createPluginParameters(); 65 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 66 | 67 | Executable testMethod = echoPlugin::echo; 68 | 69 | var thrown = assertThrows(FailureException.class, testMethod); 70 | 71 | assertAll( 72 | () -> assertThat(thrown.getMessage(), startsWith("Could not find ")), 73 | () -> 74 | assertThat( 75 | thrown.getMessage(), 76 | endsWith("Gurka_doesNotExist or Gurka_doesNotExist in classpath"))); 77 | } 78 | 79 | @Test 80 | void foundFileInClassPathShouldOutputToInfo() { 81 | var parameters = 82 | new PluginParametersBuilder().setMessage(null, "messageText.txt").createPluginParameters(); 83 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 84 | echoPlugin.echo(); 85 | 86 | verify(echoOutput).info("Björn"); 87 | } 88 | 89 | @Test 90 | void foundFileInAbsolutePathShouldOutputReadingLocation() { 91 | var absolutePath = new File("src/test/resources/messageText.txt").getAbsolutePath(); 92 | var parameters = 93 | new PluginParametersBuilder().setMessage(null, absolutePath).createPluginParameters(); 94 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 95 | echoPlugin.echo(); 96 | 97 | verify(pluginLog).debug("Reading input from " + absolutePath); 98 | } 99 | 100 | @Test 101 | void foundFileInSubModuleShouldOutputReadingLocation() { 102 | var fileName = "test/resources/messageText.txt"; 103 | var basePath = new File("src"); 104 | var parameters = 105 | new PluginParametersBuilder() 106 | .setMessage(null, fileName) 107 | .setFile(basePath, null, false, false) 108 | .createPluginParameters(); 109 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 110 | echoPlugin.echo(); 111 | 112 | verify(pluginLog).debug("Reading input from " + new File(basePath, fileName).getAbsolutePath()); 113 | } 114 | 115 | @Test 116 | void foundFileInClassPathShouldOutputReadingLocation() { 117 | var parameters = 118 | new PluginParametersBuilder().setMessage(null, "messageText.txt").createPluginParameters(); 119 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 120 | echoPlugin.echo(); 121 | 122 | var absolutePath = new File("target/test-classes/messageText.txt").toURI().getPath(); 123 | verify(pluginLog).debug("Reading input from " + absolutePath); 124 | } 125 | 126 | @Test 127 | void urlFromWebShouldReturnText() { 128 | if (noConnectionToInternet()) { 129 | return; 130 | } 131 | 132 | var parameters = 133 | new PluginParametersBuilder() 134 | .setMessage(null, "https://www.nsf.gov/") 135 | .createPluginParameters(); 136 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 137 | echoPlugin.echo(); 138 | 139 | verify(echoOutput).info(ArgumentMatchers.contains(" new PluginParametersBuilder().setLevel("Something").createPluginParameters(); 32 | 33 | var thrown = assertThrows(FailureException.class, testMethod); 34 | 35 | assertThat( 36 | thrown.getMessage(), 37 | is(equalTo("level must be either FAIL, ERROR, WARNING, INFO or DEBUG. Was: Something"))); 38 | } 39 | 40 | @Test 41 | void nullLevelShouldThrowException() { 42 | 43 | Executable testMethod = 44 | () -> new PluginParametersBuilder().setLevel(null).createPluginParameters(); 45 | 46 | var thrown = assertThrows(FailureException.class, testMethod); 47 | 48 | assertThat( 49 | thrown.getMessage(), 50 | is(equalTo("level must be either FAIL, ERROR, WARNING, INFO or DEBUG. Was: null"))); 51 | } 52 | 53 | @Test 54 | void infoLevelShouldBeDefault() { 55 | var parameters = 56 | new PluginParametersBuilder().setMessage("Björn", null).createPluginParameters(); 57 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 58 | echoPlugin.echo(); 59 | 60 | verify(echoOutput).info("Björn"); 61 | } 62 | 63 | public static Stream logLevels() { 64 | return Stream.of( 65 | Arguments.of("fAIl", (BiConsumer) EchoOutput::fail), 66 | Arguments.of("FataL", (BiConsumer) EchoOutput::fail), 67 | Arguments.of("ErRoR", (BiConsumer) EchoOutput::error), 68 | Arguments.of("WARNiNg", (BiConsumer) EchoOutput::warning), 69 | Arguments.of("waRN", (BiConsumer) EchoOutput::warning), 70 | Arguments.of("infO", (BiConsumer) EchoOutput::info), 71 | Arguments.of("deBug", (BiConsumer) EchoOutput::debug), 72 | Arguments.of("TRACe", (BiConsumer) EchoOutput::debug)); 73 | } 74 | 75 | @ParameterizedTest 76 | @MethodSource("logLevels") 77 | void failLevelShouldOutputOnFailLevel(String level, BiConsumer expectedCall) { 78 | var parameters = 79 | new PluginParametersBuilder() 80 | .setLevel(level) 81 | .setMessage("Björn", null) 82 | .createPluginParameters(); 83 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 84 | echoPlugin.echo(); 85 | 86 | expectedCall.accept(verify(echoOutput), "Björn"); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestLineSeparator.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.junit.jupiter.api.Assertions.assertAll; 7 | import static org.junit.jupiter.api.Assertions.assertThrows; 8 | import static org.mockito.Mockito.mock; 9 | import static org.mockito.Mockito.verify; 10 | import static org.mockito.Mockito.verifyNoMoreInteractions; 11 | 12 | import echo.exception.FailureException; 13 | import echo.output.EchoOutput; 14 | import echo.output.PluginLog; 15 | import echo.parameter.PluginParametersBuilder; 16 | import java.util.stream.Stream; 17 | import org.junit.jupiter.api.Test; 18 | import org.junit.jupiter.api.function.Executable; 19 | import org.junit.jupiter.params.ParameterizedTest; 20 | import org.junit.jupiter.params.provider.Arguments; 21 | import org.junit.jupiter.params.provider.MethodSource; 22 | 23 | class TestLineSeparator { 24 | private final PluginLog pluginLog = mock(PluginLog.class); 25 | private final EchoOutput echoOutput = mock(EchoOutput.class); 26 | 27 | static Stream formattingTestData() { 28 | return Stream.of( 29 | Arguments.of("\n", "ABC\n\n\nDEF\n\n\nGHI\n\n\n"), 30 | Arguments.of("\r", "ABC\r\r\rDEF\r\r\rGHI\r\r\r"), 31 | Arguments.of("\r\n", "ABC\r\n\r\n\r\nDEF\r\n\r\n\r\nGHI\r\n\r\n\r\n")); 32 | } 33 | 34 | @ParameterizedTest 35 | @MethodSource("formattingTestData") 36 | void formattingTextShouldResultInLineBreaks(String formatting, String expected) { 37 | var parameters = 38 | new PluginParametersBuilder() 39 | .setMessage("ABC\n\n\nDEF\r\r\rGHI\r\n\r\n\r\n", null) 40 | .setFormatting("UTF-8", formatting) 41 | .createPluginParameters(); 42 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 43 | echoPlugin.echo(); 44 | 45 | verify(echoOutput).info(expected); 46 | } 47 | 48 | @Test 49 | void formattingWithIllegalLineBreaksShouldThrowException() { 50 | Executable testMethod = 51 | () -> 52 | new PluginParametersBuilder() 53 | .setMessage("ABC\n\n\nDEF\r\r\rGHI\r\n\r\n\r\n", null) 54 | .setFormatting("UTF-8", "\t") 55 | .createPluginParameters(); 56 | 57 | var thrown = assertThrows(FailureException.class, testMethod); 58 | 59 | assertAll( 60 | () -> 61 | assertThat( 62 | thrown.getMessage(), 63 | is( 64 | equalTo( 65 | "LineSeparator must be either \\n, \\r or \\r\\n, but separator characters were [9]"))), 66 | () -> verifyNoMoreInteractions(pluginLog)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestMessage.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.mockito.Mockito.*; 4 | 5 | import echo.output.EchoOutput; 6 | import echo.output.PluginLog; 7 | import echo.parameter.PluginParametersBuilder; 8 | import org.junit.jupiter.api.Test; 9 | 10 | class TestMessage { 11 | private final PluginLog pluginLog = mock(PluginLog.class); 12 | 13 | @Test 14 | void stringWithSpecialCharactersShouldBeOutput() { 15 | var echoOutput = mock(EchoOutput.class); 16 | 17 | var parameters = 18 | new PluginParametersBuilder().setMessage("Björn", null).createPluginParameters(); 19 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 20 | echoPlugin.echo(); 21 | 22 | verify(echoOutput).info("Björn"); 23 | } 24 | 25 | @Test 26 | void emptyMessageShouldOutputNothing() { 27 | var echoOutput = mock(EchoOutput.class); 28 | 29 | var parameters = new PluginParametersBuilder().setMessage("", null).createPluginParameters(); 30 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 31 | echoPlugin.echo(); 32 | 33 | verifyNoInteractions(echoOutput); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestNewline.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.junit.jupiter.api.Assertions.assertThrows; 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.verify; 9 | 10 | import echo.exception.FailureException; 11 | import echo.output.EchoOutput; 12 | import echo.parameter.PluginParametersBuilder; 13 | import java.util.stream.Stream; 14 | import org.junit.jupiter.api.Test; 15 | import org.junit.jupiter.api.function.Executable; 16 | import org.junit.jupiter.params.ParameterizedTest; 17 | import org.junit.jupiter.params.provider.Arguments; 18 | import org.junit.jupiter.params.provider.MethodSource; 19 | 20 | class TestNewline { 21 | private final EchoOutput echoOutput = mock(EchoOutput.class); 22 | 23 | @Test 24 | void illegalNewlineShouldThrowException() { 25 | Executable testMethod = 26 | () -> new PluginParametersBuilder().setFormatting(null, "\t").createPluginParameters(); 27 | 28 | var thrown = assertThrows(FailureException.class, testMethod); 29 | 30 | assertThat( 31 | thrown.getMessage(), 32 | is( 33 | equalTo( 34 | "LineSeparator must be either \\n, \\r or \\r\\n, but separator characters were [9]"))); 35 | } 36 | 37 | static Stream formattingTestData() { 38 | return Stream.of( 39 | Arguments.of("\n", "Hex\nover\nthe\nphone"), 40 | Arguments.of("\r", "Hex\rover\rthe\rphone"), 41 | Arguments.of("\r\n", "Hex\r\nover\r\nthe\r\nphone")); 42 | } 43 | 44 | @ParameterizedTest 45 | @MethodSource("formattingTestData") 46 | void newlineShouldBeReplacedWithLineSeparator(String formatting, String expected) { 47 | var parameters = 48 | new PluginParametersBuilder() 49 | .setMessage("Hex\nover\rthe\r\nphone", null) 50 | .setFormatting(null, formatting) 51 | .createPluginParameters(); 52 | var echoPlugin = new EchoPlugin(null, parameters, echoOutput); 53 | echoPlugin.echo(); 54 | 55 | verify(echoOutput).info(expected); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /echo/src/test/java/echo/TestToFile.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.StringEndsWith.endsWith; 6 | import static org.hamcrest.core.StringStartsWith.startsWith; 7 | import static org.junit.jupiter.api.Assertions.assertAll; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | import static org.mockito.Mockito.*; 10 | 11 | import echo.exception.FailureException; 12 | import echo.output.EchoOutput; 13 | import echo.output.PluginLog; 14 | import echo.parameter.PluginParametersBuilder; 15 | import java.io.File; 16 | import java.io.IOException; 17 | import org.apache.commons.io.FileUtils; 18 | import org.junit.jupiter.api.BeforeEach; 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.function.Executable; 21 | 22 | class TestToFile { 23 | 24 | private final PluginLog pluginLog = mock(PluginLog.class); 25 | private final EchoOutput echoOutput = mock(EchoOutput.class); 26 | private String fileName = null; 27 | 28 | @BeforeEach 29 | void setup() { 30 | doAnswer( 31 | invocation -> { 32 | var content = invocation.getArguments()[0].toString(); 33 | if (content.startsWith("Saving output to ")) { 34 | fileName = content.substring(17); 35 | } 36 | return null; 37 | }) 38 | .when(pluginLog) 39 | .info(anyString()); 40 | } 41 | 42 | @Test 43 | void saveToNonExistingToFileShouldWork() throws IOException { 44 | var parameters = 45 | new PluginParametersBuilder() 46 | .setMessage("Björn", null) 47 | .setFile(new File("."), "test.txt", false, false) 48 | .createPluginParameters(); 49 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 50 | 51 | try { 52 | echoPlugin.echo(); 53 | 54 | verifyNoInteractions(echoOutput); 55 | 56 | var output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 57 | assertThat(output, is("Björn")); 58 | } finally { 59 | FileUtils.deleteQuietly(new File(fileName)); 60 | } 61 | } 62 | 63 | @Test 64 | void emptyMessageShouldCreateEmptyFile() throws IOException { 65 | var parameters = 66 | new PluginParametersBuilder() 67 | .setMessage("", null) 68 | .setFile(new File("."), "test.txt", false, false) 69 | .createPluginParameters(); 70 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 71 | 72 | try { 73 | echoPlugin.echo(); 74 | 75 | verifyNoInteractions(echoOutput); 76 | 77 | var output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 78 | assertThat(output, is("")); 79 | } finally { 80 | FileUtils.deleteQuietly(new File(fileName)); 81 | } 82 | } 83 | 84 | @Test 85 | void saveToNonExistingDirectoryShouldWork() throws IOException { 86 | var parameters = 87 | new PluginParametersBuilder() 88 | .setMessage("Björn", null) 89 | .setFile(new File("."), "gurka/test.txt", false, false) 90 | .createPluginParameters(); 91 | var echoPlugin = new EchoPlugin(pluginLog, parameters, echoOutput); 92 | 93 | try { 94 | echoPlugin.echo(); 95 | 96 | verifyNoInteractions(echoOutput); 97 | 98 | var output = FileUtils.readFileToString(new File(fileName), "UTF-8"); 99 | assertThat(output, is("Björn")); 100 | } finally { 101 | FileUtils.deleteQuietly(new File(fileName)); 102 | FileUtils.deleteQuietly(new File(fileName).getParentFile()); 103 | } 104 | } 105 | 106 | @Test 107 | void saveToExistingDirectoryShouldThrowException() { 108 | 109 | try { 110 | var parameters1 = 111 | new PluginParametersBuilder() 112 | .setMessage("Björn", null) 113 | .setFile(new File("."), "gurka/test.txt", false, false) 114 | .createPluginParameters(); 115 | var echoPlugin1 = new EchoPlugin(pluginLog, parameters1, echoOutput); 116 | 117 | // Create directory 118 | echoPlugin1.echo(); 119 | 120 | var parameters2 = 121 | new PluginParametersBuilder() 122 | .setMessage("Björn", null) 123 | .setFile(new File("."), "gurka", false, false) 124 | .createPluginParameters(); 125 | var echoPlugin2 = new EchoPlugin(pluginLog, parameters2, echoOutput); 126 | 127 | Executable testMethod = echoPlugin2::echo; 128 | 129 | var thrown = assertThrows(FailureException.class, testMethod); 130 | 131 | assertAll( 132 | () -> assertThat(thrown.getMessage(), startsWith("File ")), 133 | () -> assertThat(thrown.getMessage(), endsWith("gurka exists but is a directory"))); 134 | 135 | } finally { 136 | FileUtils.deleteQuietly(new File(fileName)); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /echo/src/test/resources/messageEncoding.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ekryd/echo-maven-plugin/cb573a04750b607eb456342e84dbc4af11fa0e9f/echo/src/test/resources/messageEncoding.txt -------------------------------------------------------------------------------- /echo/src/test/resources/messageText.txt: -------------------------------------------------------------------------------- 1 | Björn -------------------------------------------------------------------------------- /maven-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | 8 | com.github.ekryd.echo-maven-plugin 9 | echo-plugin 10 | 2.1.1-SNAPSHOT 11 | 12 | 13 | 14 | echo-maven-plugin 15 | maven-plugin 16 | Echo Maven plugin 17 | A maven plugin that outputs text during Maven build 18 | 19 | 20 | 21 | com.github.ekryd.echo-maven-plugin 22 | echo-output 23 | 2.1.1-SNAPSHOT 24 | 25 | 26 | org.apache.maven 27 | maven-plugin-api 28 | 29 | 30 | 31 | org.apache.maven.plugin-tools 32 | maven-plugin-annotations 33 | provided 34 | 35 | 36 | 37 | 38 | 39 | 40 | com.github.ekryd.echo-maven-plugin 41 | echo-maven-plugin 42 | 2.1.0 43 | false 44 | 45 | 46 | end 47 | 48 | echo 49 | 50 | install 51 | 52 | ${line.separator} To run the plugin directly:${line.separator} mvn ${project.groupId}:${project.artifactId}:${project.version}:echo${line.separator} 53 | 54 | 55 | 56 | end_description 57 | 58 | echo 59 | 60 | install 61 | 62 | ${line.separator} To view description:${line.separator} mvn help:describe -DgroupId=${project.groupId} -DartifactId=${project.artifactId} -Dversion=${project.version} -Ddetail 63 | 64 | 65 | 66 | 67 | 68 | 69 | org.apache.maven.plugins 70 | maven-invoker-plugin 71 | 72 | 73 | integration-test 74 | 75 | install 76 | run 77 | 78 | 79 | ${project.build.directory}/it 80 | ${project.build.directory}/local-repo 81 | src/it/settings.xml 82 | 83 | ${project.version} 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /maven-plugin/src/it/default-configuration/expected.log: -------------------------------------------------------------------------------- 1 | [INFO] 2 | To run the plugin directly: 3 | mvn com.github.ekryd.echo-maven-plugin.its:default:0.0.1-SNAPSHOT:gurka 4 | 5 | [INFO] ------------------------------------------------------------------------ 6 | [INFO] BUILD SUCCESS 7 | [INFO] ------------------------------------------------------------------------ -------------------------------------------------------------------------------- /maven-plugin/src/it/default-configuration/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.goals=clean install 2 | -------------------------------------------------------------------------------- /maven-plugin/src/it/default-configuration/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | SortPom Plugin :: ITs :: Default configuration 5 | 4.0.0 6 | default 7 | com.github.ekryd.echo-maven-plugin.its 8 | 0.0.1-SNAPSHOT 9 | pom 10 | Test default parameters of the plugin 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | com.github.ekryd.echo-maven-plugin 19 | echo-maven-plugin 20 | @pom.version@ 21 | false 22 | 23 | 24 | end 25 | 26 | echo 27 | 28 | install 29 | 30 | ${line.separator} To run the plugin directly:${line.separator} mvn ${project.groupId}:${project.artifactId}:${project.version}:gurka${line.separator} 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /maven-plugin/src/it/default-configuration/postbuild.groovy: -------------------------------------------------------------------------------- 1 | log = new File(basedir, 'build.log') 2 | expected_log = new File(basedir, 'expected.log') 3 | 4 | assert log.exists() 5 | assert log.text.replaceAll('\r','').contains(expected_log.text.replaceAll('@pom.version@', projectversion).replaceAll('\r','')) 6 | 7 | return true -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/expected.log: -------------------------------------------------------------------------------- 1 | [INFO] ClassMessage 2 | [INFO] ------------------------------------------------------------------------ -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.goals=clean install 2 | -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/module1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | default 6 | com.github.ekryd.echo-maven-plugin.its 7 | 0.0.1-SNAPSHOT 8 | 9 | 10 | module1 11 | 12 | -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/module1/src/main/resources/classMessage.txt: -------------------------------------------------------------------------------- 1 | ClassMessage -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/module2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | default 6 | com.github.ekryd.echo-maven-plugin.its 7 | 0.0.1-SNAPSHOT 8 | 9 | 10 | module2 11 | pom 12 | 13 | 14 | 15 | 16 | 17 | com.github.ekryd.echo-maven-plugin 18 | echo-maven-plugin 19 | @pom.version@ 20 | 21 | 22 | com.github.ekryd.echo-maven-plugin.its 23 | module1 24 | 0.0.1-SNAPSHOT 25 | 26 | 27 | 28 | 29 | 3 30 | 31 | echo 32 | 33 | install 34 | 35 | classMessage.txt 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | SortPom Plugin :: ITs :: Default configuration 5 | 4.0.0 6 | default 7 | com.github.ekryd.echo-maven-plugin.its 8 | 0.0.1-SNAPSHOT 9 | pom 10 | Test default parameters of the plugin 11 | 12 | 13 | module1 14 | module2 15 | 16 | 17 | -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromClassResouce/postbuild.groovy: -------------------------------------------------------------------------------- 1 | log = new File(basedir, 'build.log') 2 | expected_log = new File(basedir, 'expected.log') 3 | 4 | assert log.exists() 5 | assert log.text.replaceAll('\r','').contains(expected_log.text.replaceAll('@pom.version@', projectversion).replaceAll('\r','')) 6 | 7 | return true -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromFile/expected.log: -------------------------------------------------------------------------------- 1 | [INFO] FileMessage2 2 | [INFO] ------------------------------------------------------------------------ 3 | [INFO] BUILD SUCCESS 4 | [INFO] ------------------------------------------------------------------------ -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromFile/fileMessage2.txt: -------------------------------------------------------------------------------- 1 | FileMessage2 -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromFile/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.goals=clean install 2 | -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromFile/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | SortPom Plugin :: ITs :: Default configuration 5 | 4.0.0 6 | default 7 | com.github.ekryd.echo-maven-plugin.its 8 | 0.0.1-SNAPSHOT 9 | pom 10 | Test default parameters of the plugin 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | com.github.ekryd.echo-maven-plugin 19 | echo-maven-plugin 20 | @pom.version@ 21 | false 22 | 23 | 24 | 1 25 | 26 | echo 27 | 28 | install 29 | 30 | fileMessage2.txt 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /maven-plugin/src/it/echo-fromFile/postbuild.groovy: -------------------------------------------------------------------------------- 1 | log = new File(basedir, 'build.log') 2 | expected_log = new File(basedir, 'expected.log') 3 | 4 | assert log.exists() 5 | assert log.text.replaceAll('\r','').contains(expected_log.text.replaceAll('@pom.version@', projectversion).replaceAll('\r','')) 6 | 7 | return true -------------------------------------------------------------------------------- /maven-plugin/src/it/mojo-description/expected.log: -------------------------------------------------------------------------------- 1 | Name: Echo Maven plugin 2 | Description: A maven plugin that outputs text during Maven build 3 | Group Id: com.github.ekryd.echo-maven-plugin 4 | Artifact Id: echo-maven-plugin 5 | Version: @pom.version@ 6 | Goal Prefix: echo 7 | 8 | This plugin has 2 goals: 9 | 10 | echo:echo 11 | Description: Mojo (Maven plugin) that outputs messages during Maven build. 12 | Implementation: echo.EchoMojo 13 | Language: java 14 | Bound to phase: initialize 15 | 16 | Available parameters: 17 | 18 | append (Default: false) 19 | User property: echo.append 20 | If the message should be appended to the toFile instead of opening a new 21 | file/overwrite an existing file 22 | 23 | characterOutput (Default: false) 24 | User property: echo.characterOutput 25 | Debug flag that outputs the message as a character list 26 | 27 | encoding (Default: UTF-8) 28 | User property: echo.encoding 29 | Encoding for the messages. 30 | 31 | force (Default: false) 32 | User property: echo.force 33 | Overwrite read-only destination files 34 | 35 | fromFile 36 | User property: echo.fromFile 37 | If the message fetched from a file (or URL) instead of message tag 38 | 39 | level (Default: INFO) 40 | User property: echo.level 41 | Which output level the message should have. The following values are 42 | available 'FAIL', 'ERROR', 'WARNING', 'INFO', and 'DEBUG' 43 | 44 | lineSeparator (Default: ${line.separator}) 45 | User property: echo.lineSeparator 46 | Line separator messages. Can be either \n, \r or \r\n 47 | 48 | message 49 | User property: echo.message 50 | The message text that should be echoed 51 | 52 | skip (Default: false) 53 | User property: echo.skip 54 | Set this to 'true' to bypass echo plugin 55 | 56 | toFile 57 | User property: echo.toFile 58 | If the message should be sent to a file instead of standard output 59 | 60 | echo:help 61 | Description: Display help information on echo-maven-plugin. Call mvn 62 | echo:help -Ddetail=true -Dgoal= to display parameter details. 63 | Implementation: echo.HelpMojo 64 | Language: java 65 | 66 | Available parameters: 67 | 68 | detail (Default: false) 69 | User property: detail 70 | If true, display all settable properties for each goal. 71 | 72 | goal 73 | User property: goal 74 | The name of the goal for which to show help. If unspecified, all goals 75 | will be displayed. 76 | 77 | indentSize (Default: 2) 78 | User property: indentSize 79 | The number of spaces per indentation level, should be positive. 80 | 81 | lineLength (Default: 80) 82 | User property: lineLength 83 | The maximum length of a display line, should be positive. 84 | 85 | 86 | [INFO] ------------------------------------------------------------------------ 87 | [INFO] BUILD SUCCESS 88 | [INFO] ------------------------------------------------------------------------ 89 | -------------------------------------------------------------------------------- /maven-plugin/src/it/mojo-description/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.goals=help:describe -------------------------------------------------------------------------------- /maven-plugin/src/it/mojo-description/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | SortPom Plugin :: ITs :: Default configuration 5 | 4.0.0 6 | default 7 | com.github.ekryd.echo-maven-plugin.its 8 | 0.0.1-SNAPSHOT 9 | pom 10 | Test default parameters of the plugin 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-help-plugin 20 | 3.5.1 21 | 22 | com.github.ekryd.echo-maven-plugin 23 | echo-maven-plugin 24 | @pom.version@ 25 | true 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /maven-plugin/src/it/mojo-description/postbuild.groovy: -------------------------------------------------------------------------------- 1 | log = new File(basedir, 'build.log') 2 | expected_log = new File(basedir, 'expected.log') 3 | 4 | assert log.exists() 5 | assert log.text.replaceAll('\r','').contains(expected_log.text.replaceAll('@pom.version@', projectversion).replaceAll('\r','')) 6 | 7 | return true -------------------------------------------------------------------------------- /maven-plugin/src/it/settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | it-repo 9 | 10 | true 11 | 12 | 13 | 14 | local.central 15 | file:///@localRepository@ 16 | 17 | true 18 | 19 | 20 | true 21 | 22 | 23 | 24 | 25 | 26 | local.central 27 | file:///@localRepository@ 28 | 29 | true 30 | 31 | 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | com.github.ekryd.echo-maven-plugin 41 | 42 | 43 | -------------------------------------------------------------------------------- /maven-plugin/src/it/skip-echo/invoker.properties: -------------------------------------------------------------------------------- 1 | invoker.goals=clean install -Decho.skip 2 | -------------------------------------------------------------------------------- /maven-plugin/src/it/skip-echo/not-expected.log: -------------------------------------------------------------------------------- 1 | mvn com.github.ekryd.echo-maven-plugin.its:default:0.0.1-SNAPSHOT:gurka -------------------------------------------------------------------------------- /maven-plugin/src/it/skip-echo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | SortPom Plugin :: ITs :: Default configuration 5 | 4.0.0 6 | default 7 | com.github.ekryd.echo-maven-plugin.its 8 | 0.0.1-SNAPSHOT 9 | pom 10 | Test default parameters of the plugin 11 | 12 | UTF-8 13 | 14 | 15 | 16 | 17 | 18 | com.github.ekryd.echo-maven-plugin 19 | echo-maven-plugin 20 | @pom.version@ 21 | false 22 | 23 | 24 | end 25 | 26 | echo 27 | 28 | install 29 | 30 | ${line.separator} To run the plugin directly:${line.separator} mvn ${project.groupId}:${project.artifactId}:${project.version}:gurka${line.separator} 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /maven-plugin/src/it/skip-echo/postbuild.groovy: -------------------------------------------------------------------------------- 1 | log = new File(basedir, 'build.log') 2 | expected_log = new File(basedir, 'not-expected.log') 3 | 4 | assert log.exists() 5 | assert !log.text.replaceAll('\r','').contains(expected_log.text.replaceAll('@pom.version@', projectversion).replaceAll('\r','')) 6 | 7 | return true -------------------------------------------------------------------------------- /maven-plugin/src/main/java/echo/EchoMojo.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import echo.exception.ExceptionHandler; 4 | import echo.exception.FailureException; 5 | import echo.output.MavenEchoOutput; 6 | import echo.output.MavenPluginLog; 7 | import echo.parameter.PluginParametersBuilder; 8 | import java.io.File; 9 | import org.apache.maven.plugin.AbstractMojo; 10 | import org.apache.maven.plugin.MojoFailureException; 11 | import org.apache.maven.plugins.annotations.LifecyclePhase; 12 | import org.apache.maven.plugins.annotations.Mojo; 13 | import org.apache.maven.plugins.annotations.Parameter; 14 | 15 | /** Mojo (Maven plugin) that outputs messages during Maven build. */ 16 | @Mojo( 17 | name = "echo", 18 | threadSafe = true, 19 | defaultPhase = LifecyclePhase.INITIALIZE, 20 | requiresProject = false) 21 | @SuppressWarnings({"UnusedDeclaration"}) 22 | class EchoMojo extends AbstractMojo { 23 | /** The message text that should be echoed */ 24 | @Parameter(property = "echo.message") 25 | private String message; 26 | 27 | /** If the message fetched from a file (or URL) instead of message tag */ 28 | @Parameter(property = "echo.fromFile") 29 | private String fromFile; 30 | 31 | /** 32 | * The default path for fromFile and toFile. The fromFile will be read relative to this path. The 33 | * toFile will be created relative to this path. READ-ONLY 34 | */ 35 | @Parameter(defaultValue = "${basedir}", readonly = true) 36 | private File basePath; 37 | 38 | /** If the message should be sent to a file instead of standard output */ 39 | @Parameter(property = "echo.toFile") 40 | private String toFile; 41 | 42 | /** 43 | * If the message should be appended to the toFile instead of opening a new file/overwrite an 44 | * existing file 45 | */ 46 | @Parameter(property = "echo.append", defaultValue = "false") 47 | private boolean append; 48 | 49 | /** Overwrite read-only destination files */ 50 | @Parameter(property = "echo.force", defaultValue = "false") 51 | private boolean force; 52 | 53 | /** 54 | * Which output level the message should have. The following values are available 'FAIL', 'ERROR', 55 | * 'WARNING', 'INFO', and 'DEBUG' 56 | */ 57 | @Parameter(property = "echo.level", defaultValue = "INFO") 58 | private String level; 59 | 60 | /** Encoding for the messages. */ 61 | @Parameter(property = "echo.encoding", defaultValue = "UTF-8") 62 | private String encoding; 63 | 64 | /** Line separator messages. Can be either \n, \r or \r\n */ 65 | @Parameter(property = "echo.lineSeparator", defaultValue = "${line.separator}") 66 | private String lineSeparator; 67 | 68 | /** Debug flag that outputs the message as a character list */ 69 | @Parameter(property = "echo.characterOutput", defaultValue = "false") 70 | boolean characterOutput; 71 | 72 | /** Set this to 'true' to bypass echo plugin */ 73 | @Parameter(property = "echo.skip", defaultValue = "false") 74 | private boolean skip; 75 | 76 | private MavenPluginLog mavenLogger; 77 | private MavenEchoOutput echoOutput; 78 | private EchoPlugin echoPlugin; 79 | 80 | /** 81 | * Execute plugin. 82 | * 83 | * @throws org.apache.maven.plugin.MojoFailureException exception that will be handled by plugin 84 | * framework 85 | * @see org.apache.maven.plugin.Mojo#execute() 86 | */ 87 | @Override 88 | public void execute() throws MojoFailureException { 89 | initLoggers(); 90 | if (skip) { 91 | mavenLogger.info("Skipping echo-maven-plugin"); 92 | } else { 93 | setup(); 94 | echo(); 95 | } 96 | } 97 | 98 | private void initLoggers() { 99 | mavenLogger = new MavenPluginLog(getLog()); 100 | echoOutput = new MavenEchoOutput(getLog()); 101 | } 102 | 103 | void setup() throws MojoFailureException { 104 | 105 | try { 106 | var pluginParameters = 107 | new PluginParametersBuilder() 108 | .setMessage(message, fromFile) 109 | .setFile(basePath, toFile, append, force) 110 | .setLevel(level) 111 | .setFormatting(encoding, lineSeparator) 112 | .setDebug(characterOutput) 113 | .createPluginParameters(); 114 | 115 | echoPlugin = new EchoPlugin(mavenLogger, pluginParameters, echoOutput); 116 | } catch (FailureException fex) { 117 | new ExceptionHandler(fex).throwMojoFailureException(); 118 | } 119 | } 120 | 121 | void echo() throws MojoFailureException { 122 | try { 123 | echoPlugin.echo(); 124 | } catch (FailureException fex) { 125 | new ExceptionHandler(fex).throwMojoFailureException(); 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /maven-plugin/src/main/java/echo/exception/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package echo.exception; 2 | 3 | import org.apache.maven.plugin.MojoFailureException; 4 | 5 | /** 6 | * Converts FailureExceptions to MojoFailureExceptions. The MojoFailureException will stop the maven 7 | * build 8 | */ 9 | public final class ExceptionHandler { 10 | private final FailureException fex; 11 | 12 | /** Creates an ExceptionHandler with the exception to handle */ 13 | public ExceptionHandler(FailureException fex) { 14 | this.fex = fex; 15 | } 16 | 17 | /** Throw a MojoFailureException from the failure exception */ 18 | public void throwMojoFailureException() throws MojoFailureException { 19 | if (fex.getCause() != null) { 20 | throw new MojoFailureException(fex.getMessage(), fex.getCause()); 21 | } else { 22 | throw new MojoFailureException(fex.getMessage()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /maven-plugin/src/main/java/echo/output/MavenEchoOutput.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | import org.apache.maven.plugin.MojoFailureException; 4 | import org.apache.maven.plugin.logging.Log; 5 | 6 | /** Wraps the Maven standard output to decouple from output functionality */ 7 | public class MavenEchoOutput implements EchoOutput { 8 | private final Log wrappedLog; 9 | 10 | /** Creates an MavenEchoOutput wrapper */ 11 | public MavenEchoOutput(Log wrappedLog) { 12 | this.wrappedLog = wrappedLog; 13 | } 14 | 15 | @Override 16 | public void fail(String content) { 17 | this.throwAsUnchecked(new MojoFailureException(content)); 18 | } 19 | 20 | @Override 21 | public void error(String content) { 22 | wrappedLog.error(content); 23 | } 24 | 25 | @Override 26 | public void warning(String content) { 27 | wrappedLog.warn(content); 28 | } 29 | 30 | @Override 31 | public void info(String content) { 32 | wrappedLog.info(content); 33 | } 34 | 35 | @Override 36 | public void debug(String content) { 37 | wrappedLog.debug(content); 38 | } 39 | 40 | @SuppressWarnings("unchecked") 41 | private void throwAsUnchecked(Exception e) throws E { 42 | throw (E) e; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /maven-plugin/src/main/java/echo/output/MavenPluginLog.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | import org.apache.maven.plugin.logging.Log; 4 | 5 | /** Wraps the Maven internal plugin logger to decouple from logging framework */ 6 | public class MavenPluginLog implements PluginLog { 7 | private final Log wrappedLog; 8 | 9 | /** Create new MavenLogger wrapper */ 10 | public MavenPluginLog(Log wrappedLog) { 11 | this.wrappedLog = wrappedLog; 12 | } 13 | 14 | @Override 15 | public void info(String content) { 16 | wrappedLog.info(content); 17 | } 18 | 19 | @Override 20 | public void debug(Throwable throwable) { 21 | if (wrappedLog.isDebugEnabled()) { 22 | wrappedLog.debug(throwable); 23 | } 24 | } 25 | 26 | @Override 27 | public void debug(String content) { 28 | if (wrappedLog.isDebugEnabled()) { 29 | wrappedLog.debug(content); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /maven-plugin/src/test/java/echo/EchoMojoTest.java: -------------------------------------------------------------------------------- 1 | package echo; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.hamcrest.core.IsNull.notNullValue; 7 | import static org.junit.jupiter.api.Assertions.assertAll; 8 | import static org.junit.jupiter.api.Assertions.assertThrows; 9 | import static org.mockito.Mockito.doThrow; 10 | import static org.mockito.Mockito.mock; 11 | import static org.mockito.Mockito.verify; 12 | import static org.mockito.Mockito.verifyNoMoreInteractions; 13 | 14 | import echo.exception.FailureException; 15 | import echo.output.MavenEchoOutput; 16 | import echo.output.MavenPluginLog; 17 | import org.apache.maven.plugin.AbstractMojo; 18 | import org.apache.maven.plugin.MojoFailureException; 19 | import org.apache.maven.plugin.logging.Log; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | import org.junit.jupiter.api.function.Executable; 23 | import refutils.ReflectionHelper; 24 | 25 | class EchoMojoTest { 26 | 27 | private EchoMojo echoMojo; 28 | 29 | private final MavenPluginLog mavenLoggerMock = mock(MavenPluginLog.class); 30 | private final MavenEchoOutput mavenEchoOutputMock = mock(MavenEchoOutput.class); 31 | private final Log pluginLogMock = mock(Log.class); 32 | 33 | @BeforeEach 34 | void setUp() { 35 | echoMojo = new EchoMojo(); 36 | var echoMojoHelper = new ReflectionHelper(echoMojo); 37 | echoMojoHelper.setField("level", "INFO"); 38 | echoMojoHelper.setField("lineSeparator", "\\n"); 39 | echoMojoHelper.setField(mavenLoggerMock); 40 | echoMojoHelper.setField(mavenEchoOutputMock); 41 | } 42 | 43 | @Test 44 | void setupShouldSetupEchoPluginInstance() throws Exception { 45 | echoMojo.setup(); 46 | 47 | var echoPlugin = new ReflectionHelper(echoMojo).getField(EchoPlugin.class); 48 | assertThat(echoPlugin, notNullValue()); 49 | } 50 | 51 | @Test 52 | void exceptionInSetupShouldBeConverted() { 53 | 54 | new ReflectionHelper(echoMojo).setField("level", "Gurka"); 55 | 56 | Executable testMethod = () -> echoMojo.setup(); 57 | 58 | var thrown = assertThrows(MojoFailureException.class, testMethod); 59 | 60 | assertThat( 61 | thrown.getMessage(), 62 | is(equalTo("level must be either FAIL, ERROR, WARNING, INFO or DEBUG. Was: Gurka"))); 63 | } 64 | 65 | @Test 66 | void mavenEchoShouldRunEchoPlugin() throws Exception { 67 | var echoPlugin = mock(EchoPlugin.class); 68 | 69 | new ReflectionHelper(echoMojo).setField(echoPlugin); 70 | 71 | echoMojo.echo(); 72 | 73 | verify(echoPlugin).echo(); 74 | } 75 | 76 | @Test 77 | void echoShouldRunTheWholePlugin() throws Exception { 78 | var reflectionHelper = new ReflectionHelper(echoMojo); 79 | // Init values 80 | reflectionHelper.setField("message", "Björn"); 81 | // Init loggers 82 | reflectionHelper.setField(mavenLoggerMock); 83 | reflectionHelper.setField(mavenEchoOutputMock); 84 | 85 | echoMojo.setup(); 86 | echoMojo.echo(); 87 | 88 | verify(mavenEchoOutputMock).info("Björn"); 89 | verifyNoMoreInteractions(mavenLoggerMock); 90 | verifyNoMoreInteractions(mavenEchoOutputMock); 91 | } 92 | 93 | @Test 94 | void noMessageShouldGenerateException() { 95 | 96 | Executable testMethod = () -> echoMojo.execute(); 97 | 98 | var thrown = assertThrows(MojoFailureException.class, testMethod); 99 | 100 | assertAll( 101 | () -> 102 | assertThat( 103 | thrown.getMessage(), 104 | is(equalTo("There was nothing to output. Specify either message or fromFile"))), 105 | () -> verifyNoMoreInteractions(mavenLoggerMock), 106 | () -> verifyNoMoreInteractions(mavenEchoOutputMock)); 107 | } 108 | 109 | @Test 110 | void exceptionInEchoShouldBeConverted() { 111 | var echoPlugin = mock(EchoPlugin.class); 112 | 113 | doThrow(new FailureException("Gurka")).when(echoPlugin).echo(); 114 | new ReflectionHelper(echoMojo).setField(echoPlugin); 115 | 116 | Executable testMethod = () -> echoMojo.echo(); 117 | 118 | var thrown = assertThrows(MojoFailureException.class, testMethod); 119 | 120 | assertThat(thrown.getMessage(), is(equalTo("Gurka"))); 121 | } 122 | 123 | @Test 124 | void skipShouldOnlyOutputMessage() throws Exception { 125 | new ReflectionHelper(echoMojo).setField("skip", true); 126 | new ReflectionHelper(echoMojo, AbstractMojo.class).setField(pluginLogMock); 127 | 128 | echoMojo.execute(); 129 | 130 | verify(pluginLogMock).info("Skipping echo-maven-plugin"); 131 | } 132 | 133 | @Test 134 | void executeShouldOutputMessage() throws Exception { 135 | new ReflectionHelper(echoMojo).setField("message", "Björn"); 136 | new ReflectionHelper(echoMojo, AbstractMojo.class).setField(pluginLogMock); 137 | 138 | echoMojo.execute(); 139 | 140 | verify(pluginLogMock).info("Björn"); 141 | verifyNoMoreInteractions(pluginLogMock); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /maven-plugin/src/test/java/echo/exception/ExceptionHandlerTest.java: -------------------------------------------------------------------------------- 1 | package echo.exception; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.core.Is.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.junit.jupiter.api.Assertions.assertAll; 7 | import static org.junit.jupiter.api.Assertions.assertThrows; 8 | 9 | import org.apache.maven.plugin.MojoFailureException; 10 | import org.junit.jupiter.api.Test; 11 | import org.junit.jupiter.api.function.Executable; 12 | 13 | class ExceptionHandlerTest { 14 | 15 | @Test 16 | void failureExceptionShouldThrowMojoFailureException() { 17 | 18 | var failureException = new FailureException("Gurka"); 19 | 20 | Executable testMethod = 21 | () -> new ExceptionHandler(failureException).throwMojoFailureException(); 22 | 23 | var thrown = assertThrows(MojoFailureException.class, testMethod); 24 | 25 | assertThat(thrown.getMessage(), is(equalTo("Gurka"))); 26 | } 27 | 28 | @Test 29 | void failureExceptionShouldKeepCause() { 30 | 31 | var cause = new IllegalArgumentException("not valid"); 32 | var failureException = new FailureException("Gurka", cause); 33 | 34 | Executable testMethod = 35 | () -> new ExceptionHandler(failureException).throwMojoFailureException(); 36 | 37 | var thrown = assertThrows(MojoFailureException.class, testMethod); 38 | 39 | assertAll( 40 | () -> assertThat(thrown.getMessage(), is(equalTo("Gurka"))), 41 | () -> assertThat(thrown.getCause(), is(cause))); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /maven-plugin/src/test/java/echo/output/MavenEchoOutputTest.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | import static org.hamcrest.MatcherAssert.assertThat; 4 | import static org.hamcrest.Matchers.is; 5 | import static org.hamcrest.core.IsEqual.equalTo; 6 | import static org.junit.jupiter.api.Assertions.assertThrows; 7 | import static org.mockito.Mockito.mock; 8 | import static org.mockito.Mockito.verify; 9 | import static org.mockito.Mockito.verifyNoMoreInteractions; 10 | 11 | import org.apache.maven.plugin.MojoFailureException; 12 | import org.apache.maven.plugin.logging.Log; 13 | import org.junit.jupiter.api.BeforeEach; 14 | import org.junit.jupiter.api.Test; 15 | import org.junit.jupiter.api.function.Executable; 16 | 17 | class MavenEchoOutputTest { 18 | private final Log logMock = mock(Log.class); 19 | private MavenEchoOutput mavenEchoOutput; 20 | 21 | @BeforeEach 22 | void setUp() { 23 | mavenEchoOutput = new MavenEchoOutput(logMock); 24 | } 25 | 26 | @Test 27 | void failLevelShouldThrowException() { 28 | 29 | Executable testMethod = () -> mavenEchoOutput.fail("Gurkas"); 30 | 31 | var thrown = assertThrows(MojoFailureException.class, testMethod); 32 | 33 | assertThat(thrown.getMessage(), is(equalTo("Gurkas"))); 34 | } 35 | 36 | @Test 37 | void errorShouldOutputErrorLevel() { 38 | mavenEchoOutput.error("Gurka"); 39 | 40 | verify(logMock).error("Gurka"); 41 | verifyNoMoreInteractions(logMock); 42 | } 43 | 44 | @Test 45 | void warnShouldOutputWarnLevel() { 46 | mavenEchoOutput.warning("Gurka"); 47 | 48 | verify(logMock).warn("Gurka"); 49 | verifyNoMoreInteractions(logMock); 50 | } 51 | 52 | @Test 53 | void infoShouldOutputInfoLevel() { 54 | mavenEchoOutput.info("Gurka"); 55 | 56 | verify(logMock).info("Gurka"); 57 | verifyNoMoreInteractions(logMock); 58 | } 59 | 60 | @Test 61 | void debugShouldOutputDebugLevel() { 62 | mavenEchoOutput.debug("Gurka"); 63 | 64 | verify(logMock).debug("Gurka"); 65 | verifyNoMoreInteractions(logMock); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /maven-plugin/src/test/java/echo/output/MavenPluginLogTest.java: -------------------------------------------------------------------------------- 1 | package echo.output; 2 | 3 | import static org.mockito.Mockito.any; 4 | import static org.mockito.Mockito.mock; 5 | import static org.mockito.Mockito.verify; 6 | import static org.mockito.Mockito.verifyNoMoreInteractions; 7 | import static org.mockito.Mockito.when; 8 | 9 | import org.apache.maven.plugin.logging.Log; 10 | import org.junit.jupiter.api.BeforeEach; 11 | import org.junit.jupiter.api.Test; 12 | 13 | class MavenPluginLogTest { 14 | private final Log logMock = mock(Log.class); 15 | private MavenPluginLog mavenLogger; 16 | 17 | @BeforeEach 18 | void setUp() { 19 | mavenLogger = new MavenPluginLog(logMock); 20 | } 21 | 22 | @Test 23 | void infoShouldOutputInfoLevel() { 24 | mavenLogger.info("Gurka"); 25 | 26 | verify(logMock).info("Gurka"); 27 | verifyNoMoreInteractions(logMock); 28 | } 29 | 30 | @Test 31 | void debugExceptionLevelShouldLogToDebugIfEnabled() { 32 | when(logMock.isDebugEnabled()).thenReturn(true); 33 | 34 | mavenLogger.debug(new OutOfMemoryError("Ta daa!")); 35 | 36 | verify(logMock).isDebugEnabled(); 37 | verify(logMock).debug(any(OutOfMemoryError.class)); 38 | verifyNoMoreInteractions(logMock); 39 | } 40 | 41 | @Test 42 | void debugExceptionLevelShouldNotLogToDebugIfDisabled() { 43 | mavenLogger.debug(new OutOfMemoryError("Ta daa!")); 44 | 45 | when(logMock.isDebugEnabled()).thenReturn(false); 46 | verify(logMock).isDebugEnabled(); 47 | verifyNoMoreInteractions(logMock); 48 | } 49 | 50 | @Test 51 | void debugMessageLevelShouldLogToDebugIfEnabled() { 52 | when(logMock.isDebugEnabled()).thenReturn(true); 53 | 54 | mavenLogger.debug("Ta daa!"); 55 | 56 | verify(logMock).isDebugEnabled(); 57 | verify(logMock).debug("Ta daa!"); 58 | verifyNoMoreInteractions(logMock); 59 | } 60 | 61 | @Test 62 | void debugMessageLevelShouldNotLogToDebugIfDisabled() { 63 | mavenLogger.debug("Ta daa!"); 64 | 65 | when(logMock.isDebugEnabled()).thenReturn(false); 66 | verify(logMock).isDebugEnabled(); 67 | verifyNoMoreInteractions(logMock); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /misc/echo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ekryd/echo-maven-plugin/cb573a04750b607eb456342e84dbc4af11fa0e9f/misc/echo.png -------------------------------------------------------------------------------- /misc/welcome.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ****************************************************************************** 4 | * Use the following build options when building the Echo Maven plugin: * 5 | * * 6 | * mvn clean install (compile without signing the jar-file) * 7 | * * 8 | * mvn clean install (to deploy new version of the plugin) * 9 | * echo "test" | gpg --clearsign (test the gpg first) * 10 | * mvn release:clean * 11 | * mvn release:prepare * 12 | * mvn release:perform * 13 | * * 14 | * mvn versions:display-dependency-updates * 15 | * mvn versions:display-plugin-updates * 16 | * * 17 | ****************************************************************************** 18 | 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 4.0.0 6 | 7 | 8 | com.github.ekryd.echo-maven-plugin 9 | echo-plugin 10 | 2.1.1-SNAPSHOT 11 | pom 12 | Echo plugin parent 13 | Maven plugin that outputs text during a maven build. 14 | 15 | 16 | echo 17 | maven-plugin 18 | 19 | 20 | 21 | 11 22 | UTF-8 23 | 24 | 25 | 26 | 27 | 28 | org.junit 29 | junit-bom 30 | 5.13.0 31 | pom 32 | import 33 | 34 | 35 | commons-io 36 | commons-io 37 | 2.19.0 38 | 39 | 40 | org.apache.maven 41 | maven-plugin-api 42 | 3.9.9 43 | provided 44 | 45 | 46 | org.apache.maven.plugin-tools 47 | maven-plugin-annotations 48 | 3.15.1 49 | provided 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | com.github.ekryd.reflection-utils 58 | reflection-utils 59 | 1.2.0 60 | test 61 | 62 | 63 | org.hamcrest 64 | hamcrest 65 | 3.0 66 | test 67 | 68 | 69 | org.junit.jupiter 70 | junit-jupiter 71 | test 72 | 73 | 74 | org.mockito 75 | mockito-core 76 | 5.18.0 77 | test 78 | 79 | 80 | 81 | 82 | install 83 | 84 | 85 | 86 | 87 | 88 | org.apache.maven.plugins 89 | maven-antrun-plugin 90 | 3.1.0 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-assembly-plugin 96 | 3.7.1 97 | 98 | 99 | 100 | org.apache.maven.plugins 101 | maven-clean-plugin 102 | 3.5.0 103 | 104 | 105 | org.apache.maven.plugins 106 | maven-compiler-plugin 107 | 3.14.0 108 | 109 | ${compileSource} 110 | ${compileSource} 111 | 112 | 113 | 114 | 115 | org.apache.maven.plugins 116 | maven-dependency-plugin 117 | 3.8.1 118 | 119 | 120 | 121 | org.apache.maven.plugins 122 | maven-deploy-plugin 123 | 3.1.4 124 | 125 | 126 | 127 | org.apache.maven.plugins 128 | maven-install-plugin 129 | 3.1.4 130 | 131 | 132 | 133 | org.apache.maven.plugins 134 | maven-invoker-plugin 135 | 3.9.0 136 | 137 | 138 | 139 | org.jacoco:org.jacoco.agent:0.8.5:jar:runtime 140 | 141 | 142 | 143 | 1 144 | 145 | 146 | 147 | 148 | 149 | org.apache.maven.plugins 150 | maven-jar-plugin 151 | 3.4.2 152 | 153 | 154 | org.apache.maven.plugins 155 | maven-plugin-plugin 156 | 3.15.1 157 | 158 | 159 | 160 | org.apache.maven.plugins 161 | maven-resources-plugin 162 | 3.3.1 163 | 164 | 165 | 166 | org.apache.maven.plugins 167 | maven-site-plugin 168 | 3.21.0 169 | 170 | 171 | 172 | org.apache.maven.plugins 173 | maven-surefire-plugin 174 | 3.5.3 175 | 176 | 177 | org.codehaus.mojo 178 | versions-maven-plugin 179 | 2.18.0 180 | 181 | 182 | 183 | org.jacoco 184 | jacoco-maven-plugin 185 | 0.8.13 186 | 187 | 188 | **/*HelpMojo.class 189 | 190 | 191 | 192 | 193 | org.sonarsource.scanner.maven 194 | sonar-maven-plugin 195 | 5.1.0.4751 196 | 197 | 198 | 199 | 200 | 201 | 202 | com.github.ekryd.echo-maven-plugin 203 | echo-maven-plugin 204 | 2.1.0 205 | false 206 | 207 | 208 | welcome 209 | 210 | echo 211 | 212 | 213 | misc/welcome.txt 214 | 215 | 216 | 217 | 218 | 219 | com.github.ekryd.sortpom 220 | sortpom-maven-plugin 221 | 4.0.0 222 | 223 | false 224 | custom_1 225 | \n 226 | ${project.build.sourceEncoding} 227 | true 228 | true 229 | scope,groupId,artifactId 230 | schemaLocation 231 | 232 | 233 | 234 | 235 | sort 236 | 237 | validate 238 | 239 | 240 | 241 | 242 | com.spotify.fmt 243 | fmt-maven-plugin 244 | 2.25 245 | 246 | 247 | 248 | format 249 | 250 | 251 | 252 | 253 | 254 | org.apache.maven.plugins 255 | maven-enforcer-plugin 256 | 3.5.0 257 | 258 | 259 | enforce-plugin-versions 260 | 261 | enforce 262 | 263 | 264 | 265 | 266 | 3.2.5 267 | 268 | 269 | 1.8 270 | 271 | 272 | Best Practice is to always define plugin versions! 273 | true 274 | true 275 | true 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | org.apache.maven.plugins 284 | maven-plugin-plugin 285 | 286 | 287 | default-descriptor 288 | 289 | descriptor 290 | 291 | 292 | 293 | help-goal 294 | 295 | helpmojo 296 | 297 | 298 | echo 299 | 300 | 301 | 302 | 303 | 304 | 305 | org.apache.maven.plugins 306 | maven-release-plugin 307 | 3.1.1 308 | 309 | true 310 | false 311 | -Pdistribution 312 | deploy 313 | 314 | 315 | 316 | 317 | org.eluder.coveralls 318 | coveralls-maven-plugin 319 | 4.3.0 320 | 321 | 322 | javax.xml.bind 323 | jaxb-api 324 | 2.4.0-b180830.0359 325 | 326 | 327 | 328 | 329 | 330 | org.jacoco 331 | jacoco-maven-plugin 332 | 333 | 334 | pre-unit-test 335 | 336 | prepare-agent 337 | 338 | 339 | 340 | 341 | pre-integration-test 342 | 343 | prepare-agent-integration 344 | 345 | 346 | invoker.mavenOpts 347 | 348 | 349 | 350 | 351 | merge 352 | 353 | merge 354 | 355 | post-integration-test 356 | 357 | 358 | 359 | ${project.build.directory} 360 | 361 | *.exec 362 | 363 | 364 | 365 | ${project.build.directory}/jacocoAll.exec 366 | 367 | 368 | 369 | 370 | 371 | 372 | org.sonatype.plugins 373 | nexus-staging-maven-plugin 374 | 1.7.0 375 | true 376 | 377 | ossrh 378 | https://oss.sonatype.org/ 379 | true 380 | 381 | 382 | 383 | 384 | 385 | 386 | https://github.com/Ekryd/echo-maven-plugin/ 387 | 2013 388 | 389 | 390 | 391 | New BSD License 392 | https://en.wikipedia.org/wiki/BSD_licenses 393 | repo 394 | Whatever 395 | 396 | 397 | 398 | 399 | 400 | bjorn.ekryd 401 | Björn Ekryd 402 | bjorn.ekryd(at)gmail(dot)com 403 | https://www.linkedin.com/in/bjornekryd 404 | 405 | Architect 406 | Developer 407 | 408 | +1 409 | 410 | 411 | 412 | 413 | scm:git:https://github.com/Ekryd/echo-maven-plugin/ 414 | scm:git:https://github.com/Ekryd/echo-maven-plugin/ 415 | https://github.com/Ekryd/echo-maven-plugin/ 416 | HEAD 417 | 418 | 419 | GitHub 420 | https://github.com/Ekryd/echo-maven-plugin/issues 421 | 422 | 423 | 424 | 425 | ossrh 426 | https://oss.sonatype.org/content/repositories/snapshots 427 | 428 | 429 | 430 | 431 | 432 | 433 | distribution 434 | 435 | 436 | 437 | org.apache.maven.plugins 438 | maven-javadoc-plugin 439 | 3.11.2 440 | 441 | all,-missing 442 | 128m 443 | 512 444 | true 445 | true 446 | ${compileSource} 447 | false 448 | true 449 | 450 | 451 | https://docs.oracle.com/en/java/javase/11/docs/api/ 452 | 453 | 454 | 455 | 456 | attach-javadoc 457 | 458 | jar 459 | 460 | verify 461 | 462 | 463 | 464 | 465 | org.apache.maven.plugins 466 | maven-source-plugin 467 | 3.3.1 468 | 469 | 470 | attach-sources 471 | 472 | jar-no-fork 473 | 474 | verify 475 | 476 | 477 | 478 | 479 | org.apache.maven.plugins 480 | maven-gpg-plugin 481 | 3.2.7 482 | 483 | 484 | sign-artifacts 485 | 486 | sign 487 | 488 | verify 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base" 5 | ], 6 | "packageRules": [{ 7 | "matchUpdateTypes": [ "patch", "minor" ], 8 | "automerge": true, 9 | "automergeType": "branch" 10 | }] 11 | } 12 | --------------------------------------------------------------------------------