From 007e366cc5c0a73e29b5a2cdb24aed35ef0bc912 Mon Sep 17 00:00:00 2001 From: Alexis Viscogliosi Date: Wed, 11 Dec 2024 18:03:20 +0100 Subject: [PATCH] fix: main options to amigo options --- cmd/init.go | 126 +++++++++++++++++++++++------------------ pkg/amigo/amigo.go | 3 + pkg/entrypoint/main.go | 20 +------ pkg/entrypoint/root.go | 7 +-- pkg/utils/files.go | 28 +++++++++ 5 files changed, 106 insertions(+), 78 deletions(-) diff --git a/cmd/init.go b/cmd/init.go index ad0bd6c..a916abd 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -36,70 +36,86 @@ func executeInit( am := amigo.NewAmigo(cfg) - err = am.GenerateMainFile(file) - if err != nil { - return err - } + if !utils.IsFileExists(mainFilePath) { + err = am.GenerateMainFile(file) + if err != nil { + return err + } - logger.Info(events.FileAddedEvent{FileName: mainFilePath}) + logger.Info(events.FileAddedEvent{FileName: mainFilePath}) + } - // create the base schema version table now := time.Now() migrationFileName := fmt.Sprintf("%s_create_table_schema_version.go", now.UTC().Format(utils.FormatTime)) - file, err = utils.CreateOrOpenFile(path.Join(cfg.MigrationFolder, migrationFileName)) - if err != nil { - return fmt.Errorf("unable to open migrationsFolder.go file: %w", err) - } - inUp, err := templates.GetInitCreateTableTemplate(templates.CreateTableData{Name: table}, - am.Driver == types.DriverUnknown) - if err != nil { - return err + if !utils.HasFilesWithExtension(cfg.MigrationFolder, "go", "sql") { + // if there is no files in the directory, we create the migration file + + // create the base schema version table + + file, err = utils.CreateOrOpenFile(path.Join(cfg.MigrationFolder, migrationFileName)) + if err != nil { + return fmt.Errorf("unable to open migrationsFolder.go file: %w", err) + } + migrationFileName := fmt.Sprintf("%s_create_table_schema_version.go", now.UTC().Format(utils.FormatTime)) + file, err = utils.CreateOrOpenFile(path.Join(cfg.MigrationFolder, migrationFileName)) + if err != nil { + return fmt.Errorf("unable to open migrationsFolder.go file: %w", err) + } + + inUp, err := templates.GetInitCreateTableTemplate(templates.CreateTableData{Name: table}, + am.Driver == types.DriverUnknown) + if err != nil { + return err + } + + err = am.GenerateMigrationFile(&amigo.GenerateMigrationFileParams{ + Name: "create_table_schema_version", + Up: inUp, + Down: "// nothing to do to keep the schema version table", + Type: types.MigrationFileTypeClassic, + Now: now, + Writer: file, + UseSchemaImport: am.Driver != types.DriverUnknown, + UseFmtImport: am.Driver == types.DriverUnknown, + }) + if err != nil { + return err + } + logger.Info(events.FileAddedEvent{FileName: path.Join(migrationsFolder, migrationFileName)}) } - err = am.GenerateMigrationFile(&amigo.GenerateMigrationFileParams{ - Name: "create_table_schema_version", - Up: inUp, - Down: "// nothing to do to keep the schema version table", - Type: types.MigrationFileTypeClassic, - Now: now, - Writer: file, - UseSchemaImport: am.Driver != types.DriverUnknown, - UseFmtImport: am.Driver == types.DriverUnknown, - }) - if err != nil { - return err + if !utils.IsFileExists(path.Join(amigoFolder, "migrations.go")) { + // create the migrationsFolder file where all the migrationsFolder will be stored + file, err = utils.CreateOrOpenFile(path.Join(migrationsFolder, "migrations.go")) + if err != nil { + return err + } + + err = am.GenerateMigrationsFiles(file) + if err != nil { + return err + } + logger.Info(events.FileAddedEvent{FileName: path.Join(migrationsFolder, "migrations.go")}) } - logger.Info(events.FileAddedEvent{FileName: path.Join(migrationsFolder, migrationFileName)}) - // create the migrationsFolder file where all the migrationsFolder will be stored - file, err = utils.CreateOrOpenFile(path.Join(amigoFolder, "migrations.go")) - if err != nil { - return err - } - - err = am.GenerateMigrationsFiles(file) - if err != nil { - return err - } - - logger.Info(events.FileAddedEvent{FileName: path.Join(amigoFolder, migrationFileName)}) - - // write the context file - out, err := yaml.Marshal(amigoconfig.DefaultYamlConfig) - if err != nil { - return err - } - - openFile, err := utils.CreateOrOpenFile(path.Join(amigoFolder, amigoconfig.FileName)) - if err != nil { - return fmt.Errorf("unable to open config file: %w", err) - } - defer openFile.Close() - - _, err = openFile.WriteString(string(out)) - if err != nil { - return fmt.Errorf("unable to write config file: %w", err) + if !utils.IsFileExists(path.Join(amigoFolder, amigoconfig.FileName)) { + // write the context file + out, err := yaml.Marshal(amigoconfig.DefaultYamlConfig) + if err != nil { + return err + } + + openFile, err := utils.CreateOrOpenFile(path.Join(amigoFolder, amigoconfig.FileName)) + if err != nil { + return fmt.Errorf("unable to open config file: %w", err) + } + defer openFile.Close() + + _, err = openFile.WriteString(string(out)) + if err != nil { + return fmt.Errorf("unable to write config file: %w", err) + } } return nil diff --git a/pkg/amigo/amigo.go b/pkg/amigo/amigo.go index 9817e48..247be13 100644 --- a/pkg/amigo/amigo.go +++ b/pkg/amigo/amigo.go @@ -22,6 +22,9 @@ type Amigo struct { type OptionFn func(a *Amigo) +// WithCustomSchemaFactory allows to set a custom schema factory +// A schema factory is a function that returns a schema : func(ctx *MigratorContext, tx DB, db DB) T +// This is used for custom drivers implementation func WithCustomSchemaFactory(factory schema.Factory[schema.Schema]) OptionFn { return func(a *Amigo) { a.CustomSchemaFactory = factory diff --git a/pkg/entrypoint/main.go b/pkg/entrypoint/main.go index 0337321..562674b 100644 --- a/pkg/entrypoint/main.go +++ b/pkg/entrypoint/main.go @@ -10,25 +10,9 @@ import ( type Provider func(cfg amigoconfig.Config) (*sql.DB, []schema.Migration, error) -type MainOptions struct { - CustomAmigo func(a *amigo.Amigo) amigo.Amigo -} - -type MainOptFn func(options *MainOptions) - -func Main(resourceProvider Provider, opts ...MainOptFn) { +func Main(resourceProvider Provider, opts ...amigo.OptionFn) { provider = resourceProvider - - options := &MainOptions{} - for _, opt := range opts { - opt(options) - } + amigoOptions = opts _ = rootCmd.Execute() } - -func WithCustomAmigo(f func(a *amigo.Amigo) amigo.Amigo) MainOptFn { - return func(options *MainOptions) { - options.CustomAmigo = f - } -} diff --git a/pkg/entrypoint/root.go b/pkg/entrypoint/root.go index fbf4c0f..4e0697a 100644 --- a/pkg/entrypoint/root.go +++ b/pkg/entrypoint/root.go @@ -17,7 +17,7 @@ import ( var ( config = amigoconfig.NewConfig() provider func(cfg amigoconfig.Config) (*sql.DB, []schema.Migration, error) - customAmigoFn func(a *amigo.Amigo) *amigo.Amigo + amigoOptions []amigo.OptionFn migrationsFile = "migrations.go" ) @@ -118,10 +118,7 @@ func initConfig() { func wrapCobraFunc(f func(cmd *cobra.Command, am amigo.Amigo, args []string) error) func(cmd *cobra.Command, args []string) { return func(cmd *cobra.Command, args []string) { - am := amigo.NewAmigo(config) - if customAmigoFn != nil { - am = *customAmigoFn(&am) - } + am := amigo.NewAmigo(config, amigoOptions...) am.SetupSlog(os.Stdout, nil) if err := f(cmd, am, args); err != nil { diff --git a/pkg/utils/files.go b/pkg/utils/files.go index 9f6cc1c..950f621 100644 --- a/pkg/utils/files.go +++ b/pkg/utils/files.go @@ -3,8 +3,10 @@ package utils import ( "fmt" "io" + "io/ioutil" "os" "path/filepath" + "strings" ) func CreateOrOpenFile(path string) (*os.File, error) { @@ -18,6 +20,16 @@ func CreateOrOpenFile(path string) (*os.File, error) { return os.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) } +func IsFileExists(path string) bool { + _, err := os.Stat(path) + return !os.IsNotExist(err) +} + +func IsDirExists(path string) bool { + info, err := os.Stat(path) + return err == nil && info.IsDir() +} + func GetFileContent(path string) ([]byte, error) { file, err := os.Open(path) if err != nil { @@ -42,3 +54,19 @@ func EnsurePrentDirExists(path string) error { return nil } + +func HasFilesWithExtension(folder string, ext ...string) bool { + files, err := ioutil.ReadDir(folder) + if err != nil { + return false + } + for _, file := range files { + for _, e := range ext { + if strings.HasSuffix(file.Name(), e) { + return true + } + } + return false + } + return false +}