linguist-js 2.9.2 → 3.0.0-pre

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.
Files changed (81) hide show
  1. package/bin/index.js +1 -1
  2. package/dist/analyser/classifiers/byAttributes.d.ts +3 -0
  3. package/dist/analyser/classifiers/byAttributes.js +13 -0
  4. package/dist/analyser/classifiers/byExtension.d.ts +3 -0
  5. package/dist/analyser/classifiers/byExtension.js +31 -0
  6. package/dist/analyser/classifiers/byFilename.d.ts +3 -0
  7. package/dist/analyser/classifiers/byFilename.js +10 -0
  8. package/dist/analyser/classifiers/byHeuristics.d.ts +3 -0
  9. package/dist/analyser/classifiers/byHeuristics.js +67 -0
  10. package/dist/analyser/classifiers/byModeline.d.ts +3 -0
  11. package/dist/analyser/classifiers/byModeline.js +22 -0
  12. package/dist/analyser/classifiers/byShebang.d.ts +3 -0
  13. package/dist/analyser/classifiers/byShebang.js +27 -0
  14. package/dist/analyser/index.d.ts +3 -0
  15. package/dist/analyser/index.js +12 -0
  16. package/dist/analyser/pipeline/aggregate.d.ts +2 -0
  17. package/dist/analyser/pipeline/aggregate.js +98 -0
  18. package/dist/analyser/pipeline/classify.d.ts +3 -0
  19. package/dist/analyser/pipeline/classify.js +31 -0
  20. package/dist/analyser/pipeline/filter.d.ts +2 -0
  21. package/dist/analyser/pipeline/filter.js +14 -0
  22. package/dist/analyser/pipeline/heuristics.d.ts +3 -0
  23. package/dist/analyser/pipeline/heuristics.js +12 -0
  24. package/dist/analyser/pipeline/normalise.d.ts +2 -0
  25. package/dist/analyser/pipeline/normalise.js +9 -0
  26. package/dist/cli/output/default.d.ts +3 -0
  27. package/dist/cli/output/default.js +106 -0
  28. package/dist/cli/output/tree.d.ts +3 -0
  29. package/dist/cli/output/tree.js +11 -0
  30. package/dist/cli/runCliAnalysis.d.ts +2 -0
  31. package/dist/cli/runCliAnalysis.js +26 -0
  32. package/dist/cli/utils.d.ts +2 -0
  33. package/dist/cli/utils.js +9 -0
  34. package/dist/cli.js +14 -143
  35. package/dist/entry/analyseFs.d.ts +2 -0
  36. package/dist/entry/analyseFs.js +11 -0
  37. package/dist/entry/analyseRaw.d.ts +4 -0
  38. package/dist/entry/analyseRaw.js +11 -0
  39. package/dist/index.d.ts +19 -4
  40. package/dist/index.js +18 -483
  41. package/dist/input/fromFilesystem.d.ts +4 -0
  42. package/dist/input/fromFilesystem.js +115 -0
  43. package/dist/input/fromRawContent.d.ts +2 -0
  44. package/dist/input/fromRawContent.js +19 -0
  45. package/dist/input/normaliseOpts.d.ts +2 -0
  46. package/dist/input/normaliseOpts.js +13 -0
  47. package/dist/program/classes/attributes.d.ts +11 -0
  48. package/dist/program/classes/attributes.js +37 -0
  49. package/dist/{helpers/load-data.d.ts → program/data/loadDataFiles.d.ts} +1 -1
  50. package/dist/program/data/loadDataFiles.js +32 -0
  51. package/dist/program/data/retrieveData.d.ts +12 -0
  52. package/dist/program/data/retrieveData.js +27 -0
  53. package/dist/{helpers/norm-path.d.ts → program/fs/normalisedPath.d.ts} +1 -0
  54. package/dist/program/fs/normalisedPath.js +17 -0
  55. package/dist/program/fs/readFile.js +17 -0
  56. package/dist/{helpers/walk-tree.d.ts → program/fs/walkTree.d.ts} +1 -1
  57. package/dist/{helpers/walk-tree.js → program/fs/walkTree.js} +22 -30
  58. package/dist/{helpers/parse-gitattributes.d.ts → program/parsing/parseGitattributes.d.ts} +2 -2
  59. package/dist/{helpers/parse-gitattributes.js → program/parsing/parseGitattributes.js} +4 -8
  60. package/dist/{helpers/parse-gitignore.js → program/parsing/parseGitignore.js} +1 -4
  61. package/dist/program/processFiles.d.ts +9 -0
  62. package/dist/program/processFiles.js +111 -0
  63. package/dist/{helpers/convert-pcre.js → program/utils/pcre.js} +1 -4
  64. package/dist/{schema.d.ts → types/schema.d.ts} +1 -1
  65. package/dist/types/schema.js +1 -0
  66. package/dist/{types.d.ts → types/types.d.ts} +35 -24
  67. package/dist/types/types.js +1 -0
  68. package/ext/generated.rb +6 -0
  69. package/ext/heuristics.yml +102 -11
  70. package/ext/languages.yml +518 -88
  71. package/ext/vendor.yml +1 -0
  72. package/package.json +14 -13
  73. package/readme.md +82 -87
  74. package/dist/helpers/load-data.js +0 -37
  75. package/dist/helpers/norm-path.js +0 -15
  76. package/dist/helpers/read-file.js +0 -23
  77. package/dist/schema.js +0 -2
  78. package/dist/types.js +0 -2
  79. /package/dist/{helpers/read-file.d.ts → program/fs/readFile.d.ts} +0 -0
  80. /package/dist/{helpers/parse-gitignore.d.ts → program/parsing/parseGitignore.d.ts} +0 -0
  81. /package/dist/{helpers/convert-pcre.d.ts → program/utils/pcre.d.ts} +0 -0
package/ext/vendor.yml CHANGED
@@ -165,3 +165,4 @@
165
165
  - (^|/)\.github/
166
166
  - (^|/)\.obsidian/
167
167
  - (^|/)\.teamcity/
168
+ - (^|/)xvba_modules/
package/package.json CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "name": "linguist-js",
3
- "version": "2.9.2",
4
- "description": "Analyse languages used in a folder. Powered by GitHub Linguist, although it doesn't need to be installed.",
3
+ "version": "3.0.0-pre",
4
+ "description": "Analyse the programming languages used in a folder or from raw content, using the same rules that GitHub Linguist does.",
5
5
  "main": "dist/index.js",
6
+ "type": "module",
6
7
  "bin": {
7
8
  "linguist-js": "bin/index.js",
8
9
  "linguist": "bin/index.js"
9
10
  },
10
11
  "engines": {
11
- "node": ">=12",
12
- "npm": ">=8"
12
+ "node": ">=24",
13
+ "npm": ">=10"
13
14
  },
14
15
  "scripts": {
15
- "download-files": "npx tsx@3 build/download-files",
16
+ "download-files": "node build/download-files.ts",
16
17
  "pre-publish": "npm run download-files && npm test && npm run perf",
17
18
  "perf": "tsc && node test/perf",
18
19
  "test": "tsc && node test/folder && node test/unit"
@@ -39,19 +40,19 @@
39
40
  },
40
41
  "homepage": "https://github.com/Nixinova/Linguist#readme",
41
42
  "dependencies": {
42
- "binary-extensions": "^2.3.0 <3",
43
- "commander": "^9.5.0 <10",
43
+ "binary-extensions": "^3.1.0",
44
+ "commander": "^14.0.3",
44
45
  "common-path-prefix": "^3.0.0",
45
- "cross-fetch": "^3.2.0 <4",
46
- "ignore": "^7.0.4",
47
- "isbinaryfile": "^4.0.10 <5",
48
- "js-yaml": "^4.1.0",
46
+ "ignore": "^7.0.5",
47
+ "isbinaryfile": "^6.0.0",
48
+ "js-yaml": "^4.1.1",
49
49
  "node-cache": "^5.1.2"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/js-yaml": "^4.0.9",
53
- "@types/node": "ts5.0",
53
+ "@types/node": "^25.9.1",
54
54
  "deep-object-diff": "^1.1.9",
55
- "typescript": "~5.0.4 <5.1"
55
+ "prettier": "^3.8.3",
56
+ "typescript": "~6.0.3"
56
57
  }
57
58
  }
package/readme.md CHANGED
@@ -29,7 +29,7 @@ linguist-js --help
29
29
 
30
30
  ## Usage
31
31
 
32
- LinguistJS contains one function which analyses a given folder or folders.
32
+ LinguistJS analyses a folder, or a dictionary of already-read file content, and determines what programming languages are used within.
33
33
 
34
34
  As an example, take the following file structure:
35
35
 
@@ -42,8 +42,9 @@ As an example, take the following file structure:
42
42
  | no-lang 10B
43
43
  | x.pluginspec 10B
44
44
  ```
45
+ *(or, an object with keys `"/src", "/src/cli.js", ...` and preloaded file content)*
45
46
 
46
- Running LinguistJS on this folder will return the following JSON:
47
+ Running LinguistJS on this will return the following JSON:
47
48
 
48
49
  ```json
49
50
  {
@@ -51,9 +52,8 @@ Running LinguistJS on this folder will return the following JSON:
51
52
  "count": 5,
52
53
  "bytes": 6020,
53
54
  "lines": {
54
- "total": 100,
55
- "content": 90,
56
- "code": 80,
55
+ "total": 100,
56
+ "content": 90,
57
57
  },
58
58
  "results": {
59
59
  "/src/index.ts": "TypeScript",
@@ -63,64 +63,48 @@ Running LinguistJS on this folder will return the following JSON:
63
63
  "/x.pluginspec": "Ruby",
64
64
  },
65
65
  "alternatives": {
66
- "/x.pluginspec": ["XML"],
66
+ "/x.pluginspec": ["XML"],
67
67
  },
68
68
  },
69
69
  "languages": {
70
70
  "count": 3,
71
71
  "bytes": 6010,
72
72
  "lines": {
73
- "total": 90,
74
- "content": 80,
75
- "code": 70,
73
+ "total": 90,
74
+ "content": 80,
76
75
  },
77
76
  "results": {
78
- "JavaScript": {
79
- "type": "programming",
80
- "bytes": 1000,
81
- "lines": { "total": 49, "content": 49, "code": 44 },
82
- "color": "#f1e05a"
83
- },
84
- "Markdown": {
85
- "type": "prose",
86
- "bytes": 3000,
87
- "lines": { "total": 10, "content": 5, "code": 5 },
88
- "color": "#083fa1"
89
- },
90
- "Ruby": {
91
- "type": "programming",
92
- "bytes": 10,
93
- "lines": { "total": 1, "content": 1, "code": 1 },
94
- "color": "#701516"
95
- },
96
- "TypeScript": {
97
- "type": "programming",
98
- "bytes": 2000,
99
- "lines": { "total": 30, "content": 25, "code": 20 },
100
- "color": "#2b7489"
101
- },
77
+ "JavaScript": { "bytes": 1000, "lines": { "total": 49, "content": 49 }, },
78
+ "Markdown": { "bytes": 3000, "lines": { "total": 10, "content": 5 }, },
79
+ "Ruby": { "bytes": 10, "lines": { "total": 1, "content": 1 }, },
80
+ "TypeScript": { "bytes": 2000, "lines": { "total": 30, "content": 25 }, },
102
81
  },
103
82
  },
104
83
  "unknown": {
105
84
  "count": 1,
106
85
  "bytes": 10,
107
86
  "lines": {
108
- "total": 10,
109
- "content": 10,
110
- "code": 10,
87
+ "total": 10,
88
+ "content": 10,
111
89
  },
112
90
  "filenames": {
113
91
  "no-lang": 10,
114
92
  },
115
93
  "extensions": {},
116
94
  },
95
+ "repository": {
96
+ "JavaScript": { "type": "programming", "color": "#f1e05a" },
97
+ "Markdown": { "type": "prose", "color": "#083fa1" },
98
+ "Ruby": { "type": "programming", "color": "#701516" },
99
+ "TypeScript": { "type": "programming", "color": "#2b7489" },
100
+ }
117
101
  }
118
102
  ```
119
103
 
120
104
  ### Notes
121
105
 
122
106
  - File paths in the output use only forward slashes as delimiters, even on Windows.
123
- - Unless running in offline mode, do not rely on any language classification output from LinguistJS being unchanged between runs.
107
+ - Unless running in offline mode: do not rely on any language classification output from LinguistJS being unchanged between runs.
124
108
  Language data is fetched each run from the latest classifications of [`github-linguist`](https://github.com/github/linguist).
125
109
  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.
126
110
 
@@ -129,75 +113,86 @@ Running LinguistJS on this folder will return the following JSON:
129
113
  ### Node
130
114
 
131
115
  ```js
132
- const linguist = require('linguist-js');
116
+ import linguist from 'linguist-js';
133
117
 
134
118
  // Analyse folder on disc
135
- const folder = './src';
119
+ const folders = ['./src'];
136
120
  const options = { keepVendored: false, quick: false };
137
- const { files, languages, unknown } = await linguist(folder, options);
121
+ const { files, languages, unknown, repository } = await linguist.analyseFolders(folder, options);
138
122
 
139
123
  // Analyse file content from raw input
140
- const fileNames = ['file1.ts', 'file2.ts', 'ignoreme.js'];
141
- const fileContent = ['#!/usr/bin/env node', 'console.log("Example");', '"ignored"'];
142
- const options = { ignoredFiles: ['ignore*'] };
143
- const { files, languages, unknown } = await linguist(fileNames, { fileContent, ...options });
124
+ const fileContent = {
125
+ ['file1.ts']: '#!/usr/bin/env node',
126
+ ['file2.ts']: 'console.log("Example");',
127
+ ['ignoreme.js']: 'ignored!',
128
+ }
129
+ const options = { ignoredFiles: ['ignoreme.*'] };
130
+ const { files, languages, unknown, repository } = await linguist.analyseRawContent(fileContent, options);
144
131
  ```
145
132
 
146
- - `linguist(entry?, opts?)` (default export):
133
+ **Exports:**
134
+
135
+ - `analyseFolders(folders?, opts?)`:
136
+ Analyse the language of all files found in a folder or folders.
137
+ - `folders` (optional; string array):
138
+ A list of folders to analyse (defaults to `['./']`).
139
+ - `opts` (optional; object):
140
+ An object containing analyser options.
141
+ - `analyseRawContent(folders?, opts?)`:
147
142
  Analyse the language of all files found in a folder or folders.
148
143
  - `entry` (optional; string or string array):
149
- The folder(s) to analyse (defaults to `./`).
144
+ A list of folders to analyse (defaults to `['./']`).
150
145
  - `opts` (optional; object):
151
146
  An object containing analyser options.
152
- - `fileContent` (string or string array):
153
- Provides the file content associated with the file name(s) given as `entry` to analyse instead of reading from a folder on disk.
154
- - `ignoredFiles` (string array):
155
- A list of file path globs to explicitly ignore.
156
- - `ignoredLanguages` (string array):
157
- A list of languages to ignore.
158
- - `categories` (string array):
159
- A list of programming language categories that should be included in the results.
160
- Defaults to `['data', 'markup', 'programming', 'prose']`.
161
- - `childLanguages` (boolean):
162
- Whether to display sub-languages instead of their parents when possible (defaults to `false`).
163
- - `quick` (boolean):
164
- Whether to skip complex language analysis such as the checking of heuristics and gitattributes statements (defaults to `false`).
165
- Alias for `checkAttributes:false, checkIgnored:false, checkDetected:false, checkHeuristics:false, checkShebang:false, checkModeline:false`.
166
- - `offline` (boolean):
167
- Whether to use pre-packaged metadata files instead of fetching them from GitHub at runtime (defaults to `false`).
168
- - `calculateLines` (boolean):
169
- Whether to calculate line of code totals (defaults to `true`).
170
- - `keepVendored` (boolean):
171
- Whether to keep vendored files (dependencies, etc) (defaults to `false`).
172
- Does nothing when `fileContent` is set.
173
- - `keepBinary` (boolean):
174
- Whether binary files should be included in the output (defaults to `false`).
175
- - `relativePaths` (boolean):
176
- Change the absolute file paths in the output to be relative to the current working directory (defaults to `false`).
177
- - `checkAttributes` (boolean):
178
- Force the checking of `.gitattributes` files (defaults to `true` unless `quick` is set).
179
- Does nothing when `fileContent` is set.
180
- - `checkIgnored` (boolean):
181
- Force the checking of `.gitignore` files (defaults to `true` unless `quick` is set).
182
- Does nothing when `fileContent` is set.
183
- - `checkDetected` (boolean):
184
- Force files marked with `linguist-detectable` to show up in the output, even if the file is not part of the declared `categories`.
185
- - `checkHeuristics` (boolean):
186
- Apply heuristics to ambiguous languages (defaults to `true` unless `quick` is set).
187
- - `checkShebang` (boolean):
188
- Check shebang (`#!`) lines for explicit language classification (defaults to `true` unless `quick` is set).
189
- - `checkModeline` (boolean):
190
- Check modelines for explicit language classification (defaults to `true` unless `quick` is set).
147
+
148
+ **Analyser options:**
149
+ - `ignoredFiles` (string array):
150
+ A list of file path globs to explicitly ignore.
151
+ - `ignoredLanguages` (string array):
152
+ A list of languages to ignore.
153
+ - `categories` (string array):
154
+ A list of programming language categories that should be included in the results.
155
+ Defaults to `['data', 'markup', 'programming', 'prose']`.
156
+ - `childLanguages` (boolean):
157
+ Whether to display sub-languages instead of their parents when possible (defaults to `false`).
158
+ - `quick` (boolean):
159
+ Whether to skip complex language analysis such as the checking of heuristics and gitattributes statements (defaults to `false`).
160
+ Alias for `checkAttributes:false, checkIgnored:false, checkDetected:false, checkHeuristics:false, checkShebang:false, checkModeline:false`.
161
+ - `offline` (boolean):
162
+ Whether to use pre-packaged metadata files instead of fetching them from GitHub at runtime (defaults to `false`).
163
+ - `calculateLines` (boolean):
164
+ Whether to calculate line of code totals (defaults to `true`).
165
+ - `keepVendored` (boolean):
166
+ Whether to keep vendored files (dependencies, etc) (defaults to `false`).
167
+ Does nothing when `fileContent` is set.
168
+ - `keepBinary` (boolean):
169
+ Whether binary files should be included in the output (defaults to `false`).
170
+ - `relativePaths` (boolean):
171
+ Change the absolute file paths in the output to be relative to the current working directory (defaults to `false`).
172
+ - `checkAttributes` (boolean):
173
+ Force the checking of `.gitattributes` files (defaults to `true` unless `quick` is set).
174
+ Does nothing when `fileContent` is set.
175
+ - `checkIgnored` (boolean):
176
+ Force the checking of `.gitignore` files (defaults to `true` unless `quick` is set).
177
+ Does nothing when `fileContent` is set.
178
+ - `checkDetected` (boolean):
179
+ Force files marked with `linguist-detectable` to show up in the output, even if the file is not part of the declared `categories`.
180
+ - `checkHeuristics` (boolean):
181
+ Apply heuristics to ambiguous languages (defaults to `true` unless `quick` is set).
182
+ - `checkShebang` (boolean):
183
+ Check shebang (`#!`) lines for explicit language classification (defaults to `true` unless `quick` is set).
184
+ - `checkModeline` (boolean):
185
+ Check modelines for explicit language classification (defaults to `true` unless `quick` is set).
191
186
 
192
187
  ### Command-line
193
188
 
194
189
  ```
195
- linguist --analyze [<folders...>] [<options...>]
190
+ linguist --analyse [<folders...>] [<options...>]
196
191
  linguist --help
197
192
  linguist --version
198
193
  ```
199
194
 
200
- - `--analyze`:
195
+ - `--analyse`:
201
196
  Analyse the language of all files found in a folder or folders.
202
197
  - `[<folders...>]`:
203
198
  The folders to analyse (defaults to `./`).
@@ -1,37 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.parseGeneratedDataFile = parseGeneratedDataFile;
7
- exports.default = loadFile;
8
- const fs_1 = __importDefault(require("fs"));
9
- const path_1 = __importDefault(require("path"));
10
- const cross_fetch_1 = __importDefault(require("cross-fetch"));
11
- const node_cache_1 = __importDefault(require("node-cache"));
12
- const cache = new node_cache_1.default({});
13
- async function loadWebFile(file) {
14
- // Return cache if it exists
15
- const cachedContent = cache.get(file);
16
- if (cachedContent)
17
- return cachedContent;
18
- // Otherwise cache the request
19
- const dataUrl = (file) => `https://raw.githubusercontent.com/github/linguist/HEAD/lib/linguist/${file}`;
20
- // Load file content, falling back to the local file if the request fails
21
- const fileContent = await (0, cross_fetch_1.default)(dataUrl(file)).then(data => data.text()).catch(async () => await loadLocalFile(file));
22
- cache.set(file, fileContent);
23
- return fileContent;
24
- }
25
- async function loadLocalFile(file) {
26
- const filePath = path_1.default.resolve(__dirname, '../../ext', file);
27
- return fs_1.default.promises.readFile(filePath).then(buffer => buffer.toString());
28
- }
29
- /** Nukes unused `generated.rb` file content. */
30
- function parseGeneratedDataFile(fileContent) {
31
- var _a;
32
- return [...(_a = fileContent.match(/(?<=name\.match\(\/).+?(?=(?<!\\)\/)/gm)) !== null && _a !== void 0 ? _a : []];
33
- }
34
- /** Load a data file from github-linguist. */
35
- function loadFile(file, offline = false) {
36
- return offline ? loadLocalFile(file) : loadWebFile(file);
37
- }
@@ -1,15 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.normAbsPath = exports.normPath = void 0;
7
- const path_1 = __importDefault(require("path"));
8
- const normPath = function normalisedPath(...inputPaths) {
9
- return path_1.default.join(...inputPaths).replace(/\\/g, '/');
10
- };
11
- exports.normPath = normPath;
12
- const normAbsPath = function normalisedAbsolutePath(...inputPaths) {
13
- return path_1.default.resolve(...inputPaths).replace(/\\/g, '/');
14
- };
15
- exports.normAbsPath = normAbsPath;
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.default = readFileChunk;
7
- const fs_1 = __importDefault(require("fs"));
8
- /**
9
- * Read part of a file on disc.
10
- * @throws 'EPERM' if the file is not readable.
11
- */
12
- async function readFileChunk(filename, onlyFirstLine = false) {
13
- const chunkSize = 100;
14
- const stream = fs_1.default.createReadStream(filename, { highWaterMark: chunkSize });
15
- let content = '';
16
- for await (const data of stream) { // may throw
17
- content += data.toString();
18
- if (onlyFirstLine) {
19
- return content.split(/\r?\n/)[0];
20
- }
21
- }
22
- return content;
23
- }
package/dist/schema.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
package/dist/types.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });