gomonop/cmd/matches/plugin.go
Emmanuel BENOîT c46c9d76d9
All checks were successful
Run tests and linters / test (push) Successful in 50s
Run tests and linters / build (push) Successful in 48s
Run tests and linters / lint (push) Successful in 1m27s
feat: add the check_output_matches plugin (#5)
This PR adds the `check_output_matches` plugin, which can be used to count regexp or substring matches from either text files or command outputs and determine the final status based on the amount of matches that were found.

Reviewed-on: #5
Co-authored-by: Emmanuel BENOÎT <tseeker@nocternity.net>
Co-committed-by: Emmanuel BENOÎT <tseeker@nocternity.net>
2024-07-20 22:57:10 +02:00

76 lines
2.3 KiB
Go

// The matches package contains the implementation of the `check_output_matches`
// plugin, which can be used to run an arbitrary command and check its output
// against various patterns. It can also be configured to do the same on an
// arbitrary file.
package matches // import nocternity.net/gomonop/cmd/matches
import (
"regexp"
"nocternity.net/gomonop/pkg/plugin"
"nocternity.net/gomonop/pkg/results"
"nocternity.net/gomonop/pkg/status"
)
// Program data for the string matches plugin.
type matchesPlugin struct {
pluginFlags // Flags from the command line
results *results.Results // Plugin output state
counters []int // Counters for each match
unmatchedLines int // Number of lines that didn't match anything
}
// Initialise the plugin.
func NewPlugin() plugin.Plugin {
pluginInst := &matchesPlugin{
results: results.New("String matches counter"),
}
pluginInst.parseArguments()
return pluginInst
}
// Return the program's output value.
func (pluginInst *matchesPlugin) Results() *results.Results {
return pluginInst.results
}
// Check the values that were specified from the command line. Returns true
// if the arguments made sense.
func (pluginInst *matchesPlugin) CheckArguments() bool {
if pluginInst.dataSource == "" {
pluginInst.results.SetState(status.StatusUnknown, "no data source specified")
return false
}
if !pluginInst.strict && len(pluginInst.matches) == 0 {
pluginInst.results.SetState(status.StatusUnknown, "would match anything")
return false
}
for index := range pluginInst.matches {
if pluginInst.matches[index].matchString == "" {
pluginInst.results.SetState(status.StatusUnknown, "empty match string")
pluginInst.results.AddLinef("(At match %d)", index+1)
return false
}
if pluginInst.matches[index].isRegexp {
rexp, err := regexp.Compile(pluginInst.matches[index].matchString)
if err != nil {
pluginInst.results.SetState(status.StatusUnknown, "Invalid regular expression")
pluginInst.results.AddLine(err.Error())
pluginInst.results.AddLinef("(At match %d)", index+1)
return false
}
pluginInst.matches[index].compiledRe = rexp
}
}
return true
}
// Run the check.
func (pluginInst *matchesPlugin) RunCheck() {
pluginInst.counters = make([]int, len(pluginInst.matches))
err := pluginInst.processData()
pluginInst.checkResults(err)
}