All files / app/assets/javascripts/ide/lib/editorconfig parser.js

96.55% Statements 28/29
85.71% Branches 12/14
100% Functions 12/12
100% Lines 24/24

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        24x     42x       68x 24x   44x 32x     12x       70x   24x 24x   24x   24x 24x 24x   24x 68x         24x   24x       56x 27x       56x 83x   56x   83x        
import { parseString } from 'editorconfig/src/lib/ini';
import minimatch from 'minimatch';
import { getPathParents } from '../../utils';
 
const dirname = (path) => path.replace(/\.editorconfig$/, '');
 
function isRootConfig(config) {
  return config.some(([pattern, rules]) => !pattern && rules?.root === 'true');
}
 
function getRulesForSection(path, [pattern, rules]) {
  if (!pattern) {
    return {};
  }
  if (minimatch(path, pattern, { matchBase: true })) {
    return rules;
  }
 
  return {};
}
 
function getRulesWithConfigs(filePath, configFiles = [], rules = {}) {
  if (!configFiles.length) return rules;
 
  const [{ content, path: configPath }, ...nextConfigs] = configFiles;
  const configDir = dirname(configPath);
 
  Iif (!filePath.startsWith(configDir)) return rules;
 
  const parsed = parseString(content);
  const isRoot = isRootConfig(parsed);
  const relativeFilePath = filePath.slice(configDir.length);
 
  const sectionRules = parsed.reduce(
    (acc, section) => Object.assign(acc, getRulesForSection(relativeFilePath, section)),
    {},
  );
 
  // prefer existing rules by overwriting to section rules
  const result = Object.assign(sectionRules, rules);
 
  return isRoot ? result : getRulesWithConfigs(filePath, nextConfigs, result);
}
 
export function getRulesWithTraversal(filePath, getFileContent) {
  const editorconfigPaths = [
    ...getPathParents(filePath).map((x) => `${x}/.editorconfig`),
    '.editorconfig',
  ];
 
  return Promise.all(
    editorconfigPaths.map((path) => getFileContent(path).then((content) => ({ path, content }))),
  ).then((results) =>
    getRulesWithConfigs(
      filePath,
      results.filter((x) => x.content),
    ),
  );
}