Last active
February 16, 2025 17:57
-
-
Save snowyyd/0ab93efe562f0af32a7e5ec5c5463a1d to your computer and use it in GitHub Desktop.
Merge C# files into a single one
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Usage: node --experimental-strip-types merge.ts | |
*/ | |
"use strict"; | |
import fs from 'node:fs/promises'; | |
import path from 'node:path'; | |
const usingRe = /^using ([A-Za-z0-9.= ]+);?/; | |
const sanitizeMultilineStr = (str: string) => str.replace(/\t+/gm, '').replace(/\{tab\}/g, '\t'); | |
async function writeFile(dir: string, filename: string, data: string) | |
{ | |
await fs.mkdir(dir, { recursive: true }); | |
return fs.writeFile(path.join(dir, filename), data, 'utf8'); | |
} | |
async function readFiles(dir: string) | |
{ | |
const parsedContent: string[] = []; | |
const usingLibs = new Set(); | |
const files = (await fs.readdir(dir, { withFileTypes: true, recursive: true })) | |
.filter((x) => x.isFile() && x.name.endsWith('.cs')) // filter .cs files only | |
.map((x) => path.join(x.parentPath, x.name)); // return an array of paths | |
const contents = await Promise.all(files.map((file) => fs.readFile(file, 'utf8'))); | |
contents.forEach((content, idx) => | |
{ | |
const filteredContent = content | |
.split('\n') // split lines | |
.filter((line) => | |
{ | |
const usingsFound = line.trim().match(usingRe); | |
if (usingsFound) | |
{ | |
usingLibs.add(usingsFound[1]); | |
return false; // exclude the line with the "using directive" | |
} | |
return true; | |
}) | |
.join('\n'); // join all "lines" again | |
const contentWithNewLines = content.endsWith('\n') ? `${filteredContent.trim()}\n` : `${filteredContent.trim()}\n\n`; | |
parsedContent.push(`// Content of: ${files.at(idx)}\n${contentWithNewLines}`); | |
}); | |
return { | |
using: usingLibs, | |
contents: parsedContent, | |
}; | |
}; | |
(async () => | |
{ | |
const args = process.argv.splice(2); | |
const srcPath = args[0]; | |
const className = args[1]; | |
if (args.length === 0) | |
{ | |
console.log('Parameters: <source path> <class name>'); | |
process.exit(1); | |
} | |
if (!srcPath) throw new Error('You must set a source path!'); | |
if (!className) throw new Error('You must set the main class name!'); | |
const res = await readFiles(srcPath); | |
let output = sanitizeMultilineStr(` | |
// This file was autogenerated using the merge tool | |
// ${new Date().toString()} | |
{usings} | |
{contents} | |
`); | |
output = output | |
.replace('{usings}', Array.from(res.using).map((x) => `using ${x};`).join('\n')) | |
.replace('{contents}', res.contents.join('\n')); | |
await writeFile('dist', `${className}.cs`, output); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment