Branch data Line data Source code
1 [ + ]: 57 : /**
2 : 57 : * @module github-activity-cmd
3 : 57 : * @desc The command line interface for {@link module:github-activity github-activity} module.
4 : 57 : * @version 1.0.0
5 : 57 : * @author Essam A. El-Sherif
6 : 57 : */
7 : 57 :
8 : 57 : /* Import node.js core modules */
9 : 57 : import fs from 'node:fs';
10 : 57 : import os from 'node:os';
11 : 57 : import path from 'node:path';
12 : 57 : import process from 'node:process';
13 : 57 :
14 : 57 : /** @const {string} CMD - The command line interface. */
15 : 57 : const CMD = 'gh-act';
16 : 57 :
17 : 57 : /** @const {string} CMD_VER - The command line interface version. */
18 : 57 : const CMD_VER = 'v1.0.0';
19 : 57 :
20 : 57 : /**
21 : 57 : * @const {object} cmdOptions - Command line arguments.
22 : 57 : * @static
23 : 57 : */
24 : 57 : export const cmdOptions = {
25 : 57 : user : false, // --user
26 : 57 : output : 'v', // -b --table
27 : 57 : // -j --json
28 : 57 : // -c --csv
29 : 57 : // -v --verbose
30 : 57 : type : '', // -t --type
31 : 57 : debug : false, // -d --debug
32 : 57 : cache : true, // --nocache
33 : 57 : userAgent : `${CMD}/${CMD_VER}`,
34 : 57 : apiVersion : '2022-11-28',
35 : 57 : cacheDir : path.join(os.tmpdir(), CMD),
36 : 57 : authTokenFile: '.auth-token',
37 : 57 : };
38 : 57 :
39 : 57 : /**
40 : 57 : * @var {string} githubUser - The GitHub username given as a command line argument.
41 : 57 : * @static
42 : 57 : */
43 : 57 : export let githubUser = '';
44 : 57 :
45 : 57 : /**
46 : 57 : * function parseCmdLine()
47 : 57 : * function getHelp()
48 : 57 : * function getError(n)
49 : 57 : * function getEvents()
50 : 57 : *
51 : 57 : * @func parseCmdLine
52 : 57 : * @static
53 : 57 : * @desc Command line parser function.
54 : 57 : */
55 [ + ]: 57 : export function parseCmdLine(){
56 : 57 :
57 : 57 : const args = process.argv;
58 : 57 :
59 : 57 : if(args.length === 2){
60 : 57 : process.stdout.write(`${getHelp()}\n`);
61 : 57 : process.exit(0);
62 : 57 : }
63 : 57 :
64 [ + ]: 57 : for(let i = 2; i < args.length; i++){
65 : 18 : if(args[i] === '--help'){
66 : 18 : process.stdout.write(`${getHelp()}\n`);
67 : 18 : process.exit(0);
68 : 18 : }
69 : 18 : else
70 : 18 : if(args[i] === '--version'){
71 : 18 : process.stdout.write(`${CMD_VER}\n`);
72 : 18 : process.exit(0);
73 : 18 : }
74 : 18 : else
75 : 18 : if(args[i] === '--list'){
76 [ + ]: 18 : for(let e of getEvents()){
77 : 17 : process.stdout.write( (e[0]+' ').padEnd(30, '.') + '.... ');
78 : 17 : process.stdout.write(e[1] + '\n');
79 : 17 : }
80 : 18 : process.exit(0);
81 : 18 : }
82 : 18 : else
83 [ + ]: 18 : if(args[i].startsWith('--')){
84 : 10 : switch(args[i]){
85 : 10 : case '--':
86 : 10 : break;
87 [ + ]: 10 : case '--user':
88 : 2 : cmdOptions.user = true;
89 : 2 : break;
90 [ + ]: 10 : case '--table':
91 : 1 : cmdOptions.output = 'b';
92 : 1 : break;
93 : 10 : case '--json':
94 : 10 : cmdOptions.output = 'j';
95 : 10 : break;
96 : 10 : case '--csv':
97 : 10 : cmdOptions.output = 'c';
98 : 10 : break;
99 : 10 : case '--verbose':
100 : 10 : cmdOptions.output = 'v';
101 : 10 : break;
102 [ + ]: 10 : case '--debug':
103 : 2 : cmdOptions.debug = true;
104 : 2 : break;
105 : 10 : case '--nocache':
106 : 10 : cmdOptions.cache = false;
107 : 10 : if(args.length === 3){
108 : 10 : fs.rmSync(cmdOptions.cacheDir, {force: true, recursive: true});
109 : 10 : process.exit(0);
110 : 10 : }
111 : 10 : break;
112 [ + ]: 10 : default:
113 : 1 : if(args[i].startsWith('--type')){
114 : 1 :
115 : 1 : if(args[i] === '--type='){
116 : 1 : process.stderr.write(`${getError(0).replace('_', '--type')}\n`);
117 : 1 : process.exit(1);
118 : 1 : }
119 : 1 : else
120 : 1 : if(args[i].startsWith('--type=')){
121 : 1 : let str = args[i].replace('--type=', '');
122 : 1 :
123 : 1 : if(getEvents().has(str)){
124 : 1 : cmdOptions.type = str;
125 : 1 : }
126 : 1 : else{
127 : 1 : process.stderr.write(`${getError(4).replace('_', str)}\n`);
128 : 1 : process.exit(1);
129 : 1 : }
130 : 1 : }
131 : 1 : else
132 : 1 : if(i === args.length - 1){
133 : 1 : process.stderr.write(`${getError(0).replace('_', '--type')}\n`);
134 : 1 : process.exit(1);
135 : 1 : }
136 : 1 : else
137 : 1 : if(getEvents().has(args[i+1])){
138 : 1 : cmdOptions.type = args[++i];
139 : 1 : }
140 : 1 : else{
141 : 1 : process.stderr.write(`${getError(4).replace('_', args[i+1])}\n`);
142 : 1 : process.exit(1);
143 : 1 : }
144 : 1 : }
145 : 1 : else{
146 : 1 : process.stderr.write(`${getError(1).replace('_', args[i])}\n`);
147 : 1 : process.exit(1);
148 : 1 : }
149 : 1 : break;
150 : 10 : }
151 [ + ]: 10 : }
152 : 6 : else
153 : 6 : if(args[i] === '-'){}
154 : 6 : else
155 [ + ]: 6 : if(args[i].startsWith('-')){
156 : 1 : for(let k = 1; k < args[i].length; k++){
157 : 1 : let opt = args[i][k];
158 : 1 :
159 : 1 : switch(opt){
160 : 1 : case 'b':
161 : 1 : cmdOptions.output = 'b';
162 : 1 : break;
163 : 1 : case 'j':
164 : 1 : cmdOptions.output = 'j';
165 : 1 : break;
166 : 1 : case 'c':
167 : 1 : cmdOptions.output = 'c';
168 : 1 : break;
169 : 1 : case 'v':
170 : 1 : cmdOptions.output = 'v';
171 : 1 : break;
172 : 1 : case 'd':
173 : 1 : cmdOptions.debug = true;
174 : 1 : break;
175 : 1 : default:
176 : 1 : if(opt === 't'){
177 : 1 : if(k < args[i].length - 1 || i === args.length - 1){
178 : 1 : process.stderr.write(`${getError(0).replace('_', '-t')}\n`);
179 : 1 : process.exit(1);
180 : 1 : }
181 : 1 : else
182 : 1 : if(getEvents().has(args[i+1])){
183 : 1 : cmdOptions.type = args[++i];
184 : 1 : }
185 : 1 : else{
186 : 1 : process.stderr.write(`${getError(4).replace('_', args[i+1])}\n`);
187 : 1 : process.exit(1);
188 : 1 : }
189 : 1 : }
190 : 1 : else{
191 : 1 : process.stderr.write(`${getError(2).replace('_', opt)}\n`);
192 : 1 : process.exit(1);
193 : 1 : }
194 : 1 : break;
195 : 1 : }
196 : 1 : }
197 [ + ]: 1 : }
198 : 1 : else
199 : 1 : if(githubUser){
200 : 1 : process.stderr.write(`${getError(5)}\n`);
201 : 1 : process.exit(1);
202 : 1 : }
203 : 1 : else{
204 : 1 : githubUser = args[i];
205 : 1 : }
206 : 18 : }
207 : 57 :
208 : 57 : if(!githubUser){
209 : 57 : process.stderr.write(`${getError(6)}\n`);
210 : 57 : process.exit(1);
211 : 57 : }
212 : 57 : }
213 : 57 :
214 : 57 : /**
215 : 57 : * function parseCmdLine()
216 : 57 : * function getHelp()
217 : 57 : * function getError(n)
218 : 57 : * function getEvents()
219 : 57 : *
220 : 57 : * @func getHelp
221 : 57 : * @return {string}
222 : 57 : * @desc Function to return help info.
223 : 57 : */
224 [ + ]: 2 : function getHelp(){
225 : 2 :
226 : 2 : return `\
227 : 2 : Usage: ${CMD} [OPTION]... USER
228 : 2 : Use GitHub API to fetch GitHub user activities and display it in the terminal.
229 : 2 :
230 : 2 : -b --table tabular output
231 : 2 : -j --json output JSON data
232 : 2 : -c --csv output comma separated values
233 : 2 : -v --verbose verbose output (default)
234 : 2 : -d --debug show request and response headers
235 : 2 : -t --type[=TYPE] filter user activities by event type
236 : 2 : --user output user information and exit
237 : 2 : --nocache remove the cache directory and exit
238 : 2 : --list list GitHub event types and exit
239 : 2 : --help display this help and exit
240 : 2 : --version output version information and exit
241 : 2 :
242 : 2 : Writing your GitHub authentication token to the file '.auth-token' located in the
243 : 2 : package root directory is recommended for normal operation and required for testing.`;
244 : 2 :
245 : 2 : }
246 : 57 :
247 : 57 : /**
248 : 57 : * function parseCmdLine()
249 : 57 : * function getHelp()
250 : 57 : * function getError(n)
251 : 57 : * function getEvents()
252 : 57 : *
253 : 57 : * @func getError
254 : 57 : * @static
255 : 57 : * @param {number} Error number.
256 : 57 : * @return {string} Error message.
257 : 57 : * @desc Function to return error message.
258 : 57 : */
259 [ + ]: 57 : export function getError(n){
260 : 12 :
261 : 12 : const error = [
262 : 12 :
263 : 12 : // error[0] - missing argument
264 : 12 : `\
265 : 12 : ${CMD}: ambiguous argument ‘’ for ‘_’
266 : 12 : Try '${CMD} --help' for more information.`,
267 : 12 :
268 : 12 : // error[1] - multi-character options
269 : 12 : `\
270 : 12 : ${CMD}: unrecognized option '_'
271 : 12 : Try '${CMD} --help' for more information.`,
272 : 12 :
273 : 12 : // error[2] - single-character options
274 : 12 : `\
275 : 12 : ${CMD}: invalid option -- '_'
276 : 12 : Try '${CMD} --help' for more information.`,
277 : 12 :
278 : 12 : // error[3]
279 : 12 : `\
280 : 12 : ${CMD}: GitHub user '_' not found
281 : 12 : Try '${CMD} --help' for more information.`,
282 : 12 :
283 : 12 : // error[4]
284 : 12 : `\
285 : 12 : ${CMD}: unrecognized GitHub event type '_'
286 : 12 : Try '${CMD} --list' for more information.`,
287 : 12 :
288 : 12 : // error[5]
289 : 12 : `\
290 : 12 : ${CMD}: only one GitHub user is allowed
291 : 12 : Try '${CMD} --help' for more information.`,
292 : 12 :
293 : 12 : // error[6]
294 : 12 : `\
295 : 12 : ${CMD}: no GitHub user given
296 : 12 : Try '${CMD} --help' for more information.`,
297 : 12 :
298 : 12 : // error[7]
299 : 12 : `\
300 : 12 : ${CMD}: unable to fetch GitHub user '_' events
301 : 12 : Try '${CMD} --help' for more information.`,
302 : 12 :
303 : 12 : // error[8]
304 : 12 : `\
305 : 12 : ${CMD}: unable to fetch the authorization token
306 : 12 : Try '${CMD} --help' for more information.`,
307 : 12 : ];
308 : 12 : return error[n];
309 : 12 : }
310 : 57 :
311 : 57 : /**
312 : 57 : * function parseCmdLine()
313 : 57 : * function getHelp()
314 : 57 : * function getError(n)
315 : 57 : * function getEvents()
316 : 57 : *
317 : 57 : * @func getEvents
318 : 57 : * @static
319 : 57 : * @return {Map} Map of GitHub event types to event descriptions.
320 : 57 : * @desc Function to return a Map of GitHub events.
321 : 57 : * @see {@link https://docs.github.com/en/rest/using-the-rest-api/github-event-types?apiVersion=2022-11-28 GitHub event types}
322 : 57 : */
323 [ + ]: 57 : export function getEvents(){
324 : 5 : return new Map(
325 : 5 : [
326 : 5 : ['CommitCommentEvent', 'A commit comment is created.'],
327 : 5 : ['CreateEvent', 'A Git branch or tag is created.'],
328 : 5 : ['DeleteEvent', 'A Git branch or tag is deleted.'],
329 : 5 : ['ForkEvent', 'A user forks a repository.'],
330 : 5 : ['GollumEvent', 'A wiki page is created or updated.'],
331 : 5 : ['IssueCommentEvent', 'Activity related to an issue or pull request comment.'],
332 : 5 : ['IssuesEvent', 'Activity related to an issue.'],
333 : 5 : ['MemberEvent', 'Activity related to repository collaborators.'],
334 : 5 : ['PublicEvent', 'When a private repository is made public.'],
335 : 5 : ['PullRequestEvent', 'Activity related to pull requests.'],
336 : 5 : ['PullRequestReviewEvent', 'Activity related to pull request reviews.'],
337 : 5 : ['PullRequestReviewCommentEvent', 'Activity related to pull request review comments in the pull request\'s unified diff.'],
338 : 5 : ['PullRequestReviewThreadEvent', 'Activity related to a comment thread on a pull request being marked as resolved or unresolved.'],
339 : 5 : ['PushEvent', 'One or more commits are pushed to a repository branch or tag.'],
340 : 5 : ['ReleaseEvent', 'Activity related to a release.'],
341 : 5 : ['SponsorshipEvent', 'Activity related to a sponsorship listing.'],
342 : 5 : ['WatchEvent', 'When someone stars a repository.'],
343 : 5 : ]
344 : 5 : );
345 : 5 : }
|