mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 10:27:09 +00:00
174 lines
4.1 KiB
JavaScript
174 lines
4.1 KiB
JavaScript
const semver = require("semver");
|
|
const { exec } = require("child_process");
|
|
const { readFileSync } = require('fs');
|
|
const { pool } = require('./db/connection');
|
|
const { info } = require('./db');
|
|
const pkg = require("../package.json");
|
|
const { ALERT, ERROR, WARNING, NOTICE, INFO, DEBUG } = require('DOUGAL_ROOT/debug')(__filename);
|
|
|
|
|
|
function compatible () {
|
|
return Promise.all([
|
|
compatible_schema()
|
|
]);
|
|
}
|
|
|
|
/** Report whether the database schema version is
|
|
* compatible with the version required by this server.
|
|
*
|
|
* The current schema version is retrieved from the
|
|
* public.info table.
|
|
*
|
|
* The wanted version is retrieved from package.json
|
|
* (config.db_schema).
|
|
*
|
|
* @returns true if the versions are compatible,
|
|
* false otherwise.
|
|
*/
|
|
function compatible_schema () {
|
|
return new Promise ( async (resolve, reject) => {
|
|
const current = await schema_version();
|
|
const wanted = pkg.config.wanted.db_schema;
|
|
const component = "schema";
|
|
if (semver.satisfies(current, wanted)) {
|
|
resolve({current, wanted, component});
|
|
} else {
|
|
reject({current, wanted, component});
|
|
}
|
|
});
|
|
}
|
|
|
|
async function db_version () {
|
|
const client = await pool.connect();
|
|
let res;
|
|
try {
|
|
res = (await client.query("SELECT version(), PostGIS_Version();"))?.rows[0];
|
|
} catch (err) {
|
|
ERROR(err);
|
|
} finally {
|
|
client.release();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
async function os_version () {
|
|
try {
|
|
return Object.fromEntries(
|
|
readFileSync("/etc/os-release")
|
|
.toString("utf-8")
|
|
.split("\n")
|
|
.map(i =>
|
|
i.split("=", 2)
|
|
.map(i => i.replace(/^"|"$/g, ""))
|
|
)
|
|
.filter(i =>
|
|
["ID", "NAME", "PRETTY_NAME", "VERSION", "VERSION_ID"].includes(i[0])
|
|
)
|
|
);
|
|
} catch (err) {
|
|
ERROR(err);
|
|
}
|
|
}
|
|
|
|
async function schema_version () {
|
|
return await info.get(null, "version/db_schema");
|
|
}
|
|
|
|
/** Return software name.
|
|
*
|
|
*/
|
|
function app_name () {
|
|
return pkg.name ?? pkg.description ?? "Unknown";
|
|
}
|
|
|
|
/** Return software version, from Git if possible.
|
|
*
|
|
*/
|
|
async function describe () {
|
|
return new Promise( (resolve, reject) => {
|
|
const cmd = `git describe || echo git+$(git describe --always);`;
|
|
exec(cmd, {cwd: __dirname}, (error, stdout, stderr) => {
|
|
if (error) {
|
|
reject(error);
|
|
}
|
|
|
|
if (stdout) {
|
|
resolve(stdout.trim());
|
|
} else {
|
|
// Most likely not installed from Git, use the
|
|
// version number in package.json.
|
|
resolve(pkg.version ?? "Unknown")
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
/** Return version history, from git tags
|
|
*
|
|
*/
|
|
async function history (count=5, lines=15) {
|
|
return new Promise( (resolve, reject) => {
|
|
const separator2 = String(Math.random()).substring(2)+String(Math.random()).substring(2);
|
|
const separator1 = separator2.repeat(2);
|
|
const cmd = `for tag in $(git tag --sort=-version:refname |head -n ${count}); do printf "\n${separator1}\n"; echo "$tag"; printf "\n${separator2}\n"; git --no-pager tag -n${lines} "$tag"; done`;
|
|
|
|
exec(cmd, {cwd: __dirname}, (error, stdout, stderr) => {
|
|
if (error) {
|
|
reject(error);
|
|
}
|
|
|
|
if (stdout) {
|
|
const result = stdout
|
|
.split(separator1) // Separate each tag
|
|
.map(i => i.trim()) // Trim spaces
|
|
.filter(i => i) // Filter empty lines
|
|
.map(i => i // Now for each tag…
|
|
.split(separator2) // …separate the tag from the description
|
|
.map(i => i.trim()) // trim spaces in both
|
|
.filter( i => i) // and remove empty lines
|
|
)
|
|
|
|
resolve(Object.fromEntries(result));
|
|
// resolve(result.map( ([k, v]) => ({tag: k, notes: v}) ));
|
|
} else {
|
|
// Most likely not installed from Git, use the
|
|
// version number in package.json.
|
|
resolve()
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
function version_old () {
|
|
return pkg.version;
|
|
}
|
|
|
|
async function version () {
|
|
const name = app_name();
|
|
const server = pkg.version;
|
|
const tag = await describe();
|
|
const schema = await schema_version();
|
|
const db = await db_version();
|
|
const os = await os_version();
|
|
const compatibility = [
|
|
await compatible_schema()
|
|
]
|
|
|
|
return {
|
|
name,
|
|
server,
|
|
tag,
|
|
...pkg?.config?.versions,
|
|
schema,
|
|
db,
|
|
os,
|
|
compatibility
|
|
}
|
|
}
|
|
version.compatible = compatible;
|
|
version.name = app_name;
|
|
version.describe = describe;
|
|
version.history = history;
|
|
|
|
module.exports = version;
|