Skip to content

Commit a39a67e

Browse files
authored
Merge pull request #219 from snyk/feat/fixable-issues-filter
Feat/fixable issues filter
2 parents eee6fb0 + 7ed56b2 commit a39a67e

22 files changed

Lines changed: 765 additions & 427 deletions

plugin/icons/transparent.png

97 Bytes
Loading

plugin/plugin.xml

Lines changed: 264 additions & 242 deletions
Large diffs are not rendered by default.

plugin/src/main/java/io/snyk/eclipse/plugin/SnykStartup.java

Lines changed: 151 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,18 @@
1717
import org.eclipse.core.runtime.Status;
1818
import org.eclipse.core.runtime.jobs.Job;
1919
import org.eclipse.jface.wizard.WizardDialog;
20-
import org.eclipse.lsp4e.LanguageServersRegistry;
21-
import org.eclipse.lsp4e.LanguageServiceAccessor;
2220
import org.eclipse.ui.IStartup;
2321
import org.eclipse.ui.IWorkbench;
22+
import org.eclipse.ui.IWorkbenchPage;
2423
import org.eclipse.ui.IWorkbenchWindow;
2524
import org.eclipse.ui.PartInitException;
2625
import org.eclipse.ui.PlatformUI;
2726

2827
import io.snyk.eclipse.plugin.properties.preferences.Preferences;
2928
import io.snyk.eclipse.plugin.utils.SnykLogger;
3029
import io.snyk.eclipse.plugin.views.SnykView;
30+
import io.snyk.eclipse.plugin.views.snyktoolview.ISnykToolView;
31+
import io.snyk.eclipse.plugin.views.snyktoolview.SnykToolView;
3132
import io.snyk.eclipse.plugin.wizards.SnykWizard;
3233
import io.snyk.languageserver.LsRuntimeEnvironment;
3334
import io.snyk.languageserver.SnykLanguageServer;
@@ -36,134 +37,152 @@
3637
import io.snyk.languageserver.download.LsDownloader;
3738

