mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 21:05:37 +02:00
Bug 520163: Provide a way to exclude Scanner Errors from headless build
Implemented by allowing users to specify type of error markers to consider, as well as ability to print out the error markers that are causing build to fail. Change-Id: Iaa0b41be9ec1c1ff5268734697f361dac6fec49e Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
This commit is contained in:
parent
10ef1f11b0
commit
df31b110d0
3 changed files with 123 additions and 37 deletions
|
@ -21,13 +21,16 @@ public class HeadlessBuildMessages extends NLS {
|
|||
public static String HeadlessBuilder_cant_be_found;
|
||||
public static String HeadlessBuilder_clean_failed;
|
||||
public static String HeadlessBuilder_cleaning_all_projects;
|
||||
public static String HeadlessBuilder_completed_successfully;
|
||||
public static String HeadlessBuilder_CouldntLockWorkspace;
|
||||
public static String HeadlessBuilder_Directory;
|
||||
public static String HeadlessBuilder_encountered_errors;
|
||||
public static String HeadlessBuilder_EnvVar_Append;
|
||||
public static String HeadlessBuilder_EnvVar_Prepend;
|
||||
public static String HeadlessBuilder_EnvVar_Remove;
|
||||
public static String HeadlessBuilder_EnvVar_Replace;
|
||||
public static String HeadlessBuilder_Error;
|
||||
public static String HeadlessBuilder_help_requested;
|
||||
public static String HeadlessBuilder_importAll;
|
||||
public static String HeadlessBuilder_IncludeFile;
|
||||
public static String HeadlessBuilder_InlucdePath;
|
||||
|
@ -57,7 +60,9 @@ public class HeadlessBuildMessages extends NLS {
|
|||
public static String HeadlessBuilder_invalid_uri;
|
||||
public static String HeadlessBuilder_PreprocessorDefine;
|
||||
public static String HeadlessBuilder_usage_import;
|
||||
public static String HeadlessBuilder_usage_marker_type;
|
||||
public static String HeadlessBuilder_usage_no_indexer;
|
||||
public static String HeadlessBuilder_usage_print_all_error_markers;
|
||||
public static String HeadlessBuilder_Workspace;
|
||||
public static String HeadlessBuilder_WorkspaceInUse;
|
||||
static {
|
||||
|
|
|
@ -16,13 +16,16 @@ HeadlessBuilder_building_all=Building All Projects...
|
|||
HeadlessBuilder_cant_be_found=\ can't be found\!
|
||||
HeadlessBuilder_clean_failed=Couldn't CLEAN project
|
||||
HeadlessBuilder_cleaning_all_projects=Cleaning All Projects...
|
||||
HeadlessBuilder_completed_successfully=Headless build completed successfully
|
||||
HeadlessBuilder_CouldntLockWorkspace=Could not obtain lock for workspace location
|
||||
HeadlessBuilder_Directory=Directory:
|
||||
HeadlessBuilder_encountered_errors=Headless build encountered errors
|
||||
HeadlessBuilder_EnvVar_Append=\ \ \ -Ea {var=value} append value to environment variable when running all tools
|
||||
HeadlessBuilder_EnvVar_Prepend=\ \ \ -Ep {var=value} prepend value to environment variable when running all tools
|
||||
HeadlessBuilder_EnvVar_Remove=\ \ \ -Er {var} remove/unset the given environment variable
|
||||
HeadlessBuilder_EnvVar_Replace=\ \ \ -E {var=value} replace/add value to environment variable when running all tools
|
||||
HeadlessBuilder_Error=Error:
|
||||
HeadlessBuilder_help_requested=Help Requested
|
||||
HeadlessBuilder_invalid_argument=Invalid Arguments:
|
||||
HeadlessBuilder_is_not_accessible=\ is not accessible\!
|
||||
HeadlessBuilder_is_not_valid_in_workspace=\ is not valid in the workspace\!
|
||||
|
@ -41,7 +44,9 @@ HeadlessBuilder_usage=Usage:
|
|||
HeadlessBuilder_usage_build=\ \ \ -build {project_name_reg_ex{/config_reg_ex} | all}
|
||||
HeadlessBuilder_usage_clean_build=\ \ \ -cleanBuild {project_name_reg_ex{/config_reg_ex} | all}
|
||||
HeadlessBuilder_usage_import=\ \ \ -import {[uri:/]/path/to/project}
|
||||
HeadlessBuilder_usage_marker_type=\ \ \ -marker-type Marker types to fail build on {all | cdt | marker_id}
|
||||
HeadlessBuilder_usage_no_indexer=\ \ \ -no-indexer Disable indexer
|
||||
HeadlessBuilder_usage_print_all_error_markers=\ \ \ -printErrorMarkers Print all error markers
|
||||
HeadlessBuilder_importAll=\ \ \ -importAll {[uri:/]/path/to/projectTreeURI} Import all projects under URI
|
||||
HeadlessBuilder_IncludeFile=\ \ \ -include {include_file} additional include_file to pass to tools
|
||||
HeadlessBuilder_InlucdePath=\ \ \ -I {include_path} additional include_path to add to tools
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.dom.IPDOMManager;
|
||||
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
import org.eclipse.cdt.core.resources.ACBuilder;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||
|
@ -97,6 +98,12 @@ import org.eclipse.osgi.service.datalocation.Location;
|
|||
* - Prepend to a tool option value: -Tp {toolid} {optionid=value}
|
||||
* - Remove a tool option: -Tr {toolid} {optionid=value}
|
||||
* - Disable indexer: -no-indexer
|
||||
* - Error marker types to consider: -marker-type {all | cdt | marker_id}
|
||||
* where:
|
||||
* all is all markers -- default
|
||||
* cdt is C/C++ Problem markers
|
||||
* marker_id, e.g. org.eclipse.cdt.core.problem
|
||||
* - Display all error markers: -printErrorMarkers
|
||||
*
|
||||
* Build output is automatically sent to stdout.
|
||||
* @since 6.0
|
||||
|
@ -182,6 +189,10 @@ public class HeadlessBuilder implements IApplication {
|
|||
private List<ToolOption> toolOptions = new ArrayList<ToolOption>();
|
||||
/** Map from configuration ID -> Set of SavedToolOptions */
|
||||
private Map<String, Set<SavedToolOption>> savedToolOptions = new HashMap<String, Set<SavedToolOption>>();
|
||||
private boolean markerTypesDefault = true;
|
||||
private boolean markerTypesAll = false;
|
||||
private Set<String> markerTypes = new HashSet<>();
|
||||
private boolean printErrorMarkers = false;
|
||||
|
||||
private static final String MATCH_ALL_CONFIGS = ".*"; //$NON-NLS-1$
|
||||
|
||||
|
@ -387,19 +398,43 @@ public class HeadlessBuilder implements IApplication {
|
|||
}
|
||||
|
||||
private boolean isProjectSuccesfullyBuild(IProject project) {
|
||||
boolean result = false;
|
||||
try {
|
||||
result = project.findMaxProblemSeverity(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE) < IMarker.SEVERITY_ERROR;
|
||||
for (String markerType : markerTypes) {
|
||||
int findMaxProblemSeverity = project.findMaxProblemSeverity(markerType, true, IResource.DEPTH_INFINITE);
|
||||
if (findMaxProblemSeverity >= IMarker.SEVERITY_ERROR) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
ManagedBuilderCorePlugin.log(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void accumulateErrorMarkers(IProject project, List<String> allBuildErrors) {
|
||||
try {
|
||||
for (String markerType : markerTypes) {
|
||||
IMarker[] findMarkers = project.findMarkers(markerType, true, IResource.DEPTH_INFINITE);
|
||||
for (IMarker marker : findMarkers) {
|
||||
int severity = marker.getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
|
||||
if (severity >= IMarker.SEVERITY_ERROR) {
|
||||
// the string format of Markers is not API and recommended only for debugging, but
|
||||
// it suits our purpose here.
|
||||
allBuildErrors.add(marker.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
ManagedBuilderCorePlugin.log(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object start(IApplicationContext context) throws Exception {
|
||||
// Build result: whether projects were built successfully
|
||||
boolean buildSuccessful = true;
|
||||
List<String> allBuildErrors = new ArrayList<>();
|
||||
|
||||
// Check its OK to use this workspace as IDEApplication does
|
||||
if (!checkInstanceLocation())
|
||||
|
@ -426,6 +461,11 @@ public class HeadlessBuilder implements IApplication {
|
|||
if (!getArguments((String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS)))
|
||||
return ERROR;
|
||||
|
||||
if (markerTypesDefault || markerTypesAll) {
|
||||
markerTypes.clear();
|
||||
markerTypes.add(IMarker.PROBLEM);
|
||||
}
|
||||
|
||||
if (disableIndexer) {
|
||||
CCorePlugin.getIndexManager().setDefaultIndexerId(IPDOMManager.ID_NO_INDEXER);
|
||||
// yes, this is ugly - but I haven't found a way to "officially"
|
||||
|
@ -513,16 +553,24 @@ public class HeadlessBuilder implements IApplication {
|
|||
|
||||
System.out.println(HeadlessBuildMessages.HeadlessBuilder_building_all);
|
||||
root.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
|
||||
for(IProject p : root.getProjects())
|
||||
for(IProject p : root.getProjects()) {
|
||||
buildSuccessful = buildSuccessful && isProjectSuccesfullyBuild(p);
|
||||
if (printErrorMarkers) {
|
||||
accumulateErrorMarkers(p, allBuildErrors);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Resolve the regular expression project names to build configurations
|
||||
for (String regEx : projectRegExToBuild)
|
||||
matchConfigurations(regEx, allProjects, configsToBuild);
|
||||
// Build the list of configurations
|
||||
buildConfigurations(configsToBuild, monitor, IncrementalProjectBuilder.FULL_BUILD);
|
||||
for(IProject p : configsToBuild.keySet())
|
||||
for(IProject p : configsToBuild.keySet()) {
|
||||
buildSuccessful = buildSuccessful && isProjectSuccesfullyBuild(p);
|
||||
if (printErrorMarkers) {
|
||||
accumulateErrorMarkers(p, allBuildErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
// Reset the tool options
|
||||
|
@ -555,41 +603,48 @@ public class HeadlessBuilder implements IApplication {
|
|||
// Save modified workspace (bug 513763)
|
||||
root.getWorkspace().save(true, monitor);
|
||||
}
|
||||
|
||||
if (printErrorMarkers) {
|
||||
if (buildSuccessful) {
|
||||
System.out.println(HeadlessBuildMessages.HeadlessBuilder_completed_successfully);
|
||||
} else {
|
||||
System.out.println(HeadlessBuildMessages.HeadlessBuilder_encountered_errors);
|
||||
for (String buildError : allBuildErrors) {
|
||||
System.err.println(buildError);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buildSuccessful ? OK : ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that it's safe to use the specified workspace. i.e. that
|
||||
* we can write to it and that it's not already locked / in-use.
|
||||
*
|
||||
* Return true if a valid workspace path has been set and false otherwise.
|
||||
*
|
||||
* @return true if a valid instance location has been set and false
|
||||
* otherwise
|
||||
*/
|
||||
private boolean checkInstanceLocation() {
|
||||
// -data @none was specified but an ide requires workspace
|
||||
Location instanceLoc = Platform.getInstanceLocation();
|
||||
if (instanceLoc == null || !instanceLoc.isSet()) {
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_MustSpecifyWorkspace);
|
||||
return false;
|
||||
}
|
||||
|
||||
// -data "/valid/path", workspace already set
|
||||
try {
|
||||
// at this point its valid, so try to lock it to prevent concurrent use
|
||||
if (!instanceLoc.lock()) {
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_WorkspaceInUse);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_CouldntLockWorkspace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Verify that it's safe to use the specified workspace. i.e. that we can write to it and that it's not
|
||||
* already locked / in-use.
|
||||
*
|
||||
* Return true if a valid workspace path has been set and false otherwise.
|
||||
*
|
||||
* @return true if a valid instance location has been set and false otherwise
|
||||
*/
|
||||
private boolean checkInstanceLocation() {
|
||||
// -data @none was specified but an ide requires workspace
|
||||
Location instanceLoc = Platform.getInstanceLocation();
|
||||
if (instanceLoc == null || !instanceLoc.isSet()) {
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_MustSpecifyWorkspace);
|
||||
return false;
|
||||
}
|
||||
|
||||
// -data "/valid/path", workspace already set
|
||||
try {
|
||||
// at this point its valid, so try to lock it to prevent concurrent use
|
||||
if (!instanceLoc.lock()) {
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_WorkspaceInUse);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_CouldntLockWorkspace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to process expected arguments
|
||||
|
@ -611,6 +666,8 @@ public class HeadlessBuilder implements IApplication {
|
|||
* -Tp {toolid} {optionid=value} prepend to a tool option value
|
||||
* -Tr {toolid} {optionid=value} remove a tool option value
|
||||
* -no-indexer Disable indexer
|
||||
* -marker-types Which markers to consider
|
||||
* -printErrorMarkers Print all error markers that caused build to fail
|
||||
*
|
||||
* Each argument may be specified more than once
|
||||
* @param args String[] of arguments to parse
|
||||
|
@ -621,7 +678,9 @@ public class HeadlessBuilder implements IApplication {
|
|||
if (args == null || args.length == 0)
|
||||
throw new Exception(HeadlessBuildMessages.HeadlessBuilder_no_arguments);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if ("-import".equals(args[i])) { //$NON-NLS-1$
|
||||
if ("-help".equals(args[i])) { //$NON-NLS-1$
|
||||
throw new Exception(HeadlessBuildMessages.HeadlessBuilder_help_requested);
|
||||
} else if ("-import".equals(args[i])) { //$NON-NLS-1$
|
||||
projectsToImport.add(args[++i]);
|
||||
} else if ("-importAll".equals(args[i])) { //$NON-NLS-1$
|
||||
projectTreeToImport.add(args[++i]);
|
||||
|
@ -667,6 +726,10 @@ public class HeadlessBuilder implements IApplication {
|
|||
addToolOption(toolId, option, ToolOption.REMOVE);
|
||||
} else if ("-no-indexer".equals(args[i])) { //$NON-NLS-1$
|
||||
disableIndexer = true;
|
||||
} else if ("-marker-type".equals(args[i])) { //$NON-NLS-1$
|
||||
addMarkerType(args[++i]);
|
||||
} else if ("-printErrorMarkers".equals(args[i])) { //$NON-NLS-1$
|
||||
printErrorMarkers = true;
|
||||
} else {
|
||||
throw new Exception(HeadlessBuildMessages.HeadlessBuilder_unknown_argument + args[i]);
|
||||
}
|
||||
|
@ -681,6 +744,8 @@ public class HeadlessBuilder implements IApplication {
|
|||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_build);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_clean_build);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_no_indexer);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_marker_type);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_print_all_error_markers);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_InlucdePath);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_IncludeFile);
|
||||
System.err.println(HeadlessBuildMessages.HeadlessBuilder_PreprocessorDefine);
|
||||
|
@ -730,6 +795,17 @@ public class HeadlessBuilder implements IApplication {
|
|||
toolOptions.add(new ToolOption(toolId, optionId, value, operation));
|
||||
}
|
||||
|
||||
private void addMarkerType(String markerType) {
|
||||
markerTypesDefault = false;
|
||||
if ("all".equals(markerType)) { //$NON-NLS-1$
|
||||
markerTypesAll = true;
|
||||
} else if ("cdt".equals(markerType)) { //$NON-NLS-1$
|
||||
markerTypes.add(ICModelMarker.C_MODEL_PROBLEM_MARKER);
|
||||
} else {
|
||||
markerTypes.add(markerType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the tool options in a configuration, and saves the current values so that
|
||||
* they can be restored at the end of the build. These are reset after the build
|
||||
|
|
Loading…
Add table
Reference in a new issue