Skip to content

Commit

Permalink
breaking up init for more readability
Browse files Browse the repository at this point in the history
  • Loading branch information
nmccready committed Jan 6, 2017
1 parent 335aa4f commit a83c5fa
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 97 deletions.
90 changes: 7 additions & 83 deletions src/init.js → src/init/index.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
'use strict';
var utils = require('./utils'),
var utils = require('../utils'),
unixStylePath = utils.unixStylePath,
PLUGIN_NAME = utils.PLUGIN_NAME,
urlRegex = utils.urlRegex,
through = require('through2'),
fs = require('graceful-fs'),
path = require('path'),
convert = require('convert-source-map'),
stripBom = require('strip-bom'),
acorn = require('acorn'),
SourceMapGenerator = require('source-map').SourceMapGenerator,
css = require('css');
css = require('css'),
loadMaps = require('./loadMaps');

/**
* Initialize source mapping chain
Expand Down Expand Up @@ -43,82 +40,9 @@ function init(options) {
var preExisting = utils.getPreExisting(fileContent);

if (options.loadMaps) {
debug('loadMaps');
var sourcePath = ''; //root path for the sources in the map

// Try to read inline source map
sourceMap = convert.fromSource(fileContent, options.largeFile);
if (sourceMap) {
sourceMap = sourceMap.toObject();
// sources in map are relative to the source file
sourcePath = path.dirname(file.path);
if (!options.largeFile) {
fileContent = convert.removeComments(fileContent);
}
} else {
// look for source map comment referencing a source map file
var mapComment = convert.mapFileCommentRegex.exec(fileContent);

var mapFile;
if (mapComment) {
mapFile = path.resolve(path.dirname(file.path), mapComment[1] || mapComment[2]);
fileContent = convert.removeMapFileComments(fileContent);
// if no comment try map file with same name as source file
} else {
mapFile = file.path + '.map';
}

// sources in external map are relative to map file
sourcePath = path.dirname(mapFile);

try {
sourceMap = JSON.parse(stripBom(fs.readFileSync(mapFile, 'utf8')));
} catch (e) {}
}

// fix source paths and sourceContent for imported source map
if (sourceMap) {
sourceMap.sourcesContent = sourceMap.sourcesContent || [];
sourceMap.sources.forEach(function(source, i) {
if (source.match(urlRegex)) {
sourceMap.sourcesContent[i] = sourceMap.sourcesContent[i] || null;
return;
}
var absPath = path.resolve(sourcePath, source);
sourceMap.sources[i] = unixStylePath(path.relative(file.base, absPath));

if (!sourceMap.sourcesContent[i]) {
var sourceContent = null;
if (sourceMap.sourceRoot) {
if (sourceMap.sourceRoot.match(urlRegex)) {
sourceMap.sourcesContent[i] = null;
return;
}
absPath = path.resolve(sourcePath, sourceMap.sourceRoot, source);
}

// if current file: use content
if (absPath === file.path) {
sourceContent = fileContent;

// else load content from file
} else {
try {
if (options.debug)
debug('No source content for "' + source + '". Loading from file.');
sourceContent = stripBom(fs.readFileSync(absPath, 'utf8'));
} catch (e) {
if (options.debug)
debug('warn: source file not found: ' + absPath);
}
}
sourceMap.sourcesContent[i] = sourceContent;
}

});
}
// remove source map comment from source
file.contents = new Buffer(fileContent, 'utf8');
var result = loadMaps({file:file, fileContent:fileContent}, options);
sourceMap = result.map;
fileContent = result.content;
}

if (!sourceMap && options.identityMap) {
Expand Down Expand Up @@ -201,7 +125,7 @@ function init(options) {
};
}
else if(preExisting !== null && typeof preExisting !== 'undefined')
sourceMap.preExisting = preExisting
sourceMap.preExisting = preExisting;

sourceMap.file = unixStylePath(file.relative);
file.sourceMap = sourceMap;
Expand Down
120 changes: 120 additions & 0 deletions src/init/loadMaps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
'use strict';

var utils = require('../utils');
var PLUGIN_NAME = utils.PLUGIN_NAME;
var debug = require('debug-fabulous')()(PLUGIN_NAME + ':init:loadMaps');
var convert = require('convert-source-map');
var stripBom = require('strip-bom');
var urlRegex = utils.urlRegex;
var fs = require('graceful-fs');
var path = require('path');
var unixStylePath = utils.unixStylePath;


module.exports = function loadMaps (lOpts, options) {
debug('loadMaps');
var fileContent = lOpts.fileContent;
var file = lOpts.file;

var sources = { path: '', map: null , content: fileContent};

_getInlineSources({sources:sources, file:file, options:options});
if (!sources.map) // ahh not inline, so try file
_getFileSources({sources:sources, file:file});

_fixSources({sources: sources, file: file, options: options});

return sources;
};

function _fixSources(args) {
var sources = args.sources;
var file = args.file;
var options = args.options;

// fix source paths and sourceContent for imported source map
if (sources.map) {
sources.map.sourcesContent = sources.map.sourcesContent || [];
sources.map.sources.forEach(function(source, i) {
if (source.match(urlRegex)) {
sources.map.sourcesContent[i] = sources.map.sourcesContent[i] || null;
return;
}
var absPath = path.resolve(sources.path, source);
sources.map.sources[i] = unixStylePath(path.relative(file.base, absPath));

if (!sources.map.sourcesContent[i]) {
var sourceContent = null;
if (sources.map.sourceRoot) {
if (sources.map.sourceRoot.match(urlRegex)) {
sources.map.sourcesContent[i] = null;
return;
}
absPath = path.resolve(sources.path, sources.map.sourceRoot, source);
}

// if current file: use content
if (absPath === file.path) {
sourceContent = sources.content;

// else load content from file
} else {
try {
if (options.debug)
debug('No source content for "' + source + '". Loading from file.');
sourceContent = stripBom(fs.readFileSync(absPath, 'utf8'));
} catch (e) {
if (options.debug)
debug('warn: source file not found: ' + absPath);
}
}
sources.map.sourcesContent[i] = sourceContent;
}

});
// remove source map comment from source
file.contents = new Buffer(sources.content, 'utf8');
}

}

function _getInlineSources(args) {
var sources = args.sources,
file = args.file,
options = args.options;
// Try to read inline source map
sources.map = convert.fromSource(sources.content, options.largeFile);

if (!sources.map)
return sources;

sources.map = sources.map.toObject();
// sources in map are relative to the source file
sources.path = path.dirname(file.path);
if (!options.largeFile) {
sources.content = convert.removeComments(sources.content);
}
}

function _getFileSources(args) {
var sources = args.sources,
file = args.file;
// look for source map comment referencing a source map file
var mapComment = convert.mapFileCommentRegex.exec(sources.content);

var mapFile;
if (mapComment) {
mapFile = path.resolve(path.dirname(file.path), mapComment[1] || mapComment[2]);
sources.content = convert.removeMapFileComments(sources.content);
// if no comment try map file with same name as source file
} else {
mapFile = file.path + '.map';
}

// sources in external map are relative to map file
sources.path = path.dirname(mapFile);

try {
sources.map = JSON.parse(stripBom(fs.readFileSync(mapFile, 'utf8')));
} catch (e) {}//should we really swallow this error?
}
32 changes: 18 additions & 14 deletions test/init.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
'use strict';

var test = require('tape');
//BEGIN PRE-HOOK of debug
var debug = require('debug-fabulous')();
// Begin inner conflict with self here..
// nmccready:
//
//
// bliss: Turning debug on here clutters the test output;
// but, having debug off in portions results in not having 100% test coverage.
//
// touche: If we demand 100% coverage, then we need clutter logging :_(
//
// partial-bliss: The alternative is to have ignore cover statements on some of the logging.
// touche: However, those logging statements could potentially fail
debug.save('gulp-sourcemaps:init');
debug.save('gulp-sourcemaps:init:loadMaps');
debug.enable(debug.load());
//END PRE-HOOK of debug (must be loaded before our main module (sourcemaps))
var sourcemaps = require('..');
var File = require('vinyl');
var ReadableStream = require('stream').Readable;
var path = require('path');
var fs = require('fs');
var hookStd = require('hook-std');
var debug = require('debug-fabulous')();

var sourceContent = fs.readFileSync(path.join(__dirname, 'assets/helloworld.js')).toString();
var sourceContentCSS = fs.readFileSync(path.join(__dirname, 'assets/test.css')).toString();
Expand Down Expand Up @@ -63,19 +79,6 @@ function makeFileCSS() {
}

test('init: should pass through when file is null', function(t) {
// Begin inner conflict with self here..
// nmccready:
//
//
// bliss: Turning debug on here clutters the test output;
// but, having debug off in portions results in not having 100% test coverage.
//
// touche: If we demand 100% coverage, then we need clutter logging :_(
//
// partial-bliss: The alternative is to have ignore cover statements on some of the logging.
// touche: However, those logging statements could potentially fail
debug.save('gulp-sourcemaps:init');
debug.enable(debug.load());
// end inner conflict
var file = new File();
var pipeline = sourcemaps.init();
Expand Down Expand Up @@ -398,6 +401,7 @@ test('init: should output an error message if debug option is set and sourceCont
return regex.test(s);
};
};
console.log(history);
t.ok(
history.some(
hasRegex(/No source content for \"missingfile\". Loading from file./)),
Expand Down

0 comments on commit a83c5fa

Please sign in to comment.