All files / src index.ts

0% Statements 0/37
0% Branches 0/10
0% Functions 0/5
0% Lines 0/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100                                                                                                                                                                                                       
import fs from 'fs';
import path from 'path';
import { AntlerError } from './antler-error';
import { AntlerWarning } from './antler-warning';
import { MESSAGE_PREFIX } from './constants';
import { Rule } from './rule';
import { Callback, Node } from './types';
 
const MATCHES_LEADING_SLASH = /^\//;
 
function createNode(rootPath: string, fullPath: string): Node {
  const parentFullPath = path.resolve(fullPath, '../');
  const parentName = path.basename(parentFullPath);
 
  const shortPath = fullPath
    .replace(rootPath, '')
    .replace(MATCHES_LEADING_SLASH, '');
 
  const name = path.basename(fullPath);
 
  let childNames: ReadonlyArray<string> = [];
  let siblingNamesIncludingSelf: ReadonlyArray<string> = [];
  let isDirectory = false;
 
  Iif (fs.lstatSync(fullPath).isDirectory()) {
    isDirectory = true;
    childNames = fs.readdirSync(fullPath);
  }
 
  Iif (fs.lstatSync(parentFullPath).isDirectory()) {
    siblingNamesIncludingSelf = fs.readdirSync(parentFullPath);
  }
 
  return {
    parentName,
    path: shortPath,
    name,
    fullPath,
    isDirectory,
    siblingNamesIncludingSelf,
    childNames,
  };
}
 
function crawl(
  rootPath: string,
  node: Node,
  ruleInstances: ReadonlyArray<Rule>,
  indent: string,
  reportWarning: Callback,
  reportError: Callback
) {
  ruleInstances.forEach((instance) => {
    try {
      instance.run(node);
    } catch (error) {
      const message = error && error.message ? error.message : error;
 
      // eslint-disable-next-line no-console
      console.error(`${MESSAGE_PREFIX}${message}`);
 
      if (error instanceof AntlerWarning) {
        reportWarning();
      } else if (error instanceof AntlerError) {
        reportError();
      } else {
        process.exit(1);
      }
    }
  });
 
  node.childNames.forEach((childName) => {
    const fullPath = path.resolve(node.fullPath, childName);
    const childNode = createNode(rootPath, fullPath);
 
    crawl(
      rootPath,
      childNode,
      ruleInstances,
      `  ${indent}`,
      reportWarning,
      reportError
    );
  });
}
 
function beginCrawl(
  fullPath: string,
  ruleInstances: ReadonlyArray<Rule>,
  reportWarning: Callback,
  reportError: Callback
) {
  const rootPath = path.resolve(fullPath, '../');
  const node = createNode(rootPath, fullPath);
 
  crawl(rootPath, node, ruleInstances, '', reportWarning, reportError);
}
 
export default beginCrawl;