Replaced hard-coded, manually ordered module list with script (#25)
parent
fd95f38c87
commit
2d8e6d70a4
|
@ -28,11 +28,17 @@ TPL_TEST_PATH="$PATH_TOOLS/combine-test.tpl"
|
||||||
TPL_VAR='/**{CONTENT}**/'
|
TPL_VAR='/**{CONTENT}**/'
|
||||||
RMTRAIL="$PATH_TOOLS/rmtrail"
|
RMTRAIL="$PATH_TOOLS/rmtrail"
|
||||||
|
|
||||||
# order matters
|
# determine the order in which modules must be concatenated; order matters to
|
||||||
CAT_MODS="warn prop_parser util VisibilityObjectFactory"
|
# ensure dependencies are loaded before the module that depends on them
|
||||||
CAT_MODS="$CAT_MODS FallbackVisibilityObjectFactory member_builder"
|
CAT_MODULES=$(
|
||||||
CAT_MODS="$CAT_MODS ClassBuilder VisibilityObjectFactoryFactory"
|
cd "$PATH_TOOLS/../" &&
|
||||||
CAT_MODS="$CAT_MODS class class_final class_abstract interface"
|
grep -rIo ' require(.*)' lib/ \
|
||||||
|
| sed "s/^lib\///;s/\.js://;s/require(.*'\/\(.*\)'.*/\1/" \
|
||||||
|
| node tools/combine-order.js
|
||||||
|
) || {
|
||||||
|
echo "Failed to get module list" >&2
|
||||||
|
exit 3
|
||||||
|
}
|
||||||
|
|
||||||
##
|
##
|
||||||
# Output template header
|
# Output template header
|
||||||
|
@ -85,7 +91,7 @@ fi
|
||||||
tpl_header
|
tpl_header
|
||||||
|
|
||||||
# output each of the modules
|
# output each of the modules
|
||||||
for module in $CAT_MODS; do
|
for module in $CAT_MODULES; do
|
||||||
filename="$PATH_LIB/$module.$MODULE_EXT"
|
filename="$PATH_LIB/$module.$MODULE_EXT"
|
||||||
|
|
||||||
if [ ! -f "$filename" ]; then
|
if [ ! -f "$filename" ]; then
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Mike Gerwitz
|
||||||
|
*
|
||||||
|
* This file is part of ease.js.
|
||||||
|
*
|
||||||
|
* ease.js is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free
|
||||||
|
* Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* @author Mike Gerwitz
|
||||||
|
* @package tools
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// 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 );
|
||||||
|
} )
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue