Convert Files and Folders Structures to Bash Scripts, with NodeJS

This is a simple NodeJS app that takes a source folder as input and generates a Bash script. The Bash script has all the files' content and the folders' structure in the source folder and it can recreate them when executed.

Source code available here: https://github.com/alexadam/folders-to-script

First step, iterate through all files in the source folder:

js
const fs = require("fs") const path = require("path") const listFiles = (dirPath, result) => { files = fs.readdirSync(dirPath) result = result || ['#!/bin/sh'] for (const file of files) { ///... } return result } const allFiles = listFiles(rootPath) fs.writeFileSync('./result.sh', allFiles.join('\n'))

If file is a directory, add an mkdir -p command:

js
for (const file of files) { if (fs.statSync(dirPath + "/" + file).isDirectory()) { result.push(`mkdir -p ${path.join(dirPath, "/", file).replace(rootPath, '.')}`) result = listFiles(dirPath + "/" + file, result) } }

Else, test if file is binary or text, based on its extension:

js
const textExt = ['txt', 'md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx']; const binaryExt = ['jpg', 'png', 'gif', 'pdf', 'mp3', 'mp4']; const getFileExt = (filePath) => filePath.split('.').pop() ... else { const filePath = path.join(dirPath, "/", file); const fileExt = getFileExt(filePath); const fileContent = fs.readFileSync(filePath); if (textExt.includes(fileExt)) { result.push(` cat > ${path.join(dirPath, "/", file).replace(rootPath, '.')} << "EOF" ${fileContent} EOF `) } else if (binaryExt.includes(fileExt)) { const bindata = fileContent.toString('binary'); const hexdata = new Buffer(bindata, 'ascii').toString('hex'); result.push(`echo '${hexdata}' | xxd -r -p > ${path.join(dirPath, "/", file).replace(rootPath, '.')}`) } } ...

Binary files are stored as hex strings.

You can add/remove file extensions in the textExt or binaryExt arrays.

This is the full NodeJS script:

js
const fs = require("fs") const path = require("path") const rootPath = process.argv[2] const textExt = ['txt', 'md', 'html', 'json', 'js', 'jsx', 'ts', 'tsx']; const binaryExt = ['jpg', 'png', 'gif', 'pdf', 'mp3', 'mp4']; const getFileExt = (filePath) => filePath.split('.').pop() const listFiles = (dirPath, result) => { files = fs.readdirSync(dirPath) result = result || ['#!/bin/sh'] for (const file of files) { if (fs.statSync(dirPath + "/" + file).isDirectory()) { result.push(`mkdir -p ${path.join(dirPath, "/", file).replace(rootPath, '.')}`) result = listFiles(dirPath + "/" + file, result) } else { const filePath = path.join(dirPath, "/", file); const fileExt = getFileExt(filePath); const fileContent = fs.readFileSync(filePath); if (textExt.includes(fileExt)) { result.push(` cat > ${path.join(dirPath, "/", file).replace(rootPath, '.')} << "EOF" ${fileContent} EOF `) } else if (binaryExt.includes(fileExt)) { const bindata = fileContent.toString('binary'); const hexdata = new Buffer(bindata, 'ascii').toString('hex'); result.push(`echo '${hexdata}' | xxd -r -p > ${path.join(dirPath, "/", file).replace(rootPath, '.')}`) } } } return result } const allFiles = listFiles(rootPath) fs.writeFileSync('./result.sh', allFiles.join('\n'))

Test it with node index.js test -> it will generate a Bash script file named result.sh

Then, in an empty directory, execute the script with sh result.sh.