renovate/tools/generate-imports.mjs
Gabriel-Ladzaretti 974fa7b2a7
refactor(versioning/distro-info): for future use in debian and ubuntu versioning (#14880)
* refactor(tools/distro-info): for later use in ubuntu and debian versioning

distro-info refactor

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

styling

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

distro-info refactor

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

styling

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

use https://debian.pages.debian.net/distro-info-data/ubuntu.csv as distro info data

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

cr changes and migrated from mjs to ts

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

added a crude way to prevent writing corrupted data

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

lint fixes

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

cr changes and migrated from mjs to ts

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

cr changes

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

dynamically check if stable/released.

22.04 release for example

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

fixed JSON order

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

removed ts.ignore

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

cr changes

* refactor(tools/distro-info): for later use in ubuntu and debian versioning

cr changes

Co-authored-by: Michael Kriese <michael.kriese@visualon.de>
2022-04-09 14:38:06 +03:00

192 lines
4.5 KiB
JavaScript

import util from 'util';
import fs from 'fs-extra';
import _glob from 'glob';
import hasha from 'hasha';
import minimatch from 'minimatch';
import shell from 'shelljs';
import upath from 'upath';
const glob = util.promisify(_glob);
shell.echo('generating imports');
const newFiles = new Set();
if (!fs.existsSync('lib')) {
shell.echo('> missing sources');
shell.exit(0);
}
if (!fs.existsSync('data')) {
shell.echo('> missing data folder');
shell.exit(0);
}
/**
*
* @param {string} file
* @param {string} code
*/
async function updateFile(file, code) {
const oldCode = fs.existsSync(file) ? await fs.readFile(file, 'utf8') : null;
if (code !== oldCode) {
await fs.writeFile(file, code);
}
newFiles.add(file);
}
const dataPaths = [
'data',
'node_modules/emojibase-data/en/shortcodes/github.json',
];
const options = {
algorithm: 'sha256',
};
/**
*
* @param {string[]} paths
* @returns {string[]}
*/
function expandPaths(paths) {
return paths
.map((pathName) => {
const stat = fs.statSync(pathName);
if (stat.isFile()) {
return [pathName];
}
if (stat.isDirectory()) {
const dirPaths = fs
.readdirSync(pathName, { withFileTypes: true })
.filter(
(dirent) =>
!(dirent.isFile() && ['.DS_Store'].includes(dirent.name))
)
.map((dirent) => upath.join(pathName, dirent.name));
return expandPaths(dirPaths);
}
return [];
})
.reduce((x, y) => x.concat(y));
}
/**
* @param {string} filePath
* @returns {Promise<string>}
*/
async function getFileHash(filePath) {
try {
const hash = await hasha.fromFile(filePath, options);
return hash;
} catch (err) {
throw new Error(`ERROR: Unable to generate hash for ${filePath}`);
}
}
/**
*
* @param {string} managerName
* @returns {Promise<string>}
*/
export async function getManagerHash(managerName) {
/** @type {string[]} */
let hashes = [];
const files = (await glob(`lib/modules/manager/${managerName}/**`)).filter(
(fileName) => minimatch(fileName, '*.+(snap|spec.ts)', { matchBase: true })
);
for (const fileAddr of files) {
const hash = await getFileHash(fileAddr);
hashes.push(hash);
}
if (hashes.length) {
return hasha(hashes, options);
}
throw new Error(`Unable to generate hash for manager/${managerName}`);
}
async function generateData() {
const files = expandPaths(dataPaths).sort();
const importDataFileType = files.map((x) => ` | '${x}'`).join('\n');
const contentMapDecl = 'const data = new Map<DataFile, string>();';
/** @type {string[]} */
const contentMapAssignments = [];
for (const file of files) {
const key = file.replace(/\\/g, '/');
const rawFileContent = await fs.readFile(file, 'utf8');
const value = JSON.stringify(rawFileContent);
shell.echo(`> ${key}`);
contentMapAssignments.push(`data.set('${key}', ${value});`);
}
await updateFile(
`lib/data-files.generated.ts`,
[
`export type DataFile =\n${importDataFileType};`,
contentMapDecl,
contentMapAssignments.join('\n'),
`export default data;\n`,
].join('\n\n')
);
}
async function generateHash() {
shell.echo('generating hashes');
try {
const hashMap = `export const hashMap = new Map<string, string>();`;
/** @type {string[]} */
let hashes = [];
// get managers list
const managers = (
await fs.readdir('lib/modules/manager', { withFileTypes: true })
)
.filter((file) => file.isDirectory())
.map((file) => file.name);
for (const manager of managers) {
const hash = await getManagerHash(manager);
hashes.push(hash);
}
//add manager hashes to hashMap {key->manager, value->hash}
hashes = (await Promise.all(hashes)).map(
(hash, index) => `hashMap.set('${managers[index]}','${hash}');`
);
//write hashMap to fingerprint.generated.ts
await updateFile(
'lib/modules/manager/fingerprint.generated.ts',
[hashMap, hashes.join('\n')].join('\n\n')
);
} catch (err) {
shell.echo('ERROR:', err.message);
process.exit(1);
}
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async () => {
try {
// data-files
await generateData();
await generateHash();
await Promise.all(
shell
.find('lib/**/*.generated.ts')
.filter((f) => !newFiles.has(f))
.map((file) => fs.remove(file))
);
} catch (e) {
shell.echo(e.toString());
shell.exit(1);
}
})();