Skip to content

Commit 0b64464

Browse files
committed
Intensify search for exact match
1 parent dcfc7cd commit 0b64464

File tree

1 file changed

+95
-117
lines changed

1 file changed

+95
-117
lines changed

src/Command/InstallPackageCommand.php

+95-117
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,6 @@ protected function configure()
3838
InputOption::VALUE_NONE,
3939
'When specified, all packages defined in the .gitify config will be installed.'
4040
)
41-
->addOption(
42-
'local',
43-
'l',
44-
InputOption::VALUE_NONE,
45-
'When specified, any packages inside the /core/packages folder will be installed.'
46-
)
4741
->addOption(
4842
'interactive',
4943
'i',
@@ -113,92 +107,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
113107
return 0;
114108
}
115109

116-
// check for packages that were manually added to the core/packages folder
117-
if ($input->getOption('local')) {
118-
// most of this code is copied from:
119-
// core/model/modx/processors/workspace/packages/scanlocal.class.php
120-
$corePackagesDirectory = $this->modx->getOption('core_path').'packages/';
121-
$corePackagesDirectoryObject = dir($corePackagesDirectory);
122-
123-
while (false !== ($name = $corePackagesDirectoryObject->read())) {
124-
if (in_array($name,array('.','..','.svn','.git','_notes'))) continue;
125-
$packageFilename = $corePackagesDirectory.'/'.$name;
126-
127-
// dont add in unreadable files or directories
128-
if (!is_readable($packageFilename) || is_dir($packageFilename)) continue;
129-
130-
// must be a .transport.zip file
131-
if (strlen($name) < 14 || substr($name,strlen($name)-14,strlen($name)) != '.transport.zip') continue;
132-
$packageSignature = substr($name,0,strlen($name)-14);
133-
134-
// must have a name and version at least
135-
$p = explode('-',$packageSignature);
136-
if (count($p) < 2) continue;
137-
138-
// install if package was not found in database
139-
if ($this->modx->getCount('transport.modTransportPackage', array('signature' => $packageSignature))) {
140-
$this->output->writeln("Package $packageSignature is already installed.");
141-
142-
} else {
143-
$this->output->writeln("<comment>Installing $packageSignature...</comment>");
144-
145-
$package = $this->modx->newObject('transport.modTransportPackage');
146-
$package->set('signature', $packageSignature);
147-
$package->set('state', 1);
148-
$package->set('created',strftime('%Y-%m-%d %H:%M:%S'));
149-
$package->set('workspace', 1);
150-
151-
// set package version data
152-
$sig = explode('-',$packageSignature);
153-
if (is_array($sig)) {
154-
$package->set('package_name',$sig[0]);
155-
if (!empty($sig[1])) {
156-
$v = explode('.',$sig[1]);
157-
if (isset($v[0])) $package->set('version_major',$v[0]);
158-
if (isset($v[1])) $package->set('version_minor',$v[1]);
159-
if (isset($v[2])) $package->set('version_patch',$v[2]);
160-
}
161-
if (!empty($sig[2])) {
162-
$r = preg_split('/([0-9]+)/',$sig[2],-1,PREG_SPLIT_DELIM_CAPTURE);
163-
if (is_array($r) && !empty($r)) {
164-
$package->set('release',$r[0]);
165-
$package->set('release_index',(isset($r[1]) ? $r[1] : '0'));
166-
} else {
167-
$package->set('release',$sig[2]);
168-
}
169-
}
170-
}
171-
172-
// Determine if there are any package dependencies
173-
$package->getTransport();
174-
$package->getOne('Workspace');
175-
$wc = isset($package->Workspace->config) && is_array($package->Workspace->config) ? $package->Workspace->config : [];
176-
$at = is_array($package->get('attributes')) ? $package->get('attributes') : [];
177-
$attributes = array_merge($wc, $at);
178-
$requires = isset($attributes['requires']) && is_array($attributes['requires'])
179-
? $attributes['requires']
180-
: [];
181-
$unsatisfied = $package->checkDependencies($requires);
182-
183-
if (empty($unsatisfied)) {
184-
$package->save();
185-
$package->install();
186-
$this->output->writeln("<info>Package $packageSignature successfully installed.</info>");
187-
}
188-
// If dependencies exist, output an error message and list the packages needed.
189-
else {
190-
$this->output->writeln("\n<info>Unable to install $packageSignature! There are currently unmet dependencies:</info>");
191-
foreach ($unsatisfied as $dependency => $v) {
192-
$this->output->writeln("<info> - $dependency</info>");
193-
}
194-
$this->output->writeln("\n<info>$packageSignature has been added to the MODX package management grid, but is not yet installed.</info>\n");
195-
}
196-
}
197-
}
198-
199-
return 0;
200-
}
201-
202110
// install defined package
203111
$this->install($this->input->getArgument('package_name'));
204112

