mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-30 18:17:13 +02:00
Show detailed info about a library using pio lib show
command // Resolve #430
This commit is contained in:
@ -1,3 +1,3 @@
|
||||
[settings]
|
||||
line_length=79
|
||||
known_third_party=bottle,click,lockfile,pytest,requests,semantic_version,serial,SCons
|
||||
known_third_party=arrow,bottle,click,lockfile,pytest,requests,SCons,semantic_version,serial
|
||||
|
@ -14,6 +14,9 @@ PlatformIO 3.0
|
||||
- Recent and popular keywords
|
||||
- Featured libraries (today, week, month)
|
||||
|
||||
* Show detailed info about a library using `pio lib show <http://docs.platformio.org/page/userguide/lib/cmd_show.html>`__
|
||||
command
|
||||
(`issue #430 <https://github.com/platformio/platformio-core/issues/430>`_)
|
||||
* Added support for templated methods in ``*.ino to *.cpp`` convertor
|
||||
(`pull #858 <https://github.com/platformio/platformio-core/pull/858>`_)
|
||||
* Produce less noisy output when ``-s/--silent`` options are used for
|
||||
|
2
docs
2
docs
Submodule docs updated: 308775747a...b709064430
@ -14,7 +14,7 @@
|
||||
|
||||
import sys
|
||||
|
||||
VERSION = (3, 3, "0a1")
|
||||
VERSION = (3, 3, "0a2")
|
||||
__version__ = ".".join([str(s) for s in VERSION])
|
||||
|
||||
__title__ = "platformio"
|
||||
|
@ -12,12 +12,14 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# pylint: disable=too-many-branches, too-many-locals
|
||||
|
||||
import json
|
||||
from datetime import datetime
|
||||
from os.path import join
|
||||
from time import sleep
|
||||
from urllib import quote
|
||||
|
||||
import arrow
|
||||
import click
|
||||
|
||||
from platformio import exception, util
|
||||
@ -46,7 +48,7 @@ from platformio.util import get_api_result
|
||||
@click.pass_context
|
||||
def cli(ctx, **options):
|
||||
# skip commands that don't need storage folder
|
||||
if ctx.invoked_subcommand in ("search", "register", "stats") or \
|
||||
if ctx.invoked_subcommand in ("search", "show", "register", "stats") or \
|
||||
(len(ctx.args) == 2 and ctx.args[1] in ("-h", "--help")):
|
||||
return
|
||||
storage_dir = options['storage_dir']
|
||||
@ -158,7 +160,7 @@ def echo_liblist_item(item):
|
||||
description=description))
|
||||
|
||||
|
||||
@cli.command("search", short_help="Search for library")
|
||||
@cli.command("search", short_help="Search for a library")
|
||||
@click.argument("query", required=False, nargs=-1)
|
||||
@click.option("--json-output", is_flag=True)
|
||||
@click.option("--page", type=click.INT, default=1)
|
||||
@ -247,8 +249,7 @@ def lib_list(lm, json_output):
|
||||
items = lm.get_installed()
|
||||
|
||||
if json_output:
|
||||
click.echo(json.dumps(items))
|
||||
return
|
||||
return click.echo(json.dumps(items))
|
||||
|
||||
if not items:
|
||||
return
|
||||
@ -260,28 +261,40 @@ def lib_list(lm, json_output):
|
||||
echo_liblist_item(item)
|
||||
|
||||
|
||||
@cli.command("show", short_help="Show details about installed library")
|
||||
@click.pass_obj
|
||||
@cli.command("show", short_help="Show detailed info about a library")
|
||||
@click.argument("library", metavar="[LIBRARY]")
|
||||
def lib_show(lm, library): # pylint: disable=too-many-branches
|
||||
name, requirements, url = lm.parse_pkg_name(library)
|
||||
package_dir = lm.get_package_dir(name, requirements, url)
|
||||
if not package_dir:
|
||||
click.secho(
|
||||
"%s @ %s is not installed" % (name, requirements or "*"),
|
||||
fg="yellow")
|
||||
return
|
||||
@click.option("--json-output", is_flag=True)
|
||||
def lib_show(library, json_output):
|
||||
lm = LibraryManager()
|
||||
name, requirements, _ = lm.parse_pkg_name(library)
|
||||
lib_id = lm.get_pkg_id_by_name(
|
||||
name, requirements, silent=json_output, interactive=not json_output)
|
||||
lib = get_api_result("/lib/info/%d" % lib_id, cache_valid="1d")
|
||||
if json_output:
|
||||
return click.echo(json.dumps(lib))
|
||||
|
||||
manifest = lm.load_manifest(package_dir)
|
||||
|
||||
click.secho(manifest['name'], fg="cyan")
|
||||
click.echo("=" * len(manifest['name']))
|
||||
if "description" in manifest:
|
||||
click.echo(manifest['description'])
|
||||
click.secho(lib['name'], fg="cyan")
|
||||
click.echo("=" * len(lib['name']))
|
||||
click.echo(lib['description'])
|
||||
click.echo()
|
||||
|
||||
click.echo("Version: %s, released %s" %
|
||||
(lib['version']['name'],
|
||||
arrow.get(lib['version']['released']).humanize()))
|
||||
click.echo("Registry ID: %d" % lib['id'])
|
||||
click.echo("Manifest: %s" % lib['confurl'])
|
||||
for key in ("homepage", "repository", "license"):
|
||||
if key not in lib or not lib[key]:
|
||||
continue
|
||||
if isinstance(lib[key], list):
|
||||
click.echo("%s: %s" % (key.title(), ", ".join(lib[key])))
|
||||
else:
|
||||
click.echo("%s: %s" % (key.title(), lib[key]))
|
||||
|
||||
blocks = []
|
||||
|
||||
_authors = []
|
||||
for author in manifest.get("authors", []):
|
||||
for author in lib.get("authors", []):
|
||||
_data = []
|
||||
for key in ("name", "email", "url", "maintainer"):
|
||||
if not author[key]:
|
||||
@ -294,19 +307,33 @@ def lib_show(lm, library): # pylint: disable=too-many-branches
|
||||
_data.append(author[key])
|
||||
_authors.append(" ".join(_data))
|
||||
if _authors:
|
||||
click.echo("Authors: %s" % ", ".join(_authors))
|
||||
blocks.append(("Authors", _authors))
|
||||
|
||||
for key in ("keywords", "frameworks", "platforms", "license", "url",
|
||||
"version"):
|
||||
if key not in manifest:
|
||||
continue
|
||||
if isinstance(manifest[key], list):
|
||||
click.echo("%s: %s" % (key.title(), ", ".join(manifest[key])))
|
||||
else:
|
||||
click.echo("%s: %s" % (key.title(), manifest[key]))
|
||||
blocks.append(("Keywords", lib['keywords']))
|
||||
if lib['frameworks']:
|
||||
blocks.append(("Compatible Frameworks", lib['frameworks']))
|
||||
if lib['platforms']:
|
||||
blocks.append(("Compatible Platforms", lib['platforms']))
|
||||
blocks.append(("Headers", lib['headers']))
|
||||
blocks.append(("Examples", lib['examples']))
|
||||
blocks.append(("Versions", [
|
||||
"%s, released %s" % (v['name'], arrow.get(v['released']).humanize())
|
||||
for v in lib['versions']
|
||||
]))
|
||||
blocks.append(("Unique Downloads", [
|
||||
"Today: %s" % lib['dlstats']['day'], "Week: %s" %
|
||||
lib['dlstats']['week'], "Month: %s" % lib['dlstats']['month']
|
||||
]))
|
||||
|
||||
for (title, rows) in blocks:
|
||||
click.echo()
|
||||
click.secho(title, bold=True)
|
||||
click.echo("-" * len(title))
|
||||
for row in rows:
|
||||
click.echo(row)
|
||||
|
||||
|
||||
@cli.command("register", short_help="Register new library")
|
||||
@cli.command("register", short_help="Register a new library")
|
||||
@click.argument("config_url")
|
||||
def lib_register(config_url):
|
||||
if (not config_url.startswith("http://") and
|
||||
@ -353,8 +380,7 @@ def lib_stats(json_output):
|
||||
name=click.style(
|
||||
item['name'], fg="cyan"),
|
||||
date=str(
|
||||
datetime.strptime(item['date'].replace("Z", "UTC"),
|
||||
"%Y-%m-%dT%H:%M:%S%Z")
|
||||
arrow.get(item['date']).humanize()
|
||||
if "date" in item else ""),
|
||||
url=click.style(
|
||||
"http://platformio.org/lib/show/%s/%s" % (item[
|
||||
|
@ -19,6 +19,7 @@ import os
|
||||
from hashlib import md5
|
||||
from os.path import dirname, join
|
||||
|
||||
import arrow
|
||||
import click
|
||||
import semantic_version
|
||||
|
||||
@ -129,13 +130,8 @@ class LibraryManager(BasePkgManager):
|
||||
def max_satisfying_repo_version(versions, requirements=None):
|
||||
|
||||
def _cmp_dates(datestr1, datestr2):
|
||||
from datetime import datetime
|
||||
assert "T" in datestr1 and "T" in datestr2
|
||||
dateformat = "%Y-%m-%d %H:%M:%S"
|
||||
date1 = datetime.strptime(datestr1[:-1].replace("T", " "),
|
||||
dateformat)
|
||||
date2 = datetime.strptime(datestr2[:-1].replace("T", " "),
|
||||
dateformat)
|
||||
date1 = arrow.get(datestr1)
|
||||
date2 = arrow.get(datestr2)
|
||||
if date1 == date2:
|
||||
return 0
|
||||
return -1 if date1 < date2 else 1
|
||||
@ -150,7 +146,7 @@ class LibraryManager(BasePkgManager):
|
||||
for v in versions:
|
||||
specver = None
|
||||
try:
|
||||
specver = semantic_version.Version(v['version'], partial=True)
|
||||
specver = semantic_version.Version(v['name'], partial=True)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
@ -158,26 +154,26 @@ class LibraryManager(BasePkgManager):
|
||||
if not specver or specver not in reqspec:
|
||||
continue
|
||||
if not item or semantic_version.Version(
|
||||
item['version'], partial=True) < specver:
|
||||
item['name'], partial=True) < specver:
|
||||
item = v
|
||||
elif requirements:
|
||||
if requirements == v['version']:
|
||||
if requirements == v['name']:
|
||||
return v
|
||||
else:
|
||||
if not item or _cmp_dates(item['date'], v['date']) == -1:
|
||||
if not item or _cmp_dates(item['released'],
|
||||
v['released']) == -1:
|
||||
item = v
|
||||
return item
|
||||
|
||||
def get_latest_repo_version(self, name, requirements):
|
||||
item = self.max_satisfying_repo_version(
|
||||
util.get_api_result(
|
||||
"/lib/versions/%d" % self._get_pkg_id_by_name(name,
|
||||
requirements),
|
||||
cache_valid="1h"),
|
||||
"/lib/info/%d" % self.get_pkg_id_by_name(name, requirements),
|
||||
cache_valid="1d")['versions'],
|
||||
requirements)
|
||||
return item['version'] if item else None
|
||||
return item['name'] if item else None
|
||||
|
||||
def _get_pkg_id_by_name(self,
|
||||
def get_pkg_id_by_name(self,
|
||||
name,
|
||||
requirements,
|
||||
silent=False,
|
||||
@ -222,7 +218,7 @@ class LibraryManager(BasePkgManager):
|
||||
|
||||
try:
|
||||
if not _url:
|
||||
_name = "id=%d" % self._get_pkg_id_by_name(
|
||||
_name = "id=%d" % self.get_pkg_id_by_name(
|
||||
_name,
|
||||
_requirements,
|
||||
silent=silent,
|
||||
@ -299,6 +295,9 @@ class LibraryManager(BasePkgManager):
|
||||
if result['total'] == 1:
|
||||
lib_info = result['items'][0]
|
||||
elif result['total'] > 1:
|
||||
if silent and not interactive:
|
||||
lib_info = result['items'][0]
|
||||
else:
|
||||
click.secho(
|
||||
"Conflict: More than one library has been found "
|
||||
"by request %s:" % json.dumps(filters),
|
||||
@ -318,7 +317,8 @@ class LibraryManager(BasePkgManager):
|
||||
else:
|
||||
deplib_id = click.prompt(
|
||||
"Please choose library ID",
|
||||
type=click.Choice([str(i['id']) for i in result['items']]))
|
||||
type=click.Choice(
|
||||
[str(i['id']) for i in result['items']]))
|
||||
for item in result['items']:
|
||||
if item['id'] == int(deplib_id):
|
||||
lib_info = item
|
||||
|
9
setup.py
9
setup.py
@ -18,13 +18,14 @@ from platformio import (__author__, __description__, __email__, __license__,
|
||||
__title__, __url__, __version__)
|
||||
|
||||
install_requires = [
|
||||
"arrow<1",
|
||||
"bottle<0.13",
|
||||
"click>=5,<6",
|
||||
"lockfile>=0.9.1,<0.13",
|
||||
"requests>=2.4.0,<3",
|
||||
"semantic_version>=2.5.0",
|
||||
"colorama",
|
||||
"pyserial>=3,<4"
|
||||
"lockfile>=0.9.1,<0.13",
|
||||
"pyserial>=3,<4",
|
||||
"requests>=2.4.0,<3",
|
||||
"semantic_version>=2.5.0"
|
||||
]
|
||||
|
||||
setup(
|
||||
|
Reference in New Issue
Block a user