1
1
#!/usr/bin/env python3
2
2
# -*- coding: utf-8 -*-
3
+ """
4
+ Command-line interface (CLI) utility for counting code lines and displaying detailed results.
5
+ """
3
6
4
7
import re
5
8
import sys
6
9
import argparse
10
+ from typing import List , Optional
7
11
from code_counter import __version__
8
12
9
13
10
- def split_args (args ):
14
+ def split_args (args : str ) -> List [str ]:
15
+ """
16
+ Split input arguments separated by commas.
17
+
18
+ Parameters
19
+ ----------
20
+ args: str
21
+ Input arguments as a comma-separated string.
22
+
23
+ Returns
24
+ -------
25
+ List[str]
26
+ List of split arguments.
27
+ """
11
28
return list (args .split (',' ))
12
29
13
30
14
- def remote_repo_parse (repo ):
31
+ def parse_remote_repo (repo : str ) -> str :
32
+ """
33
+ Parse the input repository link to extract information and construct API URL.
34
+
35
+ Parameters
36
+ ----------
37
+ repo: str
38
+ Input repository link.
39
+
40
+ Returns
41
+ -------
42
+ str
43
+ Constructed API URL for the repository.
44
+ """
45
+ # Check both HTTPS and SSH links for GitHub or Gitee repositories
46
+ res = re .search (r"^(https|git)@(github|gitee).com:([^/]+)/([^\.]+)\.git$" , repo , re .I )
47
+ if not res :
48
+ print ('Remote repository link parse error! Please enter a valid HTTPS or SSH link:' )
49
+ print ('\t cocnt remote' , repo )
50
+ exit (1 )
51
+
52
+ # Construct API URL based on the matched repository
53
+ api_url = f'https://{ res .group (2 )} .com/api/v5/repos/{ res .group (3 )} /{ res .group (4 )} /contents/'
54
+ return api_url
55
+
56
+
57
+ @PendingDeprecationWarning
58
+ def remote_repo_parse (repo : str ) -> str :
59
+ """
60
+ Parse the input repository link and return the corresponding API URL.
61
+
62
+ This function is deprecated in favor of `parse_remote_repo`.
63
+
64
+ Parameters
65
+ ----------
66
+ repo: str
67
+ Input repository link.
68
+
69
+ Returns
70
+ -------
71
+ str
72
+ Constructed API URL for the repository.
73
+ """
15
74
# check HTTPS link first
16
75
res = re .search (r"^https://(github|gitee).com/([^/]+)/([^\.]+)\.git$" , repo , re .I )
17
76
# if got none, then check SSH link
@@ -34,15 +93,17 @@ def remote_repo_parse(repo):
34
93
35
94
36
95
class CodeCounterArgs :
37
- __SEARCH__ = 'search'
38
- __CONFIG__ = 'config'
39
- __REMOTE__ = 'remote'
96
+ SEARCH = 'search'
97
+ CONFIG = 'config'
98
+ REMOTE = 'remote'
40
99
41
100
def __init__ (self ):
101
+ """
102
+ Initialize CodeCounterArgs instance.
103
+ """
42
104
parser = argparse .ArgumentParser (
43
105
prog = "code-counter" ,
44
- description = "A command-line interface (CLI) utility "
45
- "that can help you easily count code and display detailed results." ,
106
+ description = "A command-line interface (CLI) utility that counts code lines and displays detailed results." ,
46
107
usage = """cocnt <command> [<args>]
47
108
These are common Code-Counter commands used in various situations:
48
109
search Search and count code lines for the given path(s)
@@ -53,54 +114,126 @@ def __init__(self):
53
114
version = '%(prog)s {}' .format (__version__ ))
54
115
parser .add_argument ("command" , help = "Subcommand to run, `search` or `config`" )
55
116
args = parser .parse_args (sys .argv [1 :2 ])
117
+
56
118
if not hasattr (self , args .command ):
57
119
print ("Unrecognized command" )
58
120
parser .print_help ()
59
121
exit (1 )
122
+
60
123
self .__args = {args .command : argparse .Namespace ()}
61
124
getattr (self , args .command )()
62
125
63
- def has_search_args (self ):
64
- return self .__SEARCH__ in self .__args
126
+ def has_search_args (self ) -> bool :
127
+ """
128
+ Check if the instance has search-related arguments.
65
129
66
- def has_remote_args (self ):
67
- return self .__REMOTE__ in self .__args
130
+ Returns
131
+ -------
132
+ bool
133
+ True if search-related arguments are present, False otherwise.
134
+ """
135
+ return self .SEARCH in self .__args
68
136
69
- def has_config_args (self ):
70
- return self .__CONFIG__ in self .__args
137
+ def has_remote_args (self ) -> bool :
138
+ """
139
+ Check if the instance has remote-related arguments.
71
140
72
- def is_github_repo (self ):
73
- if not self .has_remote_args ():
74
- return False
75
- return self .__args [self .__REMOTE__ ].input_path .startswith ('https://api.github.com/repos/' )
141
+ Returns
142
+ -------
143
+ bool
144
+ True if remote-related arguments are present, False otherwise.
145
+ """
146
+ return self .REMOTE in self .__args
76
147
77
- def is_gitee_repo (self ):
78
- if not self .has_remote_args ():
79
- return False
80
- return self .__args [self .__REMOTE__ ].input_path .startswith ('https://gitee.com/api/v5/repos/' )
148
+ def has_config_args (self ) -> bool :
149
+ """
150
+ Check if the instance has config-related arguments.
151
+
152
+ Returns
153
+ -------
154
+ bool
155
+ True if config-related arguments are present, False otherwise.
156
+ """
157
+ return self .CONFIG in self .__args
158
+
159
+ def is_github_repo (self ) -> bool :
160
+ """
161
+ Check if the provided input is a GitHub repository.
162
+
163
+ Returns
164
+ -------
165
+ bool
166
+ True if the input is a GitHub repository, False otherwise.
167
+ """
168
+ return self .has_remote_args () \
169
+ and self .__args [self .REMOTE ].input_path .startswith ('https://api.github.com/repos/' )
170
+
171
+ def is_gitee_repo (self ) -> bool :
172
+ """
173
+ Check if the provided input is a Gitee repository.
81
174
82
- def search (self ):
175
+ Returns
176
+ -------
177
+ bool
178
+ True if the input is a Gitee repository, False otherwise.
179
+ """
180
+ return self .has_remote_args () \
181
+ and self .__args [self .REMOTE ].input_path .startswith ('https://gitee.com/api/v5/repos/' )
182
+
183
+ def search (self ) -> Optional [argparse .Namespace ]:
184
+ """
185
+ Get search-related arguments.
186
+
187
+ Returns
188
+ -------
189
+ Optional[argparse.Namespace]
190
+ Search-related arguments if present, None otherwise.
191
+ """
83
192
if not self .has_search_args ():
84
193
return None
85
- if self .__args [self .__SEARCH__ ] == argparse .Namespace ():
86
- self .__args [self .__SEARCH__ ] = self .__search ()
87
- return self .__args [self .__SEARCH__ ]
194
+ if self .__args [self .SEARCH ] == argparse .Namespace ():
195
+ self .__args [self .SEARCH ] = self .__search ()
196
+ return self .__args [self .SEARCH ]
88
197
89
- def remote (self ):
198
+ def remote (self ) -> Optional [argparse .Namespace ]:
199
+ """
200
+ Get remote-related arguments.
201
+
202
+ Returns
203
+ -------
204
+ Optional[argparse.Namespace]
205
+ Remote-related arguments if present, None otherwise.
206
+ """
90
207
if not self .has_remote_args ():
91
208
return None
92
- if self .__args [self .__REMOTE__ ] == argparse .Namespace ():
93
- self .__args [self .__REMOTE__ ] = self .__remote ()
94
- return self .__args [self .__REMOTE__ ]
209
+ if self .__args [self .REMOTE ] == argparse .Namespace ():
210
+ self .__args [self .REMOTE ] = self .__remote ()
211
+ return self .__args [self .REMOTE ]
212
+
213
+ def config (self ) -> Optional [argparse .Namespace ]:
214
+ """
215
+ Get config-related arguments.
95
216
96
- def config (self ):
217
+ Returns
218
+ -------
219
+ Optional[argparse.Namespace]
220
+ Config-related arguments if present, None otherwise.
221
+ """
97
222
if not self .has_config_args ():
98
223
return None
99
- if self .__args [self .__CONFIG__ ] == argparse .Namespace ():
100
- self .__args [self .__CONFIG__ ] = self .__config ()
101
- return self .__args [self .__CONFIG__ ]
224
+ if self .__args [self .CONFIG ] == argparse .Namespace ():
225
+ self .__args [self .CONFIG ] = self .__config ()
226
+ return self .__args [self .CONFIG ]
102
227
103
- def __search (self ):
228
+ def __search (self ) -> argparse .Namespace :
229
+ """
230
+ Parse search-related arguments.
231
+
232
+ Returns
233
+ -------
234
+ argparse.Namespace
235
+ Search-related arguments.
236
+ """
104
237
parser = argparse .ArgumentParser (
105
238
description = "Search and count code lines for the given path(s)" ,
106
239
usage = "cocnt search input_path [-h] [-v] [-g] "
@@ -110,7 +243,7 @@ def __search(self):
110
243
parser .add_argument ('-v' , '--verbose' , dest = "verbose" , action = 'store_true' ,
111
244
help = "show verbose information" )
112
245
parser .add_argument ('-g' , '--graph' , dest = 'graph' , action = 'store_true' ,
113
- help = "choose to whether to visualize the result" )
246
+ help = "choose whether to visualize the result" )
114
247
parser .add_argument ('-o' , '--output' , dest = 'output_path' ,
115
248
help = "specify an output path if you want to store the result" )
116
249
parser .add_argument ('--suffix' , dest = 'suffix' , type = split_args ,
@@ -121,17 +254,25 @@ def __search(self):
121
254
help = "ignore some directories or files that you don't want to count" )
122
255
return parser .parse_args (sys .argv [2 :])
123
256
124
- def __remote (self ):
257
+ def __remote (self ) -> argparse .Namespace :
258
+ """
259
+ Parse remote-related arguments.
260
+
261
+ Returns
262
+ -------
263
+ argparse.Namespace
264
+ Remote-related arguments.
265
+ """
125
266
parser = argparse .ArgumentParser (
126
- description = "Search and count the remote repository with a given Github or Gitee HTTP link" ,
267
+ description = "Search and count the remote repository with a given GitHub or Gitee HTTP link" ,
127
268
usage = "cocnt remote <repository> [-h] [-v] [-g] "
128
269
"[-o OUTPUT_PATH] [--suffix SUFFIX] [--comment COMMENT] [--ignore IGNORE]" )
129
- parser .add_argument ('input_path' , metavar = "repository" , type = remote_repo_parse ,
270
+ parser .add_argument ('input_path' , metavar = "repository" , type = parse_remote_repo ,
130
271
help = "search and count a remote repository" )
131
272
parser .add_argument ('-v' , '--verbose' , dest = "verbose" , action = 'store_true' ,
132
273
help = "show verbose information" )
133
274
parser .add_argument ('-g' , '--graph' , dest = 'graph' , action = 'store_true' ,
134
- help = "choose to whether to visualize the result" )
275
+ help = "choose whether to visualize the result" )
135
276
parser .add_argument ('-o' , '--output' , dest = 'output_path' ,
136
277
help = "specify an output path if you want to store the result" )
137
278
parser .add_argument ('--suffix' , dest = 'suffix' , type = split_args ,
@@ -142,7 +283,15 @@ def __remote(self):
142
283
help = "ignore some directories or files that you don't want to count" )
143
284
return parser .parse_args (sys .argv [2 :])
144
285
145
- def __config (self ):
286
+ def __config (self ) -> argparse .Namespace :
287
+ """
288
+ Parse config-related arguments.
289
+
290
+ Returns
291
+ -------
292
+ argparse.Namespace
293
+ Config-related arguments.
294
+ """
146
295
parser = argparse .ArgumentParser (
147
296
prog = "code-counter" ,
148
297
description = "configure code-counter" ,
@@ -178,7 +327,7 @@ def __config(self):
178
327
help = "delete some values of the 'ignore' in the config" )
179
328
180
329
parser .add_argument ('--github-token' , dest = 'github_token' ,
181
- help = "update the Github access token" )
330
+ help = "update the GitHub access token" )
182
331
parser .add_argument ('--gitee-token' , dest = 'gitee_token' ,
183
332
help = "update the Gitee access token" )
184
333
0 commit comments