forked from phacility/phabricator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDivinerAtomizeWorkflow.php
137 lines (111 loc) · 3.62 KB
/
DivinerAtomizeWorkflow.php
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
final class DivinerAtomizeWorkflow extends DivinerWorkflow {
public function didConstruct() {
$this
->setName('atomize')
->setSynopsis(pht('Build atoms from source.'))
->setArguments(
array(
array(
'name' => 'atomizer',
'param' => 'class',
'help' => pht('Specify a subclass of DivinerAtomizer.'),
),
array(
'name' => 'book',
'param' => 'path',
'help' => pht('Path to a Diviner book configuration.'),
),
array(
'name' => 'files',
'wildcard' => true,
),
array(
'name' => 'ugly',
'help' => pht('Produce ugly (but faster) output.'),
),
));
}
public function execute(PhutilArgumentParser $args) {
$this->readBookConfiguration($args->getArg('book'));
$console = PhutilConsole::getConsole();
$atomizer_class = $args->getArg('atomizer');
if (!$atomizer_class) {
throw new Exception("Specify an atomizer class with --atomizer.");
}
$symbols = id(new PhutilSymbolLoader())
->setName($atomizer_class)
->setConcreteOnly(true)
->setAncestorClass('DivinerAtomizer')
->selectAndLoadSymbols();
if (!$symbols) {
throw new Exception(
"Atomizer class '{$atomizer_class}' must be a concrete subclass of ".
"DivinerAtomizer.");
}
$atomizer = newv($atomizer_class, array());
$files = $args->getArg('files');
if (!$files) {
throw new Exception("Specify one or more files to atomize.");
}
$file_atomizer = new DivinerFileAtomizer();
foreach (array($atomizer, $file_atomizer) as $configure) {
$configure->setBook($this->getConfig('name'));
}
$group_rules = array();
foreach ($this->getConfig('groups', array()) as $group => $spec) {
$include = (array)idx($spec, 'include', array());
foreach ($include as $pattern) {
$group_rules[$pattern] = $group;
}
}
$all_atoms = array();
$context = array(
'group' => null,
);
foreach ($files as $file) {
$abs_path = Filesystem::resolvePath($file, $this->getConfig('root'));
$data = Filesystem::readFile($abs_path);
if (!$this->shouldAtomizeFile($file, $data)) {
$console->writeLog("Skipping %s...\n", $file);
continue;
} else {
$console->writeLog("Atomizing %s...\n", $file);
}
$context['group'] = null;
foreach ($group_rules as $rule => $group) {
if (preg_match($rule, $file)) {
$context['group'] = $group;
break;
}
}
$file_atoms = $file_atomizer->atomize($file, $data, $context);
$all_atoms[] = $file_atoms;
if (count($file_atoms) !== 1) {
throw new Exception("Expected exactly one atom from file atomizer.");
}
$file_atom = head($file_atoms);
$atoms = $atomizer->atomize($file, $data, $context);
foreach ($atoms as $atom) {
if (!$atom->hasParent()) {
$file_atom->addChild($atom);
}
}
$all_atoms[] = $atoms;
}
$all_atoms = array_mergev($all_atoms);
$all_atoms = mpull($all_atoms, 'toDictionary');
$all_atoms = ipull($all_atoms, null, 'hash');
if ($args->getArg('ugly')) {
$json = json_encode($all_atoms);
} else {
$json_encoder = new PhutilJSON();
$json = $json_encoder->encodeFormatted($all_atoms);
}
$console->writeOut('%s', $json);
return 0;
}
private function shouldAtomizeFile($file_name, $file_data) {
return (strpos($file_data, '@'.'undivinable') === false);
}
}