diff --git a/README.md b/README.md index b2e0303..c1e1c6d 100644 --- a/README.md +++ b/README.md @@ -51,4 +51,4 @@ The used GitHub Action works with 2 steps: - release name - tag name - - body containing changelogs \ No newline at end of file + - body containing changelogs diff --git a/bundles/authenticator/authenticator.go b/bundles/authenticator/authenticator.go index ae1e132..7f68899 100644 --- a/bundles/authenticator/authenticator.go +++ b/bundles/authenticator/authenticator.go @@ -3,6 +3,7 @@ package authenticator import ( "github.com/dgrijalva/jwt-go" ) + type authenticatorInterface interface { GenerateToken(string) (error, string) DecodeToken(string) @@ -16,4 +17,10 @@ type Claim struct { } // Authenticator is the struct for the authenticator bundle -type Authenticator struct {} +type Authenticator struct{} + +// New returns a new authenticator value +func New() Authenticator { + auth := Authenticator{} + return auth +} diff --git a/bundles/authenticator/install.sh b/bundles/authenticator/install.sh new file mode 100644 index 0000000..d6fd8ba --- /dev/null +++ b/bundles/authenticator/install.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +go get -u github.com/edwinvautier/go-cli +go mod tidy \ No newline at end of file diff --git a/templates/shared/middlewares/authorization_middleware.go.template b/bundles/authenticator/templates/api/middlewares/authorization_middleware.go.template similarity index 100% rename from templates/shared/middlewares/authorization_middleware.go.template rename to bundles/authenticator/templates/api/middlewares/authorization_middleware.go.template diff --git a/cmd/install.go b/cmd/install.go new file mode 100644 index 0000000..df01f49 --- /dev/null +++ b/cmd/install.go @@ -0,0 +1,40 @@ +package cmd +/* +Copyright © 2021 NAME HERE + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import ( + "github.com/edwinvautier/go-cli/services/installCommand" + log "github.com/sirupsen/logrus" + "github.com/spf13/cobra" +) + +// installCmd represents the install command +var installCmd = &cobra.Command{ + Use: "install", + Short: "Install bundles to your app", + Long: `A command that install bundles from edwinvautier/go-cli/bundles`, + Run: func(cmd *cobra.Command, args []string) { + for _, bundleName := range args { + if err := installCommand.InstallBundle(bundleName); err != nil { + log.Error(err) + } + } + }, +} + +func init() { + rootCmd.AddCommand(installCmd) +} diff --git a/cmd/root.go b/cmd/root.go index 75aa3de..81379f1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -94,4 +94,4 @@ func createConfig(homeDir string) { log.Error("Couldn't create config file : ", err) } initConfig() -} \ No newline at end of file +} diff --git a/config/create_command.go b/config/create_command.go index cdcf55c..974fd16 100644 --- a/config/create_command.go +++ b/config/create_command.go @@ -70,5 +70,5 @@ type CreateCmdConfig struct { Args []string Box *packr.Box ProjectPath string - AuthModule bool + AuthModule bool } diff --git a/config/install_command.go b/config/install_command.go new file mode 100644 index 0000000..97bf8c2 --- /dev/null +++ b/config/install_command.go @@ -0,0 +1,50 @@ +package config + +import ( + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" + "os" +) + +// InitInstallCmdConfig creates the needed config for the create command by prompting user and doing other actions +func InitInstallCmdConfig(config *InstallCmdConfig) error { + workdir, err := os.Getwd() + if err != nil { + return err + } + viper.AddConfigPath(workdir) + viper.SetConfigName(".go-cli-config") + if err := viper.ReadInConfig(); err != nil { + return err + } + + config.GoPackageFullPath = viper.GetString("package") + + return nil +} + +// UpdateConfigAfterInstalling set the new bundle to true in config after install +func UpdateConfigAfterInstalling(name string) error { + workdir, err := os.Getwd() + + if err != nil { + return err + } + + viper.AddConfigPath(workdir) + viper.SetConfigName(".go-cli-config") + viper.Set("bundles."+name, true) + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + log.Info("Using config file : ", viper.ConfigFileUsed()) + viper.WriteConfig() + return nil + } + + return err +} + +// InstallCmdConfig is the struct for the templates config of install command +type InstallCmdConfig struct { + GoPackageFullPath string +} diff --git a/services/createCommand/clean_files.go b/services/createCommand/clean_files.go index a8424ae..7430129 100644 --- a/services/createCommand/clean_files.go +++ b/services/createCommand/clean_files.go @@ -8,18 +8,12 @@ import ( // CleanAllFiles removed all files that are not necessary as the user chose in the config func CleanAllFiles(config *config.CreateCmdConfig) error { - if (!config.UseDocker) { + if !config.UseDocker { if err := removeDockerFiles(config); err != nil { log.Error("Could'nt remove docker files", err) } } - if (!config.AuthModule) { - if err := removeAuthenticationFiles(config); err != nil { - log.Error("Couldn't remove authentication module files", err) - } - } - return nil } @@ -28,7 +22,7 @@ func removeDockerFiles(config *config.CreateCmdConfig) error { if err := filesystem.RemoveDirAndFiles(config.ProjectPath + "/docker"); err != nil { return err } - + if err := filesystem.RemoveSingle(config.ProjectPath + "/docker"); err != nil { return err } @@ -55,4 +49,4 @@ func removeAuthenticationFiles(config *config.CreateCmdConfig) error { // Remove token service return filesystem.RemoveSingle(config.ProjectPath + "/shared/services/password_hasher.go") -} \ No newline at end of file +} diff --git a/services/createCommand/init_project.go b/services/createCommand/init_project.go index b32eb2b..fb59b07 100644 --- a/services/createCommand/init_project.go +++ b/services/createCommand/init_project.go @@ -27,7 +27,7 @@ func InitProject(config *config.CreateCmdConfig) error { } log.Info("git initialized") - createProjectConfig(workingDirectory + "/" + config.AppName, config) + createProjectConfig(workingDirectory+"/"+config.AppName, config) if err := generateTemplates(*config); err != nil { return err @@ -73,9 +73,9 @@ func createProjectConfig(workdir string, config *config.CreateCmdConfig) { // Set config defaults viper.Set("package", config.GoPackageFullPath) - viper.Set("database", config.DBMS); - viper.Set("use_docker", config.UseDocker); - viper.SetDefault("modules.auth-module", false); + viper.Set("database", config.DBMS) + viper.Set("use_docker", config.UseDocker) + viper.SetDefault("bundles.authenticator", false) viper.AutomaticEnv() // read in environment variables that match @@ -84,4 +84,4 @@ func createProjectConfig(workdir string, config *config.CreateCmdConfig) { log.Info("Using config file : ", viper.ConfigFileUsed()) } viper.WriteConfig() -} \ No newline at end of file +} diff --git a/services/filesystem/filesystem.go b/services/filesystem/filesystem.go index d2e38cf..6130f19 100644 --- a/services/filesystem/filesystem.go +++ b/services/filesystem/filesystem.go @@ -19,4 +19,4 @@ func RemoveDirAndFiles(path string) error { // RemoveSingle removes a single resource from filesystem, file or directory func RemoveSingle(path string) error { return os.Remove(path) -} \ No newline at end of file +} diff --git a/services/installCommand/install_bundle.go b/services/installCommand/install_bundle.go new file mode 100644 index 0000000..d9717ad --- /dev/null +++ b/services/installCommand/install_bundle.go @@ -0,0 +1,46 @@ +package installCommand + +import ( + "errors" + "strings" + + "github.com/edwinvautier/go-cli/config" + "github.com/gobuffalo/packr/v2" +) + +// InstallBundle install bundle from its name +func InstallBundle(name string) error { + var installCmdConfig config.InstallCmdConfig + config.InitInstallCmdConfig(&installCmdConfig) + box := packr.New("Bundles", "../../bundles") + + if !bundleExists(name, box) { + return errors.New(name + " bundle does not exist") + } + + // execute templates + if err := executeTemplates(name, installCmdConfig); err != nil { + return err + } + + // if it exists, execute the shell script it contains + if err := executeInstallScript(box, name); err != nil { + return err + } + + // load & update config + return config.UpdateConfigAfterInstalling(name) +} + +func bundleExists(name string, box *packr.Box) bool { + files := box.List() + + for _, file := range files { + bundleName := strings.Split(file, "/")[0] + if bundleName == name { + return true + } + } + + return false +} diff --git a/services/installCommand/run_install_script.go b/services/installCommand/run_install_script.go new file mode 100644 index 0000000..594f63d --- /dev/null +++ b/services/installCommand/run_install_script.go @@ -0,0 +1,28 @@ +package installCommand + +import ( + "io/ioutil" + "os" + "os/exec" + + "github.com/edwinvautier/go-cli/services/filesystem" + "github.com/gobuffalo/packr/v2" +) + +func executeInstallScript(box *packr.Box, name string) error { + workdir, err := os.Getwd() + + if err != nil { + return err + } + + fileString, err := box.FindString("/" + name + "/install.sh") + if err != nil { + return err + } + + ioutil.WriteFile(workdir+"/install.sh", []byte(fileString), 0755) + exec.Command("sh", "install.sh").Run() + + return filesystem.RemoveSingle(workdir + "/install.sh") +} diff --git a/services/installCommand/template.go b/services/installCommand/template.go new file mode 100644 index 0000000..2cdd6d7 --- /dev/null +++ b/services/installCommand/template.go @@ -0,0 +1,62 @@ +package installCommand + +import ( + "os" + + "github.com/edwinvautier/go-cli/config" + "github.com/edwinvautier/go-cli/helpers" + "github.com/gobuffalo/packd" + "github.com/gobuffalo/packr/v2" + log "github.com/sirupsen/logrus" + "text/template" +) + +func executeTemplates(name string, installCmdConfig config.InstallCmdConfig) error { + box := packr.New("templates", "../../bundles/"+name+"/templates") + + box.Walk(func(path string, f packd.File) error { + fInfo, _ := f.FileInfo() + fileParts := helpers.GetFilePartsFromName(fInfo.Name()) + generateFile(fileParts.Path, fileParts.Name, fileParts.OutputName, installCmdConfig, box) + return nil + }) + + return nil +} + +func generateFile(path string, name string, outputName string, installCmdConfig config.InstallCmdConfig, box *packr.Box) { + // Get template content as string + templateString, err := box.FindString(path + name) + if err != nil { + log.Error(err) + return + } + workdir, err := os.Getwd() + if err != nil { + log.Error(err) + } + // Create the directory if not exist + if _, err := os.Stat(workdir + "/" + path); os.IsNotExist(err) { + os.MkdirAll(workdir+"/"+path, os.ModePerm) + } + + err = executeTemplate(installCmdConfig, outputName, workdir+"/"+path, templateString) + if err != nil { + log.Error(err) + return + } +} + +func executeTemplate(installCmdConfig config.InstallCmdConfig, outputName string, path string, templateString string) error { + // Create the file + file, err := os.Create(path + outputName) + if err != nil { + log.Error(err) + return err + } + // Execute template and write file + parsedTemplate := template.Must(template.New("template").Parse(templateString)) + err = parsedTemplate.Execute(file, installCmdConfig) + + return nil +}