linguist-js 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +1 -1
- package/dist/index.js +33 -18
- package/dist/types.d.ts +1 -0
- package/package.json +5 -5
- package/readme.md +3 -0
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ if (args.analyze)
|
|
|
54
54
|
const data = await (0, index_1.default)(root, args);
|
|
55
55
|
const { files, languages, unknown } = data;
|
|
56
56
|
// Get file count
|
|
57
|
-
|
|
57
|
+
const totalFiles = (0, walk_tree_1.default)(root).files.length;
|
|
58
58
|
// Print output
|
|
59
59
|
if (!args.json) {
|
|
60
60
|
const sortedEntries = Object.entries(languages.results).sort((a, b) => a[1].bytes < b[1].bytes ? +1 : -1);
|
package/dist/index.js
CHANGED
|
@@ -14,8 +14,8 @@ const read_file_1 = __importDefault(require("./helpers/read-file"));
|
|
|
14
14
|
const convert_pcre_1 = __importDefault(require("./helpers/convert-pcre"));
|
|
15
15
|
const convert_glob_1 = __importDefault(require("./helpers/convert-glob"));
|
|
16
16
|
async function analyse(input, opts = {}) {
|
|
17
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
18
|
-
var
|
|
17
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
18
|
+
var _r, _s, _t;
|
|
19
19
|
const langData = await (0, load_data_1.default)('languages.yml').then(js_yaml_1.default.load);
|
|
20
20
|
const vendorData = await (0, load_data_1.default)('vendor.yml').then(js_yaml_1.default.load);
|
|
21
21
|
const heuristicsData = await (0, load_data_1.default)('heuristics.yml').then(js_yaml_1.default.load);
|
|
@@ -34,7 +34,16 @@ async function analyse(input, opts = {}) {
|
|
|
34
34
|
opts.keepVendored ? [] : vendorData.map(path => RegExp(path)),
|
|
35
35
|
(_b = (_a = opts.ignoredFiles) === null || _a === void 0 ? void 0 : _a.map(path => (0, glob_to_regexp_1.default)('*' + path + '*', { extended: true }))) !== null && _b !== void 0 ? _b : [],
|
|
36
36
|
].flat();
|
|
37
|
-
let
|
|
37
|
+
let files, folders;
|
|
38
|
+
if (opts.fileContent) {
|
|
39
|
+
opts.fileContent = Array.isArray(opts.fileContent) ? opts.fileContent : [opts.fileContent];
|
|
40
|
+
files = [`${input}`];
|
|
41
|
+
folders = [''];
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const data = (0, walk_tree_1.default)(input !== null && input !== void 0 ? input : '.', ignoredFiles);
|
|
45
|
+
({ files, folders } = data);
|
|
46
|
+
}
|
|
38
47
|
// Apply aliases
|
|
39
48
|
opts = { checkIgnored: !opts.quick, checkAttributes: !opts.quick, checkHeuristics: !opts.quick, checkShebang: !opts.quick, ...opts };
|
|
40
49
|
// Ignore specific languages
|
|
@@ -50,7 +59,7 @@ async function analyse(input, opts = {}) {
|
|
|
50
59
|
const customIgnored = [];
|
|
51
60
|
const customBinary = [];
|
|
52
61
|
const customText = [];
|
|
53
|
-
if (!opts.quick) {
|
|
62
|
+
if (!opts.fileContent && !opts.quick) {
|
|
54
63
|
for (const folder of folders) {
|
|
55
64
|
// Skip if folder is marked in gitattributes
|
|
56
65
|
if (customIgnored.some(path => (0, convert_glob_1.default)(path).test(folder)))
|
|
@@ -97,7 +106,7 @@ async function analyse(input, opts = {}) {
|
|
|
97
106
|
}
|
|
98
107
|
}
|
|
99
108
|
// Check vendored files
|
|
100
|
-
if (!opts.keepVendored) {
|
|
109
|
+
if (!opts.fileContent && !opts.keepVendored) {
|
|
101
110
|
// Filter out any files that match a vendor file path
|
|
102
111
|
const matcher = (match) => RegExp(match.replace(/\/$/, '/.+$').replace(/^\.\//, ''));
|
|
103
112
|
files = files.filter(file => !customIgnored.some(pattern => matcher(pattern).test(file)));
|
|
@@ -115,9 +124,15 @@ async function analyse(input, opts = {}) {
|
|
|
115
124
|
const overridesArray = Object.entries(overrides);
|
|
116
125
|
// List all languages that could be associated with a given file
|
|
117
126
|
for (const file of files) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
127
|
+
let firstLine;
|
|
128
|
+
if (opts.fileContent) {
|
|
129
|
+
firstLine = (_f = (_e = (_d = opts.fileContent) === null || _d === void 0 ? void 0 : _d[files.indexOf(file)]) === null || _e === void 0 ? void 0 : _e.split('\n')[0]) !== null && _f !== void 0 ? _f : null;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
if (!fs_1.default.existsSync(file) || fs_1.default.lstatSync(file).isDirectory())
|
|
133
|
+
continue;
|
|
134
|
+
firstLine = await (0, read_file_1.default)(file, true).catch(() => null);
|
|
135
|
+
}
|
|
121
136
|
// Skip if file is unreadable
|
|
122
137
|
if (firstLine === null)
|
|
123
138
|
continue;
|
|
@@ -132,7 +147,7 @@ async function analyse(input, opts = {}) {
|
|
|
132
147
|
}
|
|
133
148
|
}
|
|
134
149
|
// Check override for manual language classification
|
|
135
|
-
if (!opts.quick && opts.checkAttributes) {
|
|
150
|
+
if (!opts.fileContent && !opts.quick && opts.checkAttributes) {
|
|
136
151
|
const match = overridesArray.find(item => RegExp(item[0]).test(file));
|
|
137
152
|
if (match) {
|
|
138
153
|
const forcedLang = match[1];
|
|
@@ -144,7 +159,7 @@ async function analyse(input, opts = {}) {
|
|
|
144
159
|
let skipExts = false;
|
|
145
160
|
for (const lang in langData) {
|
|
146
161
|
// Check if filename is a match
|
|
147
|
-
const matchesName = (
|
|
162
|
+
const matchesName = (_g = langData[lang].filenames) === null || _g === void 0 ? void 0 : _g.some(name => path_1.default.basename(file.toLowerCase()) === name.toLowerCase());
|
|
148
163
|
if (matchesName) {
|
|
149
164
|
addResult(file, lang);
|
|
150
165
|
skipExts = true;
|
|
@@ -153,7 +168,7 @@ async function analyse(input, opts = {}) {
|
|
|
153
168
|
if (!skipExts)
|
|
154
169
|
for (const lang in langData) {
|
|
155
170
|
// Check if extension is a match
|
|
156
|
-
const matchesExt = (
|
|
171
|
+
const matchesExt = (_h = langData[lang].extensions) === null || _h === void 0 ? void 0 : _h.some(ext => file.toLowerCase().endsWith(ext.toLowerCase()));
|
|
157
172
|
if (matchesExt)
|
|
158
173
|
addResult(file, lang);
|
|
159
174
|
}
|
|
@@ -164,7 +179,7 @@ async function analyse(input, opts = {}) {
|
|
|
164
179
|
// Narrow down file associations to the best fit
|
|
165
180
|
for (const file in fileAssociations) {
|
|
166
181
|
// Skip binary files
|
|
167
|
-
if (!opts.keepBinary) {
|
|
182
|
+
if (!opts.fileContent && !opts.keepBinary) {
|
|
168
183
|
const isCustomText = customText.some(path => RegExp(path).test(file));
|
|
169
184
|
const isCustomBinary = customBinary.some(path => RegExp(path).test(file));
|
|
170
185
|
const isBinaryExt = binary_extensions_1.default.some(ext => file.endsWith('.' + ext));
|
|
@@ -208,10 +223,10 @@ async function analyse(input, opts = {}) {
|
|
|
208
223
|
}
|
|
209
224
|
}
|
|
210
225
|
// If no heuristics, assign a language
|
|
211
|
-
(
|
|
226
|
+
(_j = (_r = results.files.results)[file]) !== null && _j !== void 0 ? _j : (_r[file] = fileAssociations[file][0]);
|
|
212
227
|
}
|
|
213
228
|
// Skip specified categories
|
|
214
|
-
if ((
|
|
229
|
+
if ((_k = opts.categories) === null || _k === void 0 ? void 0 : _k.length) {
|
|
215
230
|
const categories = ['data', 'markup', 'programming', 'prose'];
|
|
216
231
|
const hiddenCategories = categories.filter(cat => !opts.categories.includes(cat));
|
|
217
232
|
for (const [file, lang] of Object.entries(results.files.results)) {
|
|
@@ -229,7 +244,7 @@ async function analyse(input, opts = {}) {
|
|
|
229
244
|
}
|
|
230
245
|
}
|
|
231
246
|
// Convert paths to relative
|
|
232
|
-
if (opts.relativePaths) {
|
|
247
|
+
if (!opts.fileContent && opts.relativePaths) {
|
|
233
248
|
const newMap = {};
|
|
234
249
|
for (const [file, lang] of Object.entries(results.files.results)) {
|
|
235
250
|
let relPath = path_1.default.relative(process.cwd(), file).replace(/\\/g, '/');
|
|
@@ -243,21 +258,21 @@ async function analyse(input, opts = {}) {
|
|
|
243
258
|
for (const [file, lang] of Object.entries(results.files.results)) {
|
|
244
259
|
if (lang && !langData[lang])
|
|
245
260
|
continue;
|
|
246
|
-
const fileSize = fs_1.default.statSync(file).size;
|
|
261
|
+
const fileSize = (_o = (_m = (_l = opts.fileContent) === null || _l === void 0 ? void 0 : _l[files.indexOf(file)]) === null || _m === void 0 ? void 0 : _m.length) !== null && _o !== void 0 ? _o : fs_1.default.statSync(file).size;
|
|
247
262
|
results.files.bytes += fileSize;
|
|
248
263
|
// If no language found, add extension in other section
|
|
249
264
|
if (!lang) {
|
|
250
265
|
const ext = path_1.default.extname(file);
|
|
251
266
|
const unknownType = ext === '' ? 'filenames' : 'extensions';
|
|
252
267
|
const name = ext === '' ? path_1.default.basename(file) : ext;
|
|
253
|
-
(
|
|
268
|
+
(_p = (_s = results.unknown[unknownType])[name]) !== null && _p !== void 0 ? _p : (_s[name] = 0);
|
|
254
269
|
results.unknown[unknownType][name] += fileSize;
|
|
255
270
|
results.unknown.bytes += fileSize;
|
|
256
271
|
continue;
|
|
257
272
|
}
|
|
258
273
|
// Add language and bytes data to corresponding section
|
|
259
274
|
const { type } = langData[lang];
|
|
260
|
-
(
|
|
275
|
+
(_q = (_t = results.languages.results)[lang]) !== null && _q !== void 0 ? _q : (_t[lang] = { type, bytes: 0, color: langData[lang].color });
|
|
261
276
|
if (opts.childLanguages)
|
|
262
277
|
results.languages.results[lang].parent = langData[lang].group;
|
|
263
278
|
results.languages.results[lang].bytes += fileSize;
|
package/dist/types.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare type FilePath = string;
|
|
|
5
5
|
export declare type Bytes = Integer;
|
|
6
6
|
export declare type Integer = number;
|
|
7
7
|
export interface Options {
|
|
8
|
+
fileContent?: string | string[];
|
|
8
9
|
ignoredFiles?: string[];
|
|
9
10
|
ignoredLanguages?: Language[];
|
|
10
11
|
categories?: Category[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linguist-js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Analyse languages used in a folder. Powered by GitHub Linguist, although it doesn't need to be installed.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"node-cache": "^5.1.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@types/glob-to-regexp": "ts4.
|
|
49
|
-
"@types/js-yaml": "ts4.
|
|
50
|
-
"@types/node": "ts4.
|
|
48
|
+
"@types/glob-to-regexp": "ts4.6",
|
|
49
|
+
"@types/js-yaml": "ts4.6",
|
|
50
|
+
"@types/node": "ts4.6",
|
|
51
51
|
"deep-object-diff": "^1.1.7",
|
|
52
|
-
"typescript": "~4.
|
|
52
|
+
"typescript": "~4.6.1-rc"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/readme.md
CHANGED
|
@@ -77,6 +77,7 @@ Running Linguist on this folder will return the following JSON:
|
|
|
77
77
|
### Notes
|
|
78
78
|
|
|
79
79
|
- File paths in the output use only forward slashes as delimiters, even on Windows.
|
|
80
|
+
- This tool does not work when offline.
|
|
80
81
|
- Do not rely on any language classification output from Linguist being unchanged between runs.
|
|
81
82
|
Language data is fetched each run from the latest classifications of [`github-linguist`](https://github.com/github/linguist).
|
|
82
83
|
This data is subject to change at any time and may change the results of a run even when using the same version of Linguist.
|
|
@@ -99,6 +100,8 @@ const { files, languages, unknown } = linguist(folder, options);
|
|
|
99
100
|
Analyse multiple folders using the syntax `"{folder1,folder2,...}"`.
|
|
100
101
|
- `opts` (optional; object):
|
|
101
102
|
An object containing analyser options.
|
|
103
|
+
- `fileContent` (string or string array):
|
|
104
|
+
Provides the file content associated with the file name(s) given as `entry` to analyse instead of reading from a folder on disk.
|
|
102
105
|
- `ignoredFiles` (string array):
|
|
103
106
|
A list of file path globs to explicitly ignore.
|
|
104
107
|
- `ignoredLanguages` (string array):
|