Files
platformio-core/platformio/pkgmanager.py

161 lines
5.1 KiB
Python
Raw Normal View History

# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
import json
from os import makedirs, remove
from os.path import isdir, isfile, join
from shutil import rmtree
from click import echo, secho, style
from requests import get
from requests.utils import default_user_agent
from platformio import __pkgmanifesturl__, __version__
from platformio.downloader import FileDownloader
from platformio.exception import (InvalidPackageVersion, NonSystemPackage,
UnknownPackage)
from platformio.unpacker import FileUnpacker
2014-07-31 16:20:31 +03:00
from platformio.util import get_home_dir, get_systype
class PackageManager(object):
DBFILE_PATH = join(get_home_dir(), "installed.json")
def __init__(self, platform_name):
self._platform_name = platform_name
@staticmethod
def get_manifest():
try:
return PackageManager._cached_manifest
except AttributeError:
headers = {"User-Agent": "PlatformIO/%s %s" % (
__version__, default_user_agent())}
PackageManager._cached_manifest = get(__pkgmanifesturl__,
headers=headers).json()
return PackageManager._cached_manifest
@staticmethod
def download(url, dest_dir, sha1=None):
fd = FileDownloader(url, dest_dir)
fd.start()
fd.verify(sha1)
return fd.get_filepath()
@staticmethod
def unpack(pkgpath, dest_dir):
fu = FileUnpacker(pkgpath, dest_dir)
return fu.start()
@staticmethod
def get_installed(platform=None):
data = {}
if isfile(PackageManager.DBFILE_PATH):
with open(PackageManager.DBFILE_PATH) as fp:
data = json.load(fp)
return data.get(platform, None) if platform else data
def get_platform_dir(self):
return join(get_home_dir(), self._platform_name)
def is_installed(self, name):
installed = self.get_installed()
return (self._platform_name in installed and name in
installed[self._platform_name])
def get_info(self, name, version=None):
manifest = self.get_manifest()
if name not in manifest:
raise UnknownPackage(name)
# check system platform
2014-07-31 16:20:31 +03:00
systype = get_systype()
builds = ([b for b in manifest[name] if b['system'] == "all" or systype
in b['system']])
if not builds:
2014-07-31 16:20:31 +03:00
raise NonSystemPackage(name, systype)
if version:
for b in builds:
if b['version'] == version:
return b
raise InvalidPackageVersion(name, version)
else:
return sorted(builds, key=lambda s: s['version'])[-1]
def install(self, name, path):
echo("Installing %s package:" % style(name, fg="cyan"))
if self.is_installed(name):
secho("Already installed", fg="yellow")
return
info = self.get_info(name)
pkg_dir = join(self.get_platform_dir(), path)
if not isdir(pkg_dir):
makedirs(pkg_dir)
dlpath = self.download(info['url'], pkg_dir, info['sha1'])
if self.unpack(dlpath, pkg_dir):
self._register(name, info['version'], path)
# remove archive
remove(dlpath)
def uninstall(self, name, path):
echo("Uninstalling %s package: \t" % style(name, fg="cyan"),
nl=False)
rmtree(join(self.get_platform_dir(), path))
self._unregister(name)
echo("[%s]" % style("OK", fg="green"))
def update(self, name):
echo("Updating %s package:" % style(name, fg="yellow"))
installed = self.get_installed(self._platform_name)
current_version = installed[name]['version']
latest_version = self.get_info(name)['version']
echo("Versions: Current=%d, Latest=%d \t " % (
current_version, latest_version), nl=False)
if current_version == latest_version:
echo("[%s]" % (style("Up-to-date", fg="green")))
return True
else:
echo("[%s]" % (style("Out-of-date", fg="red")))
self.uninstall(name, installed[name]['path'])
self.install(name, installed[name]['path'])
def register_platform(self, name):
data = self.get_installed()
if name not in data:
data[name] = {}
self._update_db(data)
return data
def unregister_platform(self, name):
data = self.get_installed()
del data[name]
self._update_db(data)
def _register(self, name, version, path):
data = self.get_installed()
if self._platform_name not in data:
data = self.register_platform(self._platform_name)
data[self._platform_name][name] = {
"version": version,
"path": path
}
self._update_db(data)
def _unregister(self, name):
data = self.get_installed()
del data[self._platform_name][name]
self._update_db(data)
def _update_db(self, data):
with open(self.DBFILE_PATH, "w") as fp:
json.dump(data, fp)