From 87d79a576d072bd9692376fdcf0925f656cec970 Mon Sep 17 00:00:00 2001 From: Oliver Tonnhofer Date: Thu, 1 Aug 2013 16:19:20 +0200 Subject: [PATCH] refactored command parsing; update --help --- config/config.go | 231 ++++++++++++++++++++++++----------------------- diff/process.go | 22 ++--- goposm.go | 61 +++++-------- 3 files changed, 153 insertions(+), 161 deletions(-) diff --git a/config/config.go b/config/config.go index 0dfb9b1..7460d91 100644 --- a/config/config.go +++ b/config/config.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "flag" + "fmt" "log" "os" ) @@ -21,9 +22,9 @@ const defaultSrid = 3857 const defaultCacheDir = "/tmp/goposm" var ImportFlags = flag.NewFlagSet("import", flag.ExitOnError) -var DiffImportFlags = flag.NewFlagSet("diff", flag.ExitOnError) +var DiffFlags = flag.NewFlagSet("diff", flag.ExitOnError) -type ImportBaseOptions struct { +type _BaseOptions struct { Connection string CacheDir string MappingFile string @@ -33,8 +34,60 @@ type ImportBaseOptions struct { ConfigFile string } +func (o *_BaseOptions) updateFromConfig() error { + conf := &Config{ + CacheDir: defaultCacheDir, + Srid: defaultSrid, + } + + if o.ConfigFile != "" { + f, err := os.Open(o.ConfigFile) + if err != nil { + return err + } + decoder := json.NewDecoder(f) + + err = decoder.Decode(&conf) + if err != nil { + return err + } + } + if o.Connection == "" { + o.Connection = conf.Connection + } + if conf.Srid == 0 { + conf.Srid = defaultSrid + } + if o.Srid != defaultSrid { + o.Srid = conf.Srid + } + if o.MappingFile == "" { + o.MappingFile = conf.MappingFile + } + if o.LimitTo == "" { + o.LimitTo = conf.LimitTo + } + if o.LimitToCacheBuffer == 0.0 { + o.LimitToCacheBuffer = conf.LimitToCacheBuffer + } + if o.CacheDir == defaultCacheDir { + o.CacheDir = conf.CacheDir + } + return nil +} + +func (o *_BaseOptions) check() []error { + errs := []error{} + if o.Srid != 3857 { + errs = append(errs, errors.New("srid!=3857 not implemented")) + } + if o.MappingFile == "" { + errs = append(errs, errors.New("missing mapping")) + } + return errs +} + type _ImportOptions struct { - Base ImportBaseOptions Cpuprofile string Httpprofile string Memprofile string @@ -50,141 +103,95 @@ type _ImportOptions struct { Quiet bool } -type _DiffImportOptions struct { - Base ImportBaseOptions -} - +var BaseOptions = _BaseOptions{} var ImportOptions = _ImportOptions{} -var DiffImportOptions = _DiffImportOptions{} -func addBaseFlags(flags *flag.FlagSet, baseOptions *ImportBaseOptions) { - flags.StringVar(&baseOptions.Connection, "connection", "", "connection parameters") - flags.StringVar(&baseOptions.CacheDir, "cachedir", defaultCacheDir, "cache directory") - flags.StringVar(&baseOptions.MappingFile, "mapping", "", "mapping file") - flags.IntVar(&baseOptions.Srid, "srid", defaultSrid, "srs id") - flags.StringVar(&baseOptions.LimitTo, "limitto", "", "limit to geometries") - flags.StringVar(&baseOptions.ConfigFile, "config", "", "config (json)") +func addBaseFlags(flags *flag.FlagSet) { + flags.StringVar(&BaseOptions.Connection, "connection", "", "connection parameters") + flags.StringVar(&BaseOptions.CacheDir, "cachedir", defaultCacheDir, "cache directory") + flags.StringVar(&BaseOptions.MappingFile, "mapping", "", "mapping file") + flags.IntVar(&BaseOptions.Srid, "srid", defaultSrid, "srs id") + flags.StringVar(&BaseOptions.LimitTo, "limitto", "", "limit to geometries") + flags.StringVar(&BaseOptions.ConfigFile, "config", "", "config (json)") } -func addImportFlags(flags *flag.FlagSet, options *_ImportOptions) { - flags.StringVar(&options.Cpuprofile, "cpuprofile", "", "filename of cpu profile output") - flags.StringVar(&options.Httpprofile, "httpprofile", "", "bind address for profile server") - flags.StringVar(&options.Memprofile, "memprofile", "", "dir name of mem profile output and interval (fname:interval)") - flags.BoolVar(&options.Overwritecache, "overwritecache", false, "overwritecache") - flags.BoolVar(&options.Appendcache, "appendcache", false, "append cache") - flags.StringVar(&options.Read, "read", "", "read") - flags.BoolVar(&options.Write, "write", false, "write") - flags.BoolVar(&options.Optimize, "optimize", false, "optimize") - flags.BoolVar(&options.Diff, "diff", false, "enable diff support") - flags.BoolVar(&options.DeployProduction, "deployproduction", false, "deploy production") - flags.BoolVar(&options.RevertDeploy, "revertdeploy", false, "revert deploy to production") - flags.BoolVar(&options.RemoveBackup, "removebackup", false, "remove backups from deploy") - flags.BoolVar(&options.Quiet, "quiet", false, "quiet log output") +func UsageImport() { + fmt.Fprintf(os.Stderr, "Usage: %s %s [args]\n\n", os.Args[0], os.Args[1]) + ImportFlags.PrintDefaults() + os.Exit(2) } -func addDiffImportFlags(flags *flag.FlagSet, options *_DiffImportOptions) { - // no options yet +func UsageDiff() { + fmt.Fprintf(os.Stderr, "Usage: %s %s [args] [.osc.gz, ...]\n\n", os.Args[0], os.Args[1]) + DiffFlags.PrintDefaults() + os.Exit(2) } func init() { - addBaseFlags(ImportFlags, &ImportOptions.Base) - addImportFlags(ImportFlags, &ImportOptions) - addBaseFlags(DiffImportFlags, &DiffImportOptions.Base) - addDiffImportFlags(DiffImportFlags, &DiffImportOptions) + ImportFlags.Usage = UsageImport + DiffFlags.Usage = UsageDiff + + addBaseFlags(DiffFlags) + addBaseFlags(ImportFlags) + ImportFlags.StringVar(&ImportOptions.Cpuprofile, "cpuprofile", "", "filename of cpu profile output") + ImportFlags.StringVar(&ImportOptions.Httpprofile, "httpprofile", "", "bind address for profile server") + ImportFlags.StringVar(&ImportOptions.Memprofile, "memprofile", "", "dir name of mem profile output and interval (fname:interval)") + ImportFlags.BoolVar(&ImportOptions.Overwritecache, "overwritecache", false, "overwritecache") + ImportFlags.BoolVar(&ImportOptions.Appendcache, "appendcache", false, "append cache") + ImportFlags.StringVar(&ImportOptions.Read, "read", "", "read") + ImportFlags.BoolVar(&ImportOptions.Write, "write", false, "write") + ImportFlags.BoolVar(&ImportOptions.Optimize, "optimize", false, "optimize") + ImportFlags.BoolVar(&ImportOptions.Diff, "diff", false, "enable diff support") + ImportFlags.BoolVar(&ImportOptions.DeployProduction, "deployproduction", false, "deploy production") + ImportFlags.BoolVar(&ImportOptions.RevertDeploy, "revertdeploy", false, "revert deploy to production") + ImportFlags.BoolVar(&ImportOptions.RemoveBackup, "removebackup", false, "remove backups from deploy") + ImportFlags.BoolVar(&ImportOptions.Quiet, "quiet", false, "quiet log output") } -// var ( -// connection = flag.String("connection", "", "connection parameters") -// cachedir = flag.String("cachedir", defaultCacheDir, "cache directory") -// mappingFile = flag.String("mapping", "", "mapping file") -// srid = flag.Int("srid", defaultSrid, "srs id") -// limitTo = flag.String("limitto", "", "limit to geometries") -// configFile = flag.String("config", "", "config (json)") -// ) - -func ParseImport(args []string) []error { +func ParseImport(args []string) { + if len(args) == 0 { + UsageImport() + } err := ImportFlags.Parse(args) if err != nil { log.Fatal(err) } - errs := updateBaseOpts(&ImportOptions.Base) - if errs != nil { - return errs + err = BaseOptions.updateFromConfig() + if err != nil { + log.Fatal(err) + } + errs := BaseOptions.check() + if len(errs) != 0 { + reportErrors(errs) + UsageImport() } - - errs = checkOptions(&ImportOptions.Base) - return errs } -func updateBaseOpts(opts *ImportBaseOptions) []error { - - conf := &Config{ - CacheDir: defaultCacheDir, - Srid: defaultSrid, +func ParseDiffImport(args []string) { + if len(args) == 0 { + UsageDiff() } - - if opts.ConfigFile != "" { - f, err := os.Open(opts.ConfigFile) - if err != nil { - return []error{err} - } - decoder := json.NewDecoder(f) - - err = decoder.Decode(&conf) - if err != nil { - return []error{err} - } - } - if opts.Connection == "" { - opts.Connection = conf.Connection - } - if conf.Srid == 0 { - conf.Srid = defaultSrid - } - if opts.Srid != defaultSrid { - opts.Srid = conf.Srid - } - if opts.MappingFile == "" { - opts.MappingFile = conf.MappingFile - } - if opts.LimitTo == "" { - opts.LimitTo = conf.LimitTo - } - if opts.LimitToCacheBuffer == 0.0 { - opts.LimitToCacheBuffer = conf.LimitToCacheBuffer - } - if opts.CacheDir == defaultCacheDir { - opts.CacheDir = conf.CacheDir - } - return nil -} - -func ParseDiffImport(args []string) []error { - err := DiffImportFlags.Parse(args) + err := DiffFlags.Parse(args) if err != nil { log.Fatal(err) } - errs := updateBaseOpts(&DiffImportOptions.Base) - if errs != nil { - return errs + err = BaseOptions.updateFromConfig() + if err != nil { + log.Fatal(err) } - errs = checkOptions(&DiffImportOptions.Base) - - return errs + errs := BaseOptions.check() + if len(errs) != 0 { + reportErrors(errs) + UsageDiff() + } } -func checkOptions(opts *ImportBaseOptions) []error { - errs := []error{} - if opts.Srid != 3857 { - errs = append(errs, errors.New("srid!=3857 not implemented")) +func reportErrors(errs []error) { + fmt.Println("errors in config/options:") + for _, err := range errs { + fmt.Printf("\t%s\n", err) } - if opts.MappingFile == "" { - errs = append(errs, errors.New("missing mapping")) - } - if opts.Connection == "" { - errs = append(errs, errors.New("missing connection")) - } - return errs + os.Exit(1) } diff --git a/diff/process.go b/diff/process.go index ee4a2bf..71b0666 100644 --- a/diff/process.go +++ b/diff/process.go @@ -26,7 +26,7 @@ func Update(oscFile string, geometryLimiter *limit.Limiter, force bool) { if err != nil { log.Fatal(err) } - lastState, err := diffstate.ParseLastState(config.DiffImportOptions.Base.CacheDir) + lastState, err := diffstate.ParseLastState(config.BaseOptions.CacheDir) if err != nil { log.Fatal(err) } @@ -42,28 +42,28 @@ func Update(oscFile string, geometryLimiter *limit.Limiter, force bool) { elems, errc := parser.Parse(oscFile) - osmCache := cache.NewOSMCache(config.DiffImportOptions.Base.CacheDir) + osmCache := cache.NewOSMCache(config.BaseOptions.CacheDir) err = osmCache.Open() if err != nil { log.Fatal("osm cache: ", err) } - diffCache := cache.NewDiffCache(config.DiffImportOptions.Base.CacheDir) + diffCache := cache.NewDiffCache(config.BaseOptions.CacheDir) err = diffCache.Open() if err != nil { log.Fatal("diff cache: ", err) } - tagmapping, err := mapping.NewMapping(config.DiffImportOptions.Base.MappingFile) + tagmapping, err := mapping.NewMapping(config.BaseOptions.MappingFile) if err != nil { log.Fatal(err) } - connType := database.ConnectionType(config.DiffImportOptions.Base.Connection) + connType := database.ConnectionType(config.BaseOptions.Connection) dbConf := database.Config{ Type: connType, - ConnectionParams: config.DiffImportOptions.Base.Connection, - Srid: config.DiffImportOptions.Base.Srid, + ConnectionParams: config.BaseOptions.Connection, + Srid: config.BaseOptions.Srid, } db, err := database.Open(dbConf, tagmapping) if err != nil { @@ -105,19 +105,19 @@ func Update(oscFile string, geometryLimiter *limit.Limiter, force bool) { nodes := make(chan *element.Node) relWriter := writer.NewRelationWriter(osmCache, diffCache, relations, - db, polygonsTagMatcher, progress, config.DiffImportOptions.Base.Srid) + db, polygonsTagMatcher, progress, config.BaseOptions.Srid) relWriter.SetLimiter(geometryLimiter) relWriter.SetExpireTiles(expiredTiles) relWriter.Start() wayWriter := writer.NewWayWriter(osmCache, diffCache, ways, db, - lineStringsTagMatcher, polygonsTagMatcher, progress, config.DiffImportOptions.Base.Srid) + lineStringsTagMatcher, polygonsTagMatcher, progress, config.BaseOptions.Srid) wayWriter.SetLimiter(geometryLimiter) wayWriter.SetExpireTiles(expiredTiles) wayWriter.Start() nodeWriter := writer.NewNodeWriter(osmCache, nodes, db, - pointsTagMatcher, progress, config.DiffImportOptions.Base.Srid) + pointsTagMatcher, progress, config.BaseOptions.Srid) nodeWriter.SetLimiter(geometryLimiter) nodeWriter.Start() @@ -283,7 +283,7 @@ For: progress.Stop() if state != nil { - err = diffstate.WriteLastState(config.DiffImportOptions.Base.CacheDir, state) + err = diffstate.WriteLastState(config.BaseOptions.CacheDir, state) if err != nil { log.Warn(err) // warn only } diff --git a/goposm.go b/goposm.go index ba4eee3..4eb8034 100644 --- a/goposm.go +++ b/goposm.go @@ -28,15 +28,6 @@ import ( var log = logging.NewLogger("") -func reportErrors(errs []error) { - fmt.Println("errors in config/options:") - for _, err := range errs { - fmt.Printf("\t%s\n", err) - } - logging.Shutdown() - os.Exit(1) -} - func printCmds() { fmt.Fprintf(os.Stderr, "Usage: %s COMMAND [args]\n\n", os.Args[0]) fmt.Println("Available commands:") @@ -60,27 +51,18 @@ func main() { switch os.Args[1] { case "import": - errs := config.ParseImport(os.Args[2:]) - if len(errs) > 0 { - config.ImportFlags.PrintDefaults() - reportErrors(errs) - break - } + config.ParseImport(os.Args[2:]) mainimport() case "diff": - errs := config.ParseDiffImport(os.Args[2:]) - if len(errs) > 0 { - config.DiffImportFlags.PrintDefaults() - reportErrors(errs) - break - } + config.ParseDiffImport(os.Args[2:]) + var geometryLimiter *limit.Limiter - if config.DiffImportOptions.Base.LimitTo != "" { + if config.BaseOptions.LimitTo != "" { var err error step := log.StartStep("Reading limitto geometries") geometryLimiter, err = limit.NewFromOgrSourceWithBuffered( - config.DiffImportOptions.Base.LimitTo, - config.DiffImportOptions.Base.LimitToCacheBuffer, + config.BaseOptions.LimitTo, + config.BaseOptions.LimitToCacheBuffer, ) if err != nil { log.Fatal(err) @@ -88,7 +70,7 @@ func main() { log.StopStep(step) } - for _, oscFile := range config.DiffImportFlags.Args() { + for _, oscFile := range config.DiffFlags.Args() { diff.Update(oscFile, geometryLimiter, false) } case "query-cache": @@ -145,17 +127,17 @@ func mainimport() { } var geometryLimiter *limit.Limiter - if config.ImportOptions.Write && config.ImportOptions.Base.LimitTo != "" { + if config.ImportOptions.Write && config.BaseOptions.LimitTo != "" { var err error step := log.StartStep("Reading limitto geometries") - geometryLimiter, err = limit.NewFromOgrSource(config.ImportOptions.Base.LimitTo) + geometryLimiter, err = limit.NewFromOgrSource(config.BaseOptions.LimitTo) if err != nil { log.Fatal(err) } log.StopStep(step) } - tagmapping, err := mapping.NewMapping(config.ImportOptions.Base.MappingFile) + tagmapping, err := mapping.NewMapping(config.BaseOptions.MappingFile) if err != nil { log.Fatal("mapping file: ", err) } @@ -163,11 +145,14 @@ func mainimport() { var db database.DB if config.ImportOptions.Write || config.ImportOptions.DeployProduction || config.ImportOptions.RevertDeploy || config.ImportOptions.RemoveBackup || config.ImportOptions.Optimize { - connType := database.ConnectionType(config.ImportOptions.Base.Connection) + if config.BaseOptions.Connection == "" { + log.Fatal("missing connection option") + } + connType := database.ConnectionType(config.BaseOptions.Connection) conf := database.Config{ Type: connType, - ConnectionParams: config.ImportOptions.Base.Connection, - Srid: config.ImportOptions.Base.Srid, + ConnectionParams: config.BaseOptions.Connection, + Srid: config.BaseOptions.Srid, } db, err = database.Open(conf, tagmapping) if err != nil { @@ -175,11 +160,11 @@ func mainimport() { } } - osmCache := cache.NewOSMCache(config.ImportOptions.Base.CacheDir) + osmCache := cache.NewOSMCache(config.BaseOptions.CacheDir) if config.ImportOptions.Read != "" && osmCache.Exists() { if config.ImportOptions.Overwritecache { - log.Printf("removing existing cache %s", config.ImportOptions.Base.CacheDir) + log.Printf("removing existing cache %s", config.BaseOptions.CacheDir) err := osmCache.Remove() if err != nil { log.Fatal("unable to remove cache:", err) @@ -215,7 +200,7 @@ func mainimport() { if config.ImportOptions.Diff { diffstate := state.FromPbf(pbfFile) if diffstate != nil { - diffstate.WriteToFile(path.Join(config.ImportOptions.Base.CacheDir, "last.state.txt")) + diffstate.WriteToFile(path.Join(config.BaseOptions.CacheDir, "last.state.txt")) } } } @@ -242,7 +227,7 @@ func mainimport() { var diffCache *cache.DiffCache if config.ImportOptions.Diff { - diffCache = cache.NewDiffCache(config.ImportOptions.Base.CacheDir) + diffCache = cache.NewDiffCache(config.BaseOptions.CacheDir) if err = diffCache.Remove(); err != nil { log.Fatal(err) } @@ -262,7 +247,7 @@ func mainimport() { relations := osmCache.Relations.Iter() relWriter := writer.NewRelationWriter(osmCache, diffCache, relations, - db, polygonsTagMatcher, progress, config.ImportOptions.Base.Srid) + db, polygonsTagMatcher, progress, config.BaseOptions.Srid) relWriter.SetLimiter(geometryLimiter) relWriter.Start() @@ -272,7 +257,7 @@ func mainimport() { ways := osmCache.Ways.Iter() wayWriter := writer.NewWayWriter(osmCache, diffCache, ways, db, - lineStringsTagMatcher, polygonsTagMatcher, progress, config.ImportOptions.Base.Srid) + lineStringsTagMatcher, polygonsTagMatcher, progress, config.BaseOptions.Srid) wayWriter.SetLimiter(geometryLimiter) wayWriter.Start() @@ -282,7 +267,7 @@ func mainimport() { nodes := osmCache.Nodes.Iter() nodeWriter := writer.NewNodeWriter(osmCache, nodes, db, - pointsTagMatcher, progress, config.ImportOptions.Base.Srid) + pointsTagMatcher, progress, config.BaseOptions.Srid) nodeWriter.SetLimiter(geometryLimiter) nodeWriter.Start()