taler-util: set [PATH] defaults

This commit is contained in:
Florian Dold 2023-08-25 11:53:06 +02:00
parent 3d6cff9c84
commit 896841aec5
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
2 changed files with 128 additions and 20 deletions

View File

@ -170,6 +170,39 @@ const sandcastleCli = testingCli.subcommand("sandcastleArgs", "sandcastle", {
help: "Subcommands for handling GNU Taler sandcastle deployments.",
});
const configCli = testingCli.subcommand("configArgs", "config", {
help: "Subcommands for handling the Taler configuration.",
});
configCli.subcommand("show", "show").action(async (args) => {
const config = Configuration.load();
const cfgStr = config.stringify({
diagnostics: true,
});
console.log(cfgStr);
});
configCli
.subcommand("get", "get")
.requiredArgument("section", clk.STRING)
.requiredArgument("option", clk.STRING)
.flag("file", ["-f"])
.action(async (args) => {
const config = Configuration.load();
let res;
if (args.get.file) {
res = config.getString(args.get.section, args.get.option);
} else {
res = config.getPath(args.get.section, args.get.option);
}
if (res.isDefined()) {
console.log(res.value);
} else {
console.warn("not found");
process.exit(1);
}
});
const deploymentCli = testingCli.subcommand("deploymentArgs", "deployment", {
help: "Subcommands for handling GNU Taler deployments.",
});

View File

@ -1,6 +1,6 @@
/*
This file is part of GNU Taler
(C) 2020 Taler Systems S.A.
(C) 2020-2023 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
@ -40,12 +40,22 @@ export class ConfigError extends Error {
}
enum EntryOrigin {
// From a default file
Default = 1,
// Loaded from file or string
Loaded = 2,
// Changed after loading
Changed = 3,
/**
* From a default file.
*/
DefaultFile = 1,
/**
* From a system/installation specific default value.
*/
DefaultSystem = 2,
/**
* Loaded from file or string
*/
Loaded = 3,
/**
* Changed after loading
*/
Changed = 4,
}
interface Entry {
@ -169,12 +179,12 @@ export function pathsub(
const r = lookup(inner, depth + 1);
if (r !== undefined) {
s = s.substr(0, start) + r + s.substr(p + 1);
s = s.substring(0, start) + r + s.substring(p + 1);
l = start + r.length;
continue;
} else if (defaultValue !== undefined) {
const resolvedDefault = pathsub(defaultValue, lookup, depth + 1);
s = s.substr(0, start) + resolvedDefault + s.substr(p + 1);
s = s.substring(0, start) + resolvedDefault + s.substring(p + 1);
l = start + resolvedDefault.length;
continue;
}
@ -186,7 +196,7 @@ export function pathsub(
if (m && m[0]) {
const r = lookup(m[0], depth + 1);
if (r !== undefined) {
s = s.substr(0, l) + r + s.substr(l + 1 + m[0].length);
s = s.substring(0, l) + r + s.substring(l + 1 + m[0].length);
l = l + r.length;
continue;
}
@ -492,7 +502,9 @@ export class Configuration {
value: val,
sourceFile: opts.filename ?? "<unknown>",
sourceLine: lineNo,
origin: isDefaultSource ? EntryOrigin.Default : EntryOrigin.Loaded,
origin: isDefaultSource
? EntryOrigin.DefaultFile
: EntryOrigin.Loaded,
};
continue;
}
@ -535,6 +547,23 @@ export class Configuration {
};
}
/**
* Set a string value to a value from default locations.
*/
private setStringSystemDefault(
section: string,
option: string,
value: string,
): void {
const sec = this.provideSection(section);
sec.entries[option.toUpperCase()] = {
value,
sourceLine: 0,
sourceFile: "<unknown>",
origin: EntryOrigin.DefaultSystem,
};
}
/**
* Get upper-cased section names.
*/
@ -595,7 +624,7 @@ export class Configuration {
lookupVariable(x: string, depth: number = 0): string | undefined {
// We loop up options in PATHS in upper case, as option names
// are case insensitive
const val = this.findEntry("PATHS", x)?.value;
let val = this.findEntry("PATHS", x)?.value;
if (val !== undefined) {
return pathsub(val, (v, d) => this.lookupVariable(v, d), depth);
}
@ -623,21 +652,54 @@ export class Configuration {
}
private loadDefaults(): void {
let bc = process.env["TALER_BASE_CONFIG"];
if (!bc) {
let baseConfigDir = process.env["TALER_BASE_CONFIG"];
if (!baseConfigDir) {
/* Try to locate the configuration based on the location
* of the taler-config binary. */
const path = which("taler-config");
if (path) {
bc = nodejs_fs.realpathSync(
baseConfigDir = nodejs_fs.realpathSync(
nodejs_path.dirname(path) + "/../share/taler/config.d",
);
}
}
if (!bc) {
bc = "/usr/share/taler/config.d";
if (!baseConfigDir) {
baseConfigDir = "/usr/share/taler/config.d";
}
this.loadDefaultsFromDir(bc);
let installPrefix = process.env["TALER_PREFIX"];
if (!installPrefix) {
/* Try to locate install path based on the location
* of the taler-config binary. */
const path = which("taler-config");
if (path) {
installPrefix = nodejs_fs.realpathSync(
nodejs_path.dirname(path) + "/..",
);
}
}
if (!installPrefix) {
installPrefix = "/usr";
}
this.setStringSystemDefault(
"PATHS",
"LIBEXECDIR",
`${installPrefix}/taler/libexec/`,
);
this.setStringSystemDefault(
"PATHS",
"DOCDIR",
`${installPrefix}/share/doc/taler/`,
);
this.setStringSystemDefault("PATHS", "ICONDIR", `${installPrefix}/share/icons/`);
this.setStringSystemDefault("PATHS", "LOCALEDIR", `${installPrefix}/share/locale/`);
this.setStringSystemDefault("PATHS", "PREFIX", `${installPrefix}/`);
this.setStringSystemDefault("PATHS", "BINDIR", `${installPrefix}/bin`);
this.setStringSystemDefault("PATHS", "LIBDIR", `${installPrefix}/lib/taler/`);
this.setStringSystemDefault("PATHS", "DATADIR", `${installPrefix}/share/taler/`);
this.loadDefaultsFromDir(baseConfigDir);
}
getDefaultConfigFilename(): string | undefined {
@ -698,7 +760,11 @@ export class Configuration {
let headerWritten = false;
for (const optionName of Object.keys(sec.entries)) {
const entry = this.sectionMap[sectionName].entries[optionName];
if (opts.excludeDefaults && entry.origin === EntryOrigin.Default) {
if (
opts.excludeDefaults &&
(entry.origin === EntryOrigin.DefaultSystem ||
entry.origin === EntryOrigin.DefaultFile)
) {
continue;
}
if (!headerWritten) {
@ -711,7 +777,16 @@ export class Configuration {
}
if (entry !== undefined) {
if (opts.diagnostics) {
switch (entry.origin) {
case EntryOrigin.DefaultFile:
case EntryOrigin.Changed:
case EntryOrigin.Loaded:
s += `# ${entry.sourceFile}:${entry.sourceLine}\n`;
break;
case EntryOrigin.DefaultSystem:
s += `# (system/installation default)\n`;
break;
}
}
s += `${optionName} = ${entry.value}\n`;
}