Repository: regclient/regclient
Pull request #673 (2024-02-24 16:12:35)

Support formatted output on regctl registry config
<!--

Commits must be signed indicating your agreement to the [DCO](https://developercertificate.org/).
See [DCO missing](https://github.com/src-d/guide/blob/master/developer-community/fix-DCO.md) for steps to fix a missing signoff.

-->

### Fixes issue

<!-- If this is a bug fix, include "fixes #xxxx", or "closes #xxxx" -->

### Describe the change

This adds the ability to format output from the `regctl registry config` command.
<!-- Include the type of change: bug fix, new feature, breaking change, documentation update -->
<!-- Describe what was changed, why the change was made, and how it was implemented -->

### How to verify it

```shell
regctl registry config docker.io --format '{{.User}}'
```
<!-- Include steps that can be taken to verify the change -->

### Changelog text

- Feature: Support formatting output on `regctl registry config`.
<!-- If the release changelog should have an entry for this, include it here -->

### Please verify and check that the pull request fulfills the following requirements

<!-- Mark the following with an [X] to verify they are included -->

- [X] Tests have been added or not applicable
- [X] Documentation has been added, updated, or not applicable
- [X] Changes have been rebased to main
- [X] Multiple commits to the same code have been squashed

<!-- markdownlint-disable-file MD041 -->



Patch:
diff --git a/cmd/regctl/registry.go b/cmd/regctl/registry.go
index 4168bdf..a1fad23 100644
--- a/cmd/regctl/registry.go
+++ b/cmd/regctl/registry.go
@@ -2,7 +2,6 @@ package main
 
 import (
 	"bufio"
-	"encoding/json"
 	"fmt"
 	"io"
 	"os"
@@ -16,11 +15,13 @@ import (
 
 	"github.com/regclient/regclient"
 	"github.com/regclient/regclient/config"
+	"github.com/regclient/regclient/pkg/template"
 	"github.com/regclient/regclient/types/ref"
 )
 
 type registryCmd struct {
 	rootOpts             *rootCmd
+	formatConf           string
 	user, pass           string // login opts
 	passStdin            bool
 	credHelper           string
@@ -61,7 +62,10 @@ regctl registry config
 regctl registry config registry.example.org
 
 # show the configuration for Docker Hub
-regctl registry config docker.io`,
+regctl registry config docker.io
+
+# show the username used to login to docker hub
+regctl registry config docker.io --format '{{.User}}'`,
 		Args:              cobra.RangeArgs(0, 1),
 		ValidArgsFunction: registryArgListReg,
 		RunE:              registryOpts.runRegistryConfig,
@@ -119,6 +123,8 @@ regctl registry set quay.io --req-per-sec 10`,
 		RunE:              registryOpts.runRegistrySet,
 	}
 
+	registryConfigCmd.Flags().StringVar(&registryOpts.formatConf, "format", "{{jsonPretty .}}", "Format output with go template syntax")
+
 	registryLoginCmd.Flags().StringVarP(&registryOpts.user, "user", "u", "", "Username")
 	registryLoginCmd.Flags().StringVarP(&registryOpts.pass, "pass", "p", "", "Password")
 	registryLoginCmd.Flags().BoolVar(&registryOpts.passStdin, "pass-stdin", false, "Read password from stdin")
@@ -195,7 +201,6 @@ func (registryOpts *registryCmd) runRegistryConfig(cmd *cobra.Command, args []st
 		c.Hosts[i].Token = ""
 		c.Hosts[i].ClientKey = ""
 	}
-	var hj []byte
 	if len(args) > 0 {
 		h, ok := c.Hosts[args[0]]
 		if !ok {
@@ -204,20 +209,10 @@ func (registryOpts *registryCmd) runRegistryConfig(cmd *cobra.Command, args []st
 			}).Warn("No configuration found for registry")
 			return nil
 		}
-		hj, err = json.MarshalIndent(h, "", "  ")
-		if err != nil {
-			return err
-		}
+		return template.Writer(cmd.OutOrStdout(), registryOpts.formatConf, h)
 	} else {
-		hj, err = json.MarshalIndent(c.Hosts, "", "  ")
-		if err != nil {
-			return err
-		}
+		return template.Writer(cmd.OutOrStdout(), registryOpts.formatConf, c)
 	}
-
-	// TODO: enable formatted/template output
-	fmt.Fprintf(cmd.OutOrStdout(), "%s\n", hj)
-	return nil
 }
 
 func (registryOpts *registryCmd) runRegistryLogin(cmd *cobra.Command, args []string) error {


Test patch:
diff --git a/cmd/regctl/registry_test.go b/cmd/regctl/registry_test.go
index 0b4a1f3..6b1457c 100644
--- a/cmd/regctl/registry_test.go
+++ b/cmd/regctl/registry_test.go
@@ -2,7 +2,6 @@ package main
 
 import (
 	"errors"
-	"fmt"
 	"net/http"
 	"net/http/httptest"
 	"net/url"
@@ -88,16 +87,14 @@ func TestRegistry(t *testing.T) {
 		},
 		// query good and bad to ensure user is set
 		{
-			name:        "query good host",
-			args:        []string{"registry", "config", tsGoodHost},
-			expectOut:   `"user": "testgooduser",`,
-			outContains: true,
+			name:      "query good host",
+			args:      []string{"registry", "config", tsGoodHost, "--format", "{{.User}}"},
+			expectOut: `testgooduser`,
 		},
 		{
-			name:        "query bad host",
-			args:        []string{"registry", "config", tsBadHost},
-			expectOut:   `"user": "testbaduser",`,
-			outContains: true,
+			name:      "query bad host",
+			args:      []string{"registry", "config", tsBadHost, "--format", "{{.User}}"},
+			expectOut: `testbaduser`,
 		},
 		// logout
 		{
@@ -114,18 +111,14 @@ func TestRegistry(t *testing.T) {
 		},
 		// verify logout
 		{
-			name: "check logout on good host",
-			args: []string{"registry", "config", tsGoodHost},
-			expectOut: fmt.Sprintf(`"hostname": "%s",
-  "credHost": "",`, tsGoodHost),
-			outContains: true,
+			name:      "check logout on good host",
+			args:      []string{"registry", "config", tsGoodHost, "--format", "{{.User}}"},
+			expectOut: ``,
 		},
 		{
-			name: "check logout on bad host",
-			args: []string{"registry", "config", tsBadHost},
-			expectOut: fmt.Sprintf(`"hostname": "%s",
-  "credHost": "",`, tsBadHost),
-			outContains: true,
+			name:      "check logout on bad host",
+			args:      []string{"registry", "config", tsBadHost, "--format", "{{.User}}"},
+			expectOut: ``,
 		},
 	}
 	for _, tc := range tt {