diff --git a/.gitignore b/.gitignore
index 57872d0..55940e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
/vendor/
+composer.lock
\ No newline at end of file
diff --git a/README.md b/README.md
index e8511dd..85f3eab 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ $configurator->onCompile[] = function ($config, Nette\Config\Compiler $compiler)
composerUpdates:
cacheDir: %tempDir%/cache
- localConfigFile: %wwwDir%/../composer.json
+ rootDir: %wwwDir%/..
```
Screenshots
diff --git a/composer.json b/composer.json
index 94ae20b..5502ae2 100644
--- a/composer.json
+++ b/composer.json
@@ -4,6 +4,10 @@
{
"name": "Matej Koubik",
"email": "matej@koubik.name"
+ },
+ {
+ "name": "Jáchym Toušek",
+ "email": "enumag@gmail.com"
}
],
"license": ["BSD-2-Clause"],
diff --git a/src/ComposerUpdates/DI/ComposerUpdatesExtension.php b/src/ComposerUpdates/DI/ComposerUpdatesExtension.php
index 3f19ebf..e077067 100644
--- a/src/ComposerUpdates/DI/ComposerUpdatesExtension.php
+++ b/src/ComposerUpdates/DI/ComposerUpdatesExtension.php
@@ -8,27 +8,27 @@ class ComposerUpdatesExtension extends Nette\DI\CompilerExtension
{
private $defaults = array(
'cacheDir' => NULL,
- 'localConfigFile' => NULL,
+ 'rootDir' => NULL,
);
public function loadConfiguration()
{
$config = $this->getConfig($this->defaults);
- if (!is_dir($config['cacheDir']) || !is_file($config['localConfigFile'])) {
+ if (!is_dir($config['cacheDir']) || !is_dir($config['rootDir'])) {
throw new \InvalidArgumentException("Please configure the ComposerUpdates extensions using the section '{$this->name}:' in your config file.");
}
$builder = $this->getContainerBuilder();
$builder->addDefinition($this->prefix('initializer'))
- ->setClass('ComposerUpdates\Initializer', array($config['cacheDir'], $config['localConfigFile']));
+ ->setClass('ComposerUpdates\Initializer', array($config['cacheDir'], $config['rootDir']));
$builder->addDefinition($this->prefix('service'))
->setClass('ComposerUpdates\Service');
$builder->addDefinition($this->prefix('panel'))
- ->setClass('ComposerUpdates\Diagnostics\ComposerUpdatesPanel');
+ ->setClass('ComposerUpdates\Diagnostics\ComposerUpdatesPanel', array($config['rootDir']));
}
public function afterCompile(Nette\PhpGenerator\ClassType $class)
diff --git a/src/ComposerUpdates/Diagnostics/ComposerUpdatesPanel.php b/src/ComposerUpdates/Diagnostics/ComposerUpdatesPanel.php
index 2cd94ed..bc3bcfa 100644
--- a/src/ComposerUpdates/Diagnostics/ComposerUpdatesPanel.php
+++ b/src/ComposerUpdates/Diagnostics/ComposerUpdatesPanel.php
@@ -10,9 +10,19 @@ class ComposerUpdatesPanel extends Nette\Object implements Nette\Diagnostics\IBa
/** @var ComposerUpdates\PackageInfo[] */
private $packages;
- public function __construct(ComposerUpdates\Service $service)
+ public function __construct($rootDir, ComposerUpdates\Service $service, Nette\Caching\IStorage $storage)
{
- $this->packages = $service->getPackages();
+ $cache = new Nette\Caching\Cache($storage, 'ComposerUpdates.panel');
+ $this->packages = $cache->load($rootDir, function (& $dependencies) use ($rootDir, $service) {
+ $dependencies = array(
+ Nette\Caching\Cache::EXPIRATION => '1 hour',
+ Nette\Caching\Cache::FILES => array(
+ $rootDir . '/composer.json',
+ $rootDir . '/composer.lock',
+ ),
+ );
+ return array_merge($service->getPackages(), $service->getDevPackages());
+ });
}
/**
@@ -21,15 +31,21 @@ public function __construct(ComposerUpdates\Service $service)
*/
public function getTab()
{
- if (empty($this->packages)) {
+ if (!$this->packages) {
return;
}
-
- $updates = array_filter($this->packages, function(ComposerUpdates\PackageInfo $package) {
- return $package->isUpdateAvailable();
- });
+
+ $status = max(array_map(function(ComposerUpdates\PackageInfo $package) {
+ return $package->getStatus();
+ }, $this->packages));
+
+ $updates = count(array_filter($this->packages, function(ComposerUpdates\PackageInfo $package) {
+ $status = $package->getStatus();
+ return $status !== ComposerUpdates\PackageInfo::STATUS_NO_UPDATE && $status !== ComposerUpdates\PackageInfo::STATUS_NOT_INSTALLED;
+ }));
return self::render(__DIR__ . '/templates/tab.phtml', array(
+ 'status' => $status,
'updates' => $updates,
));
}
@@ -40,18 +56,19 @@ public function getTab()
*/
public function getPanel()
{
- if (empty($this->packages)) {
+ if (!$this->packages) {
return;
}
- uasort($this->packages, function (ComposerUpdates\PackageInfo $package1, ComposerUpdates\PackageInfo $package2) {
- $update1 = $package1->isUpdateAvailable();
- $update2 = $package2->isUpdateAvailable();
- return $update1 !== $update2 ? $update1 < $update2 : $package1->getName() > $package2->getName();
+ $packages = $this->packages;
+ uksort($packages, function ($key1, $key2) use ($packages) {
+ $status1 = $packages[$key1]->getStatus();
+ $status2 = $packages[$key2]->getStatus();
+ return $status1 !== $status2 ? $status1 < $status2 : $key1 > $key2;
});
return self::render(__DIR__ . '/templates/panel.phtml', array(
- 'packages' => $this->packages,
+ 'packages' => $packages,
));
}
diff --git a/src/ComposerUpdates/Diagnostics/templates/panel.phtml b/src/ComposerUpdates/Diagnostics/templates/panel.phtml
index f7b1a60..6048960 100644
--- a/src/ComposerUpdates/Diagnostics/templates/panel.phtml
+++ b/src/ComposerUpdates/Diagnostics/templates/panel.phtml
@@ -1,6 +1,6 @@
+ 'not-installed',
+ \ComposerUpdates\PackageInfo::STATUS_NO_UPDATE => 'no-update',
+ \ComposerUpdates\PackageInfo::STATUS_INCOMPATIBLE_UPDATE => 'incompatible-update',
+ \ComposerUpdates\PackageInfo::STATUS_COMPATIBLE_UPDATE => 'compatible-update',
+);
+?>
+
Composer updates
+
+ - There is no newer version of this library.
+ - There is newer version but it may not be compatible with your project. Update with caution.
+ - There is newer version compatible with your project. Update is recommended.
+ - This library is not currently installed.
+
| Package |
Version |
- Update |
+ Compatible |
+ Incompatible |
|
- isUpdateAvailable()) { ?>
-
-
-
-
+
getName()) ?>
+ isDevOnly()) { ?>
+ (dev only)
+
|
getInstalledVersion() ?>
|
- isUpdateAvailable()) { ?>
- getAvailableVersion() ?> available
+ isCompatibleUpdateAvailable()) { ?>
+ getCompatibleUpdate() ?> available
+
+ |
+
+ isIncompatibleUpdateAvailable()) { ?>
+ getIncompatibleUpdate() ?> available
|
diff --git a/src/ComposerUpdates/Diagnostics/templates/tab.phtml b/src/ComposerUpdates/Diagnostics/templates/tab.phtml
index 290ee62..1a35c23 100644
--- a/src/ComposerUpdates/Diagnostics/templates/tab.phtml
+++ b/src/ComposerUpdates/Diagnostics/templates/tab.phtml
@@ -1,6 +1,8 @@
+ 'not-installed',
+ \ComposerUpdates\PackageInfo::STATUS_NO_UPDATE => 'no-update',
+ \ComposerUpdates\PackageInfo::STATUS_INCOMPATIBLE_UPDATE => 'incompatible-update',
+ \ComposerUpdates\PackageInfo::STATUS_COMPATIBLE_UPDATE => 'compatible-update',
+);
+?>
+
+
- up to date
+ no update
-
+
diff --git a/src/ComposerUpdates/Initializer.php b/src/ComposerUpdates/Initializer.php
index 41749fb..fc1aa39 100644
--- a/src/ComposerUpdates/Initializer.php
+++ b/src/ComposerUpdates/Initializer.php
@@ -7,7 +7,7 @@
class Initializer
{
private $cacheDir;
- private $localConfigFile;
+ private $rootDir;
/** @var Composer\IO\IOInterface */
private $io;
@@ -23,16 +23,16 @@ class Initializer
/** @var Composer\Repository\RepositoryInterface */
private $installedRepository;
- /** @var Composer\PAckage\RootPackageInterface */
+ /** @var Composer\Package\RootPackageInterface */
private $rootPackage;
/** @var Composer\DependencyResolver\Pool */
private $packagePool;
- public function __construct($cacheDir, $localConfigFile)
+ public function __construct($cacheDir, $rootDir)
{
- $this->cacheDir = $cacheDir . '/_ComposerUpdates';
- $this->localConfigFile = $localConfigFile;
+ $this->cacheDir = $cacheDir . '/_ComposerUpdates.composer';
+ $this->rootDir = $rootDir;
$this->io = new Composer\IO\NullIO();
}
@@ -82,7 +82,7 @@ public function getDevRequires()
private function getConfig()
{
if ($this->config === NULL || $this->localConfig === NULL) {
- $json = new Composer\Json\JsonFile($this->localConfigFile);
+ $json = new Composer\Json\JsonFile($this->rootDir . '/composer.json');
$this->localConfig = $json->read();
$this->config = new Composer\Config;
@@ -98,7 +98,7 @@ private function getConfig()
private function getVendorDir()
{
- return dirname($this->localConfigFile) . '/' . $this->getConfig()->get('vendor-dir');
+ return $this->rootDir . '/' . $this->getConfig()->get('vendor-dir');
}
private function getRepositoryManager()
diff --git a/src/ComposerUpdates/NullVersion.php b/src/ComposerUpdates/NullVersion.php
index b962af4..6edc2f1 100644
--- a/src/ComposerUpdates/NullVersion.php
+++ b/src/ComposerUpdates/NullVersion.php
@@ -2,16 +2,11 @@
namespace ComposerUpdates;
-use composer\Package\PackageInterface;
-
class NullVersion extends Version
{
- protected $version;
-
- protected $prettyVersion;
-
public function __construct()
{
$this->version = -1;
+ $this->prettyVersion = 'none';
}
}
diff --git a/src/ComposerUpdates/PackageInfo.php b/src/ComposerUpdates/PackageInfo.php
index 85757bf..54dccf0 100644
--- a/src/ComposerUpdates/PackageInfo.php
+++ b/src/ComposerUpdates/PackageInfo.php
@@ -4,26 +4,45 @@
class PackageInfo
{
+ const STATUS_NOT_INSTALLED = 0;
+ const STATUS_NO_UPDATE = 1;
+ const STATUS_INCOMPATIBLE_UPDATE = 2;
+ const STATUS_COMPATIBLE_UPDATE = 3;
+
+ /** @var string*/
private $name;
/** @var Version */
private $installedVersion;
-
+
/** @var Version[] */
- private $newVersions;
+ private $compatibleUpdates;
+
+ /** @var Version[] */
+ private $incompatibleUpdates;
+
+ /** @var bool */
+ private $devOnly;
/**
* @param string $name
* @param Version $installedVersion
- * @param Version[] $newVersions
+ * @param Version[] $compatibleUpdates
+ * @param Version[] $incompatibleUpdates
+ * @param bool $devOnly
*/
- public function __construct($name, Version $installedVersion, array $newVersions)
+ public function __construct($name, Version $installedVersion, array $compatibleUpdates, array $incompatibleUpdates, $devOnly)
{
$this->name = $name;
$this->installedVersion = $installedVersion;
- $this->newVersions = $newVersions;
+ $this->compatibleUpdates = $compatibleUpdates;
+ $this->incompatibleUpdates = $incompatibleUpdates;
+ $this->devOnly = $devOnly;
}
+ /**
+ * @return string
+ */
public function getName()
{
return $this->name;
@@ -37,21 +56,67 @@ public function getInstalledVersion()
return $this->installedVersion;
}
+ /**
+ * @return int
+ */
+ public function getStatus()
+ {
+ if ($this->installedVersion instanceof NullVersion) {
+ return self::STATUS_NOT_INSTALLED;
+ } elseif ($this->compatibleUpdates) {
+ return self::STATUS_COMPATIBLE_UPDATE;
+ } elseif ($this->incompatibleUpdates) {
+ return self::STATUS_INCOMPATIBLE_UPDATE;
+ } else {
+ return self::STATUS_NO_UPDATE;
+ }
+ }
+
+ /**
+ * @return bool
+ */
+ public function isDevOnly()
+ {
+ return $this->devOnly;
+ }
+
/**
* @return bool
- */
- public function isUpdateAvailable()
+ */
+ public function isCompatibleUpdateAvailable()
+ {
+ return (bool) $this->compatibleUpdates;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isIncompatibleUpdateAvailable()
{
- return count($this->newVersions) > 0;
+ return (bool) $this->incompatibleUpdates;
+ }
+
+ /**
+ * @return Version
+ */
+ public function getCompatibleUpdate()
+ {
+ $max = new NullVersion();
+ foreach ($this->compatibleUpdates as $version) {
+ if ($version->isGreaterThan($max)) {
+ $max = $version;
+ }
+ }
+ return $max;
}
/**
* @return Version
*/
- public function getAvailableVersion()
+ public function getIncompatibleUpdate()
{
$max = new NullVersion();
- foreach ($this->newVersions as $version) {
+ foreach ($this->incompatibleUpdates as $version) {
if ($version->isGreaterThan($max)) {
$max = $version;
}
diff --git a/src/ComposerUpdates/Service.php b/src/ComposerUpdates/Service.php
index 834e75d..79e7b54 100644
--- a/src/ComposerUpdates/Service.php
+++ b/src/ComposerUpdates/Service.php
@@ -27,32 +27,45 @@ public function getPackages()
public function getDevPackages()
{
$requires = $this->initializer->getDevRequires();
- return $this->getPackagesFromRequires($requires);
+ return $this->getPackagesFromRequires($requires, TRUE);
}
- private function getPackagesFromRequires(array $requires)
+ private function getPackagesFromRequires(array $requires, $devOnly = FALSE)
{
$installedRepo = $this->initializer->getInstalledRepository();
- $pool = $this->initializer->getPackagePool();
$installedVersions = array();
foreach ($installedRepo->getPackages() as $package) {
$installedVersions[$package->getName()] = new Version($package);
}
+ $pool = $this->initializer->getPackagePool();
$packages = array();
foreach ($requires as $link) {
$name = $link->getTarget();
+ if (strpos($name, '/') === FALSE) {
+ continue;
+ }
+ $currentVersion = isset($installedVersions[$name]) ? $installedVersions[$name] : new NullVersion();
+
$provides = $pool->whatProvides($name, $link->getConstraint());
$versions = array_map(function ($package) {
return new Version($package);
}, $provides);
- $currentVersion = isset($installedVersions[$name]) ? $installedVersions[$name] : new NullVersion();
- $newVersions = array_filter($versions, function($version) use ($currentVersion) {
+ $compatibleUpdates = array_filter($versions, function($version) use ($currentVersion) {
return $version->isGreaterThan($currentVersion);
});
- $packages[] = new PackageInfo($name, $installedVersions[$name], $newVersions);
+
+ $provides = $pool->whatProvides($name);
+ $versions = array_map(function ($package) {
+ return new Version($package);
+ }, $provides);
+ $incompatibleUpdates = array_filter($versions, function($version) use ($currentVersion) {
+ return $version->isGreaterThan($currentVersion);
+ });
+
+ $packages[] = new PackageInfo($name, $currentVersion, $compatibleUpdates, $incompatibleUpdates, $devOnly);
}
return $packages;
diff --git a/src/ComposerUpdates/Version.php b/src/ComposerUpdates/Version.php
index e0654ed..72345ee 100644
--- a/src/ComposerUpdates/Version.php
+++ b/src/ComposerUpdates/Version.php
@@ -17,13 +17,11 @@ class Version
public function __construct(PackageInterface $package)
{
$this->version = $package->getVersion();
- $this->prettyVersion = $package->getPrettyVersion();
-
// v0.9.0-alpha5 => 0.9.0-alpha5
- $semverString = preg_replace('/^v/', '', $this->prettyVersion);
+ $this->prettyVersion = preg_replace('/^v/', '', $package->getPrettyVersion());
try {
- $this->semver = SemVer\Version::parse($semverString);
+ $this->semver = SemVer\Version::parse($this->prettyVersion);
} catch (\InvalidArgumentException $e) {
$this->semver = NULL;
}
diff --git a/tests/ComposerUpdates/PackageInfo.phpt b/tests/ComposerUpdates/PackageInfo.phpt
index 213ac17..26ffce7 100644
--- a/tests/ComposerUpdates/PackageInfo.phpt
+++ b/tests/ComposerUpdates/PackageInfo.phpt
@@ -10,17 +10,20 @@ test(function() {
$v2_0_10 = createVersion('nette/nette', '2.0.10.0', 'v2.0.10');
$v2_0_11 = createVersion('nette/nette', '2.0.11.0', 'v2.0.11');
$v2_0_12 = createVersion('nette/nette', '2.0.12.0', 'v2.0.12');
- $info = new PackageInfo('nette/nette', $v2_0_10, array($v2_0_11, $v2_0_12));
+ $info = new PackageInfo('nette/nette', $v2_0_10, array($v2_0_11, $v2_0_12), array(), FALSE);
- Assert::true($info->isUpdateAvailable());
- Assert::equal('v2.0.12', (string) $info->getAvailableVersion());
+ Assert::true($info->isCompatibleUpdateAvailable());
+ Assert::false($info->isIncompatibleUpdateAvailable());
+ Assert::same(PackageInfo::STATUS_COMPATIBLE_UPDATE, $info->getStatus());
+ Assert::equal('2.0.12', (string) $info->getCompatibleUpdate());
});
test(function() {
$v2_0_12 = createVersion('nette/nette', '2.0.12.0', 'v2.0.12');
- $info = new PackageInfo('nette/nette', $v2_0_12, array());
+ $info = new PackageInfo('nette/nette', $v2_0_12, array(), array(), FALSE);
- Assert::false($info->isUpdateAvailable());
+ Assert::false($info->isCompatibleUpdateAvailable());
+ Assert::false($info->isIncompatibleUpdateAvailable());
});
function createVersion($name, $version, $prettyVersion) {