2 Copyright (c) 2012, Yahoo! Inc. All rights reserved.
3 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
6 var path = require('path'),
7 util = require('util'),
9 async = require('async'),
10 mkdirp = require('mkdirp'),
11 writer = require('./writer'),
12 Writer = writer.Writer,
13 ContentWriter = writer.ContentWriter;
15 function extend(cons, proto) {
16 Object.keys(proto).forEach(function (k) {
17 cons.prototype[k] = proto[k];
21 function BufferedContentWriter() {
22 ContentWriter.call(this);
25 util.inherits(BufferedContentWriter, ContentWriter);
27 extend(BufferedContentWriter, {
28 write: function (str) {
31 getContent: function () {
36 function StreamContentWriter(stream) {
37 ContentWriter.call(this);
40 util.inherits(StreamContentWriter, ContentWriter);
42 extend(StreamContentWriter, {
43 write: function (str) {
44 this.stream.write(str);
48 function SyncFileWriter() {
51 util.inherits(SyncFileWriter, Writer);
53 extend(SyncFileWriter, {
54 writeFile: function (file, callback) {
55 mkdirp.sync(path.dirname(file));
56 var cw = new BufferedContentWriter();
58 fs.writeFileSync(file, cw.getContent(), 'utf8');
61 this.emit('done'); //everything already done
65 function AsyncFileWriter() {
66 this.queue = async.queue(this.processFile.bind(this), 20);
67 this.openFileMap = {};
70 util.inherits(AsyncFileWriter, Writer);
72 extend(AsyncFileWriter, {
73 writeFile: function (file, callback) {
74 this.openFileMap[file] = true;
75 this.queue.push({ file: file, callback: callback });
77 processFile: function (task, cb) {
79 userCallback = task.callback,
84 mkdirp.sync(path.dirname(file));
85 stream = fs.createWriteStream(file);
86 stream.on('close', function () {
87 delete that.openFileMap[file];
91 stream.on('error', function (err) { that.emit('error', err); });
92 contentWriter = new StreamContentWriter(stream);
93 userCallback(contentWriter);
97 this.doneCalled = true;
100 checkDone: function () {
101 if (!this.doneCalled) { return; }
102 if (Object.keys(this.openFileMap).length === 0) {
108 * a concrete writer implementation that can write files synchronously or
109 * asynchronously based on the constructor argument passed to it.
115 * fileWriter = new require('istanbul').FileWriter(sync);
117 * fileWriter.on('done', function () { console.log('done'); });
118 * fileWriter.copyFile('/foo/bar.jpg', '/baz/bar.jpg');
119 * fileWriter.writeFile('/foo/index.html', function (contentWriter) {
120 * contentWriter.println('<html>');
121 * contentWriter.println('</html>');
123 * fileWriter.done(); // will emit the `done` event when all files are written
131 function FileWriter(sync) {
134 this.delegate = sync ? new SyncFileWriter() : new AsyncFileWriter();
135 this.delegate.on('error', function (err) { that.emit('error', err); });
136 this.delegate.on('done', function () { that.emit('done'); });
139 util.inherits(FileWriter, Writer);
142 copyFile: function (source, dest) {
143 mkdirp.sync(path.dirname(dest));
144 fs.writeFileSync(dest, fs.readFileSync(source));
146 writeFile: function (file, callback) {
147 this.delegate.writeFile(file, callback);
150 this.delegate.done();
154 module.exports = FileWriter;