Revert "feat: add version checking to CLI" (#2712)

This commit is contained in:
Colin Adler
2022-06-28 21:42:23 -05:00
committed by GitHub
parent 7ee7be3391
commit 2b6dcb842d
6 changed files with 5 additions and 174 deletions
+1 -21
View File
@@ -3,7 +3,6 @@ package buildinfo
import (
"fmt"
"runtime/debug"
"strings"
"sync"
"time"
@@ -25,11 +24,6 @@ var (
tag string
)
const (
// develPrefix is prefixed to developer versions of the application.
develPrefix = "v0.0.0-devel"
)
// Version returns the semantic version of the build.
// Use golang.org/x/mod/semver to compare versions.
func Version() string {
@@ -41,7 +35,7 @@ func Version() string {
if tag == "" {
// This occurs when the tag hasn't been injected,
// like when using "go run".
version = develPrefix + revision
version = "v0.0.0-devel" + revision
return
}
version = "v" + tag
@@ -54,20 +48,6 @@ func Version() string {
return version
}
// VersionsMatch compares the two versions. It assumes the versions match if
// the major and the minor versions are equivalent. Patch versions are
// disregarded. If it detects that either version is a developer build it
// returns true.
func VersionsMatch(v1, v2 string) bool {
// Developer versions are disregarded...hopefully they know what they are
// doing.
if strings.HasPrefix(v1, develPrefix) || strings.HasPrefix(v2, develPrefix) {
return true
}
return semver.MajorMinor(v1) == semver.MajorMinor(v2)
}
// ExternalURL returns a URL referencing the current Coder version.
// For production builds, this will link directly to a release.
// For development builds, this will link to a commit.
-67
View File
@@ -1,7 +1,6 @@
package buildinfo_test
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
@@ -30,70 +29,4 @@ func TestBuildInfo(t *testing.T) {
_, valid := buildinfo.Time()
require.False(t, valid)
})
t.Run("VersionsMatch", func(t *testing.T) {
t.Parallel()
type testcase struct {
name string
v1 string
v2 string
expectMatch bool
}
cases := []testcase{
{
name: "OK",
v1: "v1.2.3",
v2: "v1.2.3",
expectMatch: true,
},
// Test that we return true if a developer version is detected.
// Developers do not need to be warned of mismatched versions.
{
name: "DevelIgnored",
v1: "v0.0.0-devel+123abac",
v2: "v1.2.3",
expectMatch: true,
},
// Our CI instance uses a "-devel" prerelease
// flag. This is not the same as a developer WIP build.
{
name: "DevelPreleaseNotIgnored",
v1: "v1.1.1-devel+123abac",
v2: "v1.2.3",
expectMatch: false,
},
{
name: "MajorMismatch",
v1: "v1.2.3",
v2: "v0.1.2",
expectMatch: false,
},
{
name: "MinorMismatch",
v1: "v1.2.3",
v2: "v1.3.2",
expectMatch: false,
},
// Different patches are ok, breaking changes are not allowed
// in patches.
{
name: "PatchMismatch",
v1: "v1.2.3+hash.whocares",
v2: "v1.2.4+somestuff.hm.ok",
expectMatch: true,
},
}
for _, c := range cases {
c := c
t.Run(c.name, func(t *testing.T) {
t.Parallel()
require.Equal(t, c.expectMatch, buildinfo.VersionsMatch(c.v1, c.v2),
fmt.Sprintf("expected match=%v for version %s and %s", c.expectMatch, c.v1, c.v2),
)
})
}
})
}
-9
View File
@@ -67,15 +67,6 @@ func login() *cobra.Command {
}
client := codersdk.New(serverURL)
// Try to check the version of the server prior to logging in.
// It may be useful to warn the user if they are trying to login
// on a very old client.
err = checkVersions(cmd, client)
if err != nil {
return xerrors.Errorf("check versions: %w", err)
}
hasInitialUser, err := client.HasFirstUser(cmd.Context())
if err != nil {
return xerrors.Errorf("has initial user: %w", err)
+3 -64
View File
@@ -4,13 +4,11 @@ import (
"fmt"
"net/url"
"os"
"strconv"
"strings"
"time"
"golang.org/x/xerrors"
"github.com/charmbracelet/lipgloss"
"github.com/kirsle/configdir"
"github.com/mattn/go-isatty"
"github.com/spf13/cobra"
@@ -42,13 +40,7 @@ const (
varForceTty = "force-tty"
notLoggedInMessage = "You are not logged in. Try logging in using 'coder login <url>'."
noVersionCheckFlag = "no-version-warning"
envNoVersionCheck = "CODER_NO_VERSION_WARNING"
)
var (
errUnauthenticated = xerrors.New(notLoggedInMessage)
envSessionToken = "CODER_SESSION_TOKEN"
envSessionToken = "CODER_SESSION_TOKEN"
)
func init() {
@@ -61,37 +53,12 @@ func init() {
}
func Root() *cobra.Command {
var varSuppressVersion bool
cmd := &cobra.Command{
Use: "coder",
SilenceErrors: true,
SilenceUsage: true,
Long: `Coder — A tool for provisioning self-hosted development environments.
`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if varSuppressVersion {
return nil
}
// Login handles checking the versions itself since it
// has a handle to an unauthenticated client.
if cmd.Name() == "login" {
return nil
}
client, err := createClient(cmd)
// If the client is unauthenticated we can ignore the check.
// The child commands should handle an unauthenticated client.
if xerrors.Is(err, errUnauthenticated) {
return nil
}
if err != nil {
return xerrors.Errorf("create client: %w", err)
}
return checkVersions(cmd, client)
},
Example: ` Start a Coder server.
` + cliui.Styles.Code.Render("$ coder server") + `
@@ -130,7 +97,6 @@ func Root() *cobra.Command {
cmd.SetUsageTemplate(usageTemplate())
cmd.PersistentFlags().String(varURL, "", "Specify the URL to your deployment.")
cliflag.BoolVarP(cmd.PersistentFlags(), &varSuppressVersion, noVersionCheckFlag, "", envNoVersionCheck, false, "Suppress warning when client and server versions do not match.")
cliflag.String(cmd.PersistentFlags(), varToken, "", envSessionToken, "", fmt.Sprintf("Specify an authentication token. For security reasons setting %s is preferred.", envSessionToken))
cliflag.String(cmd.PersistentFlags(), varAgentToken, "", "CODER_AGENT_TOKEN", "", "Specify an agent authentication token.")
_ = cmd.PersistentFlags().MarkHidden(varAgentToken)
@@ -176,7 +142,7 @@ func createClient(cmd *cobra.Command) (*codersdk.Client, error) {
if err != nil {
// If the configuration files are absent, the user is logged out
if os.IsNotExist(err) {
return nil, errUnauthenticated
return nil, xerrors.New(notLoggedInMessage)
}
return nil, err
}
@@ -191,7 +157,7 @@ func createClient(cmd *cobra.Command) (*codersdk.Client, error) {
if err != nil {
// If the configuration files are absent, the user is logged out
if os.IsNotExist(err) {
return nil, errUnauthenticated
return nil, xerrors.New(notLoggedInMessage)
}
return nil, err
}
@@ -365,30 +331,3 @@ func FormatCobraError(err error, cmd *cobra.Command) string {
helpErrMsg := fmt.Sprintf("Run '%s --help' for usage.", cmd.CommandPath())
return cliui.Styles.Error.Render(err.Error() + "\n" + helpErrMsg)
}
func checkVersions(cmd *cobra.Command, client *codersdk.Client) error {
flag := cmd.Flag("no-version-warning")
if suppress, _ := strconv.ParseBool(flag.Value.String()); suppress {
return nil
}
clientVersion := buildinfo.Version()
info, err := client.BuildInfo(cmd.Context())
if err != nil {
return xerrors.Errorf("build info: %w", err)
}
fmtWarningText := `version mismatch: client %s, server %s
download the server version with: 'curl -L https://coder.com/install.sh | sh -s -- --version %s'
`
if !buildinfo.VersionsMatch(clientVersion, info.Version) {
warn := cliui.Styles.Warn.Copy().Align(lipgloss.Left)
// Trim the leading 'v', our install.sh script does not handle this case well.
_, _ = fmt.Fprintf(cmd.OutOrStdout(), warn.Render(fmtWarningText), clientVersion, info.Version, strings.TrimPrefix(info.CanonicalVersion(), "v"))
_, _ = fmt.Fprintln(cmd.OutOrStdout())
}
return nil
}
-12
View File
@@ -4,9 +4,6 @@ import (
"context"
"encoding/json"
"net/http"
"strings"
"golang.org/x/mod/semver"
)
// BuildInfoResponse contains build information for this instance of Coder.
@@ -19,15 +16,6 @@ type BuildInfoResponse struct {
Version string `json:"version"`
}
// CanonicalVersion trims build information from the version.
// E.g. 'v0.7.4-devel+11573034' -> 'v0.7.4'.
func (b BuildInfoResponse) CanonicalVersion() string {
// We do a little hack here to massage the string into a form
// that works well with semver.
trimmed := strings.ReplaceAll(b.Version, "-devel+", "+devel-")
return semver.Canonical(trimmed)
}
// BuildInfo returns build information for this instance of Coder.
func (c *Client) BuildInfo(ctx context.Context) (BuildInfoResponse, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/buildinfo", nil)
+1 -1
View File
@@ -36,7 +36,7 @@ export interface AzureInstanceIdentityToken {
readonly encoding: string
}
// From codersdk/buildinfo.go:13:6
// From codersdk/buildinfo.go:10:6
export interface BuildInfoResponse {
readonly external_url: string
readonly version: string