Files
platformio-core/platformio/commands/lib.py

284 lines
9.5 KiB
Python
Raw Normal View History

# Copyright 2014-2015 Ivan Kravets <me@ikravets.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
2014-09-03 23:03:49 +03:00
import json
import click
from platformio import app, exception
from platformio.libmanager import LibraryManager
from platformio.util import get_api_result
2014-09-03 23:03:49 +03:00
LIBLIST_TPL = ("[{id:^14}] {name:<25} {compatibility:<30} "
"\"{authornames}\": {description}")
def echo_liblist_header():
click.echo(LIBLIST_TPL.format(
id=click.style("ID", fg="green"),
name=click.style("Name", fg="cyan"),
compatibility=click.style("Compatibility", fg="yellow"),
authornames="Authors",
description="Description"
))
2015-04-20 17:20:27 +01:00
terminal_width, _ = click.get_terminal_size()
click.echo("-" * terminal_width)
def echo_liblist_item(item):
click.echo(LIBLIST_TPL.format(
id=click.style(str(item['id']), fg="green"),
name=click.style(item['name'], fg="cyan"),
compatibility=click.style(
", ".join(item['frameworks'] + item['platforms']),
fg="yellow"
),
authornames=", ".join(item['authornames']),
description=item['description']
))
@click.group(short_help="Library Manager")
2014-09-03 23:03:49 +03:00
def cli():
pass
@cli.command("search", short_help="Search for library")
@click.option("-a", "--author", multiple=True)
@click.option("-k", "--keyword", multiple=True)
@click.option("-f", "--framework", multiple=True)
@click.option("-p", "--platform", multiple=True)
2014-11-24 21:59:25 +02:00
@click.argument("query", required=False)
def lib_search(query, **filters):
2014-11-24 21:59:25 +02:00
if not query:
query = ""
for key, values in filters.iteritems():
for value in values:
query += ' %s:"%s"' % (key, value)
result = get_api_result("/lib/search", dict(query=query))
if result['total'] == 0:
click.secho(
"Nothing has been found by your request\n"
"Try a less-specific search or use truncation (or wildcard) "
"operator", fg="yellow", nl=False)
click.secho(" *", fg="green")
click.secho("For example: DS*, PCA*, DHT* and etc.\n", fg="yellow")
click.echo("For more examples and advanced search syntax, "
"please use documentation:")
click.secho("http://docs.platformio.org"
"/en/latest/userguide/lib/cmd_search.html\n", fg="cyan")
return
click.secho("Found %d libraries:\n" % result['total'],
fg="green" if result['total'] else "yellow")
if result['total']:
echo_liblist_header()
while True:
for item in result['items']:
echo_liblist_item(item)
if int(result['page'])*int(result['perpage']) >= int(result['total']):
break
if (app.get_setting("enable_prompts") and
click.confirm("Show next libraries?")):
result = get_api_result(
"/lib/search",
dict(query=query, page=str(int(result['page']) + 1))
)
else:
break
@cli.command("install", short_help="Install library")
2014-11-24 22:24:19 +02:00
@click.argument("libid", type=click.INT, nargs=-1, metavar="[LIBRARY_ID]")
@click.option("-v", "--version")
2014-11-24 22:24:19 +02:00
@click.pass_context
def lib_install(ctx, libid, version):
lm = LibraryManager()
2014-11-24 22:24:19 +02:00
for id_ in libid:
click.echo(
"Installing library [ %s ]:" % click.style(str(id_), fg="green"))
try:
if not lm.install(id_, version):
continue
info = lm.get_info(id_)
click.secho(
"The library #%s '%s' has been successfully installed!"
% (str(id_), info['name']), fg="green")
if "dependencies" in info:
click.secho("Installing dependencies:", fg="yellow")
_dependencies = info['dependencies']
if not isinstance(_dependencies, list):
_dependencies = [_dependencies]
for item in _dependencies:
try:
2014-11-24 22:24:19 +02:00
lib_install_dependency(ctx, item)
except AssertionError:
raise exception.LibInstallDependencyError(str(item))
2014-09-06 12:53:17 +03:00
2015-11-26 22:02:59 +02:00
except exception.LibAlreadyInstalled:
click.secho("Already installed", fg="yellow")
2014-11-24 22:24:19 +02:00
def lib_install_dependency(ctx, data):
assert isinstance(data, dict)
query = []
for key in data.keys():
if key in ("authors", "frameworks", "platforms", "keywords"):
values = data[key]
if not isinstance(values, list):
values = [v.strip() for v in values.split(",") if v]
for value in values:
query.append('%s:"%s"' % (key[:-1], value))
elif isinstance(data[key], basestring):
query.append('+"%s"' % data[key])
result = get_api_result("/lib/search", dict(query=" ".join(query)))
assert result['total'] > 0
if result['total'] == 1 or not app.get_setting("enable_prompts"):
ctx.invoke(lib_install, libid=[result['items'][0]['id']])
else:
click.secho(
2015-12-08 18:42:23 +02:00
"Conflict: More than one dependent libraries have been found "
"by request %s:" % json.dumps(data), fg="red")
echo_liblist_header()
for item in result['items']:
echo_liblist_item(item)
deplib_id = click.prompt(
"Please choose one dependent library ID",
type=click.Choice([str(i['id']) for i in result['items']]))
ctx.invoke(lib_install, libid=[int(deplib_id)])
@cli.command("uninstall", short_help="Uninstall libraries")
2014-11-24 22:24:19 +02:00
@click.argument("libid", type=click.INT, nargs=-1)
def lib_uninstall(libid):
lm = LibraryManager()
2014-11-24 22:24:19 +02:00
for id_ in libid:
info = lm.get_info(id_)
if lm.uninstall(id_):
click.secho("The library #%s '%s' has been successfully "
"uninstalled!" % (str(id_), info['name']), fg="green")
@cli.command("list", short_help="List installed libraries")
@click.option("--json-output", is_flag=True)
def lib_list(json_output):
lm = LibraryManager()
items = lm.get_installed().values()
if json_output:
click.echo(json.dumps(items))
return
if not items:
return
echo_liblist_header()
2015-03-13 17:58:45 +02:00
for item in sorted(items, key=lambda i: i['id']):
item['authornames'] = [i['name'] for i in item['authors']]
echo_liblist_item(item)
@cli.command("show", short_help="Show details about installed library")
@click.argument("libid", type=click.INT)
def lib_show(libid):
lm = LibraryManager()
info = lm.get_info(libid)
click.secho(info['name'], fg="cyan")
click.echo("-" * len(info['name']))
_authors = []
for author in info['authors']:
_data = []
for key in ("name", "email", "url", "maintainer"):
if not author[key]:
continue
if key == "email":
_data.append("<%s>" % author[key])
elif key == "maintainer":
_data.append("(maintainer)")
else:
_data.append(author[key])
_authors.append(" ".join(_data))
click.echo("Authors: %s" % ", ".join(_authors))
click.echo("Keywords: %s" % ", ".join(info['keywords']))
if "frameworks" in info:
click.echo("Frameworks: %s" % ", ".join(info['frameworks']))
if "platforms" in info:
click.echo("Platforms: %s" % ", ".join(info['platforms']))
click.echo("Version: %s" % info['version'])
click.echo()
click.echo(info['description'])
click.echo()
@cli.command("update", short_help="Update installed libraries")
@click.argument("libid", type=click.INT, nargs=-1, required=False,
metavar="[LIBRARY_ID]")
2014-11-24 22:24:19 +02:00
@click.pass_context
def lib_update(ctx, libid):
lm = LibraryManager()
for id_, latest_version in (lm.get_latest_versions() or {}).items():
if libid and int(id_) not in libid:
continue
info = lm.get_info(int(id_))
click.echo("Updating [ %s ] %s library:" % (
click.style(id_, fg="yellow"),
click.style(info['name'], fg="cyan")))
current_version = info['version']
if latest_version is None:
click.secho("Unknown library", fg="red")
continue
click.echo("Versions: Current=%s, Latest=%s \t " % (
current_version, latest_version), nl=False)
if current_version == latest_version:
click.echo("[%s]" % (click.style("Up-to-date", fg="green")))
continue
else:
click.echo("[%s]" % (click.style("Out-of-date", fg="red")))
2014-11-24 22:24:19 +02:00
ctx.invoke(lib_uninstall, libid=[int(id_)])
ctx.invoke(lib_install, libid=[int(id_)])
2014-09-08 22:02:57 +03:00
@cli.command("register", short_help="Register new library")
@click.argument("config_url")
2014-09-08 22:02:57 +03:00
def lib_register(config_url):
if (not config_url.startswith("http://") and not
config_url.startswith("https://")):
raise exception.InvalidLibConfURL(config_url)
2014-09-08 22:02:57 +03:00
result = get_api_result("/lib/register", data=dict(config_url=config_url))
if "message" in result and result['message']:
click.secho(result['message'], fg="green" if "successed" in result and
result['successed'] else "red")