forked from platformio/platformio-core
Introduce Black to automate code formatting
This commit is contained in:
1 parent
5e144a2c98
commit
7c41c7c2f3
90 files changed
+4064
-3367
No files matched your search
+26
-25
@@ -25,13 +25,12 @@ from platformio.project.helpers import get_project_packages_dir
|
||||
|
||||
CORE_PACKAGES = {
|
||||
"contrib-piohome": "^2.3.2",
|
||||
"contrib-pysite":
|
||||
"~2.%d%d.190418" % (sys.version_info[0], sys.version_info[1]),
|
||||
"contrib-pysite": "~2.%d%d.190418" % (sys.version_info[0], sys.version_info[1]),
|
||||
"tool-pioplus": "^2.5.2",
|
||||
"tool-unity": "~1.20403.0",
|
||||
"tool-scons": "~2.20501.7" if PY2 else "~3.30101.0",
|
||||
"tool-cppcheck": "~1.189.0",
|
||||
"tool-clangtidy": "^1.80000.0"
|
||||
"tool-clangtidy": "^1.80000.0",
|
||||
}
|
||||
|
||||
PIOPLUS_AUTO_UPDATES_MAX = 100
|
||||
@@ -40,20 +39,19 @@ PIOPLUS_AUTO_UPDATES_MAX = 100
|
||||
|
||||
|
||||
class CorePackageManager(PackageManager):
|
||||
|
||||
def __init__(self):
|
||||
super(CorePackageManager, self).__init__(get_project_packages_dir(), [
|
||||
"https://dl.bintray.com/platformio/dl-packages/manifest.json",
|
||||
"http%s://dl.platformio.org/packages/manifest.json" %
|
||||
("" if sys.version_info < (2, 7, 9) else "s")
|
||||
])
|
||||
super(CorePackageManager, self).__init__(
|
||||
get_project_packages_dir(),
|
||||
[
|
||||
"https://dl.bintray.com/platformio/dl-packages/manifest.json",
|
||||
"http%s://dl.platformio.org/packages/manifest.json"
|
||||
% ("" if sys.version_info < (2, 7, 9) else "s"),
|
||||
],
|
||||
)
|
||||
|
||||
def install( # pylint: disable=keyword-arg-before-vararg
|
||||
self,
|
||||
name,
|
||||
requirements=None,
|
||||
*args,
|
||||
**kwargs):
|
||||
self, name, requirements=None, *args, **kwargs
|
||||
):
|
||||
PackageManager.install(self, name, requirements, *args, **kwargs)
|
||||
self.cleanup_packages()
|
||||
return self.get_package_dir(name, requirements)
|
||||
@@ -70,12 +68,12 @@ class CorePackageManager(PackageManager):
|
||||
pkg_dir = self.get_package_dir(name, requirements)
|
||||
if not pkg_dir:
|
||||
continue
|
||||
best_pkg_versions[name] = self.load_manifest(pkg_dir)['version']
|
||||
best_pkg_versions[name] = self.load_manifest(pkg_dir)["version"]
|
||||
for manifest in self.get_installed():
|
||||
if manifest['name'] not in best_pkg_versions:
|
||||
if manifest["name"] not in best_pkg_versions:
|
||||
continue
|
||||
if manifest['version'] != best_pkg_versions[manifest['name']]:
|
||||
self.uninstall(manifest['__pkg_dir'], after_update=True)
|
||||
if manifest["version"] != best_pkg_versions[manifest["name"]]:
|
||||
self.uninstall(manifest["__pkg_dir"], after_update=True)
|
||||
self.cache_reset()
|
||||
return True
|
||||
|
||||
@@ -104,6 +102,7 @@ def update_core_packages(only_check=False, silent=False):
|
||||
|
||||
def inject_contrib_pysite():
|
||||
from site import addsitedir
|
||||
|
||||
contrib_pysite_dir = get_core_package_dir("contrib-pysite")
|
||||
if contrib_pysite_dir in sys.path:
|
||||
return
|
||||
@@ -116,16 +115,18 @@ def pioplus_call(args, **kwargs):
|
||||
raise exception.PlatformioException(
|
||||
"PlatformIO Core Plus v%s does not run under Python version %s.\n"
|
||||
"Minimum supported version is 2.7.6, please upgrade Python.\n"
|
||||
"Python 3 is not yet supported.\n" % (__version__, sys.version))
|
||||
"Python 3 is not yet supported.\n" % (__version__, sys.version)
|
||||
)
|
||||
|
||||
pioplus_path = join(get_core_package_dir("tool-pioplus"), "pioplus")
|
||||
pythonexe_path = get_pythonexe_path()
|
||||
os.environ['PYTHONEXEPATH'] = pythonexe_path
|
||||
os.environ['PYTHONPYSITEDIR'] = get_core_package_dir("contrib-pysite")
|
||||
os.environ['PIOCOREPYSITEDIR'] = dirname(fs.get_source_dir() or "")
|
||||
if dirname(pythonexe_path) not in os.environ['PATH'].split(os.pathsep):
|
||||
os.environ['PATH'] = (os.pathsep).join(
|
||||
[dirname(pythonexe_path), os.environ['PATH']])
|
||||
os.environ["PYTHONEXEPATH"] = pythonexe_path
|
||||
os.environ["PYTHONPYSITEDIR"] = get_core_package_dir("contrib-pysite")
|
||||
os.environ["PIOCOREPYSITEDIR"] = dirname(fs.get_source_dir() or "")
|
||||
if dirname(pythonexe_path) not in os.environ["PATH"].split(os.pathsep):
|
||||
os.environ["PATH"] = (os.pathsep).join(
|
||||
[dirname(pythonexe_path), os.environ["PATH"]]
|
||||
)
|
||||
copy_pythonpath_to_osenv()
|
||||
code = subprocess.call([pioplus_path] + args, **kwargs)
|
||||
|
||||
|
||||
+163
-145
@@ -41,10 +41,7 @@ class LibraryManager(BasePkgManager):
|
||||
|
||||
@property
|
||||
def manifest_names(self):
|
||||
return [
|
||||
".library.json", "library.json", "library.properties",
|
||||
"module.json"
|
||||
]
|
||||
return [".library.json", "library.json", "library.properties", "module.json"]
|
||||
|
||||
def get_manifest_path(self, pkg_dir):
|
||||
path = BasePkgManager.get_manifest_path(self, pkg_dir)
|
||||
@@ -71,36 +68,37 @@ class LibraryManager(BasePkgManager):
|
||||
|
||||
# if Arduino library.properties
|
||||
if "sentence" in manifest:
|
||||
manifest['frameworks'] = ["arduino"]
|
||||
manifest['description'] = manifest['sentence']
|
||||
del manifest['sentence']
|
||||
manifest["frameworks"] = ["arduino"]
|
||||
manifest["description"] = manifest["sentence"]
|
||||
del manifest["sentence"]
|
||||
|
||||
if "author" in manifest:
|
||||
if isinstance(manifest['author'], dict):
|
||||
manifest['authors'] = [manifest['author']]
|
||||
if isinstance(manifest["author"], dict):
|
||||
manifest["authors"] = [manifest["author"]]
|
||||
else:
|
||||
manifest['authors'] = [{"name": manifest['author']}]
|
||||
del manifest['author']
|
||||
manifest["authors"] = [{"name": manifest["author"]}]
|
||||
del manifest["author"]
|
||||
|
||||
if "authors" in manifest and not isinstance(manifest['authors'], list):
|
||||
manifest['authors'] = [manifest['authors']]
|
||||
if "authors" in manifest and not isinstance(manifest["authors"], list):
|
||||
manifest["authors"] = [manifest["authors"]]
|
||||
|
||||
if "keywords" not in manifest:
|
||||
keywords = []
|
||||
for keyword in re.split(r"[\s/]+",
|
||||
manifest.get("category", "Uncategorized")):
|
||||
for keyword in re.split(
|
||||
r"[\s/]+", manifest.get("category", "Uncategorized")
|
||||
):
|
||||
keyword = keyword.strip()
|
||||
if not keyword:
|
||||
continue
|
||||
keywords.append(keyword.lower())
|
||||
manifest['keywords'] = keywords
|
||||
manifest["keywords"] = keywords
|
||||
if "category" in manifest:
|
||||
del manifest['category']
|
||||
del manifest["category"]
|
||||
|
||||
# don't replace VCS URL
|
||||
if "url" in manifest and "description" in manifest:
|
||||
manifest['homepage'] = manifest['url']
|
||||
del manifest['url']
|
||||
manifest["homepage"] = manifest["url"]
|
||||
del manifest["url"]
|
||||
|
||||
if "architectures" in manifest:
|
||||
platforms = []
|
||||
@@ -110,26 +108,23 @@ class LibraryManager(BasePkgManager):
|
||||
"samd": "atmelsam",
|
||||
"esp8266": "espressif8266",
|
||||
"esp32": "espressif32",
|
||||
"arc32": "intel_arc32"
|
||||
"arc32": "intel_arc32",
|
||||
}
|
||||
for arch in manifest['architectures'].split(","):
|
||||
for arch in manifest["architectures"].split(","):
|
||||
arch = arch.strip()
|
||||
if arch == "*":
|
||||
platforms = "*"
|
||||
break
|
||||
if arch in platforms_map:
|
||||
platforms.append(platforms_map[arch])
|
||||
manifest['platforms'] = platforms
|
||||
del manifest['architectures']
|
||||
manifest["platforms"] = platforms
|
||||
del manifest["architectures"]
|
||||
|
||||
# convert listed items via comma to array
|
||||
for key in ("keywords", "frameworks", "platforms"):
|
||||
if key not in manifest or \
|
||||
not isinstance(manifest[key], string_types):
|
||||
if key not in manifest or not isinstance(manifest[key], string_types):
|
||||
continue
|
||||
manifest[key] = [
|
||||
i.strip() for i in manifest[key].split(",") if i.strip()
|
||||
]
|
||||
manifest[key] = [i.strip() for i in manifest[key].split(",") if i.strip()]
|
||||
|
||||
return manifest
|
||||
|
||||
@@ -153,13 +148,10 @@ class LibraryManager(BasePkgManager):
|
||||
if item[k] == "*":
|
||||
del item[k]
|
||||
elif isinstance(item[k], string_types):
|
||||
item[k] = [
|
||||
i.strip() for i in item[k].split(",") if i.strip()
|
||||
]
|
||||
item[k] = [i.strip() for i in item[k].split(",") if i.strip()]
|
||||
return items
|
||||
|
||||
def max_satisfying_repo_version(self, versions, requirements=None):
|
||||
|
||||
def _cmp_dates(datestr1, datestr2):
|
||||
date1 = util.parse_date(datestr1)
|
||||
date2 = util.parse_date(datestr2)
|
||||
@@ -169,61 +161,66 @@ class LibraryManager(BasePkgManager):
|
||||
|
||||
semver_spec = None
|
||||
try:
|
||||
semver_spec = semantic_version.SimpleSpec(
|
||||
requirements) if requirements else None
|
||||
semver_spec = (
|
||||
semantic_version.SimpleSpec(requirements) if requirements else None
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
item = {}
|
||||
|
||||
for v in versions:
|
||||
semver_new = self.parse_semver_version(v['name'])
|
||||
semver_new = self.parse_semver_version(v["name"])
|
||||
if semver_spec:
|
||||
if not semver_new or semver_new not in semver_spec:
|
||||
continue
|
||||
if not item or self.parse_semver_version(
|
||||
item['name']) < semver_new:
|
||||
if not item or self.parse_semver_version(item["name"]) < semver_new:
|
||||
item = v
|
||||
elif requirements:
|
||||
if requirements == v['name']:
|
||||
if requirements == v["name"]:
|
||||
return v
|
||||
|
||||
else:
|
||||
if not item or _cmp_dates(item['released'],
|
||||
v['released']) == -1:
|
||||
if not item or _cmp_dates(item["released"], v["released"]) == -1:
|
||||
item = v
|
||||
return item
|
||||
|
||||
def get_latest_repo_version(self, name, requirements, silent=False):
|
||||
item = self.max_satisfying_repo_version(
|
||||
util.get_api_result("/lib/info/%d" % self.search_lib_id(
|
||||
{
|
||||
"name": name,
|
||||
"requirements": requirements
|
||||
}, silent=silent),
|
||||
cache_valid="1h")['versions'], requirements)
|
||||
return item['name'] if item else None
|
||||
util.get_api_result(
|
||||
"/lib/info/%d"
|
||||
% self.search_lib_id(
|
||||
{"name": name, "requirements": requirements}, silent=silent
|
||||
),
|
||||
cache_valid="1h",
|
||||
)["versions"],
|
||||
requirements,
|
||||
)
|
||||
return item["name"] if item else None
|
||||
|
||||
def _install_from_piorepo(self, name, requirements):
|
||||
assert name.startswith("id="), name
|
||||
version = self.get_latest_repo_version(name, requirements)
|
||||
if not version:
|
||||
raise exception.UndefinedPackageVersion(requirements or "latest",
|
||||
util.get_systype())
|
||||
dl_data = util.get_api_result("/lib/download/" + str(name[3:]),
|
||||
dict(version=version),
|
||||
cache_valid="30d")
|
||||
raise exception.UndefinedPackageVersion(
|
||||
requirements or "latest", util.get_systype()
|
||||
)
|
||||
dl_data = util.get_api_result(
|
||||
"/lib/download/" + str(name[3:]), dict(version=version), cache_valid="30d"
|
||||
)
|
||||
assert dl_data
|
||||
|
||||
return self._install_from_url(
|
||||
name, dl_data['url'].replace("http://", "https://")
|
||||
if app.get_setting("strict_ssl") else dl_data['url'], requirements)
|
||||
name,
|
||||
dl_data["url"].replace("http://", "https://")
|
||||
if app.get_setting("strict_ssl")
|
||||
else dl_data["url"],
|
||||
requirements,
|
||||
)
|
||||
|
||||
def search_lib_id( # pylint: disable=too-many-branches
|
||||
self,
|
||||
filters,
|
||||
silent=False,
|
||||
interactive=False):
|
||||
self, filters, silent=False, interactive=False
|
||||
):
|
||||
assert isinstance(filters, dict)
|
||||
assert "name" in filters
|
||||
|
||||
@@ -234,8 +231,10 @@ class LibraryManager(BasePkgManager):
|
||||
|
||||
# looking in PIO Library Registry
|
||||
if not silent:
|
||||
click.echo("Looking for %s library in registry" %
|
||||
click.style(filters['name'], fg="cyan"))
|
||||
click.echo(
|
||||
"Looking for %s library in registry"
|
||||
% click.style(filters["name"], fg="cyan")
|
||||
)
|
||||
query = []
|
||||
for key in filters:
|
||||
if key not in ("name", "authors", "frameworks", "platforms"):
|
||||
@@ -244,25 +243,29 @@ class LibraryManager(BasePkgManager):
|
||||
if not isinstance(values, list):
|
||||
values = [v.strip() for v in values.split(",") if v]
|
||||
for value in values:
|
||||
query.append('%s:"%s"' %
|
||||
(key[:-1] if key.endswith("s") else key, value))
|
||||
query.append(
|
||||
'%s:"%s"' % (key[:-1] if key.endswith("s") else key, value)
|
||||
)
|
||||
|
||||
lib_info = None
|
||||
result = util.get_api_result("/v2/lib/search",
|
||||
dict(query=" ".join(query)),
|
||||
cache_valid="1h")
|
||||
if result['total'] == 1:
|
||||
lib_info = result['items'][0]
|
||||
elif result['total'] > 1:
|
||||
result = util.get_api_result(
|
||||
"/v2/lib/search", dict(query=" ".join(query)), cache_valid="1h"
|
||||
)
|
||||
if result["total"] == 1:
|
||||
lib_info = result["items"][0]
|
||||
elif result["total"] > 1:
|
||||
if silent and not interactive:
|
||||
lib_info = result['items'][0]
|
||||
lib_info = result["items"][0]
|
||||
else:
|
||||
click.secho("Conflict: More than one library has been found "
|
||||
"by request %s:" % json.dumps(filters),
|
||||
fg="yellow",
|
||||
err=True)
|
||||
click.secho(
|
||||
"Conflict: More than one library has been found "
|
||||
"by request %s:" % json.dumps(filters),
|
||||
fg="yellow",
|
||||
err=True,
|
||||
)
|
||||
from platformio.commands.lib import print_lib_item
|
||||
for item in result['items']:
|
||||
|
||||
for item in result["items"]:
|
||||
print_lib_item(item)
|
||||
|
||||
if not interactive:
|
||||
@@ -270,36 +273,39 @@ class LibraryManager(BasePkgManager):
|
||||
"Automatically chose the first available library "
|
||||
"(use `--interactive` option to make a choice)",
|
||||
fg="yellow",
|
||||
err=True)
|
||||
lib_info = result['items'][0]
|
||||
err=True,
|
||||
)
|
||||
lib_info = result["items"][0]
|
||||
else:
|
||||
deplib_id = click.prompt("Please choose library ID",
|
||||
type=click.Choice([
|
||||
str(i['id'])
|
||||
for i in result['items']
|
||||
]))
|
||||
for item in result['items']:
|
||||
if item['id'] == int(deplib_id):
|
||||
deplib_id = click.prompt(
|
||||
"Please choose library ID",
|
||||
type=click.Choice([str(i["id"]) for i in result["items"]]),
|
||||
)
|
||||
for item in result["items"]:
|
||||
if item["id"] == int(deplib_id):
|
||||
lib_info = item
|
||||
break
|
||||
|
||||
if not lib_info:
|
||||
if list(filters) == ["name"]:
|
||||
raise exception.LibNotFound(filters['name'])
|
||||
raise exception.LibNotFound(filters["name"])
|
||||
raise exception.LibNotFound(str(filters))
|
||||
if not silent:
|
||||
click.echo("Found: %s" % click.style(
|
||||
"https://platformio.org/lib/show/{id}/{name}".format(
|
||||
**lib_info),
|
||||
fg="blue"))
|
||||
return int(lib_info['id'])
|
||||
click.echo(
|
||||
"Found: %s"
|
||||
% click.style(
|
||||
"https://platformio.org/lib/show/{id}/{name}".format(**lib_info),
|
||||
fg="blue",
|
||||
)
|
||||
)
|
||||
return int(lib_info["id"])
|
||||
|
||||
def _get_lib_id_from_installed(self, filters):
|
||||
if filters['name'].startswith("id="):
|
||||
return int(filters['name'][3:])
|
||||
if filters["name"].startswith("id="):
|
||||
return int(filters["name"][3:])
|
||||
package_dir = self.get_package_dir(
|
||||
filters['name'], filters.get("requirements",
|
||||
filters.get("version")))
|
||||
filters["name"], filters.get("requirements", filters.get("version"))
|
||||
)
|
||||
if not package_dir:
|
||||
return None
|
||||
manifest = self.load_manifest(package_dir)
|
||||
@@ -311,52 +317,55 @@ class LibraryManager(BasePkgManager):
|
||||
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])):
|
||||
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']
|
||||
manifest_authors = manifest["authors"]
|
||||
if not isinstance(manifest_authors, list):
|
||||
manifest_authors = [manifest_authors]
|
||||
manifest_authors = [
|
||||
a['name'] for a in manifest_authors
|
||||
a["name"]
|
||||
for a in manifest_authors
|
||||
if isinstance(a, dict) and "name" in a
|
||||
]
|
||||
filter_authors = filters['authors']
|
||||
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'])
|
||||
return int(manifest["id"])
|
||||
|
||||
def install( # pylint: disable=arguments-differ
|
||||
self,
|
||||
name,
|
||||
requirements=None,
|
||||
silent=False,
|
||||
after_update=False,
|
||||
interactive=False,
|
||||
force=False):
|
||||
self,
|
||||
name,
|
||||
requirements=None,
|
||||
silent=False,
|
||||
after_update=False,
|
||||
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
|
||||
},
|
||||
{"name": _name, "requirements": _requirements},
|
||||
silent=silent,
|
||||
interactive=interactive)
|
||||
interactive=interactive,
|
||||
)
|
||||
requirements = _requirements
|
||||
pkg_dir = BasePkgManager.install(self,
|
||||
name,
|
||||
requirements,
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
force=force)
|
||||
pkg_dir = BasePkgManager.install(
|
||||
self,
|
||||
name,
|
||||
requirements,
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
force=force,
|
||||
)
|
||||
|
||||
if not pkg_dir:
|
||||
return None
|
||||
@@ -369,7 +378,7 @@ class LibraryManager(BasePkgManager):
|
||||
click.secho("Installing dependencies", fg="yellow")
|
||||
|
||||
builtin_lib_storages = None
|
||||
for filters in self.normalize_dependencies(manifest['dependencies']):
|
||||
for filters in self.normalize_dependencies(manifest["dependencies"]):
|
||||
assert "name" in filters
|
||||
|
||||
# avoid circle dependencies
|
||||
@@ -381,35 +390,42 @@ class LibraryManager(BasePkgManager):
|
||||
self.INSTALL_HISTORY.append(history_key)
|
||||
|
||||
if any(s in filters.get("version", "") for s in ("\\", "/")):
|
||||
self.install("{name}={version}".format(**filters),
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
interactive=interactive,
|
||||
force=force)
|
||||
self.install(
|
||||
"{name}={version}".format(**filters),
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
interactive=interactive,
|
||||
force=force,
|
||||
)
|
||||
else:
|
||||
try:
|
||||
lib_id = self.search_lib_id(filters, silent, interactive)
|
||||
except exception.LibNotFound as e:
|
||||
if builtin_lib_storages is None:
|
||||
builtin_lib_storages = get_builtin_libs()
|
||||
if not silent or is_builtin_lib(builtin_lib_storages,
|
||||
filters['name']):
|
||||
if not silent or is_builtin_lib(
|
||||
builtin_lib_storages, filters["name"]
|
||||
):
|
||||
click.secho("Warning! %s" % e, fg="yellow")
|
||||
continue
|
||||
|
||||
if filters.get("version"):
|
||||
self.install(lib_id,
|
||||
filters.get("version"),
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
interactive=interactive,
|
||||
force=force)
|
||||
self.install(
|
||||
lib_id,
|
||||
filters.get("version"),
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
interactive=interactive,
|
||||
force=force,
|
||||
)
|
||||
else:
|
||||
self.install(lib_id,
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
interactive=interactive,
|
||||
force=force)
|
||||
self.install(
|
||||
lib_id,
|
||||
silent=silent,
|
||||
after_update=after_update,
|
||||
interactive=interactive,
|
||||
force=force,
|
||||
)
|
||||
return pkg_dir
|
||||
|
||||
|
||||
@@ -418,21 +434,23 @@ def get_builtin_libs(storage_names=None):
|
||||
storage_names = storage_names or []
|
||||
pm = PlatformManager()
|
||||
for manifest in pm.get_installed():
|
||||
p = PlatformFactory.newPlatform(manifest['__pkg_dir'])
|
||||
p = PlatformFactory.newPlatform(manifest["__pkg_dir"])
|
||||
for storage in p.get_lib_storages():
|
||||
if storage_names and storage['name'] not in storage_names:
|
||||
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()
|
||||
})
|
||||
lm = LibraryManager(storage["path"])
|
||||
items.append(
|
||||
{
|
||||
"name": storage["name"],
|
||||
"path": storage["path"],
|
||||
"items": lm.get_installed(),
|
||||
}
|
||||
)
|
||||
return items
|
||||
|
||||
|
||||
def is_builtin_lib(storages, name):
|
||||
for storage in storages or []:
|
||||
if any(l.get("name") == name for l in storage['items']):
|
||||
if any(l.get("name") == name for l in storage["items"]):
|
||||
return True
|
||||
return False
|
||||
+147
-138
@@ -36,7 +36,6 @@ from platformio.vcsclient import VCSClientFactory
|
||||
|
||||
|
||||
class PackageRepoIterator(object):
|
||||
|
||||
def __init__(self, package, repositories):
|
||||
assert isinstance(repositories, list)
|
||||
self.package = package
|
||||
@@ -87,8 +86,9 @@ class PkgRepoMixin(object):
|
||||
item = None
|
||||
reqspec = None
|
||||
try:
|
||||
reqspec = semantic_version.SimpleSpec(
|
||||
requirements) if requirements else None
|
||||
reqspec = (
|
||||
semantic_version.SimpleSpec(requirements) if requirements else None
|
||||
)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
@@ -99,33 +99,32 @@ class PkgRepoMixin(object):
|
||||
# if PkgRepoMixin.PIO_VERSION not in requirements.SimpleSpec(
|
||||
# v['engines']['platformio']):
|
||||
# continue
|
||||
specver = semantic_version.Version(v['version'])
|
||||
specver = semantic_version.Version(v["version"])
|
||||
if reqspec and specver not in reqspec:
|
||||
continue
|
||||
if not item or semantic_version.Version(item['version']) < specver:
|
||||
if not item or semantic_version.Version(item["version"]) < specver:
|
||||
item = v
|
||||
return item
|
||||
|
||||
def get_latest_repo_version( # pylint: disable=unused-argument
|
||||
self,
|
||||
name,
|
||||
requirements,
|
||||
silent=False):
|
||||
self, name, requirements, silent=False
|
||||
):
|
||||
version = None
|
||||
for versions in PackageRepoIterator(name, self.repositories):
|
||||
pkgdata = self.max_satisfying_repo_version(versions, requirements)
|
||||
if not pkgdata:
|
||||
continue
|
||||
if not version or semantic_version.compare(pkgdata['version'],
|
||||
version) == 1:
|
||||
version = pkgdata['version']
|
||||
if (
|
||||
not version
|
||||
or semantic_version.compare(pkgdata["version"], version) == 1
|
||||
):
|
||||
version = pkgdata["version"]
|
||||
return version
|
||||
|
||||
def get_all_repo_versions(self, name):
|
||||
result = []
|
||||
for versions in PackageRepoIterator(name, self.repositories):
|
||||
result.extend(
|
||||
[semantic_version.Version(v['version']) for v in versions])
|
||||
result.extend([semantic_version.Version(v["version"]) for v in versions])
|
||||
return [str(v) for v in sorted(set(result))]
|
||||
|
||||
|
||||
@@ -154,7 +153,8 @@ class PkgInstallerMixin(object):
|
||||
if result:
|
||||
return result
|
||||
result = [
|
||||
join(src_dir, name) for name in sorted(os.listdir(src_dir))
|
||||
join(src_dir, name)
|
||||
for name in sorted(os.listdir(src_dir))
|
||||
if isdir(join(src_dir, name))
|
||||
]
|
||||
self.cache_set(cache_key, result)
|
||||
@@ -189,14 +189,17 @@ class PkgInstallerMixin(object):
|
||||
click.secho(
|
||||
"Error: Please read http://bit.ly/package-manager-ioerror",
|
||||
fg="red",
|
||||
err=True)
|
||||
err=True,
|
||||
)
|
||||
raise e
|
||||
|
||||
if sha1:
|
||||
fd.verify(sha1)
|
||||
dst_path = fd.get_filepath()
|
||||
if not self.FILE_CACHE_VALID or getsize(
|
||||
dst_path) > PkgInstallerMixin.FILE_CACHE_MAX_SIZE:
|
||||
if (
|
||||
not self.FILE_CACHE_VALID
|
||||
or getsize(dst_path) > PkgInstallerMixin.FILE_CACHE_MAX_SIZE
|
||||
):
|
||||
return dst_path
|
||||
|
||||
with app.ContentCache() as cc:
|
||||
@@ -232,15 +235,15 @@ class PkgInstallerMixin(object):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def parse_pkg_uri( # pylint: disable=too-many-branches
|
||||
text, requirements=None):
|
||||
def parse_pkg_uri(text, requirements=None): # pylint: disable=too-many-branches
|
||||
text = str(text)
|
||||
name, url = None, None
|
||||
|
||||
# Parse requirements
|
||||
req_conditions = [
|
||||
"@" in text, not requirements, ":" not in text
|
||||
or text.rfind("/") < text.rfind("@")
|
||||
"@" in text,
|
||||
not requirements,
|
||||
":" not in text or text.rfind("/") < text.rfind("@"),
|
||||
]
|
||||
if all(req_conditions):
|
||||
text, requirements = text.rsplit("@", 1)
|
||||
@@ -259,17 +262,16 @@ class PkgInstallerMixin(object):
|
||||
elif "/" in text or "\\" in text:
|
||||
git_conditions = [
|
||||
# Handle GitHub URL (https://github.com/user/package)
|
||||
text.startswith("https://github.com/") and not text.endswith(
|
||||
(".zip", ".tar.gz")),
|
||||
(text.split("#", 1)[0]
|
||||
if "#" in text else text).endswith(".git")
|
||||
text.startswith("https://github.com/")
|
||||
and not text.endswith((".zip", ".tar.gz")),
|
||||
(text.split("#", 1)[0] if "#" in text else text).endswith(".git"),
|
||||
]
|
||||
hg_conditions = [
|
||||
# Handle Developer Mbed URL
|
||||
# (https://developer.mbed.org/users/user/code/package/)
|
||||
# (https://os.mbed.com/users/user/code/package/)
|
||||
text.startswith("https://developer.mbed.org"),
|
||||
text.startswith("https://os.mbed.com")
|
||||
text.startswith("https://os.mbed.com"),
|
||||
]
|
||||
if any(git_conditions):
|
||||
url = "git+" + text
|
||||
@@ -296,9 +298,9 @@ class PkgInstallerMixin(object):
|
||||
|
||||
@staticmethod
|
||||
def get_install_dirname(manifest):
|
||||
name = re.sub(r"[^\da-z\_\-\. ]", "_", manifest['name'], flags=re.I)
|
||||
name = re.sub(r"[^\da-z\_\-\. ]", "_", manifest["name"], flags=re.I)
|
||||
if "id" in manifest:
|
||||
name += "_ID%d" % manifest['id']
|
||||
name += "_ID%d" % manifest["id"]
|
||||
return str(name)
|
||||
|
||||
@classmethod
|
||||
@@ -322,8 +324,7 @@ class PkgInstallerMixin(object):
|
||||
return None
|
||||
|
||||
def manifest_exists(self, pkg_dir):
|
||||
return self.get_manifest_path(pkg_dir) or \
|
||||
self.get_src_manifest_path(pkg_dir)
|
||||
return self.get_manifest_path(pkg_dir) or self.get_src_manifest_path(pkg_dir)
|
||||
|
||||
def load_manifest(self, pkg_dir):
|
||||
cache_key = "load_manifest-%s" % pkg_dir
|
||||
@@ -353,19 +354,19 @@ class PkgInstallerMixin(object):
|
||||
|
||||
if src_manifest:
|
||||
if "version" in src_manifest:
|
||||
manifest['version'] = src_manifest['version']
|
||||
manifest['__src_url'] = src_manifest['url']
|
||||
manifest["version"] = src_manifest["version"]
|
||||
manifest["__src_url"] = src_manifest["url"]
|
||||
# handle a custom package name
|
||||
autogen_name = self.parse_pkg_uri(manifest['__src_url'])[0]
|
||||
if "name" not in manifest or autogen_name != src_manifest['name']:
|
||||
manifest['name'] = src_manifest['name']
|
||||
autogen_name = self.parse_pkg_uri(manifest["__src_url"])[0]
|
||||
if "name" not in manifest or autogen_name != src_manifest["name"]:
|
||||
manifest["name"] = src_manifest["name"]
|
||||
|
||||
if "name" not in manifest:
|
||||
manifest['name'] = basename(pkg_dir)
|
||||
manifest["name"] = basename(pkg_dir)
|
||||
if "version" not in manifest:
|
||||
manifest['version'] = "0.0.0"
|
||||
manifest["version"] = "0.0.0"
|
||||
|
||||
manifest['__pkg_dir'] = pkg_dir
|
||||
manifest["__pkg_dir"] = pkg_dir
|
||||
self.cache_set(cache_key, manifest)
|
||||
return manifest
|
||||
|
||||
@@ -390,25 +391,24 @@ class PkgInstallerMixin(object):
|
||||
continue
|
||||
elif pkg_id and manifest.get("id") != pkg_id:
|
||||
continue
|
||||
elif not pkg_id and manifest['name'] != name:
|
||||
elif not pkg_id and manifest["name"] != name:
|
||||
continue
|
||||
elif not PkgRepoMixin.is_system_compatible(manifest.get("system")):
|
||||
continue
|
||||
|
||||
# strict version or VCS HASH
|
||||
if requirements and requirements == manifest['version']:
|
||||
if requirements and requirements == manifest["version"]:
|
||||
return manifest
|
||||
|
||||
try:
|
||||
if requirements and not semantic_version.SimpleSpec(
|
||||
requirements).match(
|
||||
self.parse_semver_version(manifest['version'],
|
||||
raise_exception=True)):
|
||||
if requirements and not semantic_version.SimpleSpec(requirements).match(
|
||||
self.parse_semver_version(manifest["version"], raise_exception=True)
|
||||
):
|
||||
continue
|
||||
elif not best or (self.parse_semver_version(
|
||||
manifest['version'], raise_exception=True) >
|
||||
self.parse_semver_version(
|
||||
best['version'], raise_exception=True)):
|
||||
elif not best or (
|
||||
self.parse_semver_version(manifest["version"], raise_exception=True)
|
||||
> self.parse_semver_version(best["version"], raise_exception=True)
|
||||
):
|
||||
best = manifest
|
||||
except ValueError:
|
||||
pass
|
||||
@@ -417,12 +417,15 @@ class PkgInstallerMixin(object):
|
||||
|
||||
def get_package_dir(self, name, requirements=None, url=None):
|
||||
manifest = self.get_package(name, requirements, url)
|
||||
return manifest.get("__pkg_dir") if manifest and isdir(
|
||||
manifest.get("__pkg_dir")) else None
|
||||
return (
|
||||
manifest.get("__pkg_dir")
|
||||
if manifest and isdir(manifest.get("__pkg_dir"))
|
||||
else None
|
||||
)
|
||||
|
||||
def get_package_by_dir(self, pkg_dir):
|
||||
for manifest in self.get_installed():
|
||||
if manifest['__pkg_dir'] == abspath(pkg_dir):
|
||||
if manifest["__pkg_dir"] == abspath(pkg_dir):
|
||||
return manifest
|
||||
return None
|
||||
|
||||
@@ -443,9 +446,9 @@ class PkgInstallerMixin(object):
|
||||
if not pkgdata:
|
||||
continue
|
||||
try:
|
||||
pkg_dir = self._install_from_url(name, pkgdata['url'],
|
||||
requirements,
|
||||
pkgdata.get("sha1"))
|
||||
pkg_dir = self._install_from_url(
|
||||
name, pkgdata["url"], requirements, pkgdata.get("sha1")
|
||||
)
|
||||
break
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
click.secho("Warning! Package Mirror: %s" % e, fg="yellow")
|
||||
@@ -455,16 +458,12 @@ class PkgInstallerMixin(object):
|
||||
util.internet_on(raise_exception=True)
|
||||
raise exception.UnknownPackage(name)
|
||||
if not pkgdata:
|
||||
raise exception.UndefinedPackageVersion(requirements or "latest",
|
||||
util.get_systype())
|
||||
raise exception.UndefinedPackageVersion(
|
||||
requirements or "latest", util.get_systype()
|
||||
)
|
||||
return pkg_dir
|
||||
|
||||
def _install_from_url(self,
|
||||
name,
|
||||
url,
|
||||
requirements=None,
|
||||
sha1=None,
|
||||
track=False):
|
||||
def _install_from_url(self, name, url, requirements=None, sha1=None, track=False):
|
||||
tmp_dir = mkdtemp("-package", self.TMP_FOLDER_PREFIX, self.package_dir)
|
||||
src_manifest_dir = None
|
||||
src_manifest = {"name": name, "url": url, "requirements": requirements}
|
||||
@@ -486,7 +485,7 @@ class PkgInstallerMixin(object):
|
||||
vcs = VCSClientFactory.newClient(tmp_dir, url)
|
||||
assert vcs.export()
|
||||
src_manifest_dir = vcs.storage_dir
|
||||
src_manifest['version'] = vcs.get_current_revision()
|
||||
src_manifest["version"] = vcs.get_current_revision()
|
||||
|
||||
_tmp_dir = tmp_dir
|
||||
if not src_manifest_dir:
|
||||
@@ -515,7 +514,8 @@ class PkgInstallerMixin(object):
|
||||
json.dump(_data, fp)
|
||||
|
||||
def _install_from_tmp_dir( # pylint: disable=too-many-branches
|
||||
self, tmp_dir, requirements=None):
|
||||
self, tmp_dir, requirements=None
|
||||
):
|
||||
tmp_manifest = self.load_manifest(tmp_dir)
|
||||
assert set(["name", "version"]) <= set(tmp_manifest)
|
||||
|
||||
@@ -523,28 +523,30 @@ class PkgInstallerMixin(object):
|
||||
pkg_dir = join(self.package_dir, pkg_dirname)
|
||||
cur_manifest = self.load_manifest(pkg_dir)
|
||||
|
||||
tmp_semver = self.parse_semver_version(tmp_manifest['version'])
|
||||
tmp_semver = self.parse_semver_version(tmp_manifest["version"])
|
||||
cur_semver = None
|
||||
if cur_manifest:
|
||||
cur_semver = self.parse_semver_version(cur_manifest['version'])
|
||||
cur_semver = self.parse_semver_version(cur_manifest["version"])
|
||||
|
||||
# package should satisfy requirements
|
||||
if requirements:
|
||||
mismatch_error = (
|
||||
"Package version %s doesn't satisfy requirements %s" %
|
||||
(tmp_manifest['version'], requirements))
|
||||
mismatch_error = "Package version %s doesn't satisfy requirements %s" % (
|
||||
tmp_manifest["version"],
|
||||
requirements,
|
||||
)
|
||||
try:
|
||||
assert tmp_semver and tmp_semver in semantic_version.SimpleSpec(
|
||||
requirements), mismatch_error
|
||||
requirements
|
||||
), mismatch_error
|
||||
except (AssertionError, ValueError):
|
||||
assert tmp_manifest['version'] == requirements, mismatch_error
|
||||
assert tmp_manifest["version"] == requirements, mismatch_error
|
||||
|
||||
# check if package already exists
|
||||
if cur_manifest:
|
||||
# 0-overwrite, 1-rename, 2-fix to a version
|
||||
action = 0
|
||||
if "__src_url" in cur_manifest:
|
||||
if cur_manifest['__src_url'] != tmp_manifest.get("__src_url"):
|
||||
if cur_manifest["__src_url"] != tmp_manifest.get("__src_url"):
|
||||
action = 1
|
||||
elif "__src_url" in tmp_manifest:
|
||||
action = 2
|
||||
@@ -556,25 +558,25 @@ class PkgInstallerMixin(object):
|
||||
|
||||
# rename
|
||||
if action == 1:
|
||||
target_dirname = "%s@%s" % (pkg_dirname,
|
||||
cur_manifest['version'])
|
||||
target_dirname = "%s@%s" % (pkg_dirname, cur_manifest["version"])
|
||||
if "__src_url" in cur_manifest:
|
||||
target_dirname = "%s@src-%s" % (
|
||||
pkg_dirname,
|
||||
hashlib.md5(
|
||||
hashlib_encode_data(
|
||||
cur_manifest['__src_url'])).hexdigest())
|
||||
hashlib_encode_data(cur_manifest["__src_url"])
|
||||
).hexdigest(),
|
||||
)
|
||||
shutil.move(pkg_dir, join(self.package_dir, target_dirname))
|
||||
# fix to a version
|
||||
elif action == 2:
|
||||
target_dirname = "%s@%s" % (pkg_dirname,
|
||||
tmp_manifest['version'])
|
||||
target_dirname = "%s@%s" % (pkg_dirname, tmp_manifest["version"])
|
||||
if "__src_url" in tmp_manifest:
|
||||
target_dirname = "%s@src-%s" % (
|
||||
pkg_dirname,
|
||||
hashlib.md5(
|
||||
hashlib_encode_data(
|
||||
tmp_manifest['__src_url'])).hexdigest())
|
||||
hashlib_encode_data(tmp_manifest["__src_url"])
|
||||
).hexdigest(),
|
||||
)
|
||||
pkg_dir = join(self.package_dir, target_dirname)
|
||||
|
||||
# remove previous/not-satisfied package
|
||||
@@ -622,9 +624,9 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
|
||||
if "__src_url" in manifest:
|
||||
try:
|
||||
vcs = VCSClientFactory.newClient(pkg_dir,
|
||||
manifest['__src_url'],
|
||||
silent=True)
|
||||
vcs = VCSClientFactory.newClient(
|
||||
pkg_dir, manifest["__src_url"], silent=True
|
||||
)
|
||||
except (AttributeError, exception.PlatformioException):
|
||||
return None
|
||||
if not vcs.can_be_updated:
|
||||
@@ -633,10 +635,10 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
else:
|
||||
try:
|
||||
latest = self.get_latest_repo_version(
|
||||
"id=%d" %
|
||||
manifest['id'] if "id" in manifest else manifest['name'],
|
||||
"id=%d" % manifest["id"] if "id" in manifest else manifest["name"],
|
||||
requirements,
|
||||
silent=True)
|
||||
silent=True,
|
||||
)
|
||||
except (exception.PlatformioException, ValueError):
|
||||
return None
|
||||
|
||||
@@ -646,21 +648,17 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
up_to_date = False
|
||||
try:
|
||||
assert "__src_url" not in manifest
|
||||
up_to_date = (self.parse_semver_version(manifest['version'],
|
||||
raise_exception=True) >=
|
||||
self.parse_semver_version(latest,
|
||||
raise_exception=True))
|
||||
up_to_date = self.parse_semver_version(
|
||||
manifest["version"], raise_exception=True
|
||||
) >= self.parse_semver_version(latest, raise_exception=True)
|
||||
except (AssertionError, ValueError):
|
||||
up_to_date = latest == manifest['version']
|
||||
up_to_date = latest == manifest["version"]
|
||||
|
||||
return False if up_to_date else latest
|
||||
|
||||
def install(self,
|
||||
name,
|
||||
requirements=None,
|
||||
silent=False,
|
||||
after_update=False,
|
||||
force=False):
|
||||
def install(
|
||||
self, name, requirements=None, silent=False, after_update=False, force=False
|
||||
):
|
||||
pkg_dir = None
|
||||
# interprocess lock
|
||||
with LockFile(self.package_dir):
|
||||
@@ -690,34 +688,38 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
if not silent:
|
||||
click.secho(
|
||||
"{name} @ {version} is already installed".format(
|
||||
**self.load_manifest(package_dir)),
|
||||
fg="yellow")
|
||||
**self.load_manifest(package_dir)
|
||||
),
|
||||
fg="yellow",
|
||||
)
|
||||
return package_dir
|
||||
|
||||
if url:
|
||||
pkg_dir = self._install_from_url(name,
|
||||
url,
|
||||
requirements,
|
||||
track=True)
|
||||
pkg_dir = self._install_from_url(name, url, requirements, track=True)
|
||||
else:
|
||||
pkg_dir = self._install_from_piorepo(name, requirements)
|
||||
|
||||
if not pkg_dir or not self.manifest_exists(pkg_dir):
|
||||
raise exception.PackageInstallError(name, requirements or "*",
|
||||
util.get_systype())
|
||||
raise exception.PackageInstallError(
|
||||
name, requirements or "*", util.get_systype()
|
||||
)
|
||||
|
||||
manifest = self.load_manifest(pkg_dir)
|
||||
assert manifest
|
||||
|
||||
if not after_update:
|
||||
telemetry.on_event(category=self.__class__.__name__,
|
||||
action="Install",
|
||||
label=manifest['name'])
|
||||
telemetry.on_event(
|
||||
category=self.__class__.__name__,
|
||||
action="Install",
|
||||
label=manifest["name"],
|
||||
)
|
||||
|
||||
click.secho(
|
||||
"{name} @ {version} has been successfully installed!".format(
|
||||
**manifest),
|
||||
fg="green")
|
||||
**manifest
|
||||
),
|
||||
fg="green",
|
||||
)
|
||||
|
||||
return pkg_dir
|
||||
|
||||
@@ -729,18 +731,20 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
if isdir(package) and self.get_package_by_dir(package):
|
||||
pkg_dir = package
|
||||
else:
|
||||
name, requirements, url = self.parse_pkg_uri(
|
||||
package, requirements)
|
||||
name, requirements, url = self.parse_pkg_uri(package, requirements)
|
||||
pkg_dir = self.get_package_dir(name, requirements, url)
|
||||
|
||||
if not pkg_dir:
|
||||
raise exception.UnknownPackage("%s @ %s" %
|
||||
(package, requirements or "*"))
|
||||
raise exception.UnknownPackage(
|
||||
"%s @ %s" % (package, requirements or "*")
|
||||
)
|
||||
|
||||
manifest = self.load_manifest(pkg_dir)
|
||||
click.echo("Uninstalling %s @ %s: \t" % (click.style(
|
||||
manifest['name'], fg="cyan"), manifest['version']),
|
||||
nl=False)
|
||||
click.echo(
|
||||
"Uninstalling %s @ %s: \t"
|
||||
% (click.style(manifest["name"], fg="cyan"), manifest["version"]),
|
||||
nl=False,
|
||||
)
|
||||
|
||||
if islink(pkg_dir):
|
||||
os.unlink(pkg_dir)
|
||||
@@ -749,19 +753,21 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
self.cache_reset()
|
||||
|
||||
# unfix package with the same name
|
||||
pkg_dir = self.get_package_dir(manifest['name'])
|
||||
pkg_dir = self.get_package_dir(manifest["name"])
|
||||
if pkg_dir and "@" in pkg_dir:
|
||||
shutil.move(
|
||||
pkg_dir,
|
||||
join(self.package_dir, self.get_install_dirname(manifest)))
|
||||
pkg_dir, join(self.package_dir, self.get_install_dirname(manifest))
|
||||
)
|
||||
self.cache_reset()
|
||||
|
||||
click.echo("[%s]" % click.style("OK", fg="green"))
|
||||
|
||||
if not after_update:
|
||||
telemetry.on_event(category=self.__class__.__name__,
|
||||
action="Uninstall",
|
||||
label=manifest['name'])
|
||||
telemetry.on_event(
|
||||
category=self.__class__.__name__,
|
||||
action="Uninstall",
|
||||
label=manifest["name"],
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
@@ -773,16 +779,19 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
pkg_dir = self.get_package_dir(*self.parse_pkg_uri(package))
|
||||
|
||||
if not pkg_dir:
|
||||
raise exception.UnknownPackage("%s @ %s" %
|
||||
(package, requirements or "*"))
|
||||
raise exception.UnknownPackage("%s @ %s" % (package, requirements or "*"))
|
||||
|
||||
manifest = self.load_manifest(pkg_dir)
|
||||
name = manifest['name']
|
||||
name = manifest["name"]
|
||||
|
||||
click.echo("{} {:<40} @ {:<15}".format(
|
||||
"Checking" if only_check else "Updating",
|
||||
click.style(manifest['name'], fg="cyan"), manifest['version']),
|
||||
nl=False)
|
||||
click.echo(
|
||||
"{} {:<40} @ {:<15}".format(
|
||||
"Checking" if only_check else "Updating",
|
||||
click.style(manifest["name"], fg="cyan"),
|
||||
manifest["version"],
|
||||
),
|
||||
nl=False,
|
||||
)
|
||||
if not util.internet_on():
|
||||
click.echo("[%s]" % (click.style("Off-line", fg="yellow")))
|
||||
return None
|
||||
@@ -799,22 +808,22 @@ class BasePkgManager(PkgRepoMixin, PkgInstallerMixin):
|
||||
return True
|
||||
|
||||
if "__src_url" in manifest:
|
||||
vcs = VCSClientFactory.newClient(pkg_dir, manifest['__src_url'])
|
||||
vcs = VCSClientFactory.newClient(pkg_dir, manifest["__src_url"])
|
||||
assert vcs.update()
|
||||
self._update_src_manifest(dict(version=vcs.get_current_revision()),
|
||||
vcs.storage_dir)
|
||||
self._update_src_manifest(
|
||||
dict(version=vcs.get_current_revision()), vcs.storage_dir
|
||||
)
|
||||
else:
|
||||
self.uninstall(pkg_dir, after_update=True)
|
||||
self.install(name, latest, after_update=True)
|
||||
|
||||
telemetry.on_event(category=self.__class__.__name__,
|
||||
action="Update",
|
||||
label=manifest['name'])
|
||||
telemetry.on_event(
|
||||
category=self.__class__.__name__, action="Update", label=manifest["name"]
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
class PackageManager(BasePkgManager):
|
||||
|
||||
@property
|
||||
def manifest_names(self):
|
||||
return ["package.json"]
|
||||
+178
-165
@@ -26,13 +26,19 @@ from platformio import __version__, app, exception, fs, util
|
||||
from platformio.compat import PY2, hashlib_encode_data, is_bytes
|
||||
from platformio.managers.core import get_core_package_dir
|
||||
from platformio.managers.package import BasePkgManager, PackageManager
|
||||
from platformio.proc import (BuildAsyncPipe, copy_pythonpath_to_osenv,
|
||||
exec_command, get_pythonexe_path)
|
||||
from platformio.proc import (
|
||||
BuildAsyncPipe,
|
||||
copy_pythonpath_to_osenv,
|
||||
exec_command,
|
||||
get_pythonexe_path,
|
||||
)
|
||||
from platformio.project.config import ProjectConfig
|
||||
from platformio.project.helpers import (get_project_boards_dir,
|
||||
get_project_core_dir,
|
||||
get_project_packages_dir,
|
||||
get_project_platforms_dir)
|
||||
from platformio.project.helpers import (
|
||||
get_project_boards_dir,
|
||||
get_project_core_dir,
|
||||
get_project_packages_dir,
|
||||
get_project_platforms_dir,
|
||||
)
|
||||
|
||||
try:
|
||||
from urllib.parse import quote
|
||||
@@ -41,16 +47,17 @@ except ImportError:
|
||||
|
||||
|
||||
class PlatformManager(BasePkgManager):
|
||||
|
||||
def __init__(self, package_dir=None, repositories=None):
|
||||
if not repositories:
|
||||
repositories = [
|
||||
"https://dl.bintray.com/platformio/dl-platforms/manifest.json",
|
||||
"{0}://dl.platformio.org/platforms/manifest.json".format(
|
||||
"https" if app.get_setting("strict_ssl") else "http")
|
||||
"https" if app.get_setting("strict_ssl") else "http"
|
||||
),
|
||||
]
|
||||
BasePkgManager.__init__(self, package_dir
|
||||
or get_project_platforms_dir(), repositories)
|
||||
BasePkgManager.__init__(
|
||||
self, package_dir or get_project_platforms_dir(), repositories
|
||||
)
|
||||
|
||||
@property
|
||||
def manifest_names(self):
|
||||
@@ -65,21 +72,21 @@ class PlatformManager(BasePkgManager):
|
||||
return manifest_path
|
||||
return None
|
||||
|
||||
def install(self,
|
||||
name,
|
||||
requirements=None,
|
||||
with_packages=None,
|
||||
without_packages=None,
|
||||
skip_default_package=False,
|
||||
after_update=False,
|
||||
silent=False,
|
||||
force=False,
|
||||
**_): # pylint: disable=too-many-arguments, arguments-differ
|
||||
platform_dir = BasePkgManager.install(self,
|
||||
name,
|
||||
requirements,
|
||||
silent=silent,
|
||||
force=force)
|
||||
def install(
|
||||
self,
|
||||
name,
|
||||
requirements=None,
|
||||
with_packages=None,
|
||||
without_packages=None,
|
||||
skip_default_package=False,
|
||||
after_update=False,
|
||||
silent=False,
|
||||
force=False,
|
||||
**_
|
||||
): # pylint: disable=too-many-arguments, arguments-differ
|
||||
platform_dir = BasePkgManager.install(
|
||||
self, name, requirements, silent=silent, force=force
|
||||
)
|
||||
p = PlatformFactory.newPlatform(platform_dir)
|
||||
|
||||
# don't cleanup packages or install them after update
|
||||
@@ -87,11 +94,13 @@ class PlatformManager(BasePkgManager):
|
||||
if after_update:
|
||||
return True
|
||||
|
||||
p.install_packages(with_packages,
|
||||
without_packages,
|
||||
skip_default_package,
|
||||
silent=silent,
|
||||
force=force)
|
||||
p.install_packages(
|
||||
with_packages,
|
||||
without_packages,
|
||||
skip_default_package,
|
||||
silent=silent,
|
||||
force=force,
|
||||
)
|
||||
return self.cleanup_packages(list(p.packages))
|
||||
|
||||
def uninstall(self, package, requirements=None, after_update=False):
|
||||
@@ -115,11 +124,8 @@ class PlatformManager(BasePkgManager):
|
||||
return self.cleanup_packages(list(p.packages))
|
||||
|
||||
def update( # pylint: disable=arguments-differ
|
||||
self,
|
||||
package,
|
||||
requirements=None,
|
||||
only_check=False,
|
||||
only_packages=False):
|
||||
self, package, requirements=None, only_check=False, only_packages=False
|
||||
):
|
||||
if isdir(package):
|
||||
pkg_dir = package
|
||||
else:
|
||||
@@ -143,8 +149,9 @@ class PlatformManager(BasePkgManager):
|
||||
self.cleanup_packages(list(p.packages))
|
||||
|
||||
if missed_pkgs:
|
||||
p.install_packages(with_packages=list(missed_pkgs),
|
||||
skip_default_package=True)
|
||||
p.install_packages(
|
||||
with_packages=list(missed_pkgs), skip_default_package=True
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
@@ -152,20 +159,22 @@ class PlatformManager(BasePkgManager):
|
||||
self.cache_reset()
|
||||
deppkgs = {}
|
||||
for manifest in PlatformManager().get_installed():
|
||||
p = PlatformFactory.newPlatform(manifest['__pkg_dir'])
|
||||
p = PlatformFactory.newPlatform(manifest["__pkg_dir"])
|
||||
for pkgname, pkgmanifest in p.get_installed_packages().items():
|
||||
if pkgname not in deppkgs:
|
||||
deppkgs[pkgname] = set()
|
||||
deppkgs[pkgname].add(pkgmanifest['version'])
|
||||
deppkgs[pkgname].add(pkgmanifest["version"])
|
||||
|
||||
pm = PackageManager(get_project_packages_dir())
|
||||
for manifest in pm.get_installed():
|
||||
if manifest['name'] not in names:
|
||||
if manifest["name"] not in names:
|
||||
continue
|
||||
if (manifest['name'] not in deppkgs
|
||||
or manifest['version'] not in deppkgs[manifest['name']]):
|
||||
if (
|
||||
manifest["name"] not in deppkgs
|
||||
or manifest["version"] not in deppkgs[manifest["name"]]
|
||||
):
|
||||
try:
|
||||
pm.uninstall(manifest['__pkg_dir'], after_update=True)
|
||||
pm.uninstall(manifest["__pkg_dir"], after_update=True)
|
||||
except exception.UnknownPackage:
|
||||
pass
|
||||
|
||||
@@ -176,7 +185,7 @@ class PlatformManager(BasePkgManager):
|
||||
def get_installed_boards(self):
|
||||
boards = []
|
||||
for manifest in self.get_installed():
|
||||
p = PlatformFactory.newPlatform(manifest['__pkg_dir'])
|
||||
p = PlatformFactory.newPlatform(manifest["__pkg_dir"])
|
||||
for config in p.get_boards().values():
|
||||
board = config.get_brief_data()
|
||||
if board not in boards:
|
||||
@@ -189,30 +198,31 @@ class PlatformManager(BasePkgManager):
|
||||
|
||||
def get_all_boards(self):
|
||||
boards = self.get_installed_boards()
|
||||
know_boards = ["%s:%s" % (b['platform'], b['id']) for b in boards]
|
||||
know_boards = ["%s:%s" % (b["platform"], b["id"]) for b in boards]
|
||||
try:
|
||||
for board in self.get_registered_boards():
|
||||
key = "%s:%s" % (board['platform'], board['id'])
|
||||
key = "%s:%s" % (board["platform"], board["id"])
|
||||
if key not in know_boards:
|
||||
boards.append(board)
|
||||
except (exception.APIRequestError, exception.InternetIsOffline):
|
||||
pass
|
||||
return sorted(boards, key=lambda b: b['name'])
|
||||
return sorted(boards, key=lambda b: b["name"])
|
||||
|
||||
def board_config(self, id_, platform=None):
|
||||
for manifest in self.get_installed_boards():
|
||||
if manifest['id'] == id_ and (not platform
|
||||
or manifest['platform'] == platform):
|
||||
if manifest["id"] == id_ and (
|
||||
not platform or manifest["platform"] == platform
|
||||
):
|
||||
return manifest
|
||||
for manifest in self.get_registered_boards():
|
||||
if manifest['id'] == id_ and (not platform
|
||||
or manifest['platform'] == platform):
|
||||
if manifest["id"] == id_ and (
|
||||
not platform or manifest["platform"] == platform
|
||||
):
|
||||
return manifest
|
||||
raise exception.UnknownBoard(id_)
|
||||
|
||||
|
||||
class PlatformFactory(object):
|
||||
|
||||
@staticmethod
|
||||
def get_clsname(name):
|
||||
name = re.sub(r"[^\da-z\_]+", "", name, flags=re.I)
|
||||
@@ -222,8 +232,7 @@ class PlatformFactory(object):
|
||||
def load_module(name, path):
|
||||
module = None
|
||||
try:
|
||||
module = load_source("platformio.managers.platform.%s" % name,
|
||||
path)
|
||||
module = load_source("platformio.managers.platform.%s" % name, path)
|
||||
except ImportError:
|
||||
raise exception.UnknownPlatform(name)
|
||||
return module
|
||||
@@ -234,28 +243,29 @@ class PlatformFactory(object):
|
||||
platform_dir = None
|
||||
if isdir(name):
|
||||
platform_dir = name
|
||||
name = pm.load_manifest(platform_dir)['name']
|
||||
name = pm.load_manifest(platform_dir)["name"]
|
||||
elif name.endswith("platform.json") and isfile(name):
|
||||
platform_dir = dirname(name)
|
||||
name = fs.load_json(name)['name']
|
||||
name = fs.load_json(name)["name"]
|
||||
else:
|
||||
name, requirements, url = pm.parse_pkg_uri(name, requirements)
|
||||
platform_dir = pm.get_package_dir(name, requirements, url)
|
||||
if platform_dir:
|
||||
name = pm.load_manifest(platform_dir)['name']
|
||||
name = pm.load_manifest(platform_dir)["name"]
|
||||
|
||||
if not platform_dir:
|
||||
raise exception.UnknownPlatform(
|
||||
name if not requirements else "%s@%s" % (name, requirements))
|
||||
name if not requirements else "%s@%s" % (name, requirements)
|
||||
)
|
||||
|
||||
platform_cls = None
|
||||
if isfile(join(platform_dir, "platform.py")):
|
||||
platform_cls = getattr(
|
||||
cls.load_module(name, join(platform_dir, "platform.py")),
|
||||
cls.get_clsname(name))
|
||||
cls.get_clsname(name),
|
||||
)
|
||||
else:
|
||||
platform_cls = type(str(cls.get_clsname(name)), (PlatformBase, ),
|
||||
{})
|
||||
platform_cls = type(str(cls.get_clsname(name)), (PlatformBase,), {})
|
||||
|
||||
_instance = platform_cls(join(platform_dir, "platform.json"))
|
||||
assert isinstance(_instance, PlatformBase)
|
||||
@@ -263,14 +273,14 @@ class PlatformFactory(object):
|
||||
|
||||
|
||||
class PlatformPackagesMixin(object):
|
||||
|
||||
def install_packages( # pylint: disable=too-many-arguments
|
||||
self,
|
||||
with_packages=None,
|
||||
without_packages=None,
|
||||
skip_default_package=False,
|
||||
silent=False,
|
||||
force=False):
|
||||
self,
|
||||
with_packages=None,
|
||||
without_packages=None,
|
||||
skip_default_package=False,
|
||||
silent=False,
|
||||
force=False,
|
||||
):
|
||||
with_packages = set(self.find_pkg_names(with_packages or []))
|
||||
without_packages = set(self.find_pkg_names(without_packages or []))
|
||||
|
||||
@@ -283,12 +293,13 @@ class PlatformPackagesMixin(object):
|
||||
version = opts.get("version", "")
|
||||
if name in without_packages:
|
||||
continue
|
||||
elif (name in with_packages or
|
||||
not (skip_default_package or opts.get("optional", False))):
|
||||
elif name in with_packages or not (
|
||||
skip_default_package or opts.get("optional", False)
|
||||
):
|
||||
if ":" in version:
|
||||
self.pm.install("%s=%s" % (name, version),
|
||||
silent=silent,
|
||||
force=force)
|
||||
self.pm.install(
|
||||
"%s=%s" % (name, version), silent=silent, force=force
|
||||
)
|
||||
else:
|
||||
self.pm.install(name, version, silent=silent, force=force)
|
||||
|
||||
@@ -305,9 +316,12 @@ class PlatformPackagesMixin(object):
|
||||
result.append(_name)
|
||||
found = True
|
||||
|
||||
if (self.frameworks and candidate.startswith("framework-")
|
||||
and candidate[10:] in self.frameworks):
|
||||
result.append(self.frameworks[candidate[10:]]['package'])
|
||||
if (
|
||||
self.frameworks
|
||||
and candidate.startswith("framework-")
|
||||
and candidate[10:] in self.frameworks
|
||||
):
|
||||
result.append(self.frameworks[candidate[10:]]["package"])
|
||||
found = True
|
||||
|
||||
if not found:
|
||||
@@ -320,7 +334,7 @@ class PlatformPackagesMixin(object):
|
||||
requirements = self.packages[name].get("version", "")
|
||||
if ":" in requirements:
|
||||
_, requirements, __ = self.pm.parse_pkg_uri(requirements)
|
||||
self.pm.update(manifest['__pkg_dir'], requirements, only_check)
|
||||
self.pm.update(manifest["__pkg_dir"], requirements, only_check)
|
||||
|
||||
def get_installed_packages(self):
|
||||
items = {}
|
||||
@@ -335,7 +349,7 @@ class PlatformPackagesMixin(object):
|
||||
requirements = self.packages[name].get("version", "")
|
||||
if ":" in requirements:
|
||||
_, requirements, __ = self.pm.parse_pkg_uri(requirements)
|
||||
if self.pm.outdated(manifest['__pkg_dir'], requirements):
|
||||
if self.pm.outdated(manifest["__pkg_dir"], requirements):
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -343,7 +357,8 @@ class PlatformPackagesMixin(object):
|
||||
version = self.packages[name].get("version", "")
|
||||
if ":" in version:
|
||||
return self.pm.get_package_dir(
|
||||
*self.pm.parse_pkg_uri("%s=%s" % (name, version)))
|
||||
*self.pm.parse_pkg_uri("%s=%s" % (name, version))
|
||||
)
|
||||
return self.pm.get_package_dir(name, version)
|
||||
|
||||
def get_package_version(self, name):
|
||||
@@ -368,15 +383,16 @@ class PlatformRunMixin(object):
|
||||
return value.decode() if is_bytes(value) else value
|
||||
|
||||
def run( # pylint: disable=too-many-arguments
|
||||
self, variables, targets, silent, verbose, jobs):
|
||||
self, variables, targets, silent, verbose, jobs
|
||||
):
|
||||
assert isinstance(variables, dict)
|
||||
assert isinstance(targets, list)
|
||||
|
||||
config = ProjectConfig.get_instance(variables['project_config'])
|
||||
options = config.items(env=variables['pioenv'], as_dict=True)
|
||||
config = ProjectConfig.get_instance(variables["project_config"])
|
||||
options = config.items(env=variables["pioenv"], as_dict=True)
|
||||
if "framework" in options:
|
||||
# support PIO Core 3.0 dev/platforms
|
||||
options['pioframework'] = options['framework']
|
||||
options["pioframework"] = options["framework"]
|
||||
self.configure_default_packages(options, targets)
|
||||
self.install_packages(silent=True)
|
||||
|
||||
@@ -386,12 +402,12 @@ class PlatformRunMixin(object):
|
||||
if "clean" in targets:
|
||||
targets = ["-c", "."]
|
||||
|
||||
variables['platform_manifest'] = self.manifest_path
|
||||
variables["platform_manifest"] = self.manifest_path
|
||||
|
||||
if "build_script" not in variables:
|
||||
variables['build_script'] = self.get_build_script()
|
||||
if not isfile(variables['build_script']):
|
||||
raise exception.BuildScriptNotFound(variables['build_script'])
|
||||
variables["build_script"] = self.get_build_script()
|
||||
if not isfile(variables["build_script"]):
|
||||
raise exception.BuildScriptNotFound(variables["build_script"])
|
||||
|
||||
result = self._run_scons(variables, targets, jobs)
|
||||
assert "returncode" in result
|
||||
@@ -402,14 +418,16 @@ class PlatformRunMixin(object):
|
||||
args = [
|
||||
get_pythonexe_path(),
|
||||
join(get_core_package_dir("tool-scons"), "script", "scons"),
|
||||
"-Q", "--warn=no-no-parallel-support",
|
||||
"--jobs", str(jobs),
|
||||
"--sconstruct", join(fs.get_source_dir(), "builder", "main.py")
|
||||
"-Q",
|
||||
"--warn=no-no-parallel-support",
|
||||
"--jobs",
|
||||
str(jobs),
|
||||
"--sconstruct",
|
||||
join(fs.get_source_dir(), "builder", "main.py"),
|
||||
] # yapf: disable
|
||||
args.append("PIOVERBOSE=%d" % (1 if self.verbose else 0))
|
||||
# pylint: disable=protected-access
|
||||
args.append("ISATTY=%d" %
|
||||
(1 if click._compat.isatty(sys.stdout) else 0))
|
||||
args.append("ISATTY=%d" % (1 if click._compat.isatty(sys.stdout) else 0))
|
||||
args += targets
|
||||
|
||||
# encode and append variables
|
||||
@@ -428,10 +446,13 @@ class PlatformRunMixin(object):
|
||||
args,
|
||||
stdout=BuildAsyncPipe(
|
||||
line_callback=self._on_stdout_line,
|
||||
data_callback=lambda data: _write_and_flush(sys.stdout, data)),
|
||||
data_callback=lambda data: _write_and_flush(sys.stdout, data),
|
||||
),
|
||||
stderr=BuildAsyncPipe(
|
||||
line_callback=self._on_stderr_line,
|
||||
data_callback=lambda data: _write_and_flush(sys.stderr, data)))
|
||||
data_callback=lambda data: _write_and_flush(sys.stderr, data),
|
||||
),
|
||||
)
|
||||
return result
|
||||
|
||||
def _on_stdout_line(self, line):
|
||||
@@ -447,7 +468,7 @@ class PlatformRunMixin(object):
|
||||
b_pos = line.rfind(": No such file or directory")
|
||||
if a_pos == -1 or b_pos == -1:
|
||||
return
|
||||
self._echo_missed_dependency(line[a_pos + 12:b_pos].strip())
|
||||
self._echo_missed_dependency(line[a_pos + 12 : b_pos].strip())
|
||||
|
||||
def _echo_line(self, line, level):
|
||||
if line.startswith("scons: "):
|
||||
@@ -472,18 +493,22 @@ class PlatformRunMixin(object):
|
||||
* Web > {link}
|
||||
*
|
||||
{dots}
|
||||
""".format(filename=filename,
|
||||
filename_styled=click.style(filename, fg="cyan"),
|
||||
link=click.style(
|
||||
"https://platformio.org/lib/search?query=header:%s" %
|
||||
quote(filename, safe=""),
|
||||
fg="blue"),
|
||||
dots="*" * (56 + len(filename)))
|
||||
""".format(
|
||||
filename=filename,
|
||||
filename_styled=click.style(filename, fg="cyan"),
|
||||
link=click.style(
|
||||
"https://platformio.org/lib/search?query=header:%s"
|
||||
% quote(filename, safe=""),
|
||||
fg="blue",
|
||||
),
|
||||
dots="*" * (56 + len(filename)),
|
||||
)
|
||||
click.echo(banner, err=True)
|
||||
|
||||
|
||||
class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
PlatformPackagesMixin, PlatformRunMixin):
|
||||
PlatformPackagesMixin, PlatformRunMixin
|
||||
):
|
||||
|
||||
PIO_VERSION = semantic_version.Version(util.pepver_to_semver(__version__))
|
||||
_BOARDS_CACHE = {}
|
||||
@@ -497,8 +522,7 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
self._manifest = fs.load_json(manifest_path)
|
||||
self._custom_packages = None
|
||||
|
||||
self.pm = PackageManager(get_project_packages_dir(),
|
||||
self.package_repositories)
|
||||
self.pm = PackageManager(get_project_packages_dir(), self.package_repositories)
|
||||
|
||||
# if self.engines and "platformio" in self.engines:
|
||||
# if self.PIO_VERSION not in semantic_version.SimpleSpec(
|
||||
@@ -508,19 +532,19 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._manifest['name']
|
||||
return self._manifest["name"]
|
||||
|
||||
@property
|
||||
def title(self):
|
||||
return self._manifest['title']
|
||||
return self._manifest["title"]
|
||||
|
||||
@property
|
||||
def description(self):
|
||||
return self._manifest['description']
|
||||
return self._manifest["description"]
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
return self._manifest['version']
|
||||
return self._manifest["version"]
|
||||
|
||||
@property
|
||||
def homepage(self):
|
||||
@@ -561,7 +585,7 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
@property
|
||||
def packages(self):
|
||||
packages = self._manifest.get("packages", {})
|
||||
for item in (self._custom_packages or []):
|
||||
for item in self._custom_packages or []:
|
||||
name = item
|
||||
version = "*"
|
||||
if "@" in item:
|
||||
@@ -569,10 +593,7 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
name = name.strip()
|
||||
if name not in packages:
|
||||
packages[name] = {}
|
||||
packages[name].update({
|
||||
"version": version.strip(),
|
||||
"optional": False
|
||||
})
|
||||
packages[name].update({"version": version.strip(), "optional": False})
|
||||
return packages
|
||||
|
||||
def get_dir(self):
|
||||
@@ -591,15 +612,13 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
return False
|
||||
|
||||
def get_boards(self, id_=None):
|
||||
|
||||
def _append_board(board_id, manifest_path):
|
||||
config = PlatformBoardConfig(manifest_path)
|
||||
if "platform" in config and config.get("platform") != self.name:
|
||||
return
|
||||
if "platforms" in config \
|
||||
and self.name not in config.get("platforms"):
|
||||
if "platforms" in config and self.name not in config.get("platforms"):
|
||||
return
|
||||
config.manifest['platform'] = self.name
|
||||
config.manifest["platform"] = self.name
|
||||
self._BOARDS_CACHE[board_id] = config
|
||||
|
||||
bdirs = [
|
||||
@@ -649,28 +668,28 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
continue
|
||||
_pkg_name = self.frameworks[framework].get("package")
|
||||
if _pkg_name:
|
||||
self.packages[_pkg_name]['optional'] = False
|
||||
self.packages[_pkg_name]["optional"] = False
|
||||
|
||||
# enable upload tools for upload targets
|
||||
if any(["upload" in t for t in targets] + ["program" in targets]):
|
||||
for name, opts in self.packages.items():
|
||||
if opts.get("type") == "uploader":
|
||||
self.packages[name]['optional'] = False
|
||||
self.packages[name]["optional"] = False
|
||||
# skip all packages in "nobuild" mode
|
||||
# allow only upload tools and frameworks
|
||||
elif "nobuild" in targets and opts.get("type") != "framework":
|
||||
self.packages[name]['optional'] = True
|
||||
self.packages[name]["optional"] = True
|
||||
|
||||
def get_lib_storages(self):
|
||||
storages = []
|
||||
for opts in (self.frameworks or {}).values():
|
||||
if "package" not in opts:
|
||||
continue
|
||||
pkg_dir = self.get_package_dir(opts['package'])
|
||||
pkg_dir = self.get_package_dir(opts["package"])
|
||||
if not pkg_dir or not isdir(join(pkg_dir, "libraries")):
|
||||
continue
|
||||
libs_dir = join(pkg_dir, "libraries")
|
||||
storages.append({"name": opts['package'], "path": libs_dir})
|
||||
storages.append({"name": opts["package"], "path": libs_dir})
|
||||
libcores_dir = join(libs_dir, "__cores__")
|
||||
if not isdir(libcores_dir):
|
||||
continue
|
||||
@@ -678,16 +697,17 @@ class PlatformBase( # pylint: disable=too-many-public-methods
|
||||
libcore_dir = join(libcores_dir, item)
|
||||
if not isdir(libcore_dir):
|
||||
continue
|
||||
storages.append({
|
||||
"name": "%s-core-%s" % (opts['package'], item),
|
||||
"path": libcore_dir
|
||||
})
|
||||
storages.append(
|
||||
{
|
||||
"name": "%s-core-%s" % (opts["package"], item),
|
||||
"path": libcore_dir,
|
||||
}
|
||||
)
|
||||
|
||||
return storages
|
||||
|
||||
|
||||
class PlatformBoardConfig(object):
|
||||
|
||||
def __init__(self, manifest_path):
|
||||
self._id = basename(manifest_path)[:-5]
|
||||
assert isfile(manifest_path)
|
||||
@@ -698,8 +718,8 @@ class PlatformBoardConfig(object):
|
||||
raise exception.InvalidBoardManifest(manifest_path)
|
||||
if not set(["name", "url", "vendor"]) <= set(self._manifest):
|
||||
raise exception.PlatformioException(
|
||||
"Please specify name, url and vendor fields for " +
|
||||
manifest_path)
|
||||
"Please specify name, url and vendor fields for " + manifest_path
|
||||
)
|
||||
|
||||
def get(self, path, default=None):
|
||||
try:
|
||||
@@ -751,41 +771,33 @@ class PlatformBoardConfig(object):
|
||||
|
||||
def get_brief_data(self):
|
||||
return {
|
||||
"id":
|
||||
self.id,
|
||||
"name":
|
||||
self._manifest['name'],
|
||||
"platform":
|
||||
self._manifest.get("platform"),
|
||||
"mcu":
|
||||
self._manifest.get("build", {}).get("mcu", "").upper(),
|
||||
"fcpu":
|
||||
int("".join([
|
||||
c for c in str(
|
||||
self._manifest.get("build", {}).get("f_cpu", "0L"))
|
||||
if c.isdigit()
|
||||
])),
|
||||
"ram":
|
||||
self._manifest.get("upload", {}).get("maximum_ram_size", 0),
|
||||
"rom":
|
||||
self._manifest.get("upload", {}).get("maximum_size", 0),
|
||||
"connectivity":
|
||||
self._manifest.get("connectivity"),
|
||||
"frameworks":
|
||||
self._manifest.get("frameworks"),
|
||||
"debug":
|
||||
self.get_debug_data(),
|
||||
"vendor":
|
||||
self._manifest['vendor'],
|
||||
"url":
|
||||
self._manifest['url']
|
||||
"id": self.id,
|
||||
"name": self._manifest["name"],
|
||||
"platform": self._manifest.get("platform"),
|
||||
"mcu": self._manifest.get("build", {}).get("mcu", "").upper(),
|
||||
"fcpu": int(
|
||||
"".join(
|
||||
[
|
||||
c
|
||||
for c in str(self._manifest.get("build", {}).get("f_cpu", "0L"))
|
||||
if c.isdigit()
|
||||
]
|
||||
)
|
||||
),
|
||||
"ram": self._manifest.get("upload", {}).get("maximum_ram_size", 0),
|
||||
"rom": self._manifest.get("upload", {}).get("maximum_size", 0),
|
||||
"connectivity": self._manifest.get("connectivity"),
|
||||
"frameworks": self._manifest.get("frameworks"),
|
||||
"debug": self.get_debug_data(),
|
||||
"vendor": self._manifest["vendor"],
|
||||
"url": self._manifest["url"],
|
||||
}
|
||||
|
||||
def get_debug_data(self):
|
||||
if not self._manifest.get("debug", {}).get("tools"):
|
||||
return None
|
||||
tools = {}
|
||||
for name, options in self._manifest['debug']['tools'].items():
|
||||
for name, options in self._manifest["debug"]["tools"].items():
|
||||
tools[name] = {}
|
||||
for key, value in options.items():
|
||||
if key in ("default", "onboard"):
|
||||
@@ -798,22 +810,23 @@ class PlatformBoardConfig(object):
|
||||
if tool_name == "custom":
|
||||
return tool_name
|
||||
if not debug_tools:
|
||||
raise exception.DebugSupportError(self._manifest['name'])
|
||||
raise exception.DebugSupportError(self._manifest["name"])
|
||||
if tool_name:
|
||||
if tool_name in debug_tools:
|
||||
return tool_name
|
||||
raise exception.DebugInvalidOptions(
|
||||
"Unknown debug tool `%s`. Please use one of `%s` or `custom`" %
|
||||
(tool_name, ", ".join(sorted(list(debug_tools)))))
|
||||
"Unknown debug tool `%s`. Please use one of `%s` or `custom`"
|
||||
% (tool_name, ", ".join(sorted(list(debug_tools))))
|
||||
)
|
||||
|
||||
# automatically select best tool
|
||||
data = {"default": [], "onboard": [], "external": []}
|
||||
for key, value in debug_tools.items():
|
||||
if value.get("default"):
|
||||
data['default'].append(key)
|
||||
data["default"].append(key)
|
||||
elif value.get("onboard"):
|
||||
data['onboard'].append(key)
|
||||
data['external'].append(key)
|
||||
data["onboard"].append(key)
|
||||
data["external"].append(key)
|
||||
|
||||
for key, value in data.items():
|
||||
if not value:
|
||||
|
||||
Reference in new issue
Block a user