lib/lmd_common.js
function (rawConfig, configFile, configDir, flagsNames, extraOptions, usedConfigs) {
    flagsNames = flagsNames || Object.keys(LMD_PLUGINS);

    var isFirstRun = typeof usedConfigs === "undefined";

    usedConfigs = usedConfigs || {};
    usedConfigs[configFile] = true; // mark config as used

    var configs = [],
        resultConfig = {
            modules: {},
            errors: [],
            plugins_depends: {}
        };

    if (extraOptions && extraOptions.mixins) {
        rawConfig = mergeMixins(rawConfig, extraOptions.mixins);
    }

    if (extraOptions && extraOptions.styles) {
        rawConfig = deepDestructableMerge(rawConfig, {
            styles: extraOptions.styles
        });
    }

    // collect modules and module options
    var modules = collectModules(rawConfig, configDir);
    if (rawConfig.depends) {
        var /*dependsMask = rawConfig.depends === true ? DEFAULT_DEPENDS_MASK : rawConfig.depends,*/
            dependsConfigPath,
            dependsMask;
        for (var moduleName in modules) {
            if (!modules[moduleName].is_shortcut && !modules[moduleName].is_ignored) {
                dependsMask = modules[moduleName].depends;
                dependsConfigPath = getDependsConfigOf(modules[moduleName].path, dependsMask);
                dependsConfigPath.forEach(function (dependsConfigPath) {
                    if (fileExists(dependsConfigPath)) {
                        if (!usedConfigs[dependsConfigPath]) {
                            configs.unshift({
                                context: 'depends config **' + dependsConfigPath + '**',
                                config: assembleLmdConfig(dependsConfigPath, flagsNames, null, usedConfigs)
                            });
                        }
                    }
                });
            }
        }
    }

    // extend parent config
    if (typeof rawConfig['extends'] === "string") {
        var parentConfigFile = fs.realpathSync(configDir + '/' + rawConfig['extends']);
        if (!usedConfigs[parentConfigFile]) {
            var parentConfig = assembleLmdConfig(parentConfigFile, flagsNames, null, usedConfigs);
        }
    }

    var processedConfig = {
        modules: modules,
        styles: collectStyles(rawConfig, configDir),
        bundles: collectBundles(rawConfig, configDir),
        plugins: collectUserPlugins(rawConfig, configDir)
    };

    // keep fields
    MASTER_FIELDS.forEach(function (fieldName) {
        processedConfig[fieldName] = rawConfig[fieldName];
        if (FILED_ALIASES.hasOwnProperty(fieldName)) {
            processedConfig[FILED_ALIASES[fieldName]] = rawConfig[fieldName];
        }
    });

    // keep flags
    flagsNames.forEach(function (fieldName) {
        processedConfig[fieldName] = rawConfig[fieldName];
    });

    if (parentConfig) {
        mergeConfigs(resultConfig, parentConfig, flagsNames, INHERITABLE_FIELDS, true, 'parent config **' + parentConfigFile + '**');
    }

    for (var i = 0, c = configs.length, dependsMainModuleName; i < c; i++) {
        // Cleanup main module from depends
        dependsMainModuleName = configs[i].config.main || "main";
        if (configs[i].config.modules) {
            delete configs[i].config.modules[dependsMainModuleName];
        }
        mergeConfigs(resultConfig, configs[i].config, flagsNames, [], false, configs[i].context);
    }

    mergeConfigs(resultConfig, processedConfig, flagsNames, MASTER_FIELDS, true, 'main config **' + configFile + '**');

    if (isFirstRun) {
        // Apply mixins
        var mixins = resultConfig.mixins;
        if (Array.isArray(mixins)) {
            mixins.forEach(function (mixinName) {
                var mixinConfigFile = fs.realpathSync(configDir + '/' + mixinName),
                    processedMixin = assembleLmdConfig(mixinConfigFile, flagsNames, null, usedConfigs);

                mergeConfigs(resultConfig, processedMixin, flagsNames, INHERITABLE_FIELDS, true, 'mixin config **' + mixinConfigFile + '**');
            });
        }
        if (extraOptions) {
            extraOptions.modules = collectModules(extraOptions, configDir);
            extraOptions.bundles = collectBundles(extraOptions, configDir);
            extraOptions.styles = collectStyles(extraOptions, configDir);
            mergeConfigs(resultConfig, extraOptions, flagsNames, EXTRA_OPTIONS_FIELDS, true, 'CLI options');
        }
        reapplyModuleOptions(resultConfig);
        addPluginsFromBundles(resultConfig);
        addPluginsDepends(resultConfig);
        flattenBundles(resultConfig);
        resolveStyles(resultConfig);
        bundlesInheritFieldsFromPackage(resultConfig);
        removeIgnoredModules(resultConfig);
    }
    return resultConfig;
}
function (rawConfig, configFile, configDir, flagsNames, extraOptions, usedConfigs) {
    flagsNames = flagsNames || Object.keys(LMD_PLUGINS);

    var isFirstRun = typeof usedConfigs === "undefined";

    usedConfigs = usedConfigs || {};
    usedConfigs[configFile] = true; // mark config as used

    var configs = [],
        resultConfig = {
            modules: {},
            errors: [],
            plugins_depends: {}
        };

    if (extraOptions && extraOptions.mixins) {
        rawConfig = mergeMixins(rawConfig, extraOptions.mixins);
    }

    if (extraOptions && extraOptions.styles) {
        rawConfig = deepDestructableMerge(rawConfig, {
            styles: extraOptions.styles
        });
    }

    // collect modules and module options
    var modules = collectModules(rawConfig, configDir);
    if (rawConfig.depends) {
        var /*dependsMask = rawConfig.depends === true ? DEFAULT_DEPENDS_MASK : rawConfig.depends,*/
            dependsConfigPath,
            dependsMask;
        for (var moduleName in modules) {
            if (!modules[moduleName].is_shortcut && !modules[moduleName].is_ignored) {
                dependsMask = modules[moduleName].depends;
                dependsConfigPath = getDependsConfigOf(modules[moduleName].path, dependsMask);
                dependsConfigPath.forEach(function (dependsConfigPath) {
                    if (fileExists(dependsConfigPath)) {
                        if (!usedConfigs[dependsConfigPath]) {
                            configs.unshift({
                                context: 'depends config **' + dependsConfigPath + '**',
                                config: assembleLmdConfig(dependsConfigPath, flagsNames, null, usedConfigs)
                            });
                        }
                    }
                });
            }
        }
    }

    // extend parent config
    if (typeof rawConfig['extends'] === "string") {
        var parentConfigFile = fs.realpathSync(configDir + '/' + rawConfig['extends']);
        if (!usedConfigs[parentConfigFile]) {
            var parentConfig = assembleLmdConfig(parentConfigFile, flagsNames, null, usedConfigs);
        }
    }

    var processedConfig = {
        modules: modules,
        styles: collectStyles(rawConfig, configDir),
        bundles: collectBundles(rawConfig, configDir),
        plugins: collectUserPlugins(rawConfig, configDir)
    };

    // keep fields
    MASTER_FIELDS.forEach(function (fieldName) {
        processedConfig[fieldName] = rawConfig[fieldName];
        if (FILED_ALIASES.hasOwnProperty(fieldName)) {
            processedConfig[FILED_ALIASES[fieldName]] = rawConfig[fieldName];
        }
    });

    // keep flags
    flagsNames.forEach(function (fieldName) {
        processedConfig[fieldName] = rawConfig[fieldName];
    });

    if (parentConfig) {
        mergeConfigs(resultConfig, parentConfig, flagsNames, INHERITABLE_FIELDS, true, 'parent config **' + parentConfigFile + '**');
    }

    for (var i = 0, c = configs.length, dependsMainModuleName; i < c; i++) {
        // Cleanup main module from depends
        dependsMainModuleName = configs[i].config.main || "main";
        if (configs[i].config.modules) {
            delete configs[i].config.modules[dependsMainModuleName];
        }
        mergeConfigs(resultConfig, configs[i].config, flagsNames, [], false, configs[i].context);
    }

    mergeConfigs(resultConfig, processedConfig, flagsNames, MASTER_FIELDS, true, 'main config **' + configFile + '**');

    if (isFirstRun) {
        // Apply mixins
        var mixins = resultConfig.mixins;
        if (Array.isArray(mixins)) {
            mixins.forEach(function (mixinName) {
                var mixinConfigFile = fs.realpathSync(configDir + '/' + mixinName),
                    processedMixin = assembleLmdConfig(mixinConfigFile, flagsNames, null, usedConfigs);

                mergeConfigs(resultConfig, processedMixin, flagsNames, INHERITABLE_FIELDS, true, 'mixin config **' + mixinConfigFile + '**');
            });
        }
        if (extraOptions) {
            extraOptions.modules = collectModules(extraOptions, configDir);
            extraOptions.bundles = collectBundles(extraOptions, configDir);
            extraOptions.styles = collectStyles(extraOptions, configDir);
            mergeConfigs(resultConfig, extraOptions, flagsNames, EXTRA_OPTIONS_FIELDS, true, 'CLI options');
        }
        reapplyModuleOptions(resultConfig);
        addPluginsFromBundles(resultConfig);
        addPluginsDepends(resultConfig);
        flattenBundles(resultConfig);
        resolveStyles(resultConfig);
        bundlesInheritFieldsFromPackage(resultConfig);
        removeIgnoredModules(resultConfig);
    }
    return resultConfig;
}
function ( rawConfig , configFile , configDir , flagsNames , extraOptions , usedConfigs ) { flagsNames = flagsNames || Object . keys ( LMD_PLUGINS ) ; var isFirstRun = typeof usedConfigs === "undefined" ; usedConfigs = usedConfigs || { } ; usedConfigs [ configFile ] = true ; // mark config as used var configs = [ ] , resultConfig = { modules : { } , errors : [ ] , plugins_depends : { } } ; if ( extraOptions && extraOptions . mixins ) { rawConfig = mergeMixins ( rawConfig , extraOptions . mixins ) ; } if ( extraOptions && extraOptions . styles ) { rawConfig = deepDestructableMerge ( rawConfig , { styles : extraOptions . styles } ) ; } // collect modules and module options var modules = collectModules ( rawConfig , configDir ) ; if ( rawConfig . depends ) { var /*dependsMask = rawConfig.depends === true ? DEFAULT_DEPENDS_MASK : rawConfig.depends,*/ dependsConfigPath , dependsMask ; for ( var moduleName in modules ) { if ( ! modules [ moduleName ] . is_shortcut && ! modules [ moduleName ] . is_ignored ) { dependsMask = modules [ moduleName ] . depends ; dependsConfigPath = getDependsConfigOf ( modules [ moduleName ] . path , dependsMask ) ; dependsConfigPath . forEach ( function ( dependsConfigPath ) { if ( fileExists ( dependsConfigPath ) ) { if ( ! usedConfigs [ dependsConfigPath ] ) { configs . unshift ( { context : 'depends config **' + dependsConfigPath + '**' , config : assembleLmdConfig ( dependsConfigPath , flagsNames , null , usedConfigs ) } ) ; } } } ) ; } } } // extend parent config if ( typeof rawConfig [ 'extends' ] === "string" ) { var parentConfigFile = fs . realpathSync ( configDir + '/' + rawConfig [ 'extends' ] ) ; if ( ! usedConfigs [ parentConfigFile ] ) { var parentConfig = assembleLmdConfig ( parentConfigFile , flagsNames , null , usedConfigs ) ; } } var processedConfig = { modules : modules , styles : collectStyles ( rawConfig , configDir ) , bundles : collectBundles ( rawConfig , configDir ) , plugins : collectUserPlugins ( rawConfig , configDir ) } ; // keep fields MASTER_FIELDS . forEach ( function ( fieldName ) { processedConfig [ fieldName ] = rawConfig [ fieldName ] ; if ( FILED_ALIASES . hasOwnProperty ( fieldName ) ) { processedConfig [ FILED_ALIASES [ fieldName ] ] = rawConfig [ fieldName ] ; } } ) ; // keep flags flagsNames . forEach ( function ( fieldName ) { processedConfig [ fieldName ] = rawConfig [ fieldName ] ; } ) ; if ( parentConfig ) { mergeConfigs ( resultConfig , parentConfig , flagsNames , INHERITABLE_FIELDS , true , 'parent config **' + parentConfigFile + '**' ) ; } for ( var i = 0 , c = configs . length , dependsMainModuleName ; i < c ; i ++ ) { // Cleanup main module from depends dependsMainModuleName = configs [ i ] . config . main || "main" ; if ( configs [ i ] . config . modules ) { delete configs [ i ] . config . modules [ dependsMainModuleName ] ; } mergeConfigs ( resultConfig , configs [ i ] . config , flagsNames , [ ] , false , configs [ i ] . context ) ; } mergeConfigs ( resultConfig , processedConfig , flagsNames , MASTER_FIELDS , true , 'main config **' + configFile + '**' ) ; if ( isFirstRun ) { // Apply mixins var mixins = resultConfig . mixins ; if ( Array . isArray ( mixins ) ) { mixins . forEach ( function ( mixinName ) { var mixinConfigFile = fs . realpathSync ( configDir + '/' + mixinName ) , processedMixin = assembleLmdConfig ( mixinConfigFile , flagsNames , null , usedConfigs ) ; mergeConfigs ( resultConfig , processedMixin , flagsNames , INHERITABLE_FIELDS , true , 'mixin config **' + mixinConfigFile + '**' ) ; } ) ; } if ( extraOptions ) { extraOptions . modules = collectModules ( extraOptions , configDir ) ; extraOptions . bundles = collectBundles ( extraOptions , configDir ) ; extraOptions . styles = collectStyles ( extraOptions , configDir ) ; mergeConfigs ( resultConfig , extraOptions , flagsNames , EXTRA_OPTIONS_FIELDS , true , 'CLI options' ) ; } reapplyModuleOptions ( resultConfig ) ; addPluginsFromBundles ( resultConfig ) ; addPluginsDepends ( resultConfig ) ; flattenBundles ( resultConfig ) ; resolveStyles ( resultConfig ) ; bundlesInheritFieldsFromPackage ( resultConfig ) ; removeIgnoredModules ( resultConfig ) ; } return resultConfig ; }
Creates LMD config: applies depends and extends

@param {Object}   rawConfig
@param {String}   configFile
@param {String}   configDir
@param {String[]} [flagsNames]
@param {Object}   [extraOptions]
@param {Object}   [usedConfigs]

@return {Object}
Creates LMD config : applies depends and extends