11import * as commander from "commander" ;
22import { CommanderStatic } from "commander" ;
3- import { lstatSync } from "fs " ;
3+ import { URL } from "url " ;
44
55import { buildDebugger , getPackageJson } from "../utils" ;
66import { Format , Options , Sort } from "../lib/types" ;
7+ import { lstatSync } from "fs" ;
8+ import { execSync } from "child_process" ;
79
810const internal = { debug : buildDebugger ( "cli" ) } ;
911
10- export default { parse } ;
12+ export default { parse, cleanup } ;
1113
1214async function parse ( ) : Promise < Options > {
1315 const { description, version } = await getPackageJson ( ) ;
1416 const cli = getRawCli ( description , version ) . parse ( process . argv ) ;
1517
1618 assertArgsAreProvided ( cli ) ;
17- assertIsDirectory ( cli . args [ 0 ] ) ;
1819
1920 const options = buildOptions ( cli ) ;
2021
@@ -23,12 +24,18 @@ async function parse(): Promise<Options> {
2324 return options ;
2425}
2526
27+ function cleanup ( options : Options ) : void {
28+ if ( options . target instanceof URL ) {
29+ execSync ( `rm -rf ${ options . directory } ` , { stdio : "ignore" } ) ;
30+ }
31+ }
32+
2633function getRawCli (
2734 description : string | undefined ,
2835 version : string | undefined
2936) : CommanderStatic {
3037 return commander
31- . usage ( "<dir > [options]" )
38+ . usage ( "<target > [options]" )
3239 . version ( version || "" )
3340 . description ( description || "" )
3441 . option (
@@ -57,36 +64,59 @@ function getRawCli(
5764 console . log ( "Examples:" ) ;
5865 console . log ( ) ;
5966 [
60- "$ code-complexity <dir>" ,
61- "$ code-complexity <dir> --limit 3" ,
62- "$ code-complexity <dir> --sort score" ,
63- "$ code-complexity <dir> --filter 'src/**,!src/front/**'" ,
64- "$ code-complexity <dir> --limit 10 --sort score" ,
67+ "$ code-complexity ." ,
68+ "$ code-complexity https://github.com/simonrenoult/code-complexity" ,
69+ "$ code-complexity foo --limit 3" ,
70+ "$ code-complexity ../foo --sort score" ,
71+ "$ code-complexity /foo/bar --filter 'src/**,!src/front/**'" ,
72+ "$ code-complexity . --limit 10 --sort score" ,
6573 ] . forEach ( ( example ) => console . log ( example . padStart ( 2 ) ) ) ;
6674 } ) ;
6775}
6876
6977function buildOptions ( cli : CommanderStatic ) : Options {
78+ const target = parseTarget ( cli . args [ 0 ] ) ;
7079 return {
71- directory : cli . args [ 0 ] ,
80+ target,
81+ directory : parseDirectory ( target ) ,
7282 format : cli . format ? ( String ( cli . format ) as Format ) : "table" ,
7383 filter : cli . filter || [ ] ,
7484 limit : cli . limit ? Number ( cli . limit ) : undefined ,
7585 since : cli . since ? String ( cli . since ) : undefined ,
7686 sort : cli . sort ? ( String ( cli . sort ) as Sort ) : undefined ,
7787 } ;
88+
89+ // FIXME: I'm not a fan of pulling the code here but it's good enough.
90+ function parseDirectory ( target : string | URL ) : string {
91+ if ( target instanceof URL ) {
92+ const tmp = `code-complexity-${ new Date ( ) . getTime ( ) } ` ;
93+ execSync ( `git clone ${ target } ${ tmp } ` , { stdio : "ignore" } ) ;
94+ return tmp ;
95+ } else {
96+ return target ;
97+ }
98+ }
99+
100+ function parseTarget ( target : string ) : string | URL {
101+ try {
102+ return new URL ( target ) ;
103+ } catch ( e ) {
104+ try {
105+ lstatSync ( target ) ;
106+ return target ;
107+ } catch ( e ) {
108+ throw new Error (
109+ "Argument 'target' is neither a directory nor a valid URL."
110+ ) ;
111+ }
112+ }
113+ }
78114}
79115
80116function commaSeparatedList ( value : string ) : string [ ] {
81117 return value . split ( "," ) ;
82118}
83119
84- function assertIsDirectory ( directory : string ) : void {
85- if ( ! lstatSync ( directory ) . isDirectory ( ) ) {
86- throw new Error ( `Argument 'dir' must be a directory.` ) ;
87- }
88- }
89-
90120function assertArgsAreProvided ( internalCli : CommanderStatic ) : void {
91121 if ( ! internalCli . args || ! internalCli . args . length ) {
92122 internalCli . help ( ) ;
0 commit comments