-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
74 lines (60 loc) · 2.18 KB
/
index.js
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
const parseMakeDefinitions = require('@quarterto/parse-make-definitions');
const parseMakeCommentBlocks = require('@quarterto/parse-make-comment-blocks');
const groupBy = require('lodash.groupby');
const fs = require('mz/fs');
const parse = src => parseMakeCommentBlocks(src).map(block => {
block.definition = parseMakeDefinitions(block.nextLine);
return block;
});
const variableEmoji = {
recursive: '🚩',
simple: '📍',
append: '📎',
multiline: '💬',
};
const ruleEmoji = def =>
def.target.indexOf('%') >= 0 ? '📝'
: def.isDoubleColon ? '📋'
: '📄';
const formatLink = (lineNo, file) =>
`[🔗](${file}#L${lineNo})`;
const formatDefinition = (def, file) => {
switch(def.type) {
case 'variable':
return `${variableEmoji[def.flavour]} \`$(${def.name})\``;
case 'rule':
if(def.targets) { // static pattern rule
return `📑 \`${def.targets}\`: \`${def.pattern}\` ⬅️ \`${def.prerequisites}\``;
}
if(def.prerequisites) { // ordinary pattern or explicit rule
return `${ruleEmoji(def)} \`${def.target}\` ⬅️ \`${def.prerequisites}\``;
}
// simple explicit rule
return `📃 \`${def.target}\``;
}
};
const format = fn => parts => parts.map(fn).join('\n\n');
const formatBlock = (block) => `#### ${formatDefinition(block.definition)} ${block.lineNumber ? formatLink(block.lineNumber, block.file) : ''}
${block.comment}`;
const formatBlocks = format(formatBlock);
const formatSection = group => ({title, section}) => group[section] && group[section].length ? `### ${title}
${formatBlocks(group[section])}` : '';
const formatSections = group => format(formatSection(group));
exports.parseMakefiles = files => Promise.all(files.map(
file => fs.readFile(file, 'utf8').then(src =>
parse(src).map(block => (block.file = file, block))
)
)).then(
files => files.reduce(
(allBlocks, blocks) => allBlocks.concat(blocks),
[]
)
);
exports.formatBlocks = blocks => formatSections(groupBy(
blocks.filter(block => block.definition),
block => block.definition.flavour === 'multiline' ? 'function' : block.definition.type
))([
{title: 'Rules', section: 'rule'},
{title: 'Variables', section: 'variable'},
{title: 'Functions', section: 'function'},
]);