Handle custom boards

This commit is contained in:
Ivan Kravets
2016-06-08 13:34:49 +03:00
parent 0aa2db8e91
commit 3a143270c2
3 changed files with 91 additions and 48 deletions

View File

@ -16,6 +16,7 @@ import json
import click
from platformio.exception import APIRequestError
from platformio.managers.platform import PlatformManager
@ -78,24 +79,24 @@ def cli(query, installed, json_output): # pylint: disable=R0912
def _get_boards(installed=False):
boards = PlatformManager.get_registered_boards()
if installed:
_installed_boards = [
"%s:%s" % (b['platform'], b['id'])
for b in PlatformManager().get_installed_boards()
]
_new_boards = []
for board in boards:
boards = PlatformManager().get_installed_boards()
if not installed:
know_boards = ["%s:%s" % (b['platform'], b['id']) for b in boards]
for board in PlatformManager().get_registered_boards():
key = "%s:%s" % (board['platform'], board['id'])
if key in _installed_boards:
_new_boards.append(board)
boards = _new_boards
if key not in know_boards:
boards.append(board)
return boards
def _ouput_boards_json(query, installed=False):
result = []
for board in _get_boards(installed):
try:
boards = _get_boards(installed)
except APIRequestError:
if not installed:
boards = _get_boards(True)
for board in boards:
if query:
search_data = "%s %s" % (board['id'], json.dumps(board).lower())
if query.lower() not in search_data.lower():

View File

@ -12,12 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import re
import struct
import json
import os
from os import getenv
from os.path import isdir, join
from time import time
import click
import semantic_version
from platformio import __version__, app, exception, telemetry, util
from platformio.commands.lib import lib_update as cmd_libraries_update
@ -65,21 +67,13 @@ def on_platformio_exception(e):
class Upgrader(object):
def __init__(self, from_version, to_version):
self.from_version = self.version_to_int(from_version)
self.to_version = self.version_to_int(to_version)
self.from_version = semantic_version.Version.coerce(from_version)
self.to_version = semantic_version.Version.coerce(to_version)
self._upgraders = [
(self.version_to_int("3.0.0"), self._upgrade_to_3_0_0)
(semantic_version.Version("3.0.0"), self._upgrade_to_3_0_0)
]
@staticmethod
def version_to_int(version):
match = re.match(r"(\d+)\.(\d+)\.(\d+)(\D+)?", version)
assert match is not None and len(match.groups()) is 4
verchrs = [chr(int(match.group(i))) for i in range(1, 4)]
verchrs.append(chr(255 if match.group(4) is None else 0))
return struct.unpack(">I", "".join(verchrs))
def run(self, ctx):
if self.from_version > self.to_version:
return True
@ -93,9 +87,26 @@ class Upgrader(object):
return all(result)
def _upgrade_to_3_0_0(self, ctx): # pylint: disable=R0201
# convert custom board configuration
boards_dir = join(util.get_home_dir(), "boards")
if isdir(boards_dir):
for item in os.listdir(boards_dir):
if not item.endswith(".json"):
continue
data = util.load_json(join(boards_dir, item))
if set(["name", "url", "vendor"]) <= set(data.keys()):
continue
os.remove(join(boards_dir, item))
for key, value in data.items():
with open(join(boards_dir, "%s.json" % key),
"w") as f:
json.dump(value, f, sort_keys=True, indent=2)
# re-install PlatformIO 2.0 development platforms
installed_platforms = app.get_state_item("installed_platforms", [])
if installed_platforms:
ctx.invoke(cmd_platform_install, platforms=installed_platforms)
return True
@ -169,9 +180,8 @@ def check_platformio_upgrade():
app.set_state_item("last_check", last_check)
latest_version = get_latest_version()
if (latest_version == __version__ or
Upgrader.version_to_int(latest_version) <
Upgrader.version_to_int(__version__)):
if (semantic_version.Version.coerce(latest_version) <=
semantic_version.Version.coerce(__version__)):
return
terminal_width, _ = click.get_terminal_size()

View File

@ -98,11 +98,8 @@ class PlatformManager(PackageManager):
boards = []
for manifest in self.get_installed():
p = PlatformFactory.newPlatform(manifest['_manifest_path'])
for id_, config in p.get_boards().items():
manifest = config.get_manifest().copy()
manifest['id'] = id_
manifest['platform'] = p.name
boards.append(manifest)
for config in p.get_boards().values():
boards.append(config.get_brief_data())
return boards
@staticmethod
@ -394,22 +391,37 @@ class PlatformBase(PlatformPackagesMixin, PlatformRunMixin):
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
elif ("platforms" in config and
self.name not in config.get("platforms")):
return
config.manifest['platform'] = self.name
self._BOARDS_CACHE[board_id] = config
bdirs = (join(util.get_home_dir(), "boards"),
join(self.get_dir(), "boards"))
if id_ is None:
boards_dir = join(self.get_dir(), "boards")
if not isdir(boards_dir):
return {}
for item in sorted(os.listdir(boards_dir)):
_id = item[:-5]
if _id in self._BOARDS_CACHE:
for boards_dir in bdirs:
if not isdir(boards_dir):
continue
self._BOARDS_CACHE[_id] = PlatformBoardConfig(
join(self.get_dir(), "boards", item)
)
for item in sorted(os.listdir(boards_dir)):
_id = item[:-5]
if not item.endswith(".json") or _id in self._BOARDS_CACHE:
continue
_append_board(_id, join(boards_dir, item))
else:
if id_ not in self._BOARDS_CACHE:
self._BOARDS_CACHE[id_] = PlatformBoardConfig(
join(self.get_dir(), "boards", "%s.json" % id_)
)
for boards_dir in bdirs:
manifest_path = join(bdirs, "%s.json" % id_)
if not isfile(manifest_path):
continue
_append_board(id_, manifest_path)
if id_ not in self._BOARDS_CACHE:
raise exception.UnknownBoard(id_)
return self._BOARDS_CACHE[id_] if id_ else self._BOARDS_CACHE
def board_config(self, id_):
@ -472,10 +484,11 @@ class PlatformBase(PlatformPackagesMixin, PlatformRunMixin):
class PlatformBoardConfig(object):
def __init__(self, manifest_path):
if not isfile(manifest_path):
raise exception.UnknownBoard(basename(manifest_path[:-5]))
self._id = basename(manifest_path)[:-5]
assert isfile(manifest_path)
self.manifest_path = manifest_path
self._manifest = util.load_json(manifest_path)
assert set(["name", "url", "vendor"]) <= set(self._manifest.keys())
def get(self, path, default=None):
try:
@ -496,5 +509,24 @@ class PlatformBoardConfig(object):
except KeyError:
return False
def get_manifest(self):
@property
def id_(self):
return self._id
@property
def manifest(self):
return self._manifest
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(self._manifest.get("build", {}).get("f_cpu", "")[:-1]),
"ram": self._manifest.get("upload", {}).get("maximum_ram_size", 0),
"rom": self._manifest.get("upload", {}).get("maximum_size", 0),
"frameworks": self._manifest.get("frameworks"),
"vendor": self._manifest['vendor'],
"url": self._manifest['url']
}