func (s *CreateBuildOptionsMap) Run(context map[string]interface{}) error { buildOptions := make(map[string]string) for _, key := range []string{constants.CTX_HARDWARE_FOLDERS, constants.CTX_TOOLS_FOLDERS, constants.CTX_LIBRARIES_FOLDERS, constants.CTX_FQBN, constants.CTX_SKETCH_LOCATION, constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION} { originalValue := context[key] value := constants.EMPTY_STRING kindOfValue := reflect.TypeOf(originalValue).Kind() if kindOfValue == reflect.Slice { value = strings.Join(originalValue.([]string), ",") } else if kindOfValue == reflect.String { value = originalValue.(string) } else { return utils.Errorf(context, constants.MSG_UNHANDLED_TYPE_IN_CONTEXT, kindOfValue.String(), key) } buildOptions[key] = value } context[constants.CTX_BUILD_OPTIONS] = buildOptions bytes, err := json.MarshalIndent(buildOptions, "", " ") if err != nil { return utils.WrapError(err) } context[constants.CTX_BUILD_OPTIONS_JSON] = string(bytes) return nil }
func (s *CTagsRunner) Run(context map[string]interface{}) error { buildProperties := context[constants.CTX_BUILD_PROPERTIES].(map[string]string) ctagsTargetFileName := context[constants.CTX_CTAGS_TEMP_FILE_NAME].(string) logger := context[constants.CTX_LOGGER].(i18n.Logger) properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties, props.SubTree(props.SubTree(buildProperties, constants.BUILD_PROPERTIES_TOOLS_KEY), constants.CTAGS)) properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = ctagsTargetFileName pattern := properties[constants.BUILD_PROPERTIES_PATTERN] if pattern == constants.EMPTY_STRING { return utils.Errorf(context, constants.MSG_PATTERN_MISSING, constants.CTAGS) } commandLine := props.ExpandPropsInString(properties, pattern) command, err := utils.PrepareCommand(commandLine, logger) if err != nil { return utils.WrapError(err) } verbose := context[constants.CTX_VERBOSE].(bool) if verbose { fmt.Println(commandLine) } sourceBytes, err := command.Output() if err != nil { return utils.WrapError(err) } context[constants.CTX_CTAGS_OUTPUT] = string(sourceBytes) return nil }
func (s *HardwareLoader) Run(context map[string]interface{}) error { mainHardwarePlatformTxt := make(map[string]string) packages := make(map[string]*types.Package) folders := context[constants.CTX_HARDWARE_FOLDERS].([]string) folders, err := utils.AbsolutizePaths(folders) if err != nil { return utils.WrapError(err) } for _, folder := range folders { stat, err := os.Stat(folder) if err != nil { return utils.WrapError(err) } if !stat.IsDir() { return utils.Errorf(context, constants.MSG_MUST_BE_A_FOLDER, folder) } if len(mainHardwarePlatformTxt) == 0 { mainHardwarePlatformTxt, err = props.SafeLoad(filepath.Join(folder, constants.FILE_PLATFORM_TXT)) if err != nil { return utils.WrapError(err) } } hardwarePlatformTxt, err := props.SafeLoad(filepath.Join(folder, constants.FILE_PLATFORM_TXT)) if err != nil { return utils.WrapError(err) } hardwarePlatformTxt = utils.MergeMapsOfStrings(make(map[string]string), mainHardwarePlatformTxt, hardwarePlatformTxt) subfolders, err := utils.ReadDirFiltered(folder, utils.FilterDirs) if err != nil { return utils.WrapError(err) } subfolders = utils.FilterOutFoldersByNames(subfolders, constants.FOLDER_TOOLS) for _, subfolder := range subfolders { subfolderPath := filepath.Join(folder, subfolder.Name()) packageId := subfolder.Name() if _, err := os.Stat(filepath.Join(subfolderPath, constants.FOLDER_HARDWARE)); err == nil { subfolderPath = filepath.Join(subfolderPath, constants.FOLDER_HARDWARE) } targetPackage := getOrCreatePackage(packages, packageId) err = loadPackage(targetPackage, subfolderPath, hardwarePlatformTxt) if err != nil { return utils.WrapError(err) } packages[packageId] = targetPackage } } context[constants.CTX_HARDWARE] = packages return nil }
func (s *CoanRunner) Run(context map[string]interface{}) error { source := context[constants.CTX_SOURCE].(string) source += "\n" verbose := context[constants.CTX_VERBOSE].(bool) preprocPath := context[constants.CTX_PREPROC_PATH].(string) err := utils.EnsureFolderExists(preprocPath) if err != nil { return utils.WrapError(err) } coanTargetFileName := filepath.Join(preprocPath, constants.FILE_COAN_TARGET) err = utils.WriteFile(coanTargetFileName, source) if err != nil { return utils.WrapError(err) } buildProperties := context[constants.CTX_BUILD_PROPERTIES].(props.PropertiesMap) properties := buildProperties.Clone() properties.Merge(buildProperties.SubTree(constants.BUILD_PROPERTIES_TOOLS_KEY).SubTree(constants.COAN)) properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = coanTargetFileName pattern := properties[constants.BUILD_PROPERTIES_PATTERN] if pattern == constants.EMPTY_STRING { return utils.Errorf(context, constants.MSG_PATTERN_MISSING, constants.COAN) } logger := context[constants.CTX_LOGGER].(i18n.Logger) commandLine := properties.ExpandPropsInString(pattern) command, err := utils.PrepareCommandFilteredArgs(commandLine, filterAllowedArg, logger) if verbose { fmt.Println(commandLine) } sourceBytes, _ := command.Output() context[constants.CTX_SOURCE] = string(sourceBytes) return nil }
func (s *SketchLoader) Run(context map[string]interface{}) error { if !utils.MapHas(context, constants.CTX_SKETCH_LOCATION) { return nil } sketchLocation := context[constants.CTX_SKETCH_LOCATION].(string) sketchLocation, err := filepath.Abs(sketchLocation) if err != nil { return utils.WrapError(err) } mainSketchStat, err := os.Stat(sketchLocation) if err != nil { return utils.WrapError(err) } if mainSketchStat.IsDir() { sketchLocation = filepath.Join(sketchLocation, mainSketchStat.Name()+".ino") } context[constants.CTX_SKETCH_LOCATION] = sketchLocation allSketchFilePaths, err := collectAllSketchFiles(filepath.Dir(sketchLocation)) if err != nil { return utils.WrapError(err) } if !utils.SliceContains(allSketchFilePaths, sketchLocation) { return utils.Errorf(context, constants.MSG_CANT_FIND_SKETCH_IN_PATH, sketchLocation, filepath.Dir(sketchLocation)) } logger := context[constants.CTX_LOGGER].(i18n.Logger) sketch, err := makeSketch(sketchLocation, allSketchFilePaths, logger) if err != nil { return utils.WrapError(err) } context[constants.CTX_SKETCH_LOCATION] = sketchLocation context[constants.CTX_SKETCH] = sketch return nil }
func (s *FailIfBuildPathEqualsSketchPath) Run(context map[string]interface{}) error { if !utils.MapHas(context, constants.CTX_BUILD_PATH) || !utils.MapHas(context, constants.CTX_SKETCH_LOCATION) { return nil } buildPath, err := filepath.Abs(context[constants.CTX_BUILD_PATH].(string)) if err != nil { return utils.WrapError(err) } sketchPath, err := filepath.Abs(context[constants.CTX_SKETCH_LOCATION].(string)) if err != nil { return utils.WrapError(err) } sketchPath = filepath.Dir(sketchPath) if buildPath == sketchPath { return utils.Errorf(context, constants.MSG_SKETCH_CANT_BE_IN_BUILDPATH) } return nil }
func (s *SetupBuildProperties) Run(context map[string]interface{}) error { packages := context[constants.CTX_HARDWARE].(map[string]*types.Package) targetPlatform := context[constants.CTX_TARGET_PLATFORM].(*types.Platform) actualPlatform := context[constants.CTX_ACTUAL_PLATFORM].(*types.Platform) targetBoard := context[constants.CTX_TARGET_BOARD].(*types.Board) buildProperties := make(map[string]string) utils.MergeMapsOfStrings(buildProperties, actualPlatform.Properties) utils.MergeMapsOfStrings(buildProperties, targetPlatform.Properties) utils.MergeMapsOfStrings(buildProperties, targetBoard.Properties) if utils.MapHas(context, constants.CTX_BUILD_PATH) { buildProperties[constants.BUILD_PROPERTIES_BUILD_PATH] = context[constants.CTX_BUILD_PATH].(string) } if utils.MapHas(context, constants.CTX_SKETCH) { buildProperties[constants.BUILD_PROPERTIES_BUILD_PROJECT_NAME] = filepath.Base(context[constants.CTX_SKETCH].(*types.Sketch).MainFile.Name) } buildProperties[constants.BUILD_PROPERTIES_BUILD_ARCH] = strings.ToUpper(targetPlatform.PlatformId) if buildProperties[constants.BUILD_PROPERTIES_COMPILER_PATH] == constants.EMPTY_STRING { return utils.Errorf(context, constants.MSG_MISSING_COMPILER_PATH) } buildProperties[constants.BUILD_PROPERTIES_BUILD_CORE] = context[constants.CTX_BUILD_CORE].(string) buildProperties[constants.BUILD_PROPERTIES_BUILD_CORE_PATH] = filepath.Join(actualPlatform.Folder, constants.FOLDER_CORES, buildProperties[constants.BUILD_PROPERTIES_BUILD_CORE]) buildProperties[constants.BUILD_PROPERTIES_BUILD_SYSTEM_PATH] = filepath.Join(actualPlatform.Folder, constants.FOLDER_SYSTEM) buildProperties[constants.BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH] = actualPlatform.Folder buildProperties[constants.BUILD_PROPERTIES_RUNTIME_HARDWARE_PATH] = filepath.Join(actualPlatform.Folder, "..") buildProperties[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION].(string) buildProperties[constants.IDE_VERSION] = context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION].(string) buildProperties[constants.BUILD_PROPERTIES_RUNTIME_OS] = utils.PrettyOSName() variant := buildProperties[constants.BUILD_PROPERTIES_BUILD_VARIANT] if variant == constants.EMPTY_STRING { buildProperties[constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH] = constants.EMPTY_STRING } else { var variantPlatform *types.Platform variantParts := strings.Split(variant, ":") if len(variantParts) > 1 { variantPlatform = packages[variantParts[0]].Platforms[targetPlatform.PlatformId] variant = variantParts[1] } else { variantPlatform = targetPlatform } buildProperties[constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH] = filepath.Join(variantPlatform.Folder, constants.FOLDER_VARIANTS, variant) } tools := context[constants.CTX_TOOLS].([]*types.Tool) for _, tool := range tools { buildProperties[constants.BUILD_PROPERTIES_RUNTIME_TOOLS_PREFIX+tool.Name+constants.BUILD_PROPERTIES_RUNTIME_TOOLS_SUFFIX] = tool.Folder buildProperties[constants.BUILD_PROPERTIES_RUNTIME_TOOLS_PREFIX+tool.Name+"-"+tool.Version+constants.BUILD_PROPERTIES_RUNTIME_TOOLS_SUFFIX] = tool.Folder } if !utils.MapStringStringHas(buildProperties, constants.BUILD_PROPERTIES_SOFTWARE) { buildProperties[constants.BUILD_PROPERTIES_SOFTWARE] = DEFAULT_SOFTWARE } if utils.MapHas(context, constants.CTX_SKETCH_LOCATION) { sourcePath, err := filepath.Abs(context[constants.CTX_SKETCH_LOCATION].(string)) if err != nil { return err } buildProperties[constants.BUILD_PROPERTIES_SOURCE_PATH] = sourcePath } context[constants.CTX_BUILD_PROPERTIES] = buildProperties return nil }
func (s *TargetBoardResolver) Run(context map[string]interface{}) error { fqbn := context[constants.CTX_FQBN].(string) fqbnParts := strings.Split(fqbn, ":") targetPackageName := fqbnParts[0] targetPlatformName := fqbnParts[1] targetBoardName := fqbnParts[2] packages := context[constants.CTX_HARDWARE].(*types.Packages) targetPackage := packages.Packages[targetPackageName] if targetPackage == nil { return utils.Errorf(context, constants.MSG_PACKAGE_UNKNOWN, targetPackageName) } targetPlatform := targetPackage.Platforms[targetPlatformName] if targetPlatform == nil { return utils.Errorf(context, constants.MSG_PLATFORM_UNKNOWN, targetPlatformName, targetPackageName) } targetBoard := targetPlatform.Boards[targetBoardName] if targetBoard == nil { return utils.Errorf(context, constants.MSG_BOARD_UNKNOWN, targetBoardName, targetPlatformName, targetPackageName) } context[constants.CTX_TARGET_PACKAGE] = targetPackage context[constants.CTX_TARGET_PLATFORM] = targetPlatform context[constants.CTX_TARGET_BOARD] = targetBoard if len(fqbnParts) > 3 { addAdditionalPropertiesToTargetBoard(targetBoard, fqbnParts[3]) } core := targetBoard.Properties[constants.BUILD_PROPERTIES_BUILD_CORE] if core == constants.EMPTY_STRING { core = DEFAULT_BUILD_CORE } var corePlatform *types.Platform coreParts := strings.Split(core, ":") if len(coreParts) > 1 { core = coreParts[1] if packages.Packages[coreParts[0]] == nil { return utils.Errorf(context, constants.MSG_MISSING_CORE_FOR_BOARD, coreParts[0]) } corePlatform = packages.Packages[coreParts[0]].Platforms[targetPlatform.PlatformId] } var actualPlatform *types.Platform if corePlatform != nil { actualPlatform = corePlatform } else { actualPlatform = targetPlatform } context[constants.CTX_BUILD_CORE] = core context[constants.CTX_ACTUAL_PLATFORM] = actualPlatform return nil }