Skip to content

Commit c810a57

Browse files
committed
Handle extensions as a bundle
1 parent 83f6453 commit c810a57

File tree

8 files changed

+199
-47
lines changed

8 files changed

+199
-47
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@
1818
main
1919

2020
bedrock-cli_*_*
21+
build

cmd/bundle_install.go

+66-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package cmd
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"github.com/bedrock-env/bedrock-cli/extensions"
7+
"github.com/bedrock-env/bedrock-cli/helpers"
68
"github.com/spf13/cobra"
79
"io/ioutil"
10+
"os"
811
"path/filepath"
9-
"strings"
1012
)
1113

1214
var OverwriteFiles bool
@@ -16,31 +18,85 @@ var installCmd = &cobra.Command{
1618
Short: "Install the Bedrock extension bundle",
1719
Long: "Install the Bedrock extensions listed in the bundle file",
1820
Run: func(cmd *cobra.Command, args []string) {
19-
bundle := LoadBundle()
21+
BundleInstall()
22+
},
23+
}
24+
25+
func BundleInstall() {
26+
RemoveOldBundle()
27+
EnsureBundleDir()
28+
29+
desiredBundle := LoadBundle()
30+
31+
var bundle []extensions.Extension
32+
33+
for _, e := range desiredBundle {
34+
result := e.Install(extensions.InstallOptions{OverwriteFiles: OverwriteFiles, BedrockDir: helpers.BedrockDir })
2035

21-
for _, e := range bundle {
22-
e.Install(extensions.InstallOptions{OverwriteFiles: OverwriteFiles, BedrockDir: BedrockDir })
36+
if result {
37+
bundle = append(bundle, e)
2338
}
24-
},
39+
}
40+
41+
var bundleData string
42+
for _, e := range bundle {
43+
bundleData = fmt.Sprintf("%s%s\n", bundleData, e.BasePath)
44+
}
45+
46+
ioutil.WriteFile(filepath.Join(helpers.BedrockDir, "bundle", "load"), []byte(bundleData), 0744)
2547
}
2648

2749
func LoadBundle() []extensions.Extension {
28-
b, err := ioutil.ReadFile(filepath.Join(BedrockDir, "bundle"))
50+
data, err := ioutil.ReadFile(filepath.Join(helpers.BedrockDir, "bundle.json"))
2951
if err != nil {
3052
fmt.Println(err)
53+
os.Exit(1)
3154
}
3255

33-
bundleList := strings.Split(strings.TrimSpace(string(b)), "\n")
34-
var bundle []extensions.Extension
56+
var bundleConfig []map[string]string
57+
json.Unmarshal([]byte(data), &bundleConfig)
3558

36-
for _, e := range bundleList {
37-
extension := extensions.Extension{ Name: e }.Load(packageManager)
59+
fmt.Println(bundleConfig)
60+
var bundle []extensions.Extension
61+
for _, element := range bundleConfig {
62+
fmt.Println(element)
63+
extension := extensions.Extension{
64+
Name: element["name"],
65+
Branch: element["branch"],
66+
Git: element["git"],
67+
Tag: element["tag"],
68+
Ref: element["ref"],
69+
Path: element["path"],
70+
}.Load(packageManager, extensions.InstallOptions{BedrockDir: helpers.BedrockDir })
3871
bundle = append(bundle, extension)
3972
}
4073

74+
fmt.Println(bundle)
4175
return bundle
4276
}
4377

78+
func RemoveOldBundle() {
79+
bundlePath := filepath.Join(helpers.BedrockDir, "bundle")
80+
81+
if !helpers.Exists(bundlePath) {
82+
return
83+
}
84+
85+
err := os.RemoveAll(bundlePath)
86+
if err != nil {
87+
fmt.Println("Unable to remove old bundle at", bundlePath)
88+
fmt.Println(err)
89+
os.Exit(1)
90+
}
91+
}
92+
func EnsureBundleDir() {
93+
bundlePath := filepath.Join(helpers.BedrockDir, "bundle")
94+
95+
if !helpers.Exists(bundlePath) {
96+
_ = os.Mkdir(bundlePath, 0744)
97+
}
98+
}
99+
44100
func init() {
45101
bundleCmd.AddCommand(installCmd)
46102
installCmd.PersistentFlags().BoolVar(&OverwriteFiles, "overwrite",

cmd/root.go

+13-26
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ const configFileName string = ".bedrock.json"
1414
const minZSHVersion = "5.0"
1515

1616
var packageManager string
17-
var BedrockDir string
1817

1918
// rootCmd represents the base command when called without any subcommands
2019
var rootCmd = &cobra.Command{
@@ -26,23 +25,23 @@ examples and usage of using your application. For example:
2625
Cobra is a CLI library for Go that empowers applications.
2726
This application is a tool to generate the needed files
2827
to quickly create a Cobra application.`,
29-
// Uncomment the following line if your bare application
30-
// has an action associated with it:
31-
//Run: func(cmd *cobra.Command, args []string) {
32-
// // viper.Set("param1", "value1")
33-
// fmt.Println("Pkg Manager:", packageManager)
34-
// fmt.Println("author:", author)
35-
// //package_managers.InstallPackage("foo")
36-
// // package_manager_provider.InstallPackages("foo")
37-
//},
3828
}
3929

4030
// Execute adds all child commands to the root command and sets flags appropriately.
4131
// This is called by main.main(). It only needs to happen once to the rootCmd.
4232
func Execute() {
4333
var configPath = filepath.Join(helpers.Home, configFileName)
4434

45-
if firstRun(configPath) {
35+
checkFirstRun(configPath)
36+
37+
if err := rootCmd.Execute(); err != nil {
38+
fmt.Println(err)
39+
os.Exit(1)
40+
}
41+
}
42+
43+
func checkFirstRun(configPath string) {
44+
if !helpers.Exists(configPath) {
4645
fmt.Println("It looks like this might be the first time Bedrock has been run.")
4746
fmt.Print("Checking Bedrock requirements...\n\n")
4847
if !meetRequirements() {
@@ -52,11 +51,6 @@ func Execute() {
5251
}
5352

5453
viper.WriteConfigAs(configPath)
55-
56-
if err := rootCmd.Execute(); err != nil {
57-
fmt.Println(err)
58-
os.Exit(1)
59-
}
6054
}
6155

6256
func init() {
@@ -65,7 +59,8 @@ func init() {
6559
rootCmd.PersistentFlags().StringVar(&packageManager, "package-manager", helpers.DefaultPkgManager(), "Desired package manager")
6660
viper.BindPFlag("package-manager", rootCmd.PersistentFlags().Lookup("package-manager"))
6761

68-
rootCmd.PersistentFlags().StringVar(&BedrockDir, "bedrockdir", filepath.Join(helpers.Home, ".bedrock"), "The Bedrock base directory")
62+
// NOTE: Not everything reads from this yet
63+
rootCmd.PersistentFlags().StringVar(&helpers.BedrockDir, "bedrockdir", filepath.Join(helpers.Home, ".bedrock"), "The Bedrock base directory")
6964
viper.BindPFlag("bedrockdir", rootCmd.PersistentFlags().Lookup("bedrockdir"))
7065
}
7166

@@ -84,7 +79,7 @@ func meetRequirements() bool {
8479

8580
func zshDetected() bool {
8681
detected := false
87-
result, err := helpers.ExecuteInShell("zsh", "echo $ZSH_VERSION")
82+
result, err := helpers.ExecuteCommandInShell("zsh", "echo $ZSH_VERSION")
8883

8984
if err == nil {
9085
zshVersion, _ := version.NewVersion(result)
@@ -99,12 +94,4 @@ func zshDetected() bool {
9994
fmt.Printf("%s\u0078%s ZSH %s was not detected\n", helpers.ColorRed, helpers.ColorReset, minZSHVersion)
10095

10196
return detected
102-
}
103-
104-
//func checkPackageManager() {
105-
//
106-
//}
107-
108-
func firstRun(configPath string) bool {
109-
return !helpers.Exists(configPath)
11097
}

cmd/version.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,11 @@ package cmd
1717

1818
import (
1919
"fmt"
20-
2120
"github.com/spf13/cobra"
2221
)
2322

2423
const VERSION = "0.0.1"
2524

26-
// versionCmd represents the version command
2725
var versionCmd = &cobra.Command{
2826
Use: "version",
2927
Short: "A brief description of your command",
@@ -34,7 +32,7 @@ Cobra is a CLI library for Go that empowers applications.
3432
This application is a tool to generate the needed files
3533
to quickly create a Cobra application.`,
3634
Run: func(cmd *cobra.Command, args []string) {
37-
fmt.Println("Bedrock", VERSION)
35+
fmt.Fprintln(cmd.OutOrStdout(), "Bedrock", VERSION)
3836
},
3937
}
4038

cmd/version_test.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package cmd
2+
3+
import (
4+
"bytes"
5+
"io"
6+
"os"
7+
"strings"
8+
"testing"
9+
10+
"github.com/spf13/cobra"
11+
)
12+
13+
var out io.Writer = os.Stdout
14+
15+
func TestVersion(t *testing.T) {
16+
out, err := executeCommand(rootCmd, "version")
17+
18+
if err != nil {
19+
t.Fatal(err)
20+
}
21+
22+
result := strings.TrimSpace(string(out))
23+
expected := "Bedrock " + VERSION
24+
if result != expected {
25+
t.Fatalf("expected \"%s\" got \"%s\"", expected, result)
26+
}
27+
}
28+
29+
func executeCommand(root *cobra.Command, args ...string) (output string, err error) {
30+
_, output, err = executeCommandC(root, args...)
31+
return output, err
32+
}
33+
34+
func executeCommandC(root *cobra.Command, args ...string) (c *cobra.Command, output string, err error) {
35+
buf := new(bytes.Buffer)
36+
root.SetOut(buf)
37+
root.SetErr(buf)
38+
root.SetArgs(args)
39+
40+
c, err = root.ExecuteC()
41+
42+
return c, buf.String(), err
43+
}

extensions/extension_manager.go

+56-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ import (
1414

1515
type Extension struct {
1616
Name string
17+
Git string
18+
Branch string
19+
Ref string
20+
Tag string
21+
Path string
1722
InstallSteps []InstallStep
1823
Files []File
1924
PostInstallMessages []string
@@ -70,9 +75,18 @@ type InstallOptions struct {
7075
BedrockDir string
7176
}
7277

73-
func (e Extension) Load(pkgm string) Extension {
74-
e.BasePath = filepath.Join(helpers.Home, ".bedrock", "extensions", e.Name)
78+
func (e Extension) Load(pkgm string, options InstallOptions) Extension {
79+
_ = e.GetSource(options)
80+
bundlePath := filepath.Join(helpers.Home, ".bedrock", "bundle")
81+
82+
if len(e.Path) > 0 {
83+
e.BasePath = helpers.ExpandPath(e.Path)
84+
} else {
85+
e.BasePath = filepath.Join(bundlePath, e.Name)
86+
}
87+
7588
extension := LoadManifest(e, pkgm)
89+
fmt.Print(extension)
7690

7791
return extension
7892
}
@@ -101,7 +115,7 @@ func LoadManifest(e Extension, pkgm string) Extension {
101115
return e
102116
}
103117

104-
func (e Extension) Install(options InstallOptions) {
118+
func (e Extension) Install(options InstallOptions) bool {
105119
installResult := e.RunInstallSteps(options)
106120
syncResult := e.SyncFiles(options)
107121

@@ -118,12 +132,51 @@ func (e Extension) Install(options InstallOptions) {
118132
}
119133
}
120134
fmt.Println(e.Name, "-", helpers.ColorGreen + "succeeded" + helpers.ColorReset)
135+
136+
return true
121137
} else {
122138
fmt.Println(e.Name, "-", helpers.ColorRed + "failed" + helpers.ColorReset)
123139
}
140+
141+
return false
142+
}
143+
144+
func (e Extension) GetSource(options InstallOptions) bool {
145+
if len(e.Path) > 0 {
146+
return true
147+
}
148+
149+
if e.Git == "" {
150+
e.Git = fmt.Sprintf("https://github.com/bedrock-env/%s.git", e.Name)
151+
}
152+
153+
fmt.Println("Branch", e.Branch)
154+
fmt.Println("Ref", e.Ref == "")
155+
fmt.Println("Tag", e.Tag)
156+
command := fmt.Sprintf("git -C %s clone %s %s", filepath.Join(options.BedrockDir, "bundle"), e.Git, e.Name)
157+
var checkoutTarget string
158+
159+
switch {
160+
case e.Branch != "":
161+
checkoutTarget = e.Branch
162+
case e.Ref != "":
163+
checkoutTarget = e.Ref
164+
case e.Tag != "":
165+
checkoutTarget = e.Tag
166+
}
167+
if len(checkoutTarget) > 0 {
168+
command = fmt.Sprintf("%s && git -C %s checkout %s",
169+
command,filepath.Join(options.BedrockDir, "bundle", e.Name), checkoutTarget)
170+
}
171+
172+
fmt.Println("command", command)
173+
helpers.ExecuteCommandInShell("zsh", command)
174+
175+
return false
124176
}
125177

126178
func (e Extension) RunInstallSteps(options InstallOptions) bool {
179+
fmt.Println("Install steps:", e.InstallSteps)
127180
if len(e.InstallSteps) == 0 {
128181
return true
129182
}

helpers/command.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@ import (
66
)
77

88
func ExecuteCommand(binary string, command string) (string, error) {
9-
args := strings.Split(command, " ")
10-
out, err := exec.Command(binary, args...).CombinedOutput()
9+
return ExecuteCommandWithArgs(binary, strings.Split(command, " "))
10+
}
11+
12+
func ExecuteCommandWithArgs(binary string, command []string) (string, error) {
13+
out, err := exec.Command(binary, command...).CombinedOutput()
1114

1215
return string(out), err
1316
}
1417

15-
func ExecuteInShell(shell string, command string) (string, error) {
18+
func ExecuteCommandInShell(shell string, command string) (string, error) {
1619
out, err := exec.Command(shell, "-c", command).CombinedOutput()
1720

1821
return strings.TrimSpace(string(out)), err
19-
}
22+
}

0 commit comments

Comments
 (0)