2011-08-14 17:05:37 -04:00
|
|
|
/**
|
|
|
|
* Determines dependency order
|
|
|
|
*
|
|
|
|
* This script will determine the order in which files must be concatenated in
|
|
|
|
* order to run properly. Dependencies must be added before the file that
|
|
|
|
* depends on them.
|
|
|
|
*
|
|
|
|
* Circular dependencies are not supported, nor should they be.
|
|
|
|
*
|
2013-12-20 01:11:26 -05:00
|
|
|
* Copyright (C) 2011, 2013 Mike Gerwitz
|
2011-08-14 17:05:37 -04:00
|
|
|
*
|
2013-12-22 09:37:21 -05:00
|
|
|
* This file is part of GNU ease.js.
|
2011-08-14 17:05:37 -04:00
|
|
|
*
|
|
|
|
* ease.js is free software: you can redistribute it and/or modify it under the
|
Relicensed under the GPLv3+
This project was originally LGPLv+-licensed to encourage its use in a community
that is largely copyleft-phobic. After further reflection, that was a mistake,
as adoption is not the important factor here---software freedom is.
When submitting ease.js to the GNU project, it was asked if I would be willing
to relicense it under the GPLv3+; I agreed happily, because there is no reason
why we should provide proprietary software any sort of edge. Indeed, proprietary
JavaScript is a huge problem since it is automatically downloaded on the user's
PC generally without them even knowing, and is a current focus for the FSF. As
such, to remain firm in our stance against proprietary JavaScript, relicensing
made the most sense for GNU.
This is likely to upset current users of ease.js. I am not sure of their
number---I have only seen download counts periodically on npmjs.org---but I know
there are at least a small number. These users are free to continue using the
previous LGPL'd releases, but with the understanding that there will be no
further maintenance (not even bug fixes). If possible, users should use the
GPL-licensed versions and release their software as free software.
Here comes GNU ease.js.
2013-12-20 01:00:35 -05:00
|
|
|
* terms of the GNU General Public License as published by the Free Software
|
|
|
|
* Foundation, either version 3 of the License, or (at your option) any later
|
|
|
|
* version.
|
2011-08-14 17:05:37 -04:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
Relicensed under the GPLv3+
This project was originally LGPLv+-licensed to encourage its use in a community
that is largely copyleft-phobic. After further reflection, that was a mistake,
as adoption is not the important factor here---software freedom is.
When submitting ease.js to the GNU project, it was asked if I would be willing
to relicense it under the GPLv3+; I agreed happily, because there is no reason
why we should provide proprietary software any sort of edge. Indeed, proprietary
JavaScript is a huge problem since it is automatically downloaded on the user's
PC generally without them even knowing, and is a current focus for the FSF. As
such, to remain firm in our stance against proprietary JavaScript, relicensing
made the most sense for GNU.
This is likely to upset current users of ease.js. I am not sure of their
number---I have only seen download counts periodically on npmjs.org---but I know
there are at least a small number. These users are free to continue using the
previous LGPL'd releases, but with the understanding that there will be no
further maintenance (not even bug fixes). If possible, users should use the
GPL-licensed versions and release their software as free software.
Here comes GNU ease.js.
2013-12-20 01:00:35 -05:00
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
|
|
* more details.
|
2011-08-14 17:05:37 -04:00
|
|
|
*
|
Relicensed under the GPLv3+
This project was originally LGPLv+-licensed to encourage its use in a community
that is largely copyleft-phobic. After further reflection, that was a mistake,
as adoption is not the important factor here---software freedom is.
When submitting ease.js to the GNU project, it was asked if I would be willing
to relicense it under the GPLv3+; I agreed happily, because there is no reason
why we should provide proprietary software any sort of edge. Indeed, proprietary
JavaScript is a huge problem since it is automatically downloaded on the user's
PC generally without them even knowing, and is a current focus for the FSF. As
such, to remain firm in our stance against proprietary JavaScript, relicensing
made the most sense for GNU.
This is likely to upset current users of ease.js. I am not sure of their
number---I have only seen download counts periodically on npmjs.org---but I know
there are at least a small number. These users are free to continue using the
previous LGPL'd releases, but with the understanding that there will be no
further maintenance (not even bug fixes). If possible, users should use the
GPL-licensed versions and release their software as free software.
Here comes GNU ease.js.
2013-12-20 01:00:35 -05:00
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
2011-08-14 17:05:37 -04:00
|
|
|
*
|
|
|
|
* @author Mike Gerwitz
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// files and their dependencies are expected from stdin in the following format,
|
|
|
|
// one relationship per line:
|
|
|
|
// file dep
|
|
|
|
getStdinData( function( data )
|
|
|
|
{
|
|
|
|
var ordered = [],
|
|
|
|
deps = parseLines( data ),
|
|
|
|
current = ''
|
|
|
|
;
|
|
|
|
|
|
|
|
// Continue the ordering process until there are no more files remaining.
|
|
|
|
// This is necessary because not all files may be a dependency of another.
|
|
|
|
// There may be groups of completely unrelated files.
|
|
|
|
while ( current = Object.keys( deps )[0] )
|
|
|
|
{
|
|
|
|
orderDeps( deps, current, ordered );
|
|
|
|
}
|
|
|
|
|
|
|
|
outputFiles( ordered );
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Output each file, one per line
|
|
|
|
*
|
|
|
|
* @param {Array.<string>} files files to output
|
|
|
|
*
|
|
|
|
* @return {undefined}
|
|
|
|
*/
|
|
|
|
function outputFiles( files )
|
|
|
|
{
|
|
|
|
files.forEach( function( file )
|
|
|
|
{
|
|
|
|
console.log( file );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recursively order dependencies for each file
|
|
|
|
*
|
|
|
|
* For each file (current var), loop through each of its dependencies. Before
|
|
|
|
* adding itself to the list, it will recurse and loop through the dependency's
|
|
|
|
* dependencies. This process will continue until no more dependencies are
|
|
|
|
* found or found dependencies have already been parsed. This will result in the
|
|
|
|
* file being added to the list after each of its dependencies, recursively. It
|
|
|
|
* may be easier just to read the actual code.
|
|
|
|
*
|
|
|
|
* Circular dependencies are not supported, but they are detected and will
|
|
|
|
* cause termination of the script with a non-zero exit code.
|
|
|
|
*
|
|
|
|
* @param {Object} deps dependency list
|
|
|
|
* @param {string} current file to parse
|
|
|
|
* @param {Array} ordered destination array
|
|
|
|
*
|
|
|
|
* @return {Array} ordered array
|
|
|
|
*/
|
|
|
|
var orderDeps = ( function()
|
|
|
|
{
|
|
|
|
var processed = {},
|
|
|
|
processing = {};
|
|
|
|
|
|
|
|
return function orderDeps( deps, current, ordered )
|
|
|
|
{
|
|
|
|
// if we've already processed this dependency, don't do it again
|
|
|
|
if ( processed[ current ] )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// prevent infinite recursion that would be caused by circular
|
|
|
|
// dependencies
|
|
|
|
if ( processing[ current ] )
|
|
|
|
{
|
|
|
|
console.error( "Circular dependency detected: %s", current );
|
|
|
|
process.exit( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
processing[ current ] = true;
|
|
|
|
|
|
|
|
// process each dependency for this file
|
|
|
|
( deps[ current ] || [] ).forEach( function( dep )
|
|
|
|
{
|
|
|
|
// first, insert dependencies of our dependency
|
|
|
|
orderDeps( deps, dep, ordered );
|
|
|
|
} );
|
|
|
|
|
|
|
|
// add self /after/ dependencies have been added
|
|
|
|
ordered.push( current );
|
|
|
|
processed[ current ] = true;
|
|
|
|
|
|
|
|
// ensure we don't parse it again
|
|
|
|
delete deps[ current ];
|
|
|
|
delete processing[ current ];
|
|
|
|
|
|
|
|
return ordered;
|
|
|
|
};
|
|
|
|
} )();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse each line into a dependency list for each file
|
|
|
|
*
|
|
|
|
* @param {string} data string data to parse
|
|
|
|
*
|
|
|
|
* @return {Object.<Array.<string>>} dependency list for each file
|
|
|
|
*/
|
|
|
|
function parseLines( data )
|
|
|
|
{
|
|
|
|
var lines = data.split( '\n' ),
|
|
|
|
deps = {};
|
|
|
|
|
|
|
|
lines.forEach( function( line )
|
|
|
|
{
|
|
|
|
// skip blank lines
|
|
|
|
if ( !line )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var dep_info = line.split( ' ' ),
|
|
|
|
file = dep_info[ 0 ],
|
|
|
|
dep = dep_info[ 1 ]
|
|
|
|
;
|
|
|
|
|
|
|
|
deps[ file ] = deps[ file ] || [];
|
|
|
|
deps[ file ].push( dep );
|
|
|
|
} );
|
|
|
|
|
|
|
|
return deps;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Asynchronously retrieve data from stdin
|
|
|
|
*
|
|
|
|
* @param {function(Object)} callback to call with data
|
|
|
|
*
|
|
|
|
* @return {string} data from stdin
|
|
|
|
*/
|
|
|
|
function getStdinData( callback )
|
|
|
|
{
|
|
|
|
var data = '';
|
|
|
|
|
|
|
|
process.stdin.resume();
|
|
|
|
process.stdin.setEncoding( 'ascii' );
|
|
|
|
|
|
|
|
process.stdin
|
|
|
|
.on( 'data', function( chunk )
|
|
|
|
{
|
|
|
|
data += chunk;
|
|
|
|
} )
|
|
|
|
.on( 'end', function()
|
|
|
|
{
|
|
|
|
callback( data );
|
|
|
|
} )
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|