preamble
Version:
Automated License & Metadata applicators for Codebases.
200 lines (171 loc) • 5.68 kB
JavaScript
/********************************************************
* preamble
*
* Lawfull Good
*
* @license
*
* Apache-2.0
*
* Copyright 2024 Alex Stevovich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* package_name: @lawfulgood/js
* file_name: test-src\index.mjs
* purpose: {{PURPOSE}}
*
* --- SYSTEM FIELDS ---
* generated_on: 2025-03-06T09:31:49.946Z
* uuid: 74c58780-751c-4682-af38-8f0d9f692276
* certified_version: 1.0.0
* file_size: 5906 bytes
* hash: 3c81bc770945e844f73912308ed75ebd6779c9e03838ba7e1b9c83ef50d70b02
* mast: 7e7616f436edf38ab068c5ea5c35956dc89304daacad36949966a54f30f5c3ca
*
* ~generated by @lawfulgood/js on npm!
*
********************************************************/
import fs from 'fs/promises';
import { Doc as JsPrimalDoc, BlockComment } from '@primals/js';
import pkgplz from 'pkgplz';
import { createHash, randomUUID } from 'crypto';
import Config from './config.mjs';
export { Config };
//isuuidvalid()
function isValidUUID(uuid) {
return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
uuid,
);
}
export function extractLicenseFields(matter) {
const fields = {};
const lines = matter.split('\n');
for (const line of lines) {
const trimmedLine = line.trim();
if (!trimmedLine) continue;
const match = trimmedLine.match(/(?:.*\s)?([a-zA-Z0-9_]+)\s*:\s*(.*)$/);
if (match) {
const key = match[1].trim();
const value = match[2].trim();
fields[key] = value;
}
}
return fields;
}
function hash(input) {
return createHash('sha256').update(input, 'utf8').digest('hex');
}
function templateLicense(license, data) {
for (const [key, value] of Object.entries(data)) {
const pattern = new RegExp(`{{\\s*${key.toUpperCase()}\\s*}}`, 'g');
license = license.replace(pattern, value);
}
return license;
}
async function sign(file) {
const content = await fs.readFile(file, 'utf-8');
const doc = new JsPrimalDoc();
doc.from(content);
let DATA = {};
let previousLicense = null;
doc.head.elements = doc.head.elements.filter((el) => {
if (el.componentType === 'block_comment') {
//console.log('🗑️ Found and removed existing license block:', el);
previousLicense = el;
return false;
}
return true;
});
if (previousLicense) {
const licenseText = previousLicense.lines.join('\n');
Object.assign(DATA, extractLicenseFields(licenseText));
}
const stats = await fs.stat(file);
const pkg = await pkgplz();
DATA.lg_gen_package_name = pkg.name || 'Unknown';
DATA.lg_gen_package_description = pkg.description || 'Unknown';
DATA.lg_gen_file_name = file;
DATA.lg_gen_uuid = 'generated-uuid';
if (!isValidUUID(DATA.uuid)) {
DATA.lg_gen_uuid = randomUUID();
} else {
DATA.lg_gen_uuid = DATA.uuid;
}
let license = `/********************************************************
* lawfulgood
*
* quote here
*
* Copyright 2015-${new Date().getFullYear()} Alex Stevovich
*
* @license
*
* Licensed under the Elastic License 2.0.
* See https://www.elastic.co/licensing/elastic-license for full terms.
*
* "Preamble" and related marks are trademarks of Alex Stevovich.
*
* This file is part of the Preamble system and is subject to the license terms.
*
*
* package_name: {{LG_GEN_PACKAGE_NAME}}
* file_name: {{LG_GEN_FILE_NAME}}
* purpose: {{PURPOSE}}
*
* --- SYSTEM FIELDS ---
* generated_on: {{LG_GEN_GENERATED_ON}}
* uuid: {{LG_GEN_UUID}}
* certified_version: {{LG_GEN_CERTIFIED_VERSION}}
* file_size: {{LG_GEN_FILE_SIZE}}
* hash: {{LG_GEN_FILE_HASH}}
* mast: {{LG_GEN_BLOCK_HASH}}
*
* {{LG_GEN_LAWFULGOOD}}
*
********************************************************/`;
license = templateLicense(license, DATA);
const oldDocHash = DATA.hash;
const oldBlockHash = DATA.mast;
const newBlockHash = hash(license);
const newDocHash = hash(doc.content);
let docUpdated = false;
if (newDocHash != oldDocHash) {
docUpdated = true;
console.log('Doc is new!');
}
DATA = {};
DATA.lg_gen_generated_on = new Date().toISOString();
DATA.lg_gen_certified_version = pkg.version || '0.0.0';
DATA.lg_gen_file_hash = newDocHash;
DATA.lg_gen_block_hash = newBlockHash;
DATA.lg_gen_file_size = stats.size + ' bytes';
DATA.lg_gen_lawfulgood = '~generated by @lawfulgood/js on npm!';
const finalBlock = templateLicense(license, DATA);
let blockUpdated = false;
if (newBlockHash != oldBlockHash) {
blockUpdated = true;
console.log('Block is new!');
}
const newLicense = new BlockComment(finalBlock.split('\n'));
doc.head.elements.unshift(newLicense);
if (docUpdated || blockUpdated) {
console.log('Result: Changes.');
await fs.writeFile(file, doc.content, 'utf-8');
} else {
console.log('Result: No Changes.');
}
console.log('✅ License applied to', file);
}
sign('./test.mjs');