public void Start() { _logger.LogSeperateLine(); BuildResult initialRebuildResult = RebuildAtStart(); if (initialRebuildResult.IsSuccess == false) { _logger.Log("Failed to initial rebuild"); return; } if (StopMarker.StopRequested) { return; } _logger.Log("Build configuration: " + initialRebuildResult.GetBuildSolutionConfiguration()); _logger.LogSeperateLine(); List <string> sourceFilenames = CompileFileListExtractor.GetFilenames(initialRebuildResult.Outputs); sourceFilenames = Util.FilterOut(sourceFilenames, _config.FilenameFilters); if (sourceFilenames.Count <= 0) { _logger.Log("Cannot extract any file"); return; } _logger.Log("Collected source file count: " + sourceFilenames.Count); if (string.IsNullOrEmpty(_config.CheckingDirectory) == false) { List <string> filteredFilenames = new List <string>(); foreach (string filename in sourceFilenames) { if (filename.Contains(_config.CheckingDirectory)) { filteredFilenames.Add(filename); } } _logger.Log($"Collected source file count after CheckingDirectory({_config.CheckingDirectory}): {filteredFilenames.Count}"); sourceFilenames = filteredFilenames; } _logger.LogSeperateLine(); if (_config.RandomSequenceTest) { Util.Shuffle(sourceFilenames); } NeedlessIncludeLines needlessIncludeLines = TryRemoveIncludeAndCollectChanges(sourceFilenames); if (StopMarker.StopRequested) { return; } _logger.LogSeperateLine(); if (needlessIncludeLines.IncludeLineInfos.Count == 0) { _logger.Log("There is no needless include. Nice project!!!!!!!!!!!"); return; } needlessIncludeLines.Print(_logger); _logger.LogSeperateLine(); _logger.LogSeperateLine(); _logger.Log(" Start of final integrated build test"); _logger.LogSeperateLine(); _logger.LogSeperateLine(); needlessIncludeLines = FinalIntegrationTest(needlessIncludeLines); if (StopMarker.StopRequested) { return; } _logger.LogSeperateLine(); foreach (var info in needlessIncludeLines.IncludeLineInfos) { string filename = info.Filename; string includeLine = info.IncludeLine; if (string.IsNullOrEmpty(_config.ExecCmdPath) == false) { _logger.Log(string.Format("Executing {0}:{1}", filename, includeLine)); string argument = string.Format(@"""{0}"" ""{1}""", filename, includeLine); var runResult = CommandExecutor.Run(".", _config.ExecCmdPath, argument); _logger.Log("----------------------------------------------------", runResult.outputs, runResult.errors); } if (_config.ApplyChange) { _logger.Log(string.Format("Applying {0}:{1}", filename, includeLine)); using (FileModifier fileModifier = new FileModifier(filename, _config.ApplyChangeEncoding)) { fileModifier.RemoveAndWrite(includeLine); fileModifier.SetApplyPermanently(); } } } // Some changes can break the rebuild. So rebuild again BuildResult lastBuildResult = RebuildAtLast(); if (lastBuildResult.IsSuccess) { _logger.Log("Final rebuild is successful"); } else { _logger.Log("Final rebuild is failed!!!!!!!!!!!!!!!!!!!!!!!"); } }
private NeedlessIncludeLines FinalIntegrationTest(NeedlessIncludeLines needlessIncludeLines) { Dictionary <string, List <string> > filenameAndIncludes = new Dictionary <string, List <string> >(); foreach (var info in needlessIncludeLines.IncludeLineInfos) { if (filenameAndIncludes.ContainsKey(info.Filename) == false) { filenameAndIncludes.Add(info.Filename, new List <string>()); } filenameAndIncludes[info.Filename].Add(info.IncludeLine); } while (filenameAndIncludes.Count > 0) { if (StopMarker.StopRequested) { return(null); } _logger.LogSeperateLine(); _logger.Log("| Final integration test"); List <FileModifier> fileModifiers = new List <FileModifier>(); foreach (var filenameAndInclude in filenameAndIncludes) { string msg = string.Format("| + {0}:{1}", filenameAndInclude.Key, string.Join(',', filenameAndInclude.Value)); _logger.Log(msg); FileModifier fileModifier = new FileModifier(filenameAndInclude.Key, _config.ApplyChangeEncoding); fileModifier.RemoveAndWrite(filenameAndInclude.Value); fileModifiers.Add(fileModifier); } var buildResult = _builder.Build(); _logger.Log("| : Build Duration: " + buildResult.GetBuildDurationString()); foreach (var fileModifier in fileModifiers) { fileModifier.RevertAndWrite(); } if (buildResult.IsSuccess) { _logger.Log("| ----> Final Integration Test Build Success"); break; } else { _logger.Log("| ----> Final Integration Test Build Failed"); } SortedSet <string> buildErrorFilenames = BuildErrorFileListExtractor.Extract(buildResult.Outputs); foreach (var temp in filenameAndIncludes) { if (buildErrorFilenames.Count > 0 && filenameAndIncludes.ContainsKey(buildErrorFilenames.Min)) { string filename = buildErrorFilenames.Min; _logger.Log(string.Format("| ----> Remove {0} and retrying...", filename)); filenameAndIncludes.Remove(filename); break; } else { string filename = temp.Key; _logger.Log(string.Format("| ----> Remove {0} and retrying...", filename)); filenameAndIncludes.Remove(filename); break; } } } NeedlessIncludeLines output = new NeedlessIncludeLines(); if (filenameAndIncludes.Count <= 0) { return(output); } foreach (var result in filenameAndIncludes) { foreach (var line in result.Value) { output.Add(result.Key, line); } } return(output); }
private NeedlessIncludeLines TryRemoveIncludeAndCollectChanges(List <string> filenames) { NeedlessIncludeLines needlessIncludeLines = new NeedlessIncludeLines(); int checkedFileCount = 0; foreach (string filename in filenames) { if (checkedFileCount > _config.MaxCheckFileCount) { _logger.Log("Reached maxcheckfilecount,count: " + _config.MaxCheckFileCount); break; } ++checkedFileCount; string checkingMsg = string.Format("[{0}/{1}]", checkedFileCount, filenames.Count); if (_config.MaxCheckFileCount != null) { checkingMsg += string.Format("[max_limited {0}]", _config.MaxCheckFileCount); } _logger.Log(checkingMsg + string.Format(" Checking Filename: {0}", filename)); List <string> includeLines = null; using (FileModifier fileModifier = new FileModifier(filename, _config.ApplyChangeEncoding)) { includeLines = IncludeLineAnalyzer.Analyze(fileModifier.OriginalContent); } includeLines = Util.FilterOut(includeLines, _config.IncludeFilters); if (includeLines.Count <= 0) { _logger.Log(string.Format(" + {0} has no include line", filename)); continue; } SortedSet <string> oneLineNeedlessIncludeLiness = new SortedSet <string>(); // each line removing build test foreach (string includeLine in includeLines) { if (StopMarker.StopRequested) { return(needlessIncludeLines); } if (_config.IgnoreSelfHeaderInclude && Util.IsSelfHeader(filename, includeLine)) { _logger.Log(string.Format(" + skipping: {0} by IgnoreSelfHeader", includeLine)); continue; } _logger.LogWithoutEndline(string.Format(" + testing : {0} ...", includeLine)); using (var fileModifier = new FileModifier(filename, _config.ApplyChangeEncoding)) { fileModifier.RemoveAndWrite(includeLine); BuildResult testBuildResult = _builder.Build(); if (testBuildResult.IsSuccess) { _logger.LogWithoutLogTime(string.Format(" ({0} build time) ----> removing candidate", testBuildResult.GetBuildDurationString())); oneLineNeedlessIncludeLiness.Add(includeLine); } else { _logger.LogWithoutLogTime(string.Format(" ({0} build time) ----> not removing candidate", testBuildResult.GetBuildDurationString())); } } } // integrate build test because removing two line together cause build error while (oneLineNeedlessIncludeLiness.Count > 0) { if (StopMarker.StopRequested) { return(needlessIncludeLines); } using (FileModifier fileModifier = new FileModifier(filename, _config.ApplyChangeEncoding)) { List <string> integratedIncludeLines = new List <string>(); foreach (string includeLine in oneLineNeedlessIncludeLiness) { integratedIncludeLines.Add(includeLine); } fileModifier.RemoveAndWrite(integratedIncludeLines); _logger.LogWithoutEndline(string.Format(" + testing integrated : {0} ...", string.Join(',', integratedIncludeLines))); BuildResult integrateTestBuildResult = _builder.Build(); if (integrateTestBuildResult.IsSuccess) { _logger.LogWithoutLogTime(string.Format(" ({0} build time) ----> BUILD SUCCESS", integrateTestBuildResult.GetBuildDurationString())); break; } string removingIncludeLine = oneLineNeedlessIncludeLiness.Min; _logger.LogWithoutLogTime(string.Format(" ({0} build time) ----> build failed,revert {1} and retry", integrateTestBuildResult.GetBuildDurationString(), removingIncludeLine)); oneLineNeedlessIncludeLiness.Remove(removingIncludeLine); } } if (oneLineNeedlessIncludeLiness.Count <= 0) { continue; } _logger.LogSeperateLine(); _logger.Log(string.Format("| Checked Filename: {0}", filename)); foreach (string includeLine in oneLineNeedlessIncludeLiness) { _logger.Log("| + found needless include: " + includeLine); needlessIncludeLines.Add(filename, includeLine); } string foundCountMsg = "| ----> Found needless count: " + needlessIncludeLines.IncludeLineInfos.Count; if (_config.MaxSuccessRemoveCount != null) { foundCountMsg += string.Format("/{0}", _config.MaxSuccessRemoveCount); if (needlessIncludeLines.IncludeLineInfos.Count >= _config.MaxSuccessRemoveCount) { _logger.Log("Reached maxsuccessremovecount,count: " + _config.MaxSuccessRemoveCount); return(needlessIncludeLines); } } _logger.Log(foundCountMsg); _logger.LogSeperateLine(); } return(needlessIncludeLines); }