linguist-js
Version:
Analyse languages used in a folder. Powered by GitHub Linguist, although it doesn't need to be installed.
91 lines (90 loc) • 3.89 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = walk;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const parse_gitignore_1 = __importDefault(require("./parse-gitignore"));
const norm_path_1 = require("./norm-path");
let allFiles;
let allFolders;
;
;
/** Generate list of files in a directory. */
function walk(data) {
const { init, commonRoot, folderRoots, folders, ignored } = data;
// Initialise files and folders lists
if (init) {
allFiles = new Set();
allFolders = new Set();
}
// Walk tree of a folder
if (folders.length === 1) {
const folder = folders[0];
const localRoot = folderRoots[0].replace(commonRoot, '').replace(/^\//, '');
// Get list of files and folders inside this folder
const files = fs_1.default.readdirSync(folder).map(file => {
// Create path relative to root
const base = (0, norm_path_1.normAbsPath)(folder, file).replace(commonRoot, '.');
// Add trailing slash to mark directories
const isDir = fs_1.default.lstatSync(path_1.default.resolve(commonRoot, base)).isDirectory();
return isDir ? `${base}/` : base;
});
// Read and apply gitignores
const gitignoreFilename = (0, norm_path_1.normPath)(folder, '.gitignore');
if (fs_1.default.existsSync(gitignoreFilename)) {
const gitignoreContents = fs_1.default.readFileSync(gitignoreFilename, 'utf-8');
const ignoredPaths = (0, parse_gitignore_1.default)(gitignoreContents);
const rootRelIgnoredPaths = ignoredPaths.map(ignorePath =>
// get absolute path of the ignore glob
(0, norm_path_1.normPath)(folder, ignorePath)
// convert abs ignore glob to be relative to the root folder
.replace(commonRoot + '/', ''));
ignored.add(rootRelIgnoredPaths);
}
// Add gitattributes if present
const gitattributesPath = (0, norm_path_1.normPath)(folder, '.gitattributes');
if (fs_1.default.existsSync(gitattributesPath)) {
allFiles.add(gitattributesPath);
}
// Loop through files and folders
for (const file of files) {
// Create absolute path for disc operations
const path = (0, norm_path_1.normAbsPath)(commonRoot, file);
const localPath = localRoot ? file.replace(`./${localRoot}/`, '') : file.replace('./', '');
// Skip if nonexistant
const nonExistant = !fs_1.default.existsSync(path);
if (nonExistant)
continue;
// Skip if marked in gitignore
const isIgnored = ignored.test(localPath).ignored;
if (isIgnored)
continue;
// Add absolute folder path to list
allFolders.add((0, norm_path_1.normAbsPath)(folder));
// Check if this is a folder or file
if (file.endsWith('/')) {
// Recurse into subfolders
allFolders.add(path);
walk({ init: false, commonRoot, folderRoots, folders: [path], ignored });
}
else {
// Add file path to list
allFiles.add(path);
}
}
}
// Recurse into all folders
else {
for (const i in folders) {
walk({ init: false, commonRoot, folderRoots: [folderRoots[i]], folders: [folders[i]], ignored });
}
}
// Return absolute files and folders lists
return {
files: [...allFiles].map(file => file.replace(/^\./, commonRoot)),
folders: [...allFolders],
};
}