1
+ import functools
1
2
import os
2
3
from argparse import ArgumentParser , Namespace
3
- from typing import Optional , Sequence
4
+ from typing import List , Optional , Sequence
4
5
from urllib .parse import urlparse
5
6
6
7
from hdfs_native import Client
7
8
8
9
10
+ @functools .cache
11
+ def _get_client (connection_url : Optional [str ] = None ):
12
+ return Client (connection_url )
13
+
14
+
9
15
def _client_for_url (url : str ) -> Client :
10
16
parsed = urlparse (url )
11
17
12
18
if parsed .scheme :
13
19
connection_url = f"{ parsed .scheme } ://{ parsed .hostname } "
14
20
if parsed .port :
15
21
connection_url += f":{ parsed .port } "
16
- return Client (connection_url )
22
+ return _get_client (connection_url )
17
23
elif parsed .hostname or parsed .port :
18
24
raise ValueError (
19
25
f"Cannot provide host or port without scheme: { parsed .hostname } "
20
26
)
21
27
else :
22
- return Client ()
28
+ return _get_client ()
23
29
24
30
25
31
def _verify_nameservices_match (url : str , * urls : str ) -> None :
@@ -37,6 +43,19 @@ def _path_for_url(url: str) -> str:
37
43
return urlparse (url ).path
38
44
39
45
46
+ def _glob_path (client : Client , glob : str ) -> List [str ]:
47
+ # TODO: Actually implement this, for now just pretend we have multiple results
48
+ return [glob ]
49
+
50
+
51
+ def mkdir (args : Namespace ):
52
+ create_parent = args .parent
53
+
54
+ for path in args .path :
55
+ client = _client_for_url (path )
56
+ client .mkdirs (path , create_parent = create_parent )
57
+
58
+
40
59
def mv (args : Namespace ):
41
60
_verify_nameservices_match (args .dst , * args .src )
42
61
@@ -49,12 +68,16 @@ def mv(args: Namespace):
49
68
except FileNotFoundError :
50
69
pass
51
70
52
- if len (args .src ) > 1 and not dst_isdir :
71
+ resolved_src = [
72
+ path for pattern in args .src for path in _glob_path (client , pattern )
73
+ ]
74
+
75
+ if len (resolved_src ) > 1 and not dst_isdir :
53
76
raise ValueError (
54
77
"destination must be a directory if multiple sources are provided"
55
78
)
56
79
57
- for src in args . src :
80
+ for src in resolved_src :
58
81
src_path = _path_for_url (src )
59
82
if dst_isdir :
60
83
target_path = os .path .join (dst_path , os .path .basename (src_path ))
@@ -72,6 +95,24 @@ def main(in_args: Optional[Sequence[str]] = None):
72
95
73
96
subparsers = parser .add_subparsers (title = "Subcommands" , required = True )
74
97
98
+ mkdir_parser = subparsers .add_parser (
99
+ "mkdir" ,
100
+ help = "Create a directory" ,
101
+ description = "Create a directory in a specified path" ,
102
+ )
103
+ mkdir_parser .add_argument (
104
+ "path" ,
105
+ nargs = "+" ,
106
+ help = "Path for the directory to create" ,
107
+ )
108
+ mkdir_parser .add_argument (
109
+ "-p" ,
110
+ "--parent" ,
111
+ action = "store_true" ,
112
+ help = "Create any missing parent directories" ,
113
+ )
114
+ mkdir_parser .set_defaults (func = mkdir )
115
+
75
116
mv_parser = subparsers .add_parser (
76
117
"mv" ,
77
118
help = "Move files or directories" ,
0 commit comments