Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"format": "prettier --write \"**/*.md\"",
"format:check": "prettier --check \"**/*.md\"",
"prose:check": "vale --minAlertLevel error --output=docs/.vale/vale.tmpl docs",
"lint": "npm run format:check && npm run prose:check"
"lint": "npm run format:check && npm run prose:check",
"prebuild": "chmod +x ./src/metadataInject.js && node ./src/metadataInject.js"
},
"dependencies": {
"@astrojs/netlify": "^3.0.0",
Expand Down
92 changes: 92 additions & 0 deletions src/metadataInject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// Directory to search
const docsDir = path.resolve(__dirname, './content/docs'); // or './content/docs'

/**
* Recursively get all .md files in a directory.
* @param {string} dir - Directory path to search.
* @returns {string[]} - Array of file paths.
*/
function getMarkdownFiles(dir) {
let results = [];
const list = fs.readdirSync(dir);
list.forEach((file) => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
results = results.concat(getMarkdownFiles(filePath));
} else if (filePath.endsWith('.md')) {
results.push(filePath);
}
});
return results;
}

/**
* Retrieve the last Git commit metadata for a file.
* @param {string} file - File path.
* @returns {{ author: string, date: string }}
*/
function getGitMetadata(file) {
let author = 'Unknown';
let date = 'Unknown';
try {
author = execSync(`git log -1 --pretty=format:%an "${file}"`).toString().trim();
date = execSync(`git log -1 --pretty=format:%ad --date=format:'%d/%m/%Y' "${file}"`).toString().trim();
} catch (error) {
console.error(`Error getting git metadata for ${file}: ${error.message}`);
}
return { author, date };
}

/**
* Update a Markdown file by inserting last updated metadata.
* The metadata is inserted right after the YAML frontmatter, if present.
* If there is no frontmatter, the metadata is added at the top.
*
* @param {string} file - Path to the markdown file.
*/
function updateFile(file) {
const { author, date } = getGitMetadata(file);
const content = fs.readFileSync(file, 'utf8');

let yamlFront = '';
let restContent = content;

// Check if file starts with YAML frontmatter delimiter '---'
if (content.startsWith('---')) {
// Find the end of the YAML block (the second occurrence of '---')
const secondDelimiterIndex = content.indexOf('\n---', 3);
if (secondDelimiterIndex !== -1) {
// Include the entire YAML block (up to and including the second delimiter line)
const endOfYaml = content.indexOf('\n', secondDelimiterIndex + 1);
if (endOfYaml !== -1) {
yamlFront = content.substring(0, endOfYaml).trimEnd() + '\n';
restContent = content.substring(endOfYaml + 1);
}
}
}

const metadataBlock = `**Last updated by:** ${author}, **Last updated on:** ${date}\n\n`;

// Insert metadata block
const updatedContent = yamlFront
? `${yamlFront}\n${metadataBlock}${restContent}`
: `${metadataBlock}${restContent}`;

fs.writeFileSync(file, updatedContent, 'utf8');
console.log(`Updated metadata in ${file}`);
}

// Get all markdown files in the docs directory
const markdownFiles = getMarkdownFiles(docsDir);

// Process each file
markdownFiles.forEach(updateFile);