You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/03/06 03:22:16 UTC
[3/4] incubator-mynewt-newt git commit: first cut at rewrite of newt
package & project management. can understand multiple package repositories,
and uses project nomenclature discussed. packages are now broken into multiple
files. commands are broken
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/pkglist.go
----------------------------------------------------------------------
diff --git a/newt/cli/pkglist.go b/newt/cli/pkglist.go
deleted file mode 100644
index 9159c13..0000000
--- a/newt/cli/pkglist.go
+++ /dev/null
@@ -1,998 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cli
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "strings"
-
- "mynewt.apache.org/newt/util"
- "mynewt.apache.org/newt/viper"
-)
-
-type PkgList struct {
- // Repository associated with the Pkgs
- Repo *Repo
-
- // List of packages for Repo
- Pkgs map[string]*Pkg
-
- PkgDescs map[string]*PkgDesc
-
- Name string
-
- LarvaFile string
-
- RemoteUrl string
-
- Branch string
-}
-
-// Allocate a new package manager structure, and initialize it.
-func NewPkgList(repo *Repo) (*PkgList, error) {
- pkgList := &PkgList{
- Repo: repo,
- }
- err := pkgList.Init()
-
- return pkgList, err
-}
-
-func (pkgList *PkgList) LoadConfigs(t *Target, force bool) error {
- for _, pkg := range pkgList.Pkgs {
- if err := pkg.LoadConfig(t, force); err != nil {
- return err
- }
- }
- return nil
-}
-
-func (pkgList *PkgList) CheckPkgDeps(pkg *Pkg,
- deps map[string]*DependencyRequirement,
- reqcap map[string]*DependencyRequirement,
- caps map[string]*DependencyRequirement,
- capPkgs map[string]string) error {
-
- for _, depReq := range pkg.Deps {
- // don't process this package if we've already processed it
- if _, ok := deps[depReq.String()]; ok {
- continue
- }
-
- pkgName := pkg.Name
- StatusMessage(VERBOSITY_VERBOSE,
- "Checking dependency %s for package %s\n", depReq.Name, pkgName)
- pkg, ok := pkgList.Pkgs[depReq.Name]
- if !ok {
- return NewNewtError(
- fmt.Sprintf("No package dependency %s found for %s",
- depReq.Name, pkgName))
- }
-
- if ok := depReq.SatisfiesDependency(pkg); !ok {
- return NewNewtError(fmt.Sprintf("Pkg %s doesn't satisfy dependency %s",
- pkg.Name, depReq))
- }
-
- // We've checked this dependency requirement, all is gute!
- deps[depReq.String()] = depReq
- }
-
- for _, reqCap := range pkg.ReqCapabilities {
- reqcap[reqCap.String()] = reqCap
- }
-
- for _, cap := range pkg.Capabilities {
- if caps[cap.String()] != nil && capPkgs[cap.String()] != pkg.FullName {
- return NewNewtError(fmt.Sprintf("Multiple pkgs with capability %s",
- cap.String()))
- }
- caps[cap.String()] = cap
- if capPkgs != nil {
- capPkgs[cap.String()] = pkg.FullName
- }
- }
-
- // Now go through and recurse through the sub-package dependencies
- for _, depReq := range pkg.Deps {
- if _, ok := deps[depReq.String()]; ok {
- continue
- }
-
- if err := pkgList.CheckPkgDeps(pkgList.Pkgs[depReq.Name], deps,
- reqcap, caps, capPkgs); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (pkgList *PkgList) VerifyCaps(reqcaps map[string]*DependencyRequirement,
- caps map[string]*DependencyRequirement) error {
-
- for name, rcap := range reqcaps {
- capability, ok := caps[name]
- if !ok {
- return NewNewtError(fmt.Sprintf("Required capability %s not found",
- name))
- }
-
- if err := rcap.SatisfiesCapability(capability); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (pkgList *PkgList) CheckDeps() error {
- // Go through all the packages and check that their dependencies are satisfied
- for _, pkg := range pkgList.Pkgs {
- deps := map[string]*DependencyRequirement{}
- reqcap := map[string]*DependencyRequirement{}
- caps := map[string]*DependencyRequirement{}
-
- if err := pkgList.CheckPkgDeps(pkg, deps, reqcap, caps, nil); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// Load an individual package specified by pkgName into the package list for
-// this repository
-func (pkgList *PkgList) loadPkg(pkgDir string, pkgPrefix string,
- pkgName string) error {
- StatusMessage(VERBOSITY_VERBOSE, "Loading Pkg "+pkgDir+"...\n")
-
- if pkgList.Pkgs == nil {
- pkgList.Pkgs = make(map[string]*Pkg)
- }
-
- pkg, err := NewPkg(pkgList.Repo, pkgDir)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Cannot load package %s, error %s",
- pkgDir, err.Error()))
- }
-
- pkgList.Pkgs[pkgPrefix+pkgName] = pkg
-
- return nil
-}
-
-func (pkgList *PkgList) String() string {
- str := ""
- for pkgName, _ := range pkgList.Pkgs {
- str += pkgName + " "
- }
- return str
-}
-
-// Recursively load a package. Given the baseDir of the packages (e.g. pkg/ or
-// hw/bsp), and the base package name.
-func (pkgList *PkgList) loadPkgDir(baseDir string, pkgPrefix string,
- pkgName string) error {
- log.Printf("[DEBUG] Loading pkgs in %s, starting with pkg %s",
- baseDir, pkgName)
-
- // first recurse and load subpackages
- list, err := ioutil.ReadDir(baseDir + "/" + pkgName)
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- for _, ent := range list {
- if !ent.IsDir() {
- continue
- }
-
- name := ent.Name()
-
- if name == "src" || name == "include" || strings.HasPrefix(name, ".") ||
- name == "bin" {
- continue
- } else {
- if err := pkgList.loadPkgDir(baseDir, pkgPrefix,
- pkgName+"/"+name); err != nil {
- return err
- }
- }
- }
-
- if NodeNotExist(baseDir + "/" + pkgName + "/pkg.yml") {
- return nil
- }
-
- return pkgList.loadPkg(baseDir+"/"+pkgName, pkgPrefix, pkgName)
-}
-
-// Load all the packages in the repository into the package structure
-func (pkgList *PkgList) loadPkgs() error {
- repo := pkgList.Repo
-
- searchDirs := repo.PkgPaths()
-
- for _, pkgDir := range searchDirs {
- pkgBaseDir := repo.BasePath + "/" + pkgDir
-
- if NodeNotExist(pkgBaseDir) {
- continue
- }
-
- pkgDirList, err := ioutil.ReadDir(pkgBaseDir)
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- for _, subPkgDir := range pkgDirList {
- name := subPkgDir.Name()
- if filepath.HasPrefix(name, ".") || filepath.HasPrefix(name, "..") {
- continue
- }
-
- if !subPkgDir.IsDir() {
- continue
- }
-
- if err = pkgList.loadPkgDir(pkgBaseDir, pkgDir, name); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-// Initialize the package manager
-func (pkgList *PkgList) Init() error {
- if err := pkgList.loadPkgs(); err != nil {
- return err
- }
-
- pkgList.PkgDescs = map[string]*PkgDesc{}
-
- return nil
-}
-
-// Resolve the package specified by pkgName into a package structure.
-func (pkgList *PkgList) ResolvePkgName(pkgName string) (*Pkg, error) {
- pkg, ok := pkgList.Pkgs[pkgName]
- if !ok {
- return nil, NewNewtError(fmt.Sprintf("Invalid pkg '%s' specified "+
- "(pkgs = %s)", pkgName, pkgList.Pkgs))
- }
- return pkg, nil
-}
-
-func (pkgList *PkgList) ResolvePkgDescName(pkgName string) (*PkgDesc, error) {
- pkgDesc, ok := pkgList.PkgDescs[pkgName]
- if !ok {
- return nil, NewNewtError(fmt.Sprintf("Invalid pkg '%s' specified "+
- "(pkgs = %s)", pkgName, pkgList))
- }
- return pkgDesc, nil
-}
-
-func (pkgList *PkgList) ResolvePkgDir(pkgDir string) (*Pkg, error) {
- pkgDir = filepath.Clean(pkgDir)
- for name, pkg := range pkgList.Pkgs {
- if filepath.Clean(pkg.BasePath) == pkgDir {
- return pkgList.Pkgs[name], nil
- }
- }
- return nil, NewNewtError(fmt.Sprintf("Cannot resolve package dir %s in "+
- "package manager", pkgDir))
-}
-
-// Clean the build for the package specified by pkgName. if cleanAll is
-// specified, all architectures are cleaned.
-func (pkgList *PkgList) BuildClean(t *Target, pkgName string, cleanAll bool) error {
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return err
- }
-
- if err := pkg.LoadConfig(t, false); err != nil {
- return err
- }
-
- tName := t.Name + "/"
- if cleanAll {
- tName = ""
- }
-
- if pkg.Clean {
- return nil
- }
- pkg.Clean = true
-
- for _, dep := range pkg.Deps {
- if err := pkgList.BuildClean(t, dep.Name, cleanAll); err != nil {
- return err
- }
- }
-
- c, err := NewCompiler(t.GetCompiler(), t.Cdef, t.Name, []string{})
- if err != nil {
- return err
- }
-
- if NodeExist(pkg.BasePath + "/src/") {
- if err := c.RecursiveClean(pkg.BasePath+"/src/", tName); err != nil {
- return err
- }
-
- if err := os.RemoveAll(pkg.BasePath + "/bin/" + tName); err != nil {
- return NewNewtError(err.Error())
- }
- }
-
- pkg.Clean = true
-
- return nil
-}
-
-func (pkgList *PkgList) GetPkgLib(t *Target, pkg *Pkg) string {
- libDir := pkg.BasePath + "/bin/" + t.Name + "/" +
- "lib" + filepath.Base(pkg.Name) + ".a"
- return libDir
-}
-
-// @param incls Extra include paths that get specified during
-// build; not modified by this function.
-// @param libs List of libraries that have been built so far;
-// This function appends entries to this list.
-func (pkgList *PkgList) buildDeps(pkg *Pkg, t *Target, incls *[]string,
- libs *[]string) error {
-
- StatusMessage(VERBOSITY_VERBOSE,
- "Building pkg dependencies for %s, target %s\n", pkg.Name, t.Name)
-
- var err error
-
- if pkg.Includes, err = pkg.GetIncludes(t); err != nil {
- return err
- }
-
- if incls == nil {
- incls = &[]string{}
- }
- if libs == nil {
- libs = &[]string{}
- }
-
- for _, dep := range pkg.Deps {
- if dep.Name == "" {
- break
- }
-
- log.Printf("[DEBUG] Loading package dependency: %s", dep.Name)
- // Get package structure
- dpkg, err := pkgList.ResolvePkgName(dep.Name)
- if err != nil {
- return err
- }
-
- // Build the package
- if err = pkgList.Build(t, dep.Name, *incls, libs); err != nil {
- return err
- }
-
- // After build, get dependency package includes. Build function
- // generates all the package includes
- pkg.Includes = append(pkg.Includes, dpkg.Includes...)
- if lib := pkgList.GetPkgLib(t, dpkg); NodeExist(lib) {
- *libs = append(*libs, lib)
- }
- }
-
- // Add on dependency includes to package includes
- log.Printf("[DEBUG] Pkg dependencies for %s built, incls = %s",
- pkg.Name, pkg.Includes)
-
- return nil
-}
-
-// Build the package specified by pkgName
-//
-// @param incls Extra include paths that get specified during
-// build. Note: passed by value.
-// @param lib List of libraries that have been built so far;
-// This function appends entries to this list.
-func (pkgList *PkgList) Build(t *Target, pkgName string, incls []string,
- libs *[]string) error {
-
- // Look up package structure
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return err
- }
-
- if err := pkg.LoadConfig(t, false); err != nil {
- return err
- }
-
- // already built the package, no need to rebuild. This is to handle
- // recursive calls to Build()
- if pkg.Built {
- return nil
- }
- pkg.Built = true
-
- if err := pkgList.buildDeps(pkg, t, &incls, libs); err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_VERBOSE, "Building pkg %s for arch %s\n",
- pkgName, t.Arch)
-
- // NOTE: this assignment must happen after the call to buildDeps(), as
- // buildDeps() fills in the package includes.
- incls = append(incls, PkgIncludeDirs(pkg, t)...)
- log.Printf("[DEBUG] Pkg includes for %s are %s", pkgName, incls)
-
- srcDir := pkg.BasePath + "/src/"
- if NodeNotExist(srcDir) {
- // nothing to compile, return true!
- return nil
- }
-
- // Build the package designated by pkgName
- // Initialize a compiler
- c, err := NewCompiler(t.GetCompiler(), t.Cdef, t.Name, incls)
- if err != nil {
- return err
- }
- // setup Cflags, Lflags and Aflags
- c.Cflags = CreateCflags(pkgList, c, t, pkg.Cflags)
- c.Lflags = CreateLflags(c, t, pkg.Lflags)
- c.Aflags = CreateAflags(c, t, pkg.Aflags)
-
- log.Printf("[DEBUG] compiling src pkgs in base pkg directory: %s", srcDir)
-
- // For now, ignore test code. Tests get built later if the test identity
- // is in effect.
- ignDirs := []string{"test"}
-
- if err = BuildDir(srcDir, c, t, ignDirs); err != nil {
- return err
- }
-
- // Now build the test code if requested.
- if t.HasIdentity("test") {
- testSrcDir := srcDir + "/test"
- if err = BuildDir(testSrcDir, c, t, ignDirs); err != nil {
- return err
- }
- }
-
- // Archive everything into a static library, which can be linked with a
- // main program
- if err := os.Chdir(pkg.BasePath + "/"); err != nil {
- return NewNewtError(err.Error())
- }
-
- binDir := pkg.BasePath + "/bin/" + t.Name + "/"
-
- if NodeNotExist(binDir) {
- if err := os.MkdirAll(binDir, 0755); err != nil {
- return NewNewtError(err.Error())
- }
- }
-
- if err = c.CompileArchive(pkgList.GetPkgLib(t, pkg), []string{}); err != nil {
- return err
- }
-
- return nil
-}
-
-// Check the include directories for the package, to make sure there are
-// no conflicts in include paths for source code
-func (pkgList *PkgList) checkIncludes(pkg *Pkg) error {
- incls, err := filepath.Glob(pkg.BasePath + "/include/*")
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- // Append all the architecture specific directories
- archDir := pkg.BasePath + "/include/" + pkg.Name + "/arch/"
- dirs, err := ioutil.ReadDir(archDir)
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- for _, dir := range dirs {
- if !dir.IsDir() {
- return NewNewtError(fmt.Sprintf(
- "Only directories are allowed in architecture dir: %s",
- archDir+dir.Name()))
- }
-
- incls2, err := filepath.Glob(archDir + dir.Name() + "/*")
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- incls = append(incls, incls2...)
- }
-
- for _, incl := range incls {
- finfo, err := os.Stat(incl)
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- bad := false
- if !finfo.IsDir() {
- bad = true
- }
-
- if filepath.Base(incl) != pkg.Name {
- if pkg.IsBsp && filepath.Base(incl) != "bsp" {
- bad = true
- }
- }
-
- if bad {
- return NewNewtError(fmt.Sprintf("File %s should not exist"+
- "in include directory, only file allowed in include "+
- "directory is a directory with the package name %s",
- incl, pkg.Name))
- }
- }
-
- return nil
-}
-
-// Clean the tests in the tests parameter, for the package identified by
-// pkgName. If cleanAll is set to true, all architectures will be removed.
-func (pkgList *PkgList) TestClean(t *Target, pkgName string,
- cleanAll bool) error {
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return err
- }
-
- if err := pkg.LoadConfig(t, false); err != nil {
- return err
- }
-
- tName := t.Name + "/"
- if cleanAll {
- tName = ""
- }
-
- if err := os.RemoveAll(pkg.BasePath + "/src/test/bin/" + tName); err != nil {
- return NewNewtError(err.Error())
- }
- if err := os.RemoveAll(pkg.BasePath + "/src/test/obj/" + tName); err != nil {
- return NewNewtError(err.Error())
- }
-
- return nil
-}
-
-// Compile tests specified by the tests parameter. The tests are linked
-// to the package specified by the pkg parameter
-func (pkgList *PkgList) linkTests(t *Target, pkg *Pkg,
- incls []string, libs *[]string) error {
-
- c, err := NewCompiler(t.GetCompiler(), t.Cdef, t.Name, incls)
- if err != nil {
- return err
- }
-
- // Configure Lflags. Since we are only linking, Cflags and Aflags are
- // unnecessary.
- c.Lflags += " " + pkg.Lflags + " " + t.Lflags
-
- testBinDir := pkg.BasePath + "/src/test/bin/" + t.Name + "/"
- binFile := testBinDir + pkg.TestBinName()
- options := map[string]bool{}
-
- // Determine if the test executable is already up to date.
- linkRequired, err := c.depTracker.LinkRequired(binFile, options, *libs)
- if err != nil {
- return err
- }
-
- // Build the test executable if necessary.
- if linkRequired {
- if NodeNotExist(testBinDir) {
- if err := os.MkdirAll(testBinDir, 0755); err != nil {
- return NewNewtError(err.Error())
- }
- }
-
- err = c.CompileBinary(binFile, options, *libs)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// Run all the tests in the tests parameter. pkg is the package to check for
-// the tests. exitOnFailure specifies whether to exit immediately when a
-// test fails, or continue executing all tests.
-func (pkgList *PkgList) runTests(t *Target, pkg *Pkg, exitOnFailure bool) error {
- StatusMessage(VERBOSITY_DEFAULT, "Testing pkg %s for arch %s\n",
- pkg.Name, t.Arch)
-
- if err := os.Chdir(pkg.BasePath + "/src/test/bin/" + t.Name +
- "/"); err != nil {
- return err
- }
-
- o, err := ShellCommand("./" + pkg.TestBinName())
- if err != nil {
- StatusMessage(VERBOSITY_DEFAULT, "%s", string(o))
-
- // Always terminate on test failure since only one test is being run.
- return NewtErrorNoTrace(fmt.Sprintf("Test %s failed",
- pkg.TestBinName()))
- } else {
- StatusMessage(VERBOSITY_VERBOSE, "%s", string(o))
- StatusMessage(VERBOSITY_DEFAULT, "Test %s ok!\n", pkg.TestBinName())
- return nil
- }
-}
-
-// Check to ensure tests exist. Go through the array of tests specified by
-// the tests parameter. pkg is the package to check for these tests.
-func (pkgList *PkgList) testsExist(pkg *Pkg) error {
- dirName := pkg.BasePath + "/src/test/"
- if NodeNotExist(dirName) {
- return NewNewtError("No test exists for package " + pkg.Name)
- }
-
- return nil
-}
-
-// Test the package identified by pkgName, by executing the tests specified.
-// exitOnFailure signifies whether to stop the test program when one of them
-// fails.
-func (pkgList *PkgList) Test(t *Target, pkgName string,
- exitOnFailure bool) error {
-
- // A few identities are implicitly exported when the test command is used:
- // * test: ensures that the test code gets compiled.
- // * selftest: indicates that there is no project
- t.Identities["test"] = "test"
- t.Identities["selftest"] = "selftest"
-
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return err
- }
-
- if err := pkg.LoadConfig(t, false); err != nil {
- return err
- }
-
- // Make sure the test directories exist
- if err := pkgList.testsExist(pkg); err != nil {
- return err
- }
-
- // The pkg under test must be compiled with the PKG_TEST symbol defined so
- // that the appropriate main function gets built.
- pkg.Cflags += " -DPKG_TEST"
-
- incls := []string{}
- libs := []string{}
-
- // If there is a BSP:
- // 1. Calculate the include paths that it and its dependencies export.
- // This set of include paths is accessible during all subsequent
- // builds.
- // 2. Build the BSP package.
- if t.Bsp != "" {
- incls, err = BspIncludePaths(pkgList, t)
- if err != nil {
- return err
- }
- _, err = buildBsp(t, pkgList, &incls, &libs, nil)
- if err != nil {
- return err
- }
- }
-
- // Build the package under test.
- if err := pkgList.Build(t, pkgName, incls, &libs); err != nil {
- return err
- }
- lib := pkgList.GetPkgLib(t, pkg)
- if !NodeExist(lib) {
- return NewNewtError("Pkg " + pkgName + " did not produce binary")
- }
- libs = append(libs, lib)
-
- // Compile the package's test code.
- if err := pkgList.linkTests(t, pkg, incls, &libs); err != nil {
- return err
- }
-
- // Run the tests.
- if err := pkgList.runTests(t, pkg, exitOnFailure); err != nil {
- return err
- }
-
- return nil
-}
-
-func (cl *PkgList) LoadFromPkgList(local *PkgList) error {
- var err error
- for _, pkg := range local.Pkgs {
- if err := pkg.LoadConfig(nil, false); err != nil {
- return err
- }
-
- log.Printf("[DEBUG] Pkg %s loaded, putting it into pkgList %s",
- pkg.FullName, local.Name)
-
- pkgDesc := &PkgDesc{}
- pkgDesc.FullName = pkg.FullName
- pkgDesc.Deps = pkg.Deps
- pkgDesc.Caps = pkg.Capabilities
- pkgDesc.ReqCaps = pkg.ReqCapabilities
- pkgDesc.Version = pkg.Version
- pkgDesc.Hash, err = pkg.GetHash()
- if err != nil {
- return err
- }
-
- cl.PkgDescs[pkgDesc.FullName] = pkgDesc
- }
-
- return nil
-}
-
-func (cl *PkgList) Serialize() (string, error) {
- clStr := "name: " + cl.Name + "\n"
- clStr = clStr + "url: " + cl.RemoteUrl + "\n"
- clStr = clStr + "pkgs:\n"
-
- buf := bytes.Buffer{}
-
- indent := " "
- for _, pkgDesc := range cl.PkgDescs {
- buf.WriteString(pkgDesc.Serialize(indent))
- }
-
- return clStr + buf.String(), nil
-}
-
-func (cl *PkgList) strSliceToDr(list []string) ([]*DependencyRequirement, error) {
- drList := []*DependencyRequirement{}
-
- for _, name := range list {
- req, err := NewDependencyRequirementParseString(name)
- if err != nil {
- return nil, err
- }
- drList = append(drList, req)
- }
-
- if len(drList) == 0 {
- return nil, nil
- } else {
- return drList, nil
- }
-}
-
-func (cl *PkgList) fileToPkgList(cfg *viper.Viper) (map[string]*PkgDesc,
- error) {
- pkgMap := cfg.GetStringMap("pkgs")
-
- pkgList := map[string]*PkgDesc{}
-
- for name, _ := range pkgMap {
- pkgDesc, err := NewPkgDesc(cl)
- if err != nil {
- return nil, err
- }
- pkgDesc.FullName = name
-
- pkgDef := cfg.GetStringMap("pkgs." + name)
- pkgDesc.Version, err = NewVersParseString(pkgDef["vers"].(string))
- if err != nil {
- return nil, err
- }
-
- pkgDesc.Deps, err = cl.strSliceToDr(
- cfg.GetStringSlice("pkgs." + name + ".deps"))
- if err != nil {
- return nil, err
- }
-
- pkgDesc.Caps, err = cl.strSliceToDr(
- cfg.GetStringSlice("pkgs." + name + ".caps"))
- if err != nil {
- return nil, err
- }
-
- pkgDesc.ReqCaps, err = cl.strSliceToDr(
- cfg.GetStringSlice("pkgs." + name + ".req_caps"))
- if err != nil {
- return nil, err
- }
-
- pkgList[name] = pkgDesc
- }
-
- return pkgList, nil
-}
-
-// Create the manifest file name, it's the manifest dir + manifest name +
-// branch and a.yml extension
-func (pkgList *PkgList) GetPkgListFile(name string, branch string) string {
- return name + "@" + branch
-}
-
-func (pkgList *PkgList) GetPkgListFullFile(name string, branch string) string {
- return pkgList.Repo.PkgListPath + pkgList.GetPkgListFile(name, branch) + ".yml"
-}
-
-func (pkgList *PkgList) Load(name string) error {
- cfg, err := ReadConfig(pkgList.Repo.PkgListPath, name)
- if err != nil {
- return err
- }
-
- pkgListName := name
- branchName := "master"
-
- parts := strings.Split(name, "@")
- if len(parts) == 2 {
- pkgListName = parts[0]
- branchName = parts[1]
- }
-
- if cfg.GetString("name") != pkgListName {
- return NewNewtError(
- fmt.Sprintf("Wrong name %s in remote larva file (expected %s)",
- cfg.GetString("name"), pkgListName))
- }
-
- pkgList.Name = cfg.GetString("name")
- pkgList.Branch = branchName
- pkgList.RemoteUrl = cfg.GetString("url")
-
- pkgList.PkgDescs, err = pkgList.fileToPkgList(cfg)
- if err != nil {
- return err
- }
-
- pkgList.Repo.PkgLists[name] = pkgList
-
- return nil
-}
-
-func (cl *PkgList) Install(name string, url string, branch string) error {
- pkgListFile := cl.GetPkgListFullFile(name, branch)
-
- // XXX: Should warn if file already exists, and require force option
- os.Remove(pkgListFile)
-
- // Download the manifest
- dl, err := NewDownloader()
- if err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_DEFAULT, "Downloading pkg-list.yml from %s/"+
- "%s...", url, branch)
-
- if err := dl.DownloadFile(url, branch, "pkg-list.yml",
- pkgListFile); err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_DEFAULT, OK_STRING)
-
- // Load the manifest, and ensure that it is in the correct format
- StatusMessage(VERBOSITY_DEFAULT, "Verifying pkg-list.yml format...\n")
- if err := cl.Load(cl.GetPkgListFile(name, branch)); err != nil {
- os.Remove(pkgListFile)
- return err
- }
- StatusMessage(VERBOSITY_DEFAULT, OK_STRING)
-
- return nil
-}
-
-func (pkgList *PkgList) InstallPkg(pkgName string, branch string,
- downloaded []*RemoteRepo) ([]*RemoteRepo, error) {
- log.Print("[VERBOSE] Looking for ", pkgName)
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err == nil {
- log.Printf("[VERBOSE] ", pkgName, " installed already")
- return downloaded, nil
- }
- repo := pkgList.Repo
- for _, remoteRepo := range downloaded {
- pkg, err = remoteRepo.ResolvePkgName(pkgName)
- if err == nil {
- log.Print("[VERBOSE] ", pkgName, " present in downloaded pkgList ",
- remoteRepo.Name)
-
- err = remoteRepo.fetchPkg(pkgName, repo.BasePath)
- if err != nil {
- return downloaded, err
- }
-
- // update local pkgList
- err = pkgList.loadPkgDir(repo.BasePath, "", pkgName)
- if err != nil {
- return downloaded, err
- }
-
- deps, err := pkg.GetDependencies()
- if err != nil {
- return downloaded, err
- }
- for _, dep := range deps {
- log.Print("[VERBOSE] ", pkgName, " checking dependency ",
- dep.Name)
- depBranch := dep.BranchName()
- downloaded, err = pkgList.InstallPkg(dep.Name, depBranch,
- downloaded)
- if err != nil {
- return downloaded, err
- }
- }
- return downloaded, nil
- }
- }
-
- // Not in downloaded pkgLists
- pkgLists, err := repo.GetPkgLists()
- if err != nil {
- return downloaded, err
- }
- for _, remotePkgList := range pkgLists {
- pkgDesc, err := remotePkgList.ResolvePkgDescName(pkgName)
- if err == nil {
- log.Print("[VERBOSE] ", pkgName, " present in remote pkgList ",
- remotePkgList.Name, remotePkgList.Branch)
- if branch == "" {
- branch = remotePkgList.Branch
- }
- remoteRepo, err := NewRemoteRepo(remotePkgList, branch)
- if err != nil {
- return downloaded, err
- }
- downloaded = append(downloaded, remoteRepo)
- return pkgList.InstallPkg(pkgDesc.FullName, branch, downloaded)
- }
- }
-
- return downloaded, NewNewtError(fmt.Sprintf("No package %s found\n", pkgName))
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/project.go
----------------------------------------------------------------------
diff --git a/newt/cli/project.go b/newt/cli/project.go
deleted file mode 100644
index 89c9010..0000000
--- a/newt/cli/project.go
+++ /dev/null
@@ -1,501 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cli
-
-import (
- "log"
- "os"
-)
-
-// Structure representing a project
-type Project struct {
- // Project name
- Name string
-
- // Base path of project
- BasePath string
-
- // Pkgs
- Pkgs []string
-
- // Capabilities
- Capabilities []string
-
- // Assembler compiler flags
- Aflags string
-
- // Compiler flags
- Cflags string
-
- // Linker flags
- Lflags string
-
- // The repository the project is located in
- Repo *Repo
-
- // The target associated with this project
- Target *Target
-}
-
-// Load and initialize a project specified by name
-// repo & t are the repo and target to associate the project with
-func LoadProject(repo *Repo, t *Target, name string) (*Project, error) {
- p := &Project{
- Name: name,
- Repo: repo,
- Target: t,
- }
-
- StatusMessage(VERBOSITY_VERBOSE,
- "Loading project %s for repo %s, target %s\n",
- name, repo.BasePath, t.Name)
-
- if err := p.Init(); err != nil {
- return nil, err
- } else {
- return p, nil
- }
-}
-
-// Get the packages associated with the project
-func (p *Project) GetPkgs() []string {
- return p.Pkgs
-}
-
-// Load project configuration
-func (p *Project) loadConfig() error {
- log.Printf("[DEBUG] Reading Project configuration for %s in %s",
- p.Name, p.BasePath)
-
- v, err := ReadConfig(p.BasePath, "pkg")
- if err != nil {
- return err
- }
-
- t := p.Target
-
- p.Pkgs = GetStringSliceIdentities(v, t.Identities, "pkg.deps")
-
- idents := GetStringSliceIdentities(v, t.Identities, "pkg.identities")
- for _, ident := range idents {
- t.Identities[ident] = p.Name
- }
- p.Capabilities = GetStringSliceIdentities(v, t.Identities, "pkg.caps")
-
- p.Cflags = GetStringIdentities(v, t.Identities, "pkg.cflags")
- p.Lflags = GetStringIdentities(v, t.Identities, "pkg.lflags")
- p.Aflags = GetStringIdentities(v, t.Identities, "pkg.aflags")
-
- return nil
-}
-
-// Clean the project build, and all packages that were built with the
-// project, if cleanAll is true, then clean everything, not just the current
-// architecture
-func (p *Project) BuildClean(cleanAll bool) error {
- pkgList, err := NewPkgList(p.Repo)
- if err != nil {
- return err
- }
-
- // first, clean packages
- StatusMessage(VERBOSITY_VERBOSE,
- "Cleaning all the packages associated with project %s", p.Name)
- for _, pkgName := range p.GetPkgs() {
- err = pkgList.BuildClean(p.Target, pkgName, cleanAll)
- if err != nil {
- return err
- }
- }
-
- // clean the BSP, if it exists
- if p.Target.Bsp != "" {
- if err := pkgList.BuildClean(p.Target, p.Target.Bsp, cleanAll); err != nil {
- return err
- }
- }
-
- c, err := NewCompiler(p.Target.GetCompiler(), p.Target.Cdef, p.Target.Name, []string{})
- if err != nil {
- return err
- }
-
- tName := p.Target.Name
- if cleanAll {
- tName = ""
- }
-
- if err := c.RecursiveClean(p.BasePath, tName); err != nil {
- return err
- }
-
- return nil
-}
-
-// Collect all identities and capabilities that project has
-func (p *Project) collectAllDeps(pkgList *PkgList, identities map[string]string,
- capabilities map[string]string) error {
-
- pkgDepList := p.GetPkgs()
- if pkgDepList == nil {
- return nil
- }
-
- StatusMessage(VERBOSITY_VERBOSE, " Collecting all project dependencies\n")
-
- t := p.Target
-
- pkgDepList = append(pkgDepList, t.Dependencies...)
- if t.Bsp != "" {
- pkgDepList = append(pkgDepList, t.Bsp)
- }
-
- for _, pkgName := range pkgDepList {
- if pkgName == "" {
- continue
- }
-
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return err
- }
-
- err = pkg.collectDependencies(pkgList, identities, capabilities)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func (p *Project) clearAllDeps(pkgList *PkgList) {
- pkgDepList := p.GetPkgs()
- if pkgDepList == nil {
- return
- }
-
- t := p.Target
-
- pkgDepList = append(pkgDepList, t.Dependencies...)
- if t.Bsp != "" {
- pkgDepList = append(pkgDepList, t.Bsp)
- }
-
- for _, pkgName := range pkgDepList {
- if pkgName == "" {
- continue
- }
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return
- }
- pkg.clearDependencyMarker(pkgList)
- }
-}
-
-// Collect project identities and capabilities, and make target ready for
-// building.
-func (p *Project) collectDeps(pkgList *PkgList) error {
-
- identCount := 0
- capCount := 0
-
- t := p.Target
-
- StatusMessage(VERBOSITY_VERBOSE,
- "Collecting pkg dependencies for project %s\n", p.Name)
-
- // Need to do this multiple times, until there are no new identities,
- // capabilities which show up.
- identities := t.Identities
- capabilities := map[string]string{}
- for {
- err := p.collectAllDeps(pkgList, identities, capabilities)
- if err != nil {
- return err
- }
- newIdentCount := len(identities)
- newCapCount := len(capabilities)
- StatusMessage(VERBOSITY_VERBOSE, "Collected idents %d caps %d\n",
- newIdentCount, newCapCount)
- if identCount == newIdentCount && capCount == newCapCount {
- break
- }
- p.clearAllDeps(pkgList)
- identCount = newIdentCount
- capCount = newCapCount
- }
-
- return nil
-}
-
-// Build the packages that this project depends on
-// pkgList is an initialized package manager, incls is an array of includes to
-// append to (package includes get append as they are built)
-// libs is an array of archive files to append to (package libraries get
-// appended as they are built)
-func (p *Project) buildDeps(pkgList *PkgList, incls *[]string,
- libs *[]string) (map[string]string, error) {
- pkgDepList := p.GetPkgs()
- if pkgDepList == nil {
- return nil, nil
- }
-
- StatusMessage(VERBOSITY_VERBOSE,
- "Building pkg dependencies for project %s\n", p.Name)
-
- t := p.Target
-
- // Append project variables to target variables, so that all package builds
- // inherit from them
- pkgDepList = append(pkgDepList, t.Dependencies...)
- t.Capabilities = append(t.Capabilities, p.Capabilities...)
- t.Cflags += " " + p.Cflags
- t.Lflags += " " + p.Lflags
- t.Aflags += " " + p.Aflags
-
- deps := map[string]*DependencyRequirement{}
- reqcaps := map[string]*DependencyRequirement{}
- caps := map[string]*DependencyRequirement{}
- capPkgs := map[string]string{}
-
- // inherit project capabilities, mark these capabilities as supported.
- for _, cName := range t.Capabilities {
- dr, err := NewDependencyRequirementParseString(cName)
- if err != nil {
- return nil, err
- }
-
- caps[dr.String()] = dr
- }
-
- for _, pkgName := range pkgDepList {
- if pkgName == "" {
- continue
- }
-
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return nil, err
- }
-
- if err := pkgList.CheckPkgDeps(pkg, deps, reqcaps, caps, capPkgs); err != nil {
- return nil, err
- }
- }
-
- StatusMessage(VERBOSITY_VERBOSE,
- "Reporting required capabilities for project %s\n", p.Name)
- for dname, dep := range reqcaps {
- StatusMessage(VERBOSITY_VERBOSE,
- " %s - %s\n", dname, dep.Name)
- }
- StatusMessage(VERBOSITY_VERBOSE,
- "Reporting actual capabilities for project %s\n", p.Name)
- for dname, dep := range caps {
- StatusMessage(VERBOSITY_VERBOSE,
- " %s - %s ", dname, dep.Name)
- if capPkgs[dname] != "" {
- StatusMessage(VERBOSITY_VERBOSE,
- "- %s\n", capPkgs[dname])
- } else {
- StatusMessage(VERBOSITY_VERBOSE, "\n")
- }
- }
-
- // After processing all the dependencies, verify that the package's
- // capability requirements are satisfied as well
- if err := pkgList.VerifyCaps(reqcaps, caps); err != nil {
- return nil, err
- }
-
- // now go through and build everything
- for _, pkgName := range pkgDepList {
- if pkgName == "" {
- continue
- }
-
- pkg, err := pkgList.ResolvePkgName(pkgName)
- if err != nil {
- return nil, err
- }
-
- if err = pkgList.Build(p.Target, pkgName, *incls, libs); err != nil {
- return nil, err
- }
-
- // Don't fail if package did not produce a library file; some packages
- // are header-only.
- if lib := pkgList.GetPkgLib(p.Target, pkg); NodeExist(lib) {
- *libs = append(*libs, lib)
- }
-
- *incls = append(*incls, pkg.Includes...)
- }
-
- return capPkgs, nil
-}
-
-// Build the BSP for this project.
-// The BSP is specified by the Target attached to the project.
-// pkgList is an initialized pkg mgr, containing all the packages
-// incls and libs are pointers to an array of includes and libraries, when buildBsp()
-// builds the BSP, it appends the include directories for the BSP, and the archive file
-// to these variables.
-func (p *Project) buildBsp(pkgList *PkgList, incls *[]string,
- libs *[]string, capPkgs map[string]string) (string, error) {
-
- StatusMessage(VERBOSITY_VERBOSE, "Building BSP %s for project %s\n",
- p.Target.Bsp, p.Name)
-
- if p.Target.Bsp == "" {
- return "", NewNewtError("Must specify a BSP to build project")
- }
-
- return buildBsp(p.Target, pkgList, incls, libs, capPkgs)
-}
-
-// Build the project
-func (p *Project) Build() error {
- pkgList, err := NewPkgList(p.Repo)
- if err != nil {
- return err
- }
-
- // Load the configuration for this target
- if err := pkgList.LoadConfigs(nil, false); err != nil {
- return err
- }
-
- incls := []string{}
- libs := []string{}
- linkerScript := ""
-
- // Collect target identities, libraries to include
- err = p.collectDeps(pkgList)
- if err != nil {
- return err
- }
-
- // If there is a BSP:
- // 1. Calculate the include paths that it and its dependencies export.
- // This set of include paths is accessible during all subsequent
- // builds.
- // 2. Build the BSP package.
- if p.Target.Bsp != "" {
- incls, err = BspIncludePaths(pkgList, p.Target)
- if err != nil {
- return err
- }
- }
-
- // Build the project dependencies.
- capPkgs, err := p.buildDeps(pkgList, &incls, &libs)
- if err != nil {
- return err
- }
-
- if p.Target.Bsp != "" {
- linkerScript, err = p.buildBsp(pkgList, &incls, &libs, capPkgs)
- if err != nil {
- return err
- }
- }
-
- // Append project includes
- projIncls := []string{
- p.BasePath + "/include/",
- p.BasePath + "/arch/" + p.Target.Arch + "/include/",
- }
-
- incls = append(incls, projIncls...)
-
- c, err := NewCompiler(p.Target.GetCompiler(), p.Target.Cdef, p.Target.Name,
- incls)
- if err != nil {
- return err
- }
-
- c.LinkerScript = linkerScript
-
- // Add target C flags
- c.Cflags = CreateCflags(pkgList, c, p.Target, p.Cflags)
-
- os.Chdir(p.BasePath + "/src/")
- if err = c.Compile("*.c"); err != nil {
- return err
- }
-
- if !NodeNotExist(p.BasePath + "/src/arch/" + p.Target.Arch + "/") {
- os.Chdir(p.BasePath + "/src/arch/" + p.Target.Arch + "/")
- if err = c.Compile("*.c"); err != nil {
- return err
- }
- }
-
- // Mark package for this project as built
- projectPkg, err := pkgList.ResolvePkgName("project/" + p.Name)
- if projectPkg != nil {
- projectPkg.Built = true
- }
- StatusMessage(VERBOSITY_DEFAULT, "Building project %s\n", p.Name)
-
- // Create binaries in the project bin/ directory, under:
- // bin/<arch>/
- binDir := p.BinPath()
- if NodeNotExist(binDir) {
- os.MkdirAll(binDir, 0755)
- }
-
- options := map[string]bool{"mapFile": c.ldMapFile,
- "listFile": true, "binFile": true}
- err = c.CompileElf(binDir+p.Name, options, libs)
- if err != nil {
- return err
- }
- for _, pkg := range pkgList.Pkgs {
- if pkg.Built == true {
- builtPkg, err := NewBuiltPkg(pkg)
- if err != nil {
- return err
- }
- BuiltPkgs = append(BuiltPkgs, builtPkg)
- }
- }
- return nil
-}
-
-// Initialize the project, and project definition
-func (p *Project) Init() error {
- p.BasePath = p.Repo.BasePath + "/apps/" + p.Name + "/"
- if NodeNotExist(p.BasePath) {
- return NewNewtError("apps directory does not exist")
- }
-
- if err := p.loadConfig(); err != nil {
- return err
- }
- return nil
-}
-
-// Return path to target binary
-func (p *Project) BinPath() string {
- return p.BasePath + "/bin/" + p.Target.Name + "/"
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/remoterepo.go
----------------------------------------------------------------------
diff --git a/newt/cli/remoterepo.go b/newt/cli/remoterepo.go
deleted file mode 100644
index 1dadb66..0000000
--- a/newt/cli/remoterepo.go
+++ /dev/null
@@ -1,125 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cli
-
-import (
- "fmt"
- "os"
- "path/filepath"
-)
-
-type RemoteRepo struct {
- // Repository associated with the Pkgs
- Repo *Repo
-
- PkgList *PkgList
-
- Name string
-
- RemoteLoc string
-
- LocalLoc string
-}
-
-// Allocate a new structure, and initialize it.
-func NewRemoteRepo(pkgList *PkgList, branch string) (*RemoteRepo, error) {
- remoteRepo := &RemoteRepo{
- Name: pkgList.Name,
- RemoteLoc: pkgList.RemoteUrl,
- LocalLoc: "",
- }
-
- err := remoteRepo.Download(branch)
- if err != nil {
- return nil, err
- }
- return remoteRepo, nil
-}
-
-// Download it
-func (remoteRepo *RemoteRepo) Download(branch string) error {
- dl, err := NewDownloader()
- if err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_DEFAULT, "Downloading %s from %s/"+
- "%s...", remoteRepo.Name, remoteRepo.RemoteLoc, branch)
-
- dir, err := dl.GetRepo(remoteRepo.RemoteLoc, branch)
- if err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_DEFAULT, OK_STRING)
-
- remoteRepo.LocalLoc = dir
-
- repo, err := NewRepoWithDir(dir)
- if err != nil {
- return err
- }
- remoteRepo.Repo = repo
-
- pkgList, err := NewPkgList(repo)
- if err != nil {
- return err
- }
-
- err = pkgList.LoadConfigs(nil, false)
- if err != nil {
- return err
- }
- remoteRepo.PkgList = pkgList
-
- return nil
-}
-
-func (remoteRepo *RemoteRepo) ResolvePkgName(pkgName string) (*Pkg, error) {
- if remoteRepo.PkgList == nil {
- return nil, NewNewtError(fmt.Sprintf("RemoteRepo %s not downloaded yet!",
- remoteRepo.Name))
- }
- return remoteRepo.PkgList.ResolvePkgName(pkgName)
-}
-
-func (remoteRepo *RemoteRepo) fetchPkg(pkgName string, tgtBase string) error {
- pkg, err := remoteRepo.ResolvePkgName(pkgName)
- if err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_DEFAULT, "Installing %s\n", pkg.FullName)
-
- srcDir := filepath.Join(remoteRepo.LocalLoc, pkg.FullName)
- tgtDir := filepath.Join(tgtBase, pkg.FullName)
-
- err = CopyDir(srcDir, tgtDir)
- return err
-}
-
-// Remove local copy
-func (remoteRepo *RemoteRepo) Remove() error {
- if remoteRepo.LocalLoc != "" {
- err := os.RemoveAll(remoteRepo.LocalLoc)
- return err
- }
- return nil
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/repo.go
----------------------------------------------------------------------
diff --git a/newt/cli/repo.go b/newt/cli/repo.go
deleted file mode 100644
index 32630be..0000000
--- a/newt/cli/repo.go
+++ /dev/null
@@ -1,371 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cli
-
-import (
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "path"
- "path/filepath"
-)
-
-type Repo struct {
- // Name of the Repo
- Name string
-
- // Path to the Repo Store
- StorePath string
-
- // Path to the Repo PkgLists
- PkgListPath string
-
- // Repo File
- RepoFile string
-
- // Base path of the repo
- BasePath string
-
- // Store of PkgLists
- PkgLists map[string]*PkgList
-
- AddlPackagePaths []string
-
- // Targets
- Targets map[string]map[string]string
-}
-
-// Create a new Repo object and initialize it
-func NewRepo() (*Repo, error) {
- n := &Repo{}
-
- err := n.Init()
- if err != nil {
- return nil, err
- }
-
- return n, nil
-}
-
-// Create a Repo object constructed out of repo in given path
-func NewRepoWithDir(srcDir string) (*Repo, error) {
- n := &Repo{}
-
- err := n.InitPath(srcDir)
- if err != nil {
- return nil, err
- }
-
- return n, nil
-}
-
-func CreateRepo(repoName string, destDir string, tadpoleUrl string) error {
- if tadpoleUrl == "" {
- tadpoleUrl = "https://git-wip-us.apache.org/repos/asf/incubator-mynewt-tadpole.git"
- }
-
- if NodeExist(destDir) {
- return NewNewtError(fmt.Sprintf("Directory %s already exists, "+
- " cannot create new newt repo", destDir))
- }
-
- dl, err := NewDownloader()
- if err != nil {
- return err
- }
-
- StatusMessage(VERBOSITY_DEFAULT, "Downloading application skeleton from %s...",
- tadpoleUrl)
- if err := dl.DownloadFile(tadpoleUrl, "master", "/",
- destDir); err != nil {
- return err
- }
- StatusMessage(VERBOSITY_DEFAULT, OK_STRING)
-
- // Overwrite app.yml
- contents := []byte(fmt.Sprintf("project.name: %s\n", repoName))
- if err := ioutil.WriteFile(destDir+"/project.yml",
- contents, 0644); err != nil {
- return NewNewtError(err.Error())
- }
-
- // DONE!
-
- return nil
-}
-
-// Get a temporary directory to stick stuff in
-func (repo *Repo) GetTmpDir(dirName string, prefix string) (string, error) {
- tmpDir := dirName
- if NodeNotExist(tmpDir) {
- if err := os.MkdirAll(tmpDir, 0700); err != nil {
- return "", err
- }
- }
-
- name, err := ioutil.TempDir(tmpDir, prefix)
- if err != nil {
- return "", err
- }
-
- return name, nil
-}
-
-// Find the repo file. Searches the current directory, and then recurses
-// parent directories until it finds a file named project.yml
-// if no repo file found in the directory heirarchy, an error is returned
-func (repo *Repo) getRepoFile() (string, error) {
- rFile := ""
-
- curDir, err := os.Getwd()
- if err != nil {
- return rFile, NewNewtError(err.Error())
- }
-
- for {
- rFile = curDir + "/project.yml"
- log.Printf("[DEBUG] Searching for repo file at %s", rFile)
- if _, err := os.Stat(rFile); err == nil {
- log.Printf("[DEBUG] Found repo file at %s!", rFile)
- break
- }
-
- curDir = path.Clean(curDir + "../../")
- if curDir == "/" {
- rFile = ""
- err = NewNewtError("No repo file found!")
- break
- }
- }
-
- return rFile, err
-}
-
-func (repo *Repo) TargetDir(targetName string) string {
- return repo.BasePath + "/targets/" + targetName
-}
-
-// Loads a single target definition residing in the specified directory. The
-// path must contain a pkg.yml file at the top level to be a valid target
-// definion.
-func (repo *Repo) loadTarget(path string) error {
- v, err := ReadConfig(path, "pkg")
- if err != nil {
- return err
- }
-
- targetName := filepath.Base(path)
- targetMap, ok := repo.Targets[targetName]
- if !ok {
- targetMap = make(map[string]string)
- repo.Targets[targetName] = targetMap
- }
- settings := v.AllSettings()
- for k, v := range settings {
- targetMap[k] = v.(string)
- }
-
- return nil
-}
-
-// Loads all target definitions rooted at the specified path. Targets have the
-// following file structure:
-// <path>/<target-name>/pkg.yml
-func (repo *Repo) loadPath(path string) error {
- targetDirList, err := ioutil.ReadDir(path)
- if err != nil && !os.IsNotExist(err) {
- return NewNewtError(err.Error())
- }
-
- for _, node := range targetDirList {
- name := node.Name()
- if node.IsDir() &&
- !filepath.HasPrefix(name, ".") &&
- !filepath.HasPrefix(name, "..") {
-
- fullPath := path + name + "/"
-
- err = repo.loadTarget(fullPath)
- if err != nil {
- return err
- }
- }
- }
-
- return nil
-}
-
-// Retrieves the key-value variable map for the target with the specified name.
-// error is populated if variable doesn't exist
-func (repo *Repo) GetTargetVars(name string) (map[string]string, error) {
- targetVars, ok := repo.Targets[name]
- if !ok {
- return nil, NewNewtError(fmt.Sprintf("Target not found: %s", name))
- }
-
- return targetVars, nil
-}
-
-func (repo *Repo) PkgPaths() []string {
- // Get additional package search directories from the repo
- // configuration. If empty, use the default set.
-
- searchDirs := []string{
- "apps/",
- "compiler/",
- "fs/",
- "libs/",
- "net/",
- "hw/bsp/",
- "hw/mcu/",
- "hw/mcu/stm",
- "hw/drivers/",
- "hw/",
- "project/",
- "sys/",
- }
-
- if len(repo.AddlPackagePaths) > 0 {
- searchDirs = append(searchDirs, repo.AddlPackagePaths...)
- }
-
- return searchDirs
-}
-
-// Load the repo configuration file
-func (repo *Repo) loadConfig() error {
- v, err := ReadConfig(repo.BasePath, "project")
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- repo.Name = v.GetString("project.name")
- if repo.Name == "" {
- return NewNewtError("Project file must specify project name")
- }
-
- repo.AddlPackagePaths = v.GetStringSlice("project.additional_package_paths")
-
- return nil
-}
-
-func (repo *Repo) LoadPkgLists() error {
- files, err := ioutil.ReadDir(repo.PkgListPath)
- if err != nil {
- return err
- }
- for _, fileInfo := range files {
- file := fileInfo.Name()
- if filepath.Ext(file) == ".yml" {
- name := file[:len(filepath.Base(file))-len(".yml")]
- log.Printf("[DEBUG] Loading PkgList %s", name)
- pkgList, err := NewPkgList(repo)
- if err != nil {
- return err
- }
- if err := pkgList.Load(name); err != nil {
- return err
- }
- }
- }
- return nil
-}
-
-func (repo *Repo) InitPath(repoPath string) error {
- cwd, err := os.Getwd()
- if err != nil {
- return NewNewtError(err.Error())
- }
-
- if err = os.Chdir(repoPath); err != nil {
- return NewNewtError(err.Error())
- }
-
- log.Printf("[DEBUG] Searching for repository, starting in directory %s", cwd)
-
- if repo.RepoFile, err = repo.getRepoFile(); err != nil {
- return err
- }
-
- log.Printf("[DEBUG] Repo file found, directory %s, loading configuration...",
- repo.RepoFile)
-
- repo.BasePath = filepath.ToSlash(path.Dir(repo.RepoFile))
-
- if err = repo.loadConfig(); err != nil {
- return err
- }
-
- if err = os.Chdir(cwd); err != nil {
- return NewNewtError(err.Error())
- }
- return nil
-}
-
-// Initialze the repository
-// returns a NewtError on failure, and nil on success
-func (repo *Repo) Init() error {
- var err error
-
- cwd, err := os.Getwd()
- if err != nil {
- return NewNewtError(err.Error())
- }
- if err := repo.InitPath(cwd); err != nil {
- return err
- }
-
- log.Printf("[DEBUG] Configuration loaded")
-
- // Create Repo store directory
- repo.StorePath = repo.BasePath + "/.project/"
- if NodeNotExist(repo.StorePath) {
- if err := os.MkdirAll(repo.StorePath, 0755); err != nil {
- return NewNewtError(err.Error())
- }
- }
-
- // Load target YAML files.
- repo.Targets = make(map[string]map[string]string)
- if err := repo.loadPath(repo.BasePath + "/targets/"); err != nil {
- return err
- }
-
- // Load PkgLists for the current Repo
- repo.PkgListPath = repo.StorePath + "/pkg-lists/"
- if NodeNotExist(repo.PkgListPath) {
- if err := os.MkdirAll(repo.PkgListPath, 0755); err != nil {
- return NewNewtError(err.Error())
- }
- }
-
- repo.PkgLists = map[string]*PkgList{}
-
- if err := repo.LoadPkgLists(); err != nil {
- return err
- }
-
- return nil
-}
-
-func (repo *Repo) GetPkgLists() (map[string]*PkgList, error) {
- return repo.PkgLists, nil
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/target.go
----------------------------------------------------------------------
diff --git a/newt/cli/target.go b/newt/cli/target.go
deleted file mode 100644
index 576bf94..0000000
--- a/newt/cli/target.go
+++ /dev/null
@@ -1,889 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cli
-
-import (
- "bufio"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "sort"
- "strconv"
- "strings"
-)
-
-type Target struct {
- Vars map[string]string
-
- Identities map[string]string
-
- Capabilities []string
-
- Dependencies []string
-
- Cflags string
- Lflags string
- Aflags string
-
- Name string
-
- Arch string
- Cdef string
-
- Bsp string
-
- Repo *Repo
-}
-
-func NewTarget(repo *Repo, name string) *Target {
- target := Target{
- Repo: repo,
- Name: name,
- Vars: map[string]string{
- "name": name,
- "vers": "0.0.1",
- "arch": "sim",
- "compiler_def": "default",
- },
- }
-
- return &target
-}
-
-// Check if the target specified by name exists for the Repo specified by
-// r
-func TargetExists(repo *Repo, name string) bool {
- _, err := repo.GetTargetVars(name)
- return err == nil
-}
-
-func parseTargetStringSlice(str string) ([]string, error) {
- var slice []string
- if str != "" {
- slice = strings.Split(str, " ")
- }
- return slice, nil
-}
-
-// Migrates some special key-value pairs from the target's Vars map to named
-// struct fields. This function should be called any time a target is
-// modified.
-func (t *Target) populateFields() error {
- var err error
-
- t.Arch = t.Vars["arch"]
- t.Cdef = t.Vars["compiler_def"]
- t.Bsp = t.Vars["bsp"]
- t.Cflags = t.Vars["cflags"]
- t.Lflags = t.Vars["lflags"]
-
- identities, err := parseTargetStringSlice(t.Vars["identities"])
- if err != nil {
- return err
- }
- t.Identities = map[string]string{}
- for _, ident := range identities {
- StatusMessage(VERBOSITY_VERBOSE, "Setting identity; target=%s "+
- "identity=%s\n", t.Name, ident)
- t.Identities[ident] = t.Name
- }
- t.Capabilities, err = parseTargetStringSlice(t.Vars["capabilities"])
- if err != nil {
- return err
- }
-
- t.Dependencies, err = parseTargetStringSlice(t.Vars["dependencies"])
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (t *Target) SetVar(key string, value string) error {
- t.Vars[key] = value
- return t.populateFields()
-}
-
-func (t *Target) HasIdentity(identity string) bool {
- for cur, _ := range t.Identities {
- if cur == identity {
- return true
- }
- }
-
- return false
-}
-
-// Load the target specified by name for the repository specified by r
-func LoadTarget(repo *Repo, name string) (*Target, error) {
- t := NewTarget(repo, name)
-
- var err error
- vars, err := repo.GetTargetVars(name)
- if err != nil {
- return nil, err
- }
-
- for k, v := range vars {
- log.Printf("[DEBUG] Setting target %s, key=%s val=%s", name, k, v)
- t.Vars[strings.TrimPrefix(k, "pkg.")] = v
- }
-
- // Copy special key-value pairs into their corresponding target fields.
- err = t.populateFields()
- if err != nil {
- return nil, err
- }
-
- return t, nil
-}
-
-// Export a target, or all targets. If exportAll is true, then all targets are
-// exported, if false, then only the target represented by targetName is
-// exported.
-func ExportTargets(repo *Repo, name string, exportAll bool, fp *os.File) error {
- targets, err := GetTargets(repo)
- if err != nil {
- return err
- }
-
- for _, target := range targets {
- log.Printf("[DEBUG] Exporting target %s", target.Name)
-
- if !exportAll && target.Name != name {
- continue
- }
-
- fmt.Fprintf(fp, "@target=%s\n", target.Name)
-
- for k, v := range target.GetVars() {
- fmt.Fprintf(fp, "%s=%s\n", k, v)
- }
- }
- fmt.Fprintf(fp, "@endtargets\n")
-
- return nil
-}
-
-func ImportTargets(repo *Repo, name string, importAll bool, fp *os.File) error {
- s := bufio.NewScanner(fp)
-
- var currentTarget *Target = nil
-
- targets := make([]*Target, 0, 10)
-
- if importAll {
- StatusMessage(VERBOSITY_VERBOSE, "Importing all targets from %s",
- fp.Name())
- } else {
- StatusMessage(VERBOSITY_VERBOSE, "Importing target %s from %s",
- name, fp.Name())
- }
-
- for s.Scan() {
- line := s.Text()
-
- // scan lines
- // lines defining a target start with @
- if idx := strings.Index(line, "@"); idx == 0 {
- // save existing target if it exists
- if currentTarget != nil {
- targets = append(targets, currentTarget)
- currentTarget = nil
- }
-
- // look either for an end of target definitions, or a new target
- // definition
- if line == "@endtargets" {
- break
- } else {
- elements := strings.SplitN(line, "=", 2)
- elements[0] = strings.TrimSpace(elements[0])
- elements[1] = strings.TrimSpace(elements[1])
- // name is elements[0], and value is elements[1]
-
- if importAll || elements[1] == name {
- // create a current target
- currentTarget = NewTarget(repo, elements[1])
- }
- }
- } else {
- if currentTarget != nil {
- // target variables, set these on the current target
- elements := strings.SplitN(line, "=", 2)
- currentTarget.Vars[elements[0]] = elements[1]
- }
- }
- }
-
- if err := s.Err(); err != nil {
- return err
- }
-
- for _, target := range targets {
- if err := target.Save(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// Get a list of targets for the repository specified by r
-func GetTargets(repo *Repo) ([]*Target, error) {
- targets := []*Target{}
- for targetName, _ := range repo.Targets {
- target, err := LoadTarget(repo, targetName)
- if err != nil {
- return nil, err
- }
-
- targets = append(targets, target)
- }
- return targets, nil
-}
-
-// Get a map[] of variables for this target
-func (t *Target) GetVars() map[string]string {
- return t.Vars
-}
-
-// Return the compiler definition file for this target
-func (t *Target) GetCompiler() string {
- path := t.Repo.BasePath + "/compiler/"
- if t.Vars["compiler"] != "" {
- path += t.Vars["compiler"]
- } else {
- path += t.Arch
- }
- path += "/"
-
- return path
-}
-
-// Build the target
-func (t *Target) Build() error {
- if t.Vars["app"] != "" {
- StatusMessage(VERBOSITY_DEFAULT, "Building target %s (project = %s)\n",
- t.Name, t.Vars["app"])
- // Now load and build the project.
- p, err := LoadProject(t.Repo, t, t.Vars["app"])
- if err != nil {
- return err
- }
- // The project is the target, and builds itself.
- if err = p.Build(); err != nil {
- return err
- }
- } else if t.Vars["pkg"] != "" {
- pkgList, err := NewPkgList(t.Repo)
- if err != nil {
- return err
- }
-
- err = pkgList.Build(t, t.Vars["pkg"], nil, nil)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (t *Target) BuildClean(cleanAll bool) error {
- if t.Vars["app"] != "" {
- p, err := LoadProject(t.Repo, t, t.Vars["app"])
- if err != nil {
- return err
- }
-
- // The project is the target, and build cleans itself.
- if err = p.BuildClean(cleanAll); err != nil {
- return err
- }
- } else if t.Vars["pkg"] != "" {
- pkgList, err := NewPkgList(t.Repo)
- if err != nil {
- return err
- }
- err = pkgList.BuildClean(t, t.Vars["pkg"], cleanAll)
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (t *Target) Test(cmd string, flag bool) error {
- pkgList, err := NewPkgList(t.Repo)
- if err != nil {
- return err
- }
-
- switch cmd {
- case "test":
- err = pkgList.Test(t, t.Vars["pkg"], flag)
- case "testclean":
- err = pkgList.TestClean(t, t.Vars["pkg"], flag)
- default:
- err = NewNewtError("Unknown command to Test() " + cmd)
- }
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (t *Target) DeleteVar(varName string) error {
- _, exists := t.Vars[varName]
-
- if exists {
- delete(t.Vars, varName)
- if err := t.Save(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// Save the target's configuration elements
-func (t *Target) Save() error {
- dirpath := t.Repo.TargetDir(t.Name)
- if err := os.MkdirAll(dirpath, 0755); err != nil {
- return NewNewtError(err.Error())
- }
-
- filepath := dirpath + "/pkg.yml"
- file, err := os.Create(filepath)
- if err != nil {
- return NewNewtError(err.Error())
- }
- defer file.Close()
-
- file.WriteString("### Target: " + t.Name + "\n\n")
-
- keys := []string{}
- for k, _ := range t.Vars {
- keys = append(keys, k)
- }
- sort.Strings(keys)
-
- for _, k := range keys {
- file.WriteString("pkg." + k + ": " + t.Vars[k] + "\n")
- }
-
- return nil
-}
-
-// Tells you if the target's directory contains extra user files (i.e., files
-// other than pkg.yml).
-func (t *Target) ContainsUserFiles() (bool, error) {
- path := t.Repo.TargetDir(t.Name)
- contents, err := ioutil.ReadDir(path)
- if err != nil {
- return false, err
- }
-
- userFiles := false
- for _, node := range contents {
- name := node.Name()
- if name != "." && name != ".." && name != "pkg.yml" {
- userFiles = true
- break
- }
- }
-
- return userFiles, nil
-}
-
-func (t *Target) Remove() error {
- path := t.Repo.TargetDir(t.Name)
- if err := os.RemoveAll(path); err != nil {
- return NewNewtError(err.Error())
- }
-
- return nil
-}
-
-func (t *Target) projectPath() (string, error) {
- if t.Vars["app"] == "" {
- return "", NewNewtError(fmt.Sprintf("No project associated with "+
- "target %s", t.Name))
- }
- p, err := LoadProject(t.Repo, t, t.Vars["app"])
- if err != nil {
- return "", err
- }
- return p.BinPath(), nil
-}
-
-func (t *Target) binBaseName() (string, error) {
- if t.Vars["app"] == "" {
- return "", NewNewtError(fmt.Sprintf("No project associated with "+
- "target %s", t.Name))
- }
- p, err := LoadProject(t.Repo, t, t.Vars["app"])
- if err != nil {
- return "", err
- }
- return filepath.Join(p.BinPath(), p.Name), nil
-}
-
-func (t *Target) CreateImage(versionStr string) error {
- binBaseName, err := t.binBaseName()
- if err != nil {
- return err
- }
- projectBase, err := t.projectPath()
- if err != nil {
- return err
- }
-
- os.Chdir(t.Repo.BasePath)
-
- image, err := NewImage(t)
- if err != nil {
- return err
- }
- image.SourceBin = binBaseName + ".elf.bin"
- image.TargetImg = binBaseName + ".img"
- image.ManifestFile = filepath.Join(projectBase, "manifest.json")
-
- err = image.SetVersion(versionStr)
- if err != nil {
- return err
- }
-
- err = image.Generate()
- if err != nil {
- return err
- }
-
- err = image.CreateManifest()
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (t *Target) Download() error {
- pkgList, err := NewPkgList(t.Repo)
- if err != nil {
- return err
- }
-
- pkg, err := pkgList.ResolvePkgName(t.Bsp)
- if err != nil {
- return err
- }
-
- err = pkg.LoadConfig(t, false)
- if err != nil {
- return err
- }
- if pkg.DownloadScript == "" {
- return NewNewtError(fmt.Sprintf("No pkg.downloadscript defined for %s",
- pkg.FullName))
- }
- downloadScript := filepath.Join(pkg.BasePath, pkg.DownloadScript)
-
- binBaseName, err := t.binBaseName()
- if err != nil {
- return err
- }
-
- os.Chdir(t.Repo.BasePath)
-
- identString := ""
- for ident, _ := range t.Identities {
- identString = identString + " " + ident
- }
-
- StatusMessage(VERBOSITY_DEFAULT, "Downloading with %s\n", downloadScript)
- rsp, err := ShellCommand(fmt.Sprintf("%s %s %s", downloadScript,
- binBaseName, identString))
- if err != nil {
- StatusMessage(VERBOSITY_DEFAULT, "%s", rsp)
- return err
- }
-
- return nil
-}
-
-func (t *Target) Debug() error {
- pkgList, err := NewPkgList(t.Repo)
- if err != nil {
- return err
- }
-
- pkg, err := pkgList.ResolvePkgName(t.Bsp)
- if err != nil {
- return err
- }
-
- err = pkg.LoadConfig(t, false)
- if err != nil {
- return err
- }
- if pkg.DebugScript == "" {
- return NewNewtError(fmt.Sprintf("No pkg.debugscript defined for %s",
- pkg.FullName))
- }
- debugScript := filepath.Join(pkg.BasePath, pkg.DebugScript)
-
- binBaseName, err := t.binBaseName()
- if err != nil {
- return err
- }
-
- os.Chdir(t.Repo.BasePath)
-
- identString := ""
- for ident, _ := range t.Identities {
- identString = identString + " " + ident
- }
-
- StatusMessage(VERBOSITY_DEFAULT, "Debugging with %s %s\n", debugScript,
- binBaseName)
-
- cmdLine := []string{debugScript, binBaseName}
- cmdLine = append(cmdLine, identString)
- err = ShellInteractiveCommand(cmdLine)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-type MemSection struct {
- Name string
- Offset uint64
- EndOff uint64
-}
-type MemSectionArray []*MemSection
-
-func (array MemSectionArray) Len() int {
- return len(array)
-}
-
-func (array MemSectionArray) Less(i, j int) bool {
- return array[i].Offset < array[j].Offset
-}
-
-func (array MemSectionArray) Swap(i, j int) {
- array[i], array[j] = array[j], array[i]
-}
-
-func MakeMemSection(name string, off uint64, size uint64) *MemSection {
- memsection := &MemSection{
- Name: name,
- Offset: off,
- EndOff: off + size,
- }
- return memsection
-}
-
-func (m *MemSection) PartOf(addr uint64) bool {
- if addr >= m.Offset && addr < m.EndOff {
- return true
- } else {
- return false
- }
-}
-
-/*
- * We accumulate the size of libraries to elements in this.
- */
-type PkgSize struct {
- Name string
- Sizes map[string]uint32 /* Sizes indexed by mem section name */
-}
-
-type PkgSizeArray []*PkgSize
-
-func (array PkgSizeArray) Len() int {
- return len(array)
-}
-
-func (array PkgSizeArray) Less(i, j int) bool {
- return array[i].Name < array[j].Name
-}
-
-func (array PkgSizeArray) Swap(i, j int) {
- array[i], array[j] = array[j], array[i]
-}
-
-func MakePkgSize(name string, memSections map[string]*MemSection) *PkgSize {
- pkgSize := &PkgSize{
- Name: name,
- }
- pkgSize.Sizes = make(map[string]uint32)
- for secName, _ := range memSections {
- pkgSize.Sizes[secName] = 0
- }
- return pkgSize
-}
-
-/*
- * Go through GCC generated mapfile, and collect info about symbol sizes
- */
-func ParseMapFileSizes(fileName string) (map[string]*PkgSize, map[string]*MemSection,
- error) {
- var state int = 0
-
- file, err := os.Open(fileName)
- if err != nil {
- return nil, nil, err
- }
-
- memSections := make(map[string]*MemSection)
- pkgSizes := make(map[string]*PkgSize)
-
- scanner := bufio.NewScanner(file)
- for scanner.Scan() {
- switch state {
- case 0:
- if strings.Contains(scanner.Text(), "Memory Configuration") {
- state = 1
- }
- case 1:
- if strings.Contains(scanner.Text(), "Origin") {
- state = 2
- }
- case 2:
- if strings.Contains(scanner.Text(), "*default*") {
- state = 3
- continue
- }
- array := strings.Fields(scanner.Text())
- offset, err := strconv.ParseUint(array[1], 0, 64)
- if err != nil {
- return nil, nil, NewNewtError("Can't parse mem info")
- }
- size, err := strconv.ParseUint(array[2], 0, 64)
- if err != nil {
- return nil, nil, NewNewtError("Can't parse mem info")
- }
- memSections[array[0]] = MakeMemSection(array[0], offset,
- size)
- case 3:
- if strings.Contains(scanner.Text(),
- "Linker script and memory map") {
- state = 4
- }
- case 4:
- var addrStr string = ""
- var sizeStr string = ""
- var srcFile string = ""
-
- if strings.Contains(scanner.Text(), "/DISCARD/") ||
- strings.HasPrefix(scanner.Text(), "OUTPUT(") {
- /*
- * After this there is only discarded symbols
- */
- state = 5
- continue
- }
-
- array := strings.Fields(scanner.Text())
- switch len(array) {
- case 1:
- /*
- * section name on it's own, e.g.
- * *(.text*)
- *
- * section name + symbol name, e.g.
- * .text.Reset_Handler
- *
- * ignore these for now
- */
- continue
- case 2:
- /*
- * Either stuff from beginning to first useful data e.g.
- * END GROUP
- *
- * or address of symbol + symbol name, e.g.
- * 0x00000000080002c8 SystemInit
- *
- * or section names with multiple input things, e.g.
- * *(.ARM.extab* .gnu.linkonce.armextab.*)
- *
- * or space set aside in linker script e.g.
- * 0x0000000020002e80 0x400
- * (that's the initial stack)
- *
- * ignore these for now
- */
- continue
- case 3:
- /*
- * address, size, and name of file, e.g.
- * 0x000000000800bb04 0x1050 /Users/marko/foo/tadpole/hw//mcu/stm/stm32f3xx/bin/blinky_f3/libstm32f3xx.a(stm32f30x_syscfg.o)
- *
- * padding, or empty areas defined in linker script:
- * *fill* 0x000000000800cb71 0x3
- *
- * output section name, location, size, e.g.:
- * .bss 0x0000000020000ab0 0x23d0
- */
- /*
- * Record addr, size and name to find library.
- */
- if array[0] == "*fill*" {
- addrStr = array[1]
- sizeStr = array[2]
- srcFile = array[0]
- } else {
- addrStr = array[0]
- sizeStr = array[1]
- srcFile = array[2]
- }
- case 4:
- /*
- * section, address, size, name of file, e.g.
- * COMMON 0x0000000020002d28 0x8 /Users/marko/foo/tadpole/libs//os/bin/blinky_f3/libos.a(os_arch_arm.o)
- *
- * linker script symbol definitions:
- * 0x0000000020002e80 _ebss = .
- *
- * crud, e.g.:
- * 0x8 (size before relaxing)
- */
- addrStr = array[1]
- sizeStr = array[2]
- srcFile = array[3]
- default:
- continue
- }
- addr, err := strconv.ParseUint(addrStr, 0, 64)
- if err != nil {
- continue
- }
- size, err := strconv.ParseUint(sizeStr, 0, 64)
- if err != nil {
- continue
- }
- if size == 0 {
- continue
- }
- tmpStrArr := strings.Split(srcFile, "(")
- srcLib := filepath.Base(tmpStrArr[0])
- for name, section := range memSections {
- if section.PartOf(addr) {
- pkgSize := pkgSizes[srcLib]
- if pkgSize == nil {
- pkgSize =
- MakePkgSize(srcLib, memSections)
- pkgSizes[srcLib] = pkgSize
- }
- pkgSize.Sizes[name] += uint32(size)
- break
- }
- }
- default:
- }
- }
- file.Close()
- for name, section := range memSections {
- StatusMessage(VERBOSITY_VERBOSE, "Mem %s: 0x%x-0x%x\n",
- name, section.Offset, section.EndOff)
- }
-
- return pkgSizes, memSections, nil
-}
-
-/*
- * Return a printable string containing size data for the libraries
- */
-func PrintSizes(libs map[string]*PkgSize,
- sectMap map[string]*MemSection) (string, error) {
- ret := ""
-
- /*
- * Order sections by offset, and display lib sizes in that order.
- */
- memSections := make(MemSectionArray, len(sectMap))
- var i int = 0
- for _, sec := range sectMap {
- memSections[i] = sec
- i++
- }
- sort.Sort(memSections)
-
- /*
- * Order libraries by name, and display them in that order.
- */
- pkgSizes := make(PkgSizeArray, len(libs))
- i = 0
- for _, es := range libs {
- pkgSizes[i] = es
- i++
- }
- sort.Sort(pkgSizes)
-
- for _, sec := range memSections {
- ret += fmt.Sprintf("%7s ", sec.Name)
- }
- ret += "\n"
- for _, es := range pkgSizes {
- for i := 0; i < len(memSections); i++ {
- ret += fmt.Sprintf("%7d ", es.Sizes[memSections[i].Name])
- }
- ret += fmt.Sprintf("%s\n", es.Name)
- }
- return ret, nil
-}
-
-func (t *Target) GetSize() (string, error) {
- if t.Vars["app"] != "" {
- StatusMessage(VERBOSITY_DEFAULT, "Inspecting target %s (project = %s)\n",
- t.Name, t.Vars["app"])
- // Now load the project, mapfile settings
- p, err := LoadProject(t.Repo, t, t.Vars["app"])
- if err != nil {
- return "", err
- }
-
- c, err := NewCompiler(t.GetCompiler(), t.Cdef, t.Name, []string{})
- if err != nil {
- return "", err
- }
- if c.ldMapFile != true {
- return "", NewNewtError("Build does not generate mapfile")
- }
- mapFile := p.BinPath() + p.Name + ".elf.map"
-
- pkgSizes, memSections, err := ParseMapFileSizes(mapFile)
- if err != nil {
- return "", err
- }
- return PrintSizes(pkgSizes, memSections)
- }
- return "", NewNewtError("Target needs a project")
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/util.go
----------------------------------------------------------------------
diff --git a/newt/cli/util.go b/newt/cli/util.go
index 0c1502e..cc9c276 100644
--- a/newt/cli/util.go
+++ b/newt/cli/util.go
@@ -23,9 +23,6 @@ import (
"bufio"
"bytes"
"fmt"
- "mynewt.apache.org/newt/viper"
- "mynewt.apache.org/newt/yaml"
- "github.com/hashicorp/logutils"
"io/ioutil"
"log"
"os"
@@ -33,11 +30,18 @@ import (
"os/signal"
"path"
"path/filepath"
+ "regexp"
"runtime"
"sort"
"strings"
"syscall"
"time"
+
+ "github.com/hashicorp/logutils"
+ "github.com/spf13/cobra"
+ "mynewt.apache.org/newt/util"
+ "mynewt.apache.org/newt/viper"
+ "mynewt.apache.org/newt/yaml"
)
type NewtError struct {
@@ -56,6 +60,38 @@ const (
VERBOSITY_VERBOSE = 3
)
+func NewtUsage(cmd *cobra.Command, err error) {
+ if err != nil {
+ sErr := err.(*util.NewtError)
+ log.Printf("[DEBUG] %s", sErr.StackTrace)
+ fmt.Fprintf(os.Stderr, "Error: %s\n", sErr.Text)
+ }
+
+ if cmd != nil {
+ cmd.Help()
+ }
+ os.Exit(1)
+}
+
+// Display help text with a max line width of 79 characters
+func FormatHelp(text string) string {
+ // first compress all new lines and extra spaces
+ words := regexp.MustCompile("\\s+").Split(text, -1)
+ linelen := 0
+ fmtText := ""
+ for _, word := range words {
+ word = strings.Trim(word, "\n ") + " "
+ tmplen := linelen + len(word)
+ if tmplen >= 80 {
+ fmtText += "\n"
+ linelen = 0
+ }
+ fmtText += word
+ linelen += len(word)
+ }
+ return fmtText
+}
+
func (se *NewtError) Error() string {
return se.Text + "\n" + string(se.StackTrace)
}
@@ -152,7 +188,7 @@ func GetStringIdentities(v *viper.Viper, idents map[string]string, key string) s
return strings.TrimSpace(val)
}
-func GetStringSliceIdentities(v *viper.Viper, idents map[string]string,
+func GetStringSliceIdentities(v *viper.Viper, idents map[string]bool,
key string) []string {
val := v.GetStringSlice(key)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/cli/vars.go
----------------------------------------------------------------------
diff --git a/newt/cli/vars.go b/newt/cli/vars.go
deleted file mode 100644
index 7bc7a39..0000000
--- a/newt/cli/vars.go
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package cli
-
-import (
- "fmt"
- "strings"
-)
-
-func varsFromChildDirs(key string, fullPath bool) ([]string, error) {
- repo, err := NewRepo()
- if err != nil {
- return nil, err
- }
-
- valueSlice := []string{}
- searchDirs := repo.PkgPaths()
- for _, pkgDir := range searchDirs {
- pkgBaseDir := repo.BasePath + "/" + pkgDir
- values, err := DescendantDirsOfParent(pkgBaseDir, key, fullPath)
- if err != nil {
- return nil, NewNewtError(err.Error())
- }
-
- for _, value := range values {
- if fullPath {
- value = strings.TrimPrefix(value, repo.BasePath+"/")
- }
- valueSlice = append(valueSlice, value)
- }
- }
-
- return SortFields(valueSlice...), nil
-}
-
-var varsMap = map[string]func() ([]string, error){
- "arch": func() ([]string, error) {
- return varsFromChildDirs("arch", false)
- },
-
- "bsp": func() ([]string, error) {
- return varsFromChildDirs("bsp", true)
- },
-
- "compiler": func() ([]string, error) {
- return varsFromChildDirs("compiler", false)
- },
-
- "apps": func() ([]string, error) {
- return varsFromChildDirs("apps", false)
- },
-}
-
-// Returns a slice of valid values for the target variable with the specified
-// name. If an invalid target variable is specified, an error is returned.
-func VarValues(varName string) ([]string, error) {
- fn := varsMap[varName]
- if fn == nil {
- err := NewNewtError(fmt.Sprintf("Unknown target variable: \"%s\"", varName))
- return nil, err
- }
-
- values, err := fn()
- if err != nil {
- return nil, err
- }
-
- return values, nil
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/653e2697/newt/coding_style.txt
----------------------------------------------------------------------
diff --git a/newt/coding_style.txt b/newt/coding_style.txt
deleted file mode 100644
index c051b46..0000000
--- a/newt/coding_style.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-Newt Coding Style
---
-
-- Line length is fixed to no more than 90 characters
-
-- At least every function should have documentation above it in godoc format.
-Err on the side of more comments rather than fewer.
-
-- Where possible, the form:
-
- if err := func(); err != nil {
- return err
- }
-
-Is the preferred method of doing error checking. Note that "err" should be
-assigned using the := operator to avoid conflicting with enclosing scope.
-
-- In cases where it is infeasible to create an error variable, i.e. when
-using multiple assignments on structure properties, the err variable should
-be defined at the top of the function scope. i.e.:
-
- func (inst *Installer) SetName(name string) {
- // declaration at the top of the function
- var err error
-
- // ...some code here...
- inst.Name, err = inst.ParseString(name)
- if err != nil {
- return err
- }
- }
-
-
-- Every object which requires allocation, shall follow this pattern:
- - The object itself has an Init() function which accesses to initialize
- the object. e.g.:
-
- func (inst *Installer) Init() error {
- // Initialization functions here
- }
-
- - There shall be a New<Object Name> function which allocates a new
- object of <Object Name> type, and calls the init function prior to
- allocating the new object. e.g.:
-
- func NewInstaller() (*Installer, error) {
- inst := &Installer{}
- if err := inst.Init(); err != nil {
- return nil, err
- }
- return inst, nil
- }
-
-- Accessors are for object properties SHOULD ALWAYS be provided when setting
-class properties. For reading object properties, accessor functions are
-should be provided where it makes sense (i.e. to provide an implementation
-contract.)