Skip to content

Commit

Permalink
Added possibility to have multiple finders
Browse files Browse the repository at this point in the history
  • Loading branch information
judovana committed Oct 10, 2019
1 parent 7ad396e commit 8e52f5e
Show file tree
Hide file tree
Showing 7 changed files with 314 additions and 77 deletions.
78 changes: 78 additions & 0 deletions src/main/java/hudson/plugins/textfinder/TextFinderModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package hudson.plugins.textfinder;

import hudson.Extension;
import hudson.Util;
import hudson.model.AbstractDescribableImpl;
import hudson.model.Descriptor;
import java.io.Serializable;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.kohsuke.stapler.DataBoundConstructor;

public final class TextFinderModel extends AbstractDescribableImpl<TextFinderModel>
implements Serializable {
private static final long serialVersionUID = 1L;

private final String fileSet;
private final String regexp;
private final boolean succeedIfFound;
private final boolean unstableIfFound;
private final boolean notBuiltIfFound;
/** True to also scan the whole console output */
private final boolean alsoCheckConsoleOutput;

@DataBoundConstructor
public TextFinderModel(
String fileSet,
String regexp,
boolean succeedIfFound,
boolean unstableIfFound,
boolean alsoCheckConsoleOutput,
boolean notBuiltIfFound) {
this.fileSet = fileSet != null ? Util.fixEmpty(fileSet.trim()) : null;
this.regexp = regexp;
this.succeedIfFound = succeedIfFound;
this.unstableIfFound = unstableIfFound;
this.alsoCheckConsoleOutput = alsoCheckConsoleOutput;
this.notBuiltIfFound = notBuiltIfFound;

// Attempt to compile regular expression
try {
Pattern.compile(regexp);
} catch (PatternSyntaxException e) {
// falls through
}
}

public String getFileSet() {
return fileSet;
}

public String getRegexp() {
return regexp;
}

public boolean isSucceedIfFound() {
return succeedIfFound;
}

public boolean isUnstableIfFound() {
return unstableIfFound;
}

public boolean isNotBuiltIfFound() {
return notBuiltIfFound;
}

public boolean isAlsoCheckConsoleOutput() {
return alsoCheckConsoleOutput;
}

@Extension
public static class DescriptorImpl extends Descriptor<TextFinderModel> {
@Override
public String getDisplayName() {
return "Text Finder";
}
}
}
169 changes: 106 additions & 63 deletions src/main/java/hudson/plugins/textfinder/TextFinderPublisher.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,20 @@
import java.io.Reader;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import javax.servlet.ServletException;
import jenkins.MasterToSlaveFileCallable;
import jenkins.model.Jenkins;
import jenkins.tasks.SimpleBuildStep;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;

/**
Expand All @@ -50,63 +52,53 @@
*/
public class TextFinderPublisher extends Recorder implements Serializable, SimpleBuildStep {

public String fileSet;
public final String regexp;
public boolean succeedIfFound;
public boolean unstableIfFound;
public boolean notBuiltIfFound;
/** True to also scan the whole console output */
public boolean alsoCheckConsoleOutput;
/** This is the primary text finder in the configuration. */
private final TextFinderModel primaryTextFinder;

@DataBoundConstructor
public TextFinderPublisher(String regexp) {
this.regexp = regexp;
/** Additional text finder configurations are stored here. */
private final List<TextFinderModel> additionalTextFinders;

// Attempt to compile regular expression
try {
Pattern.compile(regexp);
} catch (PatternSyntaxException e) {
// falls through
}
}

@Deprecated
/**
* @param fileSet Kept for backward compatibility with old configuration.
* @param regexp Kept for backward compatibility with old configuration.
* @param succeedIfFound Kept for backward compatibility with old configuration.
* @param unstableIfFound Kept for backward compatibility with old configuration.
* @param notBuiltIfFound Kept for backward compatibility with old configuration.
* @param alsoCheckConsoleOutput Kept for backward compatibility with old configuration.
* @param additionalTextFinders configuration for additional textFinders
*/
@DataBoundConstructor
public TextFinderPublisher(
String fileSet,
String regexp,
boolean succeedIfFound,
boolean unstableIfFound,
boolean alsoCheckConsoleOutput) {
this(regexp);
this.fileSet = Util.fixEmpty(fileSet.trim());
this.succeedIfFound = succeedIfFound;
this.unstableIfFound = unstableIfFound;
this.alsoCheckConsoleOutput = alsoCheckConsoleOutput;
}

@DataBoundSetter
public void setFileSet(String fileSet) {
this.fileSet = Util.fixEmpty(fileSet.trim());
}

@DataBoundSetter
public void setSucceedIfFound(boolean succeedIfFound) {
this.succeedIfFound = succeedIfFound;
}

@DataBoundSetter
public void setUnstableIfFound(boolean unstableIfFound) {
this.unstableIfFound = unstableIfFound;
}

@DataBoundSetter
public void setNotBuiltIfFound(boolean notBuiltIfFound) {
this.notBuiltIfFound = notBuiltIfFound;
}
boolean notBuiltIfFound,
boolean alsoCheckConsoleOutput,
List<TextFinderModel> additionalTextFinders) {
this.primaryTextFinder =
new TextFinderModel(
Util.fixEmpty(fileSet != null ? fileSet.trim() : ""),
regexp,
succeedIfFound,
unstableIfFound,
alsoCheckConsoleOutput,
notBuiltIfFound);

this.additionalTextFinders = new ArrayList<>();
if (additionalTextFinders != null && !additionalTextFinders.isEmpty()) {
this.additionalTextFinders.addAll(additionalTextFinders);
}

@DataBoundSetter
public void setAlsoCheckConsoleOutput(boolean alsoCheckConsoleOutput) {
this.alsoCheckConsoleOutput = alsoCheckConsoleOutput;
// Attempt to compile regular expressions
try {
Pattern.compile(primaryTextFinder.getRegexp());
for (TextFinderModel textFinder : this.additionalTextFinders) {
Pattern.compile(textFinder.getRegexp());
}
} catch (PatternSyntaxException e) {
// falls through
}
}

@Override
Expand All @@ -117,51 +109,59 @@ public BuildStepMonitor getRequiredMonitorService() {
@Override
public void perform(Run<?, ?> run, FilePath workspace, Launcher launcher, TaskListener listener)
throws InterruptedException, IOException {
findText(run, workspace, listener);
findText(primaryTextFinder, run, workspace, listener);
for (TextFinderModel additionalTextFinder : additionalTextFinders) {
findText(additionalTextFinder, run, workspace, listener);
}
}

/** Indicates an orderly abortion of the processing. */
private static final class AbortException extends RuntimeException {}

private void findText(Run<?, ?> run, FilePath workspace, TaskListener listener)
private void findText(
TextFinderModel textFinder, Run<?, ?> run, FilePath workspace, TaskListener listener)
throws IOException, InterruptedException {
try {
PrintStream logger = listener.getLogger();
boolean foundText = false;

if (alsoCheckConsoleOutput) {
if (textFinder.isAlsoCheckConsoleOutput()) {
// Do not mention the pattern we are looking for to avoid false positives
logger.println("[Text Finder] Scanning console output...");
foundText |= checkConsole(run, compilePattern(logger, regexp), logger);
foundText |=
checkConsole(run, compilePattern(logger, textFinder.getRegexp()), logger);
logger.println(
"[Text Finder] Finished looking for pattern "
+ "'"
+ regexp
+ textFinder.getRegexp()
+ "'"
+ " in the console output");
}

final RemoteOutputStream ros = new RemoteOutputStream(logger);

if (fileSet != null) {
if (textFinder.getFileSet() != null) {
logger.println(
"[Text Finder] Looking for pattern "
+ "'"
+ regexp
+ textFinder.getRegexp()
+ "'"
+ " in the files at "
+ "'"
+ fileSet
+ textFinder.getFileSet()
+ "'");
foundText |= workspace.act(new FileChecker(ros, fileSet, regexp));
foundText |=
workspace.act(
new FileChecker(
ros, textFinder.getFileSet(), textFinder.getRegexp()));
}

if (foundText != succeedIfFound) {
if (foundText != textFinder.isSucceedIfFound()) {
final Result finalResult;
if (notBuiltIfFound) {
if (textFinder.isNotBuiltIfFound()) {
finalResult = Result.NOT_BUILT;
} else {
finalResult = unstableIfFound ? Result.UNSTABLE : Result.FAILURE;
finalResult = textFinder.isUnstableIfFound() ? Result.UNSTABLE : Result.FAILURE;
}
run.setResult(finalResult);
}
Expand Down Expand Up @@ -229,7 +229,6 @@ private static boolean checkFile(File f, Pattern pattern, PrintStream logger, Ch
logger.println("[Text Finder] Error reading file '" + f + "' -- ignoring");
Functions.printStackTrace(e, logger);
}

return false;
}

Expand All @@ -244,6 +243,41 @@ private static Pattern compilePattern(PrintStream logger, String regexp) {
return pattern;
}

@SuppressWarnings("unused")
public List<TextFinderModel> getAdditionalTextFinders() {
return additionalTextFinders;
}

@SuppressWarnings("unused")
public String getFileSet() {
return this.primaryTextFinder.getFileSet();
}

@SuppressWarnings("unused")
public String getRegexp() {
return this.primaryTextFinder.getRegexp();
}

@SuppressWarnings("unused")
public boolean isSucceedIfFound() {
return this.primaryTextFinder.isSucceedIfFound();
}

@SuppressWarnings("unused")
public boolean isUnstableIfFound() {
return this.primaryTextFinder.isUnstableIfFound();
}

@SuppressWarnings("unused")
public boolean isNotBuiltIfFound() {
return this.primaryTextFinder.isNotBuiltIfFound();
}

@SuppressWarnings("unused")
public boolean isAlsoCheckConsoleOutput() {
return this.primaryTextFinder.isAlsoCheckConsoleOutput();
}

@Symbol("findText")
@Extension
public static final class DescriptorImpl extends BuildStepDescriptor<Publisher> {
Expand All @@ -262,6 +296,15 @@ public boolean isApplicable(Class<? extends AbstractProject> jobType) {
return true;
}

public List<TextFinderModel.DescriptorImpl> getItemDescriptors() {
Jenkins jenkins = Jenkins.getInstance();
if (jenkins != null) {
return jenkins.getDescriptorList(TextFinderModel.class);
} else {
throw new NullPointerException("not able to get Jenkins instance");
}
}

/**
* Checks the regular expression validity.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form">
<f:entry field="fileSet" title="${%Files}">
<f:textbox/>
</f:entry>
<f:entry field="alsoCheckConsoleOutput" title="">
<f:checkbox/>
<label class="attach-previous">${%Also search the console output}</label>
</f:entry>
<f:entry field="regexp" title="${%Regular expression}">
<f:textbox/>
</f:entry>
<f:entry field="succeedIfFound" title="${%Succeed if found}">
<f:checkbox/>
</f:entry>
<f:entry field="unstableIfFound" title="${%Unstable if found}">
<f:checkbox/>
</f:entry>
<f:entry field="notBuiltIfFound" title="${%Not Built if found}">
<f:checkbox/>
</f:entry>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@
<f:entry field="notBuiltIfFound" title="${%Not Built if found}">
<f:checkbox/>
</f:entry>
<f:entry field="additionalTextFinders">
<f:hetero-list name="additionalTextFinders"
hasHeader="true"
descriptors="${descriptor.itemDescriptors}"
items="${instance.additionalTextFinders}"
addCaption="Add additional Text Finder"
deleteCaption="Delete additional Text Finder"/>
</f:entry>
</j:jelly>
Loading

0 comments on commit 8e52f5e

Please sign in to comment.