Skip to content

Instantly share code, notes, and snippets.

@ryan-roemer
Last active September 21, 2016 19:38
Show Gist options
  • Save ryan-roemer/70adeef07c90f3f3794fe543429c98a5 to your computer and use it in GitHub Desktop.
Save ryan-roemer/70adeef07c90f3f3794fe543429c98a5 to your computer and use it in GitHub Desktop.
Split files in directories into subfiles by line count. (So you can get viewable GitHub diff's for review-only code!)
\.git
\.hg
\.DS_Store
\.project
bower_components
node_modules
npm-debug\.log*
phantomjsdriver\.log
# Build
dist
*/dist
build
*/build
coverage
Procfile

Split Files

Super simple utility to split files into 1000 line chunks.

Install

$ git clone https://gist.github.com/70adeef07c90f3f3794fe543429c98a5.git split-files
$ cd split-files
$ npm install async recursive-readdir

Usage

$ split-files/split-files.js [PATH]

So, if for example, you have:

src/
  foo.js (100 lines)
  bar.js (1024 lines)
  baz.js (3333 lines)

Running:

$ split-files/split-files.js src

would produce:

src/
  foo.js
  bar-000.js
  bar-001.js
  baz-000.js
  baz-001.js
  baz-002.js
  baz-003.js
#!/usr/bin/env node
"use strict";
const fs = require("fs");
const path = require("path");
const async = require("async");
const readdir = require("recursive-readdir");
const FILES = path.resolve(process.argv[2] || process.cwd());
const SPLIT_NUM = 1000;
const REPLACE = true; // Remove old file?
const DEFAULT_PAD = 3; // TODO: Calculate based on actual lines.
const FILE_IGNORES = [".DS_Store"]
const pad = (n) =>
(Array(DEFAULT_PAD).fill("0").join("") + n).slice(-DEFAULT_PAD);
readdir(FILES, FILE_IGNORES, (readErr, files) => {
if (readErr) { throw readErr; }
async.auto({
readFiles: (cb) => {
async.map(files, (file, readCb) => {
console.log("* Reading: " + file);
fs.readFile(file, (err, data) => readCb(err, {
file,
data: (data || "").toString().split("\n")
}));
}, cb);
},
writeFiles: ["readFiles", (results, cb) => {
async.map(results.readFiles, (obj, writeCb) => {
let file = obj.file;
let ext = path.extname(file);
// Skip if under length.
if (obj.data.length <= SPLIT_NUM) {
console.log("* Skipping split of: " + file + " (" + obj.data.length + ")");
return writeCb(null, obj);
}
// Else, create data chunks.
let data = obj.data; // Sanity check: `.map((o, i) => i);`
let chunks = [];
while (data && data.length > 0) {
chunks.push({
file: file.substring(0, file.length - ext.length) + "-" + pad(chunks.length) + ext,
data: data.slice(0, SPLIT_NUM)
});
// Increment data.
data = data.slice(SPLIT_NUM);
}
console.log("* Splitting: " + file + " (" + obj.data.length + ") into " +
chunks.length + " files");
async.map(chunks, (chunk, splitCb) => {
console.log("* Writing split file: " + chunk.file + "(" + chunk.data.length + ")");
fs.writeFile(chunk.file, chunk.data.join("\n"), splitCb);
}, (splitErr) => {
writeCb(splitErr, { file, chunks, data: obj.data });
})
}, cb);
}],
deleteFiles: ["writeFiles", (results, cb) => {
async.map(results.writeFiles, (obj, deleteCb) => {
// Skip unsplit files or if command flag set.
if (!REPLACE || !obj.chunks) {
console.log("* Skipping delete of: " + obj.file + " (" + obj.data.length + ")");
return deleteCb();
}
// Delete.
console.log("* Deleting: " + obj.file + " (" + obj.data.length + ")");
fs.unlink(obj.file, deleteCb);
}, cb);
}]
}, (err, results) => {
if (err) { throw err; }
console.log("* Finished splitting files.");
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment