1
0
Fork 0
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:
Jonah Graham 2017-07-27 13:06:36 +01:00
parent 10ef1f11b0
commit df31b110d0
3 changed files with 123 additions and 37 deletions

View file

@ -21,13 +21,16 @@ public class HeadlessBuildMessages extends NLS {
public static String HeadlessBuilder_cant_be_found; public static String HeadlessBuilder_cant_be_found;
public static String HeadlessBuilder_clean_failed; public static String HeadlessBuilder_clean_failed;
public static String HeadlessBuilder_cleaning_all_projects; public static String HeadlessBuilder_cleaning_all_projects;
public static String HeadlessBuilder_completed_successfully;
public static String HeadlessBuilder_CouldntLockWorkspace; public static String HeadlessBuilder_CouldntLockWorkspace;
public static String HeadlessBuilder_Directory; public static String HeadlessBuilder_Directory;
public static String HeadlessBuilder_encountered_errors;
public static String HeadlessBuilder_EnvVar_Append; public static String HeadlessBuilder_EnvVar_Append;
public static String HeadlessBuilder_EnvVar_Prepend; public static String HeadlessBuilder_EnvVar_Prepend;
public static String HeadlessBuilder_EnvVar_Remove; public static String HeadlessBuilder_EnvVar_Remove;
public static String HeadlessBuilder_EnvVar_Replace; public static String HeadlessBuilder_EnvVar_Replace;
public static String HeadlessBuilder_Error; public static String HeadlessBuilder_Error;
public static String HeadlessBuilder_help_requested;
public static String HeadlessBuilder_importAll; public static String HeadlessBuilder_importAll;
public static String HeadlessBuilder_IncludeFile; public static String HeadlessBuilder_IncludeFile;
public static String HeadlessBuilder_InlucdePath; public static String HeadlessBuilder_InlucdePath;
@ -57,7 +60,9 @@ public class HeadlessBuildMessages extends NLS {
public static String HeadlessBuilder_invalid_uri; public static String HeadlessBuilder_invalid_uri;
public static String HeadlessBuilder_PreprocessorDefine; public static String HeadlessBuilder_PreprocessorDefine;
public static String HeadlessBuilder_usage_import; 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_no_indexer;
public static String HeadlessBuilder_usage_print_all_error_markers;
public static String HeadlessBuilder_Workspace; public static String HeadlessBuilder_Workspace;
public static String HeadlessBuilder_WorkspaceInUse; public static String HeadlessBuilder_WorkspaceInUse;
static { static {

View file

@ -16,13 +16,16 @@ HeadlessBuilder_building_all=Building All Projects...
HeadlessBuilder_cant_be_found=\ can't be found\! HeadlessBuilder_cant_be_found=\ can't be found\!
HeadlessBuilder_clean_failed=Couldn't CLEAN project HeadlessBuilder_clean_failed=Couldn't CLEAN project
HeadlessBuilder_cleaning_all_projects=Cleaning All Projects... HeadlessBuilder_cleaning_all_projects=Cleaning All Projects...
HeadlessBuilder_completed_successfully=Headless build completed successfully
HeadlessBuilder_CouldntLockWorkspace=Could not obtain lock for workspace location HeadlessBuilder_CouldntLockWorkspace=Could not obtain lock for workspace location
HeadlessBuilder_Directory=Directory: 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_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_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_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_EnvVar_Replace=\ \ \ -E {var=value} replace/add value to environment variable when running all tools
HeadlessBuilder_Error=Error: HeadlessBuilder_Error=Error:
HeadlessBuilder_help_requested=Help Requested
HeadlessBuilder_invalid_argument=Invalid Arguments: HeadlessBuilder_invalid_argument=Invalid Arguments:
HeadlessBuilder_is_not_accessible=\ is not accessible\! HeadlessBuilder_is_not_accessible=\ is not accessible\!
HeadlessBuilder_is_not_valid_in_workspace=\ is not valid in the workspace\! 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_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_clean_build=\ \ \ -cleanBuild {project_name_reg_ex{/config_reg_ex} | all}
HeadlessBuilder_usage_import=\ \ \ -import {[uri:/]/path/to/project} 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_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_importAll=\ \ \ -importAll {[uri:/]/path/to/projectTreeURI} Import all projects under URI
HeadlessBuilder_IncludeFile=\ \ \ -include {include_file} additional include_file to pass to tools HeadlessBuilder_IncludeFile=\ \ \ -include {include_file} additional include_file to pass to tools
HeadlessBuilder_InlucdePath=\ \ \ -I {include_path} additional include_path to add to tools HeadlessBuilder_InlucdePath=\ \ \ -I {include_path} additional include_path to add to tools

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable; import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.model.CoreModel; 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.resources.ACBuilder;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription; 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} * - Prepend to a tool option value: -Tp {toolid} {optionid=value}
* - Remove a tool option: -Tr {toolid} {optionid=value} * - Remove a tool option: -Tr {toolid} {optionid=value}
* - Disable indexer: -no-indexer * - 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. * Build output is automatically sent to stdout.
* @since 6.0 * @since 6.0
@ -182,6 +189,10 @@ public class HeadlessBuilder implements IApplication {
private List<ToolOption> toolOptions = new ArrayList<ToolOption>(); private List<ToolOption> toolOptions = new ArrayList<ToolOption>();
/** Map from configuration ID -> Set of SavedToolOptions */ /** Map from configuration ID -> Set of SavedToolOptions */
private Map<String, Set<SavedToolOption>> savedToolOptions = new HashMap<String, Set<SavedToolOption>>(); 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$ private static final String MATCH_ALL_CONFIGS = ".*"; //$NON-NLS-1$
@ -387,19 +398,43 @@ public class HeadlessBuilder implements IApplication {
} }
private boolean isProjectSuccesfullyBuild(IProject project) { private boolean isProjectSuccesfullyBuild(IProject project) {
boolean result = false;
try { 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) { } catch (CoreException e) {
ManagedBuilderCorePlugin.log(e); ManagedBuilderCorePlugin.log(e);
} }
return result;
} }
@Override @Override
public Object start(IApplicationContext context) throws Exception { public Object start(IApplicationContext context) throws Exception {
// Build result: whether projects were built successfully // Build result: whether projects were built successfully
boolean buildSuccessful = true; boolean buildSuccessful = true;
List<String> allBuildErrors = new ArrayList<>();
// Check its OK to use this workspace as IDEApplication does // Check its OK to use this workspace as IDEApplication does
if (!checkInstanceLocation()) if (!checkInstanceLocation())
@ -426,6 +461,11 @@ public class HeadlessBuilder implements IApplication {
if (!getArguments((String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS))) if (!getArguments((String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS)))
return ERROR; return ERROR;
if (markerTypesDefault || markerTypesAll) {
markerTypes.clear();
markerTypes.add(IMarker.PROBLEM);
}
if (disableIndexer) { if (disableIndexer) {
CCorePlugin.getIndexManager().setDefaultIndexerId(IPDOMManager.ID_NO_INDEXER); CCorePlugin.getIndexManager().setDefaultIndexerId(IPDOMManager.ID_NO_INDEXER);
// yes, this is ugly - but I haven't found a way to "officially" // 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); System.out.println(HeadlessBuildMessages.HeadlessBuilder_building_all);
root.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor); root.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
for(IProject p : root.getProjects()) for(IProject p : root.getProjects()) {
buildSuccessful = buildSuccessful && isProjectSuccesfullyBuild(p); buildSuccessful = buildSuccessful && isProjectSuccesfullyBuild(p);
if (printErrorMarkers) {
accumulateErrorMarkers(p, allBuildErrors);
}
}
} else { } else {
// Resolve the regular expression project names to build configurations // Resolve the regular expression project names to build configurations
for (String regEx : projectRegExToBuild) for (String regEx : projectRegExToBuild)
matchConfigurations(regEx, allProjects, configsToBuild); matchConfigurations(regEx, allProjects, configsToBuild);
// Build the list of configurations // Build the list of configurations
buildConfigurations(configsToBuild, monitor, IncrementalProjectBuilder.FULL_BUILD); buildConfigurations(configsToBuild, monitor, IncrementalProjectBuilder.FULL_BUILD);
for(IProject p : configsToBuild.keySet()) for(IProject p : configsToBuild.keySet()) {
buildSuccessful = buildSuccessful && isProjectSuccesfullyBuild(p); buildSuccessful = buildSuccessful && isProjectSuccesfullyBuild(p);
if (printErrorMarkers) {
accumulateErrorMarkers(p, allBuildErrors);
}
}
} }
} finally { } finally {
// Reset the tool options // Reset the tool options
@ -555,41 +603,48 @@ public class HeadlessBuilder implements IApplication {
// Save modified workspace (bug 513763) // Save modified workspace (bug 513763)
root.getWorkspace().save(true, monitor); 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; return buildSuccessful ? OK : ERROR;
} }
/** /**
* Verify that it's safe to use the specified workspace. i.e. that * Verify that it's safe to use the specified workspace. i.e. that we can write to it and that it's not
* we can write to it and that it's not already locked / in-use. * already locked / in-use.
* *
* Return true if a valid workspace path has been set and false otherwise. * 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 * @return true if a valid instance location has been set and false otherwise
* otherwise */
*/ private boolean checkInstanceLocation() {
private boolean checkInstanceLocation() { // -data @none was specified but an ide requires workspace
// -data @none was specified but an ide requires workspace Location instanceLoc = Platform.getInstanceLocation();
Location instanceLoc = Platform.getInstanceLocation(); if (instanceLoc == null || !instanceLoc.isSet()) {
if (instanceLoc == null || !instanceLoc.isSet()) { System.err.println(HeadlessBuildMessages.HeadlessBuilder_MustSpecifyWorkspace);
System.err.println(HeadlessBuildMessages.HeadlessBuilder_MustSpecifyWorkspace); return false;
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;
}
// -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 * 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 * -Tp {toolid} {optionid=value} prepend to a tool option value
* -Tr {toolid} {optionid=value} remove a tool option value * -Tr {toolid} {optionid=value} remove a tool option value
* -no-indexer Disable indexer * -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 * Each argument may be specified more than once
* @param args String[] of arguments to parse * @param args String[] of arguments to parse
@ -621,7 +678,9 @@ public class HeadlessBuilder implements IApplication {
if (args == null || args.length == 0) if (args == null || args.length == 0)
throw new Exception(HeadlessBuildMessages.HeadlessBuilder_no_arguments); throw new Exception(HeadlessBuildMessages.HeadlessBuilder_no_arguments);
for (int i = 0; i < args.length; i++) { 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]); projectsToImport.add(args[++i]);
} else if ("-importAll".equals(args[i])) { //$NON-NLS-1$ } else if ("-importAll".equals(args[i])) { //$NON-NLS-1$
projectTreeToImport.add(args[++i]); projectTreeToImport.add(args[++i]);
@ -667,6 +726,10 @@ public class HeadlessBuilder implements IApplication {
addToolOption(toolId, option, ToolOption.REMOVE); addToolOption(toolId, option, ToolOption.REMOVE);
} else if ("-no-indexer".equals(args[i])) { //$NON-NLS-1$ } else if ("-no-indexer".equals(args[i])) { //$NON-NLS-1$
disableIndexer = true; 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 { } else {
throw new Exception(HeadlessBuildMessages.HeadlessBuilder_unknown_argument + args[i]); 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_build);
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_clean_build); System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_clean_build);
System.err.println(HeadlessBuildMessages.HeadlessBuilder_usage_no_indexer); 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_InlucdePath);
System.err.println(HeadlessBuildMessages.HeadlessBuilder_IncludeFile); System.err.println(HeadlessBuildMessages.HeadlessBuilder_IncludeFile);
System.err.println(HeadlessBuildMessages.HeadlessBuilder_PreprocessorDefine); System.err.println(HeadlessBuildMessages.HeadlessBuilder_PreprocessorDefine);
@ -730,6 +795,17 @@ public class HeadlessBuilder implements IApplication {
toolOptions.add(new ToolOption(toolId, optionId, value, operation)); 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 * 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 * they can be restored at the end of the build. These are reset after the build