Prevent user from specifying replica URL & config flag

Previously, if a replica URL was specified then the `-config` flag
was silently ignored. This commit changes this behavior so that
specifying both the URL & config flag will now return an error.
This commit is contained in:
Ben Johnson
2021-02-28 08:09:24 -07:00
parent 9cee1285b9
commit 325482a97c
7 changed files with 56 additions and 43 deletions

View File

@@ -2,7 +2,6 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
@@ -15,9 +14,8 @@ type DatabasesCommand struct{}
// Run executes the command.
func (c *DatabasesCommand) Run(ctx context.Context, args []string) (err error) {
var configPath string
fs := flag.NewFlagSet("litestream-databases", flag.ContinueOnError)
registerConfigFlag(fs, &configPath)
configPath := registerConfigFlag(fs)
fs.Usage = c.Usage
if err := fs.Parse(args); err != nil {
return err
@@ -26,10 +24,10 @@ func (c *DatabasesCommand) Run(ctx context.Context, args []string) (err error) {
}
// Load configuration.
if configPath == "" {
return errors.New("-config required")
if *configPath == "" {
*configPath = DefaultConfigPath()
}
config, err := ReadConfigFile(configPath)
config, err := ReadConfigFile(*configPath)
if err != nil {
return err
}

View File

@@ -2,7 +2,6 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"log"
@@ -18,9 +17,8 @@ type GenerationsCommand struct{}
// Run executes the command.
func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error) {
var configPath string
fs := flag.NewFlagSet("litestream-generations", flag.ContinueOnError)
registerConfigFlag(fs, &configPath)
configPath := registerConfigFlag(fs)
replicaName := fs.String("replica", "", "replica name")
fs.Usage = c.Usage
if err := fs.Parse(args); err != nil {
@@ -35,12 +33,19 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
var r litestream.Replica
updatedAt := time.Now()
if isURL(fs.Arg(0)) {
if *configPath != "" {
return fmt.Errorf("cannot specify a replica URL and the -config flag")
}
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
return err
}
} else if configPath != "" {
} else {
if *configPath == "" {
*configPath = DefaultConfigPath()
}
// Load configuration.
config, err := ReadConfigFile(configPath)
config, err := ReadConfigFile(*configPath)
if err != nil {
return err
}
@@ -65,8 +70,6 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
if updatedAt, err = db.UpdatedAt(); err != nil {
return err
}
} else {
return errors.New("config path or replica URL required")
}
var replicas []litestream.Replica

View File

@@ -429,8 +429,8 @@ func DefaultConfigPath() string {
return defaultConfigPath
}
func registerConfigFlag(fs *flag.FlagSet, p *string) {
fs.StringVar(p, "config", DefaultConfigPath(), "config path")
func registerConfigFlag(fs *flag.FlagSet) *string {
return fs.String("config", "", "config path")
}
// expand returns an absolute path for s.

View File

@@ -2,7 +2,6 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"log"
@@ -19,8 +18,7 @@ import (
// ReplicateCommand represents a command that continuously replicates SQLite databases.
type ReplicateCommand struct {
ConfigPath string
Config Config
Config Config
// List of managed databases specified in the config.
DBs []*litestream.DB
@@ -34,7 +32,7 @@ func NewReplicateCommand() *ReplicateCommand {
func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err error) {
fs := flag.NewFlagSet("litestream-replicate", flag.ContinueOnError)
tracePath := fs.String("trace", "", "trace path")
registerConfigFlag(fs, &c.ConfigPath)
configPath := registerConfigFlag(fs)
fs.Usage = c.Usage
if err := fs.Parse(args); err != nil {
return err
@@ -44,6 +42,10 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
if fs.NArg() == 1 {
return fmt.Errorf("must specify at least one replica URL for %s", fs.Arg(0))
} else if fs.NArg() > 1 {
if *configPath != "" {
return fmt.Errorf("cannot specify a replica URL and the -config flag")
}
dbConfig := &DBConfig{Path: fs.Arg(0)}
for _, u := range fs.Args()[1:] {
dbConfig.Replicas = append(dbConfig.Replicas, &ReplicaConfig{
@@ -52,12 +54,13 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
})
}
c.Config.DBs = []*DBConfig{dbConfig}
} else if c.ConfigPath != "" {
if c.Config, err = ReadConfigFile(c.ConfigPath); err != nil {
} else {
if *configPath == "" {
*configPath = DefaultConfigPath()
}
if c.Config, err = ReadConfigFile(*configPath); err != nil {
return err
}
} else {
return errors.New("-config flag or database/replica arguments required")
}
// Enable trace logging.

View File

@@ -17,12 +17,11 @@ type RestoreCommand struct{}
// Run executes the command.
func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
var configPath string
opt := litestream.NewRestoreOptions()
opt.Verbose = true
fs := flag.NewFlagSet("litestream-restore", flag.ContinueOnError)
registerConfigFlag(fs, &configPath)
configPath := registerConfigFlag(fs)
fs.StringVar(&opt.OutputPath, "o", "", "output path")
fs.StringVar(&opt.ReplicaName, "replica", "", "replica name")
fs.StringVar(&opt.Generation, "generation", "", "generation name")
@@ -59,15 +58,19 @@ func (c *RestoreCommand) Run(ctx context.Context, args []string) (err error) {
// Determine replica & generation to restore from.
var r litestream.Replica
if isURL(fs.Arg(0)) {
if *configPath != "" {
return fmt.Errorf("cannot specify a replica URL and the -config flag")
}
if r, err = c.loadFromURL(ctx, fs.Arg(0), &opt); err != nil {
return err
}
} else if configPath != "" {
if r, err = c.loadFromConfig(ctx, fs.Arg(0), configPath, &opt); err != nil {
} else {
if *configPath == "" {
*configPath = DefaultConfigPath()
}
if r, err = c.loadFromConfig(ctx, fs.Arg(0), *configPath, &opt); err != nil {
return err
}
} else {
return errors.New("config path or replica URL required")
}
// Return an error if no matching targets found.

View File

@@ -2,7 +2,6 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
@@ -17,9 +16,8 @@ type SnapshotsCommand struct{}
// Run executes the command.
func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
var configPath string
fs := flag.NewFlagSet("litestream-snapshots", flag.ContinueOnError)
registerConfigFlag(fs, &configPath)
configPath := registerConfigFlag(fs)
replicaName := fs.String("replica", "", "replica name")
fs.Usage = c.Usage
if err := fs.Parse(args); err != nil {
@@ -33,12 +31,19 @@ func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
var db *litestream.DB
var r litestream.Replica
if isURL(fs.Arg(0)) {
if *configPath != "" {
return fmt.Errorf("cannot specify a replica URL and the -config flag")
}
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
return err
}
} else if configPath != "" {
} else {
if *configPath == "" {
*configPath = DefaultConfigPath()
}
// Load configuration.
config, err := ReadConfigFile(configPath)
config, err := ReadConfigFile(*configPath)
if err != nil {
return err
}
@@ -58,8 +63,6 @@ func (c *SnapshotsCommand) Run(ctx context.Context, args []string) (err error) {
return fmt.Errorf("replica %q not found for database %q", *replicaName, db.Path())
}
}
} else {
return errors.New("config path or replica URL required")
}
// Find snapshots by db or replica.

View File

@@ -2,7 +2,6 @@ package main
import (
"context"
"errors"
"flag"
"fmt"
"os"
@@ -17,9 +16,8 @@ type WALCommand struct{}
// Run executes the command.
func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
var configPath string
fs := flag.NewFlagSet("litestream-wal", flag.ContinueOnError)
registerConfigFlag(fs, &configPath)
configPath := registerConfigFlag(fs)
replicaName := fs.String("replica", "", "replica name")
generation := fs.String("generation", "", "generation name")
fs.Usage = c.Usage
@@ -34,12 +32,19 @@ func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
var db *litestream.DB
var r litestream.Replica
if isURL(fs.Arg(0)) {
if *configPath != "" {
return fmt.Errorf("cannot specify a replica URL and the -config flag")
}
if r, err = NewReplicaFromConfig(&ReplicaConfig{URL: fs.Arg(0)}, nil); err != nil {
return err
}
} else if configPath != "" {
} else {
if *configPath == "" {
*configPath = DefaultConfigPath()
}
// Load configuration.
config, err := ReadConfigFile(configPath)
config, err := ReadConfigFile(*configPath)
if err != nil {
return err
}
@@ -59,8 +64,6 @@ func (c *WALCommand) Run(ctx context.Context, args []string) (err error) {
return fmt.Errorf("replica %q not found for database %q", *replicaName, db.Path())
}
}
} else {
return errors.New("config path or replica URL required")
}
// Find WAL files by db or replica.