Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion cmd/go-covercheck/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ const (
TotalBlockThresholdFlagShort = "B"
TotalBlockThresholdFlagUsage = "total block threshold to enforce [0=disabled]"

FunctionThresholdFlag = "function-threshold"
FunctionThresholdFlagShort = "n"
FunctionThresholdFlagUsage = "global function threshold to enforce [0=disabled]"

TotalFunctionThresholdFlag = "total-function-threshold"
TotalFunctionThresholdFlagShort = "F"
TotalFunctionThresholdFlagUsage = "total function threshold to enforce [0=disabled]"

SortByFlag = "sort-by"
SortOrderFlag = "sort-order"

Expand Down Expand Up @@ -132,12 +140,14 @@ var (
)

SortByFlagUsage = fmt.Sprintf(
"sort-by [%s|%s|%s|%s|%s]",
"sort-by [%s|%s|%s|%s|%s|%s|%s]",
config.SortByFile,
config.SortByBlocks,
config.SortByStatements,
config.SortByFunctions,
config.SortByStatementPercent,
config.SortByBlockPercent,
config.SortByFunctionPercent,
)

SortOrderFlagUsage = fmt.Sprintf("sort order [%s|%s]",
Expand Down Expand Up @@ -431,12 +441,19 @@ func applyConfigOverrides(cfg *config.Config, cmd *cobra.Command, noConfigFile b
noConfigFile {
cfg.BlockThreshold = v
}
if v, _ := cmd.Flags().GetFloat64(FunctionThresholdFlag); cmd.Flags().Changed(FunctionThresholdFlag) ||
noConfigFile {
cfg.FunctionThreshold = v
}
if v, _ := cmd.Flags().GetFloat64(TotalStatementThresholdFlag); cmd.Flags().Changed(TotalStatementThresholdFlag) {
cfg.Total[config.StatementsSection] = v
}
if v, _ := cmd.Flags().GetFloat64(TotalBlockThresholdFlag); cmd.Flags().Changed(TotalBlockThresholdFlag) {
cfg.Total[config.BlocksSection] = v
}
if v, _ := cmd.Flags().GetFloat64(TotalFunctionThresholdFlag); cmd.Flags().Changed(TotalFunctionThresholdFlag) {
cfg.Total[config.FunctionsSection] = v
}
if v, _ := cmd.Flags().GetString(SortByFlag); cmd.Flags().Changed(SortByFlag) ||
noConfigFile {
cfg.SortBy = v
Expand Down Expand Up @@ -483,6 +500,10 @@ func applyConfigOverrides(cfg *config.Config, cmd *cobra.Command, noConfigFile b
cfg.Total[config.BlocksSection] == config.BlockThresholdDefault {
cfg.Total[config.BlocksSection] = v
}
if v, _ := cmd.Flags().GetFloat64(FunctionThresholdFlag); !cmd.Flags().Changed(TotalFunctionThresholdFlag) &&
cfg.Total[config.FunctionsSection] == config.FunctionThresholdDefault {
cfg.Total[config.FunctionsSection] = v
}
}

func getVersion() string {
Expand Down Expand Up @@ -552,6 +573,13 @@ func initFlags(cmd *cobra.Command) {
BlockThresholdFlagUsage,
)

cmd.Flags().Float64P(
FunctionThresholdFlag,
FunctionThresholdFlagShort,
config.FunctionThresholdDefault,
FunctionThresholdFlagUsage,
)

cmd.Flags().Float64P(
TotalStatementThresholdFlag,
TotalStatementThresholdFlagShort,
Expand All @@ -566,6 +594,13 @@ func initFlags(cmd *cobra.Command) {
TotalBlockThresholdFlagUsage,
)

cmd.Flags().Float64P(
TotalFunctionThresholdFlag,
TotalFunctionThresholdFlagShort,
0,
TotalFunctionThresholdFlagUsage,
)

cmd.Flags().String(
SortByFlag,
config.SortByDefault,
Expand Down
57 changes: 54 additions & 3 deletions pkg/compute/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ func collect(profiles []*cover.Profile, cfg *config.Config) (Results, bool) { //
ByTotal: Totals{
Statements: TotalStatements{},
Blocks: TotalBlocks{},
Functions: TotalFunctions{},
},
ByPackage: make([]ByPackage, 0),
}
Expand All @@ -39,8 +40,16 @@ func collect(profiles []*cover.Profile, cfg *config.Config) (Results, bool) { //
blocks++
}

// Calculate function coverage
functions, functionHits, err := GetFunctionCoverageForFile(p.FileName, p.Blocks)
if err != nil {
// If we can't get function coverage, default to 0
functions, functionHits = 0, 0
}

stmtPct := math.Percent(stmtHits, stmts)
blockPct := math.Percent(blockHits, blocks)
functionPct := math.Percent(functionHits, functions)

stmtThreshold := cfg.StatementThreshold
if t, ok := cfg.PerFile.Statements[p.FileName]; ok {
Expand All @@ -54,6 +63,12 @@ func collect(profiles []*cover.Profile, cfg *config.Config) (Results, bool) { //
}
failed = failed || blockPct < blockThreshold

functionThreshold := cfg.FunctionThreshold
if t, ok := cfg.PerFile.Functions[p.FileName]; ok {
functionThreshold = t
}
failed = failed || functionPct < functionThreshold

if failed {
hasFailure = true
}
Expand All @@ -63,22 +78,29 @@ func collect(profiles []*cover.Profile, cfg *config.Config) (Results, bool) { //
By: By{
Statements: fmt.Sprintf("%d/%d", stmtHits, stmts),
Blocks: fmt.Sprintf("%d/%d", blockHits, blocks),
Functions: fmt.Sprintf("%d/%d", functionHits, functions),
StatementPercentage: stmtPct,
StatementThreshold: stmtThreshold,
BlockPercentage: blockPct,
BlockThreshold: blockThreshold,
FunctionPercentage: functionPct,
FunctionThreshold: functionThreshold,
Failed: failed,
stmtHits: stmtHits,
blockHits: blockHits,
stmts: stmts,
blocks: blocks,
functions: functions,
functionHits: functionHits,
},
})

results.ByTotal.Statements.totalStatements += stmts
results.ByTotal.Statements.totalCoveredStatements += stmtHits
results.ByTotal.Blocks.totalBlocks += blocks
results.ByTotal.Blocks.totalCoveredBlocks += blockHits
results.ByTotal.Functions.totalFunctions += functions
results.ByTotal.Functions.totalCoveredFunctions += functionHits
}

sortFileResults(results.ByFile, cfg)
Expand All @@ -88,7 +110,8 @@ func collect(profiles []*cover.Profile, cfg *config.Config) (Results, bool) { //

return results, hasFailure || hasPackageFailure ||
results.ByTotal.Statements.Failed ||
results.ByTotal.Blocks.Failed
results.ByTotal.Blocks.Failed ||
results.ByTotal.Functions.Failed
}

func collectPackageResults(results *Results, cfg *config.Config) bool {
Expand All @@ -104,15 +127,19 @@ func collectPackageResults(results *Results, cfg *config.Config) bool {
p.blockHits += v.blockHits
p.blocks += v.blocks
p.stmts += v.stmts
p.functions += v.functions
p.functionHits += v.functionHits
working[path.Dir(v.File)] = p
}

hasFailed := false
for _, v := range working {
v.Statements = fmt.Sprintf("%d/%d", v.stmtHits, v.stmts)
v.Blocks = fmt.Sprintf("%d/%d", v.blockHits, v.blocks)
v.Functions = fmt.Sprintf("%d/%d", v.functionHits, v.functions)
v.StatementPercentage = math.Percent(v.stmtHits, v.stmts)
v.BlockPercentage = math.Percent(v.blockHits, v.blocks)
v.FunctionPercentage = math.Percent(v.functionHits, v.functions)

v.StatementThreshold = cfg.StatementThreshold
if t, ok := cfg.PerPackage.Statements[v.Package]; ok {
Expand All @@ -126,6 +153,12 @@ func collectPackageResults(results *Results, cfg *config.Config) bool {
}
v.Failed = v.Failed || v.BlockPercentage < v.BlockThreshold

v.FunctionThreshold = cfg.FunctionThreshold
if t, ok := cfg.PerPackage.Functions[v.Package]; ok {
v.FunctionThreshold = t
}
v.Failed = v.Failed || v.FunctionPercentage < v.FunctionThreshold

if v.Failed {
hasFailed = true
}
Expand All @@ -150,6 +183,14 @@ func setTotals(results *Results, cfg *config.Config) {
results.ByTotal.Blocks.Percentage = math.Percent(results.ByTotal.Blocks.totalCoveredBlocks,
results.ByTotal.Blocks.totalBlocks)
results.ByTotal.Blocks.Failed = results.ByTotal.Blocks.Percentage < results.ByTotal.Blocks.Threshold

results.ByTotal.Functions.Threshold = cfg.Total[config.FunctionsSection]
results.ByTotal.Functions.Coverage =
fmt.Sprintf("%d/%d", results.ByTotal.Functions.totalCoveredFunctions,
results.ByTotal.Functions.totalFunctions)
results.ByTotal.Functions.Percentage = math.Percent(results.ByTotal.Functions.totalCoveredFunctions,
results.ByTotal.Functions.totalFunctions)
results.ByTotal.Functions.Failed = results.ByTotal.Functions.Percentage < results.ByTotal.Functions.Threshold
}

func sortBy[T HasBy](results []T, cfg *config.Config) {
Expand All @@ -170,6 +211,11 @@ func sortBy[T HasBy](results []T, cfg *config.Config) {
return byI.BlockPercentage > byJ.BlockPercentage
}
return byI.BlockPercentage < byJ.BlockPercentage
case config.SortByFunctionPercent:
if sortByDesc {
return byI.FunctionPercentage > byJ.FunctionPercentage
}
return byI.FunctionPercentage < byJ.FunctionPercentage
case config.SortByStatements:
if sortByDesc {
return byI.stmtHits > byJ.stmtHits
Expand All @@ -180,6 +226,11 @@ func sortBy[T HasBy](results []T, cfg *config.Config) {
return byI.blockHits > byJ.blockHits
}
return byI.blockHits < byJ.blockHits
case config.SortByFunctions:
if sortByDesc {
return byI.functionHits > byJ.functionHits
}
return byI.functionHits < byJ.functionHits
default:
return false
}
Expand All @@ -188,7 +239,7 @@ func sortBy[T HasBy](results []T, cfg *config.Config) {

func sortFileResults(results []ByFile, cfg *config.Config) {
switch cfg.SortBy {
case config.SortByStatementPercent, config.SortByBlockPercent, config.SortByStatements, config.SortByBlocks:
case config.SortByStatementPercent, config.SortByBlockPercent, config.SortByFunctionPercent, config.SortByStatements, config.SortByBlocks, config.SortByFunctions:
sortBy(results, cfg)
return
default:
Expand All @@ -205,7 +256,7 @@ func sortFileResults(results []ByFile, cfg *config.Config) {

func sortPackageResults(results []ByPackage, cfg *config.Config) {
switch cfg.SortBy {
case config.SortByStatementPercent, config.SortByBlockPercent, config.SortByStatements, config.SortByBlocks:
case config.SortByStatementPercent, config.SortByBlockPercent, config.SortByFunctionPercent, config.SortByStatements, config.SortByBlocks, config.SortByFunctions:
sortBy(results, cfg)
return
default:
Expand Down
Loading