From a3a996d2e2431f3f39feb4efc2f90da62d094d57 Mon Sep 17 00:00:00 2001 From: Dallin Date: Sun, 3 May 2020 19:24:35 -0600 Subject: [PATCH] properly break up funcrtionality into smaller methods --- cmd/clone.go | 88 ++++++++++++++++++++++++++++++++++------------- cmd/clone_test.go | 22 ++++++++++-- cmd/root.go | 2 ++ 3 files changed, 85 insertions(+), 27 deletions(-) diff --git a/cmd/clone.go b/cmd/clone.go index 8d8ded4..2c6c0d4 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -25,6 +25,7 @@ import ( "log" "os" "os/exec" + "strings" ) // cloneCmd represents the clone command @@ -38,26 +39,47 @@ Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, Run: func(cmd *cobra.Command, args []string) { - to, _ := cmd.Flags().GetString("to") - name, _ := cmd.Flags().GetString("name") - importDatabase, _ := cmd.Flags().GetString("database") + dump_dir, _ := cmd.Flags().GetString("dump_dir") + dump_name, _ := cmd.Flags().GetString("dump_name") + databaseToCloneName, _ := cmd.Flags().GetString("from") + importDatabaseName, _ := cmd.Flags().GetString("to") - file, ferr := os.OpenFile(fmt.Sprintf("%s/%s.sql", to, name), os.O_RDWR|os.O_CREATE, 0644) + dump_name = strings.TrimRight(dump_name, ".sql") + + file, ferr := os.OpenFile(fmt.Sprintf("%s/%s.sql", dump_dir, dump_name), os.O_RDWR|os.O_CREATE, 0644) if (ferr != nil) { log.Fatalf("error opening file: %s", ferr) } - Clone(file, importDatabase, to, name) + Clone(file, databaseToCloneName, importDatabaseName, dump_dir, dump_name) file.Close() }, } -func Clone(file *os.File, importDatabase string, to string, name string) { +func Clone(file *os.File, databaseToCloneName string, importDatabaseName string, dump_dir string, dump_name string) { + fmt.Println("Cloning database") + dumpDatabase(file, databaseToCloneName) + + importDatabase(importDatabaseName, dump_dir, dump_name, file) + + fmt.Println("Cleaning up") + removeDumpFiles(dump_dir, dump_name) + + fmt.Println(fmt.Sprintf("%s successfully cloned from %s", importDatabaseName, databaseToCloneName)) +} + +func removeDumpFiles(dump_dir string, dump_name string) { + cleanup := exec.Command("rm", fmt.Sprintf("%s/%s.sql", dump_dir, dump_name), fmt.Sprintf("%s/%s.sql.bak", dump_dir, dump_name)) + + cleanup.Run() +} + +func dumpDatabase(file *os.File, databaseToCloneName string) { dump := exec.Command( "mysqldump", - fmt.Sprintf("%s", viper.GetString("database.database")), + fmt.Sprintf("%s", databaseToCloneName), fmt.Sprintf("-h%s", viper.GetString("database.host")), fmt.Sprintf("-u%s", viper.GetString("database.username")), fmt.Sprintf("-p%s", viper.GetString("database.password")), @@ -65,7 +87,9 @@ func Clone(file *os.File, importDatabase string, to string, name string) { "--databases", ) - fmt.Println(dump.String()) + if Verbose { + fmt.Println(dump.String()) + } dump.Stdout = file @@ -73,17 +97,10 @@ func Clone(file *os.File, importDatabase string, to string, name string) { if err != nil { log.Fatalln(err.Error()) } +} - replace := exec.Command( - "sed", - "-i.bak", - fmt.Sprintf("s/%s/%s/g", viper.GetString("database.database"), importDatabase), - fmt.Sprintf("%s/%s.sql", to, name), - ) - - fmt.Println(replace.String()) - - replace.Run() +func importDatabase(importDatabase string, to string, name string, file *os.File) { + replaceDatabaseName(importDatabase, to, name) importCmd := exec.Command( "mysql", @@ -93,6 +110,16 @@ func Clone(file *os.File, importDatabase string, to string, name string) { fmt.Sprintf("-P%s", viper.GetString("database.port")), ) + addDumpToStdin(importCmd, file) + + importCmd.Wait() + + if (Verbose) { + fmt.Println(importCmd.String()) + } +} + +func addDumpToStdin(importCmd *exec.Cmd, file *os.File) { stdin, err := importCmd.StdinPipe() if err != nil { log.Fatal(err) @@ -103,15 +130,27 @@ func Clone(file *os.File, importDatabase string, to string, name string) { } bytes, _ := ioutil.ReadFile(file.Name()) _, err = io.WriteString(stdin, string(bytes)) + if err != nil { log.Fatal(err) } - fmt.Println(importCmd.String()) + stdin.Close() +} + +func replaceDatabaseName(importDatabase string, to string, name string) { + replace := exec.Command( + "sed", + "-i.bak", + fmt.Sprintf("s/%s/%s/g", viper.GetString("database.database"), importDatabase), + fmt.Sprintf("%s/%s.sql", to, name), + ) - output, _ := importCmd.Output() + if Verbose { + fmt.Println(replace.String()) + } - fmt.Println(string(output)) + replace.Run() } func init() { @@ -119,7 +158,8 @@ func init() { home, _ := os.UserHomeDir() - cloneCmd.Flags().String("to", home, "Specify a directory to output the dump file") - cloneCmd.Flags().String("name", "dump", "Specify the name of the dump file") - cloneCmd.Flags().String("database", "cloned", "Specify a directory to output the dump file") + cloneCmd.Flags().String("dump_dir", home, "Specify a directory to output the dump file") + cloneCmd.Flags().String("dump_name", "dump", "Specify the name of the dump file") + cloneCmd.Flags().String("to", "cloned", "Specify name of new database") + cloneCmd.Flags().String("from", viper.GetString("database.database"), "Specify name of database to clone") } diff --git a/cmd/clone_test.go b/cmd/clone_test.go index 9d7745b..8df8f79 100644 --- a/cmd/clone_test.go +++ b/cmd/clone_test.go @@ -17,10 +17,12 @@ func TestCopyExistingDatabase(t *testing.T) { } _, err = db.Exec("drop table if exists test;") - _, err = db.Exec("drop table if exists new_db;") - _, err = db.Exec("create table test (column1 int not null, column2 int not null);") + _, err = db.Exec("drop database if exists new_db;") + _, err = db.Exec("create table test (column1 int not 1null, column2 int not null);") _, err = db.Exec("insert into test (column1, column2) VALUE (1,2);") + db.Close() + file, _ := os.OpenFile("./test_dump.sql", os.O_RDWR|os.O_CREATE, 0644) viper.Set("database.database", "original") @@ -29,7 +31,9 @@ func TestCopyExistingDatabase(t *testing.T) { viper.Set("database.password", "secret") viper.Set("database.port", "3310") - Clone(file, "new_db", ".", "test_dump") + Clone(file, "original", "new_db", ".", "test_dump") + + db, _ = sql.Open("mysql", "root:secret@tcp(localhost:3310)/") rows, _ := db.Query("Show databases") @@ -47,4 +51,16 @@ func TestCopyExistingDatabase(t *testing.T) { if (!ok) { log.Fatalln("Expected to find new_db in list of databases") } + + _, err = os.Stat("./test_dump.sql") + + if (err == nil) { + log.Fatalln("dump file was not removed") + } + + _, err = os.Stat("./test_dump.sql.bak") + + if (err == nil) { + log.Fatalln("dump backup file was not removed") + } } diff --git a/cmd/root.go b/cmd/root.go index c319e9b..a7e4e48 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -25,6 +25,7 @@ import ( ) var cfgFile string +var Verbose bool // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ @@ -58,6 +59,7 @@ func init() { // will be global for your application. rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.surgio-tools.yaml)") + rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output") // Cobra also supports local flags, which will only run // when this action is called directly.