3839
public class SnykStartup implements IStartup {
39-
private static LsRuntimeEnvironment runtimeEnvironment;
40-
private SnykView snykView = null;
41-
private static boolean downloading = true;
42-
private static ILog logger;
43-
44-
private static SnykStartup instance;
45-
46-
@Override
47-
public void earlyStartup() {
48-
instance = this;
49-
if (logger == null) {
50-
logger = Platform.getLog(getClass());
51-
}
52-
runtimeEnvironment = new LsRuntimeEnvironment();
53-
Job initJob = new Job("Downloading latest CLI release...") {
54-
@Override
55-
protected IStatus run(IProgressMonitor monitor) {
56-
try {
57-
logger.info("LS: Checking for needed download");
58-
if (downloadLS()) {
59-
monitor.beginTask("Downloading CLI", 100);
60-
logger.info("LS: Need to download");
61-
downloading = true;
62-
download(monitor);
63-
}
64-
} catch (Exception exception) {
65-
logError(exception);
66-
}
67-
downloading = false;
68-
monitor.subTask("Starting Snyk CLI in Language Server mode...");
69-
startLanguageServer();
70-
71-
PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
72-
Preferences prefs = Preferences.getInstance();
73-
if (prefs.getAuthToken().isBlank() && !prefs.isTest()) {
74-
monitor.subTask("Starting Snyk Wizard to configure initial settings...");
75-
SnykWizard wizard = new SnykWizard();
76-
WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), wizard);
77-
dialog.setBlockOnOpen(true);
78-
dialog.open();
79-
}
80-
});
81-
monitor.done();
82-
83-
return Status.OK_STATUS;
84-
}
85-
86-
private void startLanguageServer() {
87-
try {
88-
SnykLanguageServer.startSnykLanguageServer();
89-
} catch (RuntimeException e) {
90-
logError(e);
91-
}
92-
}
93-
};
94-
initJob.setPriority(Job.LONG);
95-
initJob.schedule();
96-
}
97-
98-
public static SnykView getSnykView() {
99-
if (instance.snykView == null) {
100-
IWorkbench workbench = PlatformUI.getWorkbench();
101-
102-
workbench.getDisplay().syncExec(() -> {
103-
IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
104-
105-
if (workbenchWindow != null) {
106-
try {
107-
instance.snykView = SnykView.getInstance();
108-
} catch (PartInitException partInitException) {
109-
logError(partInitException);
110-
}
111-
}
112-
});
113-
}
114-
115-
return instance.snykView;
116-
}
117-
118-
private boolean downloadLS() {
119-
File lsFile = new File(Preferences.getInstance().getCliPath());
120-
logger.info("LS: Expecting file at " + lsFile.getAbsolutePath());
121-
if (!Preferences.getInstance().isManagedBinaries()) {
122-
logger.info("LS: Managed binaries disabled, skipping download");
123-
return false;
124-
}
125-
if (lsFile.exists()) {
126-
logger.info("LS: File already exists, checking for age " + lsFile.getAbsolutePath());
127-
try {
128-
BasicFileAttributes basicFileAttributes;
129-
basicFileAttributes = Files.readAttributes(lsFile.toPath(), BasicFileAttributes.class);
130-
Instant lastModified = basicFileAttributes.lastModifiedTime().toInstant();
131-
boolean needsUpdate = lastModified.isBefore(Instant.now().minus(4, ChronoUnit.DAYS))
132-
|| !Preferences.getInstance().getLspVersion().equals(LsBinaries.REQUIRED_LS_PROTOCOL_VERSION);
133-
logger.info(String.format("LS: Needs update? %s. Required LSP version=%s, actual version=%s", needsUpdate,
134-
LsBinaries.REQUIRED_LS_PROTOCOL_VERSION, Preferences.getInstance().getLspVersion()));
135-
return needsUpdate;
136-
} catch (IOException e) {
137-
SnykLogger.logError(e);
138-
return false;
139-
}
140-
}
141-
return true;
142-
}
143-
144-
static LsDownloader getLsDownloader() throws URISyntaxException {
145-
return new LsDownloader(HttpClientFactory.getInstance(), runtimeEnvironment, logger);
146-
}
147-
148-
@SuppressWarnings("ResultOfMethodCallIgnored")
149-
public static IStatus download(IProgressMonitor monitor) {
150-
final File lsFile = new File(Preferences.getInstance().getCliPath());
151-
try {
152-
LsDownloader lsDownloader = getLsDownloader();
153-
lsFile.getParentFile().mkdirs();
154-
lsDownloader.download(monitor);
155-
lsFile.setExecutable(true);
156-
} catch (RuntimeException | URISyntaxException e) {
157-
return Status.error("Download of Snyk Language Server failed", e);
158-
}
159-
return Status.OK_STATUS;
160-
}
161-
162-
public static boolean isDownloading() {
163-
return downloading;
164-
}
165-
166-
public void setLogger(ILog logger) {
167-
this.logger = logger;
168-
}
40+
private static LsRuntimeEnvironment runtimeEnvironment;
41+
private SnykView snykView = null;
42+
private static SnykToolView snykToolView = null;
43+
private static boolean downloading = true;
44+
private static ILog logger;
45+
46+
private static SnykStartup instance;
47+
48+
@Override
49+
public void earlyStartup() {
50+
instance = this;
51+
if (logger == null) {
52+
logger = Platform.getLog(getClass());
53+
}
54+
runtimeEnvironment = new LsRuntimeEnvironment();
55+
Job initJob = new Job("Downloading latest CLI release...") {
56+
@Override
57+
protected IStatus run(IProgressMonitor monitor) {
58+
try {
59+
logger.info("LS: Checking for needed download");
60+
if (downloadLS()) {
61+
monitor.beginTask("Downloading CLI", 100);
62+
logger.info("LS: Need to download");
63+
downloading = true;
64+
download(monitor);
65+
}
66+
} catch (Exception exception) {
67+
logError(exception);
68+
}
69+
downloading = false;
70+
monitor.subTask("Starting Snyk CLI in Language Server mode...");
71+
startLanguageServer();
72+
73+
PlatformUI.getWorkbench().getDisplay().syncExec(() -> {
74+
Preferences prefs = Preferences.getInstance();
75+
if (prefs.getAuthToken().isBlank() && !prefs.isTest()) {
76+
monitor.subTask("Starting Snyk Wizard to configure initial settings...");
77+
SnykWizard wizard = new SnykWizard();
78+
WizardDialog dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(),
79+
wizard);
80+
dialog.setBlockOnOpen(true);
81+
dialog.open();
82+
}
83+
});
84+
monitor.done();
85+
86+
return Status.OK_STATUS;
87+
}
88+
89+
private void startLanguageServer() {
90+
try {
91+
SnykLanguageServer.startSnykLanguageServer();
92+
} catch (RuntimeException e) {
93+
logError(e);
94+
}
95+
}
96+
};
97+
initJob.setPriority(Job.LONG);
98+
initJob.schedule();
99+
}
100+
101+
public static SnykView getSnykView() {
102+
if (instance.snykView == null) {
103+
IWorkbench workbench = PlatformUI.getWorkbench();
104+
105+
workbench.getDisplay().syncExec(() -> {
106+
IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
107+
108+
if (workbenchWindow != null) {
109+
try {
110+
instance.snykView = SnykView.getInstance();
111+
} catch (PartInitException partInitException) {
112+
logError(partInitException);
113+
}
114+
}
115+
});
116+
}
117+
118+
return instance.snykView;
119+
}
120+
121+
public static ISnykToolView getView() {
122+
IWorkbench workbench = PlatformUI.getWorkbench();
123+
124+
workbench.getDisplay().syncExec(() -> {
125+
IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
126+
127+
try {
128+
snykToolView = (SnykToolView) activePage.showView(SnykToolView.ID);
129+
} catch (PartInitException e) {
130+
SnykLogger.logError(e);
131+
}
132+
});
133+
return snykToolView;
134+
}
135+
136+
private boolean downloadLS() {
137+
File lsFile = new File(Preferences.getInstance().getCliPath());
138+
logger.info("LS: Expecting file at " + lsFile.getAbsolutePath());
139+
if (!Preferences.getInstance().isManagedBinaries()) {
140+
logger.info("LS: Managed binaries disabled, skipping download");
141+
return false;
142+
}
143+
if (lsFile.exists()) {
144+
logger.info("LS: File already exists, checking for age " + lsFile.getAbsolutePath());
145+
try {
146+
BasicFileAttributes basicFileAttributes;
147+
basicFileAttributes = Files.readAttributes(lsFile.toPath(), BasicFileAttributes.class);
148+
Instant lastModified = basicFileAttributes.lastModifiedTime().toInstant();
149+
boolean needsUpdate = lastModified.isBefore(Instant.now().minus(4, ChronoUnit.DAYS))
150+
|| !Preferences.getInstance().getLspVersion().equals(LsBinaries.REQUIRED_LS_PROTOCOL_VERSION);
151+
logger.info(
152+
String.format("LS: Needs update? %s. Required LSP version=%s, actual version=%s", needsUpdate,
153+
LsBinaries.REQUIRED_LS_PROTOCOL_VERSION, Preferences.getInstance().getLspVersion()));
154+
return needsUpdate;
155+
} catch (IOException e) {
156+
SnykLogger.logError(e);
157+
return false;
158+
}
159+
}
160+
return true;
161+
}
162+
163+
static LsDownloader getLsDownloader() throws URISyntaxException {
164+
return new LsDownloader(HttpClientFactory.getInstance(), runtimeEnvironment, logger);
165+
}
166+
167+
@SuppressWarnings("ResultOfMethodCallIgnored")
168+
public static IStatus download(IProgressMonitor monitor) {
169+
final File lsFile = new File(Preferences.getInstance().getCliPath());
170+
try {
171+
LsDownloader lsDownloader = getLsDownloader();
172+
lsFile.getParentFile().mkdirs();
173+
lsDownloader.download(monitor);
174+
lsFile.setExecutable(true);
175+
} catch (RuntimeException | URISyntaxException e) {
176+
return Status.error("Download of Snyk Language Server failed", e);
177+
}
178+
return Status.OK_STATUS;
179+
}
180+
181+
public static boolean isDownloading() {
182+
return downloading;
183+
}
184+
185+
public void setLogger(ILog logger) {
186+
this.logger = logger;
187+
}
169188
}

