diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..452e43a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.egg-info +*.pyc +.pioenvs +.tox +.sconsign.dblite diff --git a/.isort.cfg b/.isort.cfg new file mode 100644 index 00000000..eac2292a --- /dev/null +++ b/.isort.cfg @@ -0,0 +1,3 @@ +[settings] +line_length=79 +known_third_party=click,clint,serial,SCons diff --git a/README.md b/README.rst similarity index 87% rename from README.md rename to README.rst index ccf1827b..a7b72c52 100644 --- a/README.md +++ b/README.rst @@ -1,4 +1,4 @@ -platformio +PlatformIO ========== An easy way to build code with different development platforms diff --git a/platformio/__init__.py b/platformio/__init__.py new file mode 100644 index 00000000..db04a2b1 --- /dev/null +++ b/platformio/__init__.py @@ -0,0 +1,16 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +VERSION = (0, 0, 0) +__version__ = ".".join([str(s) for s in VERSION]) + +__title__ = "platformio" +__description__ = ("An easy way to build code with different development" + "platforms") +__url__ = "https://github.com/ivankravets/platformio" + +__author__ = "Ivan Kravets" +__email__ = "me@ikravets.com" + +__license__ = "MIT Licence" +__copyright__ = "Copyright (C) 2014 Ivan Kravets" diff --git a/platformio/__main__.py b/platformio/__main__.py new file mode 100644 index 00000000..a144528c --- /dev/null +++ b/platformio/__main__.py @@ -0,0 +1,84 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +import click +from sys import exit + +from clint.textui import colored, indent, puts + + +from platformio.util import get_project_config, run_builder + + +@click.group() +def main(): + pass + + +@main.group() +def init(): + """ Initialize new platformio based project """ + pass + + +@main.group() +def install(): + """ Install new platforms """ + pass + + +@main.group() +def list(): + """ List installed platforms """ + pass + + +@main.command() +@click.option("--environment", "-e", multiple=True) +@click.option("--target", "-t", multiple=True) +def run(environment, target): + """Process project environments """ + + config = get_project_config() + for section in config.sections(): + if section[:4] != "env:": + continue + envname = section[4:] + + if environment and envname not in environment: + puts("Skipped %s environment" % colored.yellow(envname)) + continue + + puts("Processing %s environment:" % colored.cyan(envname)) + variables = ["%s=%s" % (o.upper(), v) for o, v in config.items(section) + if o != "targets"] + variables.append("PIOENV=" + envname) + + envtargets = [] + if target: + envtargets = [t for t in target] + elif config.has_option(section, "targets"): + envtargets = config.get(section, "targets").split() + + result = run_builder(variables, envtargets) + + # print result + with indent(4, quote=colored.white(".")): + puts(colored.green(result['out'])) + puts(colored.red(result['err'])) + + +@main.group() +def search(): + """ Search for new platforms """ + pass + + +@main.group() +def show(): + """ Show information about installed platforms """ + pass + + +if __name__ == "__main__": + exit(main()) diff --git a/platformio/builder/__init__.py b/platformio/builder/__init__.py new file mode 100644 index 00000000..ca6f0304 --- /dev/null +++ b/platformio/builder/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. diff --git a/platformio/builder/main.py b/platformio/builder/main.py new file mode 100644 index 00000000..00d0d0d0 --- /dev/null +++ b/platformio/builder/main.py @@ -0,0 +1,54 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +from os.path import isdir, join + +from SCons.Script import (DefaultEnvironment, Exit, SConscript, + SConscriptChdir, Variables) + +from platformio.util import get_home_dir, get_project_dir, get_source_dir + + +PIOBUILDER_DIR = join(get_source_dir(), "builder") +# AllowSubstExceptions() + +# define user's variables +clivars = Variables(None) +clivars.AddVariables( + ("PIOENV",), + ("PLATFORM",), + ("BOARD",), + ("UPLOAD_PORT",) +) + +# print sdf + +DefaultEnvironment( + tools=["default", "platformio"], + toolpath=[join(PIOBUILDER_DIR, "tools")], + variables=clivars, + + PROJECT_DIR=get_project_dir(), + + PLATFORMIOHOME_DIR=get_home_dir(), + PLATFORM_DIR=join("$PLATFORMIOHOME_DIR", "${PLATFORM}"), + PLATFORMCORE_DIR=join("$PLATFORM_DIR", "core"), + PLATFORMTOOLS_DIR=join("$PLATFORM_DIR", "tools"), + + BUILD_DIR=join("$PROJECT_DIR", ".pioenvs", "${PIOENV}"), + BUILDCORE_DIR=join("$BUILD_DIR", "core"), + BUILDSRC_DIR=join("$BUILD_DIR", "src") +) + +PLATFORM = DefaultEnvironment().subst("${PLATFORM}") + +if not isdir(DefaultEnvironment().subst("$PLATFORMIOHOME_DIR")): + Exit("You haven't installed any platforms yet. Please use" + "`platformio install` command") +elif not isdir(DefaultEnvironment().subst("$PLATFORM_DIR")): + Exit("An '%s' platform hasn't been installed yet. Please use " + "`platformio install %s` command" % (PLATFORM.upper(), + PLATFORM)) + +SConscriptChdir(0) +SConscript(join(PIOBUILDER_DIR, "scripts", PLATFORM + ".py")) diff --git a/platformio/builder/scripts/__init__.py b/platformio/builder/scripts/__init__.py new file mode 100644 index 00000000..ca6f0304 --- /dev/null +++ b/platformio/builder/scripts/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. diff --git a/platformio/builder/scripts/atmelavr.py b/platformio/builder/scripts/atmelavr.py new file mode 100644 index 00000000..a1185a5c --- /dev/null +++ b/platformio/builder/scripts/atmelavr.py @@ -0,0 +1,190 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +""" + Builder for Atmel AVR series of microcontrollers + + Fully compatible with Arduino programming language (based on Wiring) +""" + +from os.path import join + +from SCons.Script import (AlwaysBuild, Builder, COMMAND_LINE_TARGETS, Default, + DefaultEnvironment, Exit) + +# +# SETUP ENVIRONMENT +# + +env = DefaultEnvironment() + +BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"), + "${BOARD}") +env.Replace( + ARDUINO_VERSION=open(join(env.subst("$PLATFORM_DIR"), + "version.txt")).read().replace(".", "").strip(), + + BOARD_MCU=BOARD_OPTIONS['build.mcu'], + BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'], + BOARD_VID=BOARD_OPTIONS.get("build.vid", "0"), + BOARD_PID=BOARD_OPTIONS.get("build.pid", "0"), + + AR="avr-ar", + AS="avr-as", + CC="avr-gcc", + CXX="avr-g++", + OBJCOPY="avr-objcopy", + RANLIB="avr-ranlib", + + ARFLAGS=["rcs"], + + ASFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-x", "assembler-with-cpp", + "-mmcu=$BOARD_MCU", + "-DF_CPU=$BOARD_F_CPU", + "-DUSB_VID=$BOARD_VID", + "-DUSB_PID=$BOARD_PID", + "-DARDUINO=$ARDUINO_VERSION" + ], + CCFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-Os", # optimize for size + "-Wall", # show warnings + "-fno-exceptions", + "-ffunction-sections", # place each function in its own section + "-fdata-sections", + "-mmcu=$BOARD_MCU", + "-DF_CPU=$BOARD_F_CPU", + "-MMD", # output dependancy info + "-DUSB_VID=$BOARD_VID", + "-DUSB_PID=$BOARD_PID", + "-DARDUINO=$ARDUINO_VERSION" + ], + CFLAGS=["-std=gnu99"], + + LINKFLAGS=[ + "-Os", + "-Wl,--gc-sections" + (",--relax" if BOARD_OPTIONS['build.mcu'] == + "atmega2560" else ""), + "-mmcu=$BOARD_MCU", + "-lm" + ], + + CPPPATH=[ + "$PLATFORMCORE_DIR", + join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant']) + ], + + UPLOADER="avrdude", + UPLOADERFLAGS=[ + "-V", # do not verify + "-q", # suppress progress output + "-D", # disable auto erase for flash memory + "-p", "$BOARD_MCU", + "-C", join("$PLATFORMTOOLS_DIR", "avr", "etc", "avrdude.conf"), + "-c", ("stk500v1" if BOARD_OPTIONS['upload.protocol'] == "stk500" else + BOARD_OPTIONS['upload.protocol']), + "-b", BOARD_OPTIONS['upload.speed'], + "-P", "${UPLOAD_PORT}" + ], + UPLOADHEXCMD="$UPLOADER $UPLOADERFLAGS -U flash:w:$SOURCES:i", + UPLOADEEPCMD="$UPLOADER $UPLOADERFLAGS -U eeprom:w:$SOURCES:i" +) + +env.Append( + BUILDERS=dict( + ElfToEep=Builder( + action=" ".join([ + "$OBJCOPY", + "-O", + "ihex", + "-j", + ".eeprom", + '--set-section-flags=.eeprom="alloc,load"', + "--no-change-warnings", + "--change-section-lma", + ".eeprom=0", + "$SOURCES", + "$TARGET"]), + suffix=".eep" + ), + + ElfToHex=Builder( + action=" ".join([ + "$OBJCOPY", + "-O", + "ihex", + "-R", + ".eeprom", + "$SOURCES", + "$TARGET"]), + suffix=".hex" + ) + ) +) + +env.PrependENVPath( + "PATH", + join(env.subst("$PLATFORMTOOLS_DIR"), "avr", "bin") +) + + +# +# Target: Build Core Library +# + +target_corelib = env.BuildCoreLibrary() + + +# +# Target: Build executable and linkable firmware +# + +target_elf = env.BuildFirmware([target_corelib]) + + +# +# Target: Extract EEPROM data (from EEMEM directive) to .eep file +# + +target_eep = env.ElfToEep(join("$BUILD_DIR", "firmware"), target_elf) + + +# +# Target: Build the .hex file +# + +target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) + + +# +# Target: Upload .eep file +# + +eep = env.Alias("eep", target_eep, [ + lambda target, source, env: env.ResetDevice(), "$UPLOADEEPCMD"]) +AlwaysBuild(eep) + + +# +# Target: Upload .hex file +# + +upload = env.Alias("upload", target_hex, [ + lambda target, source, env: env.ResetDevice(), "$UPLOADHEXCMD"]) +AlwaysBuild(upload) + + +# +# Target: Define targets +# + +env.Alias("build-eep", [target_eep]) +Default([target_corelib, target_elf, target_hex]) + +# check for $UPLOAD_PORT variable +is_uptarget = ("eep" in COMMAND_LINE_TARGETS or "upload" in + COMMAND_LINE_TARGETS) +if is_uptarget and not env.subst("$UPLOAD_PORT"): + Exit("Please specify 'upload_port'") diff --git a/platformio/builder/scripts/timsp430.py b/platformio/builder/scripts/timsp430.py new file mode 100644 index 00000000..3cb8160c --- /dev/null +++ b/platformio/builder/scripts/timsp430.py @@ -0,0 +1,137 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +""" + Builder for Texas Instruments + MSP430 Ultra-Low Power 16-bit microcontrollers + + Fully compatible with Energia programming language (based on Wiring). +""" + +from os.path import join + +from SCons.Script import AlwaysBuild, Builder, Default, DefaultEnvironment + +# +# SETUP ENVIRONMENT +# + +env = DefaultEnvironment() + +BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"), + "${BOARD}") +env.Replace( + # See https://github.com/energia/Energia/blob/master/app/src/ + # processing/app/Base.java#L45 + ARDUINO_VERSION="101", + ENERGIA_VERSION="12", + + BOARD_MCU=BOARD_OPTIONS['build.mcu'], + BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'], + + AR="msp430-ar", + AS="msp430-as", + CC="msp430-gcc", + CXX="msp430-g++", + OBJCOPY="msp430-objcopy", + RANLIB="msp430-ranlib", + + ARFLAGS=["rcs"], + + ASFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-assembler-with-cpp", + "-mmcu=$BOARD_MCU", + "-DF_CPU=$BOARD_F_CPU", + "-DARDUINO=$ARDUINO_VERSION", + "-DENERGIA=$ENERGIA_VERSION" + ], + CCFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-Os", # optimize for size + "-Wall", # show warnings + "-ffunction-sections", # place each function in its own section + "-fdata-sections", + "-mmcu=$BOARD_MCU", + "-DF_CPU=$BOARD_F_CPU", + "-MMD", # output dependancy info + "-DARDUINO=$ARDUINO_VERSION", + "-DENERGIA=$ENERGIA_VERSION" + ], + + LINK="$CC", + LINKFLAGS=[ + "-Os", + "-mmcu=$BOARD_MCU", + "-Wl,-gc-sections,-u,main" + ], + + CPPPATH=[ + "$PLATFORMCORE_DIR", + join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant']) + ], + + UPLOADER=(join("$PLATFORMTOOLS_DIR", "msp430", "mspdebug", "mspdebug")), + UPLOADERFLAGS=[ + BOARD_OPTIONS['upload.protocol'], + "--force-reset" + ], + UPLOADCMD='$UPLOADER $UPLOADERFLAGS "prog $SOURCES"' +) + +env.Append( + BUILDERS=dict( + ElfToHex=Builder( + action=" ".join([ + "$OBJCOPY", + "-O", + "ihex", + "-R", + ".eeprom", + "$SOURCES", + "$TARGET"]), + suffix=".hex" + ) + ) +) + +env.PrependENVPath( + "PATH", + join(env.subst("$PLATFORMTOOLS_DIR"), "msp430", "bin") +) + + +# +# Target: Build Core Library +# + +target_corelib = env.BuildCoreLibrary() + + +# +# Target: Build executable and linkable firmware +# + +target_elf = env.BuildFirmware([target_corelib, "m"]) + + +# +# Target: Build the .hex +# + +target_hex = env.ElfToHex(join("$BUILD_DIR", "firmware"), target_elf) + + +# +# Target: Upload firmware +# + +upload = env.Alias("upload", target_hex, ["$UPLOADCMD"]) +AlwaysBuild(upload) + + +# +# Target: Define targets +# + +Default([target_corelib, target_elf, target_hex]) diff --git a/platformio/builder/scripts/titiva.py b/platformio/builder/scripts/titiva.py new file mode 100644 index 00000000..0e89ea5d --- /dev/null +++ b/platformio/builder/scripts/titiva.py @@ -0,0 +1,152 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +""" + Builder for Texas Instruments + Tiva C Series ARM Cortex-M4 microcontrollers. + + Fully compatible with Energia programming language (based on Wiring). +""" + +from os.path import join + +from SCons.Script import AlwaysBuild, Builder, Default, DefaultEnvironment + +# +# SETUP ENVIRONMENT +# + +env = DefaultEnvironment() + +BOARD_OPTIONS = env.ParseBoardOptions(join("$PLATFORM_DIR", "boards.txt"), + "${BOARD}") +env.Replace( + ARDUINO_VERSION="101", + ENERGIA_VERSION="12", + + BOARD_MCU=BOARD_OPTIONS['build.mcu'], + BOARD_F_CPU=BOARD_OPTIONS['build.f_cpu'], + + AR="arm-none-eabi-ar", + AS="arm-none-eabi-as", + CC="arm-none-eabi-gcc", + CXX="arm-none-eabi-g++", + OBJCOPY="arm-none-eabi-objcopy", + RANLIB="arm-none-eabi-ranlib", + + ARFLAGS=["rcs"], + + ASFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-assembler-with-cpp", + "-Wall", + "-mthumb", + "-mcpu=cortex-m4", + "-mfloat-abi=hard", + "-mfpu=fpv4-sp-d16", + "-fsingle-precision-constant", + "-DF_CPU=$BOARD_F_CPU", + "-DARDUINO=$ARDUINO_VERSION", + "-DENERGIA=$ENERGIA_VERSION" + ], + + CCFLAGS=[ + "-g", # include debugging info (so errors include line numbers) + "-Os", # optimize for size + "-Wall", # show warnings + "-ffunction-sections", # place each function in its own section + "-fdata-sections", + "-Wall", + "-mthumb", + "-mcpu=cortex-m4", + "-mfloat-abi=hard", + "-mfpu=fpv4-sp-d16", + "-fsingle-precision-constant", + "-DF_CPU=$BOARD_F_CPU", + "-MMD", # output dependancy info + "-DARDUINO=$ARDUINO_VERSION", + "-DENERGIA=$ENERGIA_VERSION" + ], + + CXXFLAGS=[ + "-fno-rtti", + "-fno-exceptions" + ], + + LINKFLAGS=[ + "-Os", + "-nostartfiles", + "-nostdlib", + "-Wl,--gc-sections", + "-T", join("$PLATFORMCORE_DIR", BOARD_OPTIONS['ldscript']), + "-Wl,--entry=ResetISR", + "-mthumb", + "-mcpu=cortex-m4", + "-mfloat-abi=hard", + "-mfpu=fpv4-sp-d16", + "-fsingle-precision-constant" + ], + + CPPPATH=[ + "$PLATFORMCORE_DIR", + join("$PLATFORM_DIR", "variants", BOARD_OPTIONS['build.variant']) + ], + + UPLOADER="lm4flash", + UPLOADCMD="$UPLOADER $SOURCES" +) + +env.Append( + BUILDERS=dict( + ElfToBin=Builder( + action=" ".join([ + "$OBJCOPY", + "-O", + "binary", + "$SOURCES", + "$TARGET"]), + suffix=".hex" + ) + ) +) + +env.PrependENVPath( + "PATH", + join(env.subst("$PLATFORMTOOLS_DIR"), "lm4f", "bin") +) + + +# +# Target: Build Core Library +# + +target_corelib = env.BuildCoreLibrary() + + +# +# Target: Build executable and linkable firmware +# + +target_elf = env.BuildFirmware([target_corelib, "c", "gcc", "m"]) + + +# +# Target: Build the .bin file +# + +target_bin = env.ElfToBin(join("$BUILD_DIR", "firmware"), target_elf) + + +# +# Target: Upload firmware +# + +upload = env.Alias("upload", target_bin, ["$UPLOADCMD"]) +AlwaysBuild(upload) + + +# +# Target: Define targets +# + +Default([target_corelib, target_elf, target_bin]) diff --git a/platformio/builder/tools/__init__.py b/platformio/builder/tools/__init__.py new file mode 100644 index 00000000..ca6f0304 --- /dev/null +++ b/platformio/builder/tools/__init__.py @@ -0,0 +1,2 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. diff --git a/platformio/builder/tools/platformio.py b/platformio/builder/tools/platformio.py new file mode 100644 index 00000000..f76abe65 --- /dev/null +++ b/platformio/builder/tools/platformio.py @@ -0,0 +1,98 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +from os import walk +from os.path import isfile, join +from time import sleep + +from serial import Serial + + +def BuildCoreLibrary(env): + corelib = env.Clone() + vdirs = corelib.VariantDirRecursive("$BUILDCORE_DIR", "$PLATFORMCORE_DIR") + return corelib.Library( + corelib.subst("$BUILDCORE_DIR"), + [corelib.GlobCXXFiles(vdir) for vdir in vdirs] + ) + + +def BuildFirmware(env, liblist): + src = env.Clone() + vdirs = src.VariantDirRecursive("$BUILDSRC_DIR", + join("$PROJECT_DIR", "src")) + return src.Program( + join("$BUILD_DIR", "firmware"), + [src.GlobCXXFiles(vdir) for vdir in vdirs], + LIBS=liblist, + LIBPATH="$BUILD_DIR", + PROGSUFFIX=".elf") + + +def GlobCXXFiles(env, path): + files = [] + for suff in ["*.c", "*.cpp", "*.S"]: + _list = env.Glob(join(path, suff)) + if _list: + files += _list + return files + + +def VariantDirRecursive(env, variant_dir, src_dir, duplicate=True): + # add root dir by default + variants = [variant_dir] + env.VariantDir(variant_dir, src_dir, duplicate) + for root, dirnames, filenames in walk(env.subst(src_dir)): + if not dirnames: + continue + for dn in dirnames: + env.VariantDir(join(variant_dir, dn), join(root, dn), duplicate) + variants.append(join(variant_dir, dn)) + return variants + + +def ParseBoardOptions(env, path, name): + path = env.subst(path) + name = env.subst(name) + if not isfile(path): + env.Exit("Invalid path to boards.txt -> %s" % path) + + data = {} + _namelen = len(name) + 1 + with open(path) as f: + for line in f: + if line[0:_namelen] != name + ".": + continue + line = line[_namelen:].strip() + opt, value = line.split("=", 1) + data[opt] = value + if not data: + env.Exit("Unknown Board '%s'" % name) + else: + return data + + +def ResetDevice(env): + """ Pulse the DTR line and flush serial buffer """ + s = Serial(env.subst("$UPLOAD_PORT")) + s.flushInput() + s.setDTR(False) + s.setRTS(False) + sleep(0.1) + s.setDTR(True) + s.setRTS(True) + s.close() + + +def exists(env): + return True + + +def generate(env): + env.AddMethod(BuildCoreLibrary) + env.AddMethod(BuildFirmware) + env.AddMethod(GlobCXXFiles) + env.AddMethod(VariantDirRecursive) + env.AddMethod(ParseBoardOptions) + env.AddMethod(ResetDevice) + return env diff --git a/platformio/util.py b/platformio/util.py new file mode 100644 index 00000000..8c20409f --- /dev/null +++ b/platformio/util.py @@ -0,0 +1,67 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +from sys import exit +from os import getcwd +from os.path import dirname, expanduser, join, realpath, isfile +from subprocess import Popen, PIPE + +try: + from configparser import ConfigParser +except ImportError: + from ConfigParser import ConfigParser + + +def get_home_dir(): + return expanduser("~/.platformio") + + +def get_source_dir(): + return dirname(realpath(__file__)) + + +def get_project_dir(): + return getcwd() + + +def get_project_config(): + try: + return getattr(get_project_config, "_cache") + except AttributeError: + pass + + path = join(get_project_dir(), "platformio.ini") + if not isfile(path): + exit("Not a platformio project. Use `platformio init` command") + + get_project_config._cache = ConfigParser() + get_project_config._cache.read(path) + return get_project_config._cache + + +def exec_command(args): + p = Popen(args, stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + result = dict(out=out.strip(), err=err.strip()) + + # fix STDERR "flash written" + if "flash written" in result['err']: + result['out'] += "\n" + result['err'] + result['err'] = "" + + return result + + +def run_builder(variables, targets): + assert isinstance(variables, list) + assert isinstance(targets, list) + + if "clean" in targets: + targets.remove("clean") + targets.append("-c") + + return exec_command([ + "scons", + "-Q", + "-f", join(get_source_dir(), "builder", "main.py") + ] + variables + targets) diff --git a/setup.py b/setup.py new file mode 100644 index 00000000..2949bace --- /dev/null +++ b/setup.py @@ -0,0 +1,42 @@ +# Copyright (C) Ivan Kravets +# See LICENSE for details. + +from setuptools import find_packages, setup + +from platformio import (__author__, __description__, __email__, __license__, + __title__, __url__, __version__) + +setup( + name=__title__, + version=__version__, + description=__description__, + long_description=open("README.rst").read(), + author=__author__, + author_email=__email__, + url=__url__, + license=__license__, + install_requires=[ + "click", + "clint", + "pyserial" + "SCons" + ], + packages=find_packages(), + entry_points={ + "console_scripts": [ + "platformio = platformio.__main__:main" + ] + }, + classifiers=[ + "Development Status :: 2 - Pre-Alpha", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: C", + "Programming Language :: Python", + "Topic :: Software Development", + "Topic :: Software Development :: Build Tools", + "Topic :: Software Development :: Compilers" + ] +) diff --git a/tox.ini b/tox.ini new file mode 100644 index 00000000..75505322 --- /dev/null +++ b/tox.ini @@ -0,0 +1,22 @@ +[tox] +envlist = develop, lint + +[testenv] +envlogdir = /tmp/toxlogdir +envtmpdir = /tmp/toxtmpdir +commands = + {envpython} --version + +[testenv:develop] +usedevelop = True +deps = + isort + flake8 + +[testenv:lint] +deps = + flake8 + pylint +commands = + flake8 ./platformio + pylint --rcfile=./.pylintrc ./platformio