Skip to content

Commit

Permalink
Added support for usage of descriptions in search
Browse files Browse the repository at this point in the history
description of both project,view  and build canbe now shown
In addition it is possible to search through it
  • Loading branch information
judovana committed May 4, 2023
1 parent 5da7d85 commit 7dc55ed
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 42 deletions.
18 changes: 13 additions & 5 deletions src/main/java/hudson/plugins/nested_view/NestedViewsSearch.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public NestedViewsSearch() {
Jenkins j = Jenkins.get();
for (TopLevelItem ti : j.getItems()) {
if (ti instanceof AbstractProject) {
all.add(new NamableWithClass(ti, ti.getName(), ti.getName()));
all.add(new NamableWithClass(ti, ti.getName(), ti.getName(), ((AbstractProject<?, ?>) ti).getDescription()));
}
}
addViewsRecursively(j.getViews(), "/", all);
Expand All @@ -66,10 +66,10 @@ private void addViewsRecursively(Collection<View> views, String s, List<NamableW
for (View v : views) {
if (v instanceof NestedView) {
NestedView nw = (NestedView) v;
all.add(new NamableWithClass(v, v.getViewName(), s + v.getViewName()));
all.add(new NamableWithClass(v, v.getViewName(), s + v.getViewName(), nw.getDescription()));
addViewsRecursively(((NestedView) v).getViews(), s + v.getViewName() + "/", all);
} else {
all.add(new NamableWithClass(v, v.getViewName(), s + v.getViewName()));
all.add(new NamableWithClass(v, v.getViewName(), s + v.getViewName(), v.getDescription()));
}
}
}
Expand Down Expand Up @@ -162,6 +162,9 @@ public List<HelpItem> getSearchHelp() throws IOException {
r.add(new HelpItem("v", "search only in views (default is in all) -jw (-jvn)"));
r.add(new HelpItem("n", "search only in nested views (default is in all -jw (-jvn))"));
r.add(new HelpItem("w", "search only in views and nested views (default is in all -jw (-jvn))"));
r.add(new HelpItem("#", "will show job description"));
r.add(new HelpItem("##",
"will search job description"));
r.add(new HelpItem("!", "invert result"));
r.add(new HelpItem("t", "sort results; have digital parameter:"));
r.add(new HelpItem("1", "default - by lenght of items"));
Expand All @@ -175,20 +178,25 @@ public List<HelpItem> getSearchHelp() throws IOException {
r.add(new HelpItem("P", "will include project details"));
r.add(new HelpItem("Ln", "will add information about last builds. Plain L c an be followed by mask of numbers 1-last,2-stable,3-green,4-yellow,5-red,6-unsuccess,7-completed"));
r.add(new HelpItem("Bn", "details about builds. N is limiting am amount of builds. Default is 10!"));
r.add(new HelpItem("/", "will show builds description"));
r.add(new HelpItem("Sn", "statistics (like weather, but in numbers). N is limiting am amount of builds. Default is 10! If you use SS, then all, even unused resutls will be shown"));
r.add(new HelpItem("S x B x L", "S and B switches are iterating to the past. This may have significant performance impact! L should be fast always"));
r.add(new HelpItem("d",
"will search also in DisplayName. In addition it sets `-oB` as OR and Build details are required for it to work. The OR is enforcing you to filter jobs first and name as second"));
r.add(new HelpItem("i",
"will search also in artifacts. In addition it sets `-oB` as OR and Build details are required for it to work. The OR is enforcing you to filter jobs first and name as second"));
"will search also in artifacts. In addition it sets `-oB` as OR and Build details are required for it to work. The OR is enforcing you to filter jobs first and artifact name as second"));
r.add(new HelpItem("//",
"will search also in build description. In addition it sets `-oB` as OR and Build details are required for it to work. The OR is enforcing you to filter jobs first and build description as second"));
r.add(new HelpItem("A",
"is controlling, how many artifacts in most to search through. Default 10. Reasonable numbers ends in some 100. Without i/I useless"));
r.add(new HelpItem("D/I",
"Same as -d/-i, but only projects with at least one matching build will be shown. -d/-D -i/-I do not affect suggestions and can be acompanied by number - algorithm: "));
r.add(new HelpItem("///",
"Same as //, but shows only projects with at least one matching description in build. Build descriptions do not affect suggestions and can be accompanied by number - algorithm: "));
r.add(new HelpItem("1: ", "default, what mathced project name, is not used in displayName/artifact search. -! is weird here, not sure what to do better"));
r.add(new HelpItem("2: ", "all yor expressions are used used in displayName/artifact search"));
r.add(new HelpItem("note",
"Algortihm is shared between i/I/d/D if you set it once, yo can not unset it."));
"Algortihm is shared between i/I/d/D and /// or // if you set it once, yo can not unset it."));
return r;
}

