// Module and tracker part parsers // application/modules — defines the repo's logical module structure // application/bugzilla — maps modules to Bugzilla products/components export function parseModules(text) { const lines = text.split(/\r?\n/); const modules = []; let current = null; for (const line of lines) { // Skip the "Modules:" header if (/^\s*Modules:\s*$/.test(line)) continue; // Start of module entry if (/^\s*-\s*(Name:.*)?$/.test(line)) { if (current?.name) { modules.push(current); } current = {}; const match = line.match(/^\s*-\s*Name:\s*(.*)$/); if (match) current.name = match[1]; continue; } const kv = line.match(/^\s+([A-Za-z][A-Za-z0-9]*):\s*(.*)$/); if (kv && current) { if (kv[1] === "Name") current.name = kv[2]; else if (kv[1] === "Path") current.path = kv[2]; } } if (current?.name) { modules.push(current); } return modules; } export function parseBugzillaTracker(text) { const lines = text.split(/\r?\n/); const tracker = {}; const mappings = []; let inMappings = false; let current = null; for (const line of lines) { if (!inMappings) { if (line.startsWith("URL:")) { tracker.url = line.slice("URL:".length).trim(); } else if (line.startsWith("Mappings:")) { inMappings = true; } continue; } if (/^\s*-\s*(Module:.*)?$/.test(line)) { if (current?.module && current?.product && current?.component) { mappings.push(current); } current = {}; const match = line.match(/^\s*-\s*Module:\s*(.*)$/); if (match) current.module = match[1]; continue; } const kv = line.match(/^\s+([A-Za-z][A-Za-z0-9]*):\s*(.*)$/); if (kv && current) { if (kv[1] === "Module") current.module = kv[2]; else if (kv[1] === "Product") current.product = kv[2]; else if (kv[1] === "Component") current.component = kv[2]; } } if (current?.module && current?.product && current?.component) { mappings.push(current); } tracker.mappings = mappings; return tracker; }