func loadBoards(boards map[string]*types.Board, packageId string, platformId string, folder string, logger i18n.Logger) error {
	boardsProperties, err := properties.Load(filepath.Join(folder, constants.FILE_BOARDS_TXT), logger)
	if err != nil {
		return i18n.WrapError(err)
	}

	localProperties, err := properties.SafeLoad(filepath.Join(folder, constants.FILE_BOARDS_LOCAL_TXT), logger)
	if err != nil {
		return i18n.WrapError(err)
	}

	boardsProperties = boardsProperties.Merge(localProperties)

	propertiesByBoardId := boardsProperties.FirstLevelOf()
	delete(propertiesByBoardId, constants.BOARD_PROPERTIES_MENU)

	for boardID, boardProperties := range propertiesByBoardId {
		boardProperties[constants.ID] = boardID
		board := getOrCreateBoard(boards, boardID)
		board.Properties.Merge(boardProperties)
		boards[boardID] = board
	}

	return nil
}
func libraryAlreadyDownloadedAndUnpacked(targetPath string, library Library) bool {
	_, err := os.Stat(filepath.Join(targetPath, strings.Replace(library.Name, " ", "_", -1)))
	if os.IsNotExist(err) {
		return false
	}

	libProps, err := properties.Load(filepath.Join(targetPath, strings.Replace(library.Name, " ", "_", -1), "library.properties"), i18n.HumanLogger{})
	if err != nil {
		return false
	}
	return libProps["version"] == library.Version || libProps["version"] == library.VersionInLibProperties
}
func coreAlreadyDownloadedAndUnpacked(targetPath string, core Core) (bool, error) {
	corePath := filepath.Join(targetPath, core.Maintainer, core.Arch)

	_, err := os.Stat(corePath)
	if os.IsNotExist(err) {
		return false, nil
	}
	platform, err := properties.Load(filepath.Join(corePath, "platform.txt"), i18n.HumanLogger{})
	if err != nil {
		return false, i18n.WrapError(err)
	}

	if core.Version != platform["version"] {
		err := os.RemoveAll(corePath)
		return false, i18n.WrapError(err)
	}

	return true, nil
}
func (s *PlatformKeysRewriteLoader) Run(ctx *types.Context) error {
	logger := ctx.GetLogger()
	folders := ctx.HardwareFolders

	platformKeysRewriteTxtPath, err := findPlatformKeysRewriteTxt(folders)
	if err != nil {
		return i18n.WrapError(err)
	}
	if platformKeysRewriteTxtPath == constants.EMPTY_STRING {
		return nil
	}

	platformKeysRewrite := types.PlatforKeysRewrite{}
	platformKeysRewrite.Rewrites = []types.PlatforKeyRewrite{}

	txt, err := properties.Load(platformKeysRewriteTxtPath, logger)
	keys := utils.KeysOfMapOfString(txt)
	sort.Strings(keys)

	for _, key := range keys {
		keyParts := strings.Split(key, ".")
		if keyParts[0] == constants.PLATFORM_REWRITE_OLD {
			index, err := strconv.Atoi(keyParts[1])
			if err != nil {
				return i18n.WrapError(err)
			}
			rewriteKey := strings.Join(keyParts[2:], ".")
			oldValue := txt[key]
			newValue := txt[constants.PLATFORM_REWRITE_NEW+"."+strings.Join(keyParts[1:], ".")]
			platformKeyRewrite := types.PlatforKeyRewrite{Key: rewriteKey, OldValue: oldValue, NewValue: newValue}
			platformKeysRewrite.Rewrites = growSliceOfRewrites(platformKeysRewrite.Rewrites, index)
			platformKeysRewrite.Rewrites[index] = platformKeyRewrite
		}
	}

	ctx.PlatformKeyRewrites = platformKeysRewrite

	return nil
}
func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (*types.Library, error) {
	libProperties, err := properties.Load(filepath.Join(libraryFolder, constants.LIBRARY_PROPERTIES), logger)
	if err != nil {
		return nil, i18n.WrapError(err)
	}

	if libProperties[constants.LIBRARY_MAINTAINER] == constants.EMPTY_STRING && libProperties[constants.LIBRARY_EMAIL] != constants.EMPTY_STRING {
		libProperties[constants.LIBRARY_MAINTAINER] = libProperties[constants.LIBRARY_EMAIL]
	}

	for _, propName := range LIBRARY_NOT_SO_MANDATORY_PROPERTIES {
		if libProperties[propName] == constants.EMPTY_STRING {
			libProperties[propName] = "-"
		}
	}

	library := &types.Library{}
	library.Folder = libraryFolder
	if stat, err := os.Stat(filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_SRC)); err == nil && stat.IsDir() {
		library.Layout = types.LIBRARY_RECURSIVE
		library.SrcFolder = filepath.Join(libraryFolder, constants.LIBRARY_FOLDER_SRC)
	} else {
		library.Layout = types.LIBRARY_FLAT
		library.SrcFolder = libraryFolder
		addUtilityFolder(library)
	}

	subFolders, err := utils.ReadDirFiltered(libraryFolder, utils.FilterDirs)
	if err != nil {
		return nil, i18n.WrapError(err)
	}

	if debugLevel >= 0 {
		for _, subFolder := range subFolders {
			if utils.IsSCCSOrHiddenFile(subFolder) {
				if !utils.IsSCCSFile(subFolder) && utils.IsHiddenFile(subFolder) {
					logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_WARNING_SPURIOUS_FILE_IN_LIB, filepath.Base(subFolder.Name()), libProperties[constants.LIBRARY_NAME])
				}
			}
		}
	}

	if libProperties[constants.LIBRARY_ARCHITECTURES] == constants.EMPTY_STRING {
		libProperties[constants.LIBRARY_ARCHITECTURES] = constants.LIBRARY_ALL_ARCHS
	}
	library.Archs = []string{}
	for _, arch := range strings.Split(libProperties[constants.LIBRARY_ARCHITECTURES], ",") {
		library.Archs = append(library.Archs, strings.TrimSpace(arch))
	}

	libProperties[constants.LIBRARY_CATEGORY] = strings.TrimSpace(libProperties[constants.LIBRARY_CATEGORY])
	if !LIBRARY_CATEGORIES[libProperties[constants.LIBRARY_CATEGORY]] {
		logger.Fprintln(os.Stdout, constants.LOG_LEVEL_WARN, constants.MSG_WARNING_LIB_INVALID_CATEGORY, libProperties[constants.LIBRARY_CATEGORY], libProperties[constants.LIBRARY_NAME], constants.LIB_CATEGORY_UNCATEGORIZED)
		libProperties[constants.LIBRARY_CATEGORY] = constants.LIB_CATEGORY_UNCATEGORIZED
	}
	library.Category = libProperties[constants.LIBRARY_CATEGORY]

	if libProperties[constants.LIBRARY_LICENSE] == constants.EMPTY_STRING {
		libProperties[constants.LIBRARY_LICENSE] = constants.LIB_LICENSE_UNSPECIFIED
	}
	library.License = libProperties[constants.LIBRARY_LICENSE]

	library.Name = filepath.Base(libraryFolder)
	library.Version = strings.TrimSpace(libProperties[constants.LIBRARY_VERSION])
	library.Author = strings.TrimSpace(libProperties[constants.LIBRARY_AUTHOR])
	library.Maintainer = strings.TrimSpace(libProperties[constants.LIBRARY_MAINTAINER])
	library.Sentence = strings.TrimSpace(libProperties[constants.LIBRARY_SENTENCE])
	library.Paragraph = strings.TrimSpace(libProperties[constants.LIBRARY_PARAGRAPH])
	library.URL = strings.TrimSpace(libProperties[constants.LIBRARY_URL])
	library.IsLegacy = false
	library.DotALinkage = strings.TrimSpace(libProperties[constants.LIBRARY_DOT_A_LINKAGE]) == "true"
	library.Properties = libProperties

	return library, nil
}