Implement basic plugin management
This change implements basic plugin management, but we do not yet
actually use the plugins for anything (that comes next).
Plugins are stored in `~/.pulumi/plugins`, and are expected to be
in the format `pulumi-<KIND>-<NAME>-v<VERSION>[.exe]`. The KIND is
one of `analyzer`, `language`, or `resource`, the NAME is a hyphen-
delimited name (e.g., `aws` or `foo-bar`), and VERSION is the
plugin's semantic version (e.g., `0.9.11`, `1.3.7-beta.a736cf`, etc).
This commit includes four new CLI commands:
* `pulumi plugin` is the top-level plugin command. It does nothing
but show the help text for associated child commands.
* `pulumi plugin install` can be used to install plugins manually.
If run with no additional arguments, it will compute the set of
plugins used by the current project, and download them all. It
may be run to explicitly download a single plugin, however, by
invoking it as `pulumi plugin install KIND NAME VERSION`. For
example, `pulumi plugin install resource aws v0.9.11`. By default,
this command uses the cloud backend in the usual way to perform the
download, although a separate URL may be given with --cloud-url,
just like all other commands that interact with our backend service.
* `pulumi plugin ls` lists all plugins currently installed in the
plugin cache. It displays some useful statistics, like the size
of the plugin, when it was installed, when it was last used, and
so on. It sorts the display alphabetically by plugin name, and
for plugins with multiple versions, it shows the newest at the top.
The command also summarizes how much disk space is currently being
consumed by the plugin cache. There are no filtering capabilities yet.
* `pulumi plugin prune` will delete plugins from the cache. By
default, when run with no arguments, it will delete everything.
It may be run with additional arguments, KIND, NAME, and VERSION,
each one getting more specific about what it will delete. For
instance, `pulumi plugin prune resource aws` will delete all AWS
plugin versions, while `pulumi plugin prune resource aws <0.9`
will delete all AWS plugins before version 0.9. Unless --yes is
passed, the command will confirm the deletion with a count of how
many plugins will be affected by the command.
We do not yet actually download plugins on demand yet. That will
come in a subsequent change.
2018-02-04 19:51:29 +01:00
|
|
|
// Copyright 2016-2017, Pulumi Corporation. All rights reserved.
|
|
|
|
|
|
|
|
package cmd
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"sort"
|
|
|
|
"strconv"
|
|
|
|
|
|
|
|
"github.com/dustin/go-humanize"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
|
|
|
"github.com/pulumi/pulumi/pkg/util/cmdutil"
|
|
|
|
"github.com/pulumi/pulumi/pkg/workspace"
|
|
|
|
)
|
|
|
|
|
|
|
|
func newPluginLsCmd() *cobra.Command {
|
|
|
|
var projectOnly bool
|
|
|
|
cmd := &cobra.Command{
|
|
|
|
Use: "ls",
|
|
|
|
Short: "List plugins",
|
|
|
|
Args: cmdutil.NoArgs,
|
|
|
|
Run: cmdutil.RunFunc(func(cmd *cobra.Command, args []string) error {
|
|
|
|
// Produce a list of plugins, sorted by name and version.
|
2018-02-19 19:58:03 +01:00
|
|
|
var plugins []workspace.PluginInfo
|
|
|
|
var err error
|
|
|
|
if projectOnly {
|
|
|
|
if plugins, err = getProjectPlugins(); err != nil {
|
|
|
|
return errors.Wrapf(err, "loading project plugins")
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if plugins, err = workspace.GetPlugins(); err != nil {
|
|
|
|
return errors.Wrapf(err, "loading plugins")
|
|
|
|
}
|
Implement basic plugin management
This change implements basic plugin management, but we do not yet
actually use the plugins for anything (that comes next).
Plugins are stored in `~/.pulumi/plugins`, and are expected to be
in the format `pulumi-<KIND>-<NAME>-v<VERSION>[.exe]`. The KIND is
one of `analyzer`, `language`, or `resource`, the NAME is a hyphen-
delimited name (e.g., `aws` or `foo-bar`), and VERSION is the
plugin's semantic version (e.g., `0.9.11`, `1.3.7-beta.a736cf`, etc).
This commit includes four new CLI commands:
* `pulumi plugin` is the top-level plugin command. It does nothing
but show the help text for associated child commands.
* `pulumi plugin install` can be used to install plugins manually.
If run with no additional arguments, it will compute the set of
plugins used by the current project, and download them all. It
may be run to explicitly download a single plugin, however, by
invoking it as `pulumi plugin install KIND NAME VERSION`. For
example, `pulumi plugin install resource aws v0.9.11`. By default,
this command uses the cloud backend in the usual way to perform the
download, although a separate URL may be given with --cloud-url,
just like all other commands that interact with our backend service.
* `pulumi plugin ls` lists all plugins currently installed in the
plugin cache. It displays some useful statistics, like the size
of the plugin, when it was installed, when it was last used, and
so on. It sorts the display alphabetically by plugin name, and
for plugins with multiple versions, it shows the newest at the top.
The command also summarizes how much disk space is currently being
consumed by the plugin cache. There are no filtering capabilities yet.
* `pulumi plugin prune` will delete plugins from the cache. By
default, when run with no arguments, it will delete everything.
It may be run with additional arguments, KIND, NAME, and VERSION,
each one getting more specific about what it will delete. For
instance, `pulumi plugin prune resource aws` will delete all AWS
plugin versions, while `pulumi plugin prune resource aws <0.9`
will delete all AWS plugins before version 0.9. Unless --yes is
passed, the command will confirm the deletion with a count of how
many plugins will be affected by the command.
We do not yet actually download plugins on demand yet. That will
come in a subsequent change.
2018-02-04 19:51:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Devote 26 characters to the name width, unless there is a longer name.
|
|
|
|
maxname := 26
|
|
|
|
for _, plugin := range plugins {
|
|
|
|
if len(plugin.Name) > maxname {
|
|
|
|
maxname = len(plugin.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort the plugins: by name first alphabetical ascending and version descending, so that plugins
|
|
|
|
// with the same name/kind sort by newest to oldest.
|
|
|
|
sort.Slice(plugins, func(i, j int) bool {
|
|
|
|
pi, pj := plugins[i], plugins[j]
|
|
|
|
if pi.Name < pj.Name {
|
|
|
|
return true
|
2018-02-06 18:57:32 +01:00
|
|
|
} else if pi.Name == pj.Name && pi.Kind == pj.Kind &&
|
|
|
|
(pi.Version == nil || (pj.Version != nil && pi.Version.GT(*pj.Version))) {
|
Implement basic plugin management
This change implements basic plugin management, but we do not yet
actually use the plugins for anything (that comes next).
Plugins are stored in `~/.pulumi/plugins`, and are expected to be
in the format `pulumi-<KIND>-<NAME>-v<VERSION>[.exe]`. The KIND is
one of `analyzer`, `language`, or `resource`, the NAME is a hyphen-
delimited name (e.g., `aws` or `foo-bar`), and VERSION is the
plugin's semantic version (e.g., `0.9.11`, `1.3.7-beta.a736cf`, etc).
This commit includes four new CLI commands:
* `pulumi plugin` is the top-level plugin command. It does nothing
but show the help text for associated child commands.
* `pulumi plugin install` can be used to install plugins manually.
If run with no additional arguments, it will compute the set of
plugins used by the current project, and download them all. It
may be run to explicitly download a single plugin, however, by
invoking it as `pulumi plugin install KIND NAME VERSION`. For
example, `pulumi plugin install resource aws v0.9.11`. By default,
this command uses the cloud backend in the usual way to perform the
download, although a separate URL may be given with --cloud-url,
just like all other commands that interact with our backend service.
* `pulumi plugin ls` lists all plugins currently installed in the
plugin cache. It displays some useful statistics, like the size
of the plugin, when it was installed, when it was last used, and
so on. It sorts the display alphabetically by plugin name, and
for plugins with multiple versions, it shows the newest at the top.
The command also summarizes how much disk space is currently being
consumed by the plugin cache. There are no filtering capabilities yet.
* `pulumi plugin prune` will delete plugins from the cache. By
default, when run with no arguments, it will delete everything.
It may be run with additional arguments, KIND, NAME, and VERSION,
each one getting more specific about what it will delete. For
instance, `pulumi plugin prune resource aws` will delete all AWS
plugin versions, while `pulumi plugin prune resource aws <0.9`
will delete all AWS plugins before version 0.9. Unless --yes is
passed, the command will confirm the deletion with a count of how
many plugins will be affected by the command.
We do not yet actually download plugins on demand yet. That will
come in a subsequent change.
2018-02-04 19:51:29 +01:00
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
|
|
|
// And now pretty-print the list.
|
|
|
|
var totalSize uint64
|
|
|
|
fmt.Printf("%-"+strconv.Itoa(maxname)+"s %-12s %-26s %-18s %-18s %-18s\n",
|
|
|
|
"NAME", "KIND", "VERSION", "SIZE", "INSTALLED", "LAST USED")
|
|
|
|
for _, plugin := range plugins {
|
2018-02-19 19:58:03 +01:00
|
|
|
var version string
|
|
|
|
if plugin.Version != nil {
|
|
|
|
version = plugin.Version.String()
|
|
|
|
}
|
|
|
|
var bytes string
|
|
|
|
if plugin.Size == 0 {
|
2018-02-22 18:26:19 +01:00
|
|
|
bytes = naString
|
2018-02-19 19:58:03 +01:00
|
|
|
} else {
|
|
|
|
bytes = humanize.Bytes(uint64(plugin.Size))
|
|
|
|
}
|
|
|
|
var installTime string
|
|
|
|
if plugin.InstallTime.IsZero() {
|
2018-02-22 18:26:19 +01:00
|
|
|
installTime = naString
|
2018-02-19 19:58:03 +01:00
|
|
|
} else {
|
|
|
|
installTime = humanize.Time(plugin.InstallTime)
|
|
|
|
}
|
|
|
|
var lastUsedTime string
|
|
|
|
if plugin.LastUsedTime.IsZero() {
|
|
|
|
lastUsedTime = humanNeverTime
|
|
|
|
} else {
|
|
|
|
lastUsedTime = humanize.Time(plugin.LastUsedTime)
|
|
|
|
}
|
Implement basic plugin management
This change implements basic plugin management, but we do not yet
actually use the plugins for anything (that comes next).
Plugins are stored in `~/.pulumi/plugins`, and are expected to be
in the format `pulumi-<KIND>-<NAME>-v<VERSION>[.exe]`. The KIND is
one of `analyzer`, `language`, or `resource`, the NAME is a hyphen-
delimited name (e.g., `aws` or `foo-bar`), and VERSION is the
plugin's semantic version (e.g., `0.9.11`, `1.3.7-beta.a736cf`, etc).
This commit includes four new CLI commands:
* `pulumi plugin` is the top-level plugin command. It does nothing
but show the help text for associated child commands.
* `pulumi plugin install` can be used to install plugins manually.
If run with no additional arguments, it will compute the set of
plugins used by the current project, and download them all. It
may be run to explicitly download a single plugin, however, by
invoking it as `pulumi plugin install KIND NAME VERSION`. For
example, `pulumi plugin install resource aws v0.9.11`. By default,
this command uses the cloud backend in the usual way to perform the
download, although a separate URL may be given with --cloud-url,
just like all other commands that interact with our backend service.
* `pulumi plugin ls` lists all plugins currently installed in the
plugin cache. It displays some useful statistics, like the size
of the plugin, when it was installed, when it was last used, and
so on. It sorts the display alphabetically by plugin name, and
for plugins with multiple versions, it shows the newest at the top.
The command also summarizes how much disk space is currently being
consumed by the plugin cache. There are no filtering capabilities yet.
* `pulumi plugin prune` will delete plugins from the cache. By
default, when run with no arguments, it will delete everything.
It may be run with additional arguments, KIND, NAME, and VERSION,
each one getting more specific about what it will delete. For
instance, `pulumi plugin prune resource aws` will delete all AWS
plugin versions, while `pulumi plugin prune resource aws <0.9`
will delete all AWS plugins before version 0.9. Unless --yes is
passed, the command will confirm the deletion with a count of how
many plugins will be affected by the command.
We do not yet actually download plugins on demand yet. That will
come in a subsequent change.
2018-02-04 19:51:29 +01:00
|
|
|
fmt.Printf("%-"+strconv.Itoa(maxname)+"s %-12s %-26s %-18s %-18s %-18s\n",
|
2018-02-19 19:58:03 +01:00
|
|
|
plugin.Name, plugin.Kind, version, bytes, installTime, lastUsedTime)
|
Implement basic plugin management
This change implements basic plugin management, but we do not yet
actually use the plugins for anything (that comes next).
Plugins are stored in `~/.pulumi/plugins`, and are expected to be
in the format `pulumi-<KIND>-<NAME>-v<VERSION>[.exe]`. The KIND is
one of `analyzer`, `language`, or `resource`, the NAME is a hyphen-
delimited name (e.g., `aws` or `foo-bar`), and VERSION is the
plugin's semantic version (e.g., `0.9.11`, `1.3.7-beta.a736cf`, etc).
This commit includes four new CLI commands:
* `pulumi plugin` is the top-level plugin command. It does nothing
but show the help text for associated child commands.
* `pulumi plugin install` can be used to install plugins manually.
If run with no additional arguments, it will compute the set of
plugins used by the current project, and download them all. It
may be run to explicitly download a single plugin, however, by
invoking it as `pulumi plugin install KIND NAME VERSION`. For
example, `pulumi plugin install resource aws v0.9.11`. By default,
this command uses the cloud backend in the usual way to perform the
download, although a separate URL may be given with --cloud-url,
just like all other commands that interact with our backend service.
* `pulumi plugin ls` lists all plugins currently installed in the
plugin cache. It displays some useful statistics, like the size
of the plugin, when it was installed, when it was last used, and
so on. It sorts the display alphabetically by plugin name, and
for plugins with multiple versions, it shows the newest at the top.
The command also summarizes how much disk space is currently being
consumed by the plugin cache. There are no filtering capabilities yet.
* `pulumi plugin prune` will delete plugins from the cache. By
default, when run with no arguments, it will delete everything.
It may be run with additional arguments, KIND, NAME, and VERSION,
each one getting more specific about what it will delete. For
instance, `pulumi plugin prune resource aws` will delete all AWS
plugin versions, while `pulumi plugin prune resource aws <0.9`
will delete all AWS plugins before version 0.9. Unless --yes is
passed, the command will confirm the deletion with a count of how
many plugins will be affected by the command.
We do not yet actually download plugins on demand yet. That will
come in a subsequent change.
2018-02-04 19:51:29 +01:00
|
|
|
totalSize += uint64(plugin.Size)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("\n")
|
|
|
|
fmt.Printf("TOTAL plugin cache size: %s\n", humanize.Bytes(totalSize))
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd.PersistentFlags().BoolVarP(
|
|
|
|
&projectOnly, "project", "p", false,
|
|
|
|
"List only the plugins used by the current project")
|
|
|
|
|
|
|
|
return cmd
|
|
|
|
}
|
2018-02-19 19:58:03 +01:00
|
|
|
|
|
|
|
const humanNeverTime = "never"
|
2018-02-22 18:26:19 +01:00
|
|
|
const naString = "n/a"
|