Skip to content

Commit fd9470b

Browse files
authored
Add cat to CLI (#190)
1 parent e29078f commit fd9470b

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

python/hdfs_native/cli.py

+26-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import functools
22
import os
3+
import sys
34
from argparse import ArgumentParser, Namespace
45
from typing import List, Optional, Sequence
56
from urllib.parse import urlparse
@@ -48,12 +49,23 @@ def _glob_path(client: Client, glob: str) -> List[str]:
4849
return [glob]
4950

5051

52+
def cat(args: Namespace):
53+
for src in args.src:
54+
client = _client_for_url(src)
55+
for path in _glob_path(client, _path_for_url(src)):
56+
with client.read(path) as file:
57+
while chunk := file.read(1024 * 1024):
58+
sys.stdout.buffer.write(chunk)
59+
60+
sys.stdout.buffer.flush()
61+
62+
5163
def mkdir(args: Namespace):
5264
create_parent = args.parent
5365

54-
for path in args.path:
55-
client = _client_for_url(path)
56-
client.mkdirs(path, create_parent=create_parent)
66+
for url in args.path:
67+
client = _client_for_url(url)
68+
client.mkdirs(_path_for_url(url), create_parent=create_parent)
5769

5870

5971
def mv(args: Namespace):
@@ -69,7 +81,9 @@ def mv(args: Namespace):
6981
pass
7082

7183
resolved_src = [
72-
path for pattern in args.src for path in _glob_path(client, pattern)
84+
path
85+
for pattern in args.src
86+
for path in _glob_path(client, _path_for_url(pattern))
7387
]
7488

7589
if len(resolved_src) > 1 and not dst_isdir:
@@ -95,6 +109,14 @@ def main(in_args: Optional[Sequence[str]] = None):
95109

96110
subparsers = parser.add_subparsers(title="Subcommands", required=True)
97111

112+
cat_parser = subparsers.add_parser(
113+
"cat",
114+
help="Print the contents of a file",
115+
description="Print the contents of a file to stdout",
116+
)
117+
cat_parser.add_argument("src", nargs="+", help="File pattern to print")
118+
cat_parser.set_defaults(func=cat)
119+
98120
mkdir_parser = subparsers.add_parser(
99121
"mkdir",
100122
help="Create a directory",

python/pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ name = "hdfs-native"
77
description = "Python bindings for hdfs-native Rust library"
88
readme = "README.md"
99
requires-python = ">=3.9"
10+
dynamic = ["version"]
1011
classifiers = [
1112
"Programming Language :: Rust",
1213
"Programming Language :: Python :: Implementation :: CPython",

python/tests/test_cli.py

+26
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import contextlib
2+
import io
3+
14
import pytest
25

36
from hdfs_native import Client
@@ -7,6 +10,29 @@
710
def test_cli(minidfs: str):
811
client = Client(minidfs)
912

13+
# cat
14+
with client.create("/testfile") as file:
15+
file.write(b"1234")
16+
17+
buf = io.BytesIO()
18+
with contextlib.redirect_stdout(io.TextIOWrapper(buf)):
19+
cli_main(["cat", "/testfile"])
20+
assert buf.getvalue() == b"1234"
21+
22+
with client.create("/testfile2") as file:
23+
file.write(b"5678")
24+
25+
buf = io.BytesIO()
26+
with contextlib.redirect_stdout(io.TextIOWrapper(buf)):
27+
cli_main(["cat", "/testfile", "/testfile2"])
28+
assert buf.getvalue() == b"12345678"
29+
30+
with pytest.raises(FileNotFoundError):
31+
cli_main(["cat", "/nonexistent"])
32+
33+
client.delete("/testfile")
34+
client.delete("/testfile2")
35+
1036
# mkdir
1137
cli_main(["mkdir", "/testdir"])
1238
assert client.get_file_info("/testdir").isdir

0 commit comments

Comments
 (0)