Implemented new commands: list, show, uninstall & update; minor improvements to code

This commit is contained in:
Ivan Kravets
2014-06-13 20:47:02 +03:00
parent bddb9237e2
commit 027c3d0e5e
9 changed files with 192 additions and 38 deletions

View File

@ -6,7 +6,7 @@ from click import argument, command, option, secho
from platformio.platforms._base import PlatformFactory
@command("run", short_help="Install new platforms")
@command("install", short_help="Install new platforms")
@argument("platform")
@option('--with-package', multiple=True, metavar="<package>")
@option('--without-package', multiple=True, metavar="<package>")

View File

@ -0,0 +1,16 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from click import command, echo, style
from platformio.pkgmanager import PackageManager
@command("list", short_help="List installed platforms")
def cli():
for name, pkgs in PackageManager.get_installed().iteritems():
echo("{name:<20} with packages: {pkgs}".format(
name=style(name, fg="cyan"),
pkgs=", ".join(pkgs.keys())
))

View File

@ -0,0 +1,29 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from os.path import join
from click import argument, command, echo, style
from platformio.exception import PlatformNotInstalledYet
from platformio.pkgmanager import PackageManager
from platformio.platforms._base import PlatformFactory
@command("show", short_help="Show details about an installed platforms")
@argument("platform")
def cli(platform):
p = PlatformFactory().newPlatform(platform)
if platform not in PackageManager.get_installed():
raise PlatformNotInstalledYet(platform)
# print info about platform
echo("{name:<20} - {info}".format(name=style(p.get_name(), fg="cyan"),
info=p.get_short_info()))
pm = PackageManager(platform)
for name, data in pm.get_installed(platform).iteritems():
echo("----------")
echo("Package: %s" % style(name, fg="yellow"))
echo("Location: %s" % join(pm.get_platform_dir(), data['path']))
echo("Version: %d" % int(data['version']))

View File

@ -0,0 +1,21 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from click import argument, command, secho
from platformio.exception import PlatformNotInstalledYet
from platformio.pkgmanager import PackageManager
from platformio.platforms._base import PlatformFactory
@command("uninstall", short_help="Uninstall the platforms")
@argument("platform")
def cli(platform):
if platform not in PackageManager.get_installed():
raise PlatformNotInstalledYet(platform)
p = PlatformFactory().newPlatform(platform)
if p.uninstall():
secho("The platform '%s' has been successfully "
"uninstalled!" % platform, fg="green")

View File

@ -0,0 +1,17 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
from click import command, echo, style
from platformio.pkgmanager import PackageManager
from platformio.platforms._base import PlatformFactory
@command("update", short_help="Update installed platforms")
def cli():
for platform in PackageManager.get_installed().keys():
echo("\nPlatform %s" % style(platform, fg="cyan"))
echo("--------")
p = PlatformFactory().newPlatform(platform)
p.update()

View File

@ -18,6 +18,12 @@ class UnknownPlatform(PlatformioException):
MESSAGE = "Unknown platform '%s'"
class PlatformNotInstalledYet(PlatformioException):
MESSAGE = ("The platform '%s' has not been installed yet. "
"Use `platformio install` command")
class UnknownCLICommand(PlatformioException):
MESSAGE = "Unknown command '%s'"
@ -33,11 +39,6 @@ class InvalidPackageVersion(PlatformioException):
MESSAGE = "The package '%s' with version '%d' does not exist"
class PackageInstalled(PlatformioException):
MESSAGE = "The package '%s' is installed already"
class NonSystemPackage(PlatformioException):
MESSAGE = "The package '%s' is not available for your system '%s'"

View File