plugin/src/main/java/io/snyk/eclipse/plugin/properties/preferences/Preferences.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ public static synchronized Preferences getInstance(PreferenceStore store) {
5050
public static final String FILTER_HIGH = "FILTER_SNYK_HIGH";
5151
public static final String FILTER_MEDIUM = "FILTER_SNYK_MEDIUM";
5252
public static final String FILTER_LOW = "FILTER_SNYK_LOW";
53-
public static final String FILTER_DELTA_OPEN_ISSUES = "FILTER_SNYK_OPEN_ISSUES";
54-
public static final String FILTER_DELTA_ALL_ISSUES = "FILTER_SNYK_ALL_ISSUES";
55-
public static final String FILTER_IGNORES_OPEN_ISSUES = "FILTER_IGNORES_OPEN_ISSUES";
56-
public static final String FILTER_IGNORES_IGNORED_ISSUES = "FILTER_IGNORES_IGNORED_ISSUES";
53+
public static final String FILTER_DELTA_NEW_ISSUES = "FILTER_SNYK_NEW_ISSUES";
54+
public static final String FILTER_IGNORES_SHOW_OPEN_ISSUES = "FILTER_IGNORES_OPEN_ISSUES";
55+
public static final String FILTER_IGNORES_SHOW_IGNORED_ISSUES = "FILTER_IGNORES_IGNORED_ISSUES";
56+
public static final String FILTER_FIXABLE_ISSUES = "FILTER_FIXABLE_ISSUES";
5757

5858
// This is a bit confusing - CLI takes DISABLE as env variable, but we ask for
5959
// ENABLE, so we need to revert it
@@ -97,6 +97,18 @@ public static synchronized Preferences getInstance(PreferenceStore store) {
9797
if (getPref(FILTER_CRITICAL) == null) {
9898
store(FILTER_CRITICAL, "false");
9999
}
100+
if (getPref(FILTER_DELTA_NEW_ISSUES) == null) {
101+
store(FILTER_DELTA_NEW_ISSUES, "false");
102+
}
103+
if (getPref(FILTER_IGNORES_SHOW_OPEN_ISSUES) == null) {
104+
store(FILTER_IGNORES_SHOW_OPEN_ISSUES, "true");
105+
}
106+
if (getPref(FILTER_IGNORES_SHOW_IGNORED_ISSUES) == null) {
107+
store(FILTER_IGNORES_SHOW_IGNORED_ISSUES, "true");
108+
}
109+
if (getPref(FILTER_FIXABLE_ISSUES) == null) {
110+
store(FILTER_FIXABLE_ISSUES, "false");
111+
}
100112

101113
if (getPref(SEND_ERROR_REPORTS) == null) {
102114
store(SEND_ERROR_REPORTS, "true");
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package io.snyk.eclipse.plugin.views.snyktoolview;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import org.eclipse.jface.viewers.ILabelProvider;
7+
import org.eclipse.jface.viewers.TreeViewer;
8+
import org.eclipse.jface.viewers.Viewer;
9+
import org.eclipse.jface.viewers.ViewerFilter;
10+
11+
public class TreeViewerFilter extends ViewerFilter {
12+
private List<String> searchStrings;
13+
private boolean matchAll; // If true, all filters must match; if false, any filter can match
14+
15+
public TreeViewerFilter() {
16+
this.searchStrings = new ArrayList<>();
17+
this.matchAll = true; // Default to matching all filters
18+
}
19+
20+
public void addSearchText(String s) {
21+
if (s != null && !s.isEmpty()) {
22+
this.searchStrings.add(".*" + s.toLowerCase() + ".*");
23+
}
24+
}
25+
26+
public void clearSearchText() {
27+
this.searchStrings.clear();
28+
}
29+
30+
public void setMatchAll(boolean matchAll) {
31+
this.matchAll = matchAll;
32+
}
33+
34+
@Override
35+
public boolean select(Viewer viewer, Object parentElement, Object element) {
36+
if (searchStrings.isEmpty()) {
37+
return true;
38+
}
39+
40+
TreeViewer treeViewer = (TreeViewer) viewer;
41+
String label = ((ILabelProvider) treeViewer.getLabelProvider()).getText(element);
42+
43+
if (label == null) {
44+
return false;
45+
}
46+
47+
String labelLower = label.toLowerCase();
48+
49+
if (matchAll) {
50+
return searchStrings.stream().allMatch(s -> labelLower.matches(s));
51+
} else {
52+
return searchStrings.stream().anyMatch(s -> labelLower.matches(s));
53+
}
54+
}
55+
}

0 commit comments

Comments
 (0)