@@ -269,71 +177,141 @@ private function download($packageName, $provider, $options = array()) {
269177
$provider->getClient();
270178
$this->output->writeln("Searching <comment>{$provider->get('name')}</comment> for <comment>$packageName</comment>...");
271179

180+
// The droid we are looking for
181+
$packageName = strtolower($packageName);
182+
183+
// Collect potential matches in array
272184
$packages = array();
273185

274-
// first try to find an exact match via signature from the chosen package provider
186+
// First try to find an exact match via signature from the chosen package provider
275187
$response = $provider->request('package', 'GET', array(
276188
'supports' => $product_version,
277189
'signature' => $packageName,
278190
));
279191

280-
// when we got a match (non 404), extract package information
192+
//$this->output->writeln(print_r(simplexml_load_string($response->response)));
193+
194+
// When we got a match (non 404), extract package information
281195
if (!$response->isError()) {
282196

283-
$foundPkg = simplexml_load_string ( $response->response );
197+
$foundPkg = simplexml_load_string($response->response);
284198

285-
// no matches, skip empty package name
286-
if ($foundPkg->name) {
199+
// Verify that signature matches (mismatches are known to occur!)
200+
if ($foundPkg->signature == $packageName) {
201+
$packages[strtolower((string) $foundPkg->name)] = array (
202+
'name' => (string) $foundPkg->name,
203+
'version' => (string) $foundPkg->version,
204+
'location' => (string) $foundPkg->location,
205+
'signature' => (string) $foundPkg->signature
206+
);
207+
}
208+
// Try again from a different angle
209+
else {
210+
$this->output->writeln("<error>Returned signature {$foundPkg->signature} doesn't match the package name.</error>");
211+
$this->output->writeln("Trying again from a different angle...");
212+
213+
// Query for name instead, without version number
214+
$name = explode('-', $packageName);
215+
$response = $provider->request('package', 'GET', array(
216+
'supports' => $product_version,
217+
'query' => $name[0],
218+
));
287219

288-
$packages [strtolower((string) $foundPkg->name)] = array (
289-
'name' => (string) $foundPkg->name,
290-
'version' => (string) $foundPkg->version,
291-
'location' => (string) $foundPkg->location,
292-
'signature' => (string) $foundPkg->signature
293-
);
220+
if (!empty($response)) {
221+
$foundPackages = simplexml_load_string($response->response);
222+
223+
foreach ($foundPackages as $foundPkg) {
224+
// Only accept exact match on signature
225+
if ($foundPkg->signature == $packageName) {
226+
$packages[strtolower((string) $foundPkg->name)] = array (
227+
'name' => (string) $foundPkg->name,
228+
'version' => (string) $foundPkg->version,
229+
'location' => (string) $foundPkg->location,
230+
'signature' => (string) $foundPkg->signature
231+
);
232+
}
233+
}
234+
}
294235

236+
$this->output->writeln(print_r($packages, true));
295237
}
296238
}
297239

298-
// if no exact match, try it with via query
240+
// If no exact match, try it via query
299241
if (empty($packages)) {
300242
$response = $provider->request('package', 'GET', array(
301243
'supports' => $product_version,
302244
'query' => $packageName,
303245
));
304246

247+
//$this->output->writeln(print_r(simplexml_load_string($response->response)));
248+
305249
// Check for a proper response
306250
if (!empty($response)) {
307251

308252
$foundPackages = simplexml_load_string($response->response);
309-
// no matches, simply return
253+
254+
// No matches, simply return
310255
if ($foundPackages['total'] == 0) {
311256
return true;
312257
}
313258

259+
// Collect multiple versions of the same package in array
260+
$packageVersions = array();
261+
314262
foreach ($foundPackages as $foundPkg) {
315-
$packages[strtolower((string)$foundPkg->name)] = array(
316-
'name' => (string)$foundPkg->name,
317-
'version' => (string)$foundPkg->version,
318-
'location' => (string)$foundPkg->location,
319-
'signature' => (string)$foundPkg->signature,
320-
);
263+
$name = strtolower((string)$foundPkg->name);
264+
265+
// Only accept exact match on name
266+
if ($name == $packageName) {
267+
$packages[$name] = array (
268+
'name' => (string) $foundPkg->name,
269+
'version' => (string) $foundPkg->version,
270+
'location' => (string) $foundPkg->location,
271+
'signature' => (string) $foundPkg->signature
272+
);
273+
$packageVersions[(string)$foundPkg->version] = array (
274+
'name' => (string) $foundPkg->name,
275+
'version' => (string) $foundPkg->version,
276+
'release' => (string) $foundPkg->release,
277+
'location' => (string) $foundPkg->location,
278+
'signature' => (string) $foundPkg->signature
279+
);
280+
}
321281
}
282+
283+
// If there are multiple versions of the same package, use the latest
284+
if (count($packageVersions) > 1) {
285+
$packageLatest = max(array_keys($packageVersions));
286+
$packages[$packageName] = $packageVersions[$packageLatest];
287+
288+
$this->output->writeln("Available versions:");
289+
$this->output->writeln(print_r($packageVersions, true));
290+
}
291+
292+
// If there's still no match, revisit the response and just grab all hits...
293+
if (empty($packages)) {
294+
foreach ($foundPackages as $foundPkg) {
295+
$packages[strtolower((string)$foundPkg->name)] = array(
296+
'name' => (string)$foundPkg->name,
297+
'version' => (string)$foundPkg->version,
298+
'location' => (string)$foundPkg->location,
299+
'signature' => (string)$foundPkg->signature,
300+
);
301+
}
302+
}
303+
304+
$this->output->writeln(print_r($packages, true));
322305
}
323306
}
324307

325-
// process found packages
308+
// Process found packages
326309
if (!empty($packages)) {
327310

328311
$this->output->writeln('Found ' . count($packages) . ' package(s).');
329312

330313
$helper = $this->getHelper('question');
331314

332-
// Ensure the exact match is always first
333-
if (isset($packages[strtolower($packageName)])) {
334-
$packages = array($packageName => $packages[strtolower($packageName)]) + $packages;
335-
}
336-
337315
foreach ($packages as $package) {
338316
if ($this->modx->getCount('transport.modTransportPackage', array('signature' => $package['signature']))) {
339317
$this->output->writeln("<info>Package {$package['name']} {$package['version']} is already installed.</info>");

0 commit comments

Comments
 (0)