You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.7 KiB
JavaScript

"use strict";
const Promise = require("bluebird");
const escapeStringRegexp = require("escape-string-regexp");
const execFileAsync = require("./exec-file-async");
function groupBySearchQuery(queries, results) {
let queryResults = {};
queries.forEach((query) => {
queryResults[query] = [];
});
results.forEach((result) => {
let found = false;
for (let query of queries) {
if (result.storePath.endsWith(query)) {
queryResults[query].push(result);
found = true;
break;
}
}
if (found === false) {
throw new Error(`Encountered result without matching query: ${result.storePath}`);
}
});
return queryResults;
}
module.exports = function nixLocate(libraries) {
return Promise.try(() => {
/* NOTE: This uses the regex capabilities of `nix-locate` to do a batch search; this is much, *much* faster than running `nix-locate` for each individual library. */
let combinedLibraries = libraries.map((query) => escapeStringRegexp(query)).join("|");
return execFileAsync("nix-locate", [
"--top-level",
"--whole-name",
"--at-root",
"--regex",
`/lib/(${combinedLibraries})`
]);
}).then(({ stdout, stderr }) => {
let results = stdout.split("\n").filter((line) => {
return (line.trim().length > 0);
}).map((line) => {
let match = /^(\S+)\s+([0-9,]+)\s+([a-z]+)\s+(.+)$/.exec(line);
if (match == null) {
throw new Error(`Encountered unexpected output from nix-locate: ${line}`);
} else {
let attribute = (match[1].endsWith(".out"))
? match[1].split(".").slice(0, -1).join(".")
: match[1];
return {
attribute: attribute,
storePath: match[4]
};
}
});
return groupBySearchQuery(libraries, results);
});
};