github.com/jbendotnet/noms@v0.0.0-20190904222105-c43e4293ea92/go/config/resolver.go (about)

     1  // Copyright 2016 Attic Labs, Inc. All rights reserved.
     2  // Licensed under the Apache License, version 2.0:
     3  // http://www.apache.org/licenses/LICENSE-2.0
     4  
     5  package config
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  
    11  	"github.com/attic-labs/noms/go/chunks"
    12  	"github.com/attic-labs/noms/go/datas"
    13  	"github.com/attic-labs/noms/go/spec"
    14  	"github.com/attic-labs/noms/go/types"
    15  	"github.com/attic-labs/noms/go/util/verbose"
    16  )
    17  
    18  type Resolver struct {
    19  	config      *Config
    20  	dotDatapath string // set to the first datapath that was resolved
    21  }
    22  
    23  // A Resolver enables using db defaults, db aliases and dataset '.' replacement in command
    24  // line arguments when a .nomsconfig file is present. To use it, create a config resolver
    25  // before command line processing and use it to resolve each dataspec argument in
    26  // succession.
    27  func NewResolver() *Resolver {
    28  	c, err := FindNomsConfig()
    29  	if err != nil {
    30  		if err != NoConfig {
    31  			panic(fmt.Errorf("Failed to read .nomsconfig due to: %v", err))
    32  		}
    33  		return &Resolver{}
    34  	}
    35  	return &Resolver{c, ""}
    36  }
    37  
    38  // Print replacement if one occurred
    39  func (r *Resolver) verbose(orig string, replacement string) string {
    40  	if orig != replacement {
    41  		if orig == "" {
    42  			orig = `""`
    43  		}
    44  		verbose.Log("\tresolving %s -> %s\n", orig, replacement)
    45  	}
    46  	return replacement
    47  }
    48  
    49  // Resolve string to database name. If config is defined:
    50  //   - replace the empty string with the default db url
    51  //   - replace any db alias with it's url
    52  func (r *Resolver) ResolveDbSpec(str string) string {
    53  	if r.config != nil {
    54  		if str == "" {
    55  			return r.config.Db[DefaultDbAlias].Url
    56  		}
    57  		if val, ok := r.config.Db[str]; ok {
    58  			return val.Url
    59  		}
    60  	}
    61  	return str
    62  }
    63  
    64  // Resolve string to dataset or path name.
    65  //   - replace database name as described in ResolveDatabase
    66  //   - if this is the first call to ResolvePath, remember the
    67  //     datapath part for subsequent calls.
    68  //   - if this is not the first call and a "." is used, replace
    69  //     it with the first datapath.
    70  func (r *Resolver) ResolvePathSpec(str string) string {
    71  	if r.config != nil {
    72  		split := strings.SplitN(str, spec.Separator, 2)
    73  		db, rest := "", split[0]
    74  		if len(split) > 1 {
    75  			db, rest = split[0], split[1]
    76  		}
    77  		if r.dotDatapath == "" {
    78  			r.dotDatapath = rest
    79  		} else if rest == "." {
    80  			rest = r.dotDatapath
    81  		}
    82  		return r.ResolveDbSpec(db) + spec.Separator + rest
    83  	}
    84  	return str
    85  }
    86  
    87  // Resolve string to database spec. If a config is present,
    88  //   - resolve a db alias to its db spec
    89  //   - resolve "" to the default db spec
    90  func (r *Resolver) GetDatabase(str string) (datas.Database, error) {
    91  	sp, err := spec.ForDatabase(r.verbose(str, r.ResolveDbSpec(str)))
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  	return sp.GetDatabase(), nil
    96  }
    97  
    98  // Resolve string to a chunkstore. Like ResolveDatabase, but returns the underlying ChunkStore
    99  func (r *Resolver) GetChunkStore(str string) (chunks.ChunkStore, error) {
   100  	sp, err := spec.ForDatabase(r.verbose(str, r.ResolveDbSpec(str)))
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	return sp.NewChunkStore(), nil
   105  }
   106  
   107  // Resolve string to a dataset. If a config is present,
   108  //  - if no db prefix is present, assume the default db
   109  //  - if the db prefix is an alias, replace it
   110  func (r *Resolver) GetDataset(str string) (datas.Database, datas.Dataset, error) {
   111  	sp, err := spec.ForDataset(r.verbose(str, r.ResolvePathSpec(str)))
   112  	if err != nil {
   113  		return nil, datas.Dataset{}, err
   114  	}
   115  	return sp.GetDatabase(), sp.GetDataset(), nil
   116  }
   117  
   118  // Resolve string to a value path. If a config is present,
   119  //  - if no db spec is present, assume the default db
   120  //  - if the db spec is an alias, replace it
   121  func (r *Resolver) GetPath(str string) (datas.Database, types.Value, error) {
   122  	sp, err := spec.ForPath(r.verbose(str, r.ResolvePathSpec(str)))
   123  	if err != nil {
   124  		return nil, nil, err
   125  	}
   126  	return sp.GetDatabase(), sp.GetValue(), nil
   127  }