github.com/release-engineering/exodus-rsync@v1.11.2/internal/cmd/cmd.go (about) 1 package cmd 2 3 import ( 4 "context" 5 6 "github.com/release-engineering/exodus-rsync/internal/args" 7 "github.com/release-engineering/exodus-rsync/internal/conf" 8 "github.com/release-engineering/exodus-rsync/internal/diag" 9 "github.com/release-engineering/exodus-rsync/internal/gw" 10 "github.com/release-engineering/exodus-rsync/internal/log" 11 "github.com/release-engineering/exodus-rsync/internal/rsync" 12 ) 13 14 var ext = struct { 15 conf conf.Interface 16 rsync rsync.Interface 17 gw gw.Interface 18 log log.Interface 19 diag diag.Interface 20 }{ 21 conf.Package, 22 rsync.Package, 23 gw.Package, 24 log.Package, 25 diag.Package, 26 } 27 28 // This version should be written at build time, see Makefile. 29 var version string = "(unknown version)" 30 31 type mainFunc func(context.Context, conf.Config, args.Config) int 32 33 func invalidMain(ctx context.Context, cfg conf.Config, _ args.Config) int { 34 logger := log.FromContext(ctx) 35 36 logger.F("rsyncmode", cfg.RsyncMode()).Error("Invalid 'rsyncmode' in configuration") 37 return 95 38 } 39 40 // Main is the top-level entry point to the exodus-rsync command. 41 func Main(rawArgs []string) int { 42 ctx, cancel := context.WithCancel(context.Background()) 43 defer cancel() 44 45 // Before anything else, check for --server or --sender, which 46 // indicate rsync itself is trying to do something. 47 // If either are provided, pass through to real rsync. 48 for _, arg := range rawArgs { 49 if arg == "--server" || arg == "--sender" { 50 logger := ext.log.NewLogger(args.Config{}) 51 ctx = log.NewContext(ctx, logger) 52 return rsyncRaw(ctx, rawArgs) 53 } 54 } 55 56 parsedArgs := args.Parse(rawArgs, version, nil) 57 58 logger := ext.log.NewLogger(parsedArgs) 59 60 err := parsedArgs.ValidateConfig() 61 if err != nil { 62 logger.WithField("error", err).Error("argument validation failed") 63 return 23 64 } 65 66 ctx = log.NewContext(ctx, logger) 67 68 cfg, err := ext.conf.Load(ctx, parsedArgs) 69 if err != nil { 70 if _, ok := err.(*conf.MissingConfigFile); ok { 71 // Failed to find any config files, fallback to rsync 72 logger.WithField("error", err).Debug("setting rsyncmode to 'rsync'") 73 return rsyncMain(ctx, nil, parsedArgs) 74 } 75 logger.WithField("error", err).Error("can't load config") 76 return 23 77 } 78 79 var env conf.Config = cfg.EnvironmentForDest(ctx, parsedArgs.Dest) 80 var main mainFunc = invalidMain 81 82 if env == nil || env.RsyncMode() == "rsync" { 83 main = rsyncMain 84 } else if env.RsyncMode() == "exodus" { 85 main = exodusMain 86 } else if env.RsyncMode() == "mixed" { 87 main = mixedMain 88 } 89 90 if env == nil { 91 env = cfg 92 } 93 94 logger.StartPlatformLogger(env) 95 96 // We've now decided more or less what we're going to do. 97 // In diagnostic mode, before proceeding we will *also* dump 98 // a wealth of information about the current environment, 99 // configuration and command, then proceed with publish 100 // afterward. 101 if env.Diag() { 102 ext.diag.Run(ctx, env, parsedArgs) 103 } 104 105 return main(ctx, env, parsedArgs) 106 }