Skip to content

Commit

Permalink
Merge #11004 #11015
Browse files Browse the repository at this point in the history
11004: cli: Clean up `pulumi stack` output for non-deployed stacks r=AaronFriel a=AaronFriel

Rather than display some potentially confusing output, only show the update time and Pulumi version used to deploy it when those values are present.

Improves code readability by following current variable styling.

On an empty stack, the display now appears as:

```
$ pulumi stack
Current stack is dev:
    Owner: friel
Current stack resources (0):
    No resources currently in this stack
```

Instead of:

```
$ pulumi stack
Current stack is dev:
    Last update time unknown
    Pulumi version: ?
    Owner: friel
Current stack resources (0):
    No resources currently in this stack
```

11015: Require a path separator for path based binaries. r=iwahbe a=iwahbe

This allows us to distinguish between ./myProvider (execute the binary at path) and myProvider (execute the installed plugin called myProvider).

<!--- 
Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation.
-->

# Description

<!--- Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. -->

Fixes #11014

## Checklist

<!--- Please provide details if the checkbox below is to be left unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my feature works
<!--- 
User-facing changes require a CHANGELOG entry.
-->
- [X] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the Pulumi Service,
then the service should honor older versions of the CLI where this change would not exist.
You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Service API version
  <!-- `@Pulumi` employees: If yes, you must submit corresponding changes in the service repo. -->


Co-authored-by: Aaron Friel <mayreply@aaronfriel.com>
Co-authored-by: Ian Wahbe <ian@wahbe.com>
  • Loading branch information
3 people committed Oct 13, 2022
3 parents f713611 + 0de16b5 + 5ce3d82 commit b4bf3dd
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 36 deletions.
@@ -0,0 +1,5 @@
changes:
- type: fix
scope: cli/package
description: >
Require a path separator for path based binaries. This allows us to distinguish between ./myProvider (execute the binary at path) and myProvider (execute the installed plugin).
40 changes: 29 additions & 11 deletions pkg/cmd/pulumi/package.go
Expand Up @@ -17,6 +17,7 @@ package main
import (
"encoding/json"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -106,24 +107,41 @@ func schemaFromSchemaSource(packageSource string) (*schema.Package, error) {
}
version = &v
}
info, err := os.Stat(pkg)
if os.IsNotExist(err) {
if strings.ContainsRune(pkg, filepath.Separator) {
// We infer that we were given a file path, so we assume that this is a file.
// The file was not found, so we exit.
return nil, err
}

isExecutable := func(info fs.FileInfo) bool {
return info.Mode()&0111 != 0 && !info.IsDir()
}

// No file separators, so we try to look up the schema
// On unix, these checks are identical. On windows, filepath.Separator is '\\'
if !strings.ContainsRune(pkg, filepath.Separator) && !strings.ContainsRune(pkg, '/') {
host, err := plugin.NewDefaultHost(pCtx, nil, false, nil)
if err != nil {
return nil, err
}
// We assume this was a plugin and not a path, so load the plugin.
return schema.NewPluginLoader(host).LoadPackage(pkg, version)
} else if err != nil {
return nil, err
schema, err := schema.NewPluginLoader(host).LoadPackage(pkg, version)
if err != nil {
// There is an executable with the same name, so suggest that
if info, statErr := os.Stat(pkg); statErr == nil && isExecutable(info) {
return nil, fmt.Errorf("could not find installed plugin %s, did you mean ./%[1]s: %w", pkg, err)
}
}
return schema, err

}

// We were given a path to a binary, so invoke that.
if info.Mode()&0111 == 0 {

info, err := os.Stat(pkg)
if os.IsNotExist(err) {
return nil, fmt.Errorf("could not find file %s", pkg)
} else if err != nil {
return nil, err
} else if !isExecutable(info) {
if p, err := filepath.Abs(pkg); err == nil {
pkg = p
}
return nil, fmt.Errorf("plugin at path %q not executable", pkg)
}

Expand Down
50 changes: 25 additions & 25 deletions pkg/cmd/pulumi/stack.go
Expand Up @@ -90,38 +90,38 @@ func newStackCmd() *cobra.Command {
}

if snap != nil {
if t := snap.Manifest.Time; t.IsZero() && startTime == "" {
fmt.Printf(" Last update time unknown\n")
} else if startTime == "" {
fmt.Printf(" Last updated: %s (%v)\n", humanize.Time(t), t)
t := snap.Manifest.Time.Local()
if startTime == "" {
// If a stack update is not in progress
if !t.IsZero() && t.Before(time.Now()) {
// If the update time is in the future, best to not display something incorrect based on
// inaccurate clocks.
fmt.Printf(" Last updated: %s (%v)\n", humanize.Time(t), t)
}
}
var cliver string
if snap.Manifest.Version == "" {
cliver = "?"
} else {
cliver = snap.Manifest.Version
if snap.Manifest.Version != "" {
fmt.Printf(" Pulumi version used: %s\n", snap.Manifest.Version)
}
fmt.Printf(" Pulumi version: %s\n", cliver)
for _, plugin := range snap.Manifest.Plugins {
var plugver string
if plugin.Version == nil {
plugver = "?"
for _, p := range snap.Manifest.Plugins {
var pluginVersion string
if p.Version == nil {
pluginVersion = "?"
} else {
plugver = plugin.Version.String()
pluginVersion = p.Version.String()
}
fmt.Printf(" Plugin %s [%s] version: %s\n", plugin.Name, plugin.Kind, plugver)
fmt.Printf(" Plugin %s [%s] version: %s\n", p.Name, p.Kind, pluginVersion)
}
} else {
fmt.Printf(" No updates yet; run `pulumi up`\n")
}

// Now show the resources.
var rescnt int
var resourceCount int
if snap != nil {
rescnt = len(snap.Resources)
resourceCount = len(snap.Resources)
}
fmt.Printf("Current stack resources (%d):\n", rescnt)
if rescnt == 0 {
fmt.Printf("Current stack resources (%d):\n", resourceCount)
if resourceCount == 0 {
fmt.Printf(" No resources currently in this stack\n")
} else {
rows, ok := renderTree(snap, showURNs, showIDs)
Expand Down Expand Up @@ -197,15 +197,15 @@ func printStackOutputs(outputs map[string]interface{}) {
if len(outputs) == 0 {
fmt.Printf(" No output values currently in this stack\n")
} else {
var outkeys []string
for outkey := range outputs {
outkeys = append(outkeys, outkey)
var outKeys []string
for v := range outputs {
outKeys = append(outKeys, v)
}
sort.Strings(outkeys)
sort.Strings(outKeys)

rows := []cmdutil.TableRow{}

for _, key := range outkeys {
for _, key := range outKeys {
rows = append(rows, cmdutil.TableRow{Columns: []string{key, stringifyOutput(outputs[key])}})
}

Expand Down

0 comments on commit b4bf3dd

Please sign in to comment.