@ -4,27 +4,33 @@
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 platformio import __pkgmanifesturl__
from platformio.downloader import FileDownloader
from platformio.exception import (InvalidPackageVersion, NonSystemPackage,
PackageInstalled, UnknownPackage)
UnknownPackage)
from platformio.unpacker import FileUnpacker
from platformio.util import get_home_dir, get_system
class PackageManager(object):
DBFILE_PATH = join(get_home_dir(), "installed.json")
def __init__(self, platform_name):
self._platform_name = platform_name
self._platforms_dir = get_home_dir()
self._dbfile = join(self._platforms_dir, "installed.json")
@staticmethod
def get_manifest():
return get(__pkgmanifesturl__).json()
try:
return PackageManager._cached_manifest
except AttributeError:
PackageManager._cached_manifest = get(__pkgmanifesturl__).json()
return PackageManager._cached_manifest
@staticmethod
def download(url, dest_dir, sha1=None):
@ -38,12 +44,16 @@ class PackageManager(object):
fu = FileUnpacker(pkgpath, dest_dir)
return fu.start()
def get_installed(self):
@staticmethod
def get_installed(platform=None):
data = {}
if isfile(self._dbfile):
with open(self._dbfile) as fp:
if isfile(PackageManager.DBFILE_PATH):
with open(PackageManager.DBFILE_PATH) as fp:
data = json.load(fp)
return data
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()
@ -51,9 +61,6 @@ class PackageManager(object):
installed[self._platform_name])
def get_info(self, name, version=None):
if self.is_installed(name):
raise PackageInstalled(name)
manifest = self.get_manifest()
if name not in manifest:
raise UnknownPackage(name)
@ -74,8 +81,14 @@ class PackageManager(object):
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._platforms_dir, self._platform_name, path)
pkg_dir = join(self.get_platform_dir(), path)
if not isdir(pkg_dir):
makedirs(pkg_dir)
@ -85,13 +98,59 @@ class PackageManager(object):
# 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._platform_name] = {}
data = self.register_platform(self._platform_name)
data[self._platform_name][name] = {
"version": version,
"path": path
}
with open(self._dbfile, "w") as fp:
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)

View File

@ -2,13 +2,11 @@
# See LICENSE for details.
from os.path import join
from shutil import rmtree
from click import echo, secho, style
from platformio.exception import (PackageInstalled, UnknownPackage,
UnknownPlatform)
from platformio.exception import UnknownPackage, UnknownPlatform
from platformio.pkgmanager import PackageManager
from platformio.util import exec_command, get_source_dir
from platformio.util import exec_command, get_platforms, get_source_dir
class PlatformFactory(object):
@ -17,9 +15,10 @@ class PlatformFactory(object):
def newPlatform(name):
clsname = "%sPlatform" % name.title()
try:
assert name in get_platforms()
mod = __import__("platformio.platforms." + name.lower(),
None, None, [clsname])
except ImportError:
except (AssertionError, ImportError):
raise UnknownPlatform(name)
obj = getattr(mod, clsname)()
@ -56,17 +55,26 @@ class BasePlatform(object):
elif name in with_packages or opts["default"]:
requirements.append((name, opts["path"]))
for (name, path) in requirements:
echo("Installing %s package:" % style(name, fg="cyan"))
try:
pm.install(name, path)
except PackageInstalled:
secho("Already installed", fg="yellow")
for (package, path) in requirements:
pm.install(package, path)
return True
def after_run(self, result): # pylint: disable=R0201
return result
def uninstall(self):
platform = self.get_name()
pm = PackageManager(platform)
for package, data in pm.get_installed(platform).iteritems():
pm.uninstall(package, data['path'])
pm.unregister_platform(platform)
rmtree(pm.get_platform_dir())
return True
def update(self):
platform = self.get_name()
pm = PackageManager(platform)
for package in pm.get_installed(platform).keys():
pm.update(package)
def run(self, variables, targets):
assert isinstance(variables, list)
@ -83,3 +91,6 @@ class BasePlatform(object):
] + variables + targets)
return self.after_run(result)
def after_run(self, result): # pylint: disable=R0201
return result

View File

@ -1,10 +1,10 @@
# Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details.
# Please uncomment (remove "#" sign from the beginning of the line) any
# environments which are fit to your project
# Please uncomment (remove "#" sign from the beginning of the line)
# some of the environments which fit to your project.
#
# And replace all values that match with "%..._HERE%" by real data
# And replace all values that match with "%..._HERE%" by real data.
# Simple and base environment