mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 18:17:13 +02:00
Merge branch 'release/v3.5.1'
This commit is contained in:
@ -1,3 +1,3 @@
|
|||||||
[settings]
|
[settings]
|
||||||
line_length=79
|
line_length=79
|
||||||
known_third_party=arrow,bottle,click,lockfile,pytest,requests,SCons,semantic_version,serial
|
known_third_party=bottle,click,lockfile,python-dateutil,pytest,requests,SCons,semantic_version,serial
|
||||||
|
24
HISTORY.rst
24
HISTORY.rst
@ -4,6 +4,28 @@ Release Notes
|
|||||||
PlatformIO 3.0
|
PlatformIO 3.0
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
3.5.1 (2018-01-18)
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* New ``test_speed`` option to control a communication baudrate/speed between
|
||||||
|
`PIO Unit Testing <http://docs.platformio.org/page/plus/unit-testing.html>`__
|
||||||
|
engine and a target device
|
||||||
|
(`issue #1273 <https://github.com/platformio/platformio-core/issues/1273>`_)
|
||||||
|
* Show full library version in "Library Dependency Graph" including VCS
|
||||||
|
information
|
||||||
|
(`issue #1274 <https://github.com/platformio/platformio-core/issues/1274>`_)
|
||||||
|
* Configure a custom firmware/program name in build directory (`example <http://docs.platformio.org/page/projectconf/advanced_scripting.html#custom-firmware-program-name>`__)
|
||||||
|
* Renamed ``envs_dir`` option to ``build_dir``
|
||||||
|
in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf/section_platformio.html#build-dir>`__
|
||||||
|
* Refactored code without "arrow" dependency (resolve issue with "ImportError:
|
||||||
|
No module named backports.functools_lru_cache")
|
||||||
|
* Improved support of PIO Unified Debugger for Eclipse Oxygen
|
||||||
|
* Improved a work in off-line mode
|
||||||
|
* Fixed project generator for CLion and Qt Creator IDE
|
||||||
|
(`issue #1299 <https://github.com/platformio/platformio-core/issues/1299>`_)
|
||||||
|
* Fixed PIO Unified Debugger for mbed framework
|
||||||
|
* Fixed library updates when a version is declared in VCS format (not SemVer)
|
||||||
|
|
||||||
3.5.0 (2017-12-28)
|
3.5.0 (2017-12-28)
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -28,7 +50,7 @@ PlatformIO 3.0
|
|||||||
* New `include <http://docs.platformio.org/page/projectconf/section_platformio.html#include-dir>`__
|
* New `include <http://docs.platformio.org/page/projectconf/section_platformio.html#include-dir>`__
|
||||||
folder for project's header files
|
folder for project's header files
|
||||||
(`issue #1107 <https://github.com/platformio/platformio-core/issues/1107>`_)
|
(`issue #1107 <https://github.com/platformio/platformio-core/issues/1107>`_)
|
||||||
* Depend on development platform using VSC URL (Git, Mercurial and Subversion)
|
* Depend on development platform using VCS URL (Git, Mercurial and Subversion)
|
||||||
instead of a name in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf/section_env_general.html#platform>`__.
|
instead of a name in `Project Configuration File "platformio.ini" <http://docs.platformio.org/page/projectconf/section_env_general.html#platform>`__.
|
||||||
Drop support for ``*_stage`` dev/platform names (use VCS URL instead).
|
Drop support for ``*_stage`` dev/platform names (use VCS URL instead).
|
||||||
* Reinstall/redownload package with a new ``-f, --force`` option for
|
* Reinstall/redownload package with a new ``-f, --force`` option for
|
||||||
|
2
Makefile
2
Makefile
@ -10,7 +10,7 @@ yapf:
|
|||||||
yapf --recursive --in-place platformio/
|
yapf --recursive --in-place platformio/
|
||||||
|
|
||||||
test:
|
test:
|
||||||
py.test -v -s tests --ignore tests/test_examples.py --ignore tests/test_pkgmanifest.py
|
py.test -v -s -n 3 --dist=loadscope tests --ignore tests/test_examples.py --ignore tests/test_pkgmanifest.py
|
||||||
|
|
||||||
before-commit: isort yapf lint test
|
before-commit: isort yapf lint test
|
||||||
|
|
||||||
|
2
docs
2
docs
Submodule docs updated: c76ccaf337...2e04299a17
2
examples
2
examples
Submodule examples updated: 2d716306f3...2d08187562
@ -14,14 +14,16 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
VERSION = (3, 5, 0)
|
VERSION = (3, 5, 1)
|
||||||
__version__ = ".".join([str(s) for s in VERSION])
|
__version__ = ".".join([str(s) for s in VERSION])
|
||||||
|
|
||||||
__title__ = "platformio"
|
__title__ = "platformio"
|
||||||
__description__ = ("An open source ecosystem for IoT development. "
|
__description__ = (
|
||||||
"Cross-platform build system and library manager. "
|
"An open source ecosystem for IoT development. "
|
||||||
"Continuous and IDE integration. "
|
"Cross-platform IDE and unified debugger. "
|
||||||
"Arduino, ESP8266 and ARM mbed compatible")
|
"Remote unit testing and firmware updates. "
|
||||||
|
"Arduino, ARM mbed, Espressif (ESP8266/ESP32), STM32, PIC32, nRF51/nRF52, "
|
||||||
|
"FPGA, CMSIS, SPL, AVR, Samsung ARTIK, libOpenCM3")
|
||||||
__url__ = "http://platformio.org"
|
__url__ = "http://platformio.org"
|
||||||
|
|
||||||
__author__ = "Ivan Kravets"
|
__author__ = "Ivan Kravets"
|
||||||
@ -36,5 +38,5 @@ if sys.version_info < (2, 7, 0) or sys.version_info >= (3, 0, 0):
|
|||||||
msg = ("PlatformIO Core v%s does not run under Python version %s.\n"
|
msg = ("PlatformIO Core v%s does not run under Python version %s.\n"
|
||||||
"Minimum supported version is 2.7, please upgrade Python.\n"
|
"Minimum supported version is 2.7, please upgrade Python.\n"
|
||||||
"Python 3 is not yet supported.\n")
|
"Python 3 is not yet supported.\n")
|
||||||
sys.stderr.write(msg % (__version__, sys.version.split()[0]))
|
sys.stderr.write(msg % (__version__, sys.version))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -91,8 +91,8 @@ DEFAULT_ENV_OPTIONS = dict(
|
|||||||
PROJECTSRC_DIR=util.get_projectsrc_dir(),
|
PROJECTSRC_DIR=util.get_projectsrc_dir(),
|
||||||
PROJECTTEST_DIR=util.get_projecttest_dir(),
|
PROJECTTEST_DIR=util.get_projecttest_dir(),
|
||||||
PROJECTDATA_DIR=util.get_projectdata_dir(),
|
PROJECTDATA_DIR=util.get_projectdata_dir(),
|
||||||
PROJECTPIOENVS_DIR=util.get_projectpioenvs_dir(),
|
PROJECTBUILD_DIR=util.get_projectbuild_dir(),
|
||||||
BUILD_DIR=join("$PROJECTPIOENVS_DIR", "$PIOENV"),
|
BUILD_DIR=join("$PROJECTBUILD_DIR", "$PIOENV"),
|
||||||
BUILDSRC_DIR=join("$BUILD_DIR", "src"),
|
BUILDSRC_DIR=join("$BUILD_DIR", "src"),
|
||||||
BUILDTEST_DIR=join("$BUILD_DIR", "test"),
|
BUILDTEST_DIR=join("$BUILD_DIR", "test"),
|
||||||
LIBSOURCE_DIRS=[
|
LIBSOURCE_DIRS=[
|
||||||
@ -150,7 +150,7 @@ env['LIBSOURCE_DIRS'] = [
|
|||||||
env.LoadPioPlatform(commonvars)
|
env.LoadPioPlatform(commonvars)
|
||||||
|
|
||||||
env.SConscriptChdir(0)
|
env.SConscriptChdir(0)
|
||||||
env.SConsignFile(join("$PROJECTPIOENVS_DIR", ".sconsign.dblite"))
|
env.SConsignFile(join("$PROJECTBUILD_DIR", ".sconsign.dblite"))
|
||||||
|
|
||||||
for item in env.GetPreExtraScripts():
|
for item in env.GetPreExtraScripts():
|
||||||
env.SConscript(item, exports="env")
|
env.SConscript(item, exports="env")
|
||||||
|
@ -20,6 +20,7 @@ from __future__ import absolute_import
|
|||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from glob import glob
|
||||||
from os.path import (basename, commonprefix, dirname, isdir, isfile, join,
|
from os.path import (basename, commonprefix, dirname, isdir, isfile, join,
|
||||||
realpath, sep)
|
realpath, sep)
|
||||||
from platform import system
|
from platform import system
|
||||||
@ -30,6 +31,7 @@ from SCons.Script import ARGUMENTS, COMMAND_LINE_TARGETS, DefaultEnvironment
|
|||||||
from platformio import util
|
from platformio import util
|
||||||
from platformio.builder.tools import platformio as piotool
|
from platformio.builder.tools import platformio as piotool
|
||||||
from platformio.managers.lib import LibraryManager
|
from platformio.managers.lib import LibraryManager
|
||||||
|
from platformio.managers.package import PackageManager
|
||||||
|
|
||||||
|
|
||||||
class LibBuilderFactory(object):
|
class LibBuilderFactory(object):
|
||||||
@ -131,6 +133,13 @@ class LibBuilderBase(object):
|
|||||||
def version(self):
|
def version(self):
|
||||||
return self._manifest.get("version")
|
return self._manifest.get("version")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def vcs_info(self):
|
||||||
|
items = glob(join(self.path, ".*", PackageManager.SRC_MANIFEST_NAME))
|
||||||
|
if not items:
|
||||||
|
return None
|
||||||
|
return util.load_json(items[0])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dependencies(self):
|
def dependencies(self):
|
||||||
return LibraryManager.normalize_dependencies(
|
return LibraryManager.normalize_dependencies(
|
||||||
@ -228,19 +237,6 @@ class LibBuilderBase(object):
|
|||||||
except (AssertionError, ValueError):
|
except (AssertionError, ValueError):
|
||||||
return LibBuilderBase.COMPAT_MODE_DEFAULT
|
return LibBuilderBase.COMPAT_MODE_DEFAULT
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def items_to_list(items):
|
|
||||||
if not isinstance(items, list):
|
|
||||||
items = [i.strip() for i in items.split(",")]
|
|
||||||
return [i.lower() for i in items if i]
|
|
||||||
|
|
||||||
def items_in_list(self, items, ilist):
|
|
||||||
items = self.items_to_list(items)
|
|
||||||
ilist = self.items_to_list(ilist)
|
|
||||||
if "*" in items or "*" in ilist:
|
|
||||||
return True
|
|
||||||
return set(items) & set(ilist)
|
|
||||||
|
|
||||||
def is_platforms_compatible(self, platforms):
|
def is_platforms_compatible(self, platforms):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -273,7 +269,7 @@ class LibBuilderBase(object):
|
|||||||
if env_key not in self.env:
|
if env_key not in self.env:
|
||||||
continue
|
continue
|
||||||
if (key in item and
|
if (key in item and
|
||||||
not self.items_in_list(self.env[env_key], item[key])):
|
not util.items_in_list(self.env[env_key], item[key])):
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
"Skip %s incompatible dependency %s\n" % (key[:-1],
|
"Skip %s incompatible dependency %s\n" % (key[:-1],
|
||||||
@ -304,9 +300,8 @@ class LibBuilderBase(object):
|
|||||||
|
|
||||||
def get_search_files(self):
|
def get_search_files(self):
|
||||||
items = [
|
items = [
|
||||||
join(self.src_dir, item)
|
join(self.src_dir, item) for item in self.env.MatchSourceFiles(
|
||||||
for item in self.env.MatchSourceFiles(self.src_dir,
|
self.src_dir, self.src_filter)
|
||||||
self.src_filter)
|
|
||||||
]
|
]
|
||||||
include_dir = self.include_dir
|
include_dir = self.include_dir
|
||||||
if include_dir:
|
if include_dir:
|
||||||
@ -496,7 +491,7 @@ class ArduinoLibBuilder(LibBuilderBase):
|
|||||||
return src_filter
|
return src_filter
|
||||||
|
|
||||||
def is_frameworks_compatible(self, frameworks):
|
def is_frameworks_compatible(self, frameworks):
|
||||||
return self.items_in_list(frameworks, ["arduino", "energia"])
|
return util.items_in_list(frameworks, ["arduino", "energia"])
|
||||||
|
|
||||||
|
|
||||||
class MbedLibBuilder(LibBuilderBase):
|
class MbedLibBuilder(LibBuilderBase):
|
||||||
@ -527,7 +522,7 @@ class MbedLibBuilder(LibBuilderBase):
|
|||||||
return include_dirs
|
return include_dirs
|
||||||
|
|
||||||
def is_frameworks_compatible(self, frameworks):
|
def is_frameworks_compatible(self, frameworks):
|
||||||
return self.items_in_list(frameworks, ["mbed"])
|
return util.items_in_list(frameworks, ["mbed"])
|
||||||
|
|
||||||
|
|
||||||
class PlatformIOLibBuilder(LibBuilderBase):
|
class PlatformIOLibBuilder(LibBuilderBase):
|
||||||
@ -541,7 +536,7 @@ class PlatformIOLibBuilder(LibBuilderBase):
|
|||||||
if "platforms" in manifest:
|
if "platforms" in manifest:
|
||||||
manifest['platforms'] = [
|
manifest['platforms'] = [
|
||||||
"espressif8266" if p == "espressif" else p
|
"espressif8266" if p == "espressif" else p
|
||||||
for p in self.items_to_list(manifest['platforms'])
|
for p in util.items_to_list(manifest['platforms'])
|
||||||
]
|
]
|
||||||
|
|
||||||
return manifest
|
return manifest
|
||||||
@ -610,13 +605,13 @@ class PlatformIOLibBuilder(LibBuilderBase):
|
|||||||
items = self._manifest.get("platforms")
|
items = self._manifest.get("platforms")
|
||||||
if not items:
|
if not items:
|
||||||
return LibBuilderBase.is_platforms_compatible(self, platforms)
|
return LibBuilderBase.is_platforms_compatible(self, platforms)
|
||||||
return self.items_in_list(platforms, items)
|
return util.items_in_list(platforms, items)
|
||||||
|
|
||||||
def is_frameworks_compatible(self, frameworks):
|
def is_frameworks_compatible(self, frameworks):
|
||||||
items = self._manifest.get("frameworks")
|
items = self._manifest.get("frameworks")
|
||||||
if not items:
|
if not items:
|
||||||
return LibBuilderBase.is_frameworks_compatible(self, frameworks)
|
return LibBuilderBase.is_frameworks_compatible(self, frameworks)
|
||||||
return self.items_in_list(frameworks, items)
|
return util.items_in_list(frameworks, items)
|
||||||
|
|
||||||
def get_include_dirs(self):
|
def get_include_dirs(self):
|
||||||
include_dirs = LibBuilderBase.get_include_dirs(self)
|
include_dirs = LibBuilderBase.get_include_dirs(self)
|
||||||
@ -646,7 +641,9 @@ class ProjectAsLibBuilder(LibBuilderBase):
|
|||||||
|
|
||||||
def get_include_dirs(self):
|
def get_include_dirs(self):
|
||||||
include_dirs = LibBuilderBase.get_include_dirs(self)
|
include_dirs = LibBuilderBase.get_include_dirs(self)
|
||||||
include_dirs.append(self.env.subst("$PROJECTINCLUDE_DIR"))
|
project_include_dir = self.env.subst("$PROJECTINCLUDE_DIR")
|
||||||
|
if isdir(project_include_dir):
|
||||||
|
include_dirs.append(project_include_dir)
|
||||||
return include_dirs
|
return include_dirs
|
||||||
|
|
||||||
def get_search_files(self):
|
def get_search_files(self):
|
||||||
@ -655,9 +652,9 @@ class ProjectAsLibBuilder(LibBuilderBase):
|
|||||||
# test files
|
# test files
|
||||||
if "__test" in COMMAND_LINE_TARGETS:
|
if "__test" in COMMAND_LINE_TARGETS:
|
||||||
items.extend([
|
items.extend([
|
||||||
join("$PROJECTTEST_DIR", item)
|
join("$PROJECTTEST_DIR",
|
||||||
for item in self.env.MatchSourceFiles("$PROJECTTEST_DIR",
|
item) for item in self.env.MatchSourceFiles(
|
||||||
"$PIOTEST_SRC_FILTER")
|
"$PROJECTTEST_DIR", "$PIOTEST_SRC_FILTER")
|
||||||
])
|
])
|
||||||
return items
|
return items
|
||||||
|
|
||||||
@ -803,10 +800,15 @@ def BuildProjectLibraries(env):
|
|||||||
margin = "| " * (level)
|
margin = "| " * (level)
|
||||||
for lb in root.depbuilders:
|
for lb in root.depbuilders:
|
||||||
title = "<%s>" % lb.name
|
title = "<%s>" % lb.name
|
||||||
|
vcs_info = lb.vcs_info
|
||||||
if lb.version:
|
if lb.version:
|
||||||
title += " v%s" % lb.version
|
title += " v%s" % lb.version
|
||||||
|
if vcs_info:
|
||||||
|
title += " #%s" % vcs_info.get("version")
|
||||||
sys.stdout.write("%s|-- %s" % (margin, title))
|
sys.stdout.write("%s|-- %s" % (margin, title))
|
||||||
if int(ARGUMENTS.get("PIOVERBOSE", 0)):
|
if int(ARGUMENTS.get("PIOVERBOSE", 0)):
|
||||||
|
if vcs_info:
|
||||||
|
sys.stdout.write(" [%s]" % vcs_info.get("url"))
|
||||||
sys.stdout.write(" (")
|
sys.stdout.write(" (")
|
||||||
sys.stdout.write(lb.path)
|
sys.stdout.write(lb.path)
|
||||||
sys.stdout.write(")")
|
sys.stdout.write(")")
|
||||||
@ -815,7 +817,7 @@ def BuildProjectLibraries(env):
|
|||||||
print_deps_tree(lb, level + 1)
|
print_deps_tree(lb, level + 1)
|
||||||
|
|
||||||
print "Collected %d compatible libraries" % len(lib_builders)
|
print "Collected %d compatible libraries" % len(lib_builders)
|
||||||
print "Looking for dependencies..."
|
print "Scanning dependencies..."
|
||||||
|
|
||||||
project = ProjectAsLibBuilder(env, "$PROJECT_DIR")
|
project = ProjectAsLibBuilder(env, "$PROJECT_DIR")
|
||||||
project.env = env
|
project.env = env
|
||||||
|
@ -46,6 +46,9 @@ def BuildProgram(env):
|
|||||||
if not case_sensitive_suffixes(".s", ".S"):
|
if not case_sensitive_suffixes(".s", ".S"):
|
||||||
env.Replace(AS="$CC", ASCOM="$ASPPCOM")
|
env.Replace(AS="$CC", ASCOM="$ASPPCOM")
|
||||||
|
|
||||||
|
if "__debug" in COMMAND_LINE_TARGETS:
|
||||||
|
env.ProcessDebug()
|
||||||
|
|
||||||
# process extra flags from board
|
# process extra flags from board
|
||||||
if "BOARD" in env and "build.extra_flags" in env.BoardConfig():
|
if "BOARD" in env and "build.extra_flags" in env.BoardConfig():
|
||||||
env.ProcessFlags(env.BoardConfig().get("build.extra_flags"))
|
env.ProcessFlags(env.BoardConfig().get("build.extra_flags"))
|
||||||
@ -60,18 +63,6 @@ def BuildProgram(env):
|
|||||||
# restore PIO macros if it was deleted by framework
|
# restore PIO macros if it was deleted by framework
|
||||||
_append_pio_macros()
|
_append_pio_macros()
|
||||||
|
|
||||||
# Search for project source files
|
|
||||||
env.Append(
|
|
||||||
LIBPATH=["$BUILD_DIR"],
|
|
||||||
PIOBUILDFILES=env.CollectBuildFiles(
|
|
||||||
"$BUILDSRC_DIR", "$PROJECTSRC_DIR", "$SRC_FILTER",
|
|
||||||
duplicate=False))
|
|
||||||
|
|
||||||
if "__debug" in COMMAND_LINE_TARGETS:
|
|
||||||
env.ProcessDebug()
|
|
||||||
if "__test" in COMMAND_LINE_TARGETS:
|
|
||||||
env.Append(PIOBUILDFILES=env.ProcessTest())
|
|
||||||
|
|
||||||
# build dependent libs
|
# build dependent libs
|
||||||
env.Append(LIBS=env.BuildProjectLibraries())
|
env.Append(LIBS=env.BuildProjectLibraries())
|
||||||
|
|
||||||
@ -88,7 +79,18 @@ def BuildProgram(env):
|
|||||||
# Handle SRC_BUILD_FLAGS
|
# Handle SRC_BUILD_FLAGS
|
||||||
env.ProcessFlags(env.get("SRC_BUILD_FLAGS"))
|
env.ProcessFlags(env.get("SRC_BUILD_FLAGS"))
|
||||||
|
|
||||||
if not env.get("PIOBUILDFILES") and not COMMAND_LINE_TARGETS:
|
env.Append(
|
||||||
|
LIBPATH=["$BUILD_DIR"],
|
||||||
|
PIOBUILDFILES=env.CollectBuildFiles(
|
||||||
|
"$BUILDSRC_DIR",
|
||||||
|
"$PROJECTSRC_DIR",
|
||||||
|
src_filter=env.get("SRC_FILTER"),
|
||||||
|
duplicate=False))
|
||||||
|
|
||||||
|
if "__test" in COMMAND_LINE_TARGETS:
|
||||||
|
env.Append(PIOBUILDFILES=env.ProcessTest())
|
||||||
|
|
||||||
|
if not env['PIOBUILDFILES'] and not COMMAND_LINE_TARGETS:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
"Error: Nothing to build. Please put your source code files "
|
"Error: Nothing to build. Please put your source code files "
|
||||||
"to '%s' folder\n" % env.subst("$PROJECTSRC_DIR"))
|
"to '%s' folder\n" % env.subst("$PROJECTSRC_DIR"))
|
||||||
|
@ -15,16 +15,14 @@
|
|||||||
# pylint: disable=too-many-branches, too-many-locals
|
# pylint: disable=too-many-branches, too-many-locals
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import time
|
||||||
from os.path import isdir, join
|
from os.path import isdir, join
|
||||||
from time import sleep
|
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
|
|
||||||
import arrow
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from platformio import exception, util
|
from platformio import exception, util
|
||||||
from platformio.managers.lib import LibraryManager
|
from platformio.managers.lib import LibraryManager, get_builtin_libs
|
||||||
from platformio.managers.platform import PlatformFactory, PlatformManager
|
|
||||||
from platformio.util import get_api_result
|
from platformio.util import get_api_result
|
||||||
|
|
||||||
|
|
||||||
@ -99,7 +97,7 @@ def cli(ctx, **options):
|
|||||||
help="Reinstall/redownload library if exists")
|
help="Reinstall/redownload library if exists")
|
||||||
@click.pass_obj
|
@click.pass_obj
|
||||||
def lib_install(lm, libraries, silent, interactive, force):
|
def lib_install(lm, libraries, silent, interactive, force):
|
||||||
# @TODO "save" option
|
# @TODO: "save" option
|
||||||
for library in libraries:
|
for library in libraries:
|
||||||
lm.install(
|
lm.install(
|
||||||
library, silent=silent, interactive=interactive, force=force)
|
library, silent=silent, interactive=interactive, force=force)
|
||||||
@ -252,7 +250,7 @@ def lib_search(query, json_output, page, noninteractive, **filters):
|
|||||||
result['perpage'],
|
result['perpage'],
|
||||||
fg="yellow")
|
fg="yellow")
|
||||||
click.echo()
|
click.echo()
|
||||||
sleep(5)
|
time.sleep(5)
|
||||||
elif not click.confirm("Show next libraries?"):
|
elif not click.confirm("Show next libraries?"):
|
||||||
break
|
break
|
||||||
result = get_api_result(
|
result = get_api_result(
|
||||||
@ -280,25 +278,6 @@ def lib_list(lm, json_output):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@util.memoized
|
|
||||||
def get_builtin_libs(storage_names=None):
|
|
||||||
items = []
|
|
||||||
storage_names = storage_names or []
|
|
||||||
pm = PlatformManager()
|
|
||||||
for manifest in pm.get_installed():
|
|
||||||
p = PlatformFactory.newPlatform(manifest['__pkg_dir'])
|
|
||||||
for storage in p.get_lib_storages():
|
|
||||||
if storage_names and storage['name'] not in storage_names:
|
|
||||||
continue
|
|
||||||
lm = LibraryManager(storage['path'])
|
|
||||||
items.append({
|
|
||||||
"name": storage['name'],
|
|
||||||
"path": storage['path'],
|
|
||||||
"items": lm.get_installed()
|
|
||||||
})
|
|
||||||
return items
|
|
||||||
|
|
||||||
|
|
||||||
@cli.command("builtin", short_help="List built-in libraries")
|
@cli.command("builtin", short_help="List built-in libraries")
|
||||||
@click.option("--storage", multiple=True)
|
@click.option("--storage", multiple=True)
|
||||||
@click.option("--json-output", is_flag=True)
|
@click.option("--json-output", is_flag=True)
|
||||||
@ -326,8 +305,13 @@ def lib_builtin(storage, json_output):
|
|||||||
def lib_show(library, json_output):
|
def lib_show(library, json_output):
|
||||||
lm = LibraryManager()
|
lm = LibraryManager()
|
||||||
name, requirements, _ = lm.parse_pkg_uri(library)
|
name, requirements, _ = lm.parse_pkg_uri(library)
|
||||||
lib_id = lm.get_pkg_id_by_name(
|
lib_id = lm.search_lib_id(
|
||||||
name, requirements, silent=json_output, interactive=not json_output)
|
{
|
||||||
|
"name": name,
|
||||||
|
"requirements": requirements
|
||||||
|
},
|
||||||
|
silent=json_output,
|
||||||
|
interactive=not json_output)
|
||||||
lib = get_api_result("/lib/info/%d" % lib_id, cache_valid="1d")
|
lib = get_api_result("/lib/info/%d" % lib_id, cache_valid="1d")
|
||||||
if json_output:
|
if json_output:
|
||||||
return click.echo(json.dumps(lib))
|
return click.echo(json.dumps(lib))
|
||||||
@ -338,9 +322,10 @@ def lib_show(library, json_output):
|
|||||||
click.echo(lib['description'])
|
click.echo(lib['description'])
|
||||||
click.echo()
|
click.echo()
|
||||||
|
|
||||||
click.echo("Version: %s, released %s" %
|
click.echo(
|
||||||
(lib['version']['name'],
|
"Version: %s, released %s" %
|
||||||
arrow.get(lib['version']['released']).humanize()))
|
(lib['version']['name'],
|
||||||
|
time.strftime("%c", util.parse_date(lib['version']['released']))))
|
||||||
click.echo("Manifest: %s" % lib['confurl'])
|
click.echo("Manifest: %s" % lib['confurl'])
|
||||||
for key in ("homepage", "repository", "license"):
|
for key in ("homepage", "repository", "license"):
|
||||||
if key not in lib or not lib[key]:
|
if key not in lib or not lib[key]:
|
||||||
@ -376,7 +361,8 @@ def lib_show(library, json_output):
|
|||||||
blocks.append(("Headers", lib['headers']))
|
blocks.append(("Headers", lib['headers']))
|
||||||
blocks.append(("Examples", lib['examples']))
|
blocks.append(("Examples", lib['examples']))
|
||||||
blocks.append(("Versions", [
|
blocks.append(("Versions", [
|
||||||
"%s, released %s" % (v['name'], arrow.get(v['released']).humanize())
|
"%s, released %s" %
|
||||||
|
(v['name'], time.strftime("%c", util.parse_date(v['released'])))
|
||||||
for v in lib['versions']
|
for v in lib['versions']
|
||||||
]))
|
]))
|
||||||
blocks.append(("Unique Downloads", [
|
blocks.append(("Unique Downloads", [
|
||||||
@ -439,7 +425,7 @@ def lib_stats(json_output):
|
|||||||
if "date" in item else printitem_tpl).format(
|
if "date" in item else printitem_tpl).format(
|
||||||
name=click.style(item['name'], fg="cyan"),
|
name=click.style(item['name'], fg="cyan"),
|
||||||
date=str(
|
date=str(
|
||||||
arrow.get(item['date']).humanize()
|
time.strftime("%c", util.parse_date(item['date']))
|
||||||
if "date" in item else ""),
|
if "date" in item else ""),
|
||||||
url=click.style(
|
url=click.style(
|
||||||
"http://platformio.org/lib/show/%s/%s" %
|
"http://platformio.org/lib/show/%s/%s" %
|
||||||
|
@ -23,10 +23,9 @@ import click
|
|||||||
from platformio import __version__, exception, telemetry, util
|
from platformio import __version__, exception, telemetry, util
|
||||||
from platformio.commands.device import device_monitor as cmd_device_monitor
|
from platformio.commands.device import device_monitor as cmd_device_monitor
|
||||||
from platformio.commands.lib import lib_install as cmd_lib_install
|
from platformio.commands.lib import lib_install as cmd_lib_install
|
||||||
from platformio.commands.lib import get_builtin_libs
|
|
||||||
from platformio.commands.platform import \
|
from platformio.commands.platform import \
|
||||||
platform_install as cmd_platform_install
|
platform_install as cmd_platform_install
|
||||||
from platformio.managers.lib import LibraryManager
|
from platformio.managers.lib import LibraryManager, is_builtin_lib
|
||||||
from platformio.managers.platform import PlatformFactory
|
from platformio.managers.platform import PlatformFactory
|
||||||
|
|
||||||
# pylint: disable=too-many-arguments,too-many-locals,too-many-branches
|
# pylint: disable=too-many-arguments,too-many-locals,too-many-branches
|
||||||
@ -60,15 +59,15 @@ def cli(ctx, environment, target, upload_port, project_dir, silent, verbose,
|
|||||||
raise exception.NotPlatformIOProject(project_dir)
|
raise exception.NotPlatformIOProject(project_dir)
|
||||||
|
|
||||||
with util.cd(project_dir):
|
with util.cd(project_dir):
|
||||||
# clean obsolete .pioenvs dir
|
# clean obsolete build dir
|
||||||
if not disable_auto_clean:
|
if not disable_auto_clean:
|
||||||
try:
|
try:
|
||||||
_clean_pioenvs_dir(util.get_projectpioenvs_dir())
|
_clean_build_dir(util.get_projectbuild_dir())
|
||||||
except: # pylint: disable=bare-except
|
except: # pylint: disable=bare-except
|
||||||
click.secho(
|
click.secho(
|
||||||
"Can not remove temporary directory `%s`. Please remove "
|
"Can not remove temporary directory `%s`. Please remove "
|
||||||
"`.pioenvs` directory from the project manually to avoid "
|
"it manually to avoid build issues" %
|
||||||
"build issues" % util.get_projectpioenvs_dir(force=True),
|
util.get_projectbuild_dir(force=True),
|
||||||
fg="yellow")
|
fg="yellow")
|
||||||
|
|
||||||
config = util.load_project_config()
|
config = util.load_project_config()
|
||||||
@ -133,17 +132,19 @@ class EnvironmentProcessor(object):
|
|||||||
"upload_resetmethod", "lib_deps", "lib_ignore",
|
"upload_resetmethod", "lib_deps", "lib_ignore",
|
||||||
"lib_extra_dirs", "lib_ldf_mode", "lib_compat_mode",
|
"lib_extra_dirs", "lib_ldf_mode", "lib_compat_mode",
|
||||||
"lib_archive", "piotest", "test_transport", "test_filter",
|
"lib_archive", "piotest", "test_transport", "test_filter",
|
||||||
"test_ignore", "test_port", "debug_tool", "debug_port",
|
"test_ignore", "test_port", "test_speed", "debug_tool",
|
||||||
"debug_init_cmds", "debug_extra_cmds", "debug_server",
|
"debug_port", "debug_init_cmds", "debug_extra_cmds",
|
||||||
"debug_init_break", "debug_load_cmd", "monitor_port",
|
"debug_server", "debug_init_break", "debug_load_cmd",
|
||||||
"monitor_baud", "monitor_rts", "monitor_dtr")
|
"monitor_port", "monitor_baud", "monitor_rts",
|
||||||
|
"monitor_dtr")
|
||||||
|
|
||||||
IGNORE_BUILD_OPTIONS = ("test_transport", "test_filter", "test_ignore",
|
IGNORE_BUILD_OPTIONS = ("test_transport", "test_filter", "test_ignore",
|
||||||
"test_port", "debug_tool", "debug_port",
|
"test_port", "test_speed", "debug_tool",
|
||||||
"debug_init_cmds", "debug_extra_cmds",
|
"debug_port", "debug_init_cmds",
|
||||||
"debug_server", "debug_init_break",
|
"debug_extra_cmds", "debug_server",
|
||||||
"debug_load_cmd", "monitor_port", "monitor_baud",
|
"debug_init_break", "debug_load_cmd",
|
||||||
"monitor_rts", "monitor_dtr")
|
"monitor_port", "monitor_baud", "monitor_rts",
|
||||||
|
"monitor_dtr")
|
||||||
|
|
||||||
REMAPED_OPTIONS = {"framework": "pioframework", "platform": "pioplatform"}
|
REMAPED_OPTIONS = {"framework": "pioframework", "platform": "pioplatform"}
|
||||||
|
|
||||||
@ -307,36 +308,31 @@ def _autoinstall_libdeps(ctx, libraries, verbose=False):
|
|||||||
try:
|
try:
|
||||||
ctx.invoke(cmd_lib_install, libraries=[lib], silent=not verbose)
|
ctx.invoke(cmd_lib_install, libraries=[lib], silent=not verbose)
|
||||||
except exception.LibNotFound as e:
|
except exception.LibNotFound as e:
|
||||||
if not _is_builtin_lib(lib):
|
if verbose or not is_builtin_lib(lib):
|
||||||
click.secho("Warning! %s" % e, fg="yellow")
|
click.secho("Warning! %s" % e, fg="yellow")
|
||||||
|
except exception.InternetIsOffline as e:
|
||||||
|
click.secho(str(e), fg="yellow")
|
||||||
|
|
||||||
|
|
||||||
def _is_builtin_lib(lib_name):
|
def _clean_build_dir(build_dir):
|
||||||
for storage in get_builtin_libs():
|
structhash_file = join(build_dir, "structure.hash")
|
||||||
if any([l.get("name") == lib_name for l in storage['items']]):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _clean_pioenvs_dir(pioenvs_dir):
|
|
||||||
structhash_file = join(pioenvs_dir, "structure.hash")
|
|
||||||
proj_hash = calculate_project_hash()
|
proj_hash = calculate_project_hash()
|
||||||
|
|
||||||
# if project's config is modified
|
# if project's config is modified
|
||||||
if (isdir(pioenvs_dir)
|
if (isdir(build_dir)
|
||||||
and getmtime(join(util.get_project_dir(),
|
and getmtime(join(util.get_project_dir(),
|
||||||
"platformio.ini")) > getmtime(pioenvs_dir)):
|
"platformio.ini")) > getmtime(build_dir)):
|
||||||
util.rmtree_(pioenvs_dir)
|
util.rmtree_(build_dir)
|
||||||
|
|
||||||
# check project structure
|
# check project structure
|
||||||
if isdir(pioenvs_dir) and isfile(structhash_file):
|
if isdir(build_dir) and isfile(structhash_file):
|
||||||
with open(structhash_file) as f:
|
with open(structhash_file) as f:
|
||||||
if f.read() == proj_hash:
|
if f.read() == proj_hash:
|
||||||
return
|
return
|
||||||
util.rmtree_(pioenvs_dir)
|
util.rmtree_(build_dir)
|
||||||
|
|
||||||
if not isdir(pioenvs_dir):
|
if not isdir(build_dir):
|
||||||
makedirs(pioenvs_dir)
|
makedirs(build_dir)
|
||||||
|
|
||||||
with open(structhash_file, "w") as f:
|
with open(structhash_file, "w") as f:
|
||||||
f.write(proj_hash)
|
f.write(proj_hash)
|
||||||
@ -384,13 +380,13 @@ def check_project_defopts(config):
|
|||||||
if not config.has_section("platformio"):
|
if not config.has_section("platformio"):
|
||||||
return True
|
return True
|
||||||
known = ("env_default", "home_dir", "lib_dir", "libdeps_dir", "src_dir",
|
known = ("env_default", "home_dir", "lib_dir", "libdeps_dir", "src_dir",
|
||||||
"envs_dir", "data_dir", "test_dir", "boards_dir",
|
"build_dir", "data_dir", "test_dir", "boards_dir",
|
||||||
"lib_extra_dirs")
|
"lib_extra_dirs")
|
||||||
unknown = set([k for k, _ in config.items("platformio")]) - set(known)
|
unknown = set([k for k, _ in config.items("platformio")]) - set(known)
|
||||||
if not unknown:
|
if not unknown:
|
||||||
return True
|
return True
|
||||||
click.secho(
|
click.secho(
|
||||||
"Warning! Ignore unknown `%s` option from `[platformio]` section" %
|
"Warning! Ignore unknown `%s` option in `[platformio]` section" %
|
||||||
", ".join(unknown),
|
", ".join(unknown),
|
||||||
fg="yellow")
|
fg="yellow")
|
||||||
return False
|
return False
|
||||||
|
@ -97,10 +97,9 @@ class UndefinedPackageVersion(PlatformioException):
|
|||||||
|
|
||||||
class PackageInstallError(PlatformioException):
|
class PackageInstallError(PlatformioException):
|
||||||
|
|
||||||
MESSAGE = (
|
MESSAGE = ("Could not install '{0}' with version requirements '{1}' "
|
||||||
"Could not install '{0}' with version requirements '{1}' for your "
|
"for your system '{2}'.\n"
|
||||||
"system '{2}'.\n If you use Antivirus, it can block PlatformIO "
|
"More details: http://bit.ly/faq-package-manager")
|
||||||
"Package Manager. Try to disable it for a while.")
|
|
||||||
|
|
||||||
|
|
||||||
class FDUnrecognizedStatusCode(PlatformioException):
|
class FDUnrecognizedStatusCode(PlatformioException):
|
||||||
|
@ -51,4 +51,18 @@ add_custom_target(
|
|||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib)
|
||||||
|
add_custom_target(
|
||||||
|
CODE_COMPLETION_PIOLIB
|
||||||
|
SOURCES lib
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.piolibdeps)
|
||||||
|
add_custom_target(
|
||||||
|
CODE_COMPLETION_PIOLIBDEPS
|
||||||
|
SOURCES .piolibdeps
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||||
|
@ -7,8 +7,9 @@ SET(CMAKE_CXX_FLAGS_DISTRIBUTION "{{cxx_flags}}")
|
|||||||
SET(CMAKE_C_FLAGS_DISTRIBUTION "{{cc_flags}}")
|
SET(CMAKE_C_FLAGS_DISTRIBUTION "{{cc_flags}}")
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
|
% import re
|
||||||
% for define in defines:
|
% for define in defines:
|
||||||
add_definitions(-D{{!define}})
|
add_definitions(-D'{{!re.sub(r"([\"\(\)#])", r"\\\1", define)}}')
|
||||||
% end
|
% end
|
||||||
|
|
||||||
% for include in includes:
|
% for include in includes:
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.910961921" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.910961921" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||||
<externalSettings/>
|
<externalSettings/>
|
||||||
<extensions>
|
<extensions>
|
||||||
|
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
|
||||||
</extensions>
|
</extensions>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
@ -99,6 +99,104 @@
|
|||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
</cconfiguration>
|
</cconfiguration>
|
||||||
|
<cconfiguration id="0.910961921.1363900502">
|
||||||
|
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.910961921.1363900502" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||||
|
<externalSettings/>
|
||||||
|
<extensions>
|
||||||
|
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||||
|
</extensions>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
|
<configuration artifactName="mbed" buildProperties="" description="" id="0.910961921.1363900502" name="Debug" parent="org.eclipse.cdt.build.core.prefbase.cfg">
|
||||||
|
<folderInfo id="0.910961921.1363900502." name="/" resourcePath="">
|
||||||
|
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.2116690625" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
|
||||||
|
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="org.eclipse.cdt.build.core.prefbase.toolchain.2116690625.848954921" name=""/>
|
||||||
|
<builder arguments="-f -c eclipse debug" cleanBuildTarget="run --target clean" command="platformio" enableCleanBuild="false" id="org.eclipse.cdt.build.core.settings.default.builder.985867833" incrementalBuildTarget="" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
|
||||||
|
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1855678035" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
|
||||||
|
<tool id="org.eclipse.cdt.build.core.settings.holder.30528994" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||||
|
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.794801023" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
|
||||||
|
% for include in includes:
|
||||||
|
% if "toolchain" in include:
|
||||||
|
% continue
|
||||||
|
% end
|
||||||
|
% if include.startswith(user_home_dir):
|
||||||
|
% if "windows" in systype:
|
||||||
|
<listOptionValue builtIn="false" value="${USERPROFILE}{{include.replace(user_home_dir, '')}}"/>
|
||||||
|
% else:
|
||||||
|
<listOptionValue builtIn="false" value="${HOME}{{include.replace(user_home_dir, '')}}"/>
|
||||||
|
% end
|
||||||
|
% else:
|
||||||
|
<listOptionValue builtIn="false" value="{{include}}"/>
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
</option>
|
||||||
|
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.1743427839" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" valueType="definedSymbols">
|
||||||
|
% for define in defines:
|
||||||
|
<listOptionValue builtIn="false" value="{{define}}"/>
|
||||||
|
% end
|
||||||
|
</option>
|
||||||
|
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.919136836" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||||
|
</tool>
|
||||||
|
<tool id="org.eclipse.cdt.build.core.settings.holder.1146422798" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||||
|
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.650084869" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
|
% for include in includes:
|
||||||
|
% if "toolchain" in include:
|
||||||
|
% continue
|
||||||
|
% end
|
||||||
|
% if include.startswith(user_home_dir):
|
||||||
|
% if "windows" in systype:
|
||||||
|
<listOptionValue builtIn="false" value="${USERPROFILE}{{include.replace(user_home_dir, '')}}"/>
|
||||||
|
% else:
|
||||||
|
<listOptionValue builtIn="false" value="${HOME}{{include.replace(user_home_dir, '')}}"/>
|
||||||
|
% end
|
||||||
|
% else:
|
||||||
|
<listOptionValue builtIn="false" value="{{include}}"/>
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
</option>
|
||||||
|
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.2055633423" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||||
|
% for define in defines:
|
||||||
|
<listOptionValue builtIn="false" value="{{define}}"/>
|
||||||
|
% end
|
||||||
|
</option>
|
||||||
|
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.445650141" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||||
|
</tool>
|
||||||
|
<tool id="org.eclipse.cdt.build.core.settings.holder.1637357529" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
|
||||||
|
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.1246337321" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" useByScannerDiscovery="false" valueType="includePath">
|
||||||
|
% for include in includes:
|
||||||
|
% if "toolchain" in include:
|
||||||
|
% continue
|
||||||
|
% end
|
||||||
|
% if include.startswith(user_home_dir):
|
||||||
|
% if "windows" in systype:
|
||||||
|
<listOptionValue builtIn="false" value="${USERPROFILE}{{include.replace(user_home_dir, '')}}"/>
|
||||||
|
% else:
|
||||||
|
<listOptionValue builtIn="false" value="${HOME}{{include.replace(user_home_dir, '')}}"/>
|
||||||
|
% end
|
||||||
|
% else:
|
||||||
|
<listOptionValue builtIn="false" value="{{include}}"/>
|
||||||
|
% end
|
||||||
|
% end
|
||||||
|
</option>
|
||||||
|
<option id="org.eclipse.cdt.build.core.settings.holder.symbols.2122043341" name="Symbols" superClass="org.eclipse.cdt.build.core.settings.holder.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||||
|
% for define in defines:
|
||||||
|
<listOptionValue builtIn="false" value="{{define}}"/>
|
||||||
|
% end
|
||||||
|
</option>
|
||||||
|
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.207004812" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
|
||||||
|
</tool>
|
||||||
|
</toolChain>
|
||||||
|
</folderInfo>
|
||||||
|
</configuration>
|
||||||
|
</storageModule>
|
||||||
|
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||||
|
</cconfiguration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||||
<project id="{{project_name}}.null.189551033" name="{{project_name}}"/>
|
<project id="{{project_name}}.null.189551033" name="{{project_name}}"/>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
|
<launchConfiguration type="org.eclipse.cdt.launch.applicationLaunchType">
|
||||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB" value="true"/>
|
||||||
<listAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB_LIST"/>
|
<listAttribute key="org.eclipse.cdt.dsf.gdb.AUTO_SOLIB_LIST"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="platformio -c eclipse debug -d ${project_loc} --interface=gdb"/>
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="piodebuggdb"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_ON_FORK" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_ON_FORK" value="false"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.GDB_INIT" value=".pioinit"/>
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.GDB_INIT" value=".pioinit"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.NON_STOP" value="false"/>
|
||||||
@ -12,17 +12,17 @@
|
|||||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.TRACEPOINT_MODE" value="TP_NORMAL_ONLY"/>
|
<stringAttribute key="org.eclipse.cdt.dsf.gdb.TRACEPOINT_MODE" value="TP_NORMAL_ONLY"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.internal.ui.launching.LocalApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.internal.ui.launching.LocalApplicationCDebuggerTab.DEFAULTS_SET" value="true"/>
|
||||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="0"/>
|
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="1"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="gdb"/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_ID" value="gdb"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_REGISTER_GROUPS" value=""/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="run"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
|
<booleanAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN" value="true"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
|
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_STOP_AT_MAIN_SYMBOL" value="main"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value=".pioenvs/{{env_name}}/firmware.elf"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="{{prog_path}}"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="{{project_name}}"/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="{{project_name}}"/>
|
||||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
||||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="0.910961921.1363900502"/>
|
||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||||
<listEntry value="/{{project_name}}"/>
|
<listEntry value="/{{project_name}}"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
|
@ -15,4 +15,19 @@
|
|||||||
</provider>
|
</provider>
|
||||||
</extension>
|
</extension>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<configuration id="0.910961921.1363900502" name="Debug">
|
||||||
|
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
|
||||||
|
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
|
||||||
|
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
|
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
|
||||||
|
% if "windows" in systype:
|
||||||
|
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="1291887707783033084" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${USERPROFILE}{{cxx_path.replace(user_home_dir, '')}} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||||
|
% else:
|
||||||
|
<provider class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector" console="false" env-hash="-869785120007741010" id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler Settings" parameter="${HOME}{{cxx_path.replace(user_home_dir, '')}} ${FLAGS} -E -P -v -dD "${INPUTS}"" prefer-non-shared="true">
|
||||||
|
% end
|
||||||
|
<language-scope id="org.eclipse.cdt.core.gcc"/>
|
||||||
|
<language-scope id="org.eclipse.cdt.core.g++"/>
|
||||||
|
</provider>
|
||||||
|
</extension>
|
||||||
|
</configuration>
|
||||||
</project>
|
</project>
|
||||||
|
@ -3,4 +3,9 @@ environment/project/0.910961921/PATH/delimiter={{env_pathsep.replace(":", "\\:")
|
|||||||
environment/project/0.910961921/PATH/operation=replace
|
environment/project/0.910961921/PATH/operation=replace
|
||||||
environment/project/0.910961921/PATH/value={{env_path.replace(":", "\\:")}}
|
environment/project/0.910961921/PATH/value={{env_path.replace(":", "\\:")}}
|
||||||
environment/project/0.910961921/append=true
|
environment/project/0.910961921/append=true
|
||||||
environment/project/0.910961921/appendContributed=true
|
environment/project/0.910961921/appendContributed=true
|
||||||
|
environment/project/0.910961921.1363900502/PATH/delimiter={{env_pathsep.replace(":", "\\:")}}
|
||||||
|
environment/project/0.910961921.1363900502/PATH/operation=replace
|
||||||
|
environment/project/0.910961921.1363900502/PATH/value={{env_path.replace(":", "\\:")}}
|
||||||
|
environment/project/0.910961921.1363900502/append=true
|
||||||
|
environment/project/0.910961921.1363900502/appendContributed=true
|
@ -14,7 +14,7 @@ INCLUDEPATH += "{{include}}"
|
|||||||
% end
|
% end
|
||||||
|
|
||||||
% for define in defines:
|
% for define in defines:
|
||||||
DEFINES += "{{define}}"
|
DEFINES += {{!define}}
|
||||||
% end
|
% end
|
||||||
|
|
||||||
OTHER_FILES += platformio.ini
|
OTHER_FILES += platformio.ini
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
.pioenvs
|
.pioenvs
|
||||||
.piolibdeps
|
.piolibdeps
|
||||||
.vscode/c_cpp_properties.json
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
@ -21,9 +21,9 @@ from platformio import __version__, exception, util
|
|||||||
from platformio.managers.package import PackageManager
|
from platformio.managers.package import PackageManager
|
||||||
|
|
||||||
CORE_PACKAGES = {
|
CORE_PACKAGES = {
|
||||||
"contrib-piohome": ">=0.6.0,<2",
|
"contrib-piohome": ">=0.6.1,<2",
|
||||||
"contrib-pysite": ">=0.1.2,<2",
|
"contrib-pysite": ">=0.1.2,<2",
|
||||||
"tool-pioplus": ">=0.12.1,<2",
|
"tool-pioplus": ">=0.13.3,<2",
|
||||||
"tool-unity": "~1.20302.1",
|
"tool-unity": "~1.20302.1",
|
||||||
"tool-scons": "~3.20501.2"
|
"tool-scons": "~3.20501.2"
|
||||||
}
|
}
|
||||||
@ -101,8 +101,7 @@ def pioplus_call(args, **kwargs):
|
|||||||
raise exception.PlatformioException(
|
raise exception.PlatformioException(
|
||||||
"PlatformIO Core Plus v%s does not run under Python version %s.\n"
|
"PlatformIO Core Plus v%s does not run under Python version %s.\n"
|
||||||
"Minimum supported version is 2.7.6, please upgrade Python.\n"
|
"Minimum supported version is 2.7.6, please upgrade Python.\n"
|
||||||
"Python 3 is not yet supported.\n" % (__version__,
|
"Python 3 is not yet supported.\n" % (__version__, sys.version))
|
||||||
sys.version.split()[0]))
|
|
||||||
|
|
||||||
pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
|
pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
|
||||||
pythonexe_path = util.get_pythonexe_path()
|
pythonexe_path = util.get_pythonexe_path()
|
||||||
|
@ -13,17 +13,18 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# pylint: disable=too-many-arguments, too-many-locals, too-many-branches
|
# pylint: disable=too-many-arguments, too-many-locals, too-many-branches
|
||||||
|
# pylint: disable=too-many-return-statements
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from os.path import isdir, join
|
from os.path import isdir, join
|
||||||
|
|
||||||
import arrow
|
|
||||||
import click
|
import click
|
||||||
|
|
||||||
from platformio import app, commands, exception, util
|
from platformio import app, commands, exception, util
|
||||||
from platformio.managers.package import BasePkgManager
|
from platformio.managers.package import BasePkgManager
|
||||||
|
from platformio.managers.platform import PlatformFactory, PlatformManager
|
||||||
|
|
||||||
|
|
||||||
class LibraryManager(BasePkgManager):
|
class LibraryManager(BasePkgManager):
|
||||||
@ -155,8 +156,8 @@ class LibraryManager(BasePkgManager):
|
|||||||
def max_satisfying_repo_version(self, versions, requirements=None):
|
def max_satisfying_repo_version(self, versions, requirements=None):
|
||||||
|
|
||||||
def _cmp_dates(datestr1, datestr2):
|
def _cmp_dates(datestr1, datestr2):
|
||||||
date1 = arrow.get(datestr1)
|
date1 = util.parse_date(datestr1)
|
||||||
date2 = arrow.get(datestr2)
|
date2 = util.parse_date(datestr2)
|
||||||
if date1 == date2:
|
if date1 == date2:
|
||||||
return 0
|
return 0
|
||||||
return -1 if date1 < date2 else 1
|
return -1 if date1 < date2 else 1
|
||||||
@ -186,29 +187,15 @@ class LibraryManager(BasePkgManager):
|
|||||||
def get_latest_repo_version(self, name, requirements, silent=False):
|
def get_latest_repo_version(self, name, requirements, silent=False):
|
||||||
item = self.max_satisfying_repo_version(
|
item = self.max_satisfying_repo_version(
|
||||||
util.get_api_result(
|
util.get_api_result(
|
||||||
"/lib/info/%d" % self.get_pkg_id_by_name(
|
"/lib/info/%d" % self.search_lib_id(
|
||||||
name, requirements, silent=silent),
|
{
|
||||||
|
"name": name,
|
||||||
|
"requirements": requirements
|
||||||
|
},
|
||||||
|
silent=silent),
|
||||||
cache_valid="1h")['versions'], requirements)
|
cache_valid="1h")['versions'], requirements)
|
||||||
return item['name'] if item else None
|
return item['name'] if item else None
|
||||||
|
|
||||||
def get_pkg_id_by_name(self,
|
|
||||||
name,
|
|
||||||
requirements,
|
|
||||||
silent=False,
|
|
||||||
interactive=False):
|
|
||||||
if name.startswith("id="):
|
|
||||||
return int(name[3:])
|
|
||||||
# try to find ID from installed packages
|
|
||||||
package_dir = self.get_package_dir(name, requirements)
|
|
||||||
if package_dir:
|
|
||||||
manifest = self.load_manifest(package_dir)
|
|
||||||
if "id" in manifest:
|
|
||||||
return int(manifest['id'])
|
|
||||||
return int(
|
|
||||||
self.search_for_library({
|
|
||||||
"name": name
|
|
||||||
}, silent, interactive)['id'])
|
|
||||||
|
|
||||||
def _install_from_piorepo(self, name, requirements):
|
def _install_from_piorepo(self, name, requirements):
|
||||||
assert name.startswith("id="), name
|
assert name.startswith("id="), name
|
||||||
version = self.get_latest_repo_version(name, requirements)
|
version = self.get_latest_repo_version(name, requirements)
|
||||||
@ -225,88 +212,20 @@ class LibraryManager(BasePkgManager):
|
|||||||
"http://", "https://") if app.get_setting("enable_ssl") else
|
"http://", "https://") if app.get_setting("enable_ssl") else
|
||||||
dl_data['url'], requirements)
|
dl_data['url'], requirements)
|
||||||
|
|
||||||
def install( # pylint: disable=arguments-differ
|
def search_lib_id( # pylint: disable=too-many-branches
|
||||||
self,
|
self,
|
||||||
name,
|
|
||||||
requirements=None,
|
|
||||||
silent=False,
|
|
||||||
trigger_event=True,
|
|
||||||
interactive=False,
|
|
||||||
force=False):
|
|
||||||
pkg_dir = None
|
|
||||||
try:
|
|
||||||
_name, _requirements, _url = self.parse_pkg_uri(name, requirements)
|
|
||||||
if not _url:
|
|
||||||
name = "id=%d" % self.get_pkg_id_by_name(
|
|
||||||
_name,
|
|
||||||
_requirements,
|
|
||||||
silent=silent,
|
|
||||||
interactive=interactive)
|
|
||||||
requirements = _requirements
|
|
||||||
pkg_dir = BasePkgManager.install(
|
|
||||||
self,
|
|
||||||
name,
|
|
||||||
requirements,
|
|
||||||
silent=silent,
|
|
||||||
trigger_event=trigger_event,
|
|
||||||
force=force)
|
|
||||||
except exception.InternetIsOffline as e:
|
|
||||||
if not silent:
|
|
||||||
click.secho(str(e), fg="yellow")
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not pkg_dir:
|
|
||||||
return None
|
|
||||||
|
|
||||||
manifest = self.load_manifest(pkg_dir)
|
|
||||||
if "dependencies" not in manifest:
|
|
||||||
return pkg_dir
|
|
||||||
|
|
||||||
if not silent:
|
|
||||||
click.secho("Installing dependencies", fg="yellow")
|
|
||||||
|
|
||||||
for filters in self.normalize_dependencies(manifest['dependencies']):
|
|
||||||
assert "name" in filters
|
|
||||||
if any([s in filters.get("version", "") for s in ("\\", "/")]):
|
|
||||||
self.install(
|
|
||||||
"{name}={version}".format(**filters),
|
|
||||||
silent=silent,
|
|
||||||
trigger_event=trigger_event,
|
|
||||||
interactive=interactive,
|
|
||||||
force=force)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
lib_info = self.search_for_library(filters, silent,
|
|
||||||
interactive)
|
|
||||||
except exception.LibNotFound as e:
|
|
||||||
if not silent:
|
|
||||||
click.secho("Warning! %s" % e, fg="yellow")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if filters.get("version"):
|
|
||||||
self.install(
|
|
||||||
lib_info['id'],
|
|
||||||
filters.get("version"),
|
|
||||||
silent=silent,
|
|
||||||
trigger_event=trigger_event,
|
|
||||||
interactive=interactive,
|
|
||||||
force=force)
|
|
||||||
else:
|
|
||||||
self.install(
|
|
||||||
lib_info['id'],
|
|
||||||
silent=silent,
|
|
||||||
trigger_event=trigger_event,
|
|
||||||
interactive=interactive,
|
|
||||||
force=force)
|
|
||||||
return pkg_dir
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def search_for_library( # pylint: disable=too-many-branches
|
|
||||||
filters,
|
filters,
|
||||||
silent=False,
|
silent=False,
|
||||||
interactive=False):
|
interactive=False):
|
||||||
assert isinstance(filters, dict)
|
assert isinstance(filters, dict)
|
||||||
assert "name" in filters
|
assert "name" in filters
|
||||||
|
|
||||||
|
# try to find ID within installed packages
|
||||||
|
lib_id = self._get_lib_id_from_installed(filters)
|
||||||
|
if lib_id:
|
||||||
|
return lib_id
|
||||||
|
|
||||||
|
# looking in PIO Library Registry
|
||||||
if not silent:
|
if not silent:
|
||||||
click.echo("Looking for %s library in registry" % click.style(
|
click.echo("Looking for %s library in registry" % click.style(
|
||||||
filters['name'], fg="cyan"))
|
filters['name'], fg="cyan"))
|
||||||
@ -366,4 +285,141 @@ class LibraryManager(BasePkgManager):
|
|||||||
"http://platformio.org/lib/show/{id}/{name}".format(
|
"http://platformio.org/lib/show/{id}/{name}".format(
|
||||||
**lib_info),
|
**lib_info),
|
||||||
fg="blue"))
|
fg="blue"))
|
||||||
return lib_info
|
return int(lib_info['id'])
|
||||||
|
|
||||||
|
def _get_lib_id_from_installed(self, filters):
|
||||||
|
if filters['name'].startswith("id="):
|
||||||
|
return int(filters['name'][3:])
|
||||||
|
package_dir = self.get_package_dir(filters['name'],
|
||||||
|
filters.get("requirements",
|
||||||
|
filters.get("version")))
|
||||||
|
if not package_dir:
|
||||||
|
return None
|
||||||
|
manifest = self.load_manifest(package_dir)
|
||||||
|
if "id" not in manifest:
|
||||||
|
return None
|
||||||
|
|
||||||
|
for key in ("frameworks", "platforms"):
|
||||||
|
if key not in filters:
|
||||||
|
continue
|
||||||
|
if key not in manifest:
|
||||||
|
return None
|
||||||
|
if not util.items_in_list(
|
||||||
|
util.items_to_list(filters[key]),
|
||||||
|
util.items_to_list(manifest[key])):
|
||||||
|
return None
|
||||||
|
|
||||||
|
if "authors" in filters:
|
||||||
|
if "authors" not in manifest:
|
||||||
|
return None
|
||||||
|
manifest_authors = manifest['authors']
|
||||||
|
if not isinstance(manifest_authors, list):
|
||||||
|
manifest_authors = [manifest_authors]
|
||||||
|
manifest_authors = [
|
||||||
|
a['name'] for a in manifest_authors
|
||||||
|
if isinstance(a, dict) and "name" in a
|
||||||
|
]
|
||||||
|
filter_authors = filters['authors']
|
||||||
|
if not isinstance(filter_authors, list):
|
||||||
|
filter_authors = [filter_authors]
|
||||||
|
if not set(filter_authors) <= set(manifest_authors):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return int(manifest['id'])
|
||||||
|
|
||||||
|
def install( # pylint: disable=arguments-differ
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
requirements=None,
|
||||||
|
silent=False,
|
||||||
|
trigger_event=True,
|
||||||
|
interactive=False,
|
||||||
|
force=False):
|
||||||
|
_name, _requirements, _url = self.parse_pkg_uri(name, requirements)
|
||||||
|
if not _url:
|
||||||
|
name = "id=%d" % self.search_lib_id(
|
||||||
|
{
|
||||||
|
"name": _name,
|
||||||
|
"requirements": _requirements
|
||||||
|
},
|
||||||
|
silent=silent,
|
||||||
|
interactive=interactive)
|
||||||
|
requirements = _requirements
|
||||||
|
pkg_dir = BasePkgManager.install(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
requirements,
|
||||||
|
silent=silent,
|
||||||
|
trigger_event=trigger_event,
|
||||||
|
force=force)
|
||||||
|
|
||||||
|
if not pkg_dir:
|
||||||
|
return None
|
||||||
|
|
||||||
|
manifest = self.load_manifest(pkg_dir)
|
||||||
|
if "dependencies" not in manifest:
|
||||||
|
return pkg_dir
|
||||||
|
|
||||||
|
if not silent:
|
||||||
|
click.secho("Installing dependencies", fg="yellow")
|
||||||
|
|
||||||
|
for filters in self.normalize_dependencies(manifest['dependencies']):
|
||||||
|
assert "name" in filters
|
||||||
|
if any([s in filters.get("version", "") for s in ("\\", "/")]):
|
||||||
|
self.install(
|
||||||
|
"{name}={version}".format(**filters),
|
||||||
|
silent=silent,
|
||||||
|
trigger_event=trigger_event,
|
||||||
|
interactive=interactive,
|
||||||
|
force=force)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
lib_id = self.search_lib_id(filters, silent, interactive)
|
||||||
|
except exception.LibNotFound as e:
|
||||||
|
if not silent or is_builtin_lib(filters['name']):
|
||||||
|
click.secho("Warning! %s" % e, fg="yellow")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if filters.get("version"):
|
||||||
|
self.install(
|
||||||
|
lib_id,
|
||||||
|
filters.get("version"),
|
||||||
|
silent=silent,
|
||||||
|
trigger_event=trigger_event,
|
||||||
|
interactive=interactive,
|
||||||
|
force=force)
|
||||||
|
else:
|
||||||
|
self.install(
|
||||||
|
lib_id,
|
||||||
|
silent=silent,
|
||||||
|
trigger_event=trigger_event,
|
||||||
|
interactive=interactive,
|
||||||
|
force=force)
|
||||||
|
return pkg_dir
|
||||||
|
|
||||||
|
|
||||||
|
@util.memoized
|
||||||
|
def get_builtin_libs(storage_names=None):
|
||||||
|
items = []
|
||||||
|
storage_names = storage_names or []
|
||||||
|
pm = PlatformManager()
|
||||||
|
for manifest in pm.get_installed():
|
||||||
|
p = PlatformFactory.newPlatform(manifest['__pkg_dir'])
|
||||||
|
for storage in p.get_lib_storages():
|
||||||
|
if storage_names and storage['name'] not in storage_names:
|
||||||
|
continue
|
||||||
|
lm = LibraryManager(storage['path'])
|
||||||
|
items.append({
|
||||||
|
"name": storage['name'],
|
||||||
|
"path": storage['path'],
|
||||||
|
"items": lm.get_installed()
|
||||||
|
})
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
@util.memoized
|
||||||
|
def is_builtin_lib(name):
|
||||||
|
for storage in get_builtin_libs():
|
||||||
|
if any([l.get("name") == name for l in storage['items']]):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
@ -134,6 +134,7 @@ class PkgRepoMixin(object):
|
|||||||
class PkgInstallerMixin(object):
|
class PkgInstallerMixin(object):
|
||||||
|
|
||||||
SRC_MANIFEST_NAME = ".piopkgmanager.json"
|
SRC_MANIFEST_NAME = ".piopkgmanager.json"
|
||||||
|
TMP_FOLDER_PREFIX = "_tmp_installing-"
|
||||||
|
|
||||||
FILE_CACHE_VALID = "1m" # 1 month
|
FILE_CACHE_VALID = "1m" # 1 month
|
||||||
FILE_CACHE_MAX_SIZE = 1024 * 1024
|
FILE_CACHE_MAX_SIZE = 1024 * 1024
|
||||||
@ -211,6 +212,8 @@ class PkgInstallerMixin(object):
|
|||||||
try:
|
try:
|
||||||
return semantic_version.Version(value)
|
return semantic_version.Version(value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
if "." not in str(value) and not str(value).isdigit():
|
||||||
|
raise ValueError("Invalid SemVer version %s" % value)
|
||||||
return semantic_version.Version.coerce(value)
|
return semantic_version.Version.coerce(value)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
if raise_exception:
|
if raise_exception:
|
||||||
@ -292,6 +295,8 @@ class PkgInstallerMixin(object):
|
|||||||
def get_installed(self):
|
def get_installed(self):
|
||||||
items = []
|
items = []
|
||||||
for pkg_dir in self.read_dirs(self.package_dir):
|
for pkg_dir in self.read_dirs(self.package_dir):
|
||||||
|
if self.TMP_FOLDER_PREFIX in pkg_dir:
|
||||||
|
continue
|
||||||
manifest = self.load_manifest(pkg_dir)
|
manifest = self.load_manifest(pkg_dir)
|
||||||
if not manifest:
|
if not manifest:
|
||||||
continue
|
continue
|
||||||
@ -361,7 +366,7 @@ class PkgInstallerMixin(object):
|
|||||||
break
|
break
|
||||||
except Exception as e: # pylint: disable=broad-except
|
except Exception as e: # pylint: disable=broad-except
|
||||||
click.secho("Warning! Package Mirror: %s" % e, fg="yellow")
|
click.secho("Warning! Package Mirror: %s" % e, fg="yellow")
|
||||||
click.secho("Looking for other mirror...", fg="yellow")
|
click.secho("Looking for another mirror...", fg="yellow")
|
||||||
|
|
||||||
if versions is None:
|
if versions is None:
|
||||||
raise exception.UnknownPackage(name)
|
raise exception.UnknownPackage(name)
|
||||||
@ -376,7 +381,7 @@ class PkgInstallerMixin(object):
|
|||||||
requirements=None,
|
requirements=None,
|
||||||
sha1=None,
|
sha1=None,
|
||||||
track=False):
|
track=False):
|
||||||
tmp_dir = mkdtemp("-package", "_tmp_installing-", self.package_dir)
|
tmp_dir = mkdtemp("-package", self.TMP_FOLDER_PREFIX, self.package_dir)
|
||||||
src_manifest_dir = None
|
src_manifest_dir = None
|
||||||
src_manifest = {"name": name, "url": url, "requirements": requirements}
|
src_manifest = {"name": name, "url": url, "requirements": requirements}
|
||||||
|
|
||||||
@ -661,6 +666,7 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
|||||||
name, url, requirements, track=True)
|
name, url, requirements, track=True)
|
||||||
else:
|
else:
|
||||||
pkg_dir = self._install_from_piorepo(name, requirements)
|
pkg_dir = self._install_from_piorepo(name, requirements)
|
||||||
|
|
||||||
if not pkg_dir or not self.manifest_exists(pkg_dir):
|
if not pkg_dir or not self.manifest_exists(pkg_dir):
|
||||||
raise exception.PackageInstallError(name, requirements or "*",
|
raise exception.PackageInstallError(name, requirements or "*",
|
||||||
util.get_systype())
|
util.get_systype())
|
||||||
|
@ -22,13 +22,13 @@ import socket
|
|||||||
import stat
|
import stat
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
from glob import glob
|
from glob import glob
|
||||||
from os.path import (abspath, basename, dirname, expanduser, isdir, isfile,
|
from os.path import (abspath, basename, dirname, expanduser, isdir, isfile,
|
||||||
join, normpath, splitdrive)
|
join, normpath, splitdrive)
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from time import sleep, time
|
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import requests
|
import requests
|
||||||
@ -159,10 +159,10 @@ class throttle(object):
|
|||||||
|
|
||||||
@wraps(fn)
|
@wraps(fn)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
diff = int(round((time() - self.last) * 1000))
|
diff = int(round((time.time() - self.last) * 1000))
|
||||||
if diff < self.threshhold:
|
if diff < self.threshhold:
|
||||||
sleep((self.threshhold - diff) * 0.001)
|
time.sleep((self.threshhold - diff) * 0.001)
|
||||||
self.last = time()
|
self.last = time.time()
|
||||||
return fn(*args, **kwargs)
|
return fn(*args, **kwargs)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
@ -311,8 +311,8 @@ def get_projectboards_dir():
|
|||||||
join(get_project_dir(), "boards"))
|
join(get_project_dir(), "boards"))
|
||||||
|
|
||||||
|
|
||||||
def get_projectpioenvs_dir(force=False):
|
def get_projectbuild_dir(force=False):
|
||||||
path = get_project_optional_dir("envs_dir",
|
path = get_project_optional_dir("build_dir",
|
||||||
join(get_project_dir(), ".pioenvs"))
|
join(get_project_dir(), ".pioenvs"))
|
||||||
try:
|
try:
|
||||||
if not isdir(path):
|
if not isdir(path):
|
||||||
@ -322,7 +322,7 @@ def get_projectpioenvs_dir(force=False):
|
|||||||
with open(dontmod_path, "w") as fp:
|
with open(dontmod_path, "w") as fp:
|
||||||
fp.write("""
|
fp.write("""
|
||||||
[InternetShortcut]
|
[InternetShortcut]
|
||||||
URL=http://docs.platformio.org/page/projectconf.html#envs-dir
|
URL=http://docs.platformio.org/page/projectconf/section_platformio.html#build-dir
|
||||||
""")
|
""")
|
||||||
except Exception as e: # pylint: disable=broad-except
|
except Exception as e: # pylint: disable=broad-except
|
||||||
if not force:
|
if not force:
|
||||||
@ -330,6 +330,10 @@ URL=http://docs.platformio.org/page/projectconf.html#envs-dir
|
|||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
# compatibility with PIO Core+
|
||||||
|
get_projectpioenvs_dir = get_projectbuild_dir
|
||||||
|
|
||||||
|
|
||||||
def get_projectdata_dir():
|
def get_projectdata_dir():
|
||||||
return get_project_optional_dir("data_dir", join(get_project_dir(),
|
return get_project_optional_dir("data_dir", join(get_project_dir(),
|
||||||
"data"))
|
"data"))
|
||||||
@ -445,6 +449,10 @@ def get_serial_ports(filter_hwid=False):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# Backward compatibility for PIO Core <3.5
|
||||||
|
get_serialports = get_serial_ports
|
||||||
|
|
||||||
|
|
||||||
def get_logical_devices():
|
def get_logical_devices():
|
||||||
items = []
|
items = []
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
@ -483,14 +491,6 @@ def get_logical_devices():
|
|||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
### Backward compatibility for PIO Core <3.5
|
|
||||||
get_serialports = get_serial_ports
|
|
||||||
get_logicaldisks = lambda: [{
|
|
||||||
"disk": d['path'],
|
|
||||||
"name": d['name']
|
|
||||||
} for d in get_logical_devices()]
|
|
||||||
|
|
||||||
|
|
||||||
def get_mdns_services():
|
def get_mdns_services():
|
||||||
try:
|
try:
|
||||||
import zeroconf
|
import zeroconf
|
||||||
@ -541,7 +541,7 @@ def get_mdns_services():
|
|||||||
|
|
||||||
items = []
|
items = []
|
||||||
with mDNSListener() as mdns:
|
with mDNSListener() as mdns:
|
||||||
sleep(3)
|
time.sleep(3)
|
||||||
for service in mdns.get_services():
|
for service in mdns.get_services():
|
||||||
items.append({
|
items.append({
|
||||||
"type":
|
"type":
|
||||||
@ -621,7 +621,6 @@ def _get_api_result(
|
|||||||
|
|
||||||
|
|
||||||
def get_api_result(url, params=None, data=None, auth=None, cache_valid=None):
|
def get_api_result(url, params=None, data=None, auth=None, cache_valid=None):
|
||||||
internet_on(raise_exception=True)
|
|
||||||
from platformio.app import ContentCache
|
from platformio.app import ContentCache
|
||||||
total = 0
|
total = 0
|
||||||
max_retries = 5
|
max_retries = 5
|
||||||
@ -634,6 +633,10 @@ def get_api_result(url, params=None, data=None, auth=None, cache_valid=None):
|
|||||||
result = cc.get(cache_key)
|
result = cc.get(cache_key)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
# check internet before and resolve issue with 60 seconds timeout
|
||||||
|
internet_on(raise_exception=True)
|
||||||
|
|
||||||
result = _get_api_result(url, params, data)
|
result = _get_api_result(url, params, data)
|
||||||
if cache_valid:
|
if cache_valid:
|
||||||
with ContentCache() as cc:
|
with ContentCache() as cc:
|
||||||
@ -648,7 +651,7 @@ def get_api_result(url, params=None, data=None, auth=None, cache_valid=None):
|
|||||||
"[API] ConnectionError: {0} (incremented retry: max={1}, "
|
"[API] ConnectionError: {0} (incremented retry: max={1}, "
|
||||||
"total={2})".format(e, max_retries, total),
|
"total={2})".format(e, max_retries, total),
|
||||||
fg="yellow")
|
fg="yellow")
|
||||||
sleep(2 * total)
|
time.sleep(2 * total)
|
||||||
|
|
||||||
raise exception.APIRequestError(
|
raise exception.APIRequestError(
|
||||||
"Could not connect to PlatformIO API Service. "
|
"Could not connect to PlatformIO API Service. "
|
||||||
@ -720,6 +723,26 @@ def pepver_to_semver(pepver):
|
|||||||
return re.sub(r"(\.\d+)\.?(dev|a|b|rc|post)", r"\1-\2.", pepver, 1)
|
return re.sub(r"(\.\d+)\.?(dev|a|b|rc|post)", r"\1-\2.", pepver, 1)
|
||||||
|
|
||||||
|
|
||||||
|
def items_to_list(items):
|
||||||
|
if not isinstance(items, list):
|
||||||
|
items = [i.strip() for i in items.split(",")]
|
||||||
|
return [i.lower() for i in items if i]
|
||||||
|
|
||||||
|
|
||||||
|
def items_in_list(needle, haystack):
|
||||||
|
needle = items_to_list(needle)
|
||||||
|
haystack = items_to_list(haystack)
|
||||||
|
if "*" in needle or "*" in haystack:
|
||||||
|
return True
|
||||||
|
return set(needle) & set(haystack)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_date(datestr):
|
||||||
|
if "T" in datestr and "Z" in datestr:
|
||||||
|
return time.strptime(datestr, "%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
return time.strptime(datestr)
|
||||||
|
|
||||||
|
|
||||||
def rmtree_(path):
|
def rmtree_(path):
|
||||||
|
|
||||||
def _onerror(_, name, __):
|
def _onerror(_, name, __):
|
||||||
|
2
setup.py
2
setup.py
@ -18,7 +18,6 @@ from platformio import (__author__, __description__, __email__, __license__,
|
|||||||
__title__, __url__, __version__)
|
__title__, __url__, __version__)
|
||||||
|
|
||||||
install_requires = [
|
install_requires = [
|
||||||
"arrow>=0.10.0,!=0.11.0",
|
|
||||||
"bottle<0.13",
|
"bottle<0.13",
|
||||||
"click>=5,<6",
|
"click>=5,<6",
|
||||||
"colorama",
|
"colorama",
|
||||||
@ -37,6 +36,7 @@ setup(
|
|||||||
author_email=__email__,
|
author_email=__email__,
|
||||||
url=__url__,
|
url=__url__,
|
||||||
license=__license__,
|
license=__license__,
|
||||||
|
python_requires='>=2.7, <3',
|
||||||
install_requires=install_requires,
|
install_requires=install_requires,
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
package_data={
|
package_data={
|
||||||
|
@ -45,7 +45,7 @@ def test_ci_lib_and_board(clirunner, validate_cliresult):
|
|||||||
example_dir = join("examples", "atmelavr", "arduino-external-libs")
|
example_dir = join("examples", "atmelavr", "arduino-external-libs")
|
||||||
result = clirunner.invoke(cmd_ci, [
|
result = clirunner.invoke(cmd_ci, [
|
||||||
join(example_dir, "lib", "OneWire", "examples", "DS2408_Switch",
|
join(example_dir, "lib", "OneWire", "examples", "DS2408_Switch",
|
||||||
"DS2408_Switch.pde"), "-l", join(example_dir, "lib", "OneWire"),
|
"DS2408_Switch.pde"), "-l",
|
||||||
"-b", "uno"
|
join(example_dir, "lib", "OneWire"), "-b", "uno"
|
||||||
])
|
])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
|
@ -54,7 +54,7 @@ def test_init_duplicated_boards(clirunner, validate_cliresult, tmpdir):
|
|||||||
assert set(config.sections()) == set(["env:uno"])
|
assert set(config.sections()) == set(["env:uno"])
|
||||||
|
|
||||||
|
|
||||||
def test_init_ide_without_board(clirunner, validate_cliresult, tmpdir):
|
def test_init_ide_without_board(clirunner, tmpdir):
|
||||||
with tmpdir.as_cwd():
|
with tmpdir.as_cwd():
|
||||||
result = clirunner.invoke(cmd_init, ["--ide", "atom"])
|
result = clirunner.invoke(cmd_init, ["--ide", "atom"])
|
||||||
assert result.exit_code == -1
|
assert result.exit_code == -1
|
||||||
@ -67,13 +67,15 @@ def test_init_ide_atom(clirunner, validate_cliresult, tmpdir):
|
|||||||
cmd_init, ["--ide", "atom", "-b", "uno", "-b", "teensy31"])
|
cmd_init, ["--ide", "atom", "-b", "uno", "-b", "teensy31"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(str(tmpdir))
|
validate_pioproject(str(tmpdir))
|
||||||
assert all([tmpdir.join(f).check()
|
assert all([
|
||||||
for f in (".clang_complete", ".gcc-flags.json")])
|
tmpdir.join(f).check()
|
||||||
|
for f in (".clang_complete", ".gcc-flags.json")
|
||||||
|
])
|
||||||
assert "arduinoavr" in tmpdir.join(".clang_complete").read()
|
assert "arduinoavr" in tmpdir.join(".clang_complete").read()
|
||||||
|
|
||||||
# switch to NodeMCU
|
# switch to NodeMCU
|
||||||
result = clirunner.invoke(
|
result = clirunner.invoke(cmd_init,
|
||||||
cmd_init, ["--ide", "atom", "-b", "nodemcuv2"])
|
["--ide", "atom", "-b", "nodemcuv2"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(str(tmpdir))
|
validate_pioproject(str(tmpdir))
|
||||||
assert "arduinoespressif" in tmpdir.join(".clang_complete").read()
|
assert "arduinoespressif" in tmpdir.join(".clang_complete").read()
|
||||||
@ -104,15 +106,13 @@ def test_init_special_board(clirunner, validate_cliresult):
|
|||||||
boards = json.loads(result.output)
|
boards = json.loads(result.output)
|
||||||
|
|
||||||
config = util.load_project_config()
|
config = util.load_project_config()
|
||||||
expected_result = [
|
expected_result = [("platform", str(boards[0]['platform'])),
|
||||||
("platform", str(boards[0]['platform'])),
|
("framework",
|
||||||
("framework", str(boards[0]['frameworks'][0])), ("board", "uno")
|
str(boards[0]['frameworks'][0])), ("board", "uno")]
|
||||||
]
|
|
||||||
|
|
||||||
assert config.has_section("env:uno")
|
assert config.has_section("env:uno")
|
||||||
assert len(
|
assert not set(expected_result).symmetric_difference(
|
||||||
set(expected_result).symmetric_difference(
|
set(config.items("env:uno")))
|
||||||
set(config.items("env:uno")))) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_enable_auto_uploading(clirunner, validate_cliresult):
|
def test_init_enable_auto_uploading(clirunner, validate_cliresult):
|
||||||
@ -122,14 +122,11 @@ def test_init_enable_auto_uploading(clirunner, validate_cliresult):
|
|||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(getcwd())
|
validate_pioproject(getcwd())
|
||||||
config = util.load_project_config()
|
config = util.load_project_config()
|
||||||
expected_result = [
|
expected_result = [("platform", "atmelavr"), ("framework", "arduino"),
|
||||||
("platform", "atmelavr"), ("framework", "arduino"),
|
("board", "uno"), ("targets", "upload")]
|
||||||
("board", "uno"), ("targets", "upload")
|
|
||||||
]
|
|
||||||
assert config.has_section("env:uno")
|
assert config.has_section("env:uno")
|
||||||
assert len(
|
assert not set(expected_result).symmetric_difference(
|
||||||
set(expected_result).symmetric_difference(
|
set(config.items("env:uno")))
|
||||||
set(config.items("env:uno")))) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_custom_framework(clirunner, validate_cliresult):
|
def test_init_custom_framework(clirunner, validate_cliresult):
|
||||||
@ -139,14 +136,11 @@ def test_init_custom_framework(clirunner, validate_cliresult):
|
|||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_pioproject(getcwd())
|
validate_pioproject(getcwd())
|
||||||
config = util.load_project_config()
|
config = util.load_project_config()
|
||||||
expected_result = [
|
expected_result = [("platform", "teensy"), ("framework", "mbed"),
|
||||||
("platform", "teensy"), ("framework", "mbed"),
|
("board", "teensy31")]
|
||||||
("board", "teensy31")
|
|
||||||
]
|
|
||||||
assert config.has_section("env:teensy31")
|
assert config.has_section("env:teensy31")
|
||||||
assert len(
|
assert not set(expected_result).symmetric_difference(
|
||||||
set(expected_result).symmetric_difference(
|
set(config.items("env:teensy31")))
|
||||||
set(config.items("env:teensy31")))) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_init_incorrect_board(clirunner):
|
def test_init_incorrect_board(clirunner):
|
||||||
|
@ -15,8 +15,7 @@
|
|||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from platformio import exception, util
|
from platformio import exception
|
||||||
from platformio.commands.init import cli as cmd_init
|
|
||||||
from platformio.commands.lib import cli as cmd_lib
|
from platformio.commands.lib import cli as cmd_lib
|
||||||
|
|
||||||
|
|
||||||
@ -36,25 +35,11 @@ def test_search(clirunner, validate_cliresult):
|
|||||||
def test_global_install_registry(clirunner, validate_cliresult,
|
def test_global_install_registry(clirunner, validate_cliresult,
|
||||||
isolated_pio_home):
|
isolated_pio_home):
|
||||||
result = clirunner.invoke(cmd_lib, [
|
result = clirunner.invoke(cmd_lib, [
|
||||||
"-g", "install", "58", "547@2.2.4", "DallasTemperature",
|
"-g", "install", "64", "ArduinoJson@~5.10.0", "547@2.2.4",
|
||||||
"http://dl.platformio.org/libraries/archives/3/5174.tar.gz",
|
"AsyncMqttClient@<=0.8.2", "999@77d4eb3f8a"
|
||||||
"ArduinoJson@5.6.7", "ArduinoJson@~5.7.0", "168@00589a3250"
|
|
||||||
])
|
])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
|
|
||||||
# check lib with duplicate URL
|
|
||||||
result = clirunner.invoke(cmd_lib, [
|
|
||||||
"-g", "install",
|
|
||||||
"http://dl.platformio.org/libraries/archives/3/5174.tar.gz"
|
|
||||||
])
|
|
||||||
validate_cliresult(result)
|
|
||||||
assert "is already installed" in result.output
|
|
||||||
|
|
||||||
# check lib with duplicate ID
|
|
||||||
result = clirunner.invoke(cmd_lib, ["-g", "install", "305"])
|
|
||||||
validate_cliresult(result)
|
|
||||||
assert "is already installed" in result.output
|
|
||||||
|
|
||||||
# install unknown library
|
# install unknown library
|
||||||
result = clirunner.invoke(cmd_lib, ["-g", "install", "Unknown"])
|
result = clirunner.invoke(cmd_lib, ["-g", "install", "Unknown"])
|
||||||
assert result.exit_code != 0
|
assert result.exit_code != 0
|
||||||
@ -62,9 +47,9 @@ def test_global_install_registry(clirunner, validate_cliresult,
|
|||||||
|
|
||||||
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
||||||
items2 = [
|
items2 = [
|
||||||
"ArduinoJson_ID64", "ArduinoJson_ID64@5.6.7", "DallasTemperature_ID54",
|
"ArduinoJson_ID64", "ArduinoJson_ID64@5.10.1", "NeoPixelBus_ID547",
|
||||||
"DHT22_ID58", "ESPAsyncTCP_ID305", "NeoPixelBus_ID547", "OneWire_ID1",
|
"AsyncMqttClient_ID346", "ESPAsyncTCP_ID305", "AsyncTCP_ID1826",
|
||||||
"EspSoftwareSerial_ID168"
|
"RFcontrol_ID999"
|
||||||
]
|
]
|
||||||
assert set(items1) == set(items2)
|
assert set(items1) == set(items2)
|
||||||
|
|
||||||
@ -72,11 +57,12 @@ def test_global_install_registry(clirunner, validate_cliresult,
|
|||||||
def test_global_install_archive(clirunner, validate_cliresult,
|
def test_global_install_archive(clirunner, validate_cliresult,
|
||||||
isolated_pio_home):
|
isolated_pio_home):
|
||||||
result = clirunner.invoke(cmd_lib, [
|
result = clirunner.invoke(cmd_lib, [
|
||||||
"-g", "install", "https://github.com/adafruit/Adafruit-ST7735-Library/"
|
"-g", "install",
|
||||||
"archive/master.zip",
|
|
||||||
"http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip",
|
"http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip",
|
||||||
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip",
|
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip",
|
||||||
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip@5.8.2"
|
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip@5.8.2",
|
||||||
|
"http://dl.platformio.org/libraries/archives/0/9540.tar.gz",
|
||||||
|
"https://github.com/adafruit/Adafruit-ST7735-Library/archive/master.zip"
|
||||||
])
|
])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
|
|
||||||
@ -87,16 +73,11 @@ def test_global_install_archive(clirunner, validate_cliresult,
|
|||||||
])
|
])
|
||||||
assert result.exit_code != 0
|
assert result.exit_code != 0
|
||||||
|
|
||||||
# check lib with duplicate URL
|
|
||||||
result = clirunner.invoke(cmd_lib, [
|
|
||||||
"-g", "install",
|
|
||||||
"http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip"
|
|
||||||
])
|
|
||||||
validate_cliresult(result)
|
|
||||||
assert "is already installed" in result.output
|
|
||||||
|
|
||||||
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
||||||
items2 = ["Adafruit ST7735 Library", "RadioHead-1.62"]
|
items2 = [
|
||||||
|
"RadioHead-1.62", "ArduinoJson", "DallasTemperature_ID54",
|
||||||
|
"OneWire_ID1", "Adafruit ST7735 Library"
|
||||||
|
]
|
||||||
assert set(items1) >= set(items2)
|
assert set(items1) >= set(items2)
|
||||||
|
|
||||||
|
|
||||||
@ -113,18 +94,41 @@ def test_global_install_repository(clirunner, validate_cliresult,
|
|||||||
"https://gitlab.com/ivankravets/rs485-nodeproto.git",
|
"https://gitlab.com/ivankravets/rs485-nodeproto.git",
|
||||||
"https://github.com/platformio/platformio-libmirror.git",
|
"https://github.com/platformio/platformio-libmirror.git",
|
||||||
# "https://developer.mbed.org/users/simon/code/TextLCD/",
|
# "https://developer.mbed.org/users/simon/code/TextLCD/",
|
||||||
"knolleary/pubsubclient"
|
"knolleary/pubsubclient#bef58148582f956dfa772687db80c44e2279a163"
|
||||||
])
|
])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
||||||
items2 = [
|
items2 = [
|
||||||
"PJON", "PJON@src-79de467ebe19de18287becff0a1fb42d",
|
"PJON", "PJON@src-79de467ebe19de18287becff0a1fb42d",
|
||||||
"ArduinoJson@src-69ebddd821f771debe7ee734d3c7fa81", "rs485-nodeproto",
|
"ArduinoJson@src-69ebddd821f771debe7ee734d3c7fa81", "rs485-nodeproto",
|
||||||
"PubSubClient"
|
"platformio-libmirror", "PubSubClient"
|
||||||
]
|
]
|
||||||
assert set(items1) >= set(items2)
|
assert set(items1) >= set(items2)
|
||||||
|
|
||||||
# check lib with duplicate URL
|
|
||||||
|
def test_install_duplicates(clirunner, validate_cliresult, without_internet):
|
||||||
|
# registry
|
||||||
|
result = clirunner.invoke(cmd_lib, [
|
||||||
|
"-g", "install",
|
||||||
|
"http://dl.platformio.org/libraries/archives/0/9540.tar.gz"
|
||||||
|
])
|
||||||
|
validate_cliresult(result)
|
||||||
|
assert "is already installed" in result.output
|
||||||
|
|
||||||
|
# by ID
|
||||||
|
result = clirunner.invoke(cmd_lib, ["-g", "install", "999"])
|
||||||
|
validate_cliresult(result)
|
||||||
|
assert "is already installed" in result.output
|
||||||
|
|
||||||
|
# archive
|
||||||
|
result = clirunner.invoke(cmd_lib, [
|
||||||
|
"-g", "install",
|
||||||
|
"http://www.airspayce.com/mikem/arduino/RadioHead/RadioHead-1.62.zip"
|
||||||
|
])
|
||||||
|
validate_cliresult(result)
|
||||||
|
assert "is already installed" in result.output
|
||||||
|
|
||||||
|
# repository
|
||||||
result = clirunner.invoke(cmd_lib, [
|
result = clirunner.invoke(cmd_lib, [
|
||||||
"-g", "install",
|
"-g", "install",
|
||||||
"https://github.com/platformio/platformio-libmirror.git"
|
"https://github.com/platformio/platformio-libmirror.git"
|
||||||
@ -136,23 +140,42 @@ def test_global_install_repository(clirunner, validate_cliresult,
|
|||||||
def test_global_lib_list(clirunner, validate_cliresult):
|
def test_global_lib_list(clirunner, validate_cliresult):
|
||||||
result = clirunner.invoke(cmd_lib, ["-g", "list"])
|
result = clirunner.invoke(cmd_lib, ["-g", "list"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert all([n in result.output for n in ("OneWire", "DHT22", "64")])
|
assert all([
|
||||||
|
n in result.output for n in
|
||||||
|
("Source: https://github.com/adafruit/Adafruit-ST7735-Library/archive/master.zip",
|
||||||
|
"Version: 5.10.1",
|
||||||
|
"Source: git+https://github.com/gioblu/PJON.git#3.0",
|
||||||
|
"Version: 1fb26fd", "RadioHead-1.62")
|
||||||
|
])
|
||||||
|
|
||||||
result = clirunner.invoke(cmd_lib, ["-g", "list", "--json-output"])
|
result = clirunner.invoke(cmd_lib, ["-g", "list", "--json-output"])
|
||||||
assert all([
|
assert all([
|
||||||
n in result.output
|
n in result.output for n in
|
||||||
for n in (
|
("__pkg_dir",
|
||||||
"PJON", "git+https://github.com/knolleary/pubsubclient",
|
'"__src_url": "git+https://gitlab.com/ivankravets/rs485-nodeproto.git"',
|
||||||
"https://github.com/bblanchon/ArduinoJson/archive/v5.8.2.zip")
|
'"version": "5.10.1"')
|
||||||
])
|
])
|
||||||
items1 = [i['name'] for i in json.loads(result.output)]
|
items1 = [i['name'] for i in json.loads(result.output)]
|
||||||
items2 = [
|
items2 = [
|
||||||
"OneWire", "DHT22", "PJON", "ESPAsyncTCP", "ArduinoJson",
|
"Adafruit ST7735 Library", "ArduinoJson", "ArduinoJson", "ArduinoJson",
|
||||||
"PubSubClient", "rs485-nodeproto", "Adafruit ST7735 Library",
|
"ArduinoJson", "AsyncMqttClient", "AsyncTCP", "DallasTemperature",
|
||||||
"RadioHead-1.62", "DallasTemperature", "NeoPixelBus",
|
"ESPAsyncTCP", "NeoPixelBus", "OneWire", "PJON", "PJON",
|
||||||
"EspSoftwareSerial", "platformio-libmirror"
|
"PubSubClient", "RFcontrol", "RadioHead-1.62", "platformio-libmirror",
|
||||||
|
"rs485-nodeproto"
|
||||||
]
|
]
|
||||||
assert set(items1) == set(items2)
|
assert sorted(items1) == sorted(items2)
|
||||||
|
|
||||||
|
versions1 = [
|
||||||
|
"{name}@{version}".format(**item)
|
||||||
|
for item in json.loads(result.output)
|
||||||
|
]
|
||||||
|
versions2 = [
|
||||||
|
'ArduinoJson@5.8.2', 'ArduinoJson@5.10.1', 'AsyncMqttClient@0.8.2',
|
||||||
|
'AsyncTCP@1.0.1', 'ESPAsyncTCP@1.1.3', 'NeoPixelBus@2.2.4',
|
||||||
|
'PJON@07fe9aa', 'PJON@1fb26fd', 'PubSubClient@bef5814',
|
||||||
|
'RFcontrol@77d4eb3f8a', 'RadioHead-1.62@0.0.0'
|
||||||
|
]
|
||||||
|
assert set(versions1) >= set(versions2)
|
||||||
|
|
||||||
|
|
||||||
def test_global_lib_update_check(clirunner, validate_cliresult):
|
def test_global_lib_update_check(clirunner, validate_cliresult):
|
||||||
@ -160,7 +183,7 @@ def test_global_lib_update_check(clirunner, validate_cliresult):
|
|||||||
cmd_lib, ["-g", "update", "--only-check", "--json-output"])
|
cmd_lib, ["-g", "update", "--only-check", "--json-output"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
output = json.loads(result.output)
|
output = json.loads(result.output)
|
||||||
assert set(["ArduinoJson", "EspSoftwareSerial",
|
assert set(["RFcontrol",
|
||||||
"NeoPixelBus"]) == set([l['name'] for l in output])
|
"NeoPixelBus"]) == set([l['name'] for l in output])
|
||||||
|
|
||||||
|
|
||||||
@ -181,11 +204,9 @@ def test_global_lib_update(clirunner, validate_cliresult):
|
|||||||
# update rest libraries
|
# update rest libraries
|
||||||
result = clirunner.invoke(cmd_lib, ["-g", "update"])
|
result = clirunner.invoke(cmd_lib, ["-g", "update"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
validate_cliresult(result)
|
assert result.output.count("[Fixed]") == 6
|
||||||
assert result.output.count("[Fixed]") == 5
|
assert result.output.count("[Up-to-date]") == 11
|
||||||
assert result.output.count("[Up-to-date]") == 10
|
assert "Uninstalling RFcontrol @ 77d4eb3f8a" in result.output
|
||||||
assert "Uninstalling ArduinoJson @ 5.7.3" in result.output
|
|
||||||
assert "Uninstalling EspSoftwareSerial @ 00589a3250" in result.output
|
|
||||||
|
|
||||||
# update unknown library
|
# update unknown library
|
||||||
result = clirunner.invoke(cmd_lib, ["-g", "update", "Unknown"])
|
result = clirunner.invoke(cmd_lib, ["-g", "update", "Unknown"])
|
||||||
@ -207,16 +228,17 @@ def test_global_lib_uninstall(clirunner, validate_cliresult,
|
|||||||
# uninstall the rest libraries
|
# uninstall the rest libraries
|
||||||
result = clirunner.invoke(cmd_lib, [
|
result = clirunner.invoke(cmd_lib, [
|
||||||
"-g", "uninstall", "1", "https://github.com/bblanchon/ArduinoJson.git",
|
"-g", "uninstall", "1", "https://github.com/bblanchon/ArduinoJson.git",
|
||||||
"ArduinoJson@!=5.6.7", "EspSoftwareSerial@>=3.3.1"
|
"ArduinoJson@!=5.6.7", "RFcontrol"
|
||||||
])
|
])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
|
|
||||||
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
items1 = [d.basename for d in isolated_pio_home.join("lib").listdir()]
|
||||||
items2 = [
|
items2 = [
|
||||||
"ArduinoJson_ID64", "ArduinoJson_ID64@5.6.7", "DallasTemperature_ID54",
|
"RadioHead-1.62", "rs485-nodeproto", "platformio-libmirror",
|
||||||
"DHT22_ID58", "ESPAsyncTCP_ID305", "NeoPixelBus_ID547", "PJON",
|
"PubSubClient", "ArduinoJson@src-69ebddd821f771debe7ee734d3c7fa81",
|
||||||
"PJON@src-79de467ebe19de18287becff0a1fb42d", "PubSubClient",
|
"ESPAsyncTCP_ID305", "DallasTemperature_ID54", "NeoPixelBus_ID547",
|
||||||
"RadioHead-1.62", "rs485-nodeproto", "platformio-libmirror"
|
"PJON", "AsyncMqttClient_ID346", "ArduinoJson_ID64",
|
||||||
|
"PJON@src-79de467ebe19de18287becff0a1fb42d", "AsyncTCP_ID1826"
|
||||||
]
|
]
|
||||||
assert set(items1) == set(items2)
|
assert set(items1) == set(items2)
|
||||||
|
|
||||||
@ -248,7 +270,7 @@ def test_lib_stats(clirunner, validate_cliresult):
|
|||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert all([
|
assert all([
|
||||||
s in result.output
|
s in result.output
|
||||||
for s in ("UPDATED", "ago", "http://platformio.org/lib/show")
|
for s in ("UPDATED", "POPULAR", "http://platformio.org/lib/show")
|
||||||
])
|
])
|
||||||
|
|
||||||
result = clirunner.invoke(cmd_lib, ["stats", "--json-output"])
|
result = clirunner.invoke(cmd_lib, ["stats", "--json-output"])
|
||||||
|
@ -24,27 +24,25 @@ def test_search_json_output(clirunner, validate_cliresult, isolated_pio_home):
|
|||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
search_result = json.loads(result.output)
|
search_result = json.loads(result.output)
|
||||||
assert isinstance(search_result, list)
|
assert isinstance(search_result, list)
|
||||||
assert len(search_result)
|
assert search_result
|
||||||
platforms = [item['name'] for item in search_result]
|
platforms = [item['name'] for item in search_result]
|
||||||
assert "atmelsam" in platforms
|
assert "atmelsam" in platforms
|
||||||
|
|
||||||
|
|
||||||
def test_search_raw_output(clirunner, validate_cliresult, isolated_pio_home):
|
def test_search_raw_output(clirunner, validate_cliresult):
|
||||||
result = clirunner.invoke(cli_platform.platform_search, ["arduino"])
|
result = clirunner.invoke(cli_platform.platform_search, ["arduino"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert "teensy" in result.output
|
assert "teensy" in result.output
|
||||||
|
|
||||||
|
|
||||||
def test_install_unknown_version(clirunner, validate_cliresult,
|
def test_install_unknown_version(clirunner):
|
||||||
isolated_pio_home):
|
|
||||||
result = clirunner.invoke(cli_platform.platform_install,
|
result = clirunner.invoke(cli_platform.platform_install,
|
||||||
["atmelavr@99.99.99"])
|
["atmelavr@99.99.99"])
|
||||||
assert result.exit_code == -1
|
assert result.exit_code == -1
|
||||||
assert isinstance(result.exception, exception.UndefinedPackageVersion)
|
assert isinstance(result.exception, exception.UndefinedPackageVersion)
|
||||||
|
|
||||||
|
|
||||||
def test_install_unknown_from_registry(clirunner, validate_cliresult,
|
def test_install_unknown_from_registry(clirunner):
|
||||||
isolated_pio_home):
|
|
||||||
result = clirunner.invoke(cli_platform.platform_install,
|
result = clirunner.invoke(cli_platform.platform_install,
|
||||||
["unknown-platform"])
|
["unknown-platform"])
|
||||||
assert result.exit_code == -1
|
assert result.exit_code == -1
|
||||||
@ -63,7 +61,7 @@ def test_install_known_version(clirunner, validate_cliresult,
|
|||||||
assert len(isolated_pio_home.join("packages").listdir()) == 1
|
assert len(isolated_pio_home.join("packages").listdir()) == 1
|
||||||
|
|
||||||
|
|
||||||
def test_install_from_vcs(clirunner, validate_cliresult, isolated_pio_home):
|
def test_install_from_vcs(clirunner, validate_cliresult):
|
||||||
result = clirunner.invoke(cli_platform.platform_install, [
|
result = clirunner.invoke(cli_platform.platform_install, [
|
||||||
"https://github.com/platformio/"
|
"https://github.com/platformio/"
|
||||||
"platform-espressif8266.git#feature/stage", "--skip-default-package"
|
"platform-espressif8266.git#feature/stage", "--skip-default-package"
|
||||||
@ -72,17 +70,17 @@ def test_install_from_vcs(clirunner, validate_cliresult, isolated_pio_home):
|
|||||||
assert "espressif8266" in result.output
|
assert "espressif8266" in result.output
|
||||||
|
|
||||||
|
|
||||||
def test_list_json_output(clirunner, validate_cliresult, isolated_pio_home):
|
def test_list_json_output(clirunner, validate_cliresult):
|
||||||
result = clirunner.invoke(cli_platform.platform_list, ["--json-output"])
|
result = clirunner.invoke(cli_platform.platform_list, ["--json-output"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
list_result = json.loads(result.output)
|
list_result = json.loads(result.output)
|
||||||
assert isinstance(list_result, list)
|
assert isinstance(list_result, list)
|
||||||
assert len(list_result)
|
assert list_result
|
||||||
platforms = [item['name'] for item in list_result]
|
platforms = [item['name'] for item in list_result]
|
||||||
assert set(["atmelavr", "espressif8266"]) == set(platforms)
|
assert set(["atmelavr", "espressif8266"]) == set(platforms)
|
||||||
|
|
||||||
|
|
||||||
def test_list_raw_output(clirunner, validate_cliresult, isolated_pio_home):
|
def test_list_raw_output(clirunner, validate_cliresult):
|
||||||
result = clirunner.invoke(cli_platform.platform_list)
|
result = clirunner.invoke(cli_platform.platform_list)
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert all(
|
assert all(
|
||||||
@ -111,4 +109,4 @@ def test_uninstall(clirunner, validate_cliresult, isolated_pio_home):
|
|||||||
result = clirunner.invoke(cli_platform.platform_uninstall,
|
result = clirunner.invoke(cli_platform.platform_uninstall,
|
||||||
["atmelavr", "espressif8266"])
|
["atmelavr", "espressif8266"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert len(isolated_pio_home.join("platforms").listdir()) == 0
|
assert not isolated_pio_home.join("platforms").listdir()
|
||||||
|
@ -19,6 +19,6 @@ from platformio.commands.settings import cli
|
|||||||
def test_settings_check(clirunner, validate_cliresult):
|
def test_settings_check(clirunner, validate_cliresult):
|
||||||
result = clirunner.invoke(cli, ["get"])
|
result = clirunner.invoke(cli, ["get"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert len(result.output)
|
assert result.output
|
||||||
for item in app.DEFAULT_SETTINGS.items():
|
for item in app.DEFAULT_SETTINGS.items():
|
||||||
assert item[0] in result.output
|
assert item[0] in result.output
|
||||||
|
@ -16,11 +16,7 @@ from platformio.commands.update import cli as cmd_update
|
|||||||
|
|
||||||
|
|
||||||
def test_update(clirunner, validate_cliresult):
|
def test_update(clirunner, validate_cliresult):
|
||||||
matches = (
|
matches = ("Platform Manager", "Up-to-date", "Library Manager")
|
||||||
"Platform Manager",
|
|
||||||
"Up-to-date",
|
|
||||||
"Library Manager"
|
|
||||||
)
|
|
||||||
result = clirunner.invoke(cmd_update, ["--only-check"])
|
result = clirunner.invoke(cmd_update, ["--only-check"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert all([m in result.output for m in matches])
|
assert all([m in result.output for m in matches])
|
||||||
|
@ -17,10 +17,7 @@ import os
|
|||||||
import pytest
|
import pytest
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
|
|
||||||
|
from platformio import util
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def clirunner():
|
|
||||||
return CliRunner()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
@ -33,6 +30,11 @@ def validate_cliresult():
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def clirunner():
|
||||||
|
return CliRunner()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
def isolated_pio_home(request, tmpdir_factory):
|
def isolated_pio_home(request, tmpdir_factory):
|
||||||
home_dir = tmpdir_factory.mktemp(".platformio")
|
home_dir = tmpdir_factory.mktemp(".platformio")
|
||||||
@ -43,3 +45,8 @@ def isolated_pio_home(request, tmpdir_factory):
|
|||||||
|
|
||||||
request.addfinalizer(fin)
|
request.addfinalizer(fin)
|
||||||
return home_dir
|
return home_dir
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="function")
|
||||||
|
def without_internet(monkeypatch):
|
||||||
|
monkeypatch.setattr(util, "_internet_on", lambda: False)
|
||||||
|
@ -36,26 +36,27 @@ def pytest_generate_tests(metafunc):
|
|||||||
|
|
||||||
@pytest.mark.examples
|
@pytest.mark.examples
|
||||||
def test_run(pioproject_dir):
|
def test_run(pioproject_dir):
|
||||||
if isdir(join(pioproject_dir, ".pioenvs")):
|
with util.cd(pioproject_dir):
|
||||||
util.rmtree_(join(pioproject_dir, ".pioenvs"))
|
build_dir = util.get_projectbuild_dir()
|
||||||
|
if isdir(build_dir):
|
||||||
|
util.rmtree_(build_dir)
|
||||||
|
|
||||||
result = util.exec_command(
|
result = util.exec_command(["platformio", "--force", "run"])
|
||||||
["platformio", "--force", "run", "--project-dir", pioproject_dir]
|
if result['returncode'] != 0:
|
||||||
)
|
pytest.fail(result)
|
||||||
if result['returncode'] != 0:
|
|
||||||
pytest.fail(result)
|
|
||||||
|
|
||||||
# check .elf file
|
assert isdir(build_dir)
|
||||||
pioenvs_dir = join(pioproject_dir, ".pioenvs")
|
|
||||||
for item in listdir(pioenvs_dir):
|
# check .elf file
|
||||||
if not isdir(item):
|
for item in listdir(build_dir):
|
||||||
continue
|
if not isdir(item):
|
||||||
assert isfile(join(pioenvs_dir, item, "firmware.elf"))
|
continue
|
||||||
# check .hex or .bin files
|
assert isfile(join(build_dir, item, "firmware.elf"))
|
||||||
firmwares = []
|
# check .hex or .bin files
|
||||||
for ext in ("bin", "hex"):
|
firmwares = []
|
||||||
firmwares += glob(join(pioenvs_dir, item, "firmware*.%s" % ext))
|
for ext in ("bin", "hex"):
|
||||||
if not firmwares:
|
firmwares += glob(join(build_dir, item, "firmware*.%s" % ext))
|
||||||
pytest.fail("Missed firmware file")
|
if not firmwares:
|
||||||
for firmware in firmwares:
|
pytest.fail("Missed firmware file")
|
||||||
assert getsize(firmware) > 0
|
for firmware in firmwares:
|
||||||
|
assert getsize(firmware) > 0
|
||||||
|
@ -57,8 +57,7 @@ def test_after_upgrade_2_to_3(clirunner, validate_cliresult,
|
|||||||
assert board_ids == set([b['id'] for b in json.loads(result.output)])
|
assert board_ids == set([b['id'] for b in json.loads(result.output)])
|
||||||
|
|
||||||
|
|
||||||
def test_after_upgrade_silence(clirunner, validate_cliresult,
|
def test_after_upgrade_silence(clirunner, validate_cliresult):
|
||||||
isolated_pio_home):
|
|
||||||
app.set_state_item("last_version", "2.11.2")
|
app.set_state_item("last_version", "2.11.2")
|
||||||
result = clirunner.invoke(cli_pio, ["boards", "--json-output"])
|
result = clirunner.invoke(cli_pio, ["boards", "--json-output"])
|
||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
@ -66,7 +65,7 @@ def test_after_upgrade_silence(clirunner, validate_cliresult,
|
|||||||
assert any([b['id'] == "uno" for b in boards])
|
assert any([b['id'] == "uno" for b in boards])
|
||||||
|
|
||||||
|
|
||||||
def test_check_pio_upgrade(clirunner, validate_cliresult, isolated_pio_home):
|
def test_check_pio_upgrade(clirunner, validate_cliresult):
|
||||||
|
|
||||||
def _patch_pio_version(version):
|
def _patch_pio_version(version):
|
||||||
maintenance.__version__ = version
|
maintenance.__version__ = version
|
||||||
@ -96,7 +95,7 @@ def test_check_pio_upgrade(clirunner, validate_cliresult, isolated_pio_home):
|
|||||||
_patch_pio_version(origin_version)
|
_patch_pio_version(origin_version)
|
||||||
|
|
||||||
|
|
||||||
def test_check_lib_updates(clirunner, validate_cliresult, isolated_pio_home):
|
def test_check_lib_updates(clirunner, validate_cliresult):
|
||||||
# install obsolete library
|
# install obsolete library
|
||||||
result = clirunner.invoke(cli_pio,
|
result = clirunner.invoke(cli_pio,
|
||||||
["lib", "-g", "install", "ArduinoJson@<5.7"])
|
["lib", "-g", "install", "ArduinoJson@<5.7"])
|
||||||
@ -113,8 +112,7 @@ def test_check_lib_updates(clirunner, validate_cliresult, isolated_pio_home):
|
|||||||
result.output)
|
result.output)
|
||||||
|
|
||||||
|
|
||||||
def test_check_and_update_libraries(clirunner, validate_cliresult,
|
def test_check_and_update_libraries(clirunner, validate_cliresult):
|
||||||
isolated_pio_home):
|
|
||||||
# enable library auto-updates
|
# enable library auto-updates
|
||||||
result = clirunner.invoke(
|
result = clirunner.invoke(
|
||||||
cli_pio, ["settings", "set", "auto_update_libraries", "Yes"])
|
cli_pio, ["settings", "set", "auto_update_libraries", "Yes"])
|
||||||
@ -168,8 +166,7 @@ def test_check_platform_updates(clirunner, validate_cliresult,
|
|||||||
assert "There are the new updates for platforms (native)" in result.output
|
assert "There are the new updates for platforms (native)" in result.output
|
||||||
|
|
||||||
|
|
||||||
def test_check_and_update_platforms(clirunner, validate_cliresult,
|
def test_check_and_update_platforms(clirunner, validate_cliresult):
|
||||||
isolated_pio_home):
|
|
||||||
# enable library auto-updates
|
# enable library auto-updates
|
||||||
result = clirunner.invoke(
|
result = clirunner.invoke(
|
||||||
cli_pio, ["settings", "set", "auto_update_platforms", "Yes"])
|
cli_pio, ["settings", "set", "auto_update_platforms", "Yes"])
|
||||||
@ -190,8 +187,7 @@ def test_check_and_update_platforms(clirunner, validate_cliresult,
|
|||||||
validate_cliresult(result)
|
validate_cliresult(result)
|
||||||
assert "There are the new updates for platforms (native)" in result.output
|
assert "There are the new updates for platforms (native)" in result.output
|
||||||
assert "Please wait while updating platforms" in result.output
|
assert "Please wait while updating platforms" in result.output
|
||||||
assert re.search(r"Updating native\s+@ 0.0.0\s+\[[\d\.]+\]",
|
assert re.search(r"Updating native\s+@ 0.0.0\s+\[[\d\.]+\]", result.output)
|
||||||
result.output)
|
|
||||||
|
|
||||||
# check updated version
|
# check updated version
|
||||||
result = clirunner.invoke(cli_pio, ["platform", "list", "--json-output"])
|
result = clirunner.invoke(cli_pio, ["platform", "list", "--json-output"])
|
||||||
|
@ -186,7 +186,7 @@ def test_install_packages(isolated_pio_home, tmpdir):
|
|||||||
"packages").listdir()]) == set(pkg_dirnames)
|
"packages").listdir()]) == set(pkg_dirnames)
|
||||||
|
|
||||||
|
|
||||||
def test_get_package(isolated_pio_home):
|
def test_get_package():
|
||||||
tests = [
|
tests = [
|
||||||
[("unknown", ), None],
|
[("unknown", ), None],
|
||||||
[("1", ), None],
|
[("1", ), None],
|
||||||
|
@ -12,11 +12,25 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import pytest
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from platformio import util
|
from platformio import exception, util
|
||||||
|
|
||||||
|
|
||||||
def test_ping_internet_ips():
|
def test_ping_internet_ips():
|
||||||
for ip in util.PING_INTERNET_IPS:
|
for ip in util.PING_INTERNET_IPS:
|
||||||
requests.get("http://%s" % ip, allow_redirects=False, timeout=2)
|
requests.get("http://%s" % ip, allow_redirects=False, timeout=2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_internet_offline(without_internet, isolated_pio_home):
|
||||||
|
with pytest.raises(exception.InternetIsOffline):
|
||||||
|
util.get_api_result("/stats")
|
||||||
|
|
||||||
|
|
||||||
|
def test_api_cache(monkeypatch, isolated_pio_home):
|
||||||
|
api_kwargs = {"url": "/stats", "cache_valid": "10s"}
|
||||||
|
result = util.get_api_result(**api_kwargs)
|
||||||
|
assert result and "boards" in result
|
||||||
|
monkeypatch.setattr(util, '_internet_on', lambda: False)
|
||||||
|
assert util.get_api_result(**api_kwargs) == result
|
||||||
|
Reference in New Issue
Block a user