mirror of
https://github.com/flynx/features.js.git
synced 2025-10-29 10:20:09 +00:00
almost ready...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
c4e6e48756
commit
cad40b850e
117
features.js
117
features.js
@ -1019,7 +1019,7 @@ var FeatureSetProto = {
|
||||
// - if not ??? (XXX)
|
||||
// XXX should we report stuff here???
|
||||
// XXX TODO:
|
||||
// - resolve exclusive aliases and conflicts...
|
||||
// - wrapper to pass in applicability filter...
|
||||
_buildFeatureListReorder: function(lst, filter){
|
||||
var all = this.features
|
||||
lst = (lst == null || lst == '*') ? all : lst
|
||||
@ -1071,10 +1071,10 @@ var FeatureSetProto = {
|
||||
// normalize the list -- remove non-features and resolve aliases...
|
||||
.map(function(n){
|
||||
var f = that[n]
|
||||
// resolve exclusive tags...
|
||||
while(f == null && data.exclusive && n in data.exclusive){
|
||||
var n = data.exclusive[n][0]
|
||||
f = that[n]
|
||||
// exclusive tags...
|
||||
if(f == null && data.exclusive && n in data.exclusive){
|
||||
store[n] = null
|
||||
return false
|
||||
}
|
||||
// feature not defined or is not a feature...
|
||||
if(f == null){
|
||||
@ -1116,10 +1116,6 @@ var FeatureSetProto = {
|
||||
|
||||
// traverse down...
|
||||
expand(target, _lst, store, data, _seen.concat([f]))
|
||||
|
||||
// XXX makes sense to push the dep here -- at the tail of the recursion...
|
||||
data.list
|
||||
&& data.list.push(f)
|
||||
}
|
||||
})
|
||||
|
||||
@ -1143,22 +1139,30 @@ var FeatureSetProto = {
|
||||
// ...we need to do this on the build stage to include correct
|
||||
// deps and suggesntions...
|
||||
var exclusive = {}
|
||||
var rev_exclusive = {}
|
||||
all
|
||||
.filter(function(f){ return !!that[f].exclusive })
|
||||
.forEach(function(k){
|
||||
(that[k].exclusive || [])
|
||||
.forEach(function(e){
|
||||
exclusive[e] = (exclusive[e] || []).concat([k]) }) })
|
||||
exclusive[e] = (exclusive[e] || []).concat([k])
|
||||
rev_exclusive[k] = (rev_exclusive[k] || []).concat([e]) }) })
|
||||
|
||||
// XXX revise:
|
||||
// - should this be this depending on closure so much???
|
||||
var expandFeatures = function(lst, features){
|
||||
features = features || {}
|
||||
|
||||
// feature tree...
|
||||
var features = expand('depends', lst, {},
|
||||
{
|
||||
var expand_data = {
|
||||
loops: loops,
|
||||
disable_loops: disable_loops,
|
||||
disabled: disabled,
|
||||
disable_loops: disable_loops,
|
||||
missing: missing,
|
||||
exclusive: exclusive,
|
||||
})
|
||||
}
|
||||
|
||||
features = expand('depends', lst, features, expand_data)
|
||||
|
||||
// suggestion list...
|
||||
// ...this will be used to check if we need to break on missing
|
||||
@ -1167,33 +1171,89 @@ var FeatureSetProto = {
|
||||
//
|
||||
// NOTE: this stage does not track suggested feature dependencies...
|
||||
// NOTE: we do not need loop detection active here...
|
||||
var suggested = Object.keys(
|
||||
var s = Object.keys(
|
||||
expand('suggested', Object.keys(features), {}, { disabled: disabled }))
|
||||
.filter(function(f){ return !(f in features) })
|
||||
// get suggestion dependencies...
|
||||
suggested = expand('depends', suggested, {},
|
||||
// NOTE: we do not care bout missing here...
|
||||
s = expand('depends', s, {},
|
||||
{
|
||||
loops: loops,
|
||||
disabled: disabled,
|
||||
disable_loops: disable_loops,
|
||||
exclusive: exclusive,
|
||||
})
|
||||
Object.keys(suggested)
|
||||
Object.keys(s)
|
||||
.forEach(function(f){
|
||||
// keep only suggested features -- diff with features...
|
||||
if(f in features){
|
||||
delete suggested[f]
|
||||
delete s[f]
|
||||
|
||||
// mix suggested into features...
|
||||
} else {
|
||||
features[f] = suggested[f]
|
||||
features[f] = s[f]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// check/resolve for exclusivity conflicts and aliases...
|
||||
// XXX
|
||||
var features = {}
|
||||
expandFeatures(lst, features)
|
||||
|
||||
|
||||
// reverse dependencies -- who pulled who in... (index)
|
||||
// check for exclusivity conflicts and aliases...
|
||||
var conflicts = {}
|
||||
Object.keys(features)
|
||||
.forEach(function(f){
|
||||
// alias...
|
||||
while(f in exclusive){
|
||||
var candidates = (exclusive[f] || [])
|
||||
.filter(function(c){ return c in features })
|
||||
|
||||
// resolve alias to non-included feature...
|
||||
if(candidates.length == 0){
|
||||
var target = exclusive[f][0]
|
||||
|
||||
// expand target...
|
||||
expandFeatures([target], features)
|
||||
|
||||
// link alias to existing feature...
|
||||
} else {
|
||||
var target = candidates[0]
|
||||
}
|
||||
|
||||
// remove the alias...
|
||||
delete features[f]
|
||||
// replace dependencies...
|
||||
Object.keys(features)
|
||||
.forEach(function(e){
|
||||
var i = features[e].indexOf(f)
|
||||
i >= 0
|
||||
&& features[e].splice(i, 1, target)
|
||||
})
|
||||
f = target
|
||||
}
|
||||
|
||||
// exclusive feature...
|
||||
if(f in rev_exclusive){
|
||||
// XXX handle multiple groups... (???)
|
||||
var group = rev_exclusive[f]
|
||||
var candidates = (exclusive[group] || [])
|
||||
.filter(function(c){ return c in features })
|
||||
|
||||
if(!(group in conflicts) && candidates.length > 1){
|
||||
conflicts[group] = candidates
|
||||
}
|
||||
}
|
||||
})
|
||||
// resolve any conflicts found...
|
||||
Object.keys(conflicts)
|
||||
.forEach(function(group){
|
||||
// XXX is this how we decide which feature to keep???
|
||||
disabled = disabled.concat(conflicts[group].slice(1))})
|
||||
|
||||
|
||||
// reverse dependency index...
|
||||
// ...this is used to clear out orphaned features later and for
|
||||
// introspection...
|
||||
var rev_features = {}
|
||||
@ -1289,11 +1349,12 @@ var FeatureSetProto = {
|
||||
// NOTE: this requires the list to be ordered from high to low
|
||||
// priority, i.e. the same order they should be loaded in...
|
||||
// NOTE: dependency loops will throw this into and "infinite" loop...
|
||||
//
|
||||
// XXX need a better loop detection strategy...
|
||||
var loop_limit = list.length
|
||||
var loop_limit = list.length + 1
|
||||
do {
|
||||
var moves = 0
|
||||
if(list.length == 0){
|
||||
break
|
||||
}
|
||||
list
|
||||
.slice()
|
||||
.forEach(function(e){
|
||||
@ -1333,15 +1394,19 @@ var FeatureSetProto = {
|
||||
// report loop limit...
|
||||
loop_limit <= 0
|
||||
&& console.error('Hit loop limit while sorting dependencies!')
|
||||
// report conflicts...
|
||||
Object.keys(conflicts)
|
||||
.forEach(function(group){
|
||||
console.error('Exclusive "'+ group +'" conflict at:', conflicts[group]) })
|
||||
|
||||
|
||||
return {
|
||||
list: list,
|
||||
|
||||
suggested: Object.keys(suggested),
|
||||
features: features,
|
||||
rev_features: rev_features,
|
||||
exclusive: exclusive,
|
||||
conflicts: conflicts,
|
||||
missing: missing,
|
||||
loops: loops,
|
||||
filtered_out: filtered_out,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user