codeinf 1.0.0 → 1.0.2
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/bin/cli.js +129 -41
- package/package.json +2 -4
package/bin/cli.js
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
const { analyze, formatBytes } = require('../index');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
+
// ANSI color codes
|
|
7
|
+
const colors = {
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
bright: '\x1b[1m',
|
|
10
|
+
dim: '\x1b[2m',
|
|
11
|
+
red: '\x1b[31m',
|
|
12
|
+
green: '\x1b[32m',
|
|
13
|
+
yellow: '\x1b[33m',
|
|
14
|
+
blue: '\x1b[34m',
|
|
15
|
+
magenta: '\x1b[35m',
|
|
16
|
+
cyan: '\x1b[36m',
|
|
17
|
+
white: '\x1b[37m',
|
|
18
|
+
gray: '\x1b[90m',
|
|
19
|
+
bgBlue: '\x1b[44m'
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Helper to colorize text
|
|
23
|
+
const c = (text, color) => `${colors[color] || ''}${text}${colors.reset}`;
|
|
24
|
+
|
|
6
25
|
// Parse command line arguments
|
|
7
26
|
function parseArgs(args) {
|
|
8
27
|
const options = {
|
|
@@ -12,7 +31,8 @@ function parseArgs(args) {
|
|
|
12
31
|
format: 'table',
|
|
13
32
|
top: 10,
|
|
14
33
|
help: false,
|
|
15
|
-
version: false
|
|
34
|
+
version: false,
|
|
35
|
+
noColor: false
|
|
16
36
|
};
|
|
17
37
|
|
|
18
38
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -62,6 +82,9 @@ function parseArgs(args) {
|
|
|
62
82
|
case '--json':
|
|
63
83
|
options.format = 'json';
|
|
64
84
|
break;
|
|
85
|
+
case '--no-color':
|
|
86
|
+
options.noColor = true;
|
|
87
|
+
break;
|
|
65
88
|
default:
|
|
66
89
|
if (!arg.startsWith('-') && options.path === '.') {
|
|
67
90
|
options.path = arg;
|
|
@@ -75,83 +98,148 @@ function parseArgs(args) {
|
|
|
75
98
|
// Show help
|
|
76
99
|
function showHelp() {
|
|
77
100
|
console.log(`
|
|
78
|
-
codeinf - Code statistics analyzer
|
|
101
|
+
${c('codeinf', 'cyan')} ${c('- Code statistics analyzer', 'gray')}
|
|
79
102
|
|
|
80
|
-
Usage: codeinf [path] [options]
|
|
103
|
+
${c('Usage:', 'yellow')} codeinf [path] [options]
|
|
81
104
|
|
|
82
|
-
Options:
|
|
105
|
+
${c('Options:', 'yellow')}
|
|
83
106
|
-h, --help Show this help message
|
|
84
107
|
-v, --version Show version
|
|
85
|
-
-e, --ext <
|
|
108
|
+
-e, --ext <exts> Filter by file extensions (comma-separated)
|
|
86
109
|
-i, --ignore <patterns> Additional ignore patterns (comma-separated)
|
|
87
|
-
-f, --format <format> Output format: table,
|
|
110
|
+
-f, --format <format> Output format: ${c('table', 'green')}, ${c('json', 'green')}
|
|
88
111
|
--json Output as JSON
|
|
89
112
|
-t, --top <number> Number of largest files to show (default: 10)
|
|
113
|
+
--no-color Disable colored output
|
|
90
114
|
|
|
91
|
-
Examples:
|
|
92
|
-
codeinf Analyze current directory
|
|
93
|
-
codeinf ./src Analyze src directory
|
|
94
|
-
codeinf -e js,ts Analyze only JS and TS files
|
|
95
|
-
codeinf -e .js --json Output JS stats as JSON
|
|
96
|
-
codeinf -i "test,dist" Ignore test and dist folders
|
|
97
|
-
codeinf -t 20 Show top 20 largest files
|
|
115
|
+
${c('Examples:', 'yellow')}
|
|
116
|
+
${c('codeinf', 'cyan')} Analyze current directory
|
|
117
|
+
${c('codeinf ./src', 'cyan')} Analyze src directory
|
|
118
|
+
${c('codeinf -e js,ts', 'cyan')} Analyze only JS and TS files
|
|
119
|
+
${c('codeinf -e .js --json', 'cyan')} Output JS stats as JSON
|
|
120
|
+
${c('codeinf -i "test,dist"', 'cyan')} Ignore test and dist folders
|
|
121
|
+
${c('codeinf -t 20', 'cyan')} Show top 20 largest files
|
|
98
122
|
`);
|
|
99
123
|
}
|
|
100
124
|
|
|
101
125
|
// Show version
|
|
102
126
|
function showVersion() {
|
|
103
127
|
const pkg = require('../package.json');
|
|
104
|
-
console.log(pkg.version);
|
|
128
|
+
console.log(c(`codeinf v${pkg.version}`, 'cyan'));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Get color for file extension
|
|
132
|
+
function getExtColor(ext) {
|
|
133
|
+
const colorMap = {
|
|
134
|
+
'.js': 'yellow',
|
|
135
|
+
'.ts': 'blue',
|
|
136
|
+
'.jsx': 'cyan',
|
|
137
|
+
'.tsx': 'cyan',
|
|
138
|
+
'.json': 'green',
|
|
139
|
+
'.md': 'magenta',
|
|
140
|
+
'.css': 'blue',
|
|
141
|
+
'.scss': 'magenta',
|
|
142
|
+
'.html': 'red',
|
|
143
|
+
'.py': 'green',
|
|
144
|
+
'.rb': 'red',
|
|
145
|
+
'.go': 'cyan',
|
|
146
|
+
'.rs': 'yellow',
|
|
147
|
+
'.java': 'red',
|
|
148
|
+
'.c': 'gray',
|
|
149
|
+
'.cpp': 'gray',
|
|
150
|
+
'.h': 'gray'
|
|
151
|
+
};
|
|
152
|
+
return colorMap[ext] || 'white';
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Progress bar
|
|
156
|
+
function progressBar(value, max, width = 20) {
|
|
157
|
+
const filled = Math.round((value / max) * width);
|
|
158
|
+
const empty = width - filled;
|
|
159
|
+
const bar = c('█'.repeat(filled), 'cyan') + c('░'.repeat(empty), 'gray');
|
|
160
|
+
return `[${bar}]`;
|
|
105
161
|
}
|
|
106
162
|
|
|
107
|
-
// Format output as table
|
|
108
|
-
function formatTable(data) {
|
|
163
|
+
// Format output as table with colors
|
|
164
|
+
function formatTable(data, useColor = true) {
|
|
109
165
|
const { summary, byExtension, largestFiles, path: targetPath } = data;
|
|
110
166
|
|
|
111
|
-
|
|
167
|
+
// Disable colors if requested
|
|
168
|
+
if (!useColor) {
|
|
169
|
+
Object.keys(colors).forEach(k => colors[k] = '');
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
console.log();
|
|
173
|
+
console.log(` ${c('>>', 'bgBlue')} ${c('Code Statistics', 'bright')}${c(' for:', 'gray')} ${c(targetPath, 'cyan')}`);
|
|
174
|
+
console.log(` ${c('─'.repeat(60), 'gray')}`);
|
|
175
|
+
console.log();
|
|
112
176
|
|
|
113
177
|
// Summary
|
|
114
|
-
console.log('
|
|
115
|
-
console.log(` Files: ${summary.files.toLocaleString()}`);
|
|
116
|
-
console.log(` Total Lines: ${summary.totalLines.toLocaleString()}`);
|
|
117
|
-
console.log(` Code Lines: ${summary.codeLines.toLocaleString()}`);
|
|
118
|
-
console.log(` Non-Empty: ${summary.nonEmptyLines.toLocaleString()}`);
|
|
119
|
-
console.log(` Total Size: ${formatBytes(summary.size)}`);
|
|
178
|
+
console.log(` ${c('[Summary]', 'yellow')}`);
|
|
120
179
|
console.log();
|
|
180
|
+
|
|
181
|
+
const stats = [
|
|
182
|
+
{ label: 'Files', value: summary.files, color: 'green' },
|
|
183
|
+
{ label: 'Total Lines', value: summary.totalLines.toLocaleString(), color: 'cyan' },
|
|
184
|
+
{ label: 'Code Lines', value: summary.codeLines.toLocaleString(), color: 'yellow' },
|
|
185
|
+
{ label: 'Non-Empty', value: summary.nonEmptyLines.toLocaleString(), color: 'blue' },
|
|
186
|
+
{ label: 'Total Size', value: formatBytes(summary.size), color: 'magenta' }
|
|
187
|
+
];
|
|
121
188
|
|
|
122
|
-
|
|
189
|
+
stats.forEach(stat => {
|
|
190
|
+
const value = c(stat.value.toString().padStart(12), stat.color);
|
|
191
|
+
console.log(` > ${stat.label.padEnd(15)} ${value}`);
|
|
192
|
+
});
|
|
193
|
+
console.log();
|
|
194
|
+
|
|
195
|
+
// By Extension with colors and bars
|
|
123
196
|
if (Object.keys(byExtension).length > 0) {
|
|
124
|
-
console.log('
|
|
197
|
+
console.log(` ${c('[By Extension]', 'yellow')}`);
|
|
198
|
+
console.log();
|
|
199
|
+
|
|
125
200
|
const sorted = Object.entries(byExtension)
|
|
126
201
|
.sort((a, b) => b[1].files - a[1].files);
|
|
127
202
|
|
|
128
|
-
|
|
129
|
-
|
|
203
|
+
const maxLines = Math.max(...sorted.map(([,s]) => s.lines));
|
|
204
|
+
|
|
205
|
+
console.log(` ${c('Extension'.padEnd(14), 'gray')} ${c('Files'.padStart(6), 'gray')} ${c('Lines'.padStart(10), 'gray')} ${c('Size'.padStart(10), 'gray')} ${c('Distribution', 'gray')}`);
|
|
206
|
+
console.log(` ${c('─'.repeat(75), 'gray')}`);
|
|
130
207
|
|
|
131
208
|
for (const [ext, stats] of sorted) {
|
|
132
|
-
const
|
|
133
|
-
const files = stats.files.
|
|
134
|
-
const lines = stats.lines.toLocaleString().padStart(10);
|
|
135
|
-
const size = formatBytes(stats.size).padStart(10);
|
|
136
|
-
|
|
209
|
+
const extDisplay = ext === '(no extension)' ? c('(none)', 'gray') : c(ext, getExtColor(ext));
|
|
210
|
+
const files = c(stats.files.toString().padStart(6), 'green');
|
|
211
|
+
const lines = c(stats.lines.toLocaleString().padStart(10), 'cyan');
|
|
212
|
+
const size = c(formatBytes(stats.size).padStart(10), 'magenta');
|
|
213
|
+
const bar = progressBar(stats.lines, maxLines, 15);
|
|
214
|
+
console.log(` ${extDisplay.padEnd(20)} ${files} ${lines} ${size} ${bar}`);
|
|
137
215
|
}
|
|
138
216
|
console.log();
|
|
139
217
|
}
|
|
140
218
|
|
|
141
|
-
// Largest Files
|
|
219
|
+
// Largest Files with colors
|
|
142
220
|
if (largestFiles.length > 0) {
|
|
143
|
-
console.log(` Largest Files (Top ${largestFiles.length})
|
|
144
|
-
console.log(
|
|
145
|
-
console.log(` ${'
|
|
221
|
+
console.log(` ${c('[Largest Files]', 'yellow')} ${c(`(Top ${largestFiles.length})`, 'gray')}`);
|
|
222
|
+
console.log();
|
|
223
|
+
console.log(` ${c('Lines'.padStart(8), 'gray')} ${c('Size'.padStart(10), 'gray')} ${c('Type', 'gray').padEnd(10)} ${c('Path', 'gray')}`);
|
|
224
|
+
console.log(` ${c('─'.repeat(70), 'gray')}`);
|
|
146
225
|
|
|
147
226
|
for (const file of largestFiles) {
|
|
148
|
-
const lines = file.totalLines.toLocaleString().padStart(8);
|
|
149
|
-
const size = formatBytes(file.size).padStart(10);
|
|
227
|
+
const lines = c(file.totalLines.toLocaleString().padStart(8), 'cyan');
|
|
228
|
+
const size = c(formatBytes(file.size).padStart(10), 'magenta');
|
|
229
|
+
const ext = file.extension || '(none)';
|
|
230
|
+
const extColored = ext === '(none)' ? c(ext, 'gray') : c(ext, getExtColor(ext));
|
|
150
231
|
const relPath = path.relative(targetPath, file.path) || file.path;
|
|
151
|
-
|
|
232
|
+
const pathColored = relPath.split('/').map((part, i, arr) =>
|
|
233
|
+
i === arr.length - 1 ? c(part, 'bright') : c(part, 'gray')
|
|
234
|
+
).join(c('/', 'gray'));
|
|
235
|
+
console.log(` ${lines} ${size} ${extColored.padEnd(14)} ${pathColored}`);
|
|
152
236
|
}
|
|
153
237
|
console.log();
|
|
154
238
|
}
|
|
239
|
+
|
|
240
|
+
// Footer
|
|
241
|
+
console.log(` ${c('Done!', 'green')} ${c(`(${summary.files} files analyzed)`, 'gray')}`);
|
|
242
|
+
console.log();
|
|
155
243
|
}
|
|
156
244
|
|
|
157
245
|
// Main function
|
|
@@ -178,10 +266,10 @@ async function main() {
|
|
|
178
266
|
if (options.format === 'json') {
|
|
179
267
|
console.log(JSON.stringify(result, null, 2));
|
|
180
268
|
} else {
|
|
181
|
-
formatTable(result);
|
|
269
|
+
formatTable(result, !options.noColor);
|
|
182
270
|
}
|
|
183
271
|
} catch (err) {
|
|
184
|
-
console.error(
|
|
272
|
+
console.error(`${c('Error:', 'red')} ${err.message}`);
|
|
185
273
|
process.exit(1);
|
|
186
274
|
}
|
|
187
275
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeinf",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A CLI tool to analyze code statistics like lines of code, file counts, and more with filtering capabilities",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"bin":
|
|
7
|
-
"codeinf": "./bin/cli.js"
|
|
8
|
-
},
|
|
6
|
+
"bin": "./bin/cli.js",
|
|
9
7
|
"files": [
|
|
10
8
|
"index.js",
|
|
11
9
|
"bin/",
|