This repository has been archived by the owner on Jun 13, 2019. It is now read-only.
forked from Azure/draft-classic
-
Notifications
You must be signed in to change notification settings - Fork 1
/
create.go
158 lines (140 loc) · 4.47 KB
/
create.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
154
155
156
157
158
package main
import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/BurntSushi/toml"
log "github.com/Sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/Azure/draft/pkg/draft/draftpath"
"github.com/Azure/draft/pkg/draft/manifest"
"github.com/Azure/draft/pkg/draft/pack"
"github.com/Azure/draft/pkg/linguist"
"github.com/Azure/draft/pkg/osutil"
)
const (
createDesc = `This command transforms the local directory to be deployable via 'draft up'.
`
)
type createCmd struct {
appName string
out io.Writer
pack string
home draftpath.Home
dest string
}
func newCreateCmd(out io.Writer) *cobra.Command {
cc := &createCmd{
out: out,
}
cmd := &cobra.Command{
Use: "create [path]",
Short: "transform the local directory to be deployable to Kubernetes",
Long: createDesc,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
cc.dest = args[0]
}
return cc.run()
},
}
cc.home = draftpath.Home(homePath())
f := cmd.Flags()
f.StringVarP(&cc.appName, "app", "a", "", "name of the Helm release. By default, this is a randomly generated name")
f.StringVarP(&cc.pack, "pack", "p", "", "the named Draft starter pack to scaffold the app with")
return cmd
}
func (c *createCmd) run() error {
var err error
mfest := manifest.New()
if c.appName != "" {
mfest.Environments[manifest.DefaultEnvironmentName].Name = c.appName
}
chartExists, err := osutil.Exists(filepath.Join(c.dest, "chart"))
if err != nil {
return fmt.Errorf("there was an error checking if a chart exists: %v", err)
}
if chartExists {
// chart dir already exists, so we just tell the user that we are happily skipping the
// process.
fmt.Fprintln(c.out, "--> chart directory already exists. Ready to sail!")
return nil
}
if c.pack != "" {
// --pack was explicitly defined, so we can just lazily use that here. No detection required.
lpack := filepath.Join(c.home.Packs(), c.pack)
err = pack.CreateFrom(c.dest, lpack)
if err != nil {
return err
}
} else {
// pack detection time
packPath, err := doPackDetection(c.home.Packs(), c.out)
if err != nil {
return err
}
err = pack.CreateFrom(c.dest, packPath)
if err != nil {
return err
}
}
tomlFile := filepath.Join(c.dest, "draft.toml")
draftToml, err := os.OpenFile(tomlFile, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return err
}
defer draftToml.Close()
if err := toml.NewEncoder(draftToml).Encode(mfest); err != nil {
return fmt.Errorf("could not write metadata to draft.toml: %v", err)
}
ignoreFile := filepath.Join(c.dest, ignoreFileName)
if _, err := os.Stat(ignoreFile); os.IsNotExist(err) {
d1 := []byte("*.swp\n*.tmp\n*.temp\n.git*\n")
if err := ioutil.WriteFile(ignoreFile, d1, 0644); err != nil {
return err
}
}
fmt.Fprintln(c.out, "--> Ready to sail")
return nil
}
// doPackDetection performs pack detection across all the packs available in $(draft home)/packs in
// alphabetical order, returning the pack dirpath and any errors that occurred during the pack detection.
func doPackDetection(packHomeDir string, out io.Writer) (string, error) {
langs, err := linguist.ProcessDir(".")
log.Debugf("linguist.ProcessDir('.') result:\n\nError: %v", err)
if err != nil {
return "", fmt.Errorf("there was an error detecting the language: %s", err)
}
for _, lang := range langs {
log.Debugf("%s:\t%f (%s)", lang.Language, lang.Percent, lang.Color)
}
if len(langs) == 0 {
return "", errors.New("No languages were detected. Are you sure there's code in here?")
}
detectedLang := langs[0]
fmt.Fprintf(out, "--> Draft detected the primary language as %s with %f%% certainty.\n", detectedLang.Language, detectedLang.Percent)
// HACK(bacongobbler): the c# pack is named "csharp" so it can be used in the chart. Kubernetes
// manifests don't like hashbangs in a service's name, and a common practice is to use
// {{ template "fullname" . }} in a chart.
if strings.Compare(strings.ToLower(detectedLang.Language), "c#") == 0 {
detectedLang.Language = "csharp"
}
files, err := ioutil.ReadDir(packHomeDir)
if err != nil {
return "", fmt.Errorf("there was an error reading %s: %v", packHomeDir, err)
}
for _, file := range files {
if file.IsDir() {
if strings.Compare(strings.ToLower(detectedLang.Language), strings.ToLower(file.Name())) == 0 {
packPath := filepath.Join(packHomeDir, file.Name())
log.Debugf("pack path: %s", packPath)
return packPath, nil
}
}
}
return "", errors.New("Could not find a starter pack Q_Q")
}