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 8f35dc970558a7743cada22be28f0888edaf6abe
Author: Christopher Collins <ccoll...@apache.org>
AuthorDate: Thu Sep 19 10:05:26 2019 -0500

    Separate env var generation from builder
    
    Before commit: a `Builder` object was required to calculate the
    environment variables to pass to external scripts.
    
    This is a nuissance when no `Builder` is available (e.g., when loading
    an mfgimage, or for the upcomimg per-package commands feature).
    
    After commit: Environment variables are divided into three sets (basic,
    settings, slot).  The sets are divided according to the inputs required
    to generate them.  Now the appropriate variables can be calculated
    without a `Builder` object.
---
 newt/builder/buildutil.go | 134 ++++++++++++++++++++++++++++++++++++++++++++--
 newt/builder/load.go      |  89 ++++++++++--------------------
 2 files changed, 159 insertions(+), 64 deletions(-)

diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index 6f23783..e06bd12 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -22,24 +22,29 @@ package builder
 import (
        "bytes"
        "sort"
+       "strconv"
        "strings"
 
        log "github.com/sirupsen/logrus"
 
        "mynewt.apache.org/newt/newt/parse"
+       "mynewt.apache.org/newt/newt/pkg"
+       "mynewt.apache.org/newt/newt/project"
        "mynewt.apache.org/newt/newt/resolve"
+       "mynewt.apache.org/newt/util"
 )
 
 func TestTargetName(testPkgName string) string {
        return strings.Replace(testPkgName, "/", "_", -1)
 }
 
-func (b *Builder) FeatureString() string {
+// FeatureString converts a syscfg map to a string.  The string is a
+// space-separate list of "enabled" settings.
+func FeatureString(settings map[string]string) string {
        var buffer bytes.Buffer
 
-       settingMap := b.cfg.SettingValues()
-       featureSlice := make([]string, 0, len(settingMap))
-       for k, v := range settingMap {
+       featureSlice := make([]string, 0, len(settings))
+       for k, v := range settings {
                if parse.ValueIsTrue(v) {
                        featureSlice = append(featureSlice, k)
                }
@@ -53,6 +58,7 @@ func (b *Builder) FeatureString() string {
 
                buffer.WriteString(feature)
        }
+
        return buffer.String()
 }
 
@@ -126,3 +132,123 @@ func logDepInfo(res *resolve.Resolution) {
                log.Debugf("%s", RevdepGraphText(rdg))
        }
 }
+
+// binBasePath calculates the relative path of the "application binary"
+// directory.  Examples:
+//     * bin/targets/my_blinky_sim/app
+//     * bin/targets/splitty-nrf52dk/loader
+func (b *Builder) binBasePath() (string, error) {
+       if b.appPkg == nil {
+               return "", util.NewNewtError("app package not specified")
+       }
+
+       // Convert the binary path from absolute to relative.  This is required 
for
+       // Windows compatibility.
+       return util.TryRelPath(b.AppBinBasePath()), nil
+}
+
+// BasicEnvVars calculates the basic set of environment variables passed to all
+// external scripts.  `binBase` is the result of calling `binBasePath()`.
+func BasicEnvVars(binBase string, bspPkg *pkg.BspPackage) map[string]string {
+       coreRepo := project.GetProject().FindRepo("apache-mynewt-core")
+       bspPath := bspPkg.BasePath()
+
+       return map[string]string{
+               "CORE_PATH":           coreRepo.Path(),
+               "BSP_PATH":            bspPath,
+               "BIN_BASENAME":        binBase,
+               "BIN_ROOT":            BinRoot(),
+               "MYNEWT_PROJECT_ROOT": ProjectRoot(),
+       }
+}
+
+// SettingsEnvVars calculates the syscfg set of environment variables required
+// by image loading scripts.
+func SettingsEnvVars(settings map[string]string) map[string]string {
+       env := map[string]string{}
+
+       // Add all syscfg settings to the environment with the MYNEWT_VAL_ 
prefix.
+       for k, v := range settings {
+               env["MYNEWT_VAL_"+k] = v
+       }
+
+       if parse.ValueIsTrue(settings["BOOT_LOADER"]) {
+               env["BOOT_LOADER"] = "1"
+       }
+
+       env["FEATURES"] = FeatureString(settings)
+
+       return env
+}
+
+// SlotEnvVars calculates the image-slot set of environment variables required
+// by image loading scripts.  Pass a negative `imageSlot` value if the target
+// is a boot loader.
+func SlotEnvVars(bspPkg *pkg.BspPackage,
+       imageSlot int) (map[string]string, error) {
+
+       env := map[string]string{}
+
+       var flashTargetArea string
+       if imageSlot < 0 {
+               flashTargetArea = "FLASH_AREA_BOOTLOADER"
+       } else {
+               env["IMAGE_SLOT"] = strconv.Itoa(imageSlot)
+               switch imageSlot {
+               case 0:
+                       flashTargetArea = "FLASH_AREA_IMAGE_0"
+               case 1:
+                       flashTargetArea = "FLASH_AREA_IMAGE_1"
+               default:
+                       return nil, util.FmtNewtError(
+                               "invalid image slot: have=%d want=0or1", 
imageSlot)
+               }
+       }
+
+       tgtArea := bspPkg.FlashMap.Areas[flashTargetArea]
+       if tgtArea.Name == "" {
+               return nil, util.FmtNewtError(
+                       "No flash target area %s", flashTargetArea)
+       }
+
+       env["FLASH_OFFSET"] = "0x" + strconv.FormatInt(int64(tgtArea.Offset), 
16)
+       env["FLASH_AREA_SIZE"] = "0x" + strconv.FormatInt(int64(tgtArea.Size), 
16)
+
+       return env, nil
+}
+
+// EnvVars calculates the full set of environment variables passed to external
+// scripts.
+func (b *Builder) EnvVars(imageSlot int) (map[string]string, error) {
+       bspPkg := b.targetBuilder.bspPkg
+       settings := b.cfg.SettingValues()
+
+       binBasePath, err := b.binBasePath()
+       if err != nil {
+               return nil, err
+       }
+
+       // Calculate all three sets of environment variables: basic, settings, 
and
+       // slot.  Then merge the three sets into one.
+
+       env := BasicEnvVars(binBasePath, bspPkg)
+       setEnv := SettingsEnvVars(settings)
+
+       if parse.ValueIsTrue(settings["BOOT_LOADER"]) {
+               imageSlot = -1
+       }
+
+       slotEnv, err := SlotEnvVars(bspPkg, imageSlot, settings)
+       if err != nil {
+               return nil, err
+       }
+
+       for k, v := range setEnv {
+               env[k] = v
+       }
+       for k, v := range slotEnv {
+               env[k] = v
+       }
+
+       return env, nil
+}
diff --git a/newt/builder/load.go b/newt/builder/load.go
index 9d76060..940a934 100644
--- a/newt/builder/load.go
+++ b/newt/builder/load.go
@@ -24,11 +24,9 @@ import (
        "os"
        "os/signal"
        "sort"
-       "strconv"
        "strings"
        "syscall"
 
-       "mynewt.apache.org/newt/newt/parse"
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
        "mynewt.apache.org/newt/util"
@@ -117,40 +115,36 @@ func RunOptionalCheck(checkScript string, env []string) 
error {
        return nil
 }
 
-func Load(binBaseName string, bspPkg *pkg.BspPackage,
+func Load(binBasePath string, bspPkg *pkg.BspPackage,
        extraEnvSettings map[string]string) error {
 
        if bspPkg.DownloadScript == "" {
                return nil
        }
 
-       bspPath := bspPkg.BasePath()
+       env := BasicEnvVars(binBasePath, bspPkg)
+       for k, v := range extraEnvSettings {
+               env[k] = v
+       }
 
-       sortedKeys := make([]string, 0, len(extraEnvSettings))
-       for k, _ := range extraEnvSettings {
+       sortedKeys := make([]string, 0, len(env))
+       for k, _ := range env {
                sortedKeys = append(sortedKeys, k)
        }
        sort.Strings(sortedKeys)
 
-       env := []string{}
+       envSlice := []string{}
        for _, key := range sortedKeys {
-               env = append(env, fmt.Sprintf("%s=%s", key, 
extraEnvSettings[key]))
+               envSlice = append(envSlice, fmt.Sprintf("%s=%s", key, env[key]))
        }
 
-       coreRepo := project.GetProject().FindRepo("apache-mynewt-core")
-       env = append(env, fmt.Sprintf("CORE_PATH=%s", coreRepo.Path()))
-       env = append(env, fmt.Sprintf("BSP_PATH=%s", bspPath))
-       env = append(env, fmt.Sprintf("BIN_BASENAME=%s", binBaseName))
-       env = append(env, fmt.Sprintf("BIN_ROOT=%s", BinRoot()))
-       env = append(env, fmt.Sprintf("MYNEWT_PROJECT_ROOT=%s", ProjectRoot()))
-
-       RunOptionalCheck(bspPkg.OptChkScript, env)
-       // bspPath, binBaseName are passed in command line for backwards
+       RunOptionalCheck(bspPkg.OptChkScript, envSlice)
+       // bspPath, binBasePath are passed in command line for backwards
        // compatibility
        cmd := []string{
                bspPkg.DownloadScript,
-               bspPath,
-               binBaseName,
+               bspPkg.BasePath(),
+               binBasePath,
        }
 
        util.StatusMessage(util.VERBOSITY_VERBOSE, "Load command: %s\n",
@@ -159,7 +153,7 @@ func Load(binBaseName string, bspPkg *pkg.BspPackage,
        for _, v := range env {
                util.StatusMessage(util.VERBOSITY_VERBOSE, "* %s\n", v)
        }
-       if _, err := util.ShellCommand(cmd, env); err != nil {
+       if _, err := util.ShellCommand(cmd, envSlice); err != nil {
                return err
        }
        util.StatusMessage(util.VERBOSITY_VERBOSE, "Successfully loaded 
image.\n")
@@ -178,50 +172,27 @@ func (b *Builder) Load(imageSlot int, extraJtagCmd 
string) error {
                return err
        }
 
-       envSettings := map[string]string{
-               "IMAGE_SLOT": strconv.Itoa(imageSlot),
-               "FEATURES":   b.FeatureString(),
+       env, err := b.EnvVars(imageSlot)
+       if err != nil {
+               return err
        }
+
        if extraJtagCmd != "" {
-               envSettings["EXTRA_JTAG_CMD"] = extraJtagCmd
+               env["EXTRA_JTAG_CMD"] = extraJtagCmd
        }
-       settings := b.cfg.SettingValues()
 
-       var flashTargetArea string
-       if parse.ValueIsTrue(settings["BOOT_LOADER"]) {
-               envSettings["BOOT_LOADER"] = "1"
-
-               flashTargetArea = "FLASH_AREA_BOOTLOADER"
+       if _, ok := env["BOOT_LOADER"]; ok {
                util.StatusMessage(util.VERBOSITY_DEFAULT,
                        "Loading bootloader\n")
        } else {
-               if imageSlot == 0 {
-                       flashTargetArea = "FLASH_AREA_IMAGE_0"
-               } else if imageSlot == 1 {
-                       flashTargetArea = "FLASH_AREA_IMAGE_1"
-               }
                util.StatusMessage(util.VERBOSITY_DEFAULT,
                        "Loading %s image into slot %d\n", b.buildName, 
imageSlot+1)
        }
 
-       bspPkg := b.targetBuilder.bspPkg
-       tgtArea := bspPkg.FlashMap.Areas[flashTargetArea]
-       if tgtArea.Name == "" {
-               return util.NewNewtError(fmt.Sprintf("No flash target area 
%s\n",
-                       flashTargetArea))
-       }
-       envSettings["FLASH_OFFSET"] = "0x" + 
strconv.FormatInt(int64(tgtArea.Offset), 16)
-       envSettings["FLASH_AREA_SIZE"] = "0x" + 
strconv.FormatInt(int64(tgtArea.Size), 16)
-
-       // Add all syscfg settings to the environment with the MYNEWT_VAL_ 
prefix.
-       for k, v := range settings {
-               envSettings["MYNEWT_VAL_"+k] = v
-       }
-
        // Convert the binary path from absolute to relative.  This is required 
for
        // compatibility with unix-in-windows environemnts (e.g., cygwin).
        binPath := util.TryRelPath(b.AppBinBasePath())
-       if err := Load(binPath, b.targetBuilder.bspPkg, envSettings); err != 
nil {
+       if err := Load(binPath, b.targetBuilder.bspPkg, env); err != nil {
                return err
        }
 
@@ -250,15 +221,15 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd 
string, reset bool,
        }
 
        bspPath := b.bspPkg.rpkg.Lpkg.BasePath()
-       binBaseName := binPath
-       featureString := b.FeatureString()
+       binBasePath := binPath
+       featureString := FeatureString(b.cfg.SettingValues())
        bspPkg := b.targetBuilder.bspPkg
 
        coreRepo := project.GetProject().FindRepo("apache-mynewt-core")
        envSettings := []string{
                fmt.Sprintf("CORE_PATH=%s", coreRepo.Path()),
                fmt.Sprintf("BSP_PATH=%s", bspPath),
-               fmt.Sprintf("BIN_BASENAME=%s", binBaseName),
+               fmt.Sprintf("BIN_BASENAME=%s", binBasePath),
                fmt.Sprintf("FEATURES=%s", featureString),
                fmt.Sprintf("MYNEWT_PROJECT_ROOT=%s", ProjectRoot()),
        }
@@ -276,10 +247,10 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd 
string, reset bool,
        os.Chdir(project.GetProject().Path())
 
        RunOptionalCheck(bspPkg.OptChkScript, envSettings)
-       // bspPath, binBaseName are passed in command line for backwards
+       // bspPath, binBasePath are passed in command line for backwards
        // compatibility
        cmdLine := []string{
-               b.targetBuilder.bspPkg.DebugScript, bspPath, binBaseName,
+               b.targetBuilder.bspPkg.DebugScript, bspPath, binBasePath,
        }
 
        fmt.Printf("%s\n", cmdLine)
@@ -287,12 +258,10 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd 
string, reset bool,
 }
 
 func (b *Builder) Debug(extraJtagCmd string, reset bool, noGDB bool) error {
-       if b.appPkg == nil {
-               return util.NewNewtError("app package not specified")
+       binPath, err := b.binBasePath()
+       if err != nil {
+               return err
        }
 
-       // Convert the binary path from absolute to relative.  This is required 
for
-       // Windows compatibility.
-       binPath := util.TryRelPath(b.AppBinBasePath())
        return b.debugBin(binPath, extraJtagCmd, reset, noGDB)
 }

Reply via email to