diff --git a/llvm/docs/CommandGuide/llvm-cov.rst b/llvm/docs/CommandGuide/llvm-cov.rst --- a/llvm/docs/CommandGuide/llvm-cov.rst +++ b/llvm/docs/CommandGuide/llvm-cov.rst @@ -349,6 +349,13 @@ to generate the coverage data on one machine, and then use llvm-cov on a different machine where you have the same files on a different path. +.. option:: -coverage-watermark=, + + Set high and low watermarks for coverage in html format output. This allows you + to set the high and low watermark of coverage as desired, green when + coverage >= high, red when coverage < low, and yellow otherwise. Both high and + low should be between 0-100 and high > low. + .. program:: llvm-cov report .. _llvm-cov-report: diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -973,6 +973,11 @@ "project-title", cl::Optional, cl::desc("Set project title for the coverage report")); + cl::opt CovWatermark( + "coverage-watermark", cl::Optional, + cl::desc(", value indicate thresholds for high and low" + "coverage watermark")); + auto Err = commandLineParser(argc, argv); if (Err) return Err; @@ -982,6 +987,47 @@ return 1; } + ViewOpts.HighCovWatermark = 100.0; + ViewOpts.LowCovWatermark = 80.0; + if (!CovWatermark.empty()) { + auto WaterMarkPair = StringRef(CovWatermark).split(','); + if (WaterMarkPair.first.empty() || WaterMarkPair.second.empty()) { + error("invalid argument '" + CovWatermark + + "', must be in format 'high,low'", + "-coverage-watermark"); + return 1; + } + + char *EndPointer = nullptr; + ViewOpts.HighCovWatermark = + strtod(WaterMarkPair.first.begin(), &EndPointer); + if (EndPointer != WaterMarkPair.first.end()) { + error("invalid number '" + WaterMarkPair.first + + "', invalid value for 'high'", + "-coverage-watermark"); + return 1; + } + + ViewOpts.LowCovWatermark = + strtod(WaterMarkPair.second.begin(), &EndPointer); + if (EndPointer != WaterMarkPair.second.end()) { + error("invalid number '" + WaterMarkPair.second + + "', invalid value for 'low'", + "-coverage-watermark"); + return 1; + } + + if (ViewOpts.HighCovWatermark > 100 || ViewOpts.LowCovWatermark < 0 || + ViewOpts.HighCovWatermark <= ViewOpts.LowCovWatermark) { + error( + "invalid number range '" + CovWatermark + + "', must be both high and low should be between 0-100, and high " + "> low", + "-coverage-watermark"); + return 1; + } + } + ViewOpts.ShowLineNumbers = true; ViewOpts.ShowLineStats = ShowLineExecutionCounts.getNumOccurrences() != 0 || !ShowRegions || ShowBestLineRegionsCounts; diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h --- a/llvm/tools/llvm-cov/CoverageViewOptions.h +++ b/llvm/tools/llvm-cov/CoverageViewOptions.h @@ -50,6 +50,8 @@ std::string CreatedTimeStr; unsigned NumThreads; std::string CompilationDirectory; + float HighCovWatermark; + float LowCovWatermark; /// Change the output's stream color if the colors are enabled. ColoredRawOstream colored_ostream(raw_ostream &OS, diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -338,24 +338,24 @@ SmallVector Columns; // Format a coverage triple and add the result to the list of columns. - auto AddCoverageTripleToColumn = [&Columns](unsigned Hit, unsigned Total, - float Pctg) { - std::string S; - { - raw_string_ostream RSO{S}; - if (Total) - RSO << format("%*.2f", 7, Pctg) << "% "; - else - RSO << "- "; - RSO << '(' << Hit << '/' << Total << ')'; - } - const char *CellClass = "column-entry-yellow"; - if (Hit == Total) - CellClass = "column-entry-green"; - else if (Pctg < 80.0) - CellClass = "column-entry-red"; - Columns.emplace_back(tag("td", tag("pre", S), CellClass)); - }; + auto AddCoverageTripleToColumn = + [&Columns, this](unsigned Hit, unsigned Total, float Pctg) { + std::string S; + { + raw_string_ostream RSO{S}; + if (Total) + RSO << format("%*.2f", 7, Pctg) << "% "; + else + RSO << "- "; + RSO << '(' << Hit << '/' << Total << ')'; + } + const char *CellClass = "column-entry-yellow"; + if (Pctg >= Opts.HighCovWatermark) + CellClass = "column-entry-green"; + else if (Pctg < Opts.LowCovWatermark) + CellClass = "column-entry-red"; + Columns.emplace_back(tag("td", tag("pre", S), CellClass)); + }; // Simplify the display file path, and wrap it in a link if requested. std::string Filename;