Added functionality to remove symlink registrations during the uninstallation process & upgraded fix-broken to also detect broken packages that are installed on the system
This commit is contained in:
parent
6388b27b7a
commit
0a2cee2a02
4 changed files with 173 additions and 23 deletions
|
@ -111,7 +111,7 @@
|
||||||
}
|
}
|
||||||
catch(Exception $e)
|
catch(Exception $e)
|
||||||
{
|
{
|
||||||
Console::outException(sprintf('Unable to fix missing packages: %s', $e->getMessage()), $e, 1);
|
Console::outException(sprintf('Unable to fix broken packages: %s', $e->getMessage()), $e, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,6 +401,7 @@
|
||||||
/**
|
/**
|
||||||
* Uninstall all packages from the system
|
* Uninstall all packages from the system
|
||||||
*
|
*
|
||||||
|
* @param array $args
|
||||||
* @return int
|
* @return int
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws OperationException
|
* @throws OperationException
|
||||||
|
@ -450,48 +451,76 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$package_manager = new PackageManager();
|
$package_manager = new PackageManager();
|
||||||
$results = $package_manager->getMissingPackages();
|
$missing_dependencies = $package_manager->getMissingPackages();
|
||||||
|
$broken_packages = $package_manager->getBrokenPackages();
|
||||||
$auto_yes = isset($args['y']);
|
$auto_yes = isset($args['y']);
|
||||||
|
|
||||||
if(count($results) === 0)
|
if(count($missing_dependencies) === 0 && count($broken_packages) === 0)
|
||||||
{
|
{
|
||||||
Console::out('No missing packages found');
|
Console::out('No broken packages found');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::out('The following packages that are required by other packages are missing:');
|
if(count($missing_dependencies) > 0)
|
||||||
$unfixable_count = 0;
|
|
||||||
foreach($results as $package => $source)
|
|
||||||
{
|
{
|
||||||
if($source === null)
|
Console::out('The following packages that are required by other packages are missing:');
|
||||||
|
$unfixable_count = 0;
|
||||||
|
foreach($missing_dependencies as $package => $source)
|
||||||
{
|
{
|
||||||
++$unfixable_count;
|
if($source === null)
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console::out(sprintf(' %s', $package));
|
|
||||||
}
|
|
||||||
|
|
||||||
if($unfixable_count > 0)
|
|
||||||
{
|
|
||||||
Console::out('The following packages packages cannot be fixed because they are missing and no source was specified:');
|
|
||||||
foreach($results as $package => $source)
|
|
||||||
{
|
|
||||||
if($source !== null)
|
|
||||||
{
|
{
|
||||||
|
++$unfixable_count;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::out(sprintf(' %s', $package));
|
Console::out(sprintf(' %s', $package));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($unfixable_count > 0)
|
||||||
|
{
|
||||||
|
Console::out('The following packages packages cannot be fixed because they are missing and no source was specified:');
|
||||||
|
foreach($missing_dependencies as $package => $source)
|
||||||
|
{
|
||||||
|
if($source !== null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console::out(sprintf(' %s', $package));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$auto_yes && !Console::getBooleanInput('Do you want attempt to fix these missing packages?'))
|
if(count($broken_packages) > 0)
|
||||||
|
{
|
||||||
|
Console::out('The following packages are broken and should be removed:');
|
||||||
|
foreach($broken_packages as $package)
|
||||||
|
{
|
||||||
|
Console::out(sprintf(' %s', $package));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!$auto_yes && !Console::getBooleanInput('Do you want attempt to fix these packages?'))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($results as $package => $source)
|
foreach($broken_packages as $package)
|
||||||
|
{
|
||||||
|
Console::out(sprintf('Removing broken package %s', $package));
|
||||||
|
$parsed = explode('=', $package, 2);
|
||||||
|
|
||||||
|
if(count($parsed) === 1)
|
||||||
|
{
|
||||||
|
Console::out(sprintf('Uninstalling all versions of %s, removed %s packages', $package, count($package_manager->uninstall($parsed[0]))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console::out(sprintf('Uninstalling %s, removed %s packages', $package, count($package_manager->uninstall($parsed[0], $parsed[1]))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($missing_dependencies as $package => $source)
|
||||||
{
|
{
|
||||||
if($source === null)
|
if($source === null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
use ncc\Enums\RegexPatterns;
|
use ncc\Enums\RegexPatterns;
|
||||||
use ncc\Enums\Scopes;
|
use ncc\Enums\Scopes;
|
||||||
use ncc\Enums\Types\ProjectType;
|
use ncc\Enums\Types\ProjectType;
|
||||||
|
use ncc\Enums\Versions;
|
||||||
use ncc\Exceptions\ConfigurationException;
|
use ncc\Exceptions\ConfigurationException;
|
||||||
use ncc\Exceptions\IOException;
|
use ncc\Exceptions\IOException;
|
||||||
use ncc\Exceptions\NetworkException;
|
use ncc\Exceptions\NetworkException;
|
||||||
|
@ -200,6 +201,30 @@
|
||||||
|
|
||||||
if($version === null)
|
if($version === null)
|
||||||
{
|
{
|
||||||
|
if($this->package_lock->getEntry($package_name)->isSymlinkRegistered())
|
||||||
|
{
|
||||||
|
Console::outVerbose(sprintf(
|
||||||
|
'Removing symlink for %s=%s at %s',
|
||||||
|
$package_name, $this->package_lock->getEntry($package_name)->getVersion(Versions::LATEST)->getVersion(),
|
||||||
|
PathFinder::findBinPath() . DIRECTORY_SEPARATOR . strtolower($package_name)
|
||||||
|
));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$symlink_path = PathFinder::findBinPath() . DIRECTORY_SEPARATOR . strtolower($this->package_lock->getEntry($package_name)->getAssembly()->getName());
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
throw new IOException(sprintf('Failed to resolve symlink for %s=%s: %s', $package_name, $this->package_lock->getEntry($package_name)->getVersion(Versions::LATEST)->getVersion(), $e->getMessage()), $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(is_file($symlink_path))
|
||||||
|
{
|
||||||
|
(new Filesystem())->remove($symlink_path);
|
||||||
|
$this->package_lock->getEntry($package_name)->setSymlinkRegistered(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach($this->package_lock->getEntry($package_name)->getVersions() as $iter_version)
|
foreach($this->package_lock->getEntry($package_name)->getVersions() as $iter_version)
|
||||||
{
|
{
|
||||||
Console::out(sprintf('Uninstalling package %s=%s', $package_name, $iter_version));
|
Console::out(sprintf('Uninstalling package %s=%s', $package_name, $iter_version));
|
||||||
|
@ -209,11 +234,37 @@
|
||||||
|
|
||||||
$removed_packages[] = sprintf('%s=%s', $package_name, $iter_version);
|
$removed_packages[] = sprintf('%s=%s', $package_name, $iter_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->package_lock->removeEntry($package_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Console::out(sprintf('Uninstalling package %s=%s', $package_name, $version));
|
Console::out(sprintf('Uninstalling package %s=%s', $package_name, $version));
|
||||||
$package_path = $this->package_lock->getPath($package_name, $version);
|
$package_path = $this->package_lock->getPath($package_name, $version);
|
||||||
|
|
||||||
|
if($this->package_lock->getEntry($package_name)->isSymlinkRegistered())
|
||||||
|
{
|
||||||
|
Console::outVerbose(sprintf(
|
||||||
|
'Removing symlink for %s=%s at %s',
|
||||||
|
$package_name, $version, PathFinder::findBinPath() . DIRECTORY_SEPARATOR . strtolower($package_name)
|
||||||
|
));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$symlink_path = PathFinder::findBinPath() . DIRECTORY_SEPARATOR . strtolower($this->package_lock->getEntry($package_name)->getAssembly($version)->getName());
|
||||||
|
}
|
||||||
|
catch(Exception $e)
|
||||||
|
{
|
||||||
|
Console::outWarning(sprintf('Failed to resolve symlink for %s=%s: %s', $package_name, $version, $e->getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($symlink_path) && is_file($symlink_path))
|
||||||
|
{
|
||||||
|
(new Filesystem())->remove($symlink_path);
|
||||||
|
$this->package_lock->getEntry($package_name)->setSymlinkRegistered(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->package_lock->getEntry($package_name)->removeVersion($version);
|
$this->package_lock->getEntry($package_name)->removeVersion($version);
|
||||||
(new Filesystem())->remove($package_path);
|
(new Filesystem())->remove($package_path);
|
||||||
|
|
||||||
|
@ -309,6 +360,31 @@
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of broken packages detected on the system
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getBrokenPackages(): array
|
||||||
|
{
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
foreach($this->package_lock->getEntries() as $entry)
|
||||||
|
{
|
||||||
|
foreach($this->package_lock->getEntry($entry)->getBrokenVersions() as $version)
|
||||||
|
{
|
||||||
|
if(in_array(sprintf('%s=%s', $entry, $version), $results, true))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[] = sprintf('%s=%s', $entry, $version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs a package onto the system from a local ncc package file
|
* Installs a package onto the system from a local ncc package file
|
||||||
*
|
*
|
||||||
|
|
|
@ -459,6 +459,26 @@
|
||||||
return $execution_binary_path;
|
return $execution_binary_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of all broken versions
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getBrokenVersions(): array
|
||||||
|
{
|
||||||
|
$broken_versions = [];
|
||||||
|
|
||||||
|
foreach($this->versions as $version)
|
||||||
|
{
|
||||||
|
if($version->isBroken($this->name))
|
||||||
|
{
|
||||||
|
$broken_versions[] = $version->getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $broken_versions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array representation of the object
|
* Returns an array representation of the object
|
||||||
*
|
*
|
||||||
|
|
|
@ -234,6 +234,31 @@
|
||||||
return $this->getPath($package_name) . DIRECTORY_SEPARATOR . FileDescriptor::SHADOW_PACKAGE;
|
return $this->getPath($package_name) . DIRECTORY_SEPARATOR . FileDescriptor::SHADOW_PACKAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns True if the package is broken, false otherwise
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isBroken(string $package_name): bool
|
||||||
|
{
|
||||||
|
if(!is_file($this->getPath($package_name) . DIRECTORY_SEPARATOR . FileDescriptor::SHADOW_PACKAGE))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_file($this->getPath($package_name) . DIRECTORY_SEPARATOR . FileDescriptor::ASSEMBLY))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!is_file($this->getPath($package_name) . DIRECTORY_SEPARATOR . FileDescriptor::METADATA))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an array representation of the object
|
* Returns an array representation of the object
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Reference in a new issue