browserfs
Version:
A filesystem in your browser!
121 lines (107 loc) • 3.68 kB
text/typescript
#!/usr/bin/env node
/**
* make_fixture_loader
* Generates a script that loads the test fixtures into the in-browser filesystem
* USING the in-browser filesystem.
*/
import * as path from 'path';
import * as fs from 'fs';
const fixturesPath = 'test/fixtures/files';
const files: string[] = []
const dirs = ['tmp']
const DEBUG = false
let uid = 0
// Used to print debug messages.
function debugPrint(...args: string[]) {
if (DEBUG) console.log.apply(console, args)
}
// Sanity check
if (!fs.existsSync(path.resolve('.', 'src', 'core', 'browserfs.ts'))) {
throw new Error('FixtureLoaderMaker must be run from the BrowserFS root!');
}
debugPrint('Opening load_fixtures.ts...');
const outfile = fs.openSync(path.resolve('.', 'test', 'fixtures', 'load_fixtures.ts'), 'w+');
// path0, data0
// mkdir occurs one by one
// Checks if the directory is in the listing of unique directories.
// If not, it recursively checks its parent before adding itself to the
// list. This maintains the invariant that no child directory occurs in the list
// before its parent directory.
function tryAddToDirs(dir: string) {
if (dir !== '.' && dirs.indexOf(dir) < 0) {
tryAddToDirs(path.dirname(dir));
debugPrint(`Adding ${dir} to list of directories to create...`);
dirs.push(dir)
}
}
// Recursively sort all files into directories / files
const processDirs = [fixturesPath]
while (processDirs.length > 0) {
const workingDir = processDirs.pop()!;
// Check if we need to make this directory, or any of its parents.
tryAddToDirs(workingDir);
const workingList = fs.readdirSync(workingDir);
workingList.forEach((item) => {
const itemPath = `${workingDir}/${item}`;
const itemStat = fs.statSync(itemPath);
if (itemStat.isFile()) {
debugPrint(`Adding ${itemPath} to list of files to create...`);
files.push(itemPath.replace(/\\/g, '/'));
} else {
processDirs.push(itemPath);
}
});
}
// Generate the file!
// Header
fs.writeSync(outfile, `
// Generated by scripts/make_fixture_loader.ts
// Used by unit testing only. Preloads needed testing files.
import * as BrowserFS from '../../src/index';
const fs = BrowserFS.BFSRequire('fs');
export default function (): void {
let nextDir: number;
let dirs = ${JSON.stringify(dirs)};
let mcb = function(err?: NodeJS.ErrnoException): void {
if (err && err.code !== 'EEXIST') throw err;
nextDir++;
if (nextDir === dirs.length) {
__fixturesAddFiles();
} else {
fs.mkdir(dirs[nextDir],mcb);
}
};
let fcb = function(p: string, writtenData: string) {
return function(err?: NodeJS.ErrnoException) {
if (err) throw err;
fs.readFile(p, {encoding:"base64"}, function(err: NodeJS.ErrnoException, readData: string) {
if (err) throw err;
if (writtenData != readData) throw new Error('Read data for '+p+' does not match written data:\\n'+readData+'\\n!=\\n'+writtenData);
});
};
};
let __fixturesAddFiles = function() {
`);
files.forEach((file) => {
const id = uid++;
const data = fs.readFileSync(file);
const datab64 = data.toString('base64');
fs.writeSync(outfile, `
let p${id} = "${file}";
let d${id} = "${datab64}";
fs.writeFile(p${id}, d${id}, {encoding: "base64"}, fcb(p${id}, d${id}));
`);
});
fs.writeSync(outfile, `
};
// Begin loading fixtures.
if (fs.getRootFS().isReadOnly()) { return; }
nextDir = -1;
// Ensure that root directory works.
fs.exists('/', function(doesExist) {
if (!doesExist) throw new Error("Invalid filesystem: Root does not exist.");
mcb();
});
};
`);
fs.closeSync(outfile);