linguist-js
Advanced tools
Comparing version 2.7.0 to 2.7.1
@@ -11,2 +11,3 @@ "use strict"; | ||
const index_1 = __importDefault(require("./index")); | ||
const norm_path_1 = require("./helpers/norm-path"); | ||
const colouredMsg = ([r, g, b], msg) => `\u001B[${38};2;${r};${g};${b}m${msg}${'\u001b[0m'}`; | ||
@@ -96,3 +97,3 @@ const hexToRgb = (hex) => [parseInt(hex.slice(1, 3), 16), parseInt(hex.slice(3, 5), 16), parseInt(hex.slice(5, 7), 16)]; | ||
for (const file of filesPerLanguage[lang]) { | ||
let relFile = path_1.default.relative(path_1.default.resolve('.'), file).replace(/\\/g, '/'); | ||
let relFile = (0, norm_path_1.normPath)(path_1.default.relative(path_1.default.resolve('.'), file)); | ||
if (!relFile.startsWith('../')) | ||
@@ -99,0 +100,0 @@ relFile = './' + relFile; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const path_1 = __importDefault(require("path")); | ||
const norm_path_1 = require("./norm-path"); | ||
/** | ||
@@ -19,3 +16,3 @@ * Parses a gitattributes file. | ||
const fileGlob = parts[0]; | ||
const relFileGlob = path_1.default.join(folderRoot, fileGlob).replace(/\\/g, '/'); | ||
const relFileGlob = (0, norm_path_1.normPath)(folderRoot, fileGlob); | ||
const attrParts = parts.slice(1); | ||
@@ -22,0 +19,0 @@ const isTrue = (str) => !str.startsWith('-') && !str.endsWith('=false'); |
@@ -8,2 +8,4 @@ "use strict"; | ||
const path_1 = __importDefault(require("path")); | ||
const parse_gitignore_1 = __importDefault(require("./parse-gitignore")); | ||
const norm_path_1 = require("./norm-path"); | ||
let allFiles; | ||
@@ -28,3 +30,3 @@ let allFolders; | ||
// Create path relative to root | ||
const base = path_1.default.resolve(folder, file).replace(/\\/g, '/').replace(commonRoot, '.'); | ||
const base = (0, norm_path_1.normAbsPath)(folder, file).replace(commonRoot, '.'); | ||
// Add trailing slash to mark directories | ||
@@ -34,6 +36,18 @@ const isDir = fs_1.default.lstatSync(path_1.default.resolve(commonRoot, base)).isDirectory(); | ||
}); | ||
// 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); | ||
ignored.add(ignoredPaths); | ||
} | ||
// 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 = path_1.default.resolve(commonRoot, file).replace(/\\/g, '/'); | ||
const path = (0, norm_path_1.normAbsPath)(commonRoot, file); | ||
const localPath = localRoot ? file.replace(`./${localRoot}/`, '') : file.replace('./', ''); | ||
@@ -44,3 +58,3 @@ // Skip if nonexistant | ||
continue; | ||
// Skip if marked as ignored | ||
// Skip if marked in gitignore | ||
const isIgnored = ignored.test(localPath).ignored; | ||
@@ -50,3 +64,3 @@ if (isIgnored) | ||
// Add absolute folder path to list | ||
allFolders.add(path_1.default.resolve(folder).replace(/\\/g, '/')); | ||
allFolders.add((0, norm_path_1.normAbsPath)(folder)); | ||
// Check if this is a folder or file | ||
@@ -53,0 +67,0 @@ if (file.endsWith('/')) { |
@@ -40,2 +40,3 @@ "use strict"; | ||
const convert_pcre_1 = __importDefault(require("./helpers/convert-pcre")); | ||
const norm_path_1 = require("./helpers/norm-path"); | ||
async function analyse(rawPaths, opts = {}) { | ||
@@ -73,8 +74,6 @@ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q; | ||
// Set a common root path so that vendor paths do not incorrectly match parent folders | ||
const normPath = (file) => file.replace(/\\/g, '/'); | ||
const resolvedInput = input.map(path => normPath(path_1.default.resolve(path))); | ||
const resolvedInput = input.map(path => (0, norm_path_1.normPath)(path_1.default.resolve(path))); | ||
const commonRoot = (input.length > 1 ? (0, common_path_prefix_1.default)(resolvedInput) : resolvedInput[0]).replace(/\/?$/, ''); | ||
const localRoot = (folder) => folder.replace(commonRoot, '').replace(/^\//, ''); | ||
const relPath = (file) => useRawContent ? file : normPath(path_1.default.relative(commonRoot, file)); | ||
const unRelPath = (file) => useRawContent ? file : normPath(path_1.default.resolve(commonRoot, file)); | ||
const relPath = (file) => useRawContent ? file : (0, norm_path_1.normPath)(path_1.default.relative(commonRoot, file)); | ||
const unRelPath = (file) => useRawContent ? file : (0, norm_path_1.normPath)(path_1.default.resolve(commonRoot, file)); | ||
// Other helper functions | ||
@@ -88,12 +87,8 @@ const fileMatchesGlobs = (file, ...globs) => (0, ignore_1.default)().add(globs).ignores(relPath(file)); | ||
ignored.add((_b = opts.ignoredFiles) !== null && _b !== void 0 ? _b : []); | ||
const regexIgnores = []; | ||
if (!opts.keepVendored) | ||
regexIgnores.push(...vendorPaths.map(path => RegExp(path, 'i'))); | ||
const regexIgnores = opts.keepVendored ? [] : vendorPaths.map(path => RegExp(path, 'i')); | ||
// Load file paths and folders | ||
let files; | ||
let folders; | ||
if (useRawContent) { | ||
// Uses raw file content | ||
files = input; | ||
folders = ['']; | ||
} | ||
@@ -104,22 +99,3 @@ else { | ||
files = data.files; | ||
folders = data.folders; | ||
} | ||
// Load gitignore data and apply ignores rules | ||
if (!useRawContent && opts.checkIgnored) { | ||
const nestedIgnoreFiles = files.filter(file => file.endsWith('.gitignore')); | ||
for (const ignoresFile of nestedIgnoreFiles) { | ||
const relIgnoresFile = relPath(ignoresFile); | ||
const relIgnoresFolder = path_1.default.dirname(relIgnoresFile); | ||
// Parse gitignores | ||
const ignoresDataRaw = await (0, read_file_1.default)(ignoresFile); | ||
const ignoresData = ignoresDataRaw.replace(/#.+|\s+$/gm, ''); | ||
const absoluteIgnoresData = ignoresData | ||
// '.file' -> 'root/*/.file' | ||
.replace(/^(?=[^\s\/\\])/gm, localRoot(relIgnoresFolder) + '/*/') | ||
// '/folder' -> 'root/folder' | ||
.replace(/^[\/\\]/gm, localRoot(relIgnoresFolder) + '/'); | ||
ignored.add(absoluteIgnoresData); | ||
files = filterOutIgnored(files, ignored); | ||
} | ||
} | ||
// Fetch and normalise gitattributes data of all subfolders and save to metadata | ||
@@ -130,2 +106,18 @@ const manualAttributes = {}; // Maps file globs to gitattribute boolean flags | ||
}; | ||
const findAttrsForPath = (filePath) => { | ||
const resultAttrs = {}; | ||
for (const glob in manualAttributes) { | ||
if ((0, ignore_1.default)().add(glob).ignores(relPath(filePath))) { | ||
const matchingAttrs = manualAttributes[glob]; | ||
for (const [attr, val] of Object.entries(matchingAttrs)) { | ||
if (val !== null) | ||
resultAttrs[attr] = val; | ||
} | ||
} | ||
} | ||
if (!JSON.stringify(resultAttrs)) { | ||
return null; | ||
} | ||
return resultAttrs; | ||
}; | ||
if (!useRawContent && opts.checkAttributes) { | ||
@@ -143,2 +135,21 @@ const nestedAttrFiles = files.filter(file => file.endsWith('.gitattributes')); | ||
} | ||
// Remove files that are linguist-ignored via regex by default unless explicitly unignored in gitattributes | ||
const filesToIgnore = []; | ||
for (const file of files) { | ||
const relFile = relPath(file); | ||
const isRegexIgnored = regexIgnores.some(pattern => pattern.test(relFile)); | ||
if (!isRegexIgnored) { | ||
// Checking overrides is moot if file is not even marked as ignored by default | ||
continue; | ||
} | ||
const fileAttrs = findAttrsForPath(file); | ||
if ((fileAttrs === null || fileAttrs === void 0 ? void 0 : fileAttrs.generated) === false || (fileAttrs === null || fileAttrs === void 0 ? void 0 : fileAttrs.vendored) === false) { | ||
// File is explicitly marked as *not* to be ignored | ||
// do nothing | ||
} | ||
else { | ||
filesToIgnore.push(file); | ||
} | ||
} | ||
files = files.filter(file => !filesToIgnore.includes(file)); | ||
// Apply vendor file path matches and filter out vendored files | ||
@@ -398,3 +409,3 @@ if (!opts.keepVendored) { | ||
for (const [file, lang] of Object.entries(results.files.results)) { | ||
let relPath = path_1.default.relative(process.cwd(), file).replace(/\\/g, '/'); | ||
let relPath = (0, norm_path_1.normPath)(path_1.default.relative(process.cwd(), file)); | ||
if (!relPath.startsWith('../')) { | ||
@@ -401,0 +412,0 @@ relPath = './' + relPath; |
# ISC License | ||
Copyright © Nixinova 2021–2022 | ||
Copyright © Nixinova 2021–2024 | ||
@@ -5,0 +5,0 @@ Permission to use, copy, modify, and/or distribute this software for any |
{ | ||
"name": "linguist-js", | ||
"version": "2.7.0", | ||
"version": "2.7.1", | ||
"description": "Analyse languages used in a folder. Powered by GitHub Linguist, although it doesn't need to be installed.", | ||
@@ -14,6 +14,6 @@ "main": "dist/index.js", | ||
"scripts": { | ||
"download-files": "npx tsx@3 build/download-files", | ||
"download-files": "npx tsx@4 build/download-files", | ||
"pre-publish": "npm run download-files && npm test && npm run perf", | ||
"perf": "tsc && node test/perf", | ||
"test": "tsc && node test/folder && echo --- && node test/unit" | ||
"test": "tsc && node test/folder && node test/unit" | ||
}, | ||
@@ -42,3 +42,3 @@ "files": [ | ||
"dependencies": { | ||
"binary-extensions": "^2.2.0", | ||
"binary-extensions": "^2.2.0 <3", | ||
"commander": "^9.5.0 <10", | ||
@@ -45,0 +45,0 @@ "common-path-prefix": "^3.0.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
229863
31
981
Updatedbinary-extensions@^2.2.0 <3