-
Notifications
You must be signed in to change notification settings - Fork 57
/
extract-rules.js
76 lines (72 loc) · 2.26 KB
/
extract-rules.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
75
76
const commonmark = require('commonmark')
const commonmarkParser = new commonmark.Parser()
// Parse Markdown of the form:
//
// ```md
// ###### Automation Rules
//
// - `assigned_issue`
// - `closed_issue`
// - `added_label` **wontfix**
// - `new_pullrequest` **foo-bar** **test**
// ```
function parseMarkdown (card) {
if (!card.note) {
return new Map() // no Rules
}
const root = commonmarkParser.parse(card.note)
const walker = root.walker()
const parsedRules = new Map()
let walkEvent
while ((walkEvent = walker.next())) {
const {node} = walkEvent
// Each item should be simple text that contains the rule, followed by a space,
// followed by any arguments (sometimes wrapped in spaces)
if (walkEvent.entering && node.type === 'code') {
if (node.parent.type === 'paragraph' && node.parent.parent.type === 'item') {
let args = []
let argsNode = node
while ((argsNode = argsNode.next)) {
if (argsNode.type === 'strong' || argsNode.type === 'emph') {
if (argsNode.firstChild.type === 'text') {
args.push(argsNode.firstChild.literal.trim())
}
}
}
// Try splitting up the text (backwards-compatibility)
if (args.length === 0 && node.next && node.next.literal) {
args = node.next.literal.trim().split(' ').map((arg) => arg.trim())
}
parsedRules.set(node.literal, args)
}
}
}
return parsedRules
}
// For parse out all the Automation Rules from Cards in a Project
module.exports = function extractAutomationRules (projects) {
const automationRules = []
// Use a Map to deduplicate because .firstCards and .lastCards could be the same Card
const allCards = new Map()
projects.forEach((project) => {
project.columns.nodes.forEach((column) => {
column.firstCards.nodes.forEach((card) => {
allCards.set(card.id, {card, column})
})
column.lastCards.nodes.forEach((card) => {
allCards.set(card.id, {card, column})
})
})
})
allCards.forEach(({card, column}) => {
const rules = parseMarkdown(card)
rules.forEach((ruleArgs, ruleName) => {
automationRules.push({
column,
ruleName,
ruleArgs
})
})
})
return automationRules
}