Include package host version in about

This commit is contained in:
Ian Wahbe 2021-08-20 19:38:51 -07:00
parent e4e2b7c9d5
commit d7ee074a68
2 changed files with 102 additions and 10 deletions

View file

@ -17,9 +17,11 @@ import (
"flag" "flag"
"fmt" "fmt"
"os" "os"
"os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort" "sort"
"strings"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/shirou/gopsutil/host" "github.com/shirou/gopsutil/host"
@ -33,7 +35,9 @@ import (
"github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors" "github.com/pulumi/pulumi/sdk/v3/go/common/diag/colors"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil" "github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/executable"
"github.com/pulumi/pulumi/sdk/v3/go/common/workspace" "github.com/pulumi/pulumi/sdk/v3/go/common/workspace"
"github.com/pulumi/pulumi/sdk/v3/python"
) )
func newAboutCmd() *cobra.Command { func newAboutCmd() *cobra.Command {
@ -66,7 +70,7 @@ func newAboutCmd() *cobra.Command {
fmt.Print("\n") fmt.Print("\n")
if err = formatPluginAbout(); err != nil { if err = formatPluginAbout(); err != nil {
err = errors.Wrap(err, "Failed to get information about the plugin.") err = errors.Wrap(err, "Failed to get information about the plugin")
warn(err, &opts) warn(err, &opts)
} }
fmt.Print("\n") fmt.Print("\n")
@ -83,7 +87,10 @@ func newAboutCmd() *cobra.Command {
err = errors.Wrap(err, "Failed to read project for diagnosis") err = errors.Wrap(err, "Failed to read project for diagnosis")
warn(err, &opts) warn(err, &opts)
} else { } else {
fmt.Printf("This is a %s project.\n\n", proj.Runtime.Name()) if err = formatProjectRuntimeAbout(proj); err != nil {
err = errors.Wrap(err, "Failed to get diagnostic about the project runtime")
}
fmt.Print("\n")
if err = formatProgramDependenciesAbout(proj.Runtime.Name(), pwd); err != nil { if err = formatProgramDependenciesAbout(proj.Runtime.Name(), pwd); err != nil {
err = errors.Wrap(err, "Failed to get diagnositc information about the puluimi program's plugins") err = errors.Wrap(err, "Failed to get diagnositc information about the puluimi program's plugins")
@ -111,9 +118,7 @@ func newAboutCmd() *cobra.Command {
errors.Wrap(err, "Failed to gather diagnostic information on the current backend") errors.Wrap(err, "Failed to gather diagnostic information on the current backend")
warn(err, &opts) warn(err, &opts)
} }
} }
return nil return nil
}, },
), ),
@ -125,7 +130,7 @@ func newAboutCmd() *cobra.Command {
func formatPluginAbout() error { func formatPluginAbout() error {
var plugins []workspace.PluginInfo var plugins []workspace.PluginInfo
var err error var err error
plugins, err = getProjectPlugins() plugins, err = getProjectPluginsSilently()
if err != nil { if err != nil {
return err return err
@ -315,12 +320,88 @@ func formatLogAbout() {
fmt.Printf("Pulumi locates it's logs in $TEMPDIR by default\n") fmt.Printf("Pulumi locates it's logs in $TEMPDIR by default\n")
} else { } else {
// TODO: Find out // TODO: Find out
errors.New("I don't know where the logs are on windows") errors.New("I don't know where the logs are on windows\n")
} }
} }
func formatProjectRuntimeAbout(proj *workspace.Project) error {
var ex, version string
var err error
language := proj.Runtime.Name()
switch language {
case "nodejs":
ex, err = executable.FindExecutable("node")
if err != nil {
return errors.Wrap(err, "Could not find node executable")
}
cmd := exec.Command(ex, "--version")
if out, err := cmd.Output(); err != nil {
return errors.Wrap(err, "Failed to get node version")
} else {
version = string(out)
}
case "python":
var cmd *exec.Cmd
// if CommandPath has an error, then so will Command. The error can
// therefore be ignored as redundant.
ex, _, _ = python.CommandPath()
cmd, err = python.Command("--version")
if err != nil {
return err
}
if out, err := cmd.Output(); err != nil {
return errors.Wrap(err, "Failed to get python version")
} else {
version = "v" + strings.TrimPrefix(string(out), "Python ")
}
case "go":
ex, err = executable.FindExecutable("go")
if err != nil {
return errors.Wrap(err, "Could not find python executable")
}
cmd := exec.Command(ex, "version")
if out, err := cmd.Output(); err != nil {
return errors.Wrap(err, "Failed to get go version")
} else {
version = "v" + strings.TrimPrefix(string(out), "go version go")
}
case "dotnet":
ex, err = executable.FindExecutable("dotnet")
if err != nil {
return errors.Wrap(err, "Could not find dotnet executable")
}
cmd := exec.Command(ex, "--version")
if out, err := cmd.Output(); err != nil {
return errors.Wrap(err, "Failed to get dotnet version")
} else {
version = "v" + string(out)
}
default:
return errors.New(fmt.Sprintf("Unknown Language: %s", language))
}
version = strings.TrimSpace(version)
fmt.Printf("This project is a %s project (%s %s)\n", proj.Runtime.Name(), ex, version)
return nil
}
func warn(err error, opts *display.Options) { func warn(err error, opts *display.Options) {
msg := fmt.Sprintf("%swarning:%s %s\n", msg := fmt.Sprintf("%swarning:%s %s\n",
colors.SpecAttention, colors.Reset, err) colors.SpecAttention, colors.Reset, err)
fmt.Fprintf(os.Stdout, opts.Color.Colorize(msg)) fmt.Fprintf(os.Stdout, opts.Color.Colorize(msg))
} }
// This is necessary because dotnet invokes build during the call to
// getProjectPlugins.
func getProjectPluginsSilently() ([]workspace.PluginInfo, error) {
_, w, err := os.Pipe()
if err != nil {
return nil, err
}
stdout := os.Stdout
defer func() { os.Stdout = stdout }()
os.Stdout = w
return getProjectPlugins()
}

View file

@ -31,9 +31,10 @@ const (
pythonShimCmdFormat = "pulumi-%s-shim.cmd" pythonShimCmdFormat = "pulumi-%s-shim.cmd"
) )
// Command returns an *exec.Cmd for running `python`. If the `PULUMI_PYTHON_CMD` variable is set // Find the correct path and command for Python. If the `PULUMI_PYTHON_CMD`
// it will be looked for on `PATH`, otherwise, `python3` and `python` will be looked for. // variable is set it will be looked for on `PATH`, otherwise, `python3` and
func Command(arg ...string) (*exec.Cmd, error) { // `python` will be looked for.
func CommandPath() (string /*pythonPath*/, string /*pythonCmd*/, error) {
var err error var err error
var pythonCmds []string var pythonCmds []string
@ -65,12 +66,22 @@ func Command(arg ...string) (*exec.Cmd, error) {
pythonCmd, pythonPath, err = resolveWindowsExecutionAlias(pythonCmds) pythonCmd, pythonPath, err = resolveWindowsExecutionAlias(pythonCmds)
} }
if err != nil { if err != nil {
return nil, errors.Errorf( return "", "", errors.Errorf(
"Failed to locate any of %q on your PATH. Have you installed Python 3.6 or greater?", "Failed to locate any of %q on your PATH. Have you installed Python 3.6 or greater?",
pythonCmds) pythonCmds)
} }
} }
return pythonPath, pythonCmd, nil
}
// Command returns an *exec.Cmd for running `python`. Uses `ComandPath`
// internally to find the correct executable.
func Command(arg ...string) (*exec.Cmd, error) {
pythonPath, pythonCmd, err := CommandPath()
if err != nil {
return nil, err
}
if needsPythonShim(pythonPath) { if needsPythonShim(pythonPath) {
shimCmd := fmt.Sprintf(pythonShimCmdFormat, pythonCmd) shimCmd := fmt.Sprintf(pythonShimCmdFormat, pythonCmd)
return exec.Command(shimCmd, arg...), nil return exec.Command(shimCmd, arg...), nil