From 1dd6b48773019a923908b02f674035c73cf3aa80 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 24 Mar 2017 18:01:44 -0700 Subject: [PATCH 1/3] initial thoughts for an implementation - can definitely be cleaned up --- index.js | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 6 +++- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..fccf340 --- /dev/null +++ b/index.js @@ -0,0 +1,99 @@ +'use strict'; + +var path = require('path'); +var through = require('through2'); +var convert = require('convert-source-map'); +var normalize = require('normalize-path'); + +function comment(mapFn) { + + function transform(file, _, cb) { + if (!file.sourceMap) { + return cb(null, file); + } + + // TODO: handle non-buffer + + function mapper(sourceMappingURL) { + var result = sourceMappingURL; + if (typeof mapFn === 'function') { + result = mapFn(sourceMappingURL, file); + } + + return normalize(result); + } + + var contents = file.contents.toString() + + var hasInlineSourcemap = convert.commentRegex.test(contents); + var hasExternalSourcemap = convert.mapFileCommentRegex.test(contents); + + if (!hasInlineSourcemap && !hasExternalSourcemap) { + return cb(null, file); + } + + var sourceMappingURL; + + if (hasInlineSourcemap) { + // exec map? + var result = mapper(sourceMappingURL); + + if (!result) { + // TODO: buffer + file.contents = convert.removeComments(contents); + + return cb(null, file); + } + + if (result !== sourceMappingURL) { + // TODO: buffer + file.contents = contents.replace(convert.commentRegex, result); + + return cb(null, file); + } + + return cb(null, file) + } + + if (hasExternalSourcemap) { + // exec map? + var result = mapper(sourceMappingURL); + + if (!result) { + // TODO: buffer + file.contents = convert.removeMapFileComments(contents); + + return cb(null, file); + } + + if (result !== sourceMappingURL) { + // TODO: buffer + file.contents = contents.replace(convert.mapFileCommentRegex, result); + + return cb(null, file); + } + } + + // TODO: unreachable? + cb(null, file); + } + + return through.obj(transform); +} + +function prefix(str) { + return comment(function(sourceMappingURL) { + // TODO: url instead of path? + return str + path.join('/', sourceMappingURL); + }) +} +comment.prefix = prefix; + +function remove() { + return comment(function() { + return null; + }); +} +comment.remove = remove; + +module.exports = comment; diff --git a/package.json b/package.json index 7eb1185..b187bbd 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,11 @@ "cover": "istanbul cover _mocha --report lcovonly", "coveralls": "npm run cover && istanbul-coveralls" }, - "dependencies": {}, + "dependencies": { + "convert-source-map": "^1.3.0", + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, "devDependencies": { "eslint": "^1.7.3", "eslint-config-gulp": "^2.0.0", From 9660ad4130983aca06080bd5c3342c707bb796f8 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 31 Mar 2017 17:41:04 -0700 Subject: [PATCH 2/3] refactor and add tests, coverage should be 100% now --- index.js | 103 ++--- package.json | 4 +- test/fixtures/helloworld.js | 5 + test/fixtures/helloworld.map.js | 7 + test/index.js | 703 ++++++++++++++++++++++++++++++++ 5 files changed, 772 insertions(+), 50 deletions(-) create mode 100644 test/fixtures/helloworld.js create mode 100644 test/fixtures/helloworld.map.js create mode 100644 test/index.js diff --git a/index.js b/index.js index fccf340..3cb9c50 100644 --- a/index.js +++ b/index.js @@ -5,25 +5,50 @@ var through = require('through2'); var convert = require('convert-source-map'); var normalize = require('normalize-path'); -function comment(mapFn) { +function processInline(contents, mapper) { + var sourceMappingURL = convert.getCommentValue(contents); - function transform(file, _, cb) { - if (!file.sourceMap) { - return cb(null, file); - } + var result = mapper(sourceMappingURL); - // TODO: handle non-buffer + if (!result) { + return convert.removeComments(contents); + } - function mapper(sourceMappingURL) { - var result = sourceMappingURL; - if (typeof mapFn === 'function') { - result = mapFn(sourceMappingURL, file); - } + if (result !== sourceMappingURL) { + // TODO: use the same comment type as original + // TODO: we don't want to parse/convert so this works but should be named different + result = convert.generateMapFileComment(result); + // TODO: add `replaceComments` to convert-source-map + return contents.replace(convert.commentRegex, result); + } +} - return normalize(result); +function processExternal(contents, mapper) { + var sourceMappingURL = convert.getMapFileCommentValue(contents); + + var result = mapper(sourceMappingURL); + + if (!result) { + return convert.removeMapFileComments(contents); + } + + if (result !== sourceMappingURL) { + // TODO: use the same comment type as original + result = convert.generateMapFileComment(result); + // TODO: add `replaceMapFileComments` to convert-source-map + return contents.replace(convert.mapFileCommentRegex, result); + } +} + +function comment(mapFn) { + + function transform(file, _, cb) { + // TODO: should this error? Probably not + if (!file.isBuffer()) { + return cb(null, file); } - var contents = file.contents.toString() + var contents = file.contents.toString(); var hasInlineSourcemap = convert.commentRegex.test(contents); var hasExternalSourcemap = convert.mapFileCommentRegex.test(contents); @@ -32,65 +57,47 @@ function comment(mapFn) { return cb(null, file); } - var sourceMappingURL; - - if (hasInlineSourcemap) { - // exec map? - var result = mapper(sourceMappingURL); - - if (!result) { - // TODO: buffer - file.contents = convert.removeComments(contents); - - return cb(null, file); + function mapper(sourceMappingURL) { + var result = sourceMappingURL; + if (typeof mapFn === 'function') { + result = mapFn(sourceMappingURL, file); } - if (result !== sourceMappingURL) { - // TODO: buffer - file.contents = contents.replace(convert.commentRegex, result); - - return cb(null, file); + // This is inverted because hasExternalSourcemap covers inline also + if (hasInlineSourcemap || !result) { + return result; } - return cb(null, file) + return normalize(result); } - if (hasExternalSourcemap) { - // exec map? - var result = mapper(sourceMappingURL); + // Always one of the 2 because we bail if neither + var processor = hasInlineSourcemap ? processInline : processExternal; - if (!result) { - // TODO: buffer - file.contents = convert.removeMapFileComments(contents); + var result = processor(contents, mapper); - return cb(null, file); - } - - if (result !== sourceMappingURL) { - // TODO: buffer - file.contents = contents.replace(convert.mapFileCommentRegex, result); - - return cb(null, file); - } + if (result) { + file.contents = new Buffer(result); } - // TODO: unreachable? - cb(null, file); + return cb(null, file); } return through.obj(transform); } function prefix(str) { + // TODO: should this somehow check if it is a path vs data-uri? return comment(function(sourceMappingURL) { // TODO: url instead of path? return str + path.join('/', sourceMappingURL); - }) + }); } comment.prefix = prefix; function remove() { return comment(function() { + // Returning anything falsey removes the comment return null; }); } diff --git a/package.json b/package.json index b187bbd..14ea45d 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,14 @@ "index.js" ], "scripts": { - "lint": "eslint . && jscs index.js test/", + "lint": "eslint . && jscs index.js test/index.js", "pretest": "npm run lint", "test": "mocha --async-only", "cover": "istanbul cover _mocha --report lcovonly", "coveralls": "npm run cover && istanbul-coveralls" }, "dependencies": { - "convert-source-map": "^1.3.0", + "convert-source-map": "thlorenz/convert-source-map#comment-values", "normalize-path": "^2.0.1", "through2": "^2.0.3" }, diff --git a/test/fixtures/helloworld.js b/test/fixtures/helloworld.js new file mode 100644 index 0000000..9406b3e --- /dev/null +++ b/test/fixtures/helloworld.js @@ -0,0 +1,5 @@ +'use strict'; + +function helloWorld() { + console.log('Hello world!'); +} diff --git a/test/fixtures/helloworld.map.js b/test/fixtures/helloworld.map.js new file mode 100644 index 0000000..d6b7a05 --- /dev/null +++ b/test/fixtures/helloworld.map.js @@ -0,0 +1,7 @@ +'use strict'; + +function helloWorld() { + console.log('Hello world!'); +} + +//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlcyI6WyJoZWxsb3dvcmxkLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuZnVuY3Rpb24gaGVsbG9Xb3JsZCgpIHtcbiAgICBjb25zb2xlLmxvZygnSGVsbG8gd29ybGQhJyk7XG59XG4iXSwiZmlsZSI6ImhlbGxvd29ybGQuanMifQ== diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..f4dd5ad --- /dev/null +++ b/test/index.js @@ -0,0 +1,703 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); + +var expect = require('expect'); + +var miss = require('mississippi'); +var File = require('vinyl'); +var normalize = require('normalize-path'); +var convert = require('convert-source-map'); + +var comment = require('../'); + +var pipe = miss.pipe; +var from = miss.from; +var concat = miss.concat; + +// TODO: use buffer directly? +var sourceContent = fs.readFileSync(path.join(__dirname, 'fixtures/helloworld.js'), 'utf8'); +var mappedContent = fs.readFileSync(path.join(__dirname, 'fixtures/helloworld.map.js'), 'utf8'); +var inlineMap = convert.getCommentValue(mappedContent); + +function makeFile() { + var file = new File({ + cwd: __dirname, + base: __dirname + '/assets', + path: __dirname + '/assets/helloworld.js', + contents: new Buffer(''), + }); + + file.sourceMap = { + version: 3, + file: 'helloworld.js', + names: [], + mappings: '', + sources: ['helloworld.js'], + }; + + return file; +} + +function makeExternalMapFile() { + var file = makeFile(); + file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=helloworld.js.map'); + return file; +} + +function makeInlineMapFile() { + var file = makeFile(); + file.contents = new Buffer(mappedContent); + return file; +} + +describe('comment', function() { + + // TODO: is this proper behavior? + it('ignores file if no comment', function(done) { + var file = makeFile(); + + var spy = expect.createSpy(); + + function assert(files) { + expect(files.length).toEqual(1); + expect(spy).toNotHaveBeenCalled(); + } + + pipe([ + from.obj([file]), + comment(spy), + concat(assert), + ], done); + }); + + it('ignores file if not Buffer contents', function(done) { + var file = makeFile(); + file.contents = null; + + var spy = expect.createSpy(); + + function assert(files) { + expect(files.length).toEqual(1); + expect(spy).toNotHaveBeenCalled(); + } + + pipe([ + from.obj([file]), + comment(spy), + concat(assert), + ], done); + }); + + it('only ignores a file without sourceMappingURL comment', function(done) { + var file = makeExternalMapFile(); + var file2 = makeFile(); + + function mapFn(sourceMappingURL) { + return sourceMappingURL; + } + + var spy = expect.createSpy().andCall(mapFn); + + function assert(files) { + expect(files.length).toEqual(2); + expect(spy.calls.length).toEqual(1); + } + + pipe([ + from.obj([file, file2]), + comment(spy), + concat(assert), + ], done); + }); + + it('ignores a file with invalid sourceMappingURL comment', function(done) { + var file = makeFile(); + file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL='); + + var spy = expect.createSpy(); + + function assert(files) { + expect(files.length).toEqual(1); + expect(spy).toNotHaveBeenCalled(); + } + + pipe([ + from.obj([file]), + comment(spy), + concat(assert), + ], done); + }); + + describe('with external sourceMappingURL', function() { + + it('does not care about the file.sourceMap property', function(done) { + var file = makeExternalMapFile(); + delete file.sourceMap; + + function mapFn(sourceMappingURL) { + return sourceMappingURL; + } + + var spy = expect.createSpy().andCall(mapFn); + + function assert(files) { + expect(files.length).toEqual(1); + expect(spy).toHaveBeenCalled(); + } + + pipe([ + from.obj([file]), + comment(spy), + concat(assert), + ], done); + }); + + it('calls map function per file', function(done) { + var file = makeExternalMapFile(); + + function mapFn(sourceMappingURL) { + return '/test/' + sourceMappingURL; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual('/test/helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('normalizes Windows paths to unix paths', function(done) { + var file = makeExternalMapFile(); + + function mapFn(sourceMappingURL) { + return '\\test\\' + sourceMappingURL; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual('/test/helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('does not need a map function', function(done) { + var file = makeExternalMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual('helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment(), + concat(assert), + ], done); + }); + + it('ignores non-function argument', function(done) { + var file = makeExternalMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual('helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment('invalid argument'), + concat(assert), + ], done); + }); + + it('still normalizes without a map function', function(done) { + var file = makeFile(); + file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=\\test\\helloworld.js.map'); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual('/test/helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment(), + concat(assert), + ], done); + }); + + it('calls map function with the sourceMappingURL value and the vinyl file', function(done) { + var file = makeExternalMapFile(); + + function mapFn(sourceMappingURL, file) { + expect(File.isVinyl(file)).toEqual(true); + + return file.base + '/' + sourceMappingURL; + } + + function assert(files) { + expect(files.length).toEqual(1); + + var file = files[0]; + var base = normalize(file.base); + var comment = convert.getMapFileCommentValue(file.contents.toString()); + expect(comment).toEqual(base + '/helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if null is returned from the map function', function(done) { + var file = makeExternalMapFile(); + + function mapFn() { + return null; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if undefined is returned from the map function', function(done) { + var file = makeExternalMapFile(); + + function mapFn() { + return undefined; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if false is returned from the map function', function(done) { + var file = makeExternalMapFile(); + + function mapFn() { + return false; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if an empty string is returned from the map function', function(done) { + var file = makeExternalMapFile(); + + function mapFn() { + return ''; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('changes the buffer reference when values are different', function(done) { + var file = makeExternalMapFile(); + var contents = file.contents; + + function mapFn(sourceMappingURL) { + return '/test/' + sourceMappingURL; + } + + function assert(files) { + expect(files.length).toEqual(1); + expect(files[0].contents).toNotBe(contents); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('keeps the buffer reference when values are same', function(done) { + var file = makeExternalMapFile(); + var contents = file.contents; + + function mapFn(sourceMappingURL) { + return sourceMappingURL; + } + + function assert(files) { + expect(files.length).toEqual(1); + expect(files[0].contents).toBe(contents); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + }); + + describe('with inline sourceMappingURL', function() { + + it('does not care about the file.sourceMap property', function(done) { + var file = makeInlineMapFile(); + delete file.sourceMap; + + function mapFn(sourceMappingURL) { + return sourceMappingURL; + } + + var spy = expect.createSpy().andCall(mapFn); + + function assert(files) { + expect(files.length).toEqual(1); + expect(spy).toHaveBeenCalled(); + } + + pipe([ + from.obj([file]), + comment(spy), + concat(assert), + ], done); + }); + + it('calls map function per file', function(done) { + var file = makeInlineMapFile(); + + function mapFn(sourceMappingURL) { + return sourceMappingURL.replace('utf8', 'utf-8'); + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toContain('utf-8'); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('does not normalize mapped sourceMappingURLs', function(done) { + var file = makeInlineMapFile(); + + function mapFn(sourceMappingURL) { + // Don't do this at home; things WILL break + return sourceMappingURL + '\\'; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toContain('\\'); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('does not need a map function', function(done) { + var file = makeInlineMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(inlineMap); + } + + pipe([ + from.obj([file]), + comment(), + concat(assert), + ], done); + }); + + it('ignores non-function argument', function(done) { + var file = makeInlineMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(inlineMap); + } + + pipe([ + from.obj([file]), + comment('invalid argument'), + concat(assert), + ], done); + }); + + it('does not normalize without a map function', function(done) { + var file = makeFile(); + // Don't do this at home; things WILL break + file.contents = new Buffer(sourceContent + '\n//# sourceMappingURL=' + inlineMap + '\\'); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toContain('\\'); + } + + pipe([ + from.obj([file]), + comment(), + concat(assert), + ], done); + }); + + it('calls map function with the sourceMappingURL value and the vinyl file', function(done) { + var file = makeInlineMapFile(); + + function mapFn(sourceMappingURL, file) { + expect(File.isVinyl(file)).toEqual(true); + + return sourceMappingURL.replace('utf8', 'utf-8'); + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toContain('utf-8'); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if null is returned from the map function', function(done) { + var file = makeInlineMapFile(); + + function mapFn() { + return null; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if undefined is returned from the map function', function(done) { + var file = makeInlineMapFile(); + + function mapFn() { + return undefined; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if false is returned from the map function', function(done) { + var file = makeInlineMapFile(); + + function mapFn() { + return false; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('removes the comment if an empty string is returned from the map function', function(done) { + var file = makeInlineMapFile(); + + function mapFn() { + return ''; + } + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('changes the buffer reference when values are different', function(done) { + var file = makeInlineMapFile(); + var contents = file.contents; + + function mapFn(sourceMappingURL) { + return sourceMappingURL.replace('utf8', 'utf-8'); + } + + function assert(files) { + expect(files.length).toEqual(1); + expect(files[0].contents).toNotBe(contents); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + + it('keeps the buffer reference when values are same', function(done) { + var file = makeInlineMapFile(); + var contents = file.contents; + + function mapFn(sourceMappingURL) { + return sourceMappingURL; + } + + function assert(files) { + expect(files.length).toEqual(1); + expect(files[0].contents).toBe(contents); + } + + pipe([ + from.obj([file]), + comment(mapFn), + concat(assert), + ], done); + }); + }); +}); + +describe('comment.prefix', function() { + + it('prefixes the sourceMappingURL with the string provided', function(done) { + var file = makeExternalMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual('/test/helloworld.js.map'); + } + + pipe([ + from.obj([file]), + comment.prefix('/test'), + concat(assert), + ], done); + }); +}); + +describe('comment.remove', function() { + + it('removes an external sourcemap comment', function(done) { + var file = makeExternalMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getMapFileCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment.remove(), + concat(assert), + ], done); + }); + + it('removes an inline sourcemap comment', function(done) { + var file = makeInlineMapFile(); + + function assert(files) { + expect(files.length).toEqual(1); + var comment = convert.getCommentValue(files[0].contents.toString()); + expect(comment).toEqual(null); + } + + pipe([ + from.obj([file]), + comment.remove(), + concat(assert), + ], done); + }); +}); From 9d7fa53ad9dc3ccee734c168a0d1b48ef5d9614b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 31 Mar 2017 17:48:33 -0700 Subject: [PATCH 3/3] stub readme to trigger CI --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6668fb4..53a0b6a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,34 @@ -# comment +# @gulp-sourcemaps/comment + +[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] + Gulp plugin for working with the sourceMappingURL comment of a file. + +## Example + +```js +TODO +``` + +## API + +### TODO + +## License + +MIT + +[vinyl-url]: https://github.com/gulpjs/vinyl + +[downloads-image]: http://img.shields.io/npm/dm/@gulp-sourcemaps/comment.svg +[npm-url]: https://npmjs.org/package/@gulp-sourcemaps/comment +[npm-image]: http://img.shields.io/npm/v/@gulp-sourcemaps/comment.svg + +[travis-url]: https://travis-ci.org/gulp-sourcemaps/comment +[travis-image]: http://img.shields.io/travis/gulp-sourcemaps/comment.svg?label=travis-ci + +[appveyor-url]: https://ci.appveyor.com/project/phated/comment +[appveyor-image]: https://img.shields.io/appveyor/ci/phated/comment.svg?label=appveyor + +[coveralls-url]: https://coveralls.io/r/gulp-sourcemaps/comment +[coveralls-image]: http://img.shields.io/coveralls/gulp-sourcemaps/comment.svg