1
0
mirror of https://github.com/locomotivemtl/locomotive-boilerplate.git synced 2026-01-15 00:55:08 +08:00

Improve asset versioning task

Added:
- Support for writing multiple times to the same file.
- Support for random hexadecimal value instead of timestamp.

Usage:

```json
"versions": [
    {
        "format": "timestamp",
        "key": "now",
        "outfile": "./assets.json"
    },
    {
        "format": "hex:8",
        "key": "hex",
        "outfile": "./assets.json"
    }
]
```

```json
{
    "now": 1665071717350,
    "hex": "6ef54181c4ba"
}
```
This commit is contained in:
Chauncey McAskill
2022-10-06 11:55:46 -04:00
parent 1bdd2def8d
commit 14afe2295a

View File

@@ -1,6 +1,7 @@
import loconfig from '../utils/config.js';
import message from '../utils/message.js';
import resolve from '../utils/template.js';
import { randomBytes } from 'node:crypto';
import {
mkdir,
readFile,
@@ -13,7 +14,11 @@ import {
/**
* @typedef {object} VersionOptions
* @property {string} versionKey - The JSON field to add or update.
* @property {string|number|null} prettyPrint - A string or number to insert
* white space into the output JSON string for readability purposes.
* @property {string} versionFormat - The version number format.
* @property {string} versionKey - The JSON field name assign
* the version number to.
*/
/**
@@ -22,6 +27,8 @@ import {
* @const {VersionOptions} productionVersionOptions - The predefined version options for production.
*/
export const defaultVersionOptions = {
prettyPrint: 4,
versionFormat: 'timestamp',
versionKey: 'version',
};
export const developmentVersionOptions = Object.assign({}, defaultVersionOptions);
@@ -56,36 +63,87 @@ export default async function bumpVersion(versionOptions = null) {
versionOptions = Object.assign({}, defaultVersionOptions, versionOptions);
}
loconfig.tasks.versions.forEach(async ({
const queue = new Map();
loconfig.tasks.versions.forEach(({
outfile,
key = null,
label = null
label = null,
...options
}) => {
if (!label) {
label = basename(outfile || 'undefined');
}
options.pretty = (options.pretty ?? versionOptions.prettyPrint);
options.format = (options.format ?? versionOptions.versionFormat);
options.key = (options.key ?? versionOptions.versionKey);
if (queue.has(outfile)) {
queue.get(outfile).then(() => handleBumpVersion(outfile, label, options));
} else {
queue.set(outfile, handleBumpVersion(outfile, label, options));
}
});
};
/**
* Creates a formatted version number or string.
*
* @param {string} format - The version format.
* @return {string|number}
*/
function createVersionNumber(format) {
let [ type, modifier ] = format.split(':');
switch (type) {
case 'hex':
case 'hexadecimal':
modifier = Number.parseInt(modifier);
if (Number.isNaN(modifier)) {
modifier = 6;
}
return randomBytes(modifier).toString('hex');
case 'timestamp':
return Date.now().valueOf();
}
throw new TypeError(
'Expected \'format\' to be either "timestamp" or "hexadecimal"'
);
}
/**
* @async
* @param {string} outfile
* @param {string} label
* @param {object} options
* @return {Promise}
*/
async function handleBumpVersion(outfile, label, options) {
const timeLabel = `${label} bumped in`;
console.time(timeLabel);
try {
outfile = resolve(outfile);
let json
let json;
try {
json = JSON.parse(await readFile(outfile));
} catch (err) {
json = {};
message(`${label} is a new file`, 'notice');
await mkdir(dirname(outfile), { recursive: true });
json = {};
}
json[key || versionOptions.versionKey] = (new Date()).valueOf();
json[options.key] = createVersionNumber(options.format);
await writeFile(outfile, JSON.stringify(json, null, 4))
await writeFile(outfile, JSON.stringify(json, null, options.pretty));
message(`${label} bumped`, 'success', timeLabel);
} catch (err) {
@@ -97,5 +155,4 @@ export default async function bumpVersion(versionOptions = null) {
message: `${err.name}: ${err.message}`
});
}
});
};
}