Bower seems to deviate from the semver spec in that I sometimes see dependencies that look like this (from 2klic-angular/bower.json):
"dependencies": {
"angulargrid": "s-yadav/angulargrid#^0.4.0"
}
This question goes a long way towards explaining semver itself but not so much what's going on with the s-yadav/angulargrid# portion.
Looking at bower/lib/node_modules/bower-endpoint-parser/index.js
I see the following code:
function decompose(endpoint) {
// Note that we allow spaces in targets and sources but they are trimmed
var regExp = /^(?:([\w\-]|(?:[\w\.\-]+[\w\-])?)=)?([^\|#]+)(?:#(.*))?$/;
var matches = endpoint.match(regExp);
var target;
var error;
if (!matches) {
error = new Error('Invalid endpoint: ' + endpoint);
error.code = 'EINVEND';
throw error;
}
target = trim(matches[3]);
return {
name: trim(matches[1]),
source: trim(matches[2]),
target: isWildcard(target) ? '*' : target
};
}
So it seems that a repository source can be specified as part of the dependency version using # as a delimiter.
However I've not been able to find anything that describes this in the bower docs.
Are there any other caveats to be aware of with Bowers interpretation of semver or is this the only one, and is it sufficient to split the string at # to find the requirement expression?
You can find the relevant code in bower/lib/node_modules/bower-endpoint-parser/index.js in json2decomposed
:
function json2decomposed(key, value) {
...
key = trim(key);
value = trim(value);
...
endpoint = key + '=';
split = value.split('#').map(trim);
// If # was found, the source was specified
if (split.length > 1) {
endpoint += (split[0] || key) + '#' + split[1];
// Check if value looks like a source
} else if (isSource(value)) {
endpoint += value + '#*';
// Otherwise use the key as the source
} else {
endpoint += key + '#' + split[0];
}
return decompose(endpoint);
}
So what later becomes the target
is generated by splitting the value from the JSON dependency array by #
. This target
is parsed by a resolver, so the actual behaviour depends on the resolver used, but the typical resolver uses node-semver, if node-semver can parse it. Otherwise it uses commit ids, branch names, tags etc.
So splitting the string by '#' and trimming whitespace afterwards is sufficient to find the requirements expression, but it may not be a semver version after all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With