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"
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"sort"
"strings"
"github.com/pkg/errors"
"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/resource"
"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/python"
)
func newAboutCmd() *cobra.Command {
@ -66,7 +70,7 @@ func newAboutCmd() *cobra.Command {
fmt.Print("\n")
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)
}
fmt.Print("\n")
@ -83,7 +87,10 @@ func newAboutCmd() *cobra.Command {
err = errors.Wrap(err, "Failed to read project for diagnosis")
warn(err, &opts)
} 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 {
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")
warn(err, &opts)
}
}
return nil
},
),
@ -125,7 +130,7 @@ func newAboutCmd() *cobra.Command {
func formatPluginAbout() error {
var plugins []workspace.PluginInfo
var err error
plugins, err = getProjectPlugins()
plugins, err = getProjectPluginsSilently()
if err != nil {
return err
@ -315,12 +320,88 @@ func formatLogAbout() {
fmt.Printf("Pulumi locates it's logs in $TEMPDIR by default\n")
} else {
// 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) {
msg := fmt.Sprintf("%swarning:%s %s\n",
colors.SpecAttention, colors.Reset, err)
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"
)
// Command returns an *exec.Cmd for running `python`. If the `PULUMI_PYTHON_CMD` variable is set
// it will be looked for on `PATH`, otherwise, `python3` and `python` will be looked for.
func Command(arg ...string) (*exec.Cmd, error) {
// Find the correct path and command for Python. If the `PULUMI_PYTHON_CMD`
// variable is set it will be looked for on `PATH`, otherwise, `python3` and
// `python` will be looked for.
func CommandPath() (string /*pythonPath*/, string /*pythonCmd*/, error) {
var err error
var pythonCmds []string
@ -65,12 +66,22 @@ func Command(arg ...string) (*exec.Cmd, error) {
pythonCmd, pythonPath, err = resolveWindowsExecutionAlias(pythonCmds)
}
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?",
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) {
shimCmd := fmt.Sprintf(pythonShimCmdFormat, pythonCmd)
return exec.Command(shimCmd, arg...), nil