package main import ( "context" "flag" "fmt" "log" "os" "os/signal" "syscall" "ticket-pimp/internal/controller" "ticket-pimp/internal/domain" "ticket-pimp/internal/external" "ticket-pimp/client/discord" "ticket-pimp/client/telegram" "github.com/jackc/pgx/v5/pgxpool" "github.com/jackc/pgx/v5/stdlib" "github.com/pkg/errors" migrate "github.com/rubenv/sql-migrate" "golang.org/x/sync/errgroup" ) <<<<<<< HEAD const ( envfile = "prod.env" migrationfile = "../internal/storage/migrate" // production env: // envfile = "../docker/prod.env" // migrationfile = "../internal/storage/migrate" ) ======= const migrationfile = "../internal/storage/migrate" >>>>>>> dev func main() { log.Print("started") env := flag.Int("env", -1, "0 for development env file, 1 for production environment run, missing flag for build") flag.Parse() var envPath string switch *env { case 0: envPath = ".env" case 1: envPath = "../docker/prod.env" default: envPath = "prod.env" } config := domain.InitConfig(envPath) run(&config) } func Go(ctx context.Context, fns ...func(context.Context) error) error { group, ctx := errgroup.WithContext(ctx) for _, fn := range fns { fn := fn group.Go(func() error { return fn(ctx) }) } return group.Wait() } func applyMigrations(connString string) { // Apply migrations: dbConnConfig, err := pgxpool.ParseConfig(connString) if err != nil { log.Fatalf("unable to parse connString: %v", err) } migrations := &migrate.FileMigrationSource{ Dir: migrationfile, } db := stdlib.OpenDB(*dbConnConfig.ConnConfig) const dialect = "postgres" n, err := migrate.Exec(db, dialect, migrations, migrate.Up) if err != nil { log.Fatalf("unable to handle migrations: %v", err) } fmt.Printf("Applied %d migrations!\n", n) err = db.Close() if err != nil { log.Fatal("unable to close db connection") } } func run(c *domain.Config) { ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill, syscall.SIGTERM) defer cancel() // -- DB connection init -- START connString := fmt.Sprintf( "postgresql://%s:%s@%s:%s/%s", c.DB.User, c.DB.Pass, c.DB.Host, c.DB.Port, c.DB.Name, ) conn, err := pgxpool.New( ctx, connString) if err != nil { log.Fatalf("DB connection failed: %v", err) } // Apply migrations: applyMigrations(connString) // Init services instances: git := external.NewGit(c.Git) cloud := external.NewCloud(c.Cloud) coda := external.NewCoda(c.Coda) // Controller instance init: controller := controller.NewApp( git, cloud, coda, conn, c, ) Go(ctx, func(ctx context.Context) error { opts := discord.DiscordOptions{ Controller: controller, Config: c, } if err := discord.Run(c, opts); err != nil { return errors.Errorf("discord bot cannot be runned: %v", err) } return nil }, func(ctx context.Context) error { opts := telegram.TelegramOptions{ GitService: git, CloudService: cloud, Coda: coda, AppConfig: c, Controller: controller, } if err := telegram.Run(ctx, opts); err != nil { return errors.Errorf("telegram bot cannot be runned: %v", err) } return nil }, ) }