Expand Down
27 changes: 18 additions & 9 deletions src/main/java/hudson/plugins/nested_view/search/BuildDetails.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,28 @@ public class BuildDetails {

private final String id;
private final String displayName;
private final String description;
private final String result;
private final String timeStampString;
private final String prefix;
private final Date dateTime;
private final List<Run.Artifact> artifacts;

public BuildDetails(String prefix, Run run, int archives) {
this(prefix, run.getId(), run.getDisplayName(), run.getResult(), run.getTimestampString(), run.getTime(), archives>0?run.getArtifactsUpTo(archives):new ArrayList<Run.Artifact>(0));
this(prefix, run.getId(), run.getDisplayName(), run.getDescription(), run.getResult(), run.getTimestampString(), run.getTime(),
archives > 0 ? run.getArtifactsUpTo(archives) : new ArrayList<Run.Artifact>(0));
}

@SuppressFBWarnings(value = {"EI_EXPOSE_REP2"}, justification = "date is not cared")
public BuildDetails(String prefix, String id, String displayName, Result result, String timeStampString, Date dateTime, List<Run.Artifact> list) {
public BuildDetails(String prefix, String id, String displayName, String description, Result result, String timeStampString, Date dateTime, List<Run.Artifact> list) {
this.prefix = prefix;
this.id = id;
this.displayName = displayName;
this.description = description;
this.result = result == null ? "RUNNING" : result.toString();
this.timeStampString = timeStampString;
this.dateTime = dateTime;
this.artifacts = (list==null?new ArrayList<>():list);
this.artifacts = (list == null ? new ArrayList<>() : list);
}

public List<String> getArtifacts() {
Expand Down Expand Up @@ -63,11 +66,14 @@ public LinkableCandidate toLinkable(String projectName, SearchArtifactsOptions s
post = id + "/" + displayName;
}
post = post + "/" + result + "/" + timeStampString + " ago";
if (artifacts.size()>0) {
post += " ("+artifacts.size()+" artifacts)";
if (searchArtifactsOptions != null && searchArtifactsOptions.description && description != null) {
post += " [" + description + "]";
}
if (artifacts.size() > 0) {
post += " (" + artifacts.size() + " artifacts)";
}
List<LinkableCandidate> sublinks = new ArrayList<>(artifacts.size());
if(searchArtifactsOptions != null) {
if (searchArtifactsOptions != null) {
for (Run.Artifact artifact : artifacts) {
for (String candidate : searchArtifactsOptions.query) {
if (searchArtifactsOptions.algorithm == 1 && searchArtifactsOptions.matched != null && searchArtifactsOptions.matched.contains(candidate)) {
Expand All @@ -76,8 +82,9 @@ public LinkableCandidate toLinkable(String projectName, SearchArtifactsOptions s
boolean matches = NamableWithClass.matchSingle(artifact.relativePath, candidate, searchArtifactsOptions.how);
if (!searchArtifactsOptions.invert) {
if (matches) {
sublinks.add(new LinkableCandidate("", artifact.relativePath, "", getJenkinsUrl() + "/job/" + projectName + "/" + id + "/artifact/" + artifact.relativePath, new ArrayList<>(0)));
if (listener!=null){
sublinks.add(new LinkableCandidate("", artifact.relativePath, "", getJenkinsUrl() + "/job/" + projectName + "/" + id + "/artifact/" + artifact.relativePath,
new ArrayList<>(0)));
if (listener != null) {
listener.addArtifactCouont();
}
break;
Expand Down Expand Up @@ -112,13 +119,15 @@ static class SearchArtifactsOptions {
private final Collection<String> matched;
private final String how;
private final boolean invert;
private final boolean description;

public SearchArtifactsOptions(String[] query, int algorithm, Collection<String> matched, String how, boolean invert) {
public SearchArtifactsOptions(String[] query, int algorithm, Collection<String> matched, String how, boolean invert, boolean description) {
this.query = query;
this.algorithm = algorithm;
this.matched = matched;
this.how = how;
this.invert = invert;
this.description = description;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public String getQuery() {
}

public String getUrl() {
return BuildDetails.getJenkinsUrl() + "/search/?q=" + getQuery();
return BuildDetails.getJenkinsUrl() + "/search/?q=" + getQuery().replaceAll("#","%23");
}

public int getSize() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,30 @@
import hudson.plugins.nested_view.NestedView;
import jenkins.model.Jenkins;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

public class NamableWithClass {
private final String name;
private final String fullPath;
private final String description;
private Object item;

public NamableWithClass(Object item, String name, String fullPath) {
public NamableWithClass(Object item, String name, String fullPath, String description) {
this.item = item;
this.name = name;
this.fullPath = fullPath;
this.description = description;
}

public String getName() {
return name;
}

public String getDescription() {
return description==null?"":description;
}

public String getFullPath() {
return fullPath;
}
Expand Down Expand Up @@ -65,6 +70,9 @@ private boolean matchesImpl(Query query, final Set<String> matched) {
if (query.getPart().equals("p")) {
nameOrPath = getName();
}
if (query.getQuery().contains("##")) {
nameOrPath = getDescription();
}
boolean clazzPass = false;
if (query.getWhere().contains("j") && (item instanceof AbstractProject)) {
clazzPass = true;
Expand Down
81 changes: 57 additions & 24 deletions src/main/java/hudson/plugins/nested_view/search/ProjectWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public ProjectWrapper(Optional<AbstractProject> project, boolean multiline, bool
query.isSearchByArtifacts(),
matched,
query.getHow(),
query.isInvert()
query.isInvert(),
query.isBuildComment()
);
} else {
artifactSearch = null;
Expand Down Expand Up @@ -79,6 +80,9 @@ public void createDetails() {
public List<LinkableCandidate> createDetailsImpl() {
if (project.isPresent()) {
List<LinkableCandidate> result = new ArrayList<>();
if (query!=null && query.isJobComment() && project.get().getDescription().length() > 0) {
result.add(new LinkableCandidate(project.get().getDescription()));
}
if (projectInfo) {
//-P
int bc = project.get().getNextBuildNumber() - 1;
Expand Down Expand Up @@ -154,29 +158,26 @@ public List<LinkableCandidate> createDetailsImpl() {
if (q instanceof AbstractBuild) {
AbstractBuild b = (AbstractBuild) q;
if (i1 > 0) {
if (query != null && query.isSearchByNvr() >= 0) {
if (query != null && (query.isSearchByNvr() >= 0 || query.isSearchByBuildComment()>=0)) {
for (String candidate : query.getWithoutArgumentsSplit()) {
if (query.isSearchByNvr() == 1 && matched != null && matched.contains(candidate)) {
continue;
}
String displayName = b.getDisplayName();
boolean matches = NamableWithClass.matchSingle(displayName, candidate, query.getHow());
if (!query.isInvert()) {
if (matches) {
BuildDetails bb = buildToString(b);
setDateTime(bb);
if (isBuildTimeValid(b)) {
buildsList.add(bb);
}
boolean hit = false;
if (!(query.isSearchByNvr() == 1 && matched != null && matched.contains(candidate))) {
String displayName = b.getDisplayName();
if (displayName == null) {
displayName = "";
}
} else {
if (!matches) {
BuildDetails bb = buildToString(b);
setDateTime(bb);
if (isBuildTimeValid(b)) {
buildsList.add(bb);
}
hit = tryMatch(buildsList, b, candidate, displayName);
}
if (hit) {
//we hsve to break, otherwise result can be added twice
break;
}
if (!(query.isSearchByBuildComment() == 1 && matched != null && matched.contains(candidate))) {
String description = b.getDescription();
if (description == null) {
description = "";
}
hit = tryMatch(buildsList, b, candidate, description);
}
}
} else {
Expand Down Expand Up @@ -223,6 +224,31 @@ public List<LinkableCandidate> createDetailsImpl() {
}
}

private boolean tryMatch(List<BuildDetails> buildsList, AbstractBuild b, String candidate, String displayName) {
boolean hit = false;
boolean matches = NamableWithClass.matchSingle(displayName, candidate, query.getHow());
if (!query.isInvert()) {
if (matches) {
BuildDetails bb = buildToString(b);
hit = true;
setDateTime(bb);
if (isBuildTimeValid(b)) {
buildsList.add(bb);
}
}
} else {
if (!matches) {
BuildDetails bb = buildToString(b);
hit = true;
setDateTime(bb);
if (isBuildTimeValid(b)) {
buildsList.add(bb);
}
}
}
return hit;
}

private boolean isBuildTimeValid(AbstractBuild b) {
return b.getTime().getTime() >= lowerTimeLimit.getTime();
}
Expand All @@ -248,7 +274,7 @@ private BuildDetails specifiedBuild(String s, Run lastBuild) {
if (query.isSearchByArtifacts() > 0) {
archives = Math.max(0, query.getMaxArtifacts());
}
return lastBuild != null ? new BuildDetails(s, lastBuild, archives) : new BuildDetails(s, null, null, null, null, new Date(0), new ArrayList<>(0));
return lastBuild != null ? new BuildDetails(s, lastBuild, archives) : new BuildDetails(s, null, null, null, null, null, new Date(0), new ArrayList<>(0));
}

private BuildDetails buildToString(Run ab) {
Expand All @@ -260,14 +286,21 @@ public boolean isStillValid() {
if (query == null) {
return true;
} else {
if (query.isSearchByNvr()>0) {
if (query.isSearchByNvr() > 0) {
if (query.isNvrFinalFilter() && matchedBuildsCount <= 0) {
return false;
} else {
return true;
}
}
if (query.isSearchByArtifacts()>0) {
if (query.isSearchByBuildComment() > 0) {
if (query.isBuildCommentFinalFilter() && matchedBuildsCount <= 0) {
return false;
} else {
return true;
}
}
if (query.isSearchByArtifacts() > 0) {
if (query.isArtifactFinalFilter() && matchedArtifactsCount <= 0) {
return false;
} else {
Expand Down
Loading

0 comments on commit 7dc55ed

Please sign in to comment.