Add --list and --rename options to example
Added caching of example library example metadata, to speed up tab completion and --list returns --rename option will rename output to code.py if example resolves to single file Changed connection announcement to include board name
This commit is contained in:
parent
da8f6c26c5
commit
bd834c4603
3 changed files with 50 additions and 9 deletions
|
|
@ -950,7 +950,10 @@ class DiskBackend(Backend):
|
||||||
# Copy the directory.
|
# Copy the directory.
|
||||||
shutil.copytree(source_path, target_path)
|
shutil.copytree(source_path, target_path)
|
||||||
else:
|
else:
|
||||||
target = os.path.basename(source_path)
|
if "target_name" in metadata:
|
||||||
|
target = metadata["target_name"]
|
||||||
|
else:
|
||||||
|
target = os.path.basename(source_path)
|
||||||
target_path = os.path.join(location, target)
|
target_path = os.path.join(location, target)
|
||||||
# Copy file.
|
# Copy file.
|
||||||
shutil.copyfile(source_path, target_path)
|
shutil.copyfile(source_path, target_path)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ Functions called from commands in order to provide behaviors and return informat
|
||||||
import ctypes
|
import ctypes
|
||||||
import glob
|
import glob
|
||||||
import os
|
import os
|
||||||
|
import pickle
|
||||||
|
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -100,6 +101,7 @@ def completion_for_example(ctx, param, incomplete):
|
||||||
Returns the list of available modules for the command line tab-completion
|
Returns the list of available modules for the command line tab-completion
|
||||||
with the ``circup example`` command.
|
with the ``circup example`` command.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# pylint: disable=unused-argument, consider-iterating-dictionary
|
# pylint: disable=unused-argument, consider-iterating-dictionary
|
||||||
available_examples = get_bundle_examples(get_bundles_list(), avoid_download=True)
|
available_examples = get_bundle_examples(get_bundles_list(), avoid_download=True)
|
||||||
|
|
||||||
|
|
@ -319,14 +321,22 @@ def get_bundle_examples(bundles_list, avoid_download=False):
|
||||||
:return: A dictionary of metadata about the examples available in the
|
:return: A dictionary of metadata about the examples available in the
|
||||||
library bundle.
|
library bundle.
|
||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-nested-blocks
|
# pylint: disable=too-many-nested-blocks,too-many-locals
|
||||||
all_the_examples = dict()
|
all_the_examples = dict()
|
||||||
|
bundle_examples = dict()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for bundle in bundles_list:
|
for bundle in bundles_list:
|
||||||
if not avoid_download or not os.path.isdir(bundle.lib_dir("py")):
|
if not avoid_download or not os.path.isdir(bundle.lib_dir("py")):
|
||||||
ensure_latest_bundle(bundle)
|
ensure_latest_bundle(bundle)
|
||||||
path = bundle.examples_dir("py")
|
path = bundle.examples_dir("py")
|
||||||
|
meta_saved = os.path.join(path, "../bundle_examples.pickle")
|
||||||
|
if os.path.exists(meta_saved):
|
||||||
|
with open(meta_saved, "rb") as f:
|
||||||
|
bundle_examples = pickle.load(f)
|
||||||
|
all_the_examples.update(bundle_examples)
|
||||||
|
bundle_examples.clear()
|
||||||
|
continue
|
||||||
path_examples = _get_modules_file(path, logger)
|
path_examples = _get_modules_file(path, logger)
|
||||||
for lib_name, lib_metadata in path_examples.items():
|
for lib_name, lib_metadata in path_examples.items():
|
||||||
for _dir_level in os.walk(lib_metadata["path"]):
|
for _dir_level in os.walk(lib_metadata["path"]):
|
||||||
|
|
@ -337,7 +347,11 @@ def get_bundle_examples(bundles_list, avoid_download=False):
|
||||||
if _dirs[-1] == "":
|
if _dirs[-1] == "":
|
||||||
_dirs.pop(-1)
|
_dirs.pop(-1)
|
||||||
slug = f"{os.path.sep}".join(_dirs + [_file.replace(".py", "")])
|
slug = f"{os.path.sep}".join(_dirs + [_file.replace(".py", "")])
|
||||||
|
bundle_examples[slug] = os.path.join(_dir_level[0], _file)
|
||||||
all_the_examples[slug] = os.path.join(_dir_level[0], _file)
|
all_the_examples[slug] = os.path.join(_dir_level[0], _file)
|
||||||
|
with open(meta_saved, "wb") as f:
|
||||||
|
pickle.dump(bundle_examples, f)
|
||||||
|
bundle_examples.clear()
|
||||||
|
|
||||||
except NotADirectoryError:
|
except NotADirectoryError:
|
||||||
# Bundle does not have new style examples directory
|
# Bundle does not have new style examples directory
|
||||||
|
|
|
||||||
|
|
@ -178,8 +178,8 @@ def main( # pylint: disable=too-many-locals
|
||||||
else (cpy_version, board_id)
|
else (cpy_version, board_id)
|
||||||
)
|
)
|
||||||
click.echo(
|
click.echo(
|
||||||
"Found device at {}, running CircuitPython {}.".format(
|
"Found device {} at {}, running CircuitPython {}.".format(
|
||||||
device_path, cpy_version
|
board_id, device_path, cpy_version
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|
@ -406,31 +406,55 @@ def install(
|
||||||
|
|
||||||
@main.command()
|
@main.command()
|
||||||
@click.option("--overwrite", is_flag=True, help="Overwrite the file if it exists.")
|
@click.option("--overwrite", is_flag=True, help="Overwrite the file if it exists.")
|
||||||
|
@click.option("--list", "-ls", "op_list", is_flag=True, help="List available examples.")
|
||||||
|
@click.option("--rename", is_flag=True, help="Install the example as code.py.")
|
||||||
@click.argument(
|
@click.argument(
|
||||||
"examples", required=True, nargs=-1, shell_complete=completion_for_example
|
"examples", required=False, nargs=-1, shell_complete=completion_for_example
|
||||||
)
|
)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
def example(ctx, examples, overwrite):
|
def example(ctx, examples, op_list, rename, overwrite):
|
||||||
"""
|
"""
|
||||||
Copy named example(s) from a bundle onto the device. Multiple examples
|
Copy named example(s) from a bundle onto the device. Multiple examples
|
||||||
can be installed at once by providing more than one example name, each
|
can be installed at once by providing more than one example name, each
|
||||||
separated by a space.
|
separated by a space.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if op_list:
|
||||||
|
if examples:
|
||||||
|
click.echo("\n".join(completion_for_example(ctx, "", examples)))
|
||||||
|
else:
|
||||||
|
click.echo("Available example libraries:")
|
||||||
|
available_examples = get_bundle_examples(
|
||||||
|
get_bundles_list(), avoid_download=True
|
||||||
|
)
|
||||||
|
lib_names = {
|
||||||
|
str(key.split(os.path.sep)[0]): value
|
||||||
|
for key, value in available_examples.items()
|
||||||
|
}
|
||||||
|
click.echo("\n".join(sorted(lib_names.keys())))
|
||||||
|
return
|
||||||
|
|
||||||
for example_arg in examples:
|
for example_arg in examples:
|
||||||
available_examples = get_bundle_examples(
|
available_examples = get_bundle_examples(
|
||||||
get_bundles_list(), avoid_download=True
|
get_bundles_list(), avoid_download=True
|
||||||
)
|
)
|
||||||
if example_arg in available_examples:
|
if example_arg in available_examples:
|
||||||
filename = available_examples[example_arg].split(os.path.sep)[-1]
|
filename = available_examples[example_arg].split(os.path.sep)[-1]
|
||||||
|
install_metadata = {"path": available_examples[example_arg]}
|
||||||
|
|
||||||
|
# check of we are dealing with a file that needs to be pushed as code.py
|
||||||
|
# or a directory that needs to be copied raw
|
||||||
|
filename = available_examples[example_arg].split(os.path.sep)[-1]
|
||||||
|
if rename:
|
||||||
|
if os.path.isfile(available_examples[example_arg]):
|
||||||
|
filename = "code.py"
|
||||||
|
install_metadata["target_name"] = filename
|
||||||
|
|
||||||
if overwrite or not ctx.obj["backend"].file_exists(filename):
|
if overwrite or not ctx.obj["backend"].file_exists(filename):
|
||||||
click.echo(
|
click.echo(
|
||||||
f"{'Copying' if not overwrite else 'Overwriting'}: {filename}"
|
f"{'Copying' if not overwrite else 'Overwriting'}: {filename}"
|
||||||
)
|
)
|
||||||
ctx.obj["backend"].install_module_py(
|
ctx.obj["backend"].install_module_py(install_metadata, location="")
|
||||||
{"path": available_examples[example_arg]}, location=""
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
click.secho(
|
click.secho(
|
||||||
f"File: {filename} already exists. Use --overwrite if you wish to replace it.",
|
f"File: {filename} already exists. Use --overwrite if you wish to replace it.",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue