Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diviner/workflow/DivinerAtomizeWorkflow.php
12256 views
1
<?php
2
3
final class DivinerAtomizeWorkflow extends DivinerWorkflow {
4
5
protected function didConstruct() {
6
$this
7
->setName('atomize')
8
->setSynopsis(pht('Build atoms from source.'))
9
->setArguments(
10
array(
11
array(
12
'name' => 'atomizer',
13
'param' => 'class',
14
'help' => pht('Specify a subclass of %s.', 'DivinerAtomizer'),
15
),
16
array(
17
'name' => 'book',
18
'param' => 'path',
19
'help' => pht('Path to a Diviner book configuration.'),
20
),
21
array(
22
'name' => 'files',
23
'wildcard' => true,
24
),
25
array(
26
'name' => 'ugly',
27
'help' => pht('Produce ugly (but faster) output.'),
28
),
29
));
30
}
31
32
public function execute(PhutilArgumentParser $args) {
33
$this->readBookConfiguration($args->getArg('book'));
34
35
$console = PhutilConsole::getConsole();
36
37
$atomizer_class = $args->getArg('atomizer');
38
if (!$atomizer_class) {
39
throw new PhutilArgumentUsageException(
40
pht(
41
'Specify an atomizer class with %s.',
42
'--atomizer'));
43
}
44
45
$symbols = id(new PhutilSymbolLoader())
46
->setName($atomizer_class)
47
->setConcreteOnly(true)
48
->setAncestorClass('DivinerAtomizer')
49
->selectAndLoadSymbols();
50
if (!$symbols) {
51
throw new PhutilArgumentUsageException(
52
pht(
53
"Atomizer class '%s' must be a concrete subclass of %s.",
54
$atomizer_class,
55
'DivinerAtomizer'));
56
}
57
58
$atomizer = newv($atomizer_class, array());
59
60
$files = $args->getArg('files');
61
if (!$files) {
62
throw new Exception(pht('Specify one or more files to atomize.'));
63
}
64
65
$file_atomizer = new DivinerFileAtomizer();
66
67
foreach (array($atomizer, $file_atomizer) as $configure) {
68
$configure->setBook($this->getConfig('name'));
69
}
70
71
$group_rules = array();
72
foreach ($this->getConfig('groups', array()) as $group => $spec) {
73
$include = (array)idx($spec, 'include', array());
74
foreach ($include as $pattern) {
75
$group_rules[$pattern] = $group;
76
}
77
}
78
79
$all_atoms = array();
80
$context = array(
81
'group' => null,
82
);
83
foreach ($files as $file) {
84
$abs_path = Filesystem::resolvePath($file, $this->getConfig('root'));
85
$data = Filesystem::readFile($abs_path);
86
87
if (!$this->shouldAtomizeFile($file, $data)) {
88
$console->writeLog("%s\n", pht('Skipping %s...', $file));
89
continue;
90
} else {
91
$console->writeLog("%s\n", pht('Atomizing %s...', $file));
92
}
93
94
$context['group'] = null;
95
foreach ($group_rules as $rule => $group) {
96
if (preg_match($rule, $file)) {
97
$context['group'] = $group;
98
break;
99
}
100
}
101
102
$file_atoms = $file_atomizer->atomize($file, $data, $context);
103
$all_atoms[] = $file_atoms;
104
105
if (count($file_atoms) !== 1) {
106
throw new Exception(
107
pht('Expected exactly one atom from file atomizer.'));
108
}
109
$file_atom = head($file_atoms);
110
111
$atoms = $atomizer->atomize($file, $data, $context);
112
113
foreach ($atoms as $atom) {
114
if (!$atom->hasParent()) {
115
$file_atom->addChild($atom);
116
}
117
}
118
119
$all_atoms[] = $atoms;
120
}
121
122
$all_atoms = array_mergev($all_atoms);
123
124
$all_atoms = mpull($all_atoms, 'toDictionary');
125
$all_atoms = ipull($all_atoms, null, 'hash');
126
127
if ($args->getArg('ugly')) {
128
$json = json_encode($all_atoms);
129
} else {
130
$json = id(new PhutilJSON())->encodeFormatted($all_atoms);
131
}
132
133
$console->writeOut('%s', $json);
134
return 0;
135
}
136
137
private function shouldAtomizeFile($file_name, $file_data) {
138
return strpos($file_data, '@'.'undivinable') === false;
139
}
140
141
}
142
143