]> ruderich.org/simon Gitweb - safcm/safcm.git/commitdiff
safcm: add -q (quiet) command line option
authorSimon Ruderich <simon@ruderich.org>
Mon, 5 Apr 2021 07:35:37 +0000 (09:35 +0200)
committerSimon Ruderich <simon@ruderich.org>
Mon, 5 Apr 2021 07:41:12 +0000 (09:41 +0200)
cmd/safcm/config/config.go
cmd/safcm/sync.go
cmd/safcm/sync_changes.go
cmd/safcm/sync_changes_test.go

index 6dae4a14c825d69f0414943ebe9b0079b64d60ed..bae137f3173ae402fc7da9260276fe7bca61d2ac 100644 (file)
@@ -28,6 +28,7 @@ import (
 
 type Config struct {
        DryRun   bool           `yaml:"-"` // set via command line
+       Quiet    bool           `yaml:"-"` // set via command line
        LogLevel safcm.LogLevel `yaml:"-"` // set via command line
 
        DetectGroups []string `yaml:"detect_groups"`
index 7f1e090593b6c42dd14f028de056dd24990c9812..e8f643154851a5fd91cd6b5647c9da84d73ddb4a 100644 (file)
@@ -71,6 +71,8 @@ func MainSync(args []string) error {
 
        optionDryRun := flag.Bool("n", false,
                "dry-run, show diff but don't perform any changes")
+       optionQuiet := flag.Bool("q", false,
+               "hide successful, non-trigger commands with no output from host changes listing")
        optionLog := flag.String("log", "info", "set log `level`; "+
                "levels: error, info, verbose, debug, debug2, debug3")
 
@@ -105,6 +107,7 @@ func MainSync(args []string) error {
                return err
        }
        cfg.DryRun = *optionDryRun
+       cfg.Quiet = *optionQuiet
        cfg.LogLevel = level
 
        toSync, err := hostsToSync(names, allHosts, allGroups)
index 14d73c271a4bb0d8434d5896bf17bd78a4552407..46349116a602d1fb7e389b7b089116aabbbbd418 100644 (file)
@@ -145,13 +145,41 @@ func (s *Sync) formatServiceChanges(changes []safcm.ServiceChange) string {
 func (s *Sync) formatCommandChanges(changes []safcm.CommandChange) string {
        const indent = "   > "
 
+       // Quiet hides all successful, non-trigger commands which produce no
+       // output. This is useful as many commands will be used to enforce a
+       // certain state (e.g. file not-present, `ainsl`, etc.) and are run on
+       // each sync. Displaying them provides not much useful information.
+       // Instead, quiet shows them only when they produce output (e.g.
+       // `ainsl`, `rm -v`) and thus modify the host's state.
+       var noOutput int
+       if s.config.Quiet && !s.config.DryRun {
+               for _, x := range changes {
+                       if x.Trigger == "" &&
+                               x.Error == "" &&
+                               x.Output == "" {
+                               noOutput++
+                       }
+               }
+       }
+
        var buf strings.Builder
-       fmt.Fprintf(&buf, "executed %d command(s):", len(changes))
+       fmt.Fprintf(&buf, "executed %d command(s)", len(changes))
+       if noOutput > 0 {
+               fmt.Fprintf(&buf, ", %d with no output", noOutput)
+       }
+       if noOutput != len(changes) {
+               fmt.Fprintf(&buf, ":")
+       }
        if s.config.DryRun {
                fmt.Fprintf(&buf, " (dry-run)")
        }
        fmt.Fprintf(&buf, "\n")
        for _, x := range changes {
+               if noOutput > 0 &&
+                       x.Trigger == "" && x.Error == "" && x.Output == "" {
+                       continue
+               }
+
                fmt.Fprintf(&buf, "%s", s.formatTarget(x.Command))
                if x.Trigger != "" {
                        fmt.Fprintf(&buf, ", trigger for %q", x.Trigger)
index 76a016834b87d8a09d68547bcea26720511b13a4..f48d441208e5f0bd8dc134b0e42b0a036abe5a00 100644 (file)
@@ -465,6 +465,7 @@ func TestFormatCommandChanges(t *testing.T) {
        tests := []struct {
                name    string
                dryRun  bool
+               quiet   bool
                changes []safcm.CommandChange
                exp     string
        }{
@@ -472,6 +473,7 @@ func TestFormatCommandChanges(t *testing.T) {
                {
                        "regular",
                        false,
+                       false,
                        []safcm.CommandChange{
                                {
                                        Command: "fake command",
@@ -514,6 +516,7 @@ func TestFormatCommandChanges(t *testing.T) {
                {
                        "dry-run",
                        true,
+                       false,
                        []safcm.CommandChange{
                                {
                                        Command: "fake command",
@@ -527,9 +530,116 @@ func TestFormatCommandChanges(t *testing.T) {
 `,
                },
 
+               {
+                       "quiet",
+                       false,
+                       true,
+                       []safcm.CommandChange{
+                               {
+                                       Command: "fake command",
+                                       Output:  "fake output",
+                               },
+                               {
+                                       Command: "fake command with no output",
+                               },
+                               {
+                                       Command: "fake command with newline",
+                                       Output:  "fake output\n",
+                               },
+                               {
+                                       Command: "fake command with more output",
+                                       Output:  "fake out\nfake put\nfake\n",
+                               },
+                               {
+                                       Command: "fake failed command",
+                                       Output:  "fake output",
+                                       Error:   "fake error",
+                               },
+                       },
+                       `executed 5 command(s), 1 with no output:
+"fake command":
+   > fake output
+   > \ No newline at end of file
+"fake command with newline":
+   > fake output
+"fake command with more output":
+   > fake out
+   > fake put
+   > fake
+"fake failed command", failed: "fake error":
+   > fake output
+   > \ No newline at end of file
+`,
+               },
+
+               {
+                       "quiet (only quiet commands)",
+                       false,
+                       true,
+                       []safcm.CommandChange{
+                               {
+                                       Command: "fake command with no output",
+                               },
+                               {
+                                       Command: "fake command with no output",
+                               },
+                       },
+                       `executed 2 command(s), 2 with no output
+`,
+               },
+
+               {
+                       "quiet (quiet with errors)",
+                       false,
+                       true,
+                       []safcm.CommandChange{
+                               {
+                                       Command: "fake command with no output but error",
+                                       Error:   "fake error",
+                               },
+                               {
+                                       Command: "fake command with no output",
+                               },
+                       },
+                       `executed 2 command(s), 1 with no output:
+"fake command with no output but error", failed: "fake error"
+`,
+               },
+
+               {
+                       "quiet & dry-run",
+                       true,
+                       true,
+                       []safcm.CommandChange{
+                               {
+                                       Command: "fake command",
+                               },
+                               {
+                                       Command: "fake command with no output",
+                               },
+                               {
+                                       Command: "fake command with newline",
+                               },
+                               {
+                                       Command: "fake command with more output",
+                               },
+                               {
+                                       Command: "fake failed command",
+                               },
+                       },
+                       `executed 5 command(s): (dry-run)
+"fake command"
+"fake command with no output"
+"fake command with newline"
+"fake command with more output"
+"fake failed command"
+`,
+               },
+
                {
                        "escaping",
                        false,
+                       false,
                        []safcm.CommandChange{
                                {
                                        Command: "\x00",
@@ -550,6 +660,7 @@ func TestFormatCommandChanges(t *testing.T) {
                s := &Sync{
                        config: &config.Config{
                                DryRun: tc.dryRun,
+                               Quiet:  tc.quiet,
                        },
                }