-
Notifications
You must be signed in to change notification settings - Fork 366
/
bootstrap.go
153 lines (125 loc) · 3.17 KB
/
bootstrap.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package cmd
import (
"fmt"
"net/http"
"strings"
"github.com/spf13/cobra"
"github.com/Shopify/themekit/cmd/internal/atom"
"github.com/Shopify/themekit/kit"
)
const (
masterBranch = "master"
latestRelease = "latest"
)
var (
themeZipRoot = "https://github.com/Shopify/Timber/archive/"
timberFeedPath = "https://github.com/Shopify/Timber/releases.atom"
)
var bootstrapCmd = &cobra.Command{
Use: "bootstrap",
Short: "Bootstrap a new theme using Shopify Timber",
Long: `Bootstrap will download the latest release of Timber,
The most popular theme on Shopify. Bootstrap will also setup
your config file and create a new theme id for you.
For more documentation please see http://shopify.github.io/themekit/commands/#bootstrap
`,
RunE: func(cmd *cobra.Command, args []string) error {
setFlagConfig()
return bootstrap()
},
}
func bootstrap() error {
zipLocation, err := getZipPath()
if err != nil {
return err
}
themeName := getThemeName()
if verbose {
kit.Printf(
"Attempting to create theme %s from %s",
kit.YellowText(themeName),
kit.YellowText(zipLocation),
)
}
client, theme, err := kit.CreateTheme(themeName, zipLocation)
if err != nil {
return err
}
if err := saveConfiguration(client.Config); err != nil {
return err
}
if verbose {
kit.Printf(
"Successfully created theme '%s' with id of %s on shop %s",
kit.BlueText(theme.Name),
kit.BlueText(theme.ID),
kit.YellowText(client.Config.Domain),
)
}
return download(client, []string{})
}
func getZipPath() (string, error) {
if bootstrapURL != "" {
return bootstrapURL, nil
}
return zipPathForVersion(bootstrapVersion)
}
func getThemeName() string {
if bootstrapName != "" {
return bootstrapName
}
if bootstrapURL != "" {
parts := strings.Split(bootstrapURL, "/")
return bootstrapPrefix + strings.Replace(parts[len(parts)-1], ".zip", "", 1)
}
return bootstrapPrefix + "Timber-" + bootstrapVersion
}
func zipPathForVersion(version string) (string, error) {
if version == masterBranch {
return zipPath(masterBranch), nil
}
feed, err := downloadAtomFeed()
if err != nil {
return "", err
}
entry, err := findReleaseWith(feed, version)
if err != nil {
return "", err
}
return zipPath(entry.Title), nil
}
func zipPath(version string) string {
return themeZipRoot + version + ".zip"
}
func downloadAtomFeed() (atom.Feed, error) {
resp, err := http.Get(timberFeedPath)
if err != nil {
return atom.Feed{}, err
}
defer resp.Body.Close()
feed, err := atom.LoadFeed(resp.Body)
if err != nil {
return atom.Feed{}, err
}
return feed, nil
}
func findReleaseWith(feed atom.Feed, version string) (atom.Entry, error) {
if version == latestRelease {
return feed.LatestEntry(), nil
}
for _, entry := range feed.Entries {
if entry.Title == version {
return entry, nil
}
}
return atom.Entry{Title: "Invalid Feed"}, buildInvalidVersionError(feed, version)
}
func buildInvalidVersionError(feed atom.Feed, version string) error {
entries := []string{"master", "latest"}
for _, entry := range feed.Entries {
entries = append(entries, entry.Title)
}
return fmt.Errorf(`invalid Timber Version: %s
Available Versions Are:
- %s`, version, strings.Join(entries, "\n- "))
}