diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..21364db --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,62 @@ +name: CI + +on: [push] + +permissions: + security-events: write + contents: read + actions: read + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest] + java: [8, 11] + fail-fast: false + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Set up cache for ~./m2/repository + uses: actions/cache@v2.1.2 + with: + path: ~/.m2/repository + key: maven-${{ matrix.os }}-java${{ matrix.java }}-${{ hashFiles('**/pom.xml') }} + restore-keys: | + maven-${{ matrix.os }}-java${{ matrix.java }}- + maven-${{ matrix.os }}- + - name: Set up JDK + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + + security-scan: + uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 + with: + java-cache: 'maven' + java-version: 11 + + deploy: + needs: [build] + runs-on: ubuntu-latest + + steps: + - name: Check out + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + distribution: temurin + java-version: 8 + + - name: publish release package + if: contains( github.ref, 'master' ) || contains( github.base_ref, 'master' ) + env: + JENKINS_MAVEN_PASS: ${{ secrets.JENKINS_MAVEN_PASS }} + run: ./mvnw -s .github/workflows/m2.settings.xml deploy -DskipTests=true diff --git a/.github/workflows/m2.settings.xml b/.github/workflows/m2.settings.xml new file mode 100644 index 0000000..0a6874d --- /dev/null +++ b/.github/workflows/m2.settings.xml @@ -0,0 +1,56 @@ + + + + + central + ${JENKINS_MAVEN_USER} + ${JENKINS_MAVEN_PASS} + + + snapshots + ${JENKINS_MAVEN_USER} + ${JENKINS_MAVEN_PASS} + + + + + + + + false + + central + remote-snapshot-repos + https://repo.jenkins-ci.org/artifactory/remote-snapshot-repos + + + + snapshots + remote-snapshot-repos + https://repo.jenkins-ci.org/artifactory/remote-snapshot-repos + + + + + + false + + central + remote-snapshot-repos + https://repo.jenkins-ci.org/artifactory/remote-snapshot-repos + + + + snapshots + remote-snapshot-repos + https://repo.jenkins-ci.org/artifactory/remote-snapshot-repos + + + artifactory + + + + artifactory + + diff --git a/.gitignore b/.gitignore index 52d1443..0f904d8 100755 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,16 @@ - -# Created by https://www.gitignore.io/api/java,maven,netbeans,intellij,eclipse - -### Eclipse ### - +# OS stuff +*.icloud +._* +.DS_Store +Thumbs.db +Desktop.ini +.Spotlight-V100 +.Trashes + +# IDE stuff +.idea/* +*.iml +*.ipr .metadata bin/ tmp/ @@ -200,4 +208,4 @@ nbdist/ .idea/ work/ -nbactions.xml \ No newline at end of file +nbactions.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index feb4418..72d080f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,22 @@ -# (2021-12-17) +# [2.3](https://github.com/jenkinsci/rocketchatnotifier-plugin/compare/v2.2...v2.3.0) (2022-10-28) +# Features +* Modernize Plugin (thanks to @sghill for his [contribution](https://github.com/jenkinsci/log-parser-plugin/pull/38)) ### Bug Fixes +* Colors & hints on trend graphs do not match to the data ([413b828](https://github.com/jenkinsci/log-parser-plugin/commit/413b828a52855a6345f72e869ba803544393160e)) * docker-compose up doesn't support --rm ([d613f5e](https://github.com/jenkinsci/log-parser-plugin/commit/d613f5ef8a166edc518f580165a8367746a463c0)) +* Jenkins Log Parser Debug Icon not shown ([1e930e0](https://github.com/jenkinsci/log-parser-plugin/commit/1e930e00df73337ea75d8fe8d9caa38e3d7a792a)) +* **Memory:** Correct potential OOM when parsing logs in workflows ([#36](https://github.com/jenkinsci/log-parser-plugin/issues/36)) ([bff7f9f](https://github.com/jenkinsci/log-parser-plugin/commit/bff7f9f53820aade452a4c44441bbfabc905931e)), closes [/github.com/jenkinsci/workflow-job-plugin/blob/1551f82/src/main/java/org/jenkinsci/plugins/workflow/job/WorkflowRun.java#L1105](https://github.com//github.com/jenkinsci/workflow-job-plugin/blob/1551f82/src/main/java/org/jenkinsci/plugins/workflow/job/WorkflowRun.java/issues/L1105) * Now Jenkins is available on port 8081 and boots ([f269c53](https://github.com/jenkinsci/log-parser-plugin/commit/f269c53fa0ddb5ae28ae3719afe6d6ee3ccc9d8e)) +# [2.2](https://github.com/jenkinsci/rocketchatnotifier-plugin/compare/v2.1...v2.2) (2021-12-17) + + +### Bug Fixes + +* docker-compose up doesn't support --rm ([d613f5e](https://github.com/jenkinsci/log-parser-plugin/commit/d613f5ef8a166edc518f580165a8367746a463c0)) +* Now Jenkins is available on port 8081 and boots ([f269c53](https://github.com/jenkinsci/log-parser-plugin/commit/f269c53fa0ddb5ae28ae3719afe6d6ee3ccc9d8e)) diff --git a/Jenkinsfile_dev b/Jenkinsfile_dev deleted file mode 100644 index f22da30..0000000 --- a/Jenkinsfile_dev +++ /dev/null @@ -1,48 +0,0 @@ -#!groovy - -// only 20 builds -properties([ - disableConcurrentBuilds(), - buildDiscarder(logRotator(artifactNumToKeepStr: '20', numToKeepStr: '20')) -]) - -@Library('mare-build-library') -def git = new de.mare.ci.jenkins.Git() - -node('docker') { - - def buildNumber = env.BUILD_NUMBER - def workspace = env.WORKSPACE - def buildUrl = env.BUILD_URL - - // PRINT ENVIRONMENT TO JOB - echo "workspace directory is $workspace" - echo "build URL is $buildUrl" - echo "build Number is $buildNumber" - echo "PATH is $env.PATH" - - try { - stage('Checkout') { - checkout scm - } - - stage('Build and Test') { - sh "./mvnw clean install -U" - openTasks high: 'FIXME', normal: 'TODO', pattern: '**/src/**/*.*,*.properties,Jenkinsfil*,*.gradle' - junit 'target/surefire-reports/*.xml' - } - - stage('Deploy') { - if (git.isProductionBranch()) { - sshagent(credentials: ['github-hypery2k']) { - sh "./mvnw deploy -DskipTests=true" - } - } - } - - } catch (e) { - mail subject: 'Error on build', to: 'github@martinreinhardt-online.de', body: "Please go to ${env.BUILD_URL}." - throw e - } - -} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/pom.xml b/pom.xml index 4e1258c..d7923c1 100755 --- a/pom.xml +++ b/pom.xml @@ -6,21 +6,21 @@ org.jenkins-ci.plugins plugin - 3.22 + 4.48 + log-parser hpi Log Parser Plugin - 2.2 + 2.3.0 https://wiki.jenkins-ci.org/display/JENKINS/Log+Parser+Plugin Parses the console log generated by a build - false - 2.138.2 - 8 + false + 2.332.1 2.5 2.5.1 @@ -42,7 +42,7 @@ maven-pmd-plugin 3.5 - 1.${java.level} + 11 /rulesets/basic.xml /rulesets/braces.xml @@ -75,17 +75,27 @@ + + + + io.jenkins.tools.bom + bom-2.332.x + 1643.v1cffef51df73 + import + pom + + + + org.jenkins-ci.plugins scm-api - 1.3 test io.jenkins configuration-as-code - 1.3 test @@ -132,13 +142,11 @@ org.jenkins-ci.plugins mailer - 1.22 test org.jenkins-ci symbol-annotation - 1.13 compile diff --git a/src/main/java/hudson/plugins/logparser/CompiledPatterns.java b/src/main/java/hudson/plugins/logparser/CompiledPatterns.java index efb9950..17dc425 100755 --- a/src/main/java/hudson/plugins/logparser/CompiledPatterns.java +++ b/src/main/java/hudson/plugins/logparser/CompiledPatterns.java @@ -1,6 +1,7 @@ package hudson.plugins.logparser; -import javax.annotation.CheckForNull; +import edu.umd.cs.findbugs.annotations.CheckForNull; + import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; diff --git a/src/main/java/hudson/plugins/logparser/LogParserAction.java b/src/main/java/hudson/plugins/logparser/LogParserAction.java index 92f6d23..5b9ba6d 100755 --- a/src/main/java/hudson/plugins/logparser/LogParserAction.java +++ b/src/main/java/hudson/plugins/logparser/LogParserAction.java @@ -136,13 +136,13 @@ private CategoryDataset buildDataSet() { DataSetBuilder dsb = new DataSetBuilder<>(); for (LogParserAction a = this; a != null; a = a.getPreviousAction()) { - dsb.add(a.result.getTotalErrors(), "errors", + dsb.add(a.result.getTotalErrors(), "0", new ChartUtil.NumberOnlyBuildLabel(a.getOwner())); - dsb.add(a.result.getTotalWarnings(), "warnings", + dsb.add(a.result.getTotalWarnings(), "1", new ChartUtil.NumberOnlyBuildLabel(a.getOwner())); - dsb.add(a.result.getTotalInfos(), "infos", + dsb.add(a.result.getTotalInfos(), "2", new ChartUtil.NumberOnlyBuildLabel(a.getOwner())); - dsb.add(a.result.getTotalDebugs(), "debugs", + dsb.add(a.result.getTotalDebugs(), "3", new ChartUtil.NumberOnlyBuildLabel(a.getOwner())); for (String extraTag : a.result.getExtraTags()) { dsb.add(a.result.getTotalCountsByExtraTag(extraTag), extraTag, @@ -212,22 +212,25 @@ public String generateURL(CategoryDataset dataset, int row, @Override public String generateToolTip(CategoryDataset dataset, int row, int column) { + ChartUtil.NumberOnlyBuildLabel label = (ChartUtil.NumberOnlyBuildLabel) dataset + .getColumnKey(column); + LogParserResult result = label.build.getAction(LogParserAction.class).getResult(); switch (row) { case 0: return "Errors: " + result.getTotalErrors(); case 1: return "Warnings: " + result.getTotalWarnings(); case 2: - return "Debugs: " + result.getTotalDebugs(); - default: return "Infos: " + result.getTotalInfos(); + default: + return "Debugs: " + result.getTotalDebugs(); } } }; plot.setRenderer(ar); ar.setSeriesPaint(0, ColorPalette.RED); // error - ar.setSeriesPaint(1, ColorPalette.BLUE); // info - ar.setSeriesPaint(2, ColorPalette.YELLOW); // warning + ar.setSeriesPaint(1, ColorPalette.YELLOW); // warning + ar.setSeriesPaint(2, ColorPalette.BLUE); // info ar.setSeriesPaint(3, ColorPalette.GREY); // debug // crop extra space around the graph diff --git a/src/main/java/hudson/plugins/logparser/LogParserDisplayConsts.java b/src/main/java/hudson/plugins/logparser/LogParserDisplayConsts.java index 21c5468..651f21e 100755 --- a/src/main/java/hudson/plugins/logparser/LogParserDisplayConsts.java +++ b/src/main/java/hudson/plugins/logparser/LogParserDisplayConsts.java @@ -33,7 +33,7 @@ public LogParserDisplayConsts() { iconTable.put(LogParserConsts.ERROR, "red.gif"); iconTable.put(LogParserConsts.WARNING, "yellow.gif"); iconTable.put(LogParserConsts.INFO, "blue.gif"); - iconTable.put(LogParserConsts.DEBUG, "grey.gif"); + iconTable.put(LogParserConsts.DEBUG, "gray.gif"); // How to display in link summary html linkListDisplay.put(LogParserConsts.ERROR, "Error"); diff --git a/src/main/java/hudson/plugins/logparser/LogParserParser.java b/src/main/java/hudson/plugins/logparser/LogParserParser.java index 47be62b..7fcdb7a 100755 --- a/src/main/java/hudson/plugins/logparser/LogParserParser.java +++ b/src/main/java/hudson/plugins/logparser/LogParserParser.java @@ -115,67 +115,62 @@ public LogParserResult parseLog(final Run build) throws IOException, Inter } // Open console log for reading and all other files for writing - final BufferedWriter writer = new BufferedWriter(new FileWriter( - parsedFilePath)); - - // Record writers to links files in hash - writers.put(LogParserConsts.ERROR, new BufferedWriter(new FileWriter( - errorLinksFilePath))); - writers.put(LogParserConsts.WARNING, new BufferedWriter(new FileWriter( - warningLinksFilePath))); - writers.put(LogParserConsts.INFO, new BufferedWriter(new FileWriter( - infoLinksFilePath))); - writers.put(LogParserConsts.DEBUG, new BufferedWriter(new FileWriter( - debugLinksFilePath))); - for (String extraTag : this.extraTags) { - writers.put(extraTag, new BufferedWriter(new FileWriter( - linksFilePathByExtraTags.get(extraTag)))); - } - - // Loop on the console log as long as there are input lines and parse - // line by line - // At the end of this loop, we will have: - // - a parsed log with colored lines - // - 4 links files which will be consolidated into one referencing html - // file. - - // Create dummy header and section for beginning of log - final String shortLink = " Beginning of log"; - LogParserWriter.writeHeaderTemplateToAllLinkFiles(writers, sectionCounter); // This enters a line which will later be - // replaced by the actual header and count for - // this header - headerForSection.add(shortLink); - writer.write(LogParserConsts.getHtmlOpeningTags()); - - // write styles for log body - final String styles = "\n"; - writer.write(styles); - - if (this.preformattedHtml) - writer.write("
");
-        // Read bulks of lines, parse
-        parseLogBody(build, writer, log,
-                logger);
-
-        // Write parsed output, links, etc.
-        //writeLogBody();
-
-        // Close html footer
-        if (this.preformattedHtml)
-            writer.write("
"); - writer.write(LogParserConsts.getHtmlClosingTags()); - writer.close(); // Close to unlock and flush to disk. - - writers.get(LogParserConsts.ERROR).close(); - writers.get(LogParserConsts.WARNING).close(); - writers.get(LogParserConsts.INFO).close(); - writers.get(LogParserConsts.DEBUG).close(); - for (String extraTag : this.extraTags) { - writers.get(extraTag).close(); + try (final BufferedWriter writer = new BufferedWriter(new FileWriter(parsedFilePath))) { + + // Record writers to links files in hash + writers.put(LogParserConsts.ERROR, new BufferedWriter(new FileWriter( + errorLinksFilePath))); + writers.put(LogParserConsts.WARNING, new BufferedWriter(new FileWriter( + warningLinksFilePath))); + writers.put(LogParserConsts.INFO, new BufferedWriter(new FileWriter( + infoLinksFilePath))); + writers.put(LogParserConsts.DEBUG, new BufferedWriter(new FileWriter( + debugLinksFilePath))); + for (String extraTag : this.extraTags) { + writers.put(extraTag, new BufferedWriter(new FileWriter( + linksFilePathByExtraTags.get(extraTag)))); + } + + // Loop on the console log as long as there are input lines and parse + // line by line + // At the end of this loop, we will have: + // - a parsed log with colored lines + // - 4 links files which will be consolidated into one referencing html + // file. + + // Create dummy header and section for beginning of log + final String shortLink = " Beginning of log"; + LogParserWriter.writeHeaderTemplateToAllLinkFiles(writers, sectionCounter); // This enters a line which will later be + // replaced by the actual header and count for + // this header + headerForSection.add(shortLink); + writer.write(LogParserConsts.getHtmlOpeningTags()); + + // write styles for log body + final String styles = "\n"; + writer.write(styles); + + if (this.preformattedHtml) + writer.write("
");
+            // Read bulks of lines, parse
+            parseLogBody(build, writer, log,
+                    logger);
+
+            // Write parsed output, links, etc.
+            //writeLogBody();
+
+            // Close html footer
+            if (this.preformattedHtml)
+                writer.write("
"); + writer.write(LogParserConsts.getHtmlClosingTags()); + } finally { + for (BufferedWriter writer : writers.values()) { + writer.close(); + } } // Build the reference html from the warnings/errors/info html files @@ -353,22 +348,20 @@ private void parseLogBody(final Run build, final BufferedWriter writer, fi // Read log file from start - line by line and apply the statuses as // found by the threads. - final InputStreamReader streamReader = new InputStreamReader( - build.getLogInputStream(), - build.getCharset() ); - final BufferedReader reader = new BufferedReader( streamReader ); - String line; - String status; - int line_num = 0; - while ((line = reader.readLine()) != null) { - status = lineStatusMatches.get(String.valueOf(line_num)); - final String parsedLine = parseLine(line, status); - // This is for displaying sections in the links part - writer.write(parsedLine); - writer.newLine(); // Write system dependent end of line. - line_num++; + try (final InputStreamReader streamReader = new InputStreamReader(build.getLogInputStream(), build.getCharset()); + final BufferedReader reader = new BufferedReader(streamReader)) { + String line; + String status; + int line_num = 0; + while ((line = reader.readLine()) != null) { + status = lineStatusMatches.get(String.valueOf(line_num)); + final String parsedLine = parseLine(line, status); + // This is for displaying sections in the links part + writer.write(parsedLine); + writer.newLine(); // Write system dependent end of line. + line_num++; + } } - reader.close(); // Logging information - end final Calendar calendarEnd = Calendar.getInstance(); diff --git a/src/main/java/hudson/plugins/logparser/LogParserStatusComputer.java b/src/main/java/hudson/plugins/logparser/LogParserStatusComputer.java index 6d47214..46965f7 100755 --- a/src/main/java/hudson/plugins/logparser/LogParserStatusComputer.java +++ b/src/main/java/hudson/plugins/logparser/LogParserStatusComputer.java @@ -71,69 +71,66 @@ private HashMap computeStatusMatches( logger.log(Level.INFO, "Local temp file:" + tempFileLocation); - final BufferedReader reader = new BufferedReader(new InputStreamReader( - tempFilePath.read())); - int threadCounter = 0; - - final ArrayList runners = new ArrayList<>(); - final LogParserReader logParserReader = new LogParserReader(reader); - - //ExecutorService execSvc = Executors.newFixedThreadPool( - // LogParserUtils.getNumThreads() ); - final ExecutorService execSvc = Executors.newCachedThreadPool(); - int linesInLog = LogParserUtils.countLines(tempFileLocation); - final int threadsNeeded = linesInLog - / LogParserUtils.getLinesPerThread() + 1; - - // Read and parse the log parts. Keep the threads and results in an - // array for future reference when writing - for (int i = 0; i < threadsNeeded; i++) { - //logger.log(Level.INFO,"LogParserParser: Open thread #"+threadCounter); - final LogParserThread logParserThread = new LogParserThread( - logParserReader, parsingRulesArray, compiledPatterns, - threadCounter); - //logParserThread.start(); - runners.add(logParserThread); - execSvc.execute(logParserThread); - threadCounter++; - } + try (final BufferedReader reader = new BufferedReader(new InputStreamReader(tempFilePath.read()))) { + int threadCounter = 0; + + final ArrayList runners = new ArrayList<>(); + final LogParserReader logParserReader = new LogParserReader(reader); + + //ExecutorService execSvc = Executors.newFixedThreadPool( + // LogParserUtils.getNumThreads() ); + final ExecutorService execSvc = Executors.newCachedThreadPool(); + int linesInLog = LogParserUtils.countLines(tempFileLocation); + final int threadsNeeded = linesInLog + / LogParserUtils.getLinesPerThread() + 1; + + // Read and parse the log parts. Keep the threads and results in an + // array for future reference when writing + for (int i = 0; i < threadsNeeded; i++) { + //logger.log(Level.INFO,"LogParserParser: Open thread #"+threadCounter); + final LogParserThread logParserThread = new LogParserThread( + logParserReader, parsingRulesArray, compiledPatterns, + threadCounter); + //logParserThread.start(); + runners.add(logParserThread); + execSvc.execute(logParserThread); + threadCounter++; + } - // Wait for all threads to finish before sequentially writing the - // outcome - execSvc.shutdown(); - execSvc.awaitTermination(3600, TimeUnit.SECONDS); - - // Sort the threads in the order of the log parts they read - // It could be that thread #1 read log part #2 and thread #2 read log - // part #1 - - final int runnersSize = runners.size(); - LogParserThread[] sortedRunners = new LogParserThread[runnersSize]; - for (LogParserThread logParserThread : runners) { - final LogParserLogPart logPart = logParserThread.getLogPart(); - if (logPart != null) { - final int logPartNum = logPart.getLogPartNum(); - sortedRunners[logPartNum] = logParserThread; + // Wait for all threads to finish before sequentially writing the + // outcome + execSvc.shutdown(); + execSvc.awaitTermination(3600, TimeUnit.SECONDS); + + // Sort the threads in the order of the log parts they read + // It could be that thread #1 read log part #2 and thread #2 read log + // part #1 + + final int runnersSize = runners.size(); + LogParserThread[] sortedRunners = new LogParserThread[runnersSize]; + for (LogParserThread logParserThread : runners) { + final LogParserLogPart logPart = logParserThread.getLogPart(); + if (logPart != null) { + final int logPartNum = logPart.getLogPartNum(); + sortedRunners[logPartNum] = logParserThread; + } } - } - final HashMap result = new HashMap<>(); - HashMap moreLineStatusMatches; - for (int i = 0; i < runnersSize; i++) { - final LogParserThread logParserThread = sortedRunners[i]; - if (logParserThread != null) { - moreLineStatusMatches = getLineStatusMatches( - logParserThread.getLineStatuses(), i); - result.putAll(moreLineStatusMatches); + final HashMap result = new HashMap<>(); + HashMap moreLineStatusMatches; + for (int i = 0; i < runnersSize; i++) { + final LogParserThread logParserThread = sortedRunners[i]; + if (logParserThread != null) { + moreLineStatusMatches = getLineStatusMatches( + logParserThread.getLineStatuses(), i); + result.putAll(moreLineStatusMatches); + } } + return result; + } finally { + // Delete temp file + tempFilePath.delete(); } - - reader.close(); // Close to unlock. - - // Delete temp file - tempFilePath.delete(); - - return result; // SLAVE PART END } diff --git a/src/main/java/hudson/plugins/logparser/LogParserUtils.java b/src/main/java/hudson/plugins/logparser/LogParserUtils.java index d8b4fb8..74bf91c 100755 --- a/src/main/java/hudson/plugins/logparser/LogParserUtils.java +++ b/src/main/java/hudson/plugins/logparser/LogParserUtils.java @@ -145,16 +145,15 @@ public static int getLinesPerThread() { } public static int countLines(final String filename) throws IOException { - final LineNumberReader reader = new LineNumberReader(new FileReader( - filename)); - int count = 0; - while (reader.readLine() != null) { - // Read the whole file to count the lines. - count++; + try (final LineNumberReader reader = new LineNumberReader(new FileReader(filename))) { + int count = 0; + while (reader.readLine() != null) { + // Read the whole file to count the lines. + count++; + } + count = reader.getLineNumber(); + return count; } - count = reader.getLineNumber(); - reader.close(); - return count; } private LogParserUtils() { diff --git a/src/main/java/hudson/plugins/logparser/LogParserWriter.java b/src/main/java/hudson/plugins/logparser/LogParserWriter.java index d7fe719..10f86f0 100755 --- a/src/main/java/hudson/plugins/logparser/LogParserWriter.java +++ b/src/main/java/hudson/plugins/logparser/LogParserWriter.java @@ -18,14 +18,9 @@ public static void writeHeaderTemplateToAllLinkFiles( final HashMap writers, final int sectionCounter) throws IOException { final List statuses = LogParserConsts.STATUSES_WITH_SECTIONS_IN_LINK_FILES; - final int statusesSize = statuses.size(); - for (int i = 0; i < statusesSize; i++) { - final String currentStatus = (String) statuses.get(i); - final BufferedWriter linkWriter = (BufferedWriter) writers - .get(currentStatus); - String str = "HEADER HERE: #NUMBER"; - str = str.replaceFirst("NUMBER", - ((Integer) sectionCounter).toString()); + for (String status : statuses) { + final BufferedWriter linkWriter = writers.get(status); + String str = "HEADER HERE: #" + sectionCounter; linkWriter.write(str + "\n"); } @@ -41,10 +36,9 @@ public static void writeWrapperHtml(final String buildWrapperPath) + "build log\n" + "\n" + "\n"; - final BufferedWriter writer = new BufferedWriter(new FileWriter( - buildWrapperPath)); - writer.write(wrapperHtml); - writer.close(); + try (final BufferedWriter writer = new BufferedWriter(new FileWriter(buildWrapperPath))) { + writer.write(wrapperHtml); + } } public static void writeReferenceHtml(final String buildRefPath, @@ -63,36 +57,34 @@ public static void writeReferenceHtml(final String buildRefPath, + "\t\telement.display == 'none' ? element.display='block' : element.display='none';\n" + "\t}\n" + "\n"; - final BufferedWriter writer = new BufferedWriter(new FileWriter( - buildRefPath)); - // Hudson stylesheets - writer.write(LogParserConsts.getHtmlOpeningTags()); - writer.write(refStart); // toggle links javascript - // Write Errors - writeLinks(writer, LogParserConsts.ERROR, headerForSection, - statusCountPerSection, iconTable, linkListDisplay, - linkListDisplayPlural, statusCount, linkFiles); - // Write Warnings - writeLinks(writer, LogParserConsts.WARNING, headerForSection, - statusCountPerSection, iconTable, linkListDisplay, - linkListDisplayPlural, statusCount, linkFiles); - // Write Infos - writeLinks(writer, LogParserConsts.INFO, headerForSection, - statusCountPerSection, iconTable, linkListDisplay, - linkListDisplayPlural, statusCount, linkFiles); - // Write Debugs - writeLinks(writer, LogParserConsts.DEBUG, headerForSection, - statusCountPerSection, iconTable, linkListDisplay, - linkListDisplayPlural, statusCount, linkFiles); - // Write extra tags - for (String extraTag : extraTags) { - writeLinks(writer, extraTag, headerForSection, + try (final BufferedWriter writer = new BufferedWriter(new FileWriter(buildRefPath))) { + // Hudson stylesheets + writer.write(LogParserConsts.getHtmlOpeningTags()); + writer.write(refStart); // toggle links javascript + // Write Errors + writeLinks(writer, LogParserConsts.ERROR, headerForSection, + statusCountPerSection, iconTable, linkListDisplay, + linkListDisplayPlural, statusCount, linkFiles); + // Write Warnings + writeLinks(writer, LogParserConsts.WARNING, headerForSection, + statusCountPerSection, iconTable, linkListDisplay, + linkListDisplayPlural, statusCount, linkFiles); + // Write Infos + writeLinks(writer, LogParserConsts.INFO, headerForSection, + statusCountPerSection, iconTable, linkListDisplay, + linkListDisplayPlural, statusCount, linkFiles); + // Write Debugs + writeLinks(writer, LogParserConsts.DEBUG, headerForSection, statusCountPerSection, iconTable, linkListDisplay, linkListDisplayPlural, statusCount, linkFiles); + // Write extra tags + for (String extraTag : extraTags) { + writeLinks(writer, extraTag, headerForSection, + statusCountPerSection, iconTable, linkListDisplay, + linkListDisplayPlural, statusCount, linkFiles); + } + writer.write(LogParserConsts.getHtmlClosingTags()); } - writer.write(LogParserConsts.getHtmlClosingTags()); - writer.close(); // Close to unlock and flush to disk. - } private static void writeLinks(final BufferedWriter writer, @@ -118,7 +110,7 @@ private static void writeLinks(final BufferedWriter writer, final String linkListCount = statusCount.get(status).toString(); final String hudsonRoot = Jenkins.get().getRootUrl(); - final String iconLocation = String.format("%s/images/16x16/", Functions.getResourcePath()); + final String iconLocation = String.format("%s/plugin/log-parser/images/", jenkins.model.Jenkins.RESOURCE_PATH).substring(1); final String styles = "\n"; writer.write(styles); - final String linksStart = "\""\n" + "" + linkListDisplayStr + " (" + linkListCount + ")
\n" @@ -139,49 +131,48 @@ private static void writeLinks(final BufferedWriter writer, writer.write(linksStart); // Read the links file and insert here - final BufferedReader reader = new BufferedReader(new FileReader( - linkFiles.get(status))); - final String summaryLine = "
(SUMMARY_INT_HERE LINK_LIST_DISPLAY_STR in this section)
"; - - final String headerTemplateRegexp = "HEADER HERE:"; - final String headerTemplateSplitBy = "#"; - - // If it's a header line - put the header of the section - String line; - while ((line = reader.readLine()) != null) { - String curSummaryLine = null; - if (line.startsWith(headerTemplateRegexp)) { - final int headerNum = Integer.parseInt(line.split(headerTemplateSplitBy)[1]); - line = headerForSection.get(headerNum); - final String key = LogParserUtils.getSectionCountKey(status, headerNum); - final Integer summaryInt = statusCountPerSection.get(key); - if (summaryInt == null || summaryInt == 0) { - // Don't write the header if there are no relevant lines for - // this section - line = null; - } else { - String linkListDisplayStrWithPlural = linkListDisplayStr; - if (summaryInt > 1) { - linkListDisplayStrWithPlural = linkListDisplayStrPlural; + try (final BufferedReader reader = new BufferedReader(new FileReader(linkFiles.get(status)))) { + final String summaryLine = "
(SUMMARY_INT_HERE LINK_LIST_DISPLAY_STR in this section)
"; + + final String headerTemplateRegexp = "HEADER HERE:"; + final String headerTemplateSplitBy = "#"; + + // If it's a header line - put the header of the section + String line; + while ((line = reader.readLine()) != null) { + String curSummaryLine = null; + if (line.startsWith(headerTemplateRegexp)) { + final int headerNum = Integer.parseInt(line.split(headerTemplateSplitBy)[1]); + line = headerForSection.get(headerNum); + final String key = LogParserUtils.getSectionCountKey(status, headerNum); + final Integer summaryInt = statusCountPerSection.get(key); + if (summaryInt == null || summaryInt == 0) { + // Don't write the header if there are no relevant lines for + // this section + line = null; + } else { + String linkListDisplayStrWithPlural = linkListDisplayStr; + if (summaryInt > 1) { + linkListDisplayStrWithPlural = linkListDisplayStrPlural; + } + curSummaryLine = summaryLine.replace("SUMMARY_INT_HERE", + summaryInt.toString()).replace( + "LINK_LIST_DISPLAY_STR", + linkListDisplayStrWithPlural); } - curSummaryLine = summaryLine.replace("SUMMARY_INT_HERE", - summaryInt.toString()).replace( - "LINK_LIST_DISPLAY_STR", - linkListDisplayStrWithPlural); - } - } + } - if (line != null) { - writer.write(line); - writer.newLine(); // Write system dependent end of line. - } - if (curSummaryLine != null) { - writer.write(curSummaryLine); - writer.newLine(); // Write system dependent end of line. + if (line != null) { + writer.write(line); + writer.newLine(); // Write system dependent end of line. + } + if (curSummaryLine != null) { + writer.write(curSummaryLine); + writer.newLine(); // Write system dependent end of line. + } } } - reader.close(); // Close to unlock. final String linksEnd = "\n"; writer.write(linksEnd); diff --git a/src/main/java/hudson/plugins/logparser/ReadWriteTextFile.java b/src/main/java/hudson/plugins/logparser/ReadWriteTextFile.java index 03e7891..ca57c46 100755 --- a/src/main/java/hudson/plugins/logparser/ReadWriteTextFile.java +++ b/src/main/java/hudson/plugins/logparser/ReadWriteTextFile.java @@ -8,8 +8,10 @@ import java.io.FileWriter; import java.io.IOException; import java.io.Writer; +import java.util.logging.Logger; public final class ReadWriteTextFile { + private static final Logger LOGGER = Logger.getLogger(ReadWriteTextFile.class.getName()); private ReadWriteTextFile() { // to suppress PMD warning @@ -18,19 +20,13 @@ private ReadWriteTextFile() { static public String getContents(final File aFile) { final StringBuilder contents = new StringBuilder(); - try { - final BufferedReader input = new BufferedReader(new FileReader( - aFile)); - try { - String line = null; // not declared within while loop - while ((line = input.readLine()) != null) { - contents.append(line + "\n"); - } - } finally { - input.close(); + try (final BufferedReader input = new BufferedReader(new FileReader(aFile))) { + String line = null; // not declared within while loop + while ((line = input.readLine()) != null) { + contents.append(line).append("\n"); } } catch (IOException ex) { - ex.printStackTrace(); + LOGGER.warning("Failure reading from " + aFile.getPath()); } return contents.toString(); @@ -42,7 +38,12 @@ static public void setContents(final File aFile, final String aContents) throw new IllegalArgumentException("File should not be null."); } if (!aFile.exists()) { - aFile.createNewFile(); + boolean created = aFile.createNewFile(); + if (created) { + LOGGER.fine(aFile.getPath() + " created"); + } else { + LOGGER.fine(aFile.getPath() + " already exists"); + } } if (!aFile.isFile()) { throw new IllegalArgumentException("Should not be a directory: " @@ -54,12 +55,9 @@ static public void setContents(final File aFile, final String aContents) } // use buffering - final Writer output = new BufferedWriter(new FileWriter(aFile)); - try { + try (final Writer output = new BufferedWriter(new FileWriter(aFile))) { // FileWriter always assumes default encoding is OK! output.write(aContents); - } finally { - output.close(); } } diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly new file mode 100644 index 0000000..331c7fd --- /dev/null +++ b/src/main/resources/index.jelly @@ -0,0 +1,4 @@ + +
+Parses the console log generated by a build +
diff --git a/src/test/java/org/jenkinsci/plugins/logparser/BlockSlaveToMasterFileCallable.java b/src/test/java/org/jenkinsci/plugins/logparser/BlockSlaveToMasterFileCallable.java deleted file mode 100644 index 00cfd8a..0000000 --- a/src/test/java/org/jenkinsci/plugins/logparser/BlockSlaveToMasterFileCallable.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * The MIT License - * - * Copyright 2021 CloudBees, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package org.jenkinsci.plugins.logparser; - -import edu.umd.cs.findbugs.annotations.Nullable; -import hudson.Extension; -import hudson.remoting.ChannelBuilder; -import java.io.File; -import jenkins.ReflectiveFilePathFilter; -import jenkins.SlaveToMasterFileCallable; -import jenkins.security.ChannelConfigurator; - -/** - * Prevents all {@link SlaveToMasterFileCallable}s from running during tests, to make sure we do not rely on them. - */ -public class BlockSlaveToMasterFileCallable extends ReflectiveFilePathFilter { - - @Override protected boolean op(String name, File path) throws SecurityException { - throw new SecurityException("refusing to " + name + " on " + path); - } - - @Extension public static class ChannelConfiguratorImpl extends ChannelConfigurator { - - @Override public void onChannelBuilding(ChannelBuilder builder, @Nullable Object context) { - new BlockSlaveToMasterFileCallable().installTo(builder, 1000); // higher priority than, say, AdminFilePathFilter or even DefaultFilePathFilter - } - - } - -} diff --git a/src/test/java/org/jenkinsci/plugins/logparser/LogParserWorkflowTest.java b/src/test/java/org/jenkinsci/plugins/logparser/LogParserWorkflowTest.java index 50b6fcc..f152d58 100644 --- a/src/test/java/org/jenkinsci/plugins/logparser/LogParserWorkflowTest.java +++ b/src/test/java/org/jenkinsci/plugins/logparser/LogParserWorkflowTest.java @@ -10,12 +10,15 @@ import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.junit.BeforeClass; import org.junit.ClassRule; -import org.junit.Ignore; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.ToolInstallations; +import java.io.File; +import java.net.URL; + import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** * In this test suite we initialize the Job workspaces with a resource (maven-project1.zip) that contains a Maven @@ -34,7 +37,10 @@ public static void init() throws Exception { WorkflowJob job = jenkinsRule.jenkins.createProject(WorkflowJob.class, "logParserPublisherWorkflowStep"); DumbSlave agent = jenkinsRule.createOnlineSlave(); FilePath workspace = agent.getWorkspaceFor(job); - workspace.unzipFrom(LogParserWorkflowTest.class.getResourceAsStream("./maven-project1.zip")); + assertNotNull(workspace); + URL mavenProject = LogParserWorkflowTest.class.getResource("./maven-project1"); + assertNotNull(mavenProject); + new FilePath(new File(mavenProject.toURI())).copyRecursiveTo(workspace); job.setDefinition(new CpsFlowDefinition("" + "node('" + agent.getNodeName() + "') {\n" + " def mvnHome = tool '" + mavenInstallation.getName() + "'\n" diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1.zip b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1.zip deleted file mode 100644 index 8bbe46c..0000000 Binary files a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1.zip and /dev/null differ diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/.gitignore b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/.gitignore new file mode 100644 index 0000000..67cf78c --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/.gitignore @@ -0,0 +1,61 @@ +# Created by .ignore support plugin (hsz.mobi) +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties + diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/Jenkinsfile b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/Jenkinsfile new file mode 100644 index 0000000..6ab173a --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/Jenkinsfile @@ -0,0 +1,3 @@ +node { + echo 'Hello World 6' +} diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/doc.txt b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/doc.txt new file mode 100644 index 0000000..c372db4 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/doc.txt @@ -0,0 +1 @@ +test9 diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/logparser-rules.txt b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/logparser-rules.txt new file mode 100644 index 0000000..2207fc7 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/logparser-rules.txt @@ -0,0 +1,5 @@ +warn /\[WARNING\]/ + +jenkins /JENKINS/ + +logParserPublisherWorkflowStep /\[Pipeline\] logParser/ \ No newline at end of file diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/pom.xml b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/pom.xml new file mode 100644 index 0000000..ba0fe6e --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/pom.xml @@ -0,0 +1,98 @@ + + 4.0.0 + com.cloudbees.manticore + example + jar + 1.0-SNAPSHOT + example + http://maven.apache.org + + + com.opencsv + opencsv + 3.5 + + + org.apache.struts + struts2-core + 2.3.20 + + + junit + junit + 3.8.1 + test + + + + + UTF-8 + UTF-8 + UTF-8 + 1.8 + 1.8 + + + + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.5 + + + verify-cpd + + + cpd-check + + + + + true + 25 + true + false + + + + + diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/src/main/java/com/cloudbees/manticore/App.java b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/src/main/java/com/cloudbees/manticore/App.java new file mode 100644 index 0000000..12a7206 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/src/main/java/com/cloudbees/manticore/App.java @@ -0,0 +1,55 @@ +package com.cloudbees.manticore; + +/** + * Hello world! + * + */ +public class App +{ + public static void main( String[] args ) { + System.out.println( "Hello World!" ); + } + + private int partition(int arr[], int left, int right) { + int i = left, j = right; + int tmp; + int pivot = arr[(left + right) / 2]; + + while (i <= j) { + while (arr[i] < pivot) { + i++; + } + while (arr[j] > pivot) { + j--; + } + if (i <= j) { + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + i++; + j--; + } + }; + return i; + } + + private void quickSort(int arr[], int left, int right) { + int index = partition(arr, left, right); + if (left < index - 1) { + this.quickSort(arr, left, index - 1); + } + if (index < right) { + this.quickSort(arr, index, right); + } + } + + private void quickSort2(int arr[], int left, int right) { + int index = partition(arr, left, right); + if (left < index - 1) { + this.quickSort(arr, left, index - 1); + } + if (index < right) { + this.quickSort(arr, index, right); + } + } +} diff --git a/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/src/test/java/com/cloudbees/manticore/AppTest.java b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/src/test/java/com/cloudbees/manticore/AppTest.java new file mode 100644 index 0000000..cdd09be --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/logparser/maven-project1/src/test/java/com/cloudbees/manticore/AppTest.java @@ -0,0 +1,38 @@ +package com.cloudbees.manticore; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}