Skip to content

Commit

Permalink
Added support for Arduino's library.properties depends field // R…
Browse files Browse the repository at this point in the history
…esolve #2781
  • Loading branch information
ivankravets committed Feb 4, 2020
1 parent bc69259 commit efe8e59
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 39 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ PlatformIO Core 4.0
* Install a dev-platform with ALL declared packages using a new ``--with-all-packages`` option for `pio platform install <https://docs.platformio.org/page/userguide/platforms/cmd_install.html>`__ command (`issue #3345 <https://github.com/platformio/platformio-core/issues/3345>`_)
* Added support for "pythonPackages" in `platform.json <https://docs.platformio.org/page/platforms/creating_platform.html#manifest-file-platform-json>`__ manifest (PlatformIO Package Manager will install dependent Python packages from PyPi registry automatically when dev-platform is installed)
* Handle project configuration (monitor, test, and upload options) for PIO Remote commands (`issue #2591 <https://github.com/platformio/platformio-core/issues/2591>`_)
* Added support for Arduino's library.properties ``depends`` field (`issue #2781 <https://github.com/platformio/platformio-core/issues/2781>`_)
* Updated SCons tool to 3.1.2
* Updated Unity tool to 2.5.0
* Made package ManifestSchema compatible with marshmallow >= 3 (`issue #3296 <https://github.com/platformio/platformio-core/issues/3296>`_)
Expand Down
2 changes: 1 addition & 1 deletion docs
4 changes: 1 addition & 3 deletions platformio/builder/tools/piolib.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,7 @@ def version(self):

@property
def dependencies(self):
return LibraryManager.normalize_dependencies(
self._manifest.get("dependencies", [])
)
return self._manifest.get("dependencies")

@property
def src_filter(self):
Expand Down
27 changes: 2 additions & 25 deletions platformio/managers/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import semantic_version

from platformio import app, exception, util
from platformio.compat import glob_escape, string_types
from platformio.compat import glob_escape
from platformio.managers.package import BasePkgManager
from platformio.managers.platform import PlatformFactory, PlatformManager
from platformio.project.config import ProjectConfig
Expand Down Expand Up @@ -61,29 +61,6 @@ def get_manifest_path(self, pkg_dir):

return None

@staticmethod
def normalize_dependencies(dependencies):
if not dependencies:
return []
items = []
if isinstance(dependencies, dict):
if "name" in dependencies:
items.append(dependencies)
else:
for name, version in dependencies.items():
items.append({"name": name, "version": version})
elif isinstance(dependencies, list):
items = [d for d in dependencies if "name" in d]
for item in items:
for k in ("frameworks", "platforms"):
if k not in item or isinstance(k, list):
continue
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()]
return items

def max_satisfying_repo_version(self, versions, requirements=None):
def _cmp_dates(datestr1, datestr2):
date1 = util.parse_date(datestr1)
Expand Down Expand Up @@ -312,7 +289,7 @@ def install( # pylint: disable=arguments-differ
click.secho("Installing dependencies", fg="yellow")

builtin_lib_storages = None
for filters in self.normalize_dependencies(manifest["dependencies"]):
for filters in manifest["dependencies"]:
assert "name" in filters

# avoid circle dependencies
Expand Down
53 changes: 53 additions & 0 deletions platformio/package/manifest/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import requests

from platformio import util
from platformio.compat import get_class_attributes, string_types
from platformio.fs import get_file_contents
from platformio.package.exception import ManifestParserError, UnknownManifestError
Expand Down Expand Up @@ -286,6 +287,8 @@ def parse(self, contents):
data["platforms"] = self._parse_platforms(data["platforms"]) or None
if "export" in data:
data["export"] = self._parse_export(data["export"])
if "dependencies" in data:
data["dependencies"] = self._parse_dependencies(data["dependencies"])

return data

Expand Down Expand Up @@ -350,6 +353,26 @@ def _parse_export(raw):
result[k] = raw[k] if isinstance(raw[k], list) else [raw[k]]
return result

@staticmethod
def _parse_dependencies(raw):
if isinstance(raw, dict):
if "name" in raw: # compatibility with dep as dict
return [raw]
return [dict(name=name, version=version) for name, version in raw.items()]
if isinstance(raw, list):
for i, dependency in enumerate(raw):
assert isinstance(dependency, dict)
for k, v in dependency.items():
if k not in ("platforms", "frameworks", "authors"):
continue
if "*" in v:
del raw[i][k]
raw[i][k] = util.items_to_list(v)
return raw
raise ManifestParserError(
"Invalid dependencies format, should be list or dictionary"
)


class ModuleJsonManifestParser(BaseManifestParser):
manifest_type = ManifestFileType.MODULE_JSON
Expand Down Expand Up @@ -408,6 +431,8 @@ def parse(self, contents):
if "author" in data:
data["authors"] = self._parse_authors(data)
del data["author"]
if "depends" in data:
data["dependencies"] = self._parse_dependencies(data["depends"])
return data

@staticmethod
Expand Down Expand Up @@ -534,6 +559,26 @@ def _parse_export(self):
result["include"] = [include]
return result

@staticmethod
def _parse_dependencies(raw):
result = []
for item in raw.split(","):
item = item.strip()
if not item:
continue
if item.endswith(")") and "(" in item:
name, version = item.split("(")
result.append(
dict(
name=name.strip(),
version=version[:-1].strip(),
frameworks=["arduino"],
)
)
else:
result.append(dict(name=item, frameworks=["arduino"]))
return result


class PlatformJsonManifestParser(BaseManifestParser):
manifest_type = ManifestFileType.PLATFORM_JSON
Expand All @@ -542,6 +587,8 @@ def parse(self, contents):
data = json.loads(contents)
if "frameworks" in data:
data["frameworks"] = self._parse_frameworks(data["frameworks"])
if "packages" in data:
data["dependencies"] = self._parse_dependencies(data["packages"])
return data

@staticmethod
Expand All @@ -550,6 +597,12 @@ def _parse_frameworks(raw):
return None
return [name.lower() for name in raw.keys()]

@staticmethod
def _parse_dependencies(raw):
return [
dict(name=name, version=opts.get("version")) for name, opts in raw.items()
]


class PackageJsonManifestParser(BaseManifestParser):
manifest_type = ManifestFileType.PACKAGE_JSON
Expand Down
27 changes: 27 additions & 0 deletions platformio/package/manifest/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,32 @@ class RepositorySchema(StrictSchema):
branch = fields.Str(validate=validate.Length(min=1, max=50))


class DependencySchema(StrictSchema):
name = fields.Str(required=True, validate=validate.Length(min=1, max=100))
version = fields.Str(validate=validate.Length(min=1, max=100))
authors = StrictListField(fields.Str(validate=validate.Length(min=1, max=50)))
platforms = StrictListField(
fields.Str(
validate=[
validate.Length(min=1, max=50),
validate.Regexp(
r"^([a-z\d\-_]+|\*)$", error="Only [a-z0-9-_*] chars are allowed"
),
]
)
)
frameworks = StrictListField(
fields.Str(
validate=[
validate.Length(min=1, max=50),
validate.Regexp(
r"^([a-z\d\-_]+|\*)$", error="Only [a-z0-9-_*] chars are allowed"
),
]
)
)


class ExportSchema(BaseSchema):
include = StrictListField(fields.Str)
exclude = StrictListField(fields.Str)
Expand Down Expand Up @@ -133,6 +159,7 @@ class ManifestSchema(BaseSchema):
homepage = fields.Url(validate=validate.Length(min=1, max=255))
license = fields.Str(validate=validate.Length(min=1, max=255))
repository = fields.Nested(RepositorySchema)
dependencies = fields.Nested(DependencySchema, many=True)

# library.json
export = fields.Nested(ExportSchema)
Expand Down
7 changes: 3 additions & 4 deletions platformio/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,6 @@ def _internet_on():
if os.getenv("HTTP_PROXY", os.getenv("HTTPS_PROXY")):
requests.get("http://%s" % host, allow_redirects=False, timeout=timeout)
else:

socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, 80))
return True
except: # pylint: disable=bare-except
Expand All @@ -403,9 +402,9 @@ def pepver_to_semver(pepver):


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]
if isinstance(items, list):
return items
return [i.strip() for i in items.split(",") if i.strip()]


def items_in_list(needle, haystack):
Expand Down
Loading

0 comments on commit efe8e59

Please sign in to comment.