255 lines
6.3 KiB
JavaScript
255 lines
6.3 KiB
JavaScript
|
|
function NixOS () {
|
|
var env = Components.classes["@mozilla.org/process/environment;1"].
|
|
getService(Components.interfaces.nsIEnvironment);
|
|
|
|
if (env.exists("NIXOS"))
|
|
this.nixos = env.get("NIXOS");
|
|
if (env.exists("NIXOS_CONFIG"))
|
|
this.config = env.get("NIXOS_CONFIG");
|
|
if (env.exists("NIXPKGS"))
|
|
this.nixpkgs = env.get("NIXPKGS");
|
|
if (env.exists("mountPoint"))
|
|
this.root = env.get("mountPoint");
|
|
if (env.exists("NIXOS_OPTION"))
|
|
this.optionBin = env.get("NIXOS_OPTION");
|
|
this.option = new Option("options", this, null);
|
|
};
|
|
|
|
NixOS.prototype = {
|
|
root: "",
|
|
nixos: "/etc/nixos/nixos",
|
|
nixpkgs: "/etc/nixos/nixpkgs",
|
|
config: "/etc/nixos/configuration.nix",
|
|
instantiateBin: "/run/current-system/sw/bin/nix-instantiate",
|
|
optionBin: "/run/current-system/sw/bin/nixos-option",
|
|
tmpFile: "nixos-gui",
|
|
option: null
|
|
};
|
|
|
|
function Option (name, context, parent) {
|
|
this.name = name;
|
|
this.context_ = context;
|
|
if (parent == null)
|
|
this.path = "";
|
|
else if (parent.path == "")
|
|
this.path = name;
|
|
else
|
|
this.path = parent.path + "." + name;
|
|
};
|
|
|
|
Option.prototype = {
|
|
load: function () {
|
|
var env = "";
|
|
env += "'NIXOS=" + this.context_.root + this.context_.nixos + "' ";
|
|
env += "'NIXOS_PKGS=" + this.context_.root + this.context_.nixpkgs + "' ";
|
|
env += "'NIXOS_CONFIG=" + this.context_.config + "' ";
|
|
var out = makeTempFile(this.context_.tmpFile);
|
|
var prog = this.context_.optionBin + " 2>&1 >" + out.path + " ";
|
|
var args = " --xml " + this.path;
|
|
|
|
runProgram(/*env + */ prog + args);
|
|
var xml = readFromFile(out);
|
|
out.remove(false);
|
|
|
|
// jQuery does a stack overflow when converting a huge XML to a DOM.
|
|
var dom = DOMParser().parseFromString(xml, "text/xml");
|
|
var xmlAttrs = $("expr > attrs > attr", dom);
|
|
|
|
this.isOption = xmlAttrs.first().attr("name") == "_isOption";
|
|
|
|
if (!this.isOption)
|
|
this.loadSubOptions(xmlAttrs);
|
|
else
|
|
this.loadOption(xmlAttrs);
|
|
this.isLoaded = true;
|
|
},
|
|
|
|
loadSubOptions: function (xmlAttrs) {
|
|
var cur = this;
|
|
var attrs = new Array();
|
|
|
|
xmlAttrs.each(
|
|
function (index) {
|
|
var name = $(this).attr("name");
|
|
var attr = new Option(name, cur.context_, cur);
|
|
attrs.push(attr);
|
|
}
|
|
);
|
|
|
|
this.subOptions = attrs;
|
|
},
|
|
|
|
optionAttributeMap: {
|
|
_isOption: function (cur, v) { },
|
|
value: function (cur, v) { cur.value = xml2nix($(v).children().first()); },
|
|
default: function (cur, v) { cur.defaultValue = xml2nix($(v).children().first()); },
|
|
example: function (cur, v) { cur.example = xml2nix($(v).children().first()); },
|
|
description: function (cur, v) { cur.description = this.string(v); },
|
|
typename: function (cur, v) { cur.typename = this.string(v); },
|
|
options: function (cur, v) { cur.loadSubOptions($("attrs", v).children()); },
|
|
declarations: function (cur, v) { cur.declarations = this.pathList(v); },
|
|
definitions: function (cur, v) { cur.definitions = this.pathList(v); },
|
|
|
|
string: function (v) {
|
|
return $(v).children("string").first().attr("value");
|
|
},
|
|
|
|
pathList: function (v) {
|
|
var list = [];
|
|
$(v).children("list").first().children().each(
|
|
function (idx) {
|
|
list.push($(this).attr("value"));
|
|
}
|
|
);
|
|
return list;
|
|
}
|
|
},
|
|
|
|
|
|
loadOption: function (attrs) {
|
|
var cur = this;
|
|
|
|
attrs.each(
|
|
function (index) {
|
|
var name = $(this).attr("name");
|
|
log("loadOption: " + name);
|
|
cur.optionAttributeMap[name](cur, this);
|
|
}
|
|
);
|
|
},
|
|
|
|
// keep the context under which this option has been used.
|
|
context_: null,
|
|
// name of the option.
|
|
name: "",
|
|
// result of nixos-option.
|
|
value: null,
|
|
typename: null,
|
|
defaultValue: null,
|
|
example: null,
|
|
description: "",
|
|
declarations: [],
|
|
definitions: [],
|
|
// path to reach this option
|
|
path: "",
|
|
|
|
// list of options accessible from here.
|
|
isLoaded: false,
|
|
isOption: false,
|
|
subOptions: []
|
|
};
|
|
|
|
var xml2nix_pptable = {
|
|
attrs: function (node, depth, pp) {
|
|
var children = node.children().not(
|
|
function () {
|
|
var name = $(this).attr("name");
|
|
return name.charAt(0) == "_";
|
|
}
|
|
);
|
|
var c = 0;
|
|
var out = "";
|
|
out += "{";
|
|
depth += 1;
|
|
children.each(
|
|
function (idx) {
|
|
c += 1;
|
|
out += pp.indent(depth);
|
|
out += pp.dispatch($(this), depth, pp);
|
|
}
|
|
);
|
|
depth -= 1;
|
|
if (c > 0)
|
|
out += this.indent(depth);
|
|
else
|
|
out += " ";
|
|
out += "}";
|
|
return out;
|
|
},
|
|
list: function (node, depth, pp) {
|
|
var children = node.children();
|
|
var c = 0;
|
|
var out = "";
|
|
out += "[";
|
|
depth += 1;
|
|
children.each(
|
|
function (idx) {
|
|
c += 1;
|
|
out += pp.indent(depth);
|
|
out += pp.dispatch($(this), depth, pp);
|
|
}
|
|
);
|
|
depth -= 1;
|
|
if (c > 0)
|
|
out += this.indent(depth);
|
|
else
|
|
out += " ";
|
|
out += "]";
|
|
return out;
|
|
},
|
|
attr: function (node, depth, pp) {
|
|
var name = node.attr("name");
|
|
var out = "";
|
|
var val = "";
|
|
out += name + " = ";
|
|
depth += 1;
|
|
val = pp.dispatch(node.children().first(), depth, pp);
|
|
out += val;
|
|
depth -= 1;
|
|
out += ";";
|
|
return out;
|
|
},
|
|
string: function (node, depth, pp) {
|
|
return "\"" + node.attr("value") + "\"";
|
|
},
|
|
path: function (node, depth, pp) {
|
|
return node.attr("value");
|
|
},
|
|
bool: function (node, depth, pp) {
|
|
return node.attr("value");
|
|
},
|
|
"int": function (node, depth, pp) {
|
|
return node.attr("value");
|
|
},
|
|
null: function (node, depth, pp) {
|
|
return "null";
|
|
},
|
|
derivation: function (node, depth, pp) {
|
|
return "<derivation>";
|
|
},
|
|
function: function (node, depth, pp) {
|
|
return "<function>";
|
|
},
|
|
unevaluated: function (node, depth, pp) {
|
|
return "<unevaluated>";
|
|
},
|
|
|
|
dispatch: function (node, depth, pp) {
|
|
for (var key in pp)
|
|
{
|
|
if(node.is(key))
|
|
{
|
|
// log(this.indent(depth) + "dispatch: " + key);
|
|
var out = pp[key](node, depth, pp);
|
|
// log(this.indent(depth) + "dispatch: => " + out);
|
|
return out;
|
|
}
|
|
}
|
|
return "<dispatch-error>";
|
|
},
|
|
indent: function (depth) {
|
|
var ret = "\n";
|
|
while (depth--)
|
|
ret += " ";
|
|
return ret;
|
|
}
|
|
};
|
|
|
|
function xml2nix(node) {
|
|
var depth = 0;
|
|
var pp = xml2nix_pptable;
|
|
var out = pp.dispatch(node, depth, pp);
|
|
// log("pretty:\n" + out);
|
|
return out;
|
|
}
|