Skip to content

Commit 1ea6cd2

Browse files
authored
Merge pull request #240 from slaftos/example-list
Add --list and --rename options to circup example command
2 parents da8f6c2 + 283a499 commit 1ea6cd2

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

circup/backends.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,10 @@ def install_module_py(self, metadata, location=None):
950950
# Copy the directory.
951951
shutil.copytree(source_path, target_path)
952952
else:
953-
target = os.path.basename(source_path)
953+
if "target_name" in metadata:
954+
target = metadata["target_name"]
955+
else:
956+
target = os.path.basename(source_path)
954957
target_path = os.path.join(location, target)
955958
# Copy file.
956959
shutil.copyfile(source_path, target_path)

circup/command_utils.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def completion_for_example(ctx, param, incomplete):
100100
Returns the list of available modules for the command line tab-completion
101101
with the ``circup example`` command.
102102
"""
103+
103104
# pylint: disable=unused-argument, consider-iterating-dictionary
104105
available_examples = get_bundle_examples(get_bundles_list(), avoid_download=True)
105106

@@ -319,14 +320,22 @@ def get_bundle_examples(bundles_list, avoid_download=False):
319320
:return: A dictionary of metadata about the examples available in the
320321
library bundle.
321322
"""
322-
# pylint: disable=too-many-nested-blocks
323+
# pylint: disable=too-many-nested-blocks,too-many-locals
323324
all_the_examples = dict()
325+
bundle_examples = dict()
324326

325327
try:
326328
for bundle in bundles_list:
327329
if not avoid_download or not os.path.isdir(bundle.lib_dir("py")):
328330
ensure_latest_bundle(bundle)
329331
path = bundle.examples_dir("py")
332+
meta_saved = os.path.join(path, "../bundle_examples.json")
333+
if os.path.exists(meta_saved):
334+
with open(meta_saved, "r", encoding="utf-8") as f:
335+
bundle_examples = json.load(f)
336+
all_the_examples.update(bundle_examples)
337+
bundle_examples.clear()
338+
continue
330339
path_examples = _get_modules_file(path, logger)
331340
for lib_name, lib_metadata in path_examples.items():
332341
for _dir_level in os.walk(lib_metadata["path"]):
@@ -337,8 +346,13 @@ def get_bundle_examples(bundles_list, avoid_download=False):
337346
if _dirs[-1] == "":
338347
_dirs.pop(-1)
339348
slug = f"{os.path.sep}".join(_dirs + [_file.replace(".py", "")])
349+
bundle_examples[slug] = os.path.join(_dir_level[0], _file)
340350
all_the_examples[slug] = os.path.join(_dir_level[0], _file)
341351

352+
with open(meta_saved, "w", encoding="utf-8") as f:
353+
json.dump(bundle_examples, f)
354+
bundle_examples.clear()
355+
342356
except NotADirectoryError:
343357
# Bundle does not have new style examples directory
344358
# so we cannot include its examples.

circup/commands.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ def main( # pylint: disable=too-many-locals
178178
else (cpy_version, board_id)
179179
)
180180
click.echo(
181-
"Found device at {}, running CircuitPython {}.".format(
182-
device_path, cpy_version
181+
"Found device {} at {}, running CircuitPython {}.".format(
182+
board_id, device_path, cpy_version
183183
)
184184
)
185185
try:
@@ -406,31 +406,53 @@ def install(
406406

407407
@main.command()
408408
@click.option("--overwrite", is_flag=True, help="Overwrite the file if it exists.")
409+
@click.option("--list", "-ls", "op_list", is_flag=True, help="List available examples.")
410+
@click.option("--rename", is_flag=True, help="Install the example as code.py.")
409411
@click.argument(
410-
"examples", required=True, nargs=-1, shell_complete=completion_for_example
412+
"examples", required=False, nargs=-1, shell_complete=completion_for_example
411413
)
412414
@click.pass_context
413-
def example(ctx, examples, overwrite):
415+
def example(ctx, examples, op_list, rename, overwrite):
414416
"""
415417
Copy named example(s) from a bundle onto the device. Multiple examples
416418
can be installed at once by providing more than one example name, each
417419
separated by a space.
418420
"""
419421

422+
if op_list:
423+
if examples:
424+
click.echo("\n".join(completion_for_example(ctx, "", examples)))
425+
else:
426+
click.echo("Available example libraries:")
427+
available_examples = get_bundle_examples(
428+
get_bundles_list(), avoid_download=True
429+
)
430+
lib_names = {
431+
str(key.split(os.path.sep)[0]): value
432+
for key, value in available_examples.items()
433+
}
434+
click.echo("\n".join(sorted(lib_names.keys())))
435+
return
436+
420437
for example_arg in examples:
421438
available_examples = get_bundle_examples(
422439
get_bundles_list(), avoid_download=True
423440
)
424441
if example_arg in available_examples:
425442
filename = available_examples[example_arg].split(os.path.sep)[-1]
443+
install_metadata = {"path": available_examples[example_arg]}
444+
445+
filename = available_examples[example_arg].split(os.path.sep)[-1]
446+
if rename:
447+
if os.path.isfile(available_examples[example_arg]):
448+
filename = "code.py"
449+
install_metadata["target_name"] = filename
426450

427451
if overwrite or not ctx.obj["backend"].file_exists(filename):
428452
click.echo(
429453
f"{'Copying' if not overwrite else 'Overwriting'}: {filename}"
430454
)
431-
ctx.obj["backend"].install_module_py(
432-
{"path": available_examples[example_arg]}, location=""
433-
)
455+
ctx.obj["backend"].install_module_py(install_metadata, location="")
434456
else:
435457
click.secho(
436458
f"File: {filename} already exists. Use --overwrite if you wish to replace it.",

0 commit comments

Comments
 (0)