func (proj *Project) ResolvePackage( dfltRepo interfaces.RepoInterface, name string) (*pkg.LocalPackage, error) { // Trim trailing slash from name. This is necessary when tab // completion is used to specify the name. name = strings.TrimSuffix(name, "/") repoName, pkgName, err := newtutil.ParsePackageString(name) if err != nil { return nil, util.FmtNewtError("invalid package name: %s (%s)", name, err.Error()) } var repo interfaces.RepoInterface if repoName == "" { repo = dfltRepo } else { repo = proj.repos[repoName] } dep, err := pkg.NewDependency(repo, pkgName) if err != nil { return nil, util.FmtNewtError("invalid package name: %s (%s)", name, err.Error()) } if dep == nil { return nil, util.NewNewtError("invalid package name: " + name) } pack := proj.ResolveDependency(dep) if pack == nil { return nil, util.NewNewtError("unknown package: " + name) } return pack.(*pkg.LocalPackage), nil }
func ConvertFilenames(srcFilename string, dstFilename string) (*CoreConvert, error) { coreConvert := NewCoreConvert() var err error coreConvert.Source, err = os.OpenFile(srcFilename, os.O_RDONLY, 0) if err != nil { return coreConvert, util.FmtNewtError("Cannot open file %s - %s", srcFilename, err.Error()) } defer coreConvert.Source.Close() coreConvert.Target, err = os.OpenFile(dstFilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0660) if err != nil { return coreConvert, util.FmtNewtError("Cannot open file %s - %s", dstFilename, err.Error()) } defer coreConvert.Target.Close() if err := coreConvert.Convert(); err != nil { return coreConvert, err } return coreConvert, nil }
func (cfg *Cfg) readDefsOnce(lpkg *pkg.LocalPackage, features map[string]bool) error { v := lpkg.SyscfgV lfeatures := cfg.FeaturesForLpkg(lpkg) for k, _ := range features { lfeatures[k] = true } settings := newtutil.GetStringMapFeatures(v, lfeatures, "syscfg.defs") if settings != nil { for k, v := range settings { vals := v.(map[interface{}]interface{}) entry, err := readSetting(k, lpkg, vals) if err != nil { return util.FmtNewtError("Config for package %s: %s", lpkg.Name(), err.Error()) } if _, exists := cfg.Settings[k]; exists { // XXX: Better error message. return util.FmtNewtError("setting %s redefined", k) } cfg.Settings[k] = entry } } return nil }
// Recursively iterates through an pkg's dependencies, adding each pkg // encountered to the supplied set. func (bpkg *BuildPackage) collectDepsAux(b *Builder, set *map[*BuildPackage]bool) error { if (*set)[bpkg] { return nil } (*set)[bpkg] = true for _, dep := range bpkg.Deps() { if dep.Name == "" { break } // Get pkg structure p := project.GetProject().ResolveDependency(dep) if p == nil { return util.FmtNewtError("Cannot resolve dependency %+v", dep) } dpkg := p.(*pkg.LocalPackage) dbpkg := b.PkgMap[dpkg] if dbpkg == nil { return util.FmtNewtError("Package not found %s; required by %s", dpkg.Name(), bpkg.Name()) } if err := dbpkg.collectDepsAux(b, set); err != nil { return err } } return nil }
// @return meta-offset, hash-offset, error func insertMeta(section0Data []byte, flashMap flash.FlashMap) ( int, int, error) { buf := &bytes.Buffer{} if err := writeHeader(buf); err != nil { return 0, 0, err } for _, area := range flashMap.SortedAreas() { if err := writeFlashMapEntry(area, buf); err != nil { return 0, 0, err } } if err := writeZeroHash(buf); err != nil { return 0, 0, err } hashSubOff := buf.Len() - META_HASH_SZ if err := writeFooter(buf); err != nil { return 0, 0, err } // The meta region gets placed at the very end of the boot loader slot. bootArea, ok := flashMap.Areas[flash.FLASH_AREA_NAME_BOOTLOADER] if !ok { return 0, 0, util.NewNewtError("Required boot loader flash area missing") } if bootArea.Size < buf.Len() { return 0, 0, util.FmtNewtError( "Boot loader flash area too small to accommodate meta region; "+ "boot=%d meta=%d", bootArea.Size, buf.Len()) } metaOff := bootArea.Offset + bootArea.Size - buf.Len() for i := metaOff; i < bootArea.Size; i++ { if section0Data[i] != 0xff { return 0, 0, util.FmtNewtError( "Boot loader extends into meta region; "+ "meta region starts at offset %d", metaOff) } } // Copy the meta region into the manufacturing image. The meta hash is // still zeroed. copy(section0Data[metaOff:], buf.Bytes()) return metaOff, metaOff + hashSubOff, nil }
func (t *TargetBuilder) createManifest() error { manifest := &image.ImageManifest{ Date: time.Now().Format(time.RFC3339), } rm := image.NewRepoManager() for _, lpkg := range t.AppBuilder.sortedLocalPackages() { manifest.Pkgs = append(manifest.Pkgs, rm.GetImageManifestPkg(lpkg)) } if t.LoaderBuilder != nil { for _, lpkg := range t.LoaderBuilder.sortedLocalPackages() { manifest.LoaderPkgs = append(manifest.LoaderPkgs, rm.GetImageManifestPkg(lpkg)) } } manifest.Repos = rm.AllRepos() vars := t.GetTarget().Vars keys := make([]string, 0, len(vars)) for k := range vars { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { manifest.TgtVars = append(manifest.TgtVars, k+"="+vars[k]) } file, err := os.Create(t.AppBuilder.ManifestPath()) if err != nil { return util.FmtNewtError("Cannot create manifest file %s: %s", t.AppBuilder.ManifestPath(), err.Error()) } defer file.Close() buffer, err := json.MarshalIndent(manifest, "", " ") if err != nil { return util.FmtNewtError("Cannot encode manifest: %s", err.Error()) } _, err = file.Write(buffer) if err != nil { return util.FmtNewtError("Cannot write manifest file: %s", err.Error()) } return nil }
func (mi *MfgImage) detectInvalidDevices() error { sectionIds := mi.sectionIds() deviceIds := mi.bsp.FlashMap.DeviceIds() deviceMap := map[int]struct{}{} for _, device := range deviceIds { deviceMap[device] = struct{}{} } invalidIds := []int{} for _, sectionId := range sectionIds { if _, ok := deviceMap[sectionId]; !ok { invalidIds = append(invalidIds, sectionId) } } if len(invalidIds) == 0 { return nil } listStr := "" for i, id := range invalidIds { if i != 0 { listStr += ", " } listStr += strconv.Itoa(id) } return util.FmtNewtError( "image specifies flash devices that are not present in the BSP's "+ "flash map: %s", listStr) }
func ResolvePkgs(cfgResolution CfgResolution, seedPkgs []*pkg.LocalPackage) ([]*pkg.LocalPackage, error) { r := newResolver() r.cfg = cfgResolution.Cfg for _, lpkg := range seedPkgs { r.addPkg(lpkg) } if _, err := r.loadDepsOnce(); err != nil { return nil, err } // Satisfy API requirements. for _, rpkg := range r.pkgMap { for api, _ := range rpkg.reqApiMap { apiPkg := cfgResolution.ApiMap[api] if apiPkg == nil { return nil, util.FmtNewtError( "Unsatisfied API at unexpected time: %s", api) } r.addPkg(apiPkg) } } lpkgs := make([]*pkg.LocalPackage, len(r.pkgMap)) i := 0 for lpkg, _ := range r.pkgMap { lpkgs[i] = lpkg i++ } return lpkgs, nil }
func readSetting(name string, lpkg *pkg.LocalPackage, vals map[interface{}]interface{}) (CfgEntry, error) { entry := CfgEntry{} entry.Name = name entry.Description = stringValue(vals["description"]) entry.Value = stringValue(vals["value"]) if vals["type"] == nil { entry.SettingType = CFG_SETTING_TYPE_RAW } else { var ok bool typename := stringValue(vals["type"]) entry.SettingType, ok = cfgSettingNameTypeMap[typename] if !ok { return entry, util.FmtNewtError( "setting %s specifies invalid type: %s", name, typename) } } entry.appendValue(lpkg, entry.Value) entry.Restrictions = []CfgRestriction{} restrictionStrings := cast.ToStringSlice(vals["restrictions"]) for _, rstring := range restrictionStrings { r, err := readRestriction(name, rstring) if err != nil { return entry, util.PreNewtError(err, "error parsing setting %s", name) } entry.Restrictions = append(entry.Restrictions, r) } return entry, nil }
func (cpm *ConnProfileMgr) Init() error { filename, err := connProfileCfgFilename() if err != nil { return err } // XXX: Should determine whether file exists by attempting to read it. if util.NodeExist(filename) { blob, err := ioutil.ReadFile(filename) if err != nil { return util.NewNewtError(err.Error()) } var profiles []*ConnProfile err = json.Unmarshal(blob, &profiles) if err != nil { return util.FmtNewtError("error reading connection profile "+ "config (%s): %s", filename, err.Error()) } for _, p := range profiles { cpm.profiles[p.MyName] = p } } return nil }
func (mi *MfgImage) loadError( msg string, args ...interface{}) *util.NewtError { return util.FmtNewtError("Error in %s mfg: %s", mi.basePkg.Name(), fmt.Sprintf(msg, args...)) }
// @return [paths-of-artifacts], error func (mi *MfgImage) CreateMfgImage() ([]string, error) { cs, err := mi.build() if err != nil { return nil, err } sectionDir := MfgSectionBinDir(mi.basePkg.Name()) if err := os.MkdirAll(sectionDir, 0755); err != nil { return nil, util.ChildNewtError(err) } for device, section := range cs.dsMap { sectionPath := MfgSectionBinPath(mi.basePkg.Name(), device) if err := ioutil.WriteFile(sectionPath, section, 0644); err != nil { return nil, util.ChildNewtError(err) } } manifest, err := mi.createManifest(cs) if err != nil { return nil, err } manifestPath := mi.ManifestPath() if err := ioutil.WriteFile(manifestPath, manifest, 0644); err != nil { return nil, util.FmtNewtError("Failed to write mfg manifest file: %s", err.Error()) } return mi.ToPaths(), nil }
func targetSyscfgKVFromStr(str string) (map[string]string, error) { vals := map[string]string{} if strings.TrimSpace(str) == "" { return vals, nil } // Separate syscfg vals are delimited by ':'. fields := strings.Split(str, ":") // Key-value pairs are delimited by '='. If no '=' is present, assume the // string is the key name and the value is 1. for _, f := range fields { if _, err := util.AtoiNoOct(f); err == nil { return nil, util.FmtNewtError( "Invalid setting name \"%s\"; must not be a number", f) } kv := strings.SplitN(f, "=", 2) switch len(kv) { case 1: vals[f] = "1" case 2: vals[kv[0]] = kv[1] } } return vals, nil }
func areaNameFromImgIdx(imgIdx int) (string, error) { switch imgIdx { case 0: return flash.FLASH_AREA_NAME_IMAGE_0, nil case 1: return flash.FLASH_AREA_NAME_IMAGE_1, nil default: return "", util.FmtNewtError("invalid image index: %d", imgIdx) } }
func (mi *MfgImage) partFromImage( imgPath string, flashAreaName string) (mfgPart, error) { part := mfgPart{ // Boot loader and images always go in device 0. device: 0, } area, ok := mi.bsp.FlashMap.Areas[flashAreaName] if !ok { return part, util.FmtNewtError( "Image at \"%s\" requires undefined flash area \"%s\"", imgPath, flashAreaName) } part.name = fmt.Sprintf("%s (%s)", flashAreaName, filepath.Base(imgPath)) part.offset = area.Offset var err error part.data, err = ioutil.ReadFile(imgPath) if err != nil { return part, util.ChildNewtError(err) } overflow := len(part.data) - area.Size if overflow > 0 { return part, util.FmtNewtError( "Image \"%s\" is too large to fit in flash area \"%s\"; "+ "image-size=%d flash-area-size=%d overflow=%d", imgPath, flashAreaName, len(part.data), area.Size, overflow) } // If an image slot is used, the entire flash area is unwritable. This // restriction comes from the boot loader's need to write status at the end // of an area. Pad out part with unwriten flash (0xff). This probably // isn't terribly efficient... for i := 0; i < -overflow; i++ { part.data = append(part.data, 0xff) } return part, nil }
// Reads an existing manifest file and augments it with image fields: // * Image version // * App image path // * App image hash // * Loader image path // * Loader image hash // * Build ID func (t *TargetBuilder) augmentManifest( appImg *image.Image, loaderImg *image.Image, buildId []byte) error { manifest, err := readManifest(t.AppBuilder.ManifestPath()) if err != nil { return err } manifest.Version = fmt.Sprintf("%d.%d.%d.%d", appImg.Version.Major, appImg.Version.Minor, appImg.Version.Rev, appImg.Version.BuildNum) manifest.ImageHash = fmt.Sprintf("%x", appImg.Hash) manifest.Image = filepath.Base(appImg.TargetImg) if loaderImg != nil { manifest.Loader = filepath.Base(loaderImg.TargetImg) manifest.LoaderHash = fmt.Sprintf("%x", loaderImg.Hash) } manifest.BuildID = fmt.Sprintf("%x", buildId) file, err := os.Create(t.AppBuilder.ManifestPath()) if err != nil { return util.FmtNewtError("Cannot create manifest file %s: %s", t.AppBuilder.ManifestPath(), err.Error()) } defer file.Close() buffer, err := json.MarshalIndent(manifest, "", " ") if err != nil { return util.FmtNewtError("Cannot encode manifest: %s", err.Error()) } _, err = file.Write(buffer) if err != nil { return util.FmtNewtError("Cannot write manifest file: %s", err.Error()) } return nil }
// Resolves a path with an optional repo prefix (e.g., "@apache-mynewt-core"). func (proj *Project) ResolvePath( basePath string, name string) (string, error) { repoName, subPath, err := newtutil.ParsePackageString(name) if err != nil { return "", util.FmtNewtError("invalid path: %s (%s)", name, err.Error()) } if repoName == "" { return basePath + "/" + subPath, nil } else { repo := proj.repos[repoName] if repo == nil { return "", util.FmtNewtError("Unknown repository: %s", repoName) } return repo.Path() + "/" + subPath, nil } }
// Parses a restriction value. // // Currently, two forms of restrictions are supported: // 1. "$notnull" // 2. expression // // The "$notnull" string indicates that the setting must be set to something // other than the empty string. // // An expression string indicates dependencies on other settings. It would be // better to have a real expression parser. For now, only very simple // expressions are supported. A restriction expression must be of the // following form: // [!]<req-setting> [if <base-val>] // // All setting values are interpreted as booleans. If a setting is "0", "", // or undefined, it is false; otherwise it is true. // // Examples: // # Can't enable this setting unless LOG_FCB is enabled. // pkg.restrictions: // LOG_FCB // // # Can't enable this setting unless LOG_FCB is disabled. // pkg.restrictions: // !LOG_FCB // // # Can't disable this setting unless LOG_FCB is enabled. // pkg.restrictions: // LOG_FCB if 0 func readRestrictionExpr(text string) (CfgRestrictionExpr, error) { e := CfgRestrictionExpr{} fields := strings.Fields(text) switch len(fields) { case 1: e.ReqSetting, e.ReqVal = parseRestrictionExprConsequent(fields[0]) e.BaseVal = true case 3: if fields[1] != "if" { return e, util.FmtNewtError("invalid restriction: %s", text) } e.ReqSetting, e.ReqVal = parseRestrictionExprConsequent(fields[0]) e.BaseVal = ValueIsTrue(fields[2]) default: return e, util.FmtNewtError("invalid restriction: %s", text) } return e, nil }
func readManifest(path string) (*image.ImageManifest, error) { content, err := ioutil.ReadFile(path) if err != nil { return nil, util.ChildNewtError(err) } manifest := &image.ImageManifest{} if err := json.Unmarshal(content, &manifest); err != nil { return nil, util.FmtNewtError( "Failure decoding manifest with path \"%s\": %s", err.Error()) } return manifest, nil }
func (c *Compiler) load(compilerDir string, buildProfile string) error { v, err := util.ReadConfig(compilerDir, "compiler") if err != nil { return err } features := map[string]bool{ buildProfile: true, strings.ToUpper(runtime.GOOS): true, } c.ccPath = newtutil.GetStringFeatures(v, features, "compiler.path.cc") c.cppPath = newtutil.GetStringFeatures(v, features, "compiler.path.cpp") c.asPath = newtutil.GetStringFeatures(v, features, "compiler.path.as") c.arPath = newtutil.GetStringFeatures(v, features, "compiler.path.archive") c.odPath = newtutil.GetStringFeatures(v, features, "compiler.path.objdump") c.osPath = newtutil.GetStringFeatures(v, features, "compiler.path.objsize") c.ocPath = newtutil.GetStringFeatures(v, features, "compiler.path.objcopy") c.lclInfo.Cflags = loadFlags(v, features, "compiler.flags") c.lclInfo.Lflags = loadFlags(v, features, "compiler.ld.flags") c.lclInfo.Aflags = loadFlags(v, features, "compiler.as.flags") c.ldResolveCircularDeps, err = newtutil.GetBoolFeatures(v, features, "compiler.ld.resolve_circular_deps") if err != nil { return err } c.ldMapFile, err = newtutil.GetBoolFeatures(v, features, "compiler.ld.mapfile") if err != nil { return err } c.ldBinFile, err = newtutil.GetBoolFeaturesDflt(v, features, "compiler.ld.binfile", true) if err != nil { return err } if len(c.lclInfo.Cflags) == 0 { // Assume no Cflags implies an unsupported build profile. return util.FmtNewtError("Compiler doesn't support build profile "+ "specified by target on this OS (build_profile=\"%s\" OS=\"%s\")", buildProfile, runtime.GOOS) } return nil }
func (cpm *ConnProfileMgr) DeleteConnProfile(name string) error { if cpm.profiles[name] == nil { return util.FmtNewtError("connection profile \"%s\" doesn't exist", name) } delete(cpm.profiles, name) err := cpm.save() if err != nil { return err } return nil }
func (cpm *ConnProfileMgr) GetConnProfile(pName string) (*ConnProfile, error) { // Each section is a connection profile, key values are the contents // of that section. if pName == "" { return nil, util.NewNewtError("Need to specify connection profile") } p := cpm.profiles[pName] if p == nil { return nil, util.FmtNewtError("connection profile \"%s\" doesn't "+ "exist", pName) } return p, nil }
func (mi *MfgImage) createManifest(cs createState) ([]byte, error) { manifest := mfgManifest{ BuildTime: time.Now().Format(time.RFC3339), MfgHash: fmt.Sprintf("%x", cs.hash), MetaSection: 0, MetaOffset: cs.metaOffset, } buffer, err := json.MarshalIndent(manifest, "", " ") if err != nil { return nil, util.FmtNewtError("Failed to encode mfg manifest: %s", err.Error()) } return buffer, nil }
func GetBoolFeaturesDflt(v *viper.Viper, features map[string]bool, key string, dflt bool) (bool, error) { s := GetStringFeatures(v, features, key) if s == "" { return dflt, nil } b, err := strconv.ParseBool(s) if err != nil { return dflt, util.FmtNewtError("invalid bool value for %s: %s", key, s) } return b, nil }
func (target *Target) Validate(appRequired bool) error { if target.BspName == "" { return util.NewNewtError("Target does not specify a BSP package " + "(target.bsp)") } bsp := target.resolvePackageName(target.BspName) if bsp == nil { return util.FmtNewtError("Could not resolve BSP package: %s", target.BspName) } if bsp.Type() != pkg.PACKAGE_TYPE_BSP { return util.FmtNewtError("bsp package (%s) is not of "+ "type bsp; type is: %s\n", bsp.Name(), pkg.PackageTypeNames[bsp.Type()]) } if appRequired { if target.AppName == "" { return util.NewNewtError("Target does not specify an app " + "package (target.app)") } app := target.resolvePackageName(target.AppName) if app == nil { return util.FmtNewtError("Could not resolve app package: %s", target.AppName) } if app.Type() != pkg.PACKAGE_TYPE_APP { return util.FmtNewtError("target.app package (%s) is not of "+ "type app; type is: %s\n", app.Name(), pkg.PackageTypeNames[app.Type()]) } if target.LoaderName != "" { loader := target.resolvePackageName(target.LoaderName) if loader == nil { return util.FmtNewtError( "Could not resolve loader package: %s", target.LoaderName) } if loader.Type() != pkg.PACKAGE_TYPE_APP { return util.FmtNewtError( "target.loader package (%s) is not of type app; type "+ "is: %s\n", loader.Name(), pkg.PackageTypeNames[loader.Type()]) } } } return nil }
func LoadDownloader(repoName string, repoVars map[string]string) ( Downloader, error) { switch repoVars["type"] { case "github": gd := NewGithubDownloader() gd.User = repoVars["user"] gd.Repo = repoVars["repo"] // The project.yml file can contain github access tokens and // authentication credentials, but this file is probably world-readable // and therefore not a great place for this. gd.Token = repoVars["token"] gd.Login = repoVars["login"] gd.Password = repoVars["password"] // Alternatively, the user can put security material in // $HOME/.newt/repos.yml. newtrc := newtutil.Newtrc() privRepo := newtrc.GetStringMapString("repository." + repoName) if privRepo != nil { if gd.Token == "" { gd.Token = privRepo["token"] } if gd.Login == "" { gd.Login = privRepo["login"] } if gd.Password == "" { gd.Password = privRepo["password"] } } return gd, nil case "local": ld := NewLocalDownloader() ld.Path = repoVars["path"] return ld, nil default: return nil, util.FmtNewtError("Invalid repository type: %s", repoVars["type"]) } }
func newSerialConfig( connString string, readTimeout time.Duration) (*serial.Config, error) { fields := strings.Split(connString, ":") if len(fields) == 0 { return nil, util.FmtNewtError("invalid connstring: %s", connString) } name := "" baud := 115200 for _, field := range fields { parts := strings.Split(field, "=") if len(parts) == 2 { if parts[0] == "baud" { var err error baud, err = strconv.Atoi(parts[1]) if err != nil { return nil, util.ChildNewtError(err) } } if parts[0] == "dev" { name = parts[1] } } } // Handle old-style conn string (single token indicating dev file). if name == "" { name = fields[0] } c := &serial.Config{ Name: name, Baud: baud, ReadTimeout: readTimeout, } return c, nil }
func imageStatePrintRsp(rsp *protocol.ImageStateRsp) error { if rsp.ReturnCode != 0 { return util.FmtNewtError("rc=%d\n", rsp.ReturnCode) } fmt.Println("Images:") for _, img := range rsp.Images { fmt.Printf(" slot=%d\n", img.Slot) fmt.Printf(" version: %s\n", img.Version) fmt.Printf(" bootable: %v\n", img.Bootable) fmt.Printf(" flags: %s\n", imageFlagsStr(img)) if len(img.Hash) == 0 { fmt.Printf(" hash: Unavailable\n") } else { fmt.Printf(" hash: %x\n", img.Hash) } } fmt.Printf("Split status: %s\n", rsp.SplitStatus.String()) return nil }
func NewBuilder(t *TargetBuilder, buildName string, lpkgs []*pkg.LocalPackage, apiMap map[string]*pkg.LocalPackage, cfg syscfg.Cfg) (*Builder, error) { b := &Builder{ PkgMap: make(map[*pkg.LocalPackage]*BuildPackage, len(lpkgs)), cfg: cfg, buildName: buildName, apiMap: make(map[string]*BuildPackage, len(apiMap)), linkElf: "", targetBuilder: t, injectedSettings: map[string]string{}, } for _, lpkg := range lpkgs { if _, err := b.addPackage(lpkg); err != nil { return nil, err } } // Create a pseudo build package for the generated sysinit code. if _, err := b.addSysinitBpkg(); err != nil { return nil, err } for api, lpkg := range apiMap { bpkg := b.PkgMap[lpkg] if bpkg == nil { for _, lpkg := range b.sortedLocalPackages() { log.Debugf(" * %s", lpkg.Name()) } return nil, util.FmtNewtError( "Unexpected unsatisfied API: %s; required by: %s", api, lpkg.Name()) } b.apiMap[api] = bpkg } return b, nil }
func ResolveMfgPkg(pkgName string) (*pkg.LocalPackage, error) { proj := InitProject() lpkg, err := proj.ResolvePackage(proj.LocalRepo(), pkgName) if err != nil { var err2 error lpkg, err2 = proj.ResolvePackage(proj.LocalRepo(), MFG_DEFAULT_DIR+"/"+pkgName) if err2 != nil { return nil, err } } if lpkg.Type() != pkg.PACKAGE_TYPE_MFG { return nil, util.FmtNewtError( "Package \"%s\" has incorrect type; expected mfg, got %s", pkgName, pkg.PackageTypeNames[lpkg.Type()]) } return lpkg, nil }