utils: share the include/exclude regexp flag handling (#2737)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-16 00:07:30 +02:00
committed by GitHub
parent 34738679a1
commit 81ce8ef79d
18 changed files with 422 additions and 224 deletions
+6
View File
@@ -189,6 +189,12 @@ func (c *Resolver) setDefault(v getFlagger) error {
}
if err := checkFlagValue(f, values); err != nil {
// Some flag values, like those of utils.RegexpFlag, name their flag
// in their errors, because kingpin doesn't for command line values.
if strings.HasPrefix(err.Error(), name+": ") {
return fmt.Errorf("line %d: %w", c.lines[name], err)
}
return fmt.Errorf("line %d: %s: %w", c.lines[name], name, err)
}
+67
View File
@@ -548,6 +548,73 @@ func TestParseEmptyValue(t *testing.T) {
}
}
// TestRegexpFlags verifies that every include and exclude flag of the
// collectors accepts a value from the configuration file, and that an invalid
// expression fails the parsing with an error that names the flag.
func TestRegexpFlags(t *testing.T) {
t.Parallel()
for _, name := range []string{
"collector.iis.app-exclude",
"collector.iis.app-include",
"collector.iis.site-exclude",
"collector.iis.site-include",
"collector.logical_disk.volume-exclude",
"collector.logical_disk.volume-include",
"collector.net.nic-exclude",
"collector.net.nic-include",
"collector.physical_disk.disk-exclude",
"collector.physical_disk.disk-include",
"collector.printer.exclude",
"collector.printer.include",
"collector.process.exclude",
"collector.process.include",
"collector.scheduled_task.exclude",
"collector.scheduled_task.include",
"collector.service.exclude",
"collector.service.include",
"collector.smtp.server-exclude",
"collector.smtp.server-include",
} {
t.Run(name, func(t *testing.T) {
t.Parallel()
app := kingpin.New("test", "test")
app.Flag("config.file", "config").String()
collector.NewWithFlags(app)
require.NotNil(t, app.GetFlag(name))
err := config.Parse(app, []string{"--" + name + "=("})
require.ErrorContains(t, err, name+": error parsing regexp: missing closing ): `^(?:()$`")
parts := strings.SplitN(name, ".", 3)
path := filepath.Join(t.TempDir(), "config.yaml")
data := fmt.Sprintf("%s:\n %s:\n %s: \"foo|bar\"\n", parts[0], parts[1], parts[2])
require.NoError(t, os.WriteFile(path, []byte(data), 0o600))
app = kingpin.New("test", "test")
app.Flag("config.file", "config").String()
collector.NewWithFlags(app)
require.NoError(t, config.Parse(app, []string{"--config.file=" + path}))
require.Equal(t, "foo|bar", app.GetFlag(name).Model().Value.String())
// An invalid expression in the configuration file names its key and line once.
data = fmt.Sprintf("%s:\n %s:\n %s: \"(\"\n", parts[0], parts[1], parts[2])
require.NoError(t, os.WriteFile(path, []byte(data), 0o600))
app = kingpin.New("test", "test")
app.Flag("config.file", "config").String()
collector.NewWithFlags(app)
err = config.Parse(app, []string{"--config.file=" + path})
require.ErrorContains(t, err, "line 3: "+name+": error parsing regexp: missing closing ): `^(?:()$`")
require.Equal(t, 1, strings.Count(err.Error(), name))
})
}
}
// TestParseFlagValues verifies that the configuration file takes the values the
// flags accept, whatever the Go type of the configuration, and that an invalid
// value fails with its key and line, even if the command line sets the flag.