Skip to content

Commit 1ee857b

Browse files
committed
Support optional glob match in client ls
plus some testing improvements
1 parent 8b895ff commit 1ee857b

File tree

5 files changed

+71
-12
lines changed

5 files changed

+71
-12
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## [Unreleased]
88

99
### Added
10+
- client: glob-style filtering by name or image alias in `ls` command
11+
1012
### Changed
1113
### Deprecated
1214
### Removed

fuzzbucket_client/__main__.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,10 @@ def main(sysargs: list[str] = sys.argv[:]) -> int:
254254
parser_list = subparsers.add_parser(
255255
"ls",
256256
aliases=["l", "list"],
257-
help="list your boxes",
257+
help="list matching boxes",
258258
formatter_class=CustomHelpFormatter,
259259
)
260+
parser_list.add_argument("box_match", nargs="?")
260261
parser_list.set_defaults(func=client.ls)
261262

262263
parser_update = subparsers.add_parser(
@@ -710,11 +711,20 @@ def logout(self, *_):
710711
return True
711712

712713
@_command
713-
def ls(self, *_):
714+
def ls(self, known_args: argparse.Namespace, _):
714715
log.debug(f"fetching boxes for user={self._user!r}")
715-
boxes = self._list_boxes()
716-
log.info(f"fetched boxes for user={self._user!r} count={len(boxes)}")
717-
print(self._format_boxes(boxes), end="")
716+
717+
matching_boxes = self._find_boxes(known_args.box_match)
718+
719+
if matching_boxes is None:
720+
log.error(f"no boxes found matching {known_args.box_match!r}")
721+
722+
return False
723+
724+
log.info(f"fetched boxes for user={self._user!r} count={len(matching_boxes)}")
725+
726+
print(self._format_boxes(matching_boxes), end="")
727+
718728
return True
719729

720730
@_command
@@ -1091,27 +1101,40 @@ def whoami(self, *_):
10911101

10921102
def _find_box(self, box_search):
10931103
results = self._find_boxes(box_search)
1104+
10941105
if results is None:
10951106
return None
1107+
10961108
return results[0]
10971109

10981110
def _find_boxes(self, box_search):
10991111
boxes = self._list_boxes()
1112+
1113+
if box_search is None:
1114+
return boxes
1115+
11001116
results = []
1117+
11011118
for box in boxes:
11021119
log.debug(f"finding box_search={box_search!r} considering box={box!r}")
1120+
11031121
if box.get("name") is not None and fnmatch.fnmatchcase(
11041122
box["name"], box_search
11051123
):
11061124
results.append(box)
1125+
11071126
continue
1127+
11081128
if box.get("image_alias") is not None and fnmatch.fnmatchcase(
11091129
box["image_alias"], box_search
11101130
):
11111131
results.append(box)
1132+
11121133
continue
1134+
11131135
if len(results) == 0:
11141136
return None
1137+
11151138
return results
11161139

11171140
def _list_boxes(self):

justfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ set shell := ["bash", "-c"]
22

33
default:
44
hatch run lint
5-
hatch run test
5+
FUZZBUCKET_AUTH_PROVIDER=github-oauth hatch run test
6+
FUZZBUCKET_AUTH_PROVIDER=oauth hatch run test --cov-append
67

78
deps:
89
hatch run yarn install

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ lint = [
7171
"black --check --diff {root}",
7272
"pytest -m mypy --no-cov"
7373
]
74-
test = "pytest --cov-fail-under=89"
74+
test = "pytest --cov-fail-under=89 {args}"
7575
fmt = [
7676
"isort {root}",
7777
"black {root}"

tests/test_fuzzbucket_client.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ def config_setup(tmpdir, monkeypatch):
5151
os.environ.pop("FUZZBUCKET_CREDENTIALS", None)
5252

5353

54+
def test_trinary_behavior():
55+
assert str(fuzzbucket_client.__main__._TrinaryBehavior.ALWAYS) == "always"
56+
57+
with pytest.raises(ValueError):
58+
fuzzbucket_client.__main__._TrinaryBehavior("boguster")
59+
60+
5461
def test_default_client():
5562
assert fuzzbucket_client.__main__.default_client() is not None
5663

@@ -279,13 +286,15 @@ def test_client_failing_func(monkeypatch):
279286

280287

281288
@pytest.mark.parametrize(
282-
("args",),
289+
("args", "returning"),
283290
[
284-
pytest.param(("ls",), id="empty"),
285-
pytest.param(("-j", "list"), id="output_json"),
291+
pytest.param(("ls",), 0, id="empty"),
292+
pytest.param(("-j", "list"), 0, id="output_json"),
293+
pytest.param(("list", "spark*"), 0, id="matching"),
294+
pytest.param(("list", "*giraffes*"), 86, id="not_matching"),
286295
],
287296
)
288-
def test_client_list(monkeypatch, args):
297+
def test_client_ls(monkeypatch, args, returning):
289298
client = fuzzbucket_client.__main__.Client()
290299
monkeypatch.setattr(fuzzbucket_client.__main__, "default_client", lambda: client)
291300
monkeypatch.setattr(
@@ -298,7 +307,7 @@ def test_client_list(monkeypatch, args):
298307
),
299308
)
300309
ret = fuzzbucket_client.__main__.main(["fuzzbucket-client"] + list(args))
301-
assert ret == 0
310+
assert ret == returning
302311

303312

304313
@pytest.mark.parametrize(
@@ -1351,6 +1360,30 @@ def test_client_delete_key(monkeypatch, caplog):
13511360
assert "deleted key" in caplog.text
13521361

13531362

1363+
@pytest.mark.parametrize(
1364+
("args", "response", "out_match", "returning"),
1365+
[
1366+
pytest.param(("whoami",), '{"you":"castleface"}', "castleface", 0),
1367+
pytest.param(("-j", "whoami"), '{"you":"castleface"}', "castleface", 0),
1368+
pytest.param(("whoami",), "{}", None, 86),
1369+
],
1370+
)
1371+
def test_client_whoami(args, response, out_match, returning, monkeypatch, capsys):
1372+
client = fuzzbucket_client.__main__.Client()
1373+
monkeypatch.setattr(fuzzbucket_client.__main__, "default_client", lambda: client)
1374+
1375+
monkeypatch.setattr(
1376+
client,
1377+
"_urlopen",
1378+
gen_fake_urlopen(io.StringIO(response)),
1379+
)
1380+
1381+
ret = fuzzbucket_client.__main__.main(["fuzzbucket-client"] + list(args))
1382+
assert ret == returning
1383+
if out_match is not None:
1384+
assert out_match in capsys.readouterr().out
1385+
1386+
13541387
@pytest.mark.parametrize(
13551388
(
13561389
"env_credentials",

0 commit comments

Comments
 (0)