Skip to content

Commit

Permalink
Show scopes in apis subcommands instead of count (#174)
Browse files Browse the repository at this point in the history
* For `apis` subcommands that show scopes use a truncated list, based on terminal width, to show the scopes instead of the count. Use an ellipsis to shdenote the truncation.

For the `apis show` subcommand, add an info to note that the full scopes can be viewed using `auth0 apis scopes list <api-id>`.

* Use count of scopes for the table view `apis list` uses.

* Use a separate struct so JSON output correctly uses an int for the scopes count.

* Show the actual app ID in helper text for `apis show` and clarify the list may be truncated.

* Update modules

* Remove unused function

* Move display logic out of cli package. Only show helper text on scope truncation when the scopes are actually truncated. Don't truncate scopes that fit.

* Fix truncation. NOTE: this does not handle multi-byte width characters.

Co-authored-by: Rita Zerrizuela <[email protected]>
  • Loading branch information
chrisscott and Widcket authored Mar 24, 2021
1 parent 93321c2 commit b518b64
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 12 deletions.
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -501,9 +501,13 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305023407-0d6cb8bd5a4b h1:zQ+/dCJWTuLZNCt92+rfDzgYfIWkoCRrcMAPBiQ6bt4=
golang.org/x/sys v0.0.0-20210305023407-0d6cb8bd5a4b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d h1:jbzgAvDZn8aEnytae+4ou0J0GwFZoHR0hOrTg4qH8GA=
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6 h1:EC6+IGYTjPpRfv9a2b/6Puw0W+hLtAhkV1tPsXhutqs=
golang.org/x/term v0.0.0-20210317153231-de623e64d2a6/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
104 changes: 92 additions & 12 deletions internal/display/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ package display

import (
"fmt"
"strconv"
"os"
"strings"

"github.com/auth0/auth0-cli/internal/ansi"
"github.com/auth0/auth0-cli/internal/auth0"
"golang.org/x/term"
"gopkg.in/auth0.v5/management"
)

type apiView struct {
ID string
Name string
Identifier string
Scopes int
Scopes string

raw interface{}
}
Expand All @@ -28,17 +30,38 @@ func (v *apiView) AsTableRow() []string {

func (v *apiView) KeyValues() [][]string {
return [][]string{
[]string{"ID", ansi.Faint(v.ID)},
[]string{"NAME", v.Name},
[]string{"IDENTIFIER", v.Identifier},
[]string{"SCOPES", strconv.Itoa(v.Scopes)},
{"ID", ansi.Faint(v.ID)},
{"NAME", v.Name},
{"IDENTIFIER", v.Identifier},
{"SCOPES", v.Scopes},
}
}

func (v *apiView) Object() interface{} {
return v.raw
}

type apiTableView struct {
ID string
Name string
Identifier string
Scopes int

raw interface{}
}

func (v *apiTableView) AsTableHeader() []string {
return []string{"ID", "Name", "Identifier", "Scopes"}
}

func (v *apiTableView) AsTableRow() []string {
return []string{ansi.Faint(v.ID), v.Name, v.Identifier, fmt.Sprint(v.Scopes)}
}

func (v *apiTableView) Object() interface{} {
return v.raw
}

func (r *Renderer) ApiList(apis []*management.ResourceServer) {
resource := "APIs"

Expand All @@ -53,31 +76,51 @@ func (r *Renderer) ApiList(apis []*management.ResourceServer) {
results := []View{}

for _, api := range apis {
results = append(results, makeApiView(api))
results = append(results, makeApiTableView(api))
}

r.Results(results)
}

func (r *Renderer) ApiShow(api *management.ResourceServer) {
r.Heading("API")
r.Result(makeApiView(api))
view, scopesTruncated := makeApiView(api)
r.Result(view)
if scopesTruncated {
r.Newline()
r.Infof("Scopes truncated for display. To see the full list, run %s", ansi.Faint(fmt.Sprintf("apis scopes list %s", *api.ID)))
}
}

func (r *Renderer) ApiCreate(api *management.ResourceServer) {
r.Heading("API created")
r.Result(makeApiView(api))
view, _ := makeApiView(api)
r.Result(view)
}

func (r *Renderer) ApiUpdate(api *management.ResourceServer) {
r.Heading("API updated")
r.Result(makeApiView(api))
view, _ := makeApiView(api)
r.Result(view)
}

func makeApiView(api *management.ResourceServer) (*apiView, bool) {
scopes, scopesTruncated := getScopes(api.Scopes)
view := &apiView{
ID: auth0.StringValue(api.ID),
Name: auth0.StringValue(api.Name),
Identifier: auth0.StringValue(api.Identifier),
Scopes: auth0.StringValue(scopes),

raw: api,
}
return view, scopesTruncated
}

func makeApiView(api *management.ResourceServer) *apiView {
func makeApiTableView(api *management.ResourceServer) *apiTableView {
scopes := len(api.Scopes)

return &apiView{
return &apiTableView{
ID: auth0.StringValue(api.ID),
Name: auth0.StringValue(api.Name),
Identifier: auth0.StringValue(api.Identifier),
Expand Down Expand Up @@ -125,3 +168,40 @@ func makeScopeView(scope *management.ResourceServerScope) *scopeView {
Description: auth0.StringValue(scope.Description),
}
}

func getScopes(scopes []*management.ResourceServerScope) (*string, bool) {
ellipsis := "..."
separator := " "
padding := 16 // the longest apiView key plus two spaces before and after in the label column
terminalWidth, _, err := term.GetSize(int(os.Stdin.Fd()))
if err != nil {
terminalWidth = 80
}

var scopesForDisplay string
maxCharacters := terminalWidth - padding

for i, scope := range scopes {
prepend := separator

// no separator prepended for first value
if i == 0 {
prepend = ""
}
scopesForDisplay += fmt.Sprintf("%s%s", prepend, *scope.Value)
}

if len(scopesForDisplay) <= maxCharacters {
return &scopesForDisplay, false
}

truncationIndex := maxCharacters - len(ellipsis)
lastSeparator := strings.LastIndex(string(scopesForDisplay[:truncationIndex]), separator)
if lastSeparator != -1 {
truncationIndex = lastSeparator
}

scopesForDisplay = fmt.Sprintf("%s%s", string(scopesForDisplay[:truncationIndex]), ellipsis)

return &scopesForDisplay, true
}

0 comments on commit b518b64

Please sign in to comment.