Skip to content

Commit

Permalink
Merge pull request #12037 from hmlanigan/juju-info-add-config
Browse files Browse the repository at this point in the history
#12037

## Description of change

Allow channels to be displayed again, real vs canned data issue. Instead of latest, the tracks that are latest are an empty string, insert "latest" for display purposes.

Add the ability to display charm config options in the juju info output. Handy to know before deploying.

## QA steps

```console
$ export JUJU_DEV_FEATURE_FLAGS="charm-hub"
$ juju bootstrap localhost testme
$ juju add-model seven --config charm-hub-url="https://api.staging.snapcraft.io"
$ juju info apitest-ubuntu-qa --config
name: apitest-ubuntu-qa
charm-id: 4HVy9HLeoMQ0eUALfsvE6ifqtL6DqUPm
summary: |
 juju-qa version of the ubuntu charm.
publisher: Heather Lanigan
supports: focal, xenial, bionic
subordinate: false
store-url: https://api.staging.snapcraft.io/v2/charms/apitest-ubuntu-qa
description: |
 juju-qa version of the ubuntu charm.
channels: |
 latest/stable: 1 (1) 250kB
 latest/candidate: 1 (1) 250kB
 latest/beta: 1 (1) 250kB
 latest/edge: 2 (2) 250kB
settings:
 status:
 type: string
 description: temporary string for unit status
 default: hello
 thing:
 type: string
 description: A thing used by the charm.
 default: "\U0001F381"

```
  • Loading branch information
jujubot committed Sep 23, 2020
2 parents 56b5f51 + 21b9f20 commit 2991b49
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 25 deletions.
4 changes: 4 additions & 0 deletions apiserver/facades/client/charmhub/convert.go
Expand Up @@ -103,6 +103,10 @@ func transformChannelMap(channelMap []transport.ChannelMap) ([]string, map[strin
channels := make(map[string]params.Channel, len(channelMap))
for _, cm := range channelMap {
ch := cm.Channel
// Per the charmhub/snap channel spec.
if ch.Track == "" {
ch.Track = "latest"
}
chName := ch.Track + "/" + ch.Risk
channels[chName] = params.Channel{
Revision: cm.Revision.Revision,
Expand Down
6 changes: 3 additions & 3 deletions cmd/juju/charmhub/info.go
Expand Up @@ -43,7 +43,7 @@ type infoCommand struct {

api InfoCommandAPI

verbose bool
config bool
charmOrBundle string
}

Expand All @@ -63,6 +63,7 @@ func (c *infoCommand) Info() *cmd.Info {
// It implements part of the cmd.Command interface.
func (c *infoCommand) SetFlags(f *gnuflag.FlagSet) {
c.ModelCommandBase.SetFlags(f)
f.BoolVar(&c.config, "config", false, "display config for this charm")
c.out.AddFlags(f, "tabular", map[string]cmd.Formatter{
"yaml": cmd.FormatYaml,
"json": cmd.FormatJson,
Expand Down Expand Up @@ -107,7 +108,6 @@ func (c *infoCommand) Run(ctx *cmd.Context) error {
if err != nil {
return errors.Trace(err)
}

return c.out.Write(ctx, &view)
}

Expand Down Expand Up @@ -138,7 +138,7 @@ func (c *infoCommand) formatter(writer io.Writer, value interface{}) error {
return errors.Errorf("unexpected results")
}

if err := makeInfoWriter(writer, c.warningLog, results).Print(); err != nil {
if err := makeInfoWriter(writer, c.warningLog, c.config, results).Print(); err != nil {
return errors.Trace(err)
}

Expand Down
46 changes: 27 additions & 19 deletions cmd/juju/charmhub/infowriter.go
Expand Up @@ -23,11 +23,12 @@ import (
// There are exceptions, slices of strings and tables. These
// are transformed into strings.

func makeInfoWriter(w io.Writer, warningLog Log, in *InfoResponse) Printer {
func makeInfoWriter(w io.Writer, warningLog Log, config bool, in *InfoResponse) Printer {
iw := infoWriter{
w: w,
warningf: warningLog,
in: in,
w: w,
warningf: warningLog,
in: in,
displayConfig: config,
}
if iw.in.Type == "charm" {
return charmInfoWriter{infoWriter: iw}
Expand All @@ -36,9 +37,10 @@ func makeInfoWriter(w io.Writer, warningLog Log, in *InfoResponse) Printer {
}

type infoWriter struct {
warningf Log
w io.Writer
in *InfoResponse
warningf Log
w io.Writer
in *InfoResponse
displayConfig bool
}

func (iw infoWriter) print(info interface{}) error {
Expand Down Expand Up @@ -136,18 +138,19 @@ func (b bundleInfoWriter) Print() error {
}

type charmInfoOutput struct {
Name string `yaml:"name,omitempty"`
ID string `yaml:"charm-id,omitempty"`
Summary string `yaml:"summary,omitempty"`
Publisher string `yaml:"publisher,omitempty"`
Supports string `yaml:"supports,omitempty"`
Tags string `yaml:"tags,omitempty"`
Subordinate bool `yaml:"subordinate"`
StoreURL string `yaml:"store-url,omitempty"`
Description string `yaml:"description,omitempty"`
Relations relationOutput `yaml:"relations,omitempty"`
Channels string `yaml:"channels,omitempty"`
Installed string `yaml:"installed,omitempty"`
Name string `yaml:"name,omitempty"`
ID string `yaml:"charm-id,omitempty"`
Summary string `yaml:"summary,omitempty"`
Publisher string `yaml:"publisher,omitempty"`
Supports string `yaml:"supports,omitempty"`
Tags string `yaml:"tags,omitempty"`
Subordinate bool `yaml:"subordinate"`
StoreURL string `yaml:"store-url,omitempty"`
Description string `yaml:"description,omitempty"`
Relations relationOutput `yaml:"relations,omitempty"`
Channels string `yaml:"channels,omitempty"`
Installed string `yaml:"installed,omitempty"`
Config map[string]interface{} `yaml:"config,omitempty"`
}

type relationOutput struct {
Expand All @@ -166,12 +169,17 @@ func (c charmInfoWriter) Print() error {
Summary: c.in.Summary,
Publisher: c.in.Publisher,
Supports: strings.Join(c.in.Series, ", "),
StoreURL: c.in.StoreURL,
Description: c.in.Description,
Channels: c.channels(),
Tags: strings.Join(c.in.Tags, ", "),
}
if c.in.Charm != nil {
out.Subordinate = c.in.Charm.Subordinate
if c.displayConfig && c.in.Charm.Config != nil {
out.Config = make(map[string]interface{}, 1)
out.Config["settings"] = c.in.Charm.Config.Options
}
}
if rels, err := c.relations(); err == nil {
out.Relations = rels
Expand Down
65 changes: 62 additions & 3 deletions cmd/juju/charmhub/infowriter_test.go
Expand Up @@ -6,6 +6,7 @@ package charmhub
import (
"bytes"

"github.com/juju/charm/v8"
jc "github.com/juju/testing/checkers"
gc "gopkg.in/check.v1"
)
Expand All @@ -17,7 +18,7 @@ var _ = gc.Suite(&printInfoSuite{})
func (s *printInfoSuite) TestCharmPrintInfo(c *gc.C) {
ir := getCharmInfoResponse()
ctx := commandContextForTest(c)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, &ir)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, false, &ir)
err := iw.Print()
c.Assert(err, jc.ErrorIsNil)

Expand Down Expand Up @@ -48,10 +49,54 @@ channels: |
c.Assert(obtained, gc.Equals, expected)
}

func (s *printInfoSuite) TestCharmPrintInfoWithConfig(c *gc.C) {
ir := getCharmInfoResponse()
ctx := commandContextForTest(c)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, true, &ir)
err := iw.Print()
c.Assert(err, jc.ErrorIsNil)

obtained := ctx.Stdout.(*bytes.Buffer).String()
expected := `name: wordpress
charm-id: charmCHARMcharmCHARMcharmCHARM01
summary: WordPress is a full featured web blogging tool, this charm deploys it.
publisher: Wordress Charmers
supports: bionic, xenial
tags: app, seven
subordinate: true
description: |-
This will install and setup WordPress optimized to run in the cloud.
By default it will place Ngnix and php-fpm configured to scale horizontally with
Nginx's reverse proxy.
relations:
provides:
one: two
three: four
requires:
five: six
channels: |
latest/stable: 1.0.3 2019-12-16 (16) 12MB
latest/candidate: 1.0.3 2019-12-16 (17) 12MB
latest/beta: 1.0.3 2019-12-16 (17) 12MB
latest/edge: 1.0.3 2019-12-16 (18) 12MB
config:
settings:
status:
type: string
description: temporary string for unit status
default: hello
thing:
type: string
description: A thing used by the charm.
default: "\U0001F381"
`
c.Assert(obtained, gc.Equals, expected)
}

func (s *printInfoSuite) TestBundleChannelClosed(c *gc.C) {
ir := getBundleInfoClosedTrack()
ctx := commandContextForTest(c)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, &ir)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, false, &ir)
err := iw.Print()
c.Assert(err, jc.ErrorIsNil)

Expand All @@ -73,7 +118,7 @@ channels: |
func (s *printInfoSuite) TestBundlePrintInfo(c *gc.C) {
ir := getBundleInfoResponse()
ctx := commandContextForTest(c)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, &ir)
iw := makeInfoWriter(ctx.Stdout, ctx.Warningf, false, &ir)
err := iw.Print()
c.Assert(err, jc.ErrorIsNil)

Expand Down Expand Up @@ -151,6 +196,20 @@ func getCharmInfoResponse() InfoResponse {
Series: []string{"bionic", "xenial"},
Tags: []string{"app", "seven"},
Charm: &Charm{
Config: &charm.Config{
Options: map[string]charm.Option{
"status": {
Type: "string",
Description: "temporary string for unit status",
Default: "hello",
},
"thing": {
Type: "string",
Description: "A thing used by the charm.",
Default: "🎁",
},
},
},
Subordinate: true,
Relations: map[string]map[string]string{
"provides": {
Expand Down

0 comments on commit 2991b49

Please sign in to comment.