commands

package
v0.0.0-...-63eebbb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MigrationsDirectory = "db/migrations"
)

Variables

View Source
var DBMigrate = &cobra.Command{
	Use:     "db:migrate",
	Aliases: []string{"dbm"},
	Short:   "Run database migrations",
	Run: func(cmd *cobra.Command, _ []string) {
		var dir string
		databaseURL := f.GetEnvOrString("DATABASE_URL", "")

		if f.IsProductionEnv() {
			dir = cmd.Flag("dir").Value.String()
			if dir == "" {
				log.Fatal("You should specify the directory containing migrations with the `--dir` flag")
			}
		} else {
			if !h.BuiltOnFoundation() {
				log.Fatal("This command must be run from inside a Foundation service")
			}

			dir = h.AtServiceRoot(MigrationsDirectory)
		}

		_, err := os.Stat(dir)
		if os.IsNotExist(err) {
			log.Fatalf("Migrations directory `%s` does not exist", dir)
		}

		if databaseURL == "" {
			log.Fatal("`DATABASE_URL` environment variable is not set")
		}

		m, err := migrate.New(fmt.Sprintf("file://%s", dir), databaseURL)
		if err != nil {
			log.Fatal(err)
		}

		if err = m.Up(); err != nil {
			log.Fatal(err)
		}
	},
}
View Source
var DBRollback = &cobra.Command{
	Use:     "db:rollback",
	Aliases: []string{"dbr"},
	Short:   "Rollback database migrations",
	Long:    "Rollback database migrations by a given number of steps, e.g.: `foundation db:rollback --steps 2`",
	Run: func(cmd *cobra.Command, _ []string) {
		var dir string
		databaseURL := f.GetEnvOrString("DATABASE_URL", "")

		if f.IsProductionEnv() {
			dir = cmd.Flag("dir").Value.String()
			if dir == "" {
				log.Fatal("You should specify the directory containing migrations with the `--dir` flag")
			}
		} else {
			if !h.BuiltOnFoundation() {
				log.Fatal("This command must be run from inside a Foundation service")
			}

			dir = h.AtServiceRoot(MigrationsDirectory)
		}

		_, err := os.Stat(dir)
		if os.IsNotExist(err) {
			log.Fatalf("Migrations directory `%s` does not exist", dir)
		}

		steps, err := cmd.Flags().GetInt("step")
		if err != nil || steps <= 0 {
			log.Fatal("You should set `--steps` flag to a positive integer")
		}

		if databaseURL == "" {
			log.Fatal("`DATABASE_URL` environment variable is not set")
		}

		m, err := migrate.New(fmt.Sprintf("file://%s", dir), databaseURL)
		if err != nil {
			log.Fatal(err)
		}

		if err = m.Steps(-1 * steps); err != nil {
			log.Fatal(err)
		}
	},
}
View Source
var InitOutbox = &cobra.Command{
	Use:   "init-outbox",
	Short: "Initialize outbox pattern for the current service",
	Long: `Initialize outbox pattern by copying outbox migration files from foundation framework
to the current service's db/migrations directory. This creates the foundation_outbox_events
table required for the transactional outbox pattern.`,
	Run: func(cmd *cobra.Command, _ []string) {
		if !h.BuiltOnFoundation() {
			log.Fatal("This command must be run from inside a Foundation service")
		}

		serviceRoot := h.AtServiceRoot()
		migrationsDir := filepath.Join(serviceRoot, MigrationsDirectory)

		if err := os.MkdirAll(migrationsDir, 0755); err != nil {
			log.Fatalf("Failed to create migrations directory: %v", err)
		}

		timestamp := time.Now().Format("20060102150405")
		migrationName := "create_foundation_outbox_events"

		foundationPath, err := getFoundationModulePath()
		if err != nil {
			log.Fatalf("Failed to locate foundation module: %v", err)
		}

		sourceMigrationsPath := filepath.Join(foundationPath, "outboxrepo", "migrations")

		if _, err := os.Stat(sourceMigrationsPath); os.IsNotExist(err) {
			log.Fatalf("Foundation outbox migrations not found at: %s", sourceMigrationsPath)
		}

		upFile := fmt.Sprintf("%s_%s.up.sql", timestamp, migrationName)
		downFile := fmt.Sprintf("%s_%s.down.sql", timestamp, migrationName)

		if err := copyMigrationFile(
			filepath.Join(sourceMigrationsPath, "000001_create_foundation_outbox_events.up.sql"),
			filepath.Join(migrationsDir, upFile),
		); err != nil {
			log.Fatalf("Failed to copy up migration: %v", err)
		}

		if err := copyMigrationFile(
			filepath.Join(sourceMigrationsPath, "000001_create_foundation_outbox_events.down.sql"),
			filepath.Join(migrationsDir, downFile),
		); err != nil {
			log.Fatalf("Failed to copy down migration: %v", err)
		}

		log.Printf("✅ Outbox migrations created successfully:")
		log.Printf("   - %s", upFile)
		log.Printf("   - %s", downFile)
		log.Printf("")
		log.Printf("Next steps:")
		log.Printf("1. Run migrations: foundation db:migrate")
		log.Printf("2. Enable outbox in your service: f.WithOutbox()")
		log.Printf("3. Create outbox courier: foundation new --service --name %s-outbox", getServiceName())
		log.Printf("4. Use WithResponseTransaction in handlers to publish events")
	},
}
View Source
var New = &cobra.Command{
	Use:     "new",
	Aliases: []string{"n"},
	Short:   "Create a new Foundation application or service",
	Run: func(cmd *cobra.Command, _ []string) {
		serviceFlag, err := cmd.Flags().GetBool("service")
		if err != nil {
			log.Fatal().Err(err).Msg("Failed to get `--service` flag")
		}

		rawName := cmd.Flag("name").Value.String()
		input := &newInput{
			FoundationVersion: f.Version,
			Name:              rawName,
		}

		if serviceFlag {
			newService(input)
		} else {
			newApplication(input)
		}
	},
}
View Source
var Start = &cobra.Command{
	Use:     "start",
	Aliases: []string{"s"},
	Short:   "Start a service",
	Run: func(_ *cobra.Command, _ []string) {
		if !h.BuiltOnFoundation() {
			log.Fatal("This command must be run from inside a Foundation service")
		}

		files, err := os.ReadDir(h.AtServiceRoot("cmd"))
		if err != nil {
			log.Fatal(err)
		}

		// Collect all directory names
		var binaries []string
		for _, f := range files {
			if f.IsDir() {
				binaries = append(binaries, f.Name())
			}
		}

		prompt := &survey.Select{
			Message: "Choose a service to start:",
			Options: binaries,
		}
		var binaryName string
		if err = survey.AskOne(prompt, &binaryName); err != nil {
			log.Fatal(err)
		}

		svc := exec.Command("go", "run", h.AtServiceRoot("cmd", binaryName))
		svc.Stdout = os.Stdout
		svc.Stderr = os.Stderr
		if err = svc.Run(); err != nil {
			log.Fatal(err)
		}
	},
}
View Source
var Test = &cobra.Command{
	Use:     "test",
	Aliases: []string{"t"},
	Short:   "Run tests",
	Run: func(cmd *cobra.Command, _ []string) {
		if !h.BuiltOnFoundation() {
			log.Fatal("This command must be run from inside a Foundation service")
		}

		if f.IsProductionEnv() {
			log.Fatal("You're trying to run tests in production environment")
		}

		env := os.Environ()
		env = append(env, "FOUNDATION_ENV=test")

		opts := []string{
			"test",
		}
		if cmd.Flag("opts") != nil {
			opts = append(opts, strings.Split(cmd.Flag("opts").Value.String(), " ")...)
		}
		opts = append(opts, h.AtServiceRoot("..."))

		test := exec.Command("go", opts...)
		test.Stdout = os.Stdout
		test.Stderr = os.Stderr
		test.Env = env
		if err := test.Run(); err != nil {
			log.Fatal(err)
		}
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL