summaryrefslogtreecommitdiff
path: root/novactl/cmd/init.go
blob: 084c2daa0ce9f948b216699ca63f5ba86fcf57f0 (plain)
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
package cmd

import (
	"fmt"
	"github.com/go-git/go-git/v5/config"
	"github.com/rs/zerolog/log"
	"io/fs"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/go-git/go-git/v5"
	"github.com/spf13/cobra"
)

var (
	InitializeCommand         = createInitCommand()
	Flavour           *string = nil
	Name              *string = nil
)

func createInitCommand() *cobra.Command {
	command := cobra.Command{
		Use:   "init [path]",
		Short: "Initialize a new nova based project",
		Run:   initNovaRepo,
	}

	Flavour = command.Flags().String("flavour", "javascript", "the flavour of template to use")
	Name = command.Flags().String("name", "", "the name of the project")

	return &command
}

func determineTemplate() string {
	if strings.HasPrefix(*Flavour, "http") || strings.HasPrefix(*Flavour, "ssh") {
		return *Flavour
	} else {
		return fmt.Sprintf("https://github.com/discordnova/template-%s.git", *Flavour)
	}
}

func initNovaRepo(cmd *cobra.Command, args []string) {

	url := determineTemplate()
	if len(args) == 0 {
		log.Error().Msg("A path must be specified")
		os.Exit(1)
	}

	path := strings.Join(args, " ")
	name := path

	// if the user specified a name different from the folder name
	if *Name != "" {
		name = *Name
	}

	cw, err := os.Getwd()
	if err != nil {
		return
	}
	// we get the absolute path of the folder
	path = filepath.Join(cw, path)
	log.Info().Msgf("Initializing a %s at %s using template %s", name, path, url)

	// clone the repo
	_, err = git.PlainClone(path, false, &git.CloneOptions{
		URL: url,
	})

	if err != nil {
		log.Err(err).Msg("Failed to initialize the repository")
		os.Exit(1)
	}

	log.Info().Msg("Successfully cloned the template")

	// replace all the instances of "%PROJECT%" with the project name
	err = filepath.WalkDir(path, func(path string, d fs.DirEntry, err error) error {
		if d.IsDir() || err != nil {
			return nil
		}

		read, err := ioutil.ReadFile(path)
		if err != nil {

		}
		content := strings.ReplaceAll(string(read), "%PROJECT%", name)

		err = ioutil.WriteFile(path, []byte(content), 0)

		if err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		log.Err(err).Msgf("Failed to bootstrap the project")
		// we try to remove the folder
		_ = os.Remove(path)
		os.Exit(1)
	}
	// we remove the git folder
	err = os.RemoveAll(filepath.Join(path, ".git"))

	repo, err := git.PlainInit(path, false)
	if err != nil {
		log.Err(err).Msgf("Failed to initialize the git repository")
		os.Exit(1)
	}

	err = repo.CreateBranch(&config.Branch{
		Name: "main",
	})
	if err != nil {
		log.Err(err).Msgf("Failed to create the main branch")
		os.Exit(1)
	}

	tree, err := repo.Worktree()
	if err != nil {
		log.Err(err).Msgf("Failed to get worktree")
		os.Exit(1)
	}
	_, err = tree.Add(".")
	if err != nil {
		log.Err(err).Msgf("Failed to index the files")
		os.Exit(1)
	}
	_, err = tree.Commit("first commit", &git.CommitOptions{})
	if err != nil {
		log.Err(err).Msgf("Failed to index the first commit")
		os.Exit(1)
	}

	log.Info().Msgf("Created a new repository at %", path)
}