From df31b110d0e9b11379d15571fab6748f4a228957 Mon Sep 17 00:00:00 2001 From: Jonah Graham Date: Thu, 27 Jul 2017 13:06:36 +0100 Subject: 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 --- .../internal/core/HeadlessBuildMessages.java | 5 + .../internal/core/HeadlessBuildMessages.properties | 5 + .../internal/core/HeadlessBuilder.java | 150 ++++++++++++++++----- 3 files changed, 123 insertions(+), 37 deletions(-) (limited to 'build') diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.java index 0797a92904b..0563d84d3d9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.java @@ -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 { diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.properties b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.properties index 8abccfdd911..311eec70e1d 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuildMessages.properties @@ -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 diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuilder.java index 991cdde5244..5af700a4178 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/HeadlessBuilder.java @@ -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 toolOptions = new ArrayList(); /** Map from configuration ID -> Set of SavedToolOptions */ private Map> savedToolOptions = new HashMap>(); + private boolean markerTypesDefault = true; + private boolean markerTypesAll = false; + private Set 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 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 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 -- cgit v1.2.3