diff --git a/banner.js b/banner.js index db3974c..068770c 100644 --- a/banner.js +++ b/banner.js @@ -1,19 +1,75 @@ -const fs = require("fs"); -const pkg = require("./package.json"); -const filename = "assets/js/main.min.js"; -const script = fs.readFileSync(filename); -const padStart = str => ("0" + str).slice(-2); -const dateObj = new Date(); -const date = `${dateObj.getFullYear()}-${padStart( - dateObj.getMonth() + 1 -)}-${padStart(dateObj.getDate())}`; -const banner = `/*! +// scripts/prepend-banner.js +// Node >= 12 (uses fs.promises) +const fs = require("fs").promises; +const path = require("path"); + +async function main() { + try { + const pkg = require(path.resolve(__dirname, "..", "package.json")); + const filename = process.argv[2] || path.resolve(__dirname, "..", "assets/js/main.min.js"); + + // Read file as UTF-8 text + const content = await fs.readFile(filename, "utf8"); + + // If file already starts with a banner comment (/*! or /**), skip. + // This is more robust than slicing bytes and comparing to a raw string. + if (content.startsWith("/*!") || content.startsWith("/**")) { + console.log(`Banner already present in: ${filename} — nothing to do.`); + return; + } + + // Build date string (YYYY-MM-DD) + const padStart = (s) => ("0" + String(s)).slice(-2); + const dateObj = new Date(); + const date = `${dateObj.getFullYear()}-${padStart(dateObj.getMonth() + 1)}-${padStart( + dateObj.getDate() + )}`; + + const banner = `/*! * Minimal Mistakes Jekyll Theme ${pkg.version} by ${pkg.author} * Copyright 2013-${dateObj.getFullYear()} Michael Rose - mademistakes.com | @mmistakes * Licensed under ${pkg.license} */ `; -if (script.slice(0, 3) != "/**") { - fs.writeFileSync(filename, banner + script); + // Prepare temporary file path in same directory for atomic replace + const dir = path.dirname(filename); + const base = path.basename(filename); + const tmpName = path.join(dir, `.${base}.tmp-${Date.now()}`); + + // Preserve original file metadata (mode and times) + let stat; + try { + stat = await fs.stat(filename); + } catch { + stat = null; + } + + // Write tmp file then rename (atomic on most OSes) + await fs.writeFile(tmpName, banner + content, "utf8"); + await fs.rename(tmpName, filename); + + // Restore mode and times if we got them + if (stat) { + try { + await fs.chmod(filename, stat.mode); + } catch (err) { + // non-fatal; continue + } + try { + const atime = stat.atime; + const mtime = stat.mtime; + await fs.utimes(filename, atime, mtime); + } catch (err) { + // non-fatal + } + } + + console.log(`Banner prepended to: ${filename}`); + } catch (err) { + console.error("Error:", err.message || err); + process.exitCode = 1; + } } + +main();