Skip to content

Commit fcd1016

Browse files
vodorokgamesh411
authored andcommitted
Add new CodeChecker resolution logic (#170)
* Add new CodeChecker resolution logic Refactored the logic, how CodeChecker is found and configured. There is now an internal representation of a CodeChecker. There are a locator service introduced to handle CodeChecker resolution. There are a new gui radio button group to select how CodeChecker should be found. There is a proper dynamic widget enablement function depending on the selected options, and more verbose messages for the preferences panel. * Add tests for resolution logic New Unit tests and extended Integration tests. The CodeChecker class, and the locator logic is tested for PATH and Pre built package resolution. This is the same for the Integration tests, so only these two are tested. The Custom built CodeChecker package with virtual env needs a virtual environment emulation, which is not implemented yet. * python virtual env stripping and fixing
1 parent a970b51 commit fcd1016

37 files changed

+1067
-618
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package org.codechecker.eclipse.plugin.codechecker;
2+
3+
import java.io.File;
4+
import java.nio.file.Path;
5+
import java.nio.file.Paths;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
10+
import org.codechecker.eclipse.plugin.config.CcConfigurationBase;
11+
import org.codechecker.eclipse.plugin.config.Config.ConfigTypes;
12+
import org.codechecker.eclipse.plugin.runtime.LogI;
13+
import org.codechecker.eclipse.plugin.runtime.SLogger;
14+
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;
15+
import org.eclipse.core.runtime.IProgressMonitor;
16+
import org.eclipse.jdt.annotation.NonNull;
17+
18+
import com.google.common.base.Optional;
19+
20+
/**
21+
* Internal representation of a CodeChecker package.
22+
*/
23+
public class CodeChecker implements ICodeChecker {
24+
25+
private static final String LOCATION_KEY = "location";
26+
private static final String RESULTS_KEY = "results";
27+
private static final String LOGFILE_KEY = "logFile";
28+
private static final String LOCATION_SUB = "${location}";
29+
private static final String RESULTS_SUB = "${results}";
30+
private static final String LOGFILE_SUB = "${logFile}";
31+
32+
private static final String RESULTS_FOLDER = RESULTS_KEY;
33+
34+
private Path location;
35+
private ShellExecutorHelper she;
36+
private Map<String, File> subMap;
37+
38+
/**
39+
*
40+
* @param path
41+
* Path to the binary itself.
42+
* @param she
43+
* The ShellExecutor to be used.
44+
*
45+
* @throws InvalidCodeCheckerException
46+
* Thrown when no CodeChecker found.
47+
*/
48+
public CodeChecker(Path path, ShellExecutorHelper she) throws InvalidCodeCheckerException {
49+
location = path;
50+
this.she = she;
51+
subMap = new HashMap<String, File>();
52+
subMap.put(LOCATION_KEY, path.toAbsolutePath().toFile());
53+
getVersion();
54+
}
55+
56+
@Override
57+
@NonNull
58+
public String getCheckers() {
59+
String cmd = LOCATION_SUB + " checkers";
60+
Optional<String> ccOutput = she.waitReturnOutput(cmd, subMap, false);
61+
return ccOutput.or("No Checkers found");
62+
}
63+
64+
@Override
65+
@NonNull
66+
public String getVersion() throws InvalidCodeCheckerException {
67+
String cmd = LOCATION_SUB + " version";
68+
Optional<String> ccOutput = she.waitReturnOutput(cmd, subMap, false);
69+
if (!ccOutput.isPresent() || ccOutput.get().isEmpty())
70+
throw new InvalidCodeCheckerException("Couldn't run CodeChecker version!");
71+
return ccOutput.get();
72+
}
73+
74+
@Override
75+
public Path getLocation() {
76+
return location;
77+
}
78+
79+
@Override
80+
public String analyze(Path logFile, boolean logToConsole, IProgressMonitor monitor, int taskCount,
81+
CcConfigurationBase config) {
82+
83+
subMap.put(RESULTS_KEY, logFile.getParent().toAbsolutePath().resolve(Paths.get(RESULTS_FOLDER)).toFile());
84+
subMap.put(LOGFILE_KEY, logFile.toAbsolutePath().toFile());
85+
String cmd = LOCATION_SUB + " analyze " + config.get(ConfigTypes.CHECKER_LIST) + " -j "
86+
+ config.get(ConfigTypes.ANAL_THREADS) + " -n javarunner" + " -o "
87+
+ RESULTS_SUB + " " + LOGFILE_SUB;
88+
89+
SLogger.log(LogI.INFO, "Running analyze Command: " + cmd);
90+
Optional<String> ccOutput = she.progressableWaitReturnOutput(cmd, subMap, logToConsole, monitor, taskCount);
91+
92+
return ccOutput.or("");
93+
}
94+
95+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.codechecker.eclipse.plugin.codechecker;
2+
3+
import java.nio.file.Path;
4+
5+
import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
6+
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;
7+
8+
/**
9+
* Implementation of the {@link ICodeCheckerFactory} interface.
10+
*/
11+
public class CodeCheckerFactory implements ICodeCheckerFactory {
12+
@Override
13+
public ICodeChecker createCodeChecker(Path pathToBin, ShellExecutorHelper she)
14+
throws InvalidCodeCheckerException {
15+
return new CodeChecker(pathToBin, she);
16+
}
17+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.codechecker.eclipse.plugin.codechecker;
2+
3+
import java.nio.file.Path;
4+
5+
import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
6+
import org.codechecker.eclipse.plugin.config.CcConfigurationBase;
7+
import org.eclipse.core.runtime.IProgressMonitor;
8+
import org.eclipse.jdt.annotation.NonNull;
9+
10+
/**
11+
* Interface representing a CodeChecker package.
12+
*/
13+
public interface ICodeChecker {
14+
/**
15+
* Returns the unformatted output of the CodeChecker checkers command.
16+
*
17+
* @return The checker list.
18+
*/
19+
@NonNull
20+
public String getCheckers();
21+
22+
/**
23+
* Returns the full and complete version string of the CodeChecker package. The
24+
* returned String will never be empty.
25+
*
26+
* @return The version String.
27+
* @throws InvalidCodeCheckerException
28+
* Thrown when no version string can be returned.
29+
*/
30+
@NonNull
31+
public String getVersion() throws InvalidCodeCheckerException;
32+
33+
/**
34+
* To get the location of the CodeChecker binary. The returned String will never
35+
* be empty.
36+
*
37+
* @return The path.
38+
*/
39+
public Path getLocation();
40+
41+
/**
42+
* Executes CodeChecker check command on the build log received in the logFile
43+
* parameter.
44+
*
45+
* @param logFile
46+
* A Path to the build log in the following format:
47+
* http://clang.llvm.org/docs/JSONCompilationDatabase.html .
48+
* @param logToConsole
49+
* Flag for indicating console logging.
50+
* @param monitor
51+
* ProgressMonitor for to be able to increment progress bar.
52+
* @param taskCount
53+
* How many analyze step to be taken.
54+
* @param config
55+
* The configuration being used.
56+
* @return CodeChecker The full analyze command output.
57+
*/
58+
public String analyze(Path logFile, boolean logToConsole, IProgressMonitor monitor, int taskCount,
59+
CcConfigurationBase config);
60+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.codechecker.eclipse.plugin.codechecker;
2+
3+
import java.nio.file.Path;
4+
5+
import org.codechecker.eclipse.plugin.codechecker.locator.InvalidCodeCheckerException;
6+
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;
7+
8+
/**
9+
* Interface for CodeChecker factory.
10+
*/
11+
public interface ICodeCheckerFactory {
12+
/**
13+
* Method for creating CodeChecker instances.
14+
*
15+
* @param pathToBin
16+
* Path to the CodeChecker binary. (Not to root!)
17+
* @param she
18+
* The shell executor helper that will be used.
19+
* @return A newly created {@link ICodeChecker} ICodeChecker instance.
20+
* @throws InvalidCodeCheckerException
21+
* Thrown when a new instance couldn't be created.
22+
*/
23+
public ICodeChecker createCodeChecker(Path pathToBin, ShellExecutorHelper she)
24+
throws InvalidCodeCheckerException;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.codechecker.eclipse.plugin.codechecker.locator;
2+
3+
/**
4+
* Class responsible to create {@link CodeCheckerLocatorService} instances.
5+
*/
6+
public class CodeCheckerLocatorFactory {
7+
/**
8+
* Returns a {@link CodeCheckerLocatorService} depending on a the input
9+
* parameter.
10+
*
11+
* @param t
12+
* Any of the {@link ResolutionMethodTypes} enum values.
13+
* @return A {@link CodeCheckerLocatorService} instance.
14+
*/
15+
public CodeCheckerLocatorService create(ResolutionMethodTypes t) {
16+
switch (t) {
17+
case PATH:
18+
return new EnvCodeCheckerLocatorService();
19+
case PRE:
20+
return new PreBuiltCodeCheckerLocatorService();
21+
default:
22+
return null;
23+
}
24+
}
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.codechecker.eclipse.plugin.codechecker.locator;
2+
3+
import java.nio.file.Path;
4+
5+
import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
6+
import org.codechecker.eclipse.plugin.codechecker.ICodeCheckerFactory;
7+
import org.codechecker.eclipse.plugin.runtime.IShellExecutorHelperFactory;
8+
9+
/**
10+
* Implementations of this interface should return the location of the
11+
* CodeChecker package.
12+
*/
13+
public abstract class CodeCheckerLocatorService {
14+
/**
15+
* @param pathToBin
16+
* Path to CodeChecker package root.
17+
* @param ccfactory
18+
* An {@link ICodeCheckerFactory} that will create the CodeChecker.
19+
* @param sheFactory
20+
* A {@link IShellExecutorHelperFactory} to be used.
21+
* @return A CodeChecker Instance.
22+
* @throws InvalidCodeCheckerException
23+
* Thrown when the {@link ICodeChecker} instantiation fails.
24+
*/
25+
public abstract ICodeChecker findCodeChecker(Path pathToBin, ICodeCheckerFactory ccfactory, IShellExecutorHelperFactory sheFactory)
26+
throws InvalidCodeCheckerException;
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.codechecker.eclipse.plugin.codechecker.locator;
2+
3+
import java.nio.file.Path;
4+
import java.nio.file.Paths;
5+
6+
import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
7+
import org.codechecker.eclipse.plugin.codechecker.ICodeCheckerFactory;
8+
import org.codechecker.eclipse.plugin.runtime.IShellExecutorHelperFactory;
9+
import org.codechecker.eclipse.plugin.runtime.ShellExecutorHelper;
10+
11+
/**
12+
* Provides a CodeChecker instance tied to a CodeChecker package resulting of
13+
* "which CodeChecker".
14+
*/
15+
public class EnvCodeCheckerLocatorService extends CodeCheckerLocatorService {
16+
public static final String CC_NOT_FOUND = "CodeChecker wasn't found in PATH environment variable!";
17+
18+
@Override
19+
public ICodeChecker findCodeChecker(Path path, ICodeCheckerFactory ccFactory,
20+
IShellExecutorHelperFactory sheFactory) throws InvalidCodeCheckerException {
21+
22+
ShellExecutorHelper she = sheFactory.createShellExecutorHelper(System.getenv());
23+
String location = she.quickReturnFirstLine("which CodeChecker", null).or("");
24+
try {
25+
return ccFactory.createCodeChecker(Paths.get(location), she);
26+
} catch (InvalidCodeCheckerException e) {
27+
throw new InvalidCodeCheckerException(CC_NOT_FOUND);
28+
}
29+
}
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.codechecker.eclipse.plugin.codechecker.locator;
2+
3+
/**
4+
* Custom exception indicating a failed CodeChecker instance creation.
5+
*/
6+
@SuppressWarnings("serial")
7+
public class InvalidCodeCheckerException extends Exception {
8+
/**
9+
* Ctor.
10+
*
11+
* @param errorMessage
12+
* Error message.
13+
*/
14+
public InvalidCodeCheckerException(String errorMessage) {
15+
super(errorMessage);
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.codechecker.eclipse.plugin.codechecker.locator;
2+
3+
import java.nio.file.Path;
4+
5+
import org.codechecker.eclipse.plugin.codechecker.ICodeChecker;
6+
import org.codechecker.eclipse.plugin.codechecker.ICodeCheckerFactory;
7+
import org.codechecker.eclipse.plugin.runtime.IShellExecutorHelperFactory;
8+
9+
/**
10+
* Provides a CodeChecker instance which is tied to a pre-built CodeChecker
11+
* package.
12+
*/
13+
public class PreBuiltCodeCheckerLocatorService extends CodeCheckerLocatorService {
14+
public static final String CC_INVALID = "The path to the CodeChecker binary is not valid";
15+
public static final String CC_NOT_FOUND = "Couldn't find CodeChecker at the given destination!";
16+
17+
@Override
18+
public ICodeChecker findCodeChecker(Path pathToBin, ICodeCheckerFactory ccfactory,
19+
IShellExecutorHelperFactory sheFactory) throws InvalidCodeCheckerException {
20+
if (pathToBin == null)
21+
throw new IllegalArgumentException(CC_INVALID);
22+
try {
23+
return ccfactory.createCodeChecker(pathToBin, sheFactory.createShellExecutorHelper(System.getenv()));
24+
} catch (InvalidCodeCheckerException e) {
25+
throw new InvalidCodeCheckerException(CC_NOT_FOUND);
26+
}
27+
}
28+
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.codechecker.eclipse.plugin.codechecker.locator;
2+
3+
/**
4+
* This enum represents the available types of CodeChecker resolution methods.
5+
*/
6+
public enum ResolutionMethodTypes {
7+
PATH, PRE;
8+
}

0 commit comments

Comments
 (0)