-
Notifications
You must be signed in to change notification settings - Fork 0
/
concat_code.ts
94 lines (79 loc) · 2.48 KB
/
concat_code.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/env ts-node
import * as fs from 'fs';
import * as path from 'path';
import * as process from 'process';
import ignore from 'ignore';
import { Writable } from 'stream';
interface Options {
directories: string[];
output?: string;
}
function parseArgs(): Options {
const args = process.argv.slice(2);
const directories: string[] = [];
let output: string | undefined = undefined;
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === '-o' || arg === '--output') {
output = args[i + 1];
i++;
} else {
// 出力指定以外はディレクトリとみなす
directories.push(arg);
}
}
if (directories.length === 0) {
console.error('Usage: concat_code <directory1> <directory2> ... [-o output]');
process.exit(1);
}
return { directories, output };
}
function gatherFiles(dir: string): string[] {
let fileList: string[] = [];
const items = fs.readdirSync(dir, { withFileTypes: true });
for (const item of items) {
const fullPath = path.join(dir, item.name);
if (item.isDirectory()) {
fileList = fileList.concat(gatherFiles(fullPath));
} else {
fileList.push(fullPath);
}
}
return fileList;
}
function getFilteredFiles(directory: string, ig: ReturnType<typeof ignore>): string[] {
const absDir = path.resolve(directory);
const allFiles = gatherFiles(absDir);
const relFiles = allFiles.map(f => path.relative(absDir, f));
const filtered = relFiles.filter(f => !ig.ignores(f));
return filtered;
}
function main() {
const { directories, output } = parseArgs();
let outStream: Writable = process.stdout;
if (output) {
outStream = fs.createWriteStream(output, { encoding: 'utf-8' });
}
for (const dir of directories) {
const absDir = path.resolve(dir);
const gitignorePath = path.join(absDir, '.gitignore');
let ig = ignore();
if (fs.existsSync(gitignorePath)) {
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
ig = ignore().add(gitignoreContent);
}
const filteredFiles = getFilteredFiles(dir, ig);
for (const f of filteredFiles) {
const fullPath = path.join(absDir, f);
const code = fs.readFileSync(fullPath, { encoding: 'utf-8' });
outStream.write(`## ${dir}/${f}\n`);
outStream.write("```\n");
outStream.write(code);
outStream.write("\n```\n\n");
}
}
if (outStream !== process.stdout && (outStream as fs.WriteStream).end) {
(outStream as fs.WriteStream).end();
}
}
main();