- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5
feat: place examples in pack directories for cli #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
0f3293f
              c5c9f84
              1092dcb
              14102ad
              d423377
              683b4c3
              71f9de4
              3a1ee8b
              d3b531c
              73d083e
              61a9bd6
              012a45e
              d90a271
              c12f6b5
              c0bead8
              63ac630
              e0a2c75
              81fa5cf
              10771b1
              4ee36af
              4019e36
              65fd2c7
              74e992b
              d53fab8
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| **Added:** | ||
|  | ||
| * <news item> | ||
|  | ||
| **Changed:** | ||
|  | ||
| * change examples directory structure to insert the name of the ``pack" that the examples exemplify. | ||
|  | ||
| **Deprecated:** | ||
|  | ||
| * <news item> | ||
|  | ||
| **Removed:** | ||
|  | ||
| * <news item> | ||
|  | ||
| **Fixed:** | ||
|  | ||
| * <news item> | ||
|  | ||
| **Security:** | ||
|  | ||
| * <news item> | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -26,7 +26,7 @@ | |
|  | ||
|  | ||
| # Examples | ||
| def _installed_examples_dir() -> Path: | ||
| def _get_examples_dir() -> Path: | ||
| """Return the absolute path to the installed examples directory. | ||
|  | ||
| Returns | ||
|  | @@ -52,27 +52,33 @@ def _installed_examples_dir() -> Path: | |
| ) | ||
|  | ||
|  | ||
| def list_examples() -> List[str]: | ||
| """List installed example names. | ||
| def map_pack_to_examples() -> dict[str, List[str]]: | ||
| """Return a dictionary mapping pack name -> list of example | ||
| subdirectories. | ||
|  | ||
| Returns | ||
| ------- | ||
| list of str | ||
| Installed example directory names. | ||
| dict: | ||
| pack name -> list of example subdirectory names | ||
| """ | ||
| root = _installed_examples_dir() | ||
| root = _get_examples_dir() | ||
| if not root.exists(): | ||
| return [] | ||
| return sorted([p.name for p in root.iterdir() if p.is_dir()]) | ||
| return {} | ||
| examples_by_pack = {} | ||
| for pack_dir in sorted(root.iterdir()): | ||
| if pack_dir.is_dir(): | ||
| exdirs = sorted(p.name for p in pack_dir.iterdir() if p.is_dir()) | ||
| examples_by_pack[pack_dir.name] = exdirs | ||
| return examples_by_pack | ||
|  | ||
|  | ||
| def copy_example(example: str) -> Path: | ||
| def copy_example(pack_example: str) -> Path: | ||
| """Copy an example into the current working directory. | ||
|  | ||
| Parameters | ||
| ---------- | ||
| example : str | ||
| Example directory name under the installed examples root. | ||
| Pack and example name in the form ``<pack>/<exdir>``. | ||
|  | ||
| Returns | ||
| ------- | ||
|  | @@ -81,15 +87,20 @@ def copy_example(example: str) -> Path: | |
|  | ||
| Raises | ||
| ------ | ||
| ValueError | ||
| If the format is invalid. | ||
| FileNotFoundError | ||
| If the example directory does not exist. | ||
| FileExistsError | ||
| If the destination directory already exists. | ||
| """ | ||
| src = _installed_examples_dir() / example | ||
| if "/" not in pack_example: | ||
| raise ValueError("Example must be specified as <pack>/<exdir>") | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enforces new format of copying examples. This format is  | ||
| pack, exdir = pack_example.split("/", 1) | ||
| src = _get_examples_dir() / pack / exdir | ||
| if not src.exists() or not src.is_dir(): | ||
| raise FileNotFoundError(f"Example not found: {example}") | ||
| dest = Path.cwd() / example | ||
| raise FileNotFoundError(f"Example not found: {pack_example}") | ||
| dest = Path.cwd() / exdir | ||
| if dest.exists(): | ||
| raise FileExistsError(f"Destination {dest} already exists") | ||
| copytree(src, dest) | ||
|  | @@ -163,7 +174,9 @@ def _build_parser() -> argparse.ArgumentParser: | |
| _parser=p_example | ||
| ) | ||
| p_example_copy = sub_ex.add_parser("copy", help="Copy an example to CWD") | ||
| p_example_copy.add_argument("name", metavar="EXAMPLE", help="Example name") | ||
| p_example_copy.add_argument( | ||
| "name", metavar="EXAMPLE", help="Example name <pack>/<exdir>" | ||
| ) | ||
| p_example_copy.set_defaults(_parser=p_example) | ||
| p_example.set_defaults(example_cmd=None) | ||
|  | ||
|  | @@ -339,10 +352,11 @@ def _cmd_example(ns: argparse.Namespace) -> int: | |
| print(f"Example copied to: {out}") | ||
| return 0 | ||
| if ns.example_cmd == "list": | ||
| for g in list_examples(): | ||
| print(g) | ||
| for pack, examples in map_pack_to_examples().items(): | ||
| print(f"{pack}:") | ||
| for ex in examples: | ||
| print(f" - {ex}") | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prints examples in the format of instead of  | ||
| return 0 | ||
|  | ||
| plog.error("Unknown example subcommand.") | ||
| ns._parser.print_help() | ||
| return 2 | ||
|  | ||
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import pytest | ||
|  | ||
| from diffpy.cmi import cli | ||
|  | ||
|  | ||
| @pytest.mark.parametrize( | ||
| "structure, expected", | ||
|          | ||
| [ | ||
| # case: no packs, no examples | ||
| ([], {}), | ||
| # case: one pack with one example | ||
|          | ||
| ([("packA", ["ex1"])], {"packA": ["ex1"]}), | ||
| # case: one pack with multiple examples | ||
| ([("packA", ["ex1", "ex2"])], {"packA": ["ex1", "ex2"]}), | ||
| # case: multiple packs with one example each | ||
| ( | ||
| [("packA", ["ex1"]), ("packB", ["ex2"])], | ||
| {"packA": ["ex1"], "packB": ["ex2"]}, | ||
| ), | ||
| # case: multiple packs with multiple examples | ||
| ( | ||
| [("packA", ["ex1", "ex2"]), ("packB", ["ex3", "ex4"])], | ||
| {"packA": ["ex1", "ex2"], "packB": ["ex3", "ex4"]}, | ||
| ), | ||
| ], | ||
| ) | ||
| def test_map_pack_to_examples(tmp_path, mocker, structure, expected): | ||
| """Finds examples directory and returns a dictionary mapping packs | ||
| to examples.""" | ||
| # example input: build example structure | ||
|          | ||
| for pack, exdirs in structure: | ||
| packdir = tmp_path / pack | ||
| packdir.mkdir() | ||
| for ex in exdirs: | ||
| (packdir / ex).mkdir() | ||
| # patch _get_examples_dir to point to tmp_path | ||
| mocker.patch.object(cli, "_get_examples_dir", return_value=tmp_path) | ||
|          | ||
| # expected behavior: a dictionary mapping pack to lists of examples | ||
| result = cli.map_pack_to_examples() | ||
| assert result == expected | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
returns a dict, mapping pack name (str) to its corresponding list of examples (list of strs). This replaces previous format were all the examples are stored in one list.