package shared import ( "context" "flag" "fmt" "os" "strings" "git.maronato.dev/maronato/goshort/internal/config" "git.maronato.dev/maronato/goshort/internal/storage" sqlitestorage "git.maronato.dev/maronato/goshort/internal/storage/sqlite" "github.com/peterbourgon/ff/v3" ) type Command struct { // cfg is the command config populated by Parse. cfg *config.Config // exec is the command execution function. exec func(context.Context, *config.Config) error } func NewCommand(cfg *config.Config, exec func(context.Context, *config.Config) error) *Command { return &Command{ cfg: cfg, exec: exec, } } func (c *Command) Exec(ctx context.Context, _ []string) error { return c.exec(ctx, c.cfg) } func NewSharedCmdOptions() []ff.Option { return []ff.Option{ ff.WithEnvVarPrefix("GOSHORT"), } } func RegisterBaseFlags(fs *flag.FlagSet, cfg *config.Config) { fs.BoolVar(&cfg.Quiet, "quiet", config.DefaultQuiet, "enable quiet mode") // Verbose flag that accepts multiple values fs.IntVar((*int)(&cfg.Verbose), "verbose", int(config.DefaultVerbose), "set verbosity level") defaultHost := config.DefaultHost if os.Getenv("ENV_DOCKER") == "true" { // This is a QOL hack to allow docker to bind the port without manually specifying the host defaultHost = "0.0.0.0" } fs.StringVar(&cfg.Host, "host", defaultHost, "host to listen on") fs.StringVar(&cfg.Port, "port", config.DefaultPort, "port to listen on") } func RegisterServerFlags(fs *flag.FlagSet, cfg *config.Config) { fs.BoolVar( &cfg.DisableRegistration, "disable-registration", config.DefaultDisableRegistration, "wether or not registration is disabled", ) dbTypeString := fmt.Sprintf("type of database to use [%s]", strings.Join(config.GetDBTypeList(), ", ")) fs.StringVar(&cfg.DBType, "db-type", config.DefaultDBType, dbTypeString) fs.StringVar(&cfg.DBURL, "db", config.DefaultDBURL, "database connection string or sqlite db path") fs.DurationVar(&cfg.SessionDuration, "session-duration", config.DefaultSessionDuration, "session duration") fs.BoolVar(&cfg.DisableCredentialsLogin, "disable-credentials-login", config.DefaultDisableCredentialsLogin, "disable credentials login") fs.StringVar(&cfg.OIDCIssuerURL, "oidc-issuer-url", "", "OIDC issuer URL") fs.StringVar(&cfg.OIDCClientID, "oidc-client-id", "", "OIDC client ID") fs.StringVar(&cfg.OIDCClientSecret, "oidc-client-secret", "", "OIDC client secret") fs.StringVar(&cfg.OIDCRedirectURL, "oidc-redirect-url", "", "OIDC redirect URL") fs.StringVar(&cfg.OIDCIssuerName, "oidc-issuer-name", config.DefaultOIDCIssuerName, "OIDC issuer name") } // InitStorage initializes the storage depending on the config. func InitStorage(ctx context.Context, cfg *config.Config) storage.Storage { //nolint:ireturn // This function may return multiple types switch cfg.DBType { case config.DBTypeMemory: return sqlitestorage.NewSQLiteStorage(ctx, cfg) case config.DBTypeSQLite: return sqlitestorage.NewSQLiteStorage(ctx, cfg) default: panic("database type not implemented!") } }