Repository: incubator-mynewt-newt
Updated Branches:
  refs/heads/develop 05d40c264 -> 0694075af


add feature_blacklist and feature_whitelist, to control where features are 
present.  these can only be set in tlps (bsp, app, target).  automatically add 
definitions for FEATURE_* when a feature is enabled.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/0694075a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/0694075a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/0694075a

Branch: refs/heads/develop
Commit: 0694075af78ff84964b35835680a385255c15fc2
Parents: 05d40c2
Author: Sterling Hughes <[email protected]>
Authored: Tue Aug 2 15:16:42 2016 -0700
Committer: Sterling Hughes <[email protected]>
Committed: Tue Aug 2 15:16:42 2016 -0700

----------------------------------------------------------------------
 newt/builder/build.go        | 77 +++++++++++++++++++++++++++++++++++----
 newt/builder/buildpackage.go | 26 +++++++------
 newt/builder/buildutil.go    |  4 +-
 newt/pkg/localpackage.go     | 16 ++++++++
 newt/pkg/package.go          |  7 +---
 5 files changed, 105 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index b3dd222..3d54f0e 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -23,6 +23,8 @@ import (
        "fmt"
        "os"
        "path/filepath"
+       "regexp"
+       "strings"
 
        log "github.com/Sirupsen/logrus"
 
@@ -42,6 +44,9 @@ type Builder struct {
        compilerPkg  *pkg.LocalPackage
        compilerInfo *toolchain.CompilerInfo
 
+       featureWhiteList []map[string]interface{}
+       featureBlackList []map[string]interface{}
+
        target *target.Target
 }
 
@@ -65,10 +70,22 @@ func (b *Builder) Init(target *target.Target) error {
        return nil
 }
 
-func (b *Builder) Features() map[string]bool {
+func (b *Builder) AllFeatures() map[string]bool {
        return b.features
 }
 
+func (b *Builder) Features(pkg pkg.Package) map[string]bool {
+       featureList := map[string]bool{}
+
+       for fname, _ := range b.features {
+               if b.CheckValidFeature(pkg, fname) {
+                       featureList[fname] = true
+               }
+       }
+
+       return featureList
+}
+
 func (b *Builder) AddFeature(feature string) {
        b.features[feature] = true
 }
@@ -319,6 +336,9 @@ func (b *Builder) PrepBuild() error {
                return nil
        }
 
+       b.featureBlackList = []map[string]interface{}{}
+       b.featureWhiteList = []map[string]interface{}{}
+
        // Collect the seed packages.
        bspPkg := b.target.Bsp()
        if bspPkg == nil {
@@ -330,6 +350,9 @@ func (b *Builder) PrepBuild() error {
                }
        }
 
+       b.featureBlackList = append(b.featureBlackList, 
bspPkg.FeatureBlackList())
+       b.featureWhiteList = append(b.featureWhiteList, 
bspPkg.FeatureWhiteList())
+
        b.Bsp = pkg.NewBspPackage(bspPkg)
        compilerPkg := b.resolveCompiler()
        if compilerPkg == nil {
@@ -355,6 +378,9 @@ func (b *Builder) PrepBuild() error {
                b.appPkg = appBpkg
        }
 
+       b.featureBlackList = append(b.featureBlackList, 
appBpkg.FeatureBlackList())
+       b.featureWhiteList = append(b.featureWhiteList, 
appBpkg.FeatureWhiteList())
+
        bspBpkg := b.Packages[bspPkg]
        if bspBpkg == nil {
                bspBpkg = b.AddPackage(bspPkg)
@@ -362,6 +388,9 @@ func (b *Builder) PrepBuild() error {
 
        targetBpkg := b.AddPackage(b.target.Package())
 
+       b.featureBlackList = append(b.featureBlackList, 
targetBpkg.FeatureBlackList())
+       b.featureWhiteList = append(b.featureWhiteList, 
targetBpkg.FeatureWhiteList())
+
        // Populate the full set of packages to be built and resolve the feature
        // set.
        if err := b.loadDeps(); err != nil {
@@ -400,11 +429,6 @@ func (b *Builder) PrepBuild() error {
                return err
        }
 
-       // For every feature defined, generate a define and append it to cflags
-       for fname, _ := range b.Features() {
-               targetCi.Cflags = append(targetCi.Cflags,
-                       fmt.Sprintf("-DFEATURE_%s", fname))
-       }
        baseCi.AddCompilerInfo(targetCi)
 
        // App flags.
@@ -440,7 +464,7 @@ func (b *Builder) PrepBuild() error {
 
        // Read the BSP configuration.  These settings are necessary for the 
link
        // step.
-       if err := b.Bsp.Reload(b.Features()); err != nil {
+       if err := b.Bsp.Reload(b.Features(b.Bsp)); err != nil {
                return err
        }
 
@@ -450,6 +474,45 @@ func (b *Builder) PrepBuild() error {
        return nil
 }
 
+func (b *Builder) matchFeature(flist []map[string]interface{},
+       pkg pkg.Package, featureName string) bool {
+
+       fullName := ""
+       if pkg != nil {
+               fullName = pkg.FullName()
+       }
+
+       for _, matchList := range flist {
+               for pkgDesc, featureDesc := range matchList {
+                       re, _ := regexp.Compile(pkgDesc)
+                       if re.MatchString(fullName) {
+                               if strings.Compare(featureDesc.(string), 
featureName) == 0 {
+                                       return true
+                               }
+                       }
+               }
+       }
+
+       return false
+}
+
+func (b *Builder) CheckValidFeature(pkg pkg.Package,
+       feature string) bool {
+
+       // If the feature is not in the blacklist, automatically valid
+       if match := b.matchFeature(b.featureBlackList, pkg, feature); !match {
+               return true
+       }
+
+       // If it is in the blacklist, check if its in the whitelist
+       // if not, override the feature definition.
+       if match := b.matchFeature(b.featureWhiteList, pkg, feature); match {
+               return true
+       } else {
+               return false
+       }
+}
+
 func (b *Builder) Build() error {
        if err := b.target.Validate(true); err != nil {
                return err

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/builder/buildpackage.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildpackage.go b/newt/builder/buildpackage.go
index 03d11e3..287c769 100644
--- a/newt/builder/buildpackage.go
+++ b/newt/builder/buildpackage.go
@@ -139,16 +139,20 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
        }
 
        ci := toolchain.NewCompilerInfo()
-       ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(),
+       ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, 
b.Features(bpkg),
                "pkg.cflags")
-       ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(),
+       ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, 
b.Features(bpkg),
                "pkg.lflags")
-       ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(),
+       ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, 
b.Features(bpkg),
                "pkg.aflags")
 
+       for fname, _ := range b.Features(bpkg) {
+               ci.Cflags = append(ci.Cflags, fmt.Sprintf("-DFEATURE_%s", 
fname))
+       }
+
        ci.IgnoreFiles = []*regexp.Regexp{}
        ignPats := newtutil.GetStringSliceFeatures(bpkg.Viper,
-               b.Features(), "pkg.ign_files")
+               b.Features(bpkg), "pkg.ign_files")
        for _, str := range ignPats {
                re, err := regexp.Compile(str)
                if err != nil {
@@ -160,7 +164,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
 
        ci.IgnoreDirs = []*regexp.Regexp{}
        ignPats = newtutil.GetStringSliceFeatures(bpkg.Viper,
-               b.Features(), "pkg.ign_dirs")
+               b.Features(bpkg), "pkg.ign_dirs")
        for _, str := range ignPats {
                re, err := regexp.Compile(str)
                if err != nil {
@@ -171,7 +175,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
        }
 
        bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.Viper,
-               b.Features(), "pkg.src_dirs")
+               b.Features(bpkg), "pkg.src_dirs")
 
        includePaths, err := bpkg.recursiveIncludePaths(b)
        if err != nil {
@@ -184,7 +188,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
 }
 
 func (bpkg *BuildPackage) loadFeatures(b *Builder) (map[string]bool, bool) {
-       features := b.Features()
+       features := b.AllFeatures()
 
        foundNewFeature := false
 
@@ -200,7 +204,7 @@ func (bpkg *BuildPackage) loadFeatures(b *Builder) 
(map[string]bool, bool) {
                }
        }
 
-       return b.Features(), foundNewFeature
+       return b.Features(bpkg), foundNewFeature
 }
 
 // Searches for a package which can satisfy bpkg's API requirement.  If such a
@@ -266,7 +270,7 @@ func (bpkg *BuildPackage) loadDeps(b *Builder,
 
        // Determine if this package supports any APIs that we haven't seen
        // yet.  If so, another full iteration is required.
-       apis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(),
+       apis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
                "pkg.apis")
        for _, api := range apis {
                newApi := b.AddApi(api, bpkg)
@@ -289,7 +293,7 @@ func (bpkg *BuildPackage) satisfyApis(b *Builder) bool {
 
        // Determine if any of the package's API requirements can now be 
satisfied.
        // If so, another full iteration is required.
-       reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(),
+       reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg),
                "pkg.req_apis")
        for _, reqApi := range reqApis {
                reqStatus, ok := bpkg.reqApiMap[reqApi]
@@ -360,7 +364,7 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) 
[]string {
        incls = append(incls, srcDir)
        incls = append(incls, srcDir+"/arch/"+b.Bsp.Arch)
 
-       if b.Features()["TEST"] {
+       if b.Features(bpkg)["TEST"] {
                testSrcDir := srcDir + "/test"
                incls = append(incls, testSrcDir)
                incls = append(incls, testSrcDir+"/arch/"+b.Bsp.Arch)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index cd7ec85..c90251f 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -75,8 +75,8 @@ func (b *Builder) TestExePath(pkgName string) string {
 func (b *Builder) FeatureString() string {
        var buffer bytes.Buffer
 
-       features := make([]string, 0, len(b.Features()))
-       for f, _ := range b.Features() {
+       features := make([]string, 0, len(b.Features(nil)))
+       for f, _ := range b.Features(nil) {
                features = append(features, f)
        }
        sort.Strings(features)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/pkg/localpackage.go
----------------------------------------------------------------------
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index b776f9d..78207b5 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -65,6 +65,11 @@ type LocalPackage struct {
        // APIs that this package requires
        reqApis []string
 
+       // This is only used for top-level packages, but make no distinction
+       // and always read it in.
+       featureBlackList map[string]interface{}
+       featureWhiteList map[string]interface{}
+
        // Pointer to pkg.yml configuration structure
        Viper *viper.Viper
 
@@ -309,6 +314,9 @@ func (pkg *LocalPackage) Load() error {
                }
        }
 
+       pkg.featureBlackList = v.GetStringMap("pkg.feature_blacklist")
+       pkg.featureWhiteList = v.GetStringMap("pkg.feature_whitelist")
+
        // Read the package description from the file
        pkg.desc, err = pkg.readDesc(v)
        if err != nil {
@@ -320,6 +328,14 @@ func (pkg *LocalPackage) Load() error {
        return nil
 }
 
+func (pkg *LocalPackage) FeatureBlackList() map[string]interface{} {
+       return pkg.featureBlackList
+}
+
+func (pkg *LocalPackage) FeatureWhiteList() map[string]interface{} {
+       return pkg.featureWhiteList
+}
+
 func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
        newName string) *LocalPackage {
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/pkg/package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/package.go b/newt/pkg/package.go
index 7a37632..4fa988c 100644
--- a/newt/pkg/package.go
+++ b/newt/pkg/package.go
@@ -20,10 +20,7 @@
 
 package pkg
 
-import (
-       "mynewt.apache.org/newt/newt/interfaces"
-       "mynewt.apache.org/newt/newt/repo"
-)
+import "mynewt.apache.org/newt/newt/interfaces"
 
 const PACKAGE_FILE_NAME = "pkg.yml"
 
@@ -60,7 +57,7 @@ var PackageTypeNames = map[interfaces.PackageType]string{
 // case.
 type Package interface {
        // The repository this package belongs to
-       Repo() *repo.Repo
+       Repo() interfaces.RepoInterface
        // The name of this package
        Name() string
        // The full name of this package, including repo

Reply via email to