config

package
v0.0.0-...-6b15219 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2023 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package config is a simple library that manages config set-up for boardgame-util and friends, reading from config.json and config.SECRET.json files. See boardgame- util/README.md for more on the structure of config.json files.

Although a number of the details are exposed in this package, generally you just use Get() and then directly read the values of the returned Config's Dev and Prod properties.

Index

Constants

View Source
const (
	//FieldInvalid is an invalid default value
	FieldInvalid ModeField = "<INVALID>"
	//FieldAllowedOrigins denotes that field of the output
	FieldAllowedOrigins = "AllowedOrigins"
	//FieldDefaultPort denotes that field of the output
	FieldDefaultPort = "DefaultPort"
	//FieldDefaultStaticPort denotes that field of the output
	FieldDefaultStaticPort = "DefaultStaticPort"
	//FieldAdminUserIds denotes that field of the output
	FieldAdminUserIds = "AdminUserIds"
	//FieldDisableAdminChecking denotes that field of the output
	FieldDisableAdminChecking = "DisableAdminChecking"
	//FieldOfflineDevMode denotes that field of the output
	FieldOfflineDevMode = "OfflineDevMode"
	//FieldStorage denotes that field of the output
	FieldStorage = "Storage"
	//FieldDefaultStorageType denotes that field of the output
	FieldDefaultStorageType = "DefaultStorageType"
	//FieldGoogleAnalytics denotes that field of the output
	FieldGoogleAnalytics = "GoogleAnalytics"
	//FieldFirebase denotes that field of the output
	FieldFirebase = "Firebase"
	//FieldAPIHost denotes that field of the output
	FieldAPIHost = "ApiHost"
	//FieldGames denotes that field of the output
	FieldGames = "Games"
)
View Source
const (
	//FirebaseInvalid denotes an invalid default key
	FirebaseInvalid FirebaseKey = "<INVALID>"
	//FirebaseAPIKey denotes the apiKey key in firebase
	FirebaseAPIKey = "apiKey"
	//FirebaseAuthDomain denotes the authDomain key in firebase
	FirebaseAuthDomain = "authDomain"
	//FirebaseDatabaseURL denotes the databaseURL key in firebase
	FirebaseDatabaseURL = "databaseURL"
	//FirebaseProjectID denotes the projectId key in firebase
	FirebaseProjectID = "projectId"
	//FirebaseStorageBucket denotes the storageBucket key in firebase
	FirebaseStorageBucket = "storageBucket"
	//FirebaseMessagingSenderID denotes the messagingSenderId key in firebase
	FirebaseMessagingSenderID = "messagingSenderId"
)

Variables

FieldTypes maps each ConfigModeField to its ConfigModeFieldType.

FirebaseKeys enumerates all firebase keys

Functions

func DefaultFileNames

func DefaultFileNames(dirOrFile string) (publicConfig, privateConfig string, err error)

DefaultFileNames returns the publicConfig and privateConfig names for the given path, even if they don't exist. If dirOrFile ends in ".json" then that will be returned, with privateConfig being in the same folder. If it's a dir, it will be the default filenames in that folder.

func FileNames

func FileNames(dir string, skipUpwardSearch bool) (publicConfig, privateConfig string, err error)

FileNames returns the publicConfig filename and privateConfig filename to use given the search path. If dir is a config file itself, loads that (and any private component in same directory). Next it interprets dir as a directory to search within for any config files. If none are found, walks upwards in the directory hierarchy (as long as that's still in $GOPATH) until it finds a folder that appears to work. If dir is "", working directory is assumed. If skipUpwardSearch is true, then if dir is non-blank upward searching in the dir hiearchy will not be done.

Types

type ClientConfig

type ClientConfig struct {
	Firebase        *FirebaseConfig `json:"firebase"`
	GoogleAnalytics string          `json:"google_analytics"`
	Host            string          `json:"host"`
	DevHost         string          `json:"dev_host"`
	OfflineDevMode  bool            `json:"offline_dev_mode,omitempty"`
}

ClientConfig is the struct representation of a client config that the client web application expects. It can be generated from a config object via Client(). Its json representation is what the client web app expects.

type Config

type Config struct {
	Dev  *Mode
	Prod *Mode
	// contains filtered or unexported fields
}

Config represents the derived config values. It is based on RawConfigs. This is the object you generally use directly in your application.

func DefaultStarterConfig

func DefaultStarterConfig(dirOrFile string) *Config

DefaultStarterConfig returns the default starting config, which is most appropriate starting point. dirOrFile will be used to give the path name, using DefaultFileNames. Leave "" for default.

func Get

func Get(dir string, createIfNotExist bool) (*Config, error)

Get fetches a fully realized config. It is a simple convenience wrapper around FileNames and GetConfig. If createIfNotExist is true, then if the files don't exist on disk we'll generate file names and return raw configs for those filenames.

func GetConfig

func GetConfig(publicConfigFile, privateConfigFile string, createIfNotExist bool) (*Config, error)

GetConfig returns a Config for those two named files. publicConfig and privateConfig may both be "" without erroring. If createIfNotExist is true, then NewRawConfig will be told to create the Configs even if they don't exist on disk.

func MinimalStarterConfig

func MinimalStarterConfig(dirOrFile string) *Config

MinimalStarterConfig returns a minimal config starter point, with minimal settings you might want to set. dirOrFile will be used to give the path name, using DefaultFileNames. Leave "" for default.

func NewConfig

func NewConfig(raw, rawSecret *RawConfig) *Config

NewConfig returns a new, derived config object based on the given raw configs, using primarily mode.Extend, mode.Derive in the right order to produce the result. Both raw and rawSecret may be nil. In general you don't use this directly, but use Get().

func SampleStarterConfig

func SampleStarterConfig(dirOrFile string) *Config

SampleStarterConfig returns a full sample starting config, which is also provided in `boardgame/config.SAMPLE.json`. dirOrFile will be used to give the path name, using DefaultFileNames. Leave "" for default.

func (*Config) AddOverride

func (c *Config) AddOverride(o OptionOverrider)

AddOverride takes an OptionOverrider. Overrides are applied to the final Dev and Prod configModes after they are derived, passing prodMode of true for the prod mode. If you want an override to only apply to dev or prod, the OptionOverrider you pass should filter based on prodMode. The changes are temporary and will not be persisted to disk when Save() is called. If you want changes that will be persisted, see Update.

func (*Config) Client

func (c *Config) Client(prodMode bool) *ClientConfig

Client returns a ClientConfig derived from the given config. The returned ClientConfig is reasonable to marshal to json and encode for the client web app. Will use the firebase and google analytics block from dev mode unless prodMode is true. In practice those blocks rarely differ in dev or prod mode so that parameter shouldn't matter.

func (*Config) Path

func (c *Config) Path() string

Path returns the path that this config's public components were loaded from. Convenience wrapper around c.RawConfig().Path().

func (*Config) RawConfig

func (c *Config) RawConfig() *RawConfig

RawConfig returns the underlying, non-secret config that this derived config is based on.

func (*Config) RawSecretConfig

func (c *Config) RawSecretConfig() *RawConfig

RawSecretConfig returns the underlying secret config that this derived config is based on, or nil if there is no secret component.

func (*Config) Save

func (c *Config) Save() error

Save saves the two underlying RawConfigs back to disk. Convenience wrapper around RawConfig().Save(), RawSecretConfig.Save()

func (*Config) SecretPath

func (c *Config) SecretPath() string

SecretPath returns the path that this config's secret components were loaded from, or "" if no secret components. Convenience wrapper around c.RawSecretConfig().Path().

func (*Config) Update

func (c *Config) Update(typ ModeType, secret bool, updater Updater) error

Update modifies the config in a specified way. typ and secret select the RawConfigMode to modify (creating one if necessary) and then updater applies the update. See Set* functions in this package for factories for common Updater. After the update, the Config has all of its values rederived to reflect the change. If you want changes that will not be persisted, see AddOverride.

type FirebaseConfig

type FirebaseConfig struct {
	APIKey            string `json:"apiKey"`
	AuthDomain        string `json:"authDomain"`
	DatabaseURL       string `json:"databaseURL"`
	ProjectID         string `json:"projectId"`
	StorageBucket     string `json:"storageBucket"`
	MessagingSenderID string `json:"messagingSenderId"`
}

FirebaseConfig is a sub-struct within ConfigMode that holds values specific to firebase.

type FirebaseKey

type FirebaseKey string

FirebaseKey denotes a specific key in a firebase object

func FirebaseKeyFromString

func FirebaseKeyFromString(key string) FirebaseKey

FirebaseKeyFromString returns the FirebseKey denoted by key (fuzzy matching).

type GameNode

type GameNode struct {
	Leafs []string
	Mids  map[string]*GameNode
}

GameNode is a special struct that can represent either the terminal leaf game packages, or the mid-folders. It has its own UnmarshalJSON which decides based on the raw json whether to populate Leafs or Mids. This means that the actual JSON ingested can elide the "Leafs" or "Mids" keys for brevity.

A Leafs that has the value "" means "one key with no additional suffix". This allows terminating leafs within a node that is otherwise a mid.

Example valid JSON to ingest for GameNode:

{
	"github.com/jkomoros": {
		"boardgame/examples": [
			"checkers",
			"blackjack"
		],
		"other-games-repo": [
			"pass"
		],
		"other-mixed-leaf-mid-repo": {
			"leaf": [
				""
			],
			"subdir": [
				"foo"
			]
		}
	}
}

func NewGameNode

func NewGameNode(paths ...string) *GameNode

NewGameNode takes the given values and creates a reduced GameNode tree where all of the common prefixes are factored out.

func (*GameNode) AddGame

func (g *GameNode) AddGame(game string) *GameNode

AddGame adds the given game to the list and returns a game node that contains it.

func (*GameNode) List

func (g *GameNode) List() []string

List returns a flattened, alphabetized, unique list of paths implied by the contents of this node. Mids are joined by filepath.Separator.

Input:

{
	"github.com/jkomoros": {
		"boardgame/examples": [
			"checkers",
			"blackjack"
		],
		"other-games-repo": [
			"pass"
		],
		"other-mixed-leaf-mid-repo": {
			"leaf": [
				""
			],
			"subdir": [
				"foo"
			]
		}
	}
}

Output:

[
	"github.com/jkomoros/boardgame/examples/blackjack",
	"github.com/jkomoros/boardgame/examples/checkers",
	"github.com/jkomoros/other-games-repo/pass",
	"github.com/jkomoros/other-mixed-leaf-mid-repo/leaf",
	"github.com/jkomoros/other-mixed-leaf-mid-repo/subdir/foo",
]

func (*GameNode) MarshalJSON

func (g *GameNode) MarshalJSON() ([]byte, error)

MarshalJSON packs the given GameNode into a JSON payload.

func (*GameNode) Normalize

func (g *GameNode) Normalize() *GameNode

Normalize returns a GameNode representing the same list of games, but in a canonically normalized tree structure.

func (*GameNode) RemoveGame

func (g *GameNode) RemoveGame(game string) *GameNode

RemoveGame returns a game node that doesn't generate `game`.

func (*GameNode) UnmarshalJSON

func (g *GameNode) UnmarshalJSON(raw []byte) error

UnmarshalJSON unpacks the GameNode JSON payload into a valid GameNode.

type Mode

type Mode struct {
	//ConfigMode is primarily just the common config mode values
	ModeCommon
	//Games is not intended to be inflated from JSON, but rather is derived
	//based on the contents of Games. It is OK to use literally as Games in
	//RawConfig, though, because its serialization is a legal GamesNode.
	Games []string `json:"games"`
	// contains filtered or unexported fields
}

Mode is the final, derived struct holding all of the leaf values in config.

func (*Mode) AllGamePackages

func (c *Mode) AllGamePackages() ([]*gamepkg.Pkg, error)

AllGamePackages returns either a gamepkg for each listed game, or an error if any one of them was invalid. A wrapper around gamepkg.AllPackages(), that passes the path of the config as optionalBasePath, so that relative paths in games listed in config are interpreted as relative to the config.json, not whatever working directory boardgame-util is being run in.

func (*Mode) GamePackages

func (c *Mode) GamePackages() ([]*gamepkg.Pkg, map[string]error)

GamePackages returns all of the game packages listed in Games[] that are valid, with errors for the invalid ones. A wrapper around gamepkg.Packages(), that passes the path of the config as optionalBasePath, so that relative paths in games listed in config are interpreted as relative to the config.json, not whatever working directory boardgame-util is being run in.

func (*Mode) OriginAllowed

func (c *Mode) OriginAllowed(origin string) bool

OriginAllowed returns whether the given orgiin is allowed, based on the configuration of AllowedOrigins, which treats "" and "*" specially.

func (*Mode) ParentConfig

func (c *Mode) ParentConfig() *Config

ParentConfig returns the Config that this ConfigMode is part of. Specifically, returns the config that was passed as ParentConfig to RawConfigMode.Derive().

func (*Mode) String

func (c *Mode) String() string

type ModeCommon

type ModeCommon struct {
	AllowedOrigins    string   `json:"allowedOrigins,omitempty"`
	DefaultPort       string   `json:"defaultPort,omitempty"`
	DefaultStaticPort string   `json:"defaultStaticPort,omitempty"`
	AdminUserIds      []string `json:"adminUserIds,omitempty"`
	//This is a dangerous config. Only enable in Dev!
	DisableAdminChecking bool `json:"disableAdminChecking,omitempty"`
	//This is a dangerous config, designed to only be used in dev.
	OfflineDevMode bool              `json:"offlineDevMode,omitempty"`
	Storage        map[string]string `json:"storage,omitempty"`
	//The storage type that should be used if no storage type is provided via
	//command line options.
	DefaultStorageType string `json:"defaultStorageType,omitempty"`

	//The GA config string. Will be used to generate the client_config json
	//blob. Generally has a structure like "UA-321655-11"
	GoogleAnalytics string          `json:"googleAnalytics,omitempty"`
	Firebase        *FirebaseConfig `json:"firebase,omitempty"`
	//The host name the client should connect to in that mode. Something like
	//"http://localhost:8888"
	APIHost string `json:"apiHost,omitempty"`
}

ModeCommon is the values that both ConfigMode and RawConfigMode share directly, factored out for convenience so they can be anonymously embedded in ConfigMdoe and RawConfigMode.

type ModeField

type ModeField string

ModeField denotes the field in a RawConfigMode. Used to pass to the UpdateConfig family of function factories.

func FieldFromString

func FieldFromString(s string) ModeField

FieldFromString returns a ModeField by doing fuzzing matching.

type ModeFieldType

type ModeFieldType int

ModeFieldType is the type of field in RawConfigMode. Different UpdateConfig function factories only work on certain types of fields.

const (
	//FieldTypeInvalid is an invalid default value
	FieldTypeInvalid ModeFieldType = iota
	//FieldTypeString denotes a field with type string
	FieldTypeString
	//FieldTypeStringSlice denotes a field with type []string
	FieldTypeStringSlice
	//FieldTypeStringMap denotes a field with type map[string]string
	FieldTypeStringMap
	//FieldTypeBool denotes a field with type bool
	FieldTypeBool
	//FieldTypeFirebase denotes a field with type firebase
	FieldTypeFirebase
	//FieldTypeGameNode denotes a field with type GameNode
	FieldTypeGameNode
)

type ModeType

type ModeType int

ModeType defines which sub-mode (Base, Dev, or Prod) we're referring to.

const (
	//TypeBase referrs to the Base sub-mode that underlies both Dev and Prod.
	TypeBase ModeType = iota
	//TypeDev referrs to the Dev sub-mode that builds on top of Base.
	TypeDev
	//TypeProd referrs to the Prod sub-mode that builds on top of Base.
	TypeProd
)

type OptionOverrider

type OptionOverrider func(prodMode bool, c *Mode)

OptionOverrider is a class of function that is the primary option that config.AddOverride takes. They take a configmode and modify some number of properties. prodMode is true if it's being called on the prod option, false if on dev. A few are defined as conveniences in this package.

func EnableOfflineDevMode

func EnableOfflineDevMode() OptionOverrider

EnableOfflineDevMode returns an OptionOverrider that can be passed to config.AddOverride. It simply sets OfflineDevMode to true. It will not modify ProdMode, since that value is unsafe in prod mode.

type RawConfig

type RawConfig struct {
	Base *RawConfigMode `json:"base,omitempty"`
	Dev  *RawConfigMode `json:"dev,omitempty"`
	Prod *RawConfigMode `json:"prod,omitempty"`
	// contains filtered or unexported fields
}

RawConfig corresponds to the raw input/output from disk without any modifications. The derived Config object will use RawConfig's and combine them to create the overall Config.

func NewRawConfig

func NewRawConfig(filename string, create bool) (*RawConfig, error)

NewRawConfig loads up a raw config given a config.json file on disk. Generally you don't use this directly, but instead use Get(). If create is true, then if the file doesn't exist on disk it's not an error, and a blank config with that name will be returned.

func (*RawConfig) HasContent

func (r *RawConfig) HasContent() bool

HasContent returns true if there is any content in the RawConfig at all.

func (*RawConfig) Path

func (r *RawConfig) Path() string

Path returns the filename of the file that this RawConfig represents on disk.

func (*RawConfig) Save

func (r *RawConfig) Save() error

Save saves RawConfig back to disk at Path(). If HasContent() returns false and Path() doesn't exist yet, no file is saved and a nil error is returned.

type RawConfigMode

type RawConfigMode struct {
	//ConfigMode is primarily just the common config mode values
	ModeCommon
	Games *GameNode `json:"games,omitempty"`
}

RawConfigMode is the leaf of RawConfig, where all of the actual values are stored.

func (*RawConfigMode) Copy

func (c *RawConfigMode) Copy() *RawConfigMode

Copy returns a deep copy of the RawConfigMode.

func (*RawConfigMode) Derive

func (c *RawConfigMode) Derive(parentConfig *Config, prodMode bool) *Mode

Derive tells the RawConfigMode to create a new, fully derived ConfigMode based on the current properties of this RawConfigMode, setting defaults as necessary. parentConfig is the Config that this configMode will be part of. prodMode is whether the ConfigMode being derived is for a Prod or Dev slot in Config. Will always return a reasonably defaulted ConfigMode even if the RawcConfigMode itself is nil. Generally you don't call this, but use NewConfig() instead.

func (*RawConfigMode) Extend

func (c *RawConfigMode) Extend(other *RawConfigMode) *RawConfigMode

Extend takes a given base config mode, extends it with properties set in other (with any non-zero value overwriting the base values, and with Games and string lists being merged and de-duped) and returns a *new* config representing the merged one. Normally you don't call this directly but use NewConfig instead.

func (*RawConfigMode) String

func (c *RawConfigMode) String() string

type Updater

type Updater func(r *RawConfigMode, typ ModeType) error

Updater is a function that takes a rawConfig and makes a modifcation in place on that object. It should return a non-nil error if it wasn't able to do the modification for some reason. These are one of the primary objects to config.Update(). This package defines a number of factories for these.

func AddGame

func AddGame(val string) Updater

AddGame adds the given value to the Games node. Val can be a path or import; in either case it's looked up via gamepkg, and its Import() is used if the package is valid. Returns an error if the package isn't valid.

func AddString

func AddString(field ModeField, val string) Updater

AddString adds the given string, if it doesn't exist, to the []string type ModeField. Field must be of FieldTypeStringSlice.

func DeleteString

func DeleteString(field ModeField) Updater

DeleteString returns a function to unset the given config string propert, as long as field is of type FieldTypeString.

func RemoveGame

func RemoveGame(val string) Updater

RemoveGame removes the given value from the Games node.

func RemoveString

func RemoveString(field ModeField, val string) Updater

RemoveString removes the given string, if it exists, from the []string type ModeField. If it was the last item to remove, sets that field to nil. Field must be of FieldTypeStringSlice.

func SetBool

func SetBool(field ModeField, val bool) Updater

SetBool sets the field denoted by field to the val. Field must be of type FieldTypeBool.

func SetFirebaseKey

func SetFirebaseKey(key FirebaseKey, val string) Updater

SetFirebaseKey sets the key denoted by FirebaseKey to val. Implicitly operates only on the FieldFirebase field. If Firebase is nil, initalizes it.

func SetString

func SetString(field ModeField, val string) Updater

SetString returns a function to set the given rawconfig string property to the given value. field must be of FieldTypeString.

func SetStringKey

func SetStringKey(field ModeField, key, val string) Updater

SetStringKey adds the given key and val to the map[string]string field denoted by field. If that key is already set, it updates it to the new value. If the map is nil, creates one. Field must be of FieldTypeStringMap. If val is "" then the key will be deleted.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL