123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- /*
- Copyright 2012-2015, Yahoo Inc.
- Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
- */
- const util = require('util');
- const path = require('path');
- const fs = require('fs');
- const mkdirp = require('make-dir');
- const supportsColor = require('supports-color');
- const isAbsolute =
- path.isAbsolute ||
- /* istanbul ignore next */ function(p) {
- return path.resolve(p) === path.normalize(p);
- };
- /**
- * abstract interface for writing content
- * @class ContentWriter
- * @constructor
- */
- /* istanbul ignore next: abstract class */
- function ContentWriter() {}
- /**
- * writes a string as-is to the destination
- * @param {String} str the string to write
- */
- /* istanbul ignore next: abstract class */
- ContentWriter.prototype.write = function() {
- throw new Error('write: must be overridden');
- };
- /**
- * returns the colorized version of a string. Typically,
- * content writers that write to files will return the
- * same string and ones writing to a tty will wrap it in
- * appropriate escape sequences.
- * @param {String} str the string to colorize
- * @param {String} clazz one of `high`, `medium` or `low`
- * @returns {String} the colorized form of the string
- */
- ContentWriter.prototype.colorize = function(str /*, clazz*/) {
- return str;
- };
- /**
- * writes a string appended with a newline to the destination
- * @param {String} str the string to write
- */
- ContentWriter.prototype.println = function(str) {
- this.write(str + '\n');
- };
- /**
- * closes this content writer. Should be called after all writes are complete.
- */
- ContentWriter.prototype.close = function() {};
- /**
- * a content writer that writes to a file
- * @param {Number} fd - the file descriptor
- * @extends ContentWriter
- * @constructor
- */
- function FileContentWriter(fd) {
- this.fd = fd;
- }
- util.inherits(FileContentWriter, ContentWriter);
- FileContentWriter.prototype.write = function(str) {
- fs.writeSync(this.fd, str);
- };
- FileContentWriter.prototype.close = function() {
- fs.closeSync(this.fd);
- };
- /**
- * a content writer that writes to the console
- * @extends ContentWriter
- * @constructor
- */
- function ConsoleWriter() {}
- util.inherits(ConsoleWriter, ContentWriter);
- // allow stdout to be captured for tests.
- let capture = false;
- let output = '';
- ConsoleWriter.prototype.write = function(str) {
- if (capture) {
- output += str;
- } else {
- process.stdout.write(str);
- }
- };
- ConsoleWriter.prototype.colorize = function(str, clazz) {
- const colors = {
- low: '31;1',
- medium: '33;1',
- high: '32;1'
- };
- /* istanbul ignore next: different modes for CI and local */
- if (supportsColor.stdout && colors[clazz]) {
- return '\u001b[' + colors[clazz] + 'm' + str + '\u001b[0m';
- }
- return str;
- };
- /**
- * utility for writing files under a specific directory
- * @class FileWriter
- * @param {String} baseDir the base directory under which files should be written
- * @constructor
- */
- function FileWriter(baseDir) {
- if (!baseDir) {
- throw new Error('baseDir must be specified');
- }
- this.baseDir = baseDir;
- }
- /**
- * static helpers for capturing stdout report output;
- * super useful for tests!
- */
- FileWriter.startCapture = function() {
- capture = true;
- };
- FileWriter.stopCapture = function() {
- capture = false;
- };
- FileWriter.getOutput = function() {
- return output;
- };
- FileWriter.resetOutput = function() {
- output = '';
- };
- /**
- * returns a FileWriter that is rooted at the supplied subdirectory
- * @param {String} subdir the subdirectory under which to root the
- * returned FileWriter
- * @returns {FileWriter}
- */
- FileWriter.prototype.writerForDir = function(subdir) {
- if (isAbsolute(subdir)) {
- throw new Error(
- 'Cannot create subdir writer for absolute path: ' + subdir
- );
- }
- return new FileWriter(this.baseDir + '/' + subdir);
- };
- /**
- * copies a file from a source directory to a destination name
- * @param {String} source path to source file
- * @param {String} dest relative path to destination file
- * @param {String} [header=undefined] optional text to prepend to destination
- * (e.g., an "this file is autogenerated" comment, copyright notice, etc.)
- */
- FileWriter.prototype.copyFile = function(source, dest, header) {
- if (isAbsolute(dest)) {
- throw new Error('Cannot write to absolute path: ' + dest);
- }
- dest = path.resolve(this.baseDir, dest);
- mkdirp.sync(path.dirname(dest));
- let contents;
- if (header) {
- contents = header + fs.readFileSync(source, 'utf8');
- } else {
- contents = fs.readFileSync(source);
- }
- fs.writeFileSync(dest, contents);
- };
- /**
- * returns a content writer for writing content to the supplied file.
- * @param {String|null} file the relative path to the file or the special
- * values `"-"` or `null` for writing to the console
- * @returns {ContentWriter}
- */
- FileWriter.prototype.writeFile = function(file) {
- if (file === null || file === '-') {
- return new ConsoleWriter();
- }
- if (isAbsolute(file)) {
- throw new Error('Cannot write to absolute path: ' + file);
- }
- file = path.resolve(this.baseDir, file);
- mkdirp.sync(path.dirname(file));
- return new FileContentWriter(fs.openSync(file, 'w'));
- };
- module.exports = FileWriter;
|