mirror of
https://github.com/github/codeql-action.git
synced 2025-12-28 02:00:12 +08:00
This version will count lines of code in each file serially. It still runs all file system operations asynchronously. The only difference now is that it will only count one file at a time. It is slower, but it is able to count large repositories without running out of memory.
210 lines
5.7 KiB
JavaScript
210 lines
5.7 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.LocDir = void 0;
|
|
const globby_1 = __importDefault(require("globby"));
|
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
const path_1 = __importDefault(require("path"));
|
|
// @ts-ignore
|
|
const slash2_1 = __importDefault(require("slash2"));
|
|
const file_1 = require("./file");
|
|
const languages_1 = require("./languages");
|
|
const defaultInfo = {
|
|
total: 0,
|
|
code: 0,
|
|
comment: 0,
|
|
};
|
|
const defaultExclude = [
|
|
// javascript
|
|
'**/*.map',
|
|
'**/yarn**',
|
|
'**/.github',
|
|
'**/node_modules/**',
|
|
'**/dist/**',
|
|
'**/*.snap',
|
|
// java
|
|
'**/target',
|
|
"**/*.class",
|
|
"**/*.o",
|
|
"**/bin",
|
|
"**/*.map",
|
|
// python
|
|
"**/*.pyc",
|
|
"**/*.pyo",
|
|
// other
|
|
"**/*.dil",
|
|
"**/*.ra",
|
|
// images
|
|
'**/*.png',
|
|
'**/*.jpg',
|
|
'**/*.jpeg',
|
|
'**/*.gif',
|
|
'**/*.ico',
|
|
'**/*.bmp',
|
|
'**/*.webp',
|
|
'**/*.tiff',
|
|
'**/*.psd',
|
|
'**/*.ai',
|
|
'**/*.ps',
|
|
'**/*.eps',
|
|
// fonts
|
|
'**/*.ttf',
|
|
'**/*.otf',
|
|
'**/*.woff',
|
|
'**/*.woff2',
|
|
'**/*.eot',
|
|
'**/*.ttc',
|
|
// audio
|
|
'**/*.mp3',
|
|
'**/*.wav',
|
|
'**/*.ogg',
|
|
'**/*.flac',
|
|
'**/*.aac',
|
|
'**/*.m4a',
|
|
'**/*.aif*',
|
|
// video
|
|
'**/*.mp4',
|
|
'**/*.mkv',
|
|
'**/*.avi',
|
|
'**/*.mov',
|
|
'**/*.wmv',
|
|
'**/*.mpg',
|
|
'**/*.mpeg',
|
|
'**/*.m2v',
|
|
'**/*.m4v',
|
|
// office
|
|
'**/*.doc',
|
|
'**/*.docx',
|
|
'**/*.docm',
|
|
'**/*.dot',
|
|
'**/*.dotx',
|
|
'**/*.xls',
|
|
'**/*.xlsx',
|
|
// documents
|
|
'**/*.pdf',
|
|
'**/*.epub',
|
|
'**/*.mobi',
|
|
// archives
|
|
'**/*.rar',
|
|
'**/*.zip',
|
|
'**/*.7z',
|
|
'**/*.tar',
|
|
'**/*.gz',
|
|
'**/*.bz2',
|
|
'**/*.bz',
|
|
'**/*.tbz',
|
|
'**/*.tgz',
|
|
];
|
|
/**
|
|
* Collect the info of a directory.
|
|
*/
|
|
class LocDir {
|
|
constructor(options) {
|
|
Object.defineProperty(this, "cwd", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
Object.defineProperty(this, "include", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
Object.defineProperty(this, "exclude", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
Object.defineProperty(this, "analysisLanguages", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: void 0
|
|
});
|
|
Object.defineProperty(this, "allLanguages", {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: new languages_1.Languages()
|
|
});
|
|
// ensure all excludes are globstar. Note that '**/*.ts/**' matches files
|
|
// that end in .ts because the globstar indicates 0 or more directory paths.
|
|
this.exclude = ensureArray(options.exclude)
|
|
.concat(defaultExclude)
|
|
.map(item => item.endsWith('**') ? item : `${item}/**`);
|
|
// remove all leading './' since this messes up globstar matches in the
|
|
// excludes.
|
|
this.include = ensureArray(options.include, '**')
|
|
.map(item => item.startsWith('./') ? item.substring(2) : item)
|
|
.map(item => item.endsWith('**') ? item : `${item}/**`);
|
|
this.cwd = options.cwd || process.cwd();
|
|
this.analysisLanguages = options.analysisLanguages;
|
|
}
|
|
/**
|
|
* Calculate directory info.
|
|
*/
|
|
async loadInfo() {
|
|
const paths = await globby_1.default(this.include, {
|
|
cwd: this.cwd,
|
|
ignore: this.exclude,
|
|
nodir: true
|
|
});
|
|
const files = [];
|
|
const info = { ...defaultInfo };
|
|
let languages = {};
|
|
// We _could_ use Promise.all to count the files in parallel, but that
|
|
// would lead to out of memory errors when there are many files.
|
|
for (const pathItem of paths) {
|
|
const fullPath = slash2_1.default(path_1.default.join(this.cwd, pathItem));
|
|
if (!pathItem ||
|
|
this.ignoreLanguage(pathItem) ||
|
|
!(await fs_extra_1.default.pathExists(fullPath)) ||
|
|
(await fs_extra_1.default.stat(fullPath)).isDirectory()) {
|
|
continue;
|
|
}
|
|
const file = new file_1.LocFile(fullPath);
|
|
const fileLineInfo = await file.getFileInfo();
|
|
const { lines } = fileLineInfo;
|
|
info.total += lines.total;
|
|
info.code += lines.code;
|
|
info.comment += lines.comment;
|
|
const language = { ...languages[fileLineInfo.languages] };
|
|
language.code = lines.code + (language.code || 0);
|
|
language.sum = (language.sum || 0) + 1;
|
|
language.comment = lines.comment + (language.comment || 0);
|
|
language.total = lines.total + (language.total || 0);
|
|
languages = {
|
|
...languages,
|
|
[fileLineInfo.languages]: language,
|
|
};
|
|
files.push(fullPath);
|
|
}
|
|
return {
|
|
files,
|
|
info,
|
|
languages,
|
|
};
|
|
}
|
|
/**
|
|
* Ignore analyzing this file if analysis languages are specified
|
|
* and this language is not one of them.
|
|
*/
|
|
ignoreLanguage(pathItem) {
|
|
return this.analysisLanguages && !this.analysisLanguages.includes(this.allLanguages.getType(pathItem));
|
|
}
|
|
}
|
|
exports.LocDir = LocDir;
|
|
function ensureArray(arr, dfault) {
|
|
if (!arr) {
|
|
return dfault ? [dfault] : [];
|
|
}
|
|
return Array.isArray(arr)
|
|
? arr
|
|
: [arr];
|
|
}
|
|
//# sourceMappingURL=directory.js.map
|