Initial commit
commit
7da080b8c3
@ -0,0 +1,2 @@
|
||||
/node_modules/
|
||||
/lib/
|
@ -0,0 +1 @@
|
||||
/node_modules/
|
@ -0,0 +1,29 @@
|
||||
# drv
|
||||
|
||||
A Nix `.drv` file parser.
|
||||
|
||||
## License
|
||||
|
||||
[WTFPL](http://www.wtfpl.net/txt/copying/) or [CC0](https://creativecommons.org/publicdomain/zero/1.0/), whichever you prefer. A donation and/or attribution are appreciated, but not required.
|
||||
|
||||
## Donate
|
||||
|
||||
Maintaining open-source projects takes a lot of time, and the more donations I receive, the more time I can dedicate to open-source. If this module is useful to you, consider [making a donation](http://cryto.net/~joepie91/donate.html)!
|
||||
|
||||
You can donate using Bitcoin, PayPal, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else. Thank you!
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the files in `src/`, not those in `lib/`.
|
||||
|
||||
Build tool of choice is `gulp`; simply run `gulp` while developing, and it will watch for changes.
|
||||
|
||||
Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.
|
||||
|
||||
## Usage
|
||||
|
||||
TODO
|
||||
|
||||
## API
|
||||
|
||||
TODO
|
@ -0,0 +1,32 @@
|
||||
const gulp = require('gulp');
|
||||
|
||||
const presetES2015 = require("@joepie91/gulp-preset-es2015");
|
||||
const presetPegjs = require("@joepie91/gulp-preset-pegjs")
|
||||
|
||||
let sources = {
|
||||
babel: ["src/**/*.js"],
|
||||
pegjs: ["src/**/*.pegjs"]
|
||||
}
|
||||
|
||||
gulp.task('babel', function() {
|
||||
return gulp.src(sources.babel)
|
||||
.pipe(presetES2015({
|
||||
basePath: __dirname
|
||||
}))
|
||||
.pipe(gulp.dest("lib/"));
|
||||
});
|
||||
|
||||
gulp.task('pegjs', function() {
|
||||
return gulp.src(sources.pegjs)
|
||||
.pipe(presetPegjs({
|
||||
basePath: __dirname
|
||||
}))
|
||||
.pipe(gulp.dest("lib/"));
|
||||
})
|
||||
|
||||
gulp.task('watch', function () {
|
||||
gulp.watch(sources.babel, ['babel']);
|
||||
gulp.watch(sources.pegjs, ['pegjs']);
|
||||
});
|
||||
|
||||
gulp.task('default', ['pegjs', 'babel', 'watch']);
|
@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = require("./lib");
|
@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "drv",
|
||||
"version": "1.0.0",
|
||||
"description": "Nix .drv file parser",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "http://git.cryto.net/joepie91/node-drv.git"
|
||||
},
|
||||
"keywords": [
|
||||
"nix",
|
||||
"nixos",
|
||||
"drv",
|
||||
"derive",
|
||||
"derivation",
|
||||
"parser"
|
||||
],
|
||||
"author": "Sven Slootweg",
|
||||
"license": "WTFPL",
|
||||
"devDependencies": {
|
||||
"@joepie91/gulp-preset-es2015": "^1.0.1",
|
||||
"@joepie91/gulp-preset-pegjs": "^1.0.0",
|
||||
"babel-preset-es2015": "^6.6.0",
|
||||
"gulp": "^3.9.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
start
|
||||
= deriveTag
|
||||
|
||||
value
|
||||
= deriveTag
|
||||
/ array
|
||||
/ tuple
|
||||
/ string
|
||||
|
||||
multipleItems
|
||||
= item:value subsequentItems:("," value)* { return [item].concat(subsequentItems.map(subsequentItem => subsequentItem[1])); }
|
||||
|
||||
deriveTag
|
||||
= "Derive(" items:multipleItems ")" { return {type: "deriveTag", items: items}; }
|
||||
|
||||
array
|
||||
= "[" items:multipleItems "]" { return {type: "array", items: items}; }
|
||||
|
||||
tuple
|
||||
= "(" items:multipleItems ")" { return {type: "tuple", items: items}; }
|
||||
|
||||
string
|
||||
= '"' chars:stringCharacter* '"' { return chars.join(""); }
|
||||
|
||||
stringCharacter
|
||||
= !('"' / "\\") char:. { return char; }
|
||||
/ stringEscapedQuote { return '"'; }
|
||||
|
||||
stringEscapedQuote
|
||||
= '\\"'
|
@ -0,0 +1,84 @@
|
||||
'use strict';
|
||||
|
||||
const drvParser = require("./drv");
|
||||
|
||||
function valueType(value) {
|
||||
if (typeof value === "string") {
|
||||
return "string";
|
||||
} else {
|
||||
return value.type;
|
||||
}
|
||||
}
|
||||
|
||||
function assertType(value, expectedType) {
|
||||
if (valueType(value) == null) {
|
||||
throw new Error(`Expected a '${expectedType}', got nothing`);
|
||||
} else if (valueType(value) !== expectedType) {
|
||||
throw new Error(`Expected a '${expectedType}', got '${valueType(value)}'`);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function assertedValue(type, value) {
|
||||
if (assertType(value, type)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
function mapArray(array, callback) {
|
||||
return assertedValue("array", array).items.map(callback);
|
||||
}
|
||||
|
||||
function mapTuple(tuple, fields, callback) {
|
||||
return assertedValue("tuple", tuple).items.reduce((result, item, i) => {
|
||||
if (fields[i] != null) {
|
||||
let value;
|
||||
|
||||
if (callback != null) {
|
||||
value = callback(item, i);
|
||||
} else {
|
||||
value = item;
|
||||
}
|
||||
|
||||
result[fields[i]] = value;
|
||||
return result;
|
||||
} else {
|
||||
throw new Error(`Attempted to map field ${i}, but only ${fields.length} field names were specified`);
|
||||
}
|
||||
}, {});
|
||||
}
|
||||
|
||||
function parseDerivation(text) {
|
||||
let root = parseAST(text);
|
||||
|
||||
return {
|
||||
outputs: mapArray(root.items[0], (item) => {
|
||||
return mapTuple(item, ["name", "path", "hashAlgorithm", "hash"]);
|
||||
}),
|
||||
inputDerivations: mapArray(root.items[1], (item) => {
|
||||
return mapTuple(item, ["path", "inputDerivations"], (value, i) => {
|
||||
if (i === 1) {
|
||||
/* An `array` of inputDerivations */
|
||||
return value.items;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}),
|
||||
inputSources: assertedValue("array", root.items[2]).items,
|
||||
platform: assertedValue("string", root.items[3]),
|
||||
builder: assertedValue("string", root.items[4]),
|
||||
builderArguments: assertedValue("array", root.items[5]).items,
|
||||
environmentVariables: mapArray(root.items[6], (item) => {
|
||||
return mapTuple(item, ["name", "value"]);
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
function parseAST(text) {
|
||||
return drvParser.parse(text);
|
||||
}
|
||||
|
||||
parseDerivation.ast = parseAST;
|
||||
module.exports = parseDerivation;
|
@ -0,0 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const util = require("util");
|
||||
const parse = require("./lib");
|
||||
|
||||
let testDerivation = 'Derive([("dev","/nix/store/lpwm4gcsda53g26jp6rxz4x13l8lywzg-libXdmcp-1.1.2-dev","",""),("doc","/nix/store/y8925a01zwzrw0sakpv066bc4m6b2qj5-libXdmcp-1.1.2-doc","",""),("out","/nix/store/3iq0cd1ll0c7hss8xxgalxqn0jm0b2mi-libXdmcp-1.1.2","","")],[("/nix/store/3l3gnqvlwrmiqdma5vg3zibkabv4d6wh-pkg-config-0.29.drv",["out"]),("/nix/store/6qrlismj26hncj3809k302z6d3ycfwhh-stdenv.drv",["out"]),("/nix/store/flyb4cyxz0s48iq8qcdxdf2bcmgcc4cq-bash-4.3-p48.drv",["out"]),("/nix/store/pm59fc4bwblygsfxbq5dr72lkg7wxwsi-libXdmcp-1.1.2.tar.bz2.drv",["out"]),("/nix/store/w3qvvackybwaq6d2sw58yacsrbbrxa4b-xproto-7.0.29.drv",["out"])],["/nix/store/zsi9kk33hj7kvjfw0zahpdsiggg58nn4-builder.sh"],"x86_64-linux","/nix/store/gabjbkwga2dhhp2wzyaxl83r8hjjfc37-bash-4.3-p48/bin/bash",["-e","/nix/store/zsi9kk33hj7kvjfw0zahpdsiggg58nn4-builder.sh"],[("buildInputs",""),("builder","/nix/store/gabjbkwga2dhhp2wzyaxl83r8hjjfc37-bash-4.3-p48/bin/bash"),("dev","/nix/store/lpwm4gcsda53g26jp6rxz4x13l8lywzg-libXdmcp-1.1.2-dev"),("doc","/nix/store/y8925a01zwzrw0sakpv066bc4m6b2qj5-libXdmcp-1.1.2-doc"),("hardeningDisable","bindnow relro"),("name","libXdmcp-1.1.2"),("nativeBuildInputs","/nix/store/y419xb805psvlia6rl2jjrxmfsin5v63-pkg-config-0.29 /nix/store/cpy3mign235h3bjx63jz4baiislqznb9-xproto-7.0.29"),("out","/nix/store/3iq0cd1ll0c7hss8xxgalxqn0jm0b2mi-libXdmcp-1.1.2"),("outputs","out dev doc"),("propagatedBuildInputs",""),("propagatedNativeBuildInputs",""),("src","/nix/store/djf171kmvws6891q2nzd2icdjd5bgj4r-libXdmcp-1.1.2.tar.bz2"),("stdenv","/nix/store/985d95clq0216a6pcp3qzw4igp84ajvr-stdenv"),("system","x86_64-linux")])';
|
||||
|
||||
try {
|
||||
console.log(util.inspect(parse(testDerivation), {colors: true, depth: null}));
|
||||
} catch (err) {
|
||||
console.error(util.inspect(err, {colors: true}));
|
||||
}
|
Loading…
Reference in New Issue