Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add script to generate CLI structure #629

Merged
merged 6 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ generate: format
echo "// SPDX-License-Identifier: Apache-2.0" | cat - pkg/migrations/types.go > pkg/migrations/types.go.tmp
mv pkg/migrations/types.go.tmp pkg/migrations/types.go

# Generate the cli-definition.json file
go run tools/build-cli-definition.go

lint:
golangci-lint --config=.golangci.yml run

Expand Down
180 changes: 180 additions & 0 deletions cli-definition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
{
"name": "pgroll",
"commands": [
{
"name": "analyze",
"short": "Analyze the SQL schema of the target database",
"use": "analyze",
"example": "",
"flags": [],
"subcommands": [],
"args": []
},
{
"name": "complete",
"short": "Complete an ongoing migration with the operations present in the given file",
"use": "complete <file>",
"example": "",
"flags": [],
"subcommands": [],
"args": []
},
{
"name": "init",
"short": "Initialize pgroll in the target database",
"use": "init <file>",
"example": "",
"flags": [],
"subcommands": [],
"args": []
},
{
"name": "latest",
"short": "Print the name of the latest schema version, either in the target database or a local directory",
"use": "latest",
"example": "latest --local ./migrations",
"flags": [
{
"name": "local",
"shorthand": "l",
"description": "retrieve the latest version from a local migration directory",
"default": ""
},
{
"name": "with-schema",
"shorthand": "s",
"description": "prefix the version with the schema name",
"default": "false"
}
],
"subcommands": [],
"args": []
},
{
"name": "migrate",
"short": "Apply outstanding migrations from a directory to a database",
"use": "migrate <directory>",
"example": "migrate ./migrations",
"flags": [
{
"name": "complete",
"shorthand": "c",
"description": "complete the final migration rather than leaving it active",
"default": "false"
}
],
"subcommands": [],
"args": [
"directory"
]
},
{
"name": "pull",
"short": "Pull migration history from the target database and write it to disk",
"use": "pull <target directory>",
"example": "",
"flags": [
{
"name": "with-prefixes",
"shorthand": "p",
"description": "prefix each migration filename with its position in the schema history",
"default": "false"
}
],
"subcommands": [],
"args": [
"directory"
]
},
{
"name": "rollback",
"short": "Roll back an ongoing migration",
"use": "rollback <file>",
"example": "",
"flags": [],
"subcommands": [],
"args": []
},
{
"name": "sql",
"short": "Convert SQL statements to pgroll operations",
"use": "sql <sql statement>",
"example": "",
"flags": [],
"subcommands": [],
"args": [
"statement"
]
},
{
"name": "start",
"short": "Start a migration for the operations present in the given file",
"use": "start <file>",
"example": "",
"flags": [
{
"name": "complete",
"shorthand": "c",
"description": "Mark the migration as complete",
"default": "false"
},
{
"name": "skip-validation",
"shorthand": "s",
"description": "skip migration validation",
"default": "false"
}
],
"subcommands": [],
"args": [
"file"
]
},
{
"name": "status",
"short": "Show pgroll status",
"use": "status",
"example": "",
"flags": [],
"subcommands": [],
"args": []
}
],
"flags": [
{
"name": "backfill-batch-delay",
"description": "Duration of delay between batch backfills (eg. 1s, 1000ms)",
"default": "0s"
},
{
"name": "backfill-batch-size",
"description": "Number of rows backfilled in each batch",
"default": "1000"
},
{
"name": "lock-timeout",
"description": "Postgres lock timeout in milliseconds for pgroll DDL operations",
"default": "500"
},
{
"name": "pgroll-schema",
"description": "Postgres schema to use for pgroll internal state",
"default": "pgroll"
},
{
"name": "postgres-url",
"description": "Postgres URL",
"default": "postgres://postgres:postgres@localhost?sslmode=disable"
},
{
"name": "role",
"description": "Optional postgres role to set when executing migrations",
"default": ""
},
{
"name": "schema",
"description": "Postgres schema to use for the migration",
"default": "public"
}
]
}
2 changes: 1 addition & 1 deletion cmd/latest.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func latestCmd() *cobra.Command {
var migrationsDir string

latestCmd := &cobra.Command{
Use: "latest <directory>",
Use: "latest",
Short: "Print the name of the latest schema version, either in the target database or a local directory",
Example: "latest --local ./migrations",
Args: cobra.NoArgs,
Expand Down
9 changes: 5 additions & 4 deletions cmd/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ func migrateCmd() *cobra.Command {
var complete bool

migrateCmd := &cobra.Command{
Use: "migrate <directory>",
Short: "Apply outstanding migrations from a directory to a database",
Example: "migrate ./migrations",
Args: cobra.ExactArgs(1),
Use: "migrate <directory>",
Short: "Apply outstanding migrations from a directory to a database",
Example: "migrate ./migrations",
Args: cobra.ExactArgs(1),
ValidArgs: []string{"directory"},
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
migrationsDir := args[0]
Expand Down
7 changes: 4 additions & 3 deletions cmd/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ func pullCmd() *cobra.Command {
var withPrefixes bool

pullCmd := &cobra.Command{
Use: "pull <target directory>",
Short: "Pull migration history from the target database and write it to disk",
Args: cobra.ExactArgs(1),
Use: "pull <target directory>",
Short: "Pull migration history from the target database and write it to disk",
Args: cobra.ExactArgs(1),
ValidArgs: []string{"directory"},
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
targetDir := args[0]
Expand Down
63 changes: 33 additions & 30 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,6 @@ import (
// Version is the pgroll version
var Version = "development"

func init() {
andrew-farries marked this conversation as resolved.
Show resolved Hide resolved
viper.SetEnvPrefix("PGROLL")
viper.AutomaticEnv()

rootCmd.PersistentFlags().String("postgres-url", "postgres://postgres:postgres@localhost?sslmode=disable", "Postgres URL")
rootCmd.PersistentFlags().String("schema", "public", "Postgres schema to use for the migration")
rootCmd.PersistentFlags().String("pgroll-schema", "pgroll", "Postgres schema to use for pgroll internal state")
rootCmd.PersistentFlags().Int("lock-timeout", 500, "Postgres lock timeout in milliseconds for pgroll DDL operations")
rootCmd.PersistentFlags().Int("backfill-batch-size", roll.DefaultBackfillBatchSize, "Number of rows backfilled in each batch")
rootCmd.PersistentFlags().Duration("backfill-batch-delay", roll.DefaultBackfillDelay, "Duration of delay between batch backfills (eg. 1s, 1000ms)")
rootCmd.PersistentFlags().String("role", "", "Optional postgres role to set when executing migrations")

viper.BindPFlag("PG_URL", rootCmd.PersistentFlags().Lookup("postgres-url"))
viper.BindPFlag("SCHEMA", rootCmd.PersistentFlags().Lookup("schema"))
viper.BindPFlag("STATE_SCHEMA", rootCmd.PersistentFlags().Lookup("pgroll-schema"))
viper.BindPFlag("LOCK_TIMEOUT", rootCmd.PersistentFlags().Lookup("lock-timeout"))
viper.BindPFlag("BACKFILL_BATCH_SIZE", rootCmd.PersistentFlags().Lookup("backfill-batch-size"))
viper.BindPFlag("BACKFILL_BATCH_DELAY", rootCmd.PersistentFlags().Lookup("backfill-batch-delay"))
viper.BindPFlag("ROLE", rootCmd.PersistentFlags().Lookup("role"))
}

var rootCmd = &cobra.Command{
Use: "pgroll",
SilenceUsage: true,
Version: Version,
}

func NewRoll(ctx context.Context) (*roll.Roll, error) {
pgURL := flags.PostgresURL()
schema := flags.Schema()
Expand All @@ -67,8 +40,32 @@ func NewRoll(ctx context.Context) (*roll.Roll, error) {
)
}

// Execute executes the root command.
func Execute() error {
func Prepare() *cobra.Command {
rootCmd := &cobra.Command{
Use: "pgroll",
SilenceUsage: true,
Version: Version,
}

viper.SetEnvPrefix("PGROLL")
viper.AutomaticEnv()

rootCmd.PersistentFlags().String("postgres-url", "postgres://postgres:postgres@localhost?sslmode=disable", "Postgres URL")
rootCmd.PersistentFlags().String("schema", "public", "Postgres schema to use for the migration")
rootCmd.PersistentFlags().String("pgroll-schema", "pgroll", "Postgres schema to use for pgroll internal state")
rootCmd.PersistentFlags().Int("lock-timeout", 500, "Postgres lock timeout in milliseconds for pgroll DDL operations")
rootCmd.PersistentFlags().Int("backfill-batch-size", roll.DefaultBackfillBatchSize, "Number of rows backfilled in each batch")
rootCmd.PersistentFlags().Duration("backfill-batch-delay", roll.DefaultBackfillDelay, "Duration of delay between batch backfills (eg. 1s, 1000ms)")
rootCmd.PersistentFlags().String("role", "", "Optional postgres role to set when executing migrations")

viper.BindPFlag("PG_URL", rootCmd.PersistentFlags().Lookup("postgres-url"))
viper.BindPFlag("SCHEMA", rootCmd.PersistentFlags().Lookup("schema"))
viper.BindPFlag("STATE_SCHEMA", rootCmd.PersistentFlags().Lookup("pgroll-schema"))
viper.BindPFlag("LOCK_TIMEOUT", rootCmd.PersistentFlags().Lookup("lock-timeout"))
viper.BindPFlag("BACKFILL_BATCH_SIZE", rootCmd.PersistentFlags().Lookup("backfill-batch-size"))
viper.BindPFlag("BACKFILL_BATCH_DELAY", rootCmd.PersistentFlags().Lookup("backfill-batch-delay"))
viper.BindPFlag("ROLE", rootCmd.PersistentFlags().Lookup("role"))

// register subcommands
rootCmd.AddCommand(startCmd())
rootCmd.AddCommand(completeCmd)
Expand All @@ -81,5 +78,11 @@ func Execute() error {
rootCmd.AddCommand(latestCmd())
rootCmd.AddCommand(sqlCmd())

return rootCmd.Execute()
return rootCmd
}

// Execute executes the root command.
func Execute() error {
cmd := Prepare()
return cmd.Execute()
}
9 changes: 5 additions & 4 deletions cmd/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import (

func sqlCmd() *cobra.Command {
sqlCmd := &cobra.Command{
Use: "sql <sql statement>",
Short: "Convert SQL statements to pgroll operations",
Args: cobra.ExactArgs(1),
Hidden: true,
Use: "sql <sql statement>",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Use: "sql <sql statement>",
Use: "sql <statement>",

Short: "Convert SQL statements to pgroll operations",
Args: cobra.ExactArgs(1),
ValidArgs: []string{"statement"},
Hidden: true,
RunE: func(cmd *cobra.Command, args []string) error {
sql := args[0]

Expand Down
7 changes: 4 additions & 3 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ func startCmd() *cobra.Command {
var complete bool

startCmd := &cobra.Command{
Use: "start <file>",
Short: "Start a migration for the operations present in the given file",
Args: cobra.ExactArgs(1),
Use: "start <file>",
Short: "Start a migration for the operations present in the given file",
Args: cobra.ExactArgs(1),
ValidArgs: []string{"file"},
RunE: func(cmd *cobra.Command, args []string) error {
fileName := args[0]

Expand Down
Loading