linguist-js
Advanced tools
Comparing version 1.4.5 to 1.5.0
@@ -17,3 +17,3 @@ "use strict"; | ||
.option('-s|--summary', 'Show output in a human-readable format', false) | ||
.option('-q|--quick', 'Skip checking of gitattributes/gitignore files (alias for -AIH=false)', false) | ||
.option('-q|--quick', 'Skip checking of gitattributes/gitignore files (alias for -AIHS=false)', false) | ||
.option('-V|--keepVendored', 'Prevent skipping over vendored/generated files', false) | ||
@@ -23,2 +23,3 @@ .option('-A|--checkAttributes', 'Force the checking of gitattributes files (default: true unless --quick is set)') | ||
.option('-H|--checkHeuristics', 'Apply heuristics to ambiguous languages (default: true unless --quick is set)') | ||
.option('-S|--checkShebang|--checkHashbang', 'Check shebang lines for explicit classification (default: true unless --quick is set)') | ||
.helpOption(`-h|--help`, 'Display this help message') | ||
@@ -25,0 +26,0 @@ .version(VERSION, '-v|--version', 'Display the installed version of linguist-js'); |
@@ -8,3 +8,3 @@ "use strict"; | ||
const js_yaml_1 = __importDefault(require("js-yaml")); | ||
const fast_glob_1 = __importDefault(require("fast-glob")); | ||
const tiny_glob_1 = __importDefault(require("tiny-glob")); | ||
const glob_to_regexp_1 = __importDefault(require("glob-to-regexp")); | ||
@@ -16,2 +16,13 @@ const convertToRegex = (path) => glob_to_regexp_1.default('**/' + path, { globstar: true, extended: true }); | ||
const loadFile = async (file) => await cross_fetch_1.default(dataUrl(file)).then(data => data.text()); | ||
async function readFile(filename, onlyFirstLine = false) { | ||
const chunkSize = 100; | ||
const stream = fs_1.default.createReadStream(filename, { highWaterMark: chunkSize }); | ||
let content = ''; | ||
for await (const data of stream) { | ||
content += data.toString(); | ||
if (onlyFirstLine && /\n/.test(content)) | ||
return content; | ||
} | ||
return content; | ||
} | ||
module.exports = async function analyse(root = '.', opts = {}) { | ||
@@ -35,7 +46,7 @@ var _a, _b, _c, _d, _e, _f, _g; | ||
}; | ||
let files = await fast_glob_1.default(root + '/**/*', { absolute: true, onlyFiles: true, dot: true }); | ||
files = files.filter(file => !file.includes('/.git/')); | ||
let files = await tiny_glob_1.default(root + '/**/*', { absolute: true, filesOnly: true, dot: true }); | ||
files = files.map(path => path.replace(/\\/g, '/')).filter(file => !file.includes('/.git/')); | ||
const folders = new Set(files.map(file => file.replace(/[^/]+$/, ''))); | ||
// Apply aliases | ||
opts = { checkIgnored: !opts.quick, checkAttributes: !opts.quick, checkHeuristics: !opts.quick, ...opts }; | ||
opts = { checkIgnored: !opts.quick, checkAttributes: !opts.quick, checkHeuristics: !opts.quick, checkShebang: !opts.quick, ...opts }; | ||
// Apply explicit ignores | ||
@@ -56,3 +67,3 @@ if (opts.ignore) { | ||
if (opts.checkIgnored && fs_1.default.existsSync(ignoresFile)) { | ||
const ignoresData = fs_1.default.readFileSync(ignoresFile, { encoding: 'utf8' }); | ||
const ignoresData = await readFile(ignoresFile); | ||
const ignoresList = ignoresData.split(/\r?\n/).filter(line => line.trim() && !line.startsWith('#')); | ||
@@ -64,3 +75,3 @@ const ignoredPaths = ignoresList.map(path => glob_to_regexp_1.default('*' + path + '*', { extended: true }).source); | ||
if (opts.checkAttributes && fs_1.default.existsSync(attributesFile)) { | ||
const attributesData = fs_1.default.readFileSync(attributesFile, { encoding: 'utf8' }); | ||
const attributesData = await readFile(attributesFile); | ||
// Custom vendor options | ||
@@ -105,4 +116,17 @@ const vendorMatches = attributesData.matchAll(/^(\S+).*[^-]linguist-(vendored|generated|documentation)(?!=false)/gm); | ||
continue; | ||
// Check shebang line for explicit classification | ||
if (!opts.quick && opts.checkShebang) { | ||
const firstLine = await readFile(file, true); | ||
if (firstLine.startsWith('#!')) { | ||
const interpreter = firstLine.split(/\s/)[1]; | ||
const match = Object.entries(langData).filter(([_lang, data]) => { var _a; return (_a = data.interpreters) === null || _a === void 0 ? void 0 : _a.includes(interpreter); }); | ||
if (match.length) { | ||
const forcedLang = match[0][0]; | ||
addResult(file, forcedLang); | ||
continue; | ||
} | ||
} | ||
} | ||
// Check override for manual language classification | ||
if (!opts.quick) { | ||
if (!opts.quick && opts.checkAttributes) { | ||
const match = overridesArray.find(item => RegExp(item[0]).test(file)); | ||
@@ -153,3 +177,3 @@ if (match) { | ||
// Check file contents and apply heuristic patterns | ||
const fileContent = fs_1.default.readFileSync(file, { encoding: 'utf8' }); | ||
const fileContent = await readFile(file); | ||
if (patterns.some(pattern => RegExp(pattern).test(fileContent))) { | ||
@@ -156,0 +180,0 @@ finalResults[file] = heuristic.language; |
@@ -13,2 +13,3 @@ import { LanguageType } from "./schema"; | ||
checkHeuristics?: boolean; | ||
checkShebang?: boolean; | ||
ignore?: string[]; | ||
@@ -15,0 +16,0 @@ } |
{ | ||
"name": "linguist-js", | ||
"version": "1.4.5", | ||
"version": "1.5.0", | ||
"description": "Analyse languages used in a folder. Powered by GitHub Linguist, although it doesn't need to be installed.", | ||
@@ -37,5 +37,5 @@ "main": "dist/index.js", | ||
"cross-fetch": "^3.1.4", | ||
"fast-glob": "^3.2.7", | ||
"glob-to-regexp": "^0.4.1", | ||
"js-yaml": "^4.1.0" | ||
"js-yaml": "^4.1.0", | ||
"tiny-glob": "^0.2.9" | ||
}, | ||
@@ -42,0 +42,0 @@ "devDependencies": { |
@@ -88,3 +88,3 @@ [![Latest version](https://img.shields.io/github/v/release/Nixinova/Linguist?label=latest%20version&style=flat-square)](https://github.com/Nixinova/Linguist/releases) | ||
Whether to skip the checking of `.gitattributes` and `.gitignore` files for manual language classifications (defaults to `false`). | ||
Alias for `checkAttributes: false, checkIgnored: false`. | ||
Alias for `checkAttributes:false, checkIgnored:false, checkHeuristics:false, checkShebang:false`. | ||
- `keepVendored` (boolean): | ||
@@ -98,2 +98,4 @@ Whether to keep vendored files (dependencies, etc) (defaults to `false`). | ||
Apply heuristics to ambiguous languages (defaults to `true` unless `quick` is set). | ||
- `checkShebang` (boolean): | ||
Check shebang (`#!`) lines for explicit language classification (defaults to `true` unless `quick` is set). | ||
@@ -121,11 +123,13 @@ ### Command-line | ||
Whether to skip the checking of `.gitattributes` and `.gitignore` files for manual language classifications. | ||
Alias for `--checkAttributes=false --checkIgnored=false --checkHeuristics=false`. | ||
Alias for `--checkAttributes=false --checkIgnored=false --checkHeuristics=false --checkShebang=false`. | ||
- `--keepVendored` (optional): | ||
Whether to include vendored files (auto-generated files, dependencies folder, etc). | ||
- `checkAttributes` (optional): | ||
- `--checkAttributes` (optional): | ||
Force the checking of `.gitatributes` files (use alongside `--quick` to overwrite). | ||
- `checkIgnored` (optional): | ||
- `--checkIgnored` (optional): | ||
Force the checking of `.gitignore` files (use alongside `--quick` to overwrite). | ||
- `checkHeuristics` (optional): | ||
- `--checkHeuristics` (optional): | ||
Apply heuristics to ambiguous languages (use alongside `--quick` to overwrite). | ||
- `--checkShebang` (optional): | ||
Check shebang (`#!`) lines for explicit classification (use alongside `--quick` to overwrite). | ||
- `--help`: | ||
@@ -132,0 +136,0 @@ Display a help message. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23961
354
136
+ Addedtiny-glob@^0.2.9
+ Addedglobalyzer@0.1.0(transitive)
+ Addedglobrex@0.1.2(transitive)
+ Addedtiny-glob@0.2.9(transitive)
- Removedfast-glob@^3.2.7
- Removed@nodelib/fs.scandir@2.1.5(transitive)
- Removed@nodelib/fs.stat@2.0.5(transitive)
- Removed@nodelib/fs.walk@1.2.8(transitive)
- Removedbraces@3.0.3(transitive)
- Removedfast-glob@3.3.2(transitive)
- Removedfastq@1.17.1(transitive)
- Removedfill-range@7.1.1(transitive)
- Removedglob-parent@5.1.2(transitive)
- Removedis-extglob@2.1.1(transitive)
- Removedis-glob@4.0.3(transitive)
- Removedis-number@7.0.0(transitive)
- Removedmerge2@1.4.1(transitive)
- Removedmicromatch@4.0.8(transitive)
- Removedpicomatch@2.3.1(transitive)
- Removedqueue-microtask@1.2.3(transitive)
- Removedreusify@1.0.4(transitive)
- Removedrun-parallel@1.2.0(transitive)
- Removedto-regex-range@5.0.1(transitive)