SPB Git

spb/drive Public

SPB Drive — self-hosted personal cloud drive (files, previews, sharing) on the MacLustr cluster.

JavaScript 82.7% CSS 10.6% Nunjucks 3.6% Shell 1.8% SQL 1.3%
3.0 KB · 70 lines javascript
Raw Blame History
1#!/usr/bin/env node2/**3 * ─────────────────────────────────────────────4 *  SPB Drive — Personal Cloud Drive5 * ─────────────────────────────────────────────6 *  Author  : Simon-Pierre Boucher7 *  Contact : contact@spboucher.ai8 *  File    : scripts/inject-headers.mjs9 *  Purpose : Prepend the canonical author header to any tracked file missing it10 *  License : MIT © Simon-Pierre Boucher11 * ─────────────────────────────────────────────12 */1314import { execSync } from 'node:child_process';15import { readFileSync, writeFileSync } from 'node:fs';1617const LINES = (file, purpose) => [18  '─────────────────────────────────────────────',19  ' SPB Drive — Personal Cloud Drive',20  '─────────────────────────────────────────────',21  ' Author  : Simon-Pierre Boucher',22  ' Contact : contact@spboucher.ai',23  ` File    : ${file}`,24  ` Purpose : ${purpose}`,25  ' License : MIT © Simon-Pierre Boucher',26  '─────────────────────────────────────────────',27];2829/** Comment wrappers per extension family. */30const STYLES = {31  block: (lines) => `/**\n${lines.map((l) => ` * ${l}`.trimEnd()).join('\n')}\n */\n\n`,32  hash: (lines) => `${lines.map((l) => `# ${l}`.trimEnd()).join('\n')}\n\n`,33  html: (lines) => `<!--\n${lines.map((l) => `  ${l}`.trimEnd()).join('\n')}\n-->\n\n`,34  sql: (lines) => `${lines.map((l) => `-- ${l}`.trimEnd()).join('\n')}\n\n`,35};3637const EXT_STYLE = {38  '.js': 'block', '.mjs': 'block', '.cjs': 'block', '.ts': 'block',39  '.css': 'block', '.scss': 'block',40  '.py': 'hash', '.sh': 'hash', '.bash': 'hash', '.yml': 'hash', '.yaml': 'hash', '.toml': 'hash',41  '.html': 'html', '.njk': 'html', '.md': 'html',42  '.sql': 'sql',43};4445const files = execSync('git ls-files', { encoding: 'utf8' }).split('\n').filter(Boolean);46let injected = 0;4748for (const file of files) {49  const base = file.split('/').pop();50  const dot = base.lastIndexOf('.');51  const style = dot >= 0 ? EXT_STYLE[base.slice(dot).toLowerCase()] : null;52  if (!style) continue;53  let text;54  try { text = readFileSync(file, 'utf8'); } catch { continue; }55  if (text.slice(0, 1200).includes('contact@spboucher.ai')) continue;5657  let header = STYLES[style](LINES(file, 'Part of SPB Drive'));58  let body = text;59  if (body.startsWith('#!')) {60    const nl = body.indexOf('\n') + 1;61    header = body.slice(0, nl) + header;62    body = body.slice(nl);63  }64  writeFileSync(file, header + body);65  console.log(`+ header → ${file}`);66  injected += 1;67}6869console.log(injected > 0 ? `✓ Injected ${injected} header(s).` : '✓ Nothing to inject.');70