mirror of https://github.com/theNewDynamic/gohugo-theme-ananke.git

Patrick Kollitsch
31.01.2025 b119a21663b0df4688ceb5d18a2eed30c2d88974
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { execSync } from "child_process";
import fs from "fs";
import path from "path";
import dotenv from "dotenv";
import fetch from "node-fetch";
 
// Load environment variables
dotenv.config();
 
// GitHub API Token (required)
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
if (!GITHUB_TOKEN) {
    console.error("❌ ERROR: GITHUB_TOKEN is not set. Add it to .env.");
    process.exit(1);
}
 
// Directory to scan (i18n folder)
const TARGET_DIR = process.argv[2] || "i18n";
const SECTION = process.argv[3] || path.basename(TARGET_DIR);
const REPO_ROOT = execSync("git rev-parse --show-toplevel").toString().trim();
const CODEOWNERS_FILE = path.join(REPO_ROOT, ".github", "CODEOWNERS");
 
// Section markers
const SECTION_START = `# ${SECTION} - automatically created`;
const SECTION_END = `# ${SECTION} - end`;
 
// Get commit authors for a specific file
const getCommitAuthors = (file) => {
    try {
        return execSync(`git log --format='%ae' -- "${file}" | sort -u`)
            .toString()
            .trim()
            .split("\n")
            .filter((email) => email);
    } catch (error) {
        return [];
    }
};
 
// Fetch GitHub username from email
const fetchGitHubUsername = async (email) => {
    try {
        const url = `https://api.github.com/search/users?q=${email}+in:email`;
        const response = await fetch(url, {
            headers: { Authorization: `token ${GITHUB_TOKEN}` },
        });
        const data = await response.json();
        if (data.items && data.items.length > 0) {
            return `@${data.items[0].login}`;
        }
        return `@${email.split("@")[0]}`; // Fallback
    } catch (error) {
        console.error(`❌ ERROR fetching GitHub username for ${email}:`, error);
        return `@${email.split("@")[0]}`;
    }
};
 
// Process files and generate CODEOWNERS entries
const generateCodeowners = async () => {
    const files = execSync(`find ${TARGET_DIR} -type f`)
        .toString()
        .trim()
        .split("\n");
    let codeownersContent = "";
 
    for (const file of files) {
        const authors = await Promise.all(
            getCommitAuthors(file).map(fetchGitHubUsername),
        );
 
        if (authors.length > 0) {
            codeownersContent += `/${file} ${authors.join(" ")}\n`;
        }
    }
 
    if (!fs.existsSync(path.dirname(CODEOWNERS_FILE))) {
        fs.mkdirSync(path.dirname(CODEOWNERS_FILE), { recursive: true });
    }
 
    let existingContent = fs.existsSync(CODEOWNERS_FILE)
        ? fs.readFileSync(CODEOWNERS_FILE, "utf8")
        : "";
    existingContent = existingContent
        .replace(new RegExp(`\n?${SECTION_START}[\\s\\S]*?${SECTION_END}`, "g"), "")
        .trim();
 
    const updatedContent = `${existingContent}\n\n${SECTION_START}\n${codeownersContent}${SECTION_END}\n`;
    fs.writeFileSync(CODEOWNERS_FILE, updatedContent.trim() + "\n");
 
    console.log(`✅ CODEOWNERS updated for section: [${SECTION}]`);
};
 
generateCodeowners();