Repository: Shopify/themekit
Pull request #939 (2021-06-10 13:47:51)

Add messaging Theme Kit Access messaging and flag to suppress it
The Theme Kit Access app is in beta now. When we move to GA, we want to encourage developers to make the switch by adding messaging to the Theme Kit CLI. This PR adds that message and a flag to be able to suppress it.

Part of https://github.com/Shopify/themekit-access/issues/147

### Warn Checklist
- [x] This changes the interface and requires a Major/Minor version change.
- [x] I have :tophat:'d these changes by using the commands I changed by hand.
- [ ] I have added a dependancy to the project.
- [ ] I have considered any potential impact on [node-themekit](https://github.com/Shopify/node-themekit)



Patch:
diff --git a/cmd/theme.go b/cmd/theme.go
index 73bbf25..bdca2f1 100644
--- a/cmd/theme.go
+++ b/cmd/theme.go
@@ -11,6 +11,7 @@ import (
 	"github.com/Shopify/themekit/src/colors"
 	"github.com/Shopify/themekit/src/env"
 	"github.com/Shopify/themekit/src/release"
+	"github.com/Shopify/themekit/src/util"
 )
 
 const afterUpdateMessage = `Successfully updated to theme kit version %v, for more information on this release please see the change log
@@ -42,6 +43,18 @@ Complete documentation is available at https://shopify.dev/tools/theme-kit.`,
 				colors.ColorStdOut.Print(colors.Yellow("An update for Themekit is available. To update please run `theme update`"))
 			}
 		},
+		PersistentPostRun: func(cmd *cobra.Command, args []string) {
+			// env validation requires a theme id. setting a dummy one here if not provided
+			if flags.ThemeID == "" {
+				flags.ThemeID = "1337"
+			}
+			cmdutil.ForDefaultClient(flags, args, func(ctx *cmdutil.Ctx) error {
+				if !flags.DisableThemeKitAccessNotifier && !util.IsThemeKitAccessPassword(ctx.Env.Password) {
+					colors.ColorStdOut.Print(colors.Yellow("* Build themes without private apps. Learn more about the Theme Kit Access app: https://shopify.dev/tools/theme-kit/manage-theme-kit-access"))
+				}
+				return nil
+			})
+		},
 	}
 
 	updateCmd = &cobra.Command{
@@ -89,6 +102,7 @@ func init() {
 	ThemeCmd.PersistentFlags().StringArrayVar(&flags.Ignores, "ignores", []string{}, "A path to a file that contains ignore patterns.")
 	ThemeCmd.PersistentFlags().BoolVar(&flags.DisableIgnore, "no-ignore", false, "Will disable config ignores so that all files can be changed")
 	ThemeCmd.PersistentFlags().BoolVar(&flags.AllowLive, "allow-live", false, "Will allow themekit to make changes to the live theme on the store.")
+	ThemeCmd.PersistentFlags().BoolVarP(&flags.DisableThemeKitAccessNotifier, "no-theme-kit-access-notifier", "", false, "Stop theme kit from notifying about Theme Kit Access.")
 
 	watchCmd.Flags().StringVarP(&flags.Notify, "notify", "n", "", "file to touch or url to notify when a file has been changed")
 	watchCmd.Flags().BoolVarP(&flags.AllEnvs, "allenvs", "a", false, "run command with all environments")
diff --git a/src/cmdutil/util.go b/src/cmdutil/util.go
index 6e09726..8c4e3c6 100644
--- a/src/cmdutil/util.go
+++ b/src/cmdutil/util.go
@@ -30,33 +30,34 @@ var (
 // Flags encapsulates all the possible flags that can be set in the themekit
 // command line. Some of the values are used across different commands
 type Flags struct {
-	ConfigPath            string
-	VariableFilePath      string
-	Environments          []string
-	Directory             string
-	Password              string
-	ThemeID               string
-	Domain                string
-	Proxy                 string
-	Timeout               time.Duration
-	Verbose               bool
-	DisableUpdateNotifier bool
-	IgnoredFiles          []string
-	Ignores               []string
-	DisableIgnore         bool
-	Notify                string
-	AllEnvs               bool
-	Version               string
-	Prefix                string
-	URL                   string
-	Name                  string
-	Edit                  bool
-	With                  string
-	List                  bool
-	NoDelete              bool
-	AllowLive             bool
-	Live                  bool
-	HidePreviewBar        bool
+	ConfigPath                    string
+	VariableFilePath              string
+	Environments                  []string
+	Directory                     string
+	Password                      string
+	ThemeID                       string
+	Domain                        string
+	Proxy                         string
+	Timeout                       time.Duration
+	Verbose                       bool
+	DisableUpdateNotifier         bool
+	IgnoredFiles                  []string
+	Ignores                       []string
+	DisableIgnore                 bool
+	Notify                        string
+	AllEnvs                       bool
+	Version                       string
+	Prefix                        string
+	URL                           string
+	Name                          string
+	Edit                          bool
+	With                          string
+	List                          bool
+	NoDelete                      bool
+	AllowLive                     bool
+	Live                          bool
+	HidePreviewBar                bool
+	DisableThemeKitAccessNotifier bool
 }
 
 // Ctx is a specific context that a command will run in
diff --git a/src/httpify/client.go b/src/httpify/client.go
index d024d4f..be9c001 100644
--- a/src/httpify/client.go
+++ b/src/httpify/client.go
@@ -13,10 +13,9 @@ import (
 
 	"github.com/Shopify/themekit/src/ratelimiter"
 	"github.com/Shopify/themekit/src/release"
+	"github.com/Shopify/themekit/src/util"
 )
 
-const themeKitPasswordPrefix = "shptka_"
-
 var (
 	// ErrConnectionIssue is an error that is thrown when a very specific error is
 	// returned from our http request that usually implies bad connections.
@@ -109,7 +108,7 @@ func (client *HTTPClient) do(method, path string, body interface{}, headers map[
 	appBaseURL := client.baseURL.String()
 
 	// redirect to Theme Kit Access
-	if strings.HasPrefix(client.password, themeKitPasswordPrefix) {
+	if util.IsThemeKitAccessPassword(client.password) {
 		appBaseURL = themeKitAccessURL
 	}
 
@@ -123,7 +122,7 @@ func (client *HTTPClient) do(method, path string, body interface{}, headers map[
 	req.Header.Add("Content-Type", "application/json")
 	req.Header.Add("Accept", "application/json")
 	req.Header.Add("User-Agent", fmt.Sprintf("go/themekit (%s; %s; %s)", runtime.GOOS, runtime.GOARCH, release.ThemeKitVersion.String()))
-	if strings.HasPrefix(client.password, themeKitPasswordPrefix) {
+	if util.IsThemeKitAccessPassword(client.password) {
 		req.Header.Add("X-Shopify-Shop", client.domain)
 	}
 	for label, value := range headers {
diff --git a/src/util/themekit_access.go b/src/util/themekit_access.go
new file mode 100644
index 0000000..78ad382
--- /dev/null
+++ b/src/util/themekit_access.go
@@ -0,0 +1,9 @@
+package util
+
+import "strings"
+
+// IsThemeKitAccessPassword checks if the password is a Theme Kit Access password
+func IsThemeKitAccessPassword(password string) bool {
+	themeKitPasswordPrefix := "shptka_"
+	return strings.HasPrefix(password, themeKitPasswordPrefix)
+}


Test patch:
diff --git a/src/util/themekit_access_test.go b/src/util/themekit_access_test.go
new file mode 100644
index 0000000..eeff27c
--- /dev/null
+++ b/src/util/themekit_access_test.go
@@ -0,0 +1,15 @@
+package util
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestIsThemeKitAccessPassword(t *testing.T) {
+	themeKitAccessPassword := "shptka_00000000000000000000000000000000"
+	assert.True(t, IsThemeKitAccessPassword(themeKitAccessPassword))
+
+	privateAppPassword := "shp_00000000000000000000000000000000"
+	assert.False(t, IsThemeKitAccessPassword(privateAppPassword))
+}