func tryBuildWithContext(t *testing.T, context map[string]interface{}, sketchPath ...string) {
	sketchLocation := filepath.Join(sketchPath...)
	context[constants.CTX_SKETCH_LOCATION] = sketchLocation

	err := builder.RunBuilder(context)
	NoError(t, err, "Build error for "+sketchLocation)
}
func tryBuildWithContext(t *testing.T, ctx *types.Context, sketchPath ...string) {
	sketchLocation := filepath.Join(sketchPath...)
	ctx.SketchLocation = sketchLocation

	err := builder.RunBuilder(ctx)
	NoError(t, err, "Build error for "+sketchLocation)
}
예제 #3
0
func main() {
	flag.Parse()

	if *versionFlag {
		fmt.Println("Arduino Builder " + VERSION)
		fmt.Println("Copyright (C) 2015 Arduino LLC and contributors")
		fmt.Println("See https://www.arduino.cc/ and https://github.com/arduino/arduino-builder/graphs/contributors")
		fmt.Println("This is free software; see the source for copying conditions.  There is NO")
		fmt.Println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.")
		return
	}

	ctx := &types.Context{}

	if *buildOptionsFileFlag != "" {
		buildOptions := make(props.PropertiesMap)
		if _, err := os.Stat(*buildOptionsFileFlag); err == nil {
			data, err := ioutil.ReadFile(*buildOptionsFileFlag)
			if err != nil {
				printCompleteError(err)
			}
			err = json.Unmarshal(data, &buildOptions)
			if err != nil {
				printCompleteError(err)
			}
		}
		ctx.InjectBuildOptions(buildOptions)
	}

	// FLAG_HARDWARE
	if hardwareFolders, err := toSliceOfUnquoted(hardwareFoldersFlag); err != nil {
		printCompleteError(err)
	} else if len(hardwareFolders) > 0 {
		ctx.HardwareFolders = hardwareFolders
	}
	if len(ctx.HardwareFolders) == 0 {
		printErrorMessageAndFlagUsage(errors.New("Parameter '" + FLAG_HARDWARE + "' is mandatory"))
	}

	// FLAG_TOOLS
	if toolsFolders, err := toSliceOfUnquoted(toolsFoldersFlag); err != nil {
		printCompleteError(err)
	} else if len(toolsFolders) > 0 {
		ctx.ToolsFolders = toolsFolders
	}
	if len(ctx.ToolsFolders) == 0 {
		printErrorMessageAndFlagUsage(errors.New("Parameter '" + FLAG_TOOLS + "' is mandatory"))
	}

	// FLAG_LIBRARIES
	if librariesFolders, err := toSliceOfUnquoted(librariesFoldersFlag); err != nil {
		printCompleteError(err)
	} else if len(librariesFolders) > 0 {
		ctx.OtherLibrariesFolders = librariesFolders
	}

	// FLAG_BUILT_IN_LIBRARIES
	if librariesBuiltInFolders, err := toSliceOfUnquoted(librariesBuiltInFoldersFlag); err != nil {
		printCompleteError(err)
	} else if len(librariesBuiltInFolders) > 0 {
		ctx.BuiltInLibrariesFolders = librariesBuiltInFolders
	}

	// FLAG_PREFS
	if customBuildProperties, err := toSliceOfUnquoted(customBuildPropertiesFlag); err != nil {
		printCompleteError(err)
	} else if len(customBuildProperties) > 0 {
		ctx.CustomBuildProperties = customBuildProperties
	}

	// FLAG_FQBN
	if fqbn, err := gohasissues.Unquote(*fqbnFlag); err != nil {
		printCompleteError(err)
	} else if fqbn != "" {
		ctx.FQBN = fqbn
	}
	if ctx.FQBN == "" {
		printErrorMessageAndFlagUsage(errors.New("Parameter '" + FLAG_FQBN + "' is mandatory"))
	}

	// FLAG_BUILD_PATH
	buildPath, err := gohasissues.Unquote(*buildPathFlag)
	if err != nil {
		printCompleteError(err)
	}
	if buildPath != "" {
		_, err := os.Stat(buildPath)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			os.Exit(1)
		}

		err = utils.EnsureFolderExists(buildPath)
		if err != nil {
			printCompleteError(err)
		}
	}
	ctx.BuildPath = buildPath

	// FLAG_VID_PID
	if *vidPidFlag != "" {
		ctx.USBVidPid = *vidPidFlag
	}

	if flag.NArg() > 0 {
		sketchLocation := flag.Arg(0)
		sketchLocation, err := gohasissues.Unquote(sketchLocation)
		if err != nil {
			printCompleteError(err)
		}
		ctx.SketchLocation = sketchLocation
	}

	if *verboseFlag && *quietFlag {
		*verboseFlag = false
		*quietFlag = false
	}

	ctx.Verbose = *verboseFlag

	// FLAG_IDE_VERSION
	if ctx.ArduinoAPIVersion == "" {
		// if deprecated "--ideVersionFlag" has been used...
		if *coreAPIVersionFlag == "10600" && *ideVersionFlag != "10600" {
			ctx.ArduinoAPIVersion = *ideVersionFlag
		} else {
			ctx.ArduinoAPIVersion = *coreAPIVersionFlag
		}
	}

	if *warningsLevelFlag != "" {
		ctx.WarningsLevel = *warningsLevelFlag
	}

	if *debugLevelFlag > -1 {
		ctx.DebugLevel = *debugLevelFlag
	}

	if *quietFlag {
		ctx.SetLogger(i18n.NoopLogger{})
	} else if *loggerFlag == FLAG_LOGGER_MACHINE {
		ctx.SetLogger(i18n.MachineLogger{})
	} else {
		ctx.SetLogger(i18n.HumanLogger{})
	}

	if *dumpPrefsFlag {
		err = builder.RunParseHardwareAndDumpBuildProperties(ctx)
	} else if *preprocessFlag {
		err = builder.RunPreprocess(ctx)
	} else {
		if flag.NArg() == 0 {
			fmt.Fprintln(os.Stderr, "Last parameter must be the sketch to compile")
			flag.Usage()
			os.Exit(1)
		}
		err = builder.RunBuilder(ctx)
	}

	if err != nil {
		err = i18n.WrapError(err)

		fmt.Fprintln(os.Stderr, err)

		if ctx.DebugLevel >= 10 {
			fmt.Fprintln(os.Stderr, err.(*errors.Error).ErrorStack())
		}

		os.Exit(toExitCode(err))
	}
}
예제 #4
0
func main() {
	flag.Parse()

	if *versionFlag {
		fmt.Println("Arduino Builder " + VERSION)
		fmt.Println("Copyright (C) 2015 Arduino LLC and contributors")
		fmt.Println("See https://www.arduino.cc/ and https://github.com/arduino/arduino-builder/graphs/contributors")
		fmt.Println("This is free software; see the source for copying conditions.  There is NO")
		fmt.Println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.")
		defer os.Exit(0)
		return
	}

	context := make(map[string]interface{})

	buildOptions := make(map[string]string)
	if *buildOptionsFileFlag != "" {
		if _, err := os.Stat(*buildOptionsFileFlag); err == nil {
			data, err := ioutil.ReadFile(*buildOptionsFileFlag)
			if err != nil {
				printCompleteError(err)
				defer os.Exit(1)
				return
			}
			err = json.Unmarshal(data, &buildOptions)
			if err != nil {
				printCompleteError(err)
				defer os.Exit(1)
				return
			}
		}
	}

	var err error
	printStackTrace := false
	err, printStackTrace = setContextSliceKeyOrLoadItFromOptions(context, hardwareFoldersFlag, buildOptions, constants.CTX_HARDWARE_FOLDERS, FLAG_HARDWARE, true)
	if err != nil {
		printError(err, printStackTrace)
		defer os.Exit(1)
		return
	}

	err, printStackTrace = setContextSliceKeyOrLoadItFromOptions(context, toolsFoldersFlag, buildOptions, constants.CTX_TOOLS_FOLDERS, FLAG_TOOLS, true)
	if err != nil {
		printError(err, printStackTrace)
		defer os.Exit(1)
		return
	}

	err, printStackTrace = setContextSliceKeyOrLoadItFromOptions(context, librariesFoldersFlag, buildOptions, constants.CTX_OTHER_LIBRARIES_FOLDERS, FLAG_LIBRARIES, false)
	if err != nil {
		printError(err, printStackTrace)
		defer os.Exit(1)
		return
	}

	err, printStackTrace = setContextSliceKeyOrLoadItFromOptions(context, librariesBuiltInFoldersFlag, buildOptions, constants.CTX_BUILT_IN_LIBRARIES_FOLDERS, FLAG_BUILT_IN_LIBRARIES, false)
	if err != nil {
		printError(err, printStackTrace)
		defer os.Exit(1)
		return
	}

	err, printStackTrace = setContextSliceKeyOrLoadItFromOptions(context, customBuildPropertiesFlag, buildOptions, constants.CTX_CUSTOM_BUILD_PROPERTIES, FLAG_PREFS, false)
	if err != nil {
		printError(err, printStackTrace)
		defer os.Exit(1)
		return
	}

	fqbn, err := gohasissues.Unquote(*fqbnFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}

	if fqbn == "" {
		fqbn = buildOptions[constants.CTX_FQBN]
	}

	if fqbn == "" {
		printErrorMessageAndFlagUsage(errors.New("Parameter '" + FLAG_FQBN + "' is mandatory"))
		defer os.Exit(1)
		return
	}
	context[constants.CTX_FQBN] = fqbn

	buildPath, err := gohasissues.Unquote(*buildPathFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}

	if buildPath != "" {
		_, err := os.Stat(buildPath)
		if err != nil {
			fmt.Fprintln(os.Stderr, err)
			defer os.Exit(1)
			return
		}

		err = utils.EnsureFolderExists(buildPath)
		if err != nil {
			printCompleteError(err)
			defer os.Exit(1)
			return
		}
	}
	context[constants.CTX_BUILD_PATH] = buildPath

	if *vidPidFlag != "" {
		context[constants.CTX_VIDPID] = *vidPidFlag
	}

	if flag.NArg() > 0 {
		sketchLocation := flag.Arg(0)
		sketchLocation, err := gohasissues.Unquote(sketchLocation)
		if err != nil {
			printCompleteError(err)
			defer os.Exit(1)
			return
		}
		context[constants.CTX_SKETCH_LOCATION] = sketchLocation
	}

	if *verboseFlag && *quietFlag {
		*verboseFlag = false
		*quietFlag = false
	}

	context[constants.CTX_VERBOSE] = *verboseFlag

	ideVersion := ""
	if utils.MapStringStringHas(buildOptions, constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION) {
		ideVersion = buildOptions[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION]
	} else {
		ideVersion = *ideVersionFlag
	}
	context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = ideVersion

	if *warningsLevelFlag != "" {
		context[constants.CTX_WARNINGS_LEVEL] = *warningsLevelFlag
	}

	if *debugLevelFlag > -1 {
		context[constants.CTX_DEBUG_LEVEL] = *debugLevelFlag
	}

	if *libraryDiscoveryRecursionDepthFlag > 0 {
		context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH] = *libraryDiscoveryRecursionDepthFlag
	}

	if *quietFlag {
		context[constants.CTX_LOGGER] = i18n.NoopLogger{}
	} else if *loggerFlag == FLAG_LOGGER_MACHINE {
		context[constants.CTX_LOGGER] = i18n.MachineLogger{}
	} else {
		context[constants.CTX_LOGGER] = i18n.HumanLogger{}
	}

	if *dumpPrefsFlag {
		err = builder.RunParseHardwareAndDumpBuildProperties(context)
	} else if *preprocessFlag {
		err = builder.RunPreprocess(context)
	} else {
		if flag.NArg() == 0 {
			fmt.Fprintln(os.Stderr, "Last parameter must be the sketch to compile")
			flag.Usage()
			defer os.Exit(1)
			return
		}
		err = builder.RunBuilder(context)
	}

	exitCode := 0
	if err != nil {
		err = utils.WrapError(err)

		fmt.Fprintln(os.Stderr, err)

		if utils.DebugLevel(context) >= 10 {
			fmt.Fprintln(os.Stderr, err.(*errors.Error).ErrorStack())
		}

		exitCode = toExitCode(err)
	}

	defer os.Exit(exitCode)
}
예제 #5
0
func main() {
	flag.Parse()

	if *versionFlag {
		fmt.Println("Arduino Builder " + VERSION)
		fmt.Println("Copyright (C) 2015 Arduino LLC and contributors")
		fmt.Println("See https://www.arduino.cc/ and https://github.com/arduino/arduino-builder/graphs/contributors")
		fmt.Println("This is free software; see the source for copying conditions.  There is NO")
		fmt.Println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.")
		defer os.Exit(0)
		return
	}

	compile := *compileFlag
	dumpPrefs := *dumpPrefsFlag

	if compile && dumpPrefs {
		fmt.Println("You can either specify --compile or --dump-prefs, not both")
		defer os.Exit(1)
		return
	}

	if !compile && !dumpPrefs {
		compile = true
	}

	context := make(map[string]interface{})

	hardware, err := toSliceOfUnquoted(hardwareFoldersFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}

	if len(hardware) == 0 {
		fmt.Println("Parameter 'hardware' is mandatory")
		flag.Usage()
		defer os.Exit(1)
		return
	}
	context[constants.CTX_HARDWARE_FOLDERS] = hardware

	tools, err := toSliceOfUnquoted(toolsFoldersFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}

	if len(tools) == 0 {
		fmt.Println("Parameter 'tools' is mandatory")
		flag.Usage()
		defer os.Exit(1)
		return
	}
	context[constants.CTX_TOOLS_FOLDERS] = tools

	libraries, err := toSliceOfUnquoted(librariesFoldersFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}
	context[constants.CTX_LIBRARIES_FOLDERS] = libraries

	customBuildProperties, err := toSliceOfUnquoted(customBuildPropertiesFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}
	context[constants.CTX_CUSTOM_BUILD_PROPERTIES] = customBuildProperties

	fqbn, err := gohasissues.Unquote(*fqbnFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}

	if fqbn == "" {
		fmt.Println("Parameter 'fqbn' is mandatory")
		flag.Usage()
		defer os.Exit(1)
		return
	}
	context[constants.CTX_FQBN] = fqbn

	buildPath, err := gohasissues.Unquote(*buildPathFlag)
	if err != nil {
		printCompleteError(err)
		defer os.Exit(1)
		return
	}

	if buildPath != "" {
		_, err := os.Stat(buildPath)
		if err != nil {
			fmt.Println(err)
			defer os.Exit(1)
			return
		}

		err = os.MkdirAll(buildPath, os.FileMode(0755))
		if err != nil {
			printCompleteError(err)
			defer os.Exit(1)
			return
		}
	}
	context[constants.CTX_BUILD_PATH] = buildPath

	if compile && flag.NArg() == 0 {
		fmt.Println("Last parameter must be the sketch to compile")
		flag.Usage()
		defer os.Exit(1)
		return
	}

	if flag.NArg() > 0 {
		sketchLocation := flag.Arg(0)
		sketchLocation, err := gohasissues.Unquote(sketchLocation)
		if err != nil {
			printCompleteError(err)
			defer os.Exit(1)
			return
		}
		context[constants.CTX_SKETCH_LOCATION] = sketchLocation
	}

	context[constants.CTX_VERBOSE] = *verboseFlag
	context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = *ideVersionFlag

	if *warningsLevelFlag != "" {
		context[constants.CTX_WARNINGS_LEVEL] = *warningsLevelFlag
	}

	if *debugLevelFlag > -1 {
		context[constants.CTX_DEBUG_LEVEL] = *debugLevelFlag
	}

	if *libraryDiscoveryRecursionDepthFlag > 0 {
		context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH] = *libraryDiscoveryRecursionDepthFlag
	}

	if *loggerFlag == "machine" {
		context[constants.CTX_LOGGER] = i18n.MachineLogger{}
	} else {
		context[constants.CTX_LOGGER] = i18n.HumanLogger{}
	}

	if compile {
		err = builder.RunBuilder(context)
	} else if dumpPrefs {
		err = builder.RunParseHardwareAndDumpBuildProperties(context)
	}

	exitCode := 0
	if err != nil {
		err = utils.WrapError(err)

		fmt.Println(err)

		if utils.DebugLevel(context) >= 10 {
			fmt.Println(err.(*errors.Error).ErrorStack())
		}

		exitCode = toExitCode(err)
	}

	defer os.Exit(exitCode)
}