You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2018/11/19 18:22:33 UTC
[mynewt-newt] 02/03: ycfg: Add name string
This is an automated email from the ASF dual-hosted git repository.
ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git
commit 8d32a7a185b784d39a5d1dde27ed33a0e43e61f7
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Nov 7 17:22:10 2018 -0800
ycfg: Add name string
This is to help users debug bad YAML files. When a YCfg object is
created, the YAML filename is associated with the YCfg. When an error
is encountered, the warning / error text can contain the name of the bad
file.
---
newt/cli/target_cmds.go | 3 +-
newt/newtutil/newtutil.go | 13 ++++--
newt/pkg/bsp_package.go | 14 ++++--
newt/pkg/localpackage.go | 42 +++++++++--------
newt/settings/settings.go | 9 ++--
newt/target/target.go | 23 +++++-----
newt/ycfg/ycfg.go | 114 ++++++++++++++++++++++++++++------------------
7 files changed, 129 insertions(+), 89 deletions(-)
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index 04c3260..62182af 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -35,7 +35,6 @@ import (
"mynewt.apache.org/newt/newt/resolve"
"mynewt.apache.org/newt/newt/syscfg"
"mynewt.apache.org/newt/newt/target"
- "mynewt.apache.org/newt/newt/ycfg"
"mynewt.apache.org/newt/util"
)
@@ -304,7 +303,7 @@ func targetSetCmd(cmd *cobra.Command, args []string) {
// A few variables are special cases; they get set in the base package
// instead of the target.
if kv[0] == "target.syscfg" {
- t.Package().SyscfgY = ycfg.YCfg{}
+ t.Package().SyscfgY.Clear()
kv, err := syscfg.KeyValueFromStr(kv[1])
if err != nil {
NewtUsage(cmd, err)
diff --git a/newt/newtutil/newtutil.go b/newt/newtutil/newtutil.go
index 96795cd..3ea9fe2 100644
--- a/newt/newtutil/newtutil.go
+++ b/newt/newtutil/newtutil.go
@@ -176,19 +176,24 @@ func MakeTempRepoDir() (string, error) {
}
func ReadConfigPath(path string) (ycfg.YCfg, error) {
+ yc := ycfg.NewYCfg(path)
+
file, err := ioutil.ReadFile(path)
if err != nil {
- return ycfg.YCfg{}, util.FmtNewtError("Error reading %s: %s",
- path, err.Error())
+ return yc, util.ChildNewtError(err)
}
settings := map[string]interface{}{}
if err := yaml.Unmarshal(file, &settings); err != nil {
- return ycfg.YCfg{}, util.FmtNewtError("Failure parsing \"%s\": %s",
+ return yc, util.FmtNewtError("Failure parsing \"%s\": %s",
path, err.Error())
}
- return ycfg.NewYCfg(path, settings)
+ if err := yc.Populate(settings); err != nil {
+ return yc, err
+ }
+
+ return yc, nil
}
// Read in the configuration file specified by name, in path
diff --git a/newt/pkg/bsp_package.go b/newt/pkg/bsp_package.go
index 56399a0..1406593 100644
--- a/newt/pkg/bsp_package.go
+++ b/newt/pkg/bsp_package.go
@@ -20,6 +20,7 @@
package pkg
import (
+ "fmt"
"runtime"
"strings"
@@ -44,6 +45,10 @@ type BspPackage struct {
BspV ycfg.YCfg
}
+func (bsp *BspPackage) BspYamlPath() string {
+ return fmt.Sprintf("%s/%s", bsp.BasePath(), BSP_YAML_FILENAME)
+}
+
func (bsp *BspPackage) resolvePathSetting(
settings map[string]string, key string) (string, error) {
@@ -111,12 +116,11 @@ func (bsp *BspPackage) Reload(settings map[string]string) error {
}
settings[strings.ToUpper(runtime.GOOS)] = "1"
- bsp.BspV, err = newtutil.ReadConfig(bsp.BasePath(),
- strings.TrimSuffix(BSP_YAML_FILENAME, ".yml"))
+ bsp.BspV, err = newtutil.ReadConfigPath(bsp.BspYamlPath())
if err != nil {
return err
}
- bsp.AddCfgFilename(bsp.BasePath() + BSP_YAML_FILENAME)
+ bsp.AddCfgFilename(bsp.BspYamlPath())
bsp.CompilerName = bsp.BspV.GetValString("bsp.compiler", settings)
bsp.Arch = bsp.BspV.GetValString("bsp.arch", settings)
@@ -171,10 +175,12 @@ func NewBspPackage(lpkg *LocalPackage) (*BspPackage, error) {
CompilerName: "",
DownloadScript: "",
DebugScript: "",
- BspV: ycfg.YCfg{},
}
+
lpkg.Load()
bsp.LocalPackage = lpkg
+ bsp.BspV = ycfg.NewYCfg(bsp.BspYamlPath())
+
err := bsp.Reload(nil)
return bsp, err
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index 0b23036..072726f 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -77,12 +77,13 @@ type LocalPackage struct {
func NewLocalPackage(r *repo.Repo, pkgDir string) *LocalPackage {
pkg := &LocalPackage{
desc: &PackageDesc{},
- PkgY: ycfg.YCfg{},
- SyscfgY: ycfg.YCfg{},
repo: r,
basePath: filepath.ToSlash(filepath.Clean(pkgDir)),
injectedSettings: map[string]string{},
}
+
+ pkg.PkgY = ycfg.NewYCfg(pkg.PkgYamlPath())
+ pkg.SyscfgY = ycfg.NewYCfg(pkg.SyscfgYamlPath())
return pkg
}
@@ -117,6 +118,14 @@ func (pkg *LocalPackage) RelativePath() string {
return strings.TrimPrefix(pkg.BasePath(), proj.Path())
}
+func (pkg *LocalPackage) PkgYamlPath() string {
+ return fmt.Sprintf("%s/%s", pkg.BasePath(), PACKAGE_FILE_NAME)
+}
+
+func (pkg *LocalPackage) SyscfgYamlPath() string {
+ return fmt.Sprintf("%s/%s", pkg.BasePath(), SYSCFG_YAML_FILENAME)
+}
+
func (pkg *LocalPackage) Type() interfaces.PackageType {
return pkg.packageType
}
@@ -203,10 +212,8 @@ func (pkg *LocalPackage) readDesc(yc ycfg.YCfg) (*PackageDesc, error) {
func (pkg *LocalPackage) sequenceString(key string) string {
var buffer bytes.Buffer
- if pkg.PkgY != nil {
- for _, f := range pkg.PkgY.GetValStringSlice(key, nil) {
- buffer.WriteString(" - " + yaml.EscapeString(f) + "\n")
- }
+ for _, f := range pkg.PkgY.GetValStringSlice(key, nil) {
+ buffer.WriteString(" - " + yaml.EscapeString(f) + "\n")
}
if buffer.Len() == 0 {
@@ -222,8 +229,7 @@ func (lpkg *LocalPackage) SaveSyscfg() error {
return util.NewNewtError(err.Error())
}
- filepath := dirpath + "/" + SYSCFG_YAML_FILENAME
- file, err := os.Create(filepath)
+ file, err := os.Create(lpkg.SyscfgYamlPath())
if err != nil {
return util.NewNewtError(err.Error())
}
@@ -244,8 +250,7 @@ func (pkg *LocalPackage) Save() error {
return util.NewNewtError(err.Error())
}
- filepath := dirpath + "/" + PACKAGE_FILE_NAME
- file, err := os.Create(filepath)
+ file, err := os.Create(pkg.PkgYamlPath())
if err != nil {
return util.NewNewtError(err.Error())
}
@@ -291,12 +296,11 @@ func (pkg *LocalPackage) Load() error {
var err error
- pkg.PkgY, err = newtutil.ReadConfig(pkg.basePath,
- strings.TrimSuffix(PACKAGE_FILE_NAME, ".yml"))
+ pkg.PkgY, err = newtutil.ReadConfigPath(pkg.PkgYamlPath())
if err != nil {
return err
}
- pkg.AddCfgFilename(pkg.basePath + "/" + PACKAGE_FILE_NAME)
+ pkg.AddCfgFilename(pkg.PkgYamlPath())
// Set package name from the package
pkg.name = pkg.PkgY.GetValString("pkg.name", nil)
@@ -353,15 +357,13 @@ func (pkg *LocalPackage) Load() error {
}
// Load syscfg settings.
- if util.NodeExist(pkg.basePath + "/" + SYSCFG_YAML_FILENAME) {
- pkg.SyscfgY, err = newtutil.ReadConfig(pkg.basePath,
- strings.TrimSuffix(SYSCFG_YAML_FILENAME, ".yml"))
- if err != nil {
- return err
- }
- pkg.AddCfgFilename(pkg.basePath + "/" + SYSCFG_YAML_FILENAME)
+ pkg.SyscfgY, err = newtutil.ReadConfigPath(pkg.SyscfgYamlPath())
+ if err != nil && !util.IsNotExist(err) {
+ return err
}
+ pkg.AddCfgFilename(pkg.SyscfgYamlPath())
+
return nil
}
diff --git a/newt/settings/settings.go b/newt/settings/settings.go
index 1613505..24cd6a5 100644
--- a/newt/settings/settings.go
+++ b/newt/settings/settings.go
@@ -33,7 +33,7 @@ const NEWTRC_DIR string = ".newt"
const REPOS_FILENAME string = "repos.yml"
// Contains general newt settings read from $HOME/.newt
-var newtrc ycfg.YCfg
+var newtrc *ycfg.YCfg
func readNewtrc() ycfg.YCfg {
usr, err := user.Current()
@@ -54,9 +54,10 @@ func readNewtrc() ycfg.YCfg {
func Newtrc() ycfg.YCfg {
if newtrc != nil {
- return newtrc
+ return *newtrc
}
- newtrc = readNewtrc()
- return newtrc
+ yc := readNewtrc()
+ newtrc = &yc
+ return yc
}
diff --git a/newt/target/target.go b/newt/target/target.go
index 0979854..ee3acdc 100644
--- a/newt/target/target.go
+++ b/newt/target/target.go
@@ -20,10 +20,10 @@
package target
import (
+ "fmt"
"os"
"path/filepath"
"strconv"
- "strings"
"mynewt.apache.org/newt/newt/newtutil"
"mynewt.apache.org/newt/newt/pkg"
@@ -56,9 +56,13 @@ type Target struct {
func NewTarget(basePkg *pkg.LocalPackage) *Target {
target := &Target{
- TargetY: ycfg.YCfg{},
+ basePkg: basePkg,
}
- target.Init(basePkg)
+
+ if basePkg.SyscfgY.Tree() == nil {
+ panic("Fatal: target missing syscfg")
+ }
+ target.TargetY = ycfg.NewYCfg(target.TargetYamlPath())
return target
}
@@ -71,13 +75,12 @@ func LoadTarget(basePkg *pkg.LocalPackage) (*Target, error) {
return target, nil
}
-func (target *Target) Init(basePkg *pkg.LocalPackage) {
- target.basePkg = basePkg
+func (target *Target) TargetYamlPath() string {
+ return fmt.Sprintf("%s/%s", target.basePkg.BasePath(), TARGET_FILENAME)
}
func (target *Target) Load(basePkg *pkg.LocalPackage) error {
- yc, err := newtutil.ReadConfig(basePkg.BasePath(),
- strings.TrimSuffix(TARGET_FILENAME, ".yml"))
+ yc, err := newtutil.ReadConfigPath(target.TargetYamlPath())
if err != nil {
return err
}
@@ -110,7 +113,7 @@ func (target *Target) Load(basePkg *pkg.LocalPackage) error {
// Remember the name of the configuration file so that it can be specified
// as a dependency to the compiler.
- target.basePkg.AddCfgFilename(basePkg.BasePath() + TARGET_FILENAME)
+ target.basePkg.AddCfgFilename(target.TargetYamlPath())
return nil
}
@@ -263,9 +266,7 @@ func (t *Target) Save() error {
return err
}
- dirpath := t.basePkg.BasePath()
- filepath := dirpath + "/" + TARGET_FILENAME
- file, err := os.Create(filepath)
+ file, err := os.Create(t.TargetYamlPath())
if err != nil {
return util.NewNewtError(err.Error())
}
diff --git a/newt/ycfg/ycfg.go b/newt/ycfg/ycfg.go
index db0f1fb..53b4d71 100644
--- a/newt/ycfg/ycfg.go
+++ b/newt/ycfg/ycfg.go
@@ -23,10 +23,10 @@ import (
"fmt"
"strings"
- log "github.com/Sirupsen/logrus"
"github.com/spf13/cast"
"mynewt.apache.org/newt/newt/parse"
+ "mynewt.apache.org/newt/util"
)
// YAML configuration object. This is a substitute for a viper configuration
@@ -66,7 +66,13 @@ import (
// Since each expression is a child node of the setting in question, they are
// all known at the time of the lookup. To determine the value of the setting,
// each expression is parsed, and only the one evaluating to true is selected.
-type YCfg map[string]*YCfgNode
+type YCfg struct {
+ // Name of config; typically a YAML filename.
+ name string
+
+ // The settings.
+ tree YCfgTree
+}
type YCfgEntry struct {
Value interface{}
@@ -77,29 +83,39 @@ type YCfgNode struct {
Overwrite bool
Name string
Value interface{}
- Children YCfg
+ Children YCfgTree
Parent *YCfgNode
}
+func (yc *YCfg) Tree() YCfgTree {
+ return yc.tree
+}
+
+type YCfgTree map[string]*YCfgNode
+
+func NewYCfgNode() *YCfgNode {
+ return &YCfgNode{Children: YCfgTree{}}
+}
+
func (node *YCfgNode) addChild(name string) (*YCfgNode, error) {
if node.Children == nil {
- node.Children = YCfg{}
+ node.Children = YCfgTree{}
}
if node.Children[name] != nil {
return nil, fmt.Errorf("Duplicate YCfgNode: %s", name)
}
- child := &YCfgNode{
- Name: name,
- Parent: node,
- }
+ child := NewYCfgNode()
+ child.Name = name
+ child.Parent = node
+
node.Children[name] = child
return child, nil
}
-func (yc YCfg) Replace(key string, val interface{}) error {
+func (yc *YCfg) Replace(key string, val interface{}) error {
elems := strings.Split(key, ".")
if len(elems) == 0 {
return fmt.Errorf("Invalid ycfg key: \"\"")
@@ -113,12 +129,12 @@ func (yc YCfg) Replace(key string, val interface{}) error {
var parent *YCfgNode
for i, e := range elems {
- var parentChildren YCfg
+ var parentChildren YCfgTree
if parent == nil {
- parentChildren = yc
+ parentChildren = yc.tree
} else {
if parent.Children == nil {
- parent.Children = YCfg{}
+ parent.Children = YCfgTree{}
}
parentChildren = parent.Children
}
@@ -131,7 +147,8 @@ func (yc YCfg) Replace(key string, val interface{}) error {
return err
}
} else {
- child = &YCfgNode{Name: e}
+ child = NewYCfgNode()
+ child.Name = e
parentChildren[e] = child
}
}
@@ -147,26 +164,31 @@ func (yc YCfg) Replace(key string, val interface{}) error {
return nil
}
-func NewYCfg(kv map[string]interface{}) (YCfg, error) {
- yc := YCfg{}
+func NewYCfg(name string) YCfg {
+ return YCfg{
+ name: name,
+ tree: YCfgTree{},
+ }
+}
+func (yc *YCfg) Populate(kv map[string]interface{}) error {
for k, v := range kv {
if err := yc.Replace(k, v); err != nil {
- return nil, err
+ return err
}
}
- return yc, nil
+ return nil
}
-func (yc YCfg) find(key string) *YCfgNode {
+func (yc *YCfg) find(key string) *YCfgNode {
elems := strings.Split(key, ".")
if len(elems) == 0 {
return nil
}
cur := &YCfgNode{
- Children: yc,
+ Children: yc.tree,
}
for _, e := range elems {
if cur.Children == nil {
@@ -182,7 +204,7 @@ func (yc YCfg) find(key string) *YCfgNode {
return cur
}
-func (yc YCfg) Get(key string, settings map[string]string) []YCfgEntry {
+func (yc *YCfg) Get(key string, settings map[string]string) []YCfgEntry {
node := yc.find(key)
if node == nil {
return nil
@@ -198,7 +220,7 @@ func (yc YCfg) Get(key string, settings map[string]string) []YCfgEntry {
for _, child := range node.Children {
val, err := parse.ParseAndEval(child.Name, settings)
if err != nil {
- log.Error(err.Error())
+ util.OneTimeWarning("%s: %s", yc.name, err.Error())
} else if val {
entry := YCfgEntry{
Value: child.Value,
@@ -215,7 +237,7 @@ func (yc YCfg) Get(key string, settings map[string]string) []YCfgEntry {
return entries
}
-func (yc YCfg) GetSlice(key string, settings map[string]string) []YCfgEntry {
+func (yc *YCfg) GetSlice(key string, settings map[string]string) []YCfgEntry {
sliceEntries := yc.Get(key, settings)
if len(sliceEntries) == 0 {
return nil
@@ -242,7 +264,7 @@ func (yc YCfg) GetSlice(key string, settings map[string]string) []YCfgEntry {
return result
}
-func (yc YCfg) GetValSlice(
+func (yc *YCfg) GetValSlice(
key string, settings map[string]string) []interface{} {
entries := yc.GetSlice(key, settings)
@@ -258,7 +280,7 @@ func (yc YCfg) GetValSlice(
return vals
}
-func (yc YCfg) GetStringSlice(key string,
+func (yc *YCfg) GetStringSlice(key string,
settings map[string]string) []YCfgEntry {
sliceEntries := yc.Get(key, settings)
@@ -287,7 +309,7 @@ func (yc YCfg) GetStringSlice(key string,
return result
}
-func (yc YCfg) GetValStringSlice(
+func (yc *YCfg) GetValStringSlice(
key string, settings map[string]string) []string {
entries := yc.GetStringSlice(key, settings)
@@ -305,7 +327,7 @@ func (yc YCfg) GetValStringSlice(
return vals
}
-func (yc YCfg) GetValStringSliceNonempty(
+func (yc *YCfg) GetValStringSliceNonempty(
key string, settings map[string]string) []string {
strs := yc.GetValStringSlice(key, settings)
@@ -319,7 +341,7 @@ func (yc YCfg) GetValStringSliceNonempty(
return filtered
}
-func (yc YCfg) GetStringMap(
+func (yc *YCfg) GetStringMap(
key string, settings map[string]string) map[string]YCfgEntry {
mapEntries := yc.Get(key, settings)
@@ -344,7 +366,7 @@ func (yc YCfg) GetStringMap(
return result
}
-func (yc YCfg) GetValStringMap(
+func (yc *YCfg) GetValStringMap(
key string, settings map[string]string) map[string]interface{} {
entryMap := yc.GetStringMap(key, settings)
@@ -359,7 +381,7 @@ func (yc YCfg) GetValStringMap(
return smap
}
-func (yc YCfg) GetFirst(key string, settings map[string]string) (YCfgEntry, bool) {
+func (yc *YCfg) GetFirst(key string, settings map[string]string) (YCfgEntry, bool) {
entries := yc.Get(key, settings)
if len(entries) == 0 {
return YCfgEntry{}, false
@@ -368,7 +390,7 @@ func (yc YCfg) GetFirst(key string, settings map[string]string) (YCfgEntry, bool
return entries[0], true
}
-func (yc YCfg) GetFirstVal(key string, settings map[string]string) interface{} {
+func (yc *YCfg) GetFirstVal(key string, settings map[string]string) interface{} {
entry, ok := yc.GetFirst(key, settings)
if !ok {
return nil
@@ -377,7 +399,7 @@ func (yc YCfg) GetFirstVal(key string, settings map[string]string) interface{} {
return entry.Value
}
-func (yc YCfg) GetValString(key string, settings map[string]string) string {
+func (yc *YCfg) GetValString(key string, settings map[string]string) string {
entry, ok := yc.GetFirst(key, settings)
if !ok {
return ""
@@ -386,7 +408,7 @@ func (yc YCfg) GetValString(key string, settings map[string]string) string {
}
}
-func (yc YCfg) GetValInt(key string, settings map[string]string) int {
+func (yc *YCfg) GetValInt(key string, settings map[string]string) int {
entry, ok := yc.GetFirst(key, settings)
if !ok {
return 0
@@ -395,7 +417,7 @@ func (yc YCfg) GetValInt(key string, settings map[string]string) int {
}
}
-func (yc YCfg) GetValBoolDflt(key string, settings map[string]string,
+func (yc *YCfg) GetValBoolDflt(key string, settings map[string]string,
dflt bool) bool {
entry, ok := yc.GetFirst(key, settings)
@@ -406,11 +428,11 @@ func (yc YCfg) GetValBoolDflt(key string, settings map[string]string,
}
}
-func (yc YCfg) GetValBool(key string, settings map[string]string) bool {
+func (yc *YCfg) GetValBool(key string, settings map[string]string) bool {
return yc.GetValBoolDflt(key, settings, false)
}
-func (yc YCfg) GetStringMapString(key string,
+func (yc *YCfg) GetStringMapString(key string,
settings map[string]string) map[string]YCfgEntry {
mapEntries := yc.Get(key, settings)
@@ -435,7 +457,7 @@ func (yc YCfg) GetStringMapString(key string,
return result
}
-func (yc YCfg) GetValStringMapString(key string,
+func (yc *YCfg) GetValStringMapString(key string,
settings map[string]string) map[string]string {
entryMap := yc.GetStringMapString(key, settings)
@@ -465,11 +487,15 @@ func (node *YCfgNode) FullName() string {
return strings.Join(tokens, ".")
}
-func (yc YCfg) Delete(name string) {
- delete(yc, name)
+func (yc *YCfg) Delete(key string) {
+ delete(yc.tree, key)
+}
+
+func (yc *YCfg) Clear() {
+ yc.tree = YCfgTree{}
}
-func (yc YCfg) Traverse(cb func(node *YCfgNode, depth int)) {
+func (yc *YCfg) Traverse(cb func(node *YCfgNode, depth int)) {
var traverseLevel func(
node *YCfgNode,
cb func(node *YCfgNode, depth int),
@@ -486,12 +512,12 @@ func (yc YCfg) Traverse(cb func(node *YCfgNode, depth int)) {
}
}
- for _, n := range yc {
+ for _, n := range yc.tree {
traverseLevel(n, cb, 0)
}
}
-func (yc YCfg) AllSettings() map[string]interface{} {
+func (yc *YCfg) AllSettings() map[string]interface{} {
settings := map[string]interface{}{}
yc.Traverse(func(node *YCfgNode, depth int) {
@@ -503,7 +529,7 @@ func (yc YCfg) AllSettings() map[string]interface{} {
return settings
}
-func (yc YCfg) AllSettingsAsStrings() map[string]string {
+func (yc *YCfg) AllSettingsAsStrings() map[string]string {
settings := yc.AllSettings()
smap := make(map[string]string, len(settings))
for k, v := range settings {
@@ -513,8 +539,8 @@ func (yc YCfg) AllSettingsAsStrings() map[string]string {
return smap
}
-func (yc YCfg) String() string {
- lines := make([]string, 0, len(yc))
+func (yc *YCfg) String() string {
+ lines := make([]string, 0, len(yc.tree))
yc.Traverse(func(node *YCfgNode, depth int) {
line := strings.Repeat(" ", depth*4) + node.Name
if node.Value != nil {