]> git.wincent.com - wincent.git/commitdiff
feat(fig): show usage information
authorGreg Hurrell <greg@hurrell.net>
Thu, 2 Apr 2020 22:51:16 +0000 (00:51 +0200)
committerGreg Hurrell <greg@hurrell.net>
Thu, 2 Apr 2020 22:51:16 +0000 (00:51 +0200)
src/getOptions.ts
src/main.ts
src/readAspect.ts
src/readProject.ts

index 66bea41410fa72f7b411288d0e617cc4f6eb71d0..f323c4506e34753d61fc4f7ad9043c3c7d171251 100644 (file)
@@ -1,5 +1,12 @@
-import {LOG_LEVEL, setLogLevel} from './console';
+import {promises as fs} from 'fs';
+import * as path from 'path';
+
+import {root} from './Fig';
+import {COLORS, LOG_LEVEL, log, setLogLevel} from './console';
+import dedent from './dedent';
+import ErrorWithMetadata from './ErrorWithMetadata';
 import escapeRegExpPattern from './escapeRegExpPattern';
+import readAspect from './readAspect';
 
 import type {LogLevel} from './console';
 
@@ -13,7 +20,11 @@ type Options = {
   testsOnly: boolean;
 };
 
-export default function getOptions(args: Array<string>): Options {
+const {bold} = COLORS;
+
+export default async function getOptions(
+  args: Array<string>
+): Promise<Options> {
   const options: Options = {
     logLevel: LOG_LEVEL.INFO,
     startAt: {
@@ -23,15 +34,16 @@ export default function getOptions(args: Array<string>): Options {
     testsOnly: false,
   };
 
-  args.forEach((arg) => {
-    if (arg === '--debug') {
+  for (const arg of args) {
+    if (arg === '--debug' || arg === '-d') {
       options.logLevel = LOG_LEVEL.DEBUG;
     } else if (arg === '--quiet' || arg === '-q') {
       options.logLevel = LOG_LEVEL.NOTICE;
-    } else if (arg === '--test') {
+    } else if (arg === '--test' || arg === '-t') {
       options.testsOnly = true;
     } else if (arg === '--help' || arg === '-h') {
-      // TODO: print and exit
+      await printUsage();
+      throw new ErrorWithMetadata('aborting');
     } else if (arg.startsWith('--start-at-task=')) {
       options.startAt.literal = (
         arg.match(/^--start-at-task=(.*)/)?.[1] ?? ''
@@ -44,10 +56,55 @@ export default function getOptions(args: Array<string>): Options {
         ].join('.*'),
         'i'
       );
+    } else if (arg.startsWith('-')) {
+      throw new ErrorWithMetadata(`unrecognized argument ${arg}`);
     } else {
-      // TODO: error for bad args
+      // TODO: error for bad aspects
     }
-  });
+  }
 
   return options;
 }
+
+async function printUsage() {
+  const directory = path.join(root, 'aspects');
+
+  const entries = await fs.readdir(directory, {withFileTypes: true});
+
+  const aspects = entries
+    .filter((entry) => entry.isDirectory())
+    .map((entry) => entry.name);
+
+  // TODO: actually implement all the switches mentioned here
+  log(
+    dedent`
+
+      ./install [options] [aspects...]
+
+      ${bold`Options:`}
+
+        -c/--check # not yet implemented
+        -d/--debug
+        -f/--force # not yet implemented
+        -h/--help
+        -q/--quiet
+        -t/--test
+        -v/--verbose (repeat up to four times for more verbosity) # not yet implemented
+        --start-at-task='aspect | task' # TODO: maybe make -s short variant
+        --step # not yet implemented
+
+      ${bold`Aspects:`}
+    `
+  );
+
+  for (const aspect of aspects) {
+    const {description} = await readAspect(
+      path.join(directory, aspect, 'aspect.json')
+    );
+
+    log(`  ${aspect}`);
+    log(`    ${description}`);
+  }
+
+  log();
+}
index 270f91c2646b6ed03af1910de23919841e57bfd4..fa90d6cdcb12b4639e8ff911e28a9ce578e396e6 100644 (file)
@@ -21,7 +21,7 @@ async function main() {
   }
 
   // Skip first two args (node executable and main.js script).
-  const options = getOptions(process.argv.slice(2));
+  const options = await getOptions(process.argv.slice(2));
 
   setLogLevel(options.logLevel);
 
index 8b641be27e2cc68522a480762dc2daeeafa7454e..7895d7ba9353eb57fb356f6d55c1f96828bf3875 100644 (file)
@@ -7,7 +7,7 @@ import {Aspect, assertAspect} from './types/Aspect';
 const readFile = promisify(fs.readFile);
 
 export default async function readAspect(path: string): Promise<Aspect> {
-  log.info(`Reading aspect configuration: ${path}`);
+  log.debug(`Reading aspect configuration: ${path}`);
 
   const json = await readFile(path, 'utf8');
 
index 1e7a446d79a9ca7a80359596cc860f3695a4c2e3..e5a0946b95e9b2bbbd0c6164963f7d4c76da3dd1 100644 (file)
@@ -7,7 +7,7 @@ import {Project, assertProject} from './types/Project';
 const readFile = promisify(fs.readFile);
 
 export default async function readProject(path: string): Promise<Project> {
-  log.info(`Reading project configuration: ${path}`);
+  log.debug(`Reading project configuration: ${path}`);
 
   const json = await readFile(path, 'utf8');