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 import click
from platformio.exception import APIRequestError
from platformio.managers.platform import PlatformManager from platformio.managers.platform import PlatformManager
@ -78,24 +79,24 @@ def cli(query, installed, json_output): # pylint: disable=R0912
def _get_boards(installed=False): def _get_boards(installed=False):
boards = PlatformManager.get_registered_boards() boards = PlatformManager().get_installed_boards()
if installed: if not installed:
_installed_boards = [ know_boards = ["%s:%s" % (b['platform'], b['id']) for b in boards]
"%s:%s" % (b['platform'], b['id']) for board in PlatformManager().get_registered_boards():
for b in PlatformManager().get_installed_boards()
]
_new_boards = []
for board in boards:
key = "%s:%s" % (board['platform'], board['id']) key = "%s:%s" % (board['platform'], board['id'])
if key in _installed_boards: if key not in know_boards:
_new_boards.append(board) boards.append(board)
boards = _new_boards
return boards return boards
def _ouput_boards_json(query, installed=False): def _ouput_boards_json(query, installed=False):
result = [] 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: if query:
search_data = "%s %s" % (board['id'], json.dumps(board).lower()) search_data = "%s %s" % (board['id'], json.dumps(board).lower())
if query.lower() not in search_data.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 # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import re import json
import struct import os
from os import getenv from os import getenv
from os.path import isdir, join
from time import time from time import time
import click import click
import semantic_version
from platformio import __version__, app, exception, telemetry, util from platformio import __version__, app, exception, telemetry, util
from platformio.commands.lib import lib_update as cmd_libraries_update from platformio.commands.lib import lib_update as cmd_libraries_update
@ -65,21 +67,13 @@ def on_platformio_exception(e):
class Upgrader(object): class Upgrader(object):
def __init__(self, from_version, to_version): def __init__(self, from_version, to_version):
self.from_version = self.version_to_int(from_version) self.from_version = semantic_version.Version.coerce(from_version)
self.to_version = self.version_to_int(to_version) self.to_version = semantic_version.Version.coerce(to_version)
self._upgraders = [ 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): def run(self, ctx):
if self.from_version > self.to_version: if self.from_version > self.to_version:
return True return True
@ -93,9 +87,26 @@ class Upgrader(object):
return all(result) return all(result)
def _upgrade_to_3_0_0(self, ctx): # pylint: disable=R0201 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", []) installed_platforms = app.get_state_item("installed_platforms", [])
if installed_platforms: if installed_platforms:
ctx.invoke(cmd_platform_install, platforms=installed_platforms) ctx.invoke(cmd_platform_install, platforms=installed_platforms)
return True return True
@ -169,9 +180,8 @@ def check_platformio_upgrade():
app.set_state_item("last_check", last_check) app.set_state_item("last_check", last_check)
latest_version = get_latest_version() latest_version = get_latest_version()
if (latest_version == __version__ or if (semantic_version.Version.coerce(latest_version) <=
Upgrader.version_to_int(latest_version) < semantic_version.Version.coerce(__version__)):
Upgrader.version_to_int(__version__)):
return return
terminal_width, _ = click.get_terminal_size() terminal_width, _ = click.get_terminal_size()

View File

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