Merge branch 'master' into 2.0

main
Jordi Boggiano 5 years ago
commit 6c4357a7ed
No known key found for this signature in database
GPG Key ID: 7BBD42C429EC80BC

@ -30,9 +30,11 @@ matrix:
env:
- deps=high
- php: nightly
- php: 7.4snapshot
fast_finish: true
allow_failures:
- php: nightly
- php: 7.4snapshot
before_install:
# disable xdebug if available

@ -259,6 +259,10 @@ match the platform requirements of the installed packages. This can be used
to verify that a production server has all the extensions needed to run a
project after installing it for example.
Unlike update/install, this command will ignore config.platform settings and
check the real platform packages so you can be certain you have the required
platform dependencies.
## global
The global command allows you to run other commands like `install`, `remove`, `require`

@ -112,6 +112,19 @@ Note that this will still need to pull and scan all of your VCS repositories
because any VCS repository might contain (on any branch) one of the selected
packages.
If you want to scan only the selected package and not all VCS repositories you need
to declare a *name* for all your package (this only work on VCS repositories type) :
```json
{
"repositories": [
{ "name": "company/privaterepo", "type": "vcs", "url": "https://github.com/mycompany/privaterepo" },
{ "name": "private/repo", "type": "vcs", "url": "http://svn.example.org/private/repo" },
{ "name": "mycompany/privaterepo2", "type": "vcs", "url": "https://github.com/mycompany/privaterepo2" }
]
}
```
If you want to scan only a single repository and update all packages found in
it, pass the VCS repository URL as an optional argument:

@ -34,6 +34,8 @@ class CheckPlatformReqsCommand extends BaseCommand
<<<EOT
Checks that your PHP and extensions versions match the platform requirements of the installed packages.
Unlike update/install, this command will ignore config.platform settings and check the real platform packages so you can be certain you have the required platform dependencies.
<info>php composer.phar check-platform-reqs</info>
EOT
@ -49,6 +51,10 @@ EOT
$dependencies = $composer->getLocker()->getLockedRepository(!$input->getOption('no-dev'))->getPackages();
} else {
$dependencies = $composer->getRepositoryManager()->getLocalRepository()->getPackages();
// fallback to lockfile if installed repo is empty
if (!$dependencies) {
$dependencies = $composer->getLocker()->getLockedRepository(true)->getPackages();
}
$requires += $composer->getPackage()->getDevRequires();
}
foreach ($requires as $require => $link) {

@ -168,13 +168,25 @@ EOT
if ($repositories) {
$config = Factory::createConfig($io);
$repos = array(new PlatformRepository);
$createDefaultPackagistRepo = true;
foreach ($repositories as $repo) {
$repos[] = RepositoryFactory::fromString($io, $config, $repo);
$repoConfig = RepositoryFactory::configFromString($io, $config, $repo);
if (
(isset($repoConfig['packagist']) && $repoConfig === array('packagist' => false))
|| (isset($repoConfig['packagist.org']) && $repoConfig === array('packagist.org' => false))
) {
$createDefaultPackagistRepo = false;
continue;
}
$repos[] = RepositoryFactory::createRepo($io, $config, $repoConfig);
}
if ($createDefaultPackagistRepo) {
$repos[] = RepositoryFactory::createRepo($io, $config, array(
'type' => 'composer',
'url' => 'https://repo.packagist.org',
));
}
$repos[] = RepositoryFactory::createRepo($io, $config, array(
'type' => 'composer',
'url' => 'https://repo.packagist.org',
));
$this->repos = new CompositeRepository($repos);
unset($repos, $config, $repositories);

@ -26,6 +26,7 @@ use Composer\Plugin\PluginEvents;
use Composer\Repository\CompositeRepository;
use Composer\Repository\PlatformRepository;
use Composer\IO\IOInterface;
use Composer\Util\Silencer;
/**
* @author Jérémy Romey <jeremy@free-agent.fr>
@ -103,11 +104,6 @@ EOT
return 1;
}
if (!is_writable($this->file)) {
$io->writeError('<error>'.$this->file.' is not writable.</error>');
return 1;
}
if (filesize($this->file) === 0) {
file_put_contents($this->file, "{\n}\n");
@ -116,6 +112,14 @@ EOT
$this->json = new JsonFile($this->file);
$this->composerBackup = file_get_contents($this->json->getPath());
// check for writability by writing to the file as is_writable can not be trusted on network-mounts
// see https://github.com/composer/composer/issues/8231 and https://bugs.php.net/bug.php?id=68926
if (!is_writable($this->file) && !Silencer::call('file_put_contents', $this->file, $this->composerBackup)) {
$io->writeError('<error>'.$this->file.' is not writable.</error>');
return 1;
}
$composer = $this->getComposer(true, $input->getOption('no-plugins'));
$repos = $composer->getRepositoryManager()->getRepositories();
@ -141,7 +145,12 @@ EOT
// validate requirements format
$versionParser = new VersionParser();
foreach ($requirements as $constraint) {
foreach ($requirements as $package => $constraint) {
if (strtolower($package) === $composer->getPackage()->getName()) {
$io->writeError(sprintf('<error>Root package \'%s\' cannot require itself in its composer.json</error>', $package));
return 1;
}
$versionParser->parseConstraints($constraint);
}

@ -379,6 +379,9 @@ class Application extends BaseApplication
public function resetComposer()
{
$this->composer = null;
if ($this->getIO() && method_exists($this->getIO(), 'resetAuthentications')) {
$this->getIO()->resetAuthentications();
}
}
/**

@ -197,7 +197,7 @@ class RuleSetGenerator
}
}
protected function addConflictRules()
protected function addConflictRules($ignorePlatformReqs = false)
{
/** @var PackageInterface $package */
foreach ($this->addedPackages as $package) {
@ -206,6 +206,10 @@ class RuleSetGenerator
continue;
}
if ($ignorePlatformReqs && preg_match(PlatformRepository::PLATFORM_PACKAGE_REGEX, $link->getTarget())) {
continue;
}
/** @var PackageInterface $possibleConflict */
foreach ($this->addedPackagesByNames[$link->getTarget()] as $possibleConflict) {
$conflictMatch = $this->pool->match($possibleConflict, $link->getTarget(), $link->getConstraint(), true);
@ -304,7 +308,7 @@ class RuleSetGenerator
$this->addRulesForJobs($ignorePlatformReqs);
$this->addConflictRules();
$this->addConflictRules($ignorePlatformReqs);
// Remove references to packages
$this->addedPackages = $this->addedPackagesByNames = null;

@ -87,8 +87,6 @@ class PerforceDownloader extends VcsDownloader
public function getLocalChanges(PackageInterface $package, $path)
{
$this->io->writeError('Perforce driver does not check for local changes before overriding', true);
return null;
}
/**

@ -200,7 +200,9 @@ class EventDispatcher
try {
/** @var InstallerEvent $event */
$return = $this->dispatch($scriptName, new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags));
$scriptEvent = new Script\Event($scriptName, $event->getComposer(), $event->getIO(), $event->isDevMode(), $args, $flags);
$scriptEvent->setOriginatingEvent($event);
$return = $this->dispatch($scriptName, $scriptEvent);
} catch (ScriptExecutionException $e) {
$this->io->writeError(sprintf('<error>Script %s was called via %s</error>', $callable, $event->getName()), true, IOInterface::QUIET);
throw $e;

@ -28,6 +28,14 @@ abstract class BaseIO implements IOInterface
return $this->authentications;
}
/**
* {@inheritDoc}
*/
public function resetAuthentications()
{
$this->authentications = array();
}
/**
* {@inheritDoc}
*/

@ -326,9 +326,10 @@ class JsonManipulator
}
// try and find a match for the subkey
if ($this->pregMatch('{"'.preg_quote($name).'"\s*:}i', $children)) {
$keyRegex = str_replace('/', '\\\\?/', preg_quote($name));
if ($this->pregMatch('{"'.$keyRegex.'"\s*:}i', $children)) {
// find best match for the value of "name"
if (preg_match_all('{'.self::$DEFINES.'"'.preg_quote($name).'"\s*:\s*(?:(?&json))}x', $children, $matches)) {
if (preg_match_all('{'.self::$DEFINES.'"'.$keyRegex.'"\s*:\s*(?:(?&json))}x', $children, $matches)) {
$bestMatch = '';
foreach ($matches[0] as $match) {
if (strlen($bestMatch) < strlen($match)) {

@ -16,6 +16,7 @@ use Composer\IO\IOInterface;
use Composer\Json\JsonFile;
use Composer\Package\Loader\ArrayLoader;
use Composer\Package\Loader\LoaderInterface;
use Composer\Util\Zip;
/**
* @author Serge Smertin <serg.smertin@gmail.com>
@ -80,76 +81,15 @@ class ArtifactRepository extends ArrayRepository implements ConfigurableReposito
}
}
/**
* Find a file by name, returning the one that has the shortest path.
*
* @param \ZipArchive $zip
* @param string $filename
* @return bool|int
*/
private function locateFile(\ZipArchive $zip, $filename)
{
$indexOfShortestMatch = false;
$lengthOfShortestMatch = -1;
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
if (strcmp(basename($stat['name']), $filename) === 0) {
$directoryName = dirname($stat['name']);
if ($directoryName == '.') {
//if composer.json is in root directory
//it has to be the one to use.
return $i;
}
if (strpos($directoryName, '\\') !== false ||
strpos($directoryName, '/') !== false) {
//composer.json files below first directory are rejected
continue;
}
$length = strlen($stat['name']);
if ($indexOfShortestMatch === false || $length < $lengthOfShortestMatch) {
//Check it's not a directory.
$contents = $zip->getFromIndex($i);
if ($contents !== false) {
$indexOfShortestMatch = $i;
$lengthOfShortestMatch = $length;
}
}
}
}
return $indexOfShortestMatch;
}
private function getComposerInformation(\SplFileInfo $file)
{
$zip = new \ZipArchive();
if ($zip->open($file->getPathname()) !== true) {
return false;
}
if (0 == $zip->numFiles) {
$zip->close();
$json = Zip::getComposerJson($file->getPathname());
if (null === $json) {
return false;
}
$foundFileIndex = $this->locateFile($zip, 'composer.json');
if (false === $foundFileIndex) {
$zip->close();
return false;
}
$configurationFileName = $zip->getNameIndex($foundFileIndex);
$zip->close();
$composerFile = "zip://{$file->getPathname()}#$configurationFileName";
$json = file_get_contents($composerFile);
$package = JsonFile::parseJson($json, $composerFile);
$package = JsonFile::parseJson($json, $file->getPathname().'#composer.json');
$package['dist'] = array(
'type' => 'zip',
'url' => strtr($file->getPathname(), '\\', '/'),

@ -308,6 +308,10 @@ class GitHubDriver extends VcsDriver
*/
protected function generateSshUrl()
{
if (false !== strpos($this->originUrl, ':')) {
return 'ssh://git@' . $this->originUrl . '/'.$this->owner.'/'.$this->repository.'.git';
}
return 'git@' . $this->originUrl . ':'.$this->owner.'/'.$this->repository.'.git';
}

@ -68,9 +68,9 @@ class GitLabDriver extends VcsDriver
private $isPrivate = true;
/**
* @var int port number
* @var bool true if the origin has a port number or a path component in it
*/
protected $portNumber;
private $hasNonstandardOrigin = false;
const URL_REGEX = '#^(?:(?P<scheme>https?)://(?P<domain>.+?)(?::(?P<port>[0-9]+))?/|git@(?P<domain2>[^:]+):)(?P<parts>.+)/(?P<repo>[^/]+?)(?:\.git|/)?$#';
@ -95,11 +95,10 @@ class GitLabDriver extends VcsDriver
? $match['scheme']
: (isset($this->repoConfig['secure-http']) && $this->repoConfig['secure-http'] === false ? 'http' : 'https')
;
$this->originUrl = $this->determineOrigin($configuredDomains, $guessedDomain, $urlParts);
$this->originUrl = $this->determineOrigin($configuredDomains, $guessedDomain, $urlParts, $match['port']);
if (!empty($match['port']) && true === is_numeric($match['port'])) {
// If it is an HTTP based URL, and it has a port
$this->portNumber = (int) $match['port'];
if (false !== strpos($this->originUrl, ':') || false !== strpos($this->originUrl, '/')) {
$this->hasNonstandardOrigin = true;
}
$this->namespace = implode('/', $urlParts);
@ -260,10 +259,7 @@ class GitLabDriver extends VcsDriver
*/
public function getApiUrl()
{
$domainName = $this->originUrl;
$portNumber = (true === is_numeric($this->portNumber)) ? sprintf(':%s', $this->portNumber) : '';
return $this->scheme.'://'.$domainName.$portNumber.'/api/v4/projects/'.$this->urlEncodeAll($this->namespace).'%2F'.$this->urlEncodeAll($this->repository);
return $this->scheme.'://'.$this->originUrl.'/api/v4/projects/'.$this->urlEncodeAll($this->namespace).'%2F'.$this->urlEncodeAll($this->repository);
}
/**
@ -362,6 +358,10 @@ class GitLabDriver extends VcsDriver
*/
protected function generateSshUrl()
{
if ($this->hasNonstandardOrigin) {
return 'ssh://git@'.$this->originUrl.'/'.$this->namespace.'/'.$this->repository.'.git';
}
return 'git@' . $this->originUrl . ':'.$this->namespace.'/'.$this->repository.'.git';
}
@ -464,7 +464,7 @@ class GitLabDriver extends VcsDriver
$guessedDomain = !empty($match['domain']) ? $match['domain'] : $match['domain2'];
$urlParts = explode('/', $match['parts']);
if (false === self::determineOrigin((array) $config->get('gitlab-domains'), $guessedDomain, $urlParts)) {
if (false === self::determineOrigin((array) $config->get('gitlab-domains'), $guessedDomain, $urlParts, $match['port'])) {
return false;
}
@ -495,16 +495,16 @@ class GitLabDriver extends VcsDriver
* @param array $urlParts
* @return bool|string
*/
private static function determineOrigin(array $configuredDomains, $guessedDomain, array &$urlParts)
private static function determineOrigin(array $configuredDomains, $guessedDomain, array &$urlParts, $portNumber)
{
if (in_array($guessedDomain, $configuredDomains)) {
if (in_array($guessedDomain, $configuredDomains) || ($portNumber && in_array($guessedDomain.':'.$portNumber, $configuredDomains))) {
return $guessedDomain;
}
while (null !== ($part = array_shift($urlParts))) {
$guessedDomain .= '/' . $part;
if (in_array($guessedDomain, $configuredDomains)) {
if (in_array($guessedDomain, $configuredDomains) || ($portNumber && in_array(preg_replace('{/}', ':'.$portNumber.'/', $guessedDomain, 1), $configuredDomains))) {
return $guessedDomain;
}
}

@ -39,6 +39,11 @@ class Event extends BaseEvent
*/
private $devMode;
/**
* @var BaseEvent
*/
private $originatingEvent;
/**
* Constructor.
*
@ -55,6 +60,7 @@ class Event extends BaseEvent
$this->composer = $composer;
$this->io = $io;
$this->devMode = $devMode;
$this->originatingEvent = null;
}
/**
@ -86,4 +92,42 @@ class Event extends BaseEvent
{
return $this->devMode;
}
/**
* Set the originating event.
*
* @return \Composer\EventDispatcher\Event|null
*/
public function getOriginatingEvent()
{
return $this->originatingEvent;
}
/**
* Set the originating event.
*
* @param \Composer\EventDispatcher\Event $event
* @return $this
*/
public function setOriginatingEvent(BaseEvent $event)
{
$this->originatingEvent = $this->calculateOriginatingEvent($event);
return $this;
}
/**
* Returns the upper-most event in chain.
*
* @param \Composer\EventDispatcher\Event $event
* @return \Composer\EventDispatcher\Event
*/
private function calculateOriginatingEvent(BaseEvent $event)
{
if ($event instanceof Event && $event->getOriginatingEvent()) {
return $this->calculateOriginatingEvent($event->getOriginatingEvent());
}
return $event;
}
}

@ -33,6 +33,7 @@ class ErrorHandler
*
* @static
* @throws \ErrorException
* @return bool
*/
public static function handle($level, $message, $file, $line)
{
@ -63,6 +64,8 @@ class ErrorHandler
}, array_slice(debug_backtrace(), 2))));
}
}
return true;
}
/**

@ -57,7 +57,10 @@ class GitLab
*/
public function authorizeOAuth($originUrl)
{
if (!in_array($originUrl, $this->config->get('gitlab-domains'), true)) {
// before composer 1.9, origin URLs had no port number in them
$bcOriginUrl = preg_replace('{:\d+}', '', $originUrl);
if (!in_array($originUrl, $this->config->get('gitlab-domains'), true) && !in_array($bcOriginUrl, $this->config->get('gitlab-domains'), true)) {
return false;
}
@ -77,6 +80,12 @@ class GitLab
return true;
}
if (isset($authTokens[$bcOriginUrl])) {
$this->io->setAuthentication($originUrl, $authTokens[$bcOriginUrl], 'private-token');
return true;
}
return false;
}

@ -363,8 +363,6 @@ class Perforce
while ($line !== false) {
$line = fgets($pipe);
}
return;
}
public function windowsLogin($password)

@ -286,6 +286,8 @@ class RemoteFilesystem
$errorMessage .= "\n";
}
$errorMessage .= preg_replace('{^file_get_contents\(.*?\): }', '', $msg);
return true;
});
try {
$result = $this->getRemoteContents($originUrl, $fileUrl, $ctx, $http_response_header);
@ -459,6 +461,8 @@ class RemoteFilesystem
$errorMessage .= "\n";
}
$errorMessage .= preg_replace('{^file_put_contents\(.*?\): }', '', $msg);
return true;
});
$result = (bool) file_put_contents($fileName, $result);
restore_error_handler();

@ -19,8 +19,6 @@ use Composer\CaBundle\CaBundle;
*/
final class TlsHelper
{
private static $useOpensslParse;
/**
* Match hostname against a certificate.
*

@ -70,6 +70,9 @@ class Url
}
$origin = (string) parse_url($url, PHP_URL_HOST);
if ($port = parse_url($url, PHP_URL_PORT)) {
$origin .= ':'.$port;
}
if (strpos($origin, '.github.com') === (strlen($origin) - 11)) {
return 'github.com';

@ -0,0 +1,108 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Util;
/**
* @author Andreas Schempp <andreas.schempp@terminal42.ch>
*/
class Zip
{
/**
* Gets content of the root composer.json inside a ZIP archive.
*
* @param string $pathToZip
* @param string $filename
*
* @return string|null
*/
public static function getComposerJson($pathToZip)
{
if (!extension_loaded('zip')) {
throw new \RuntimeException('The Zip Util requires PHP\'s zip extension');
}
$zip = new \ZipArchive();
if ($zip->open($pathToZip) !== true) {
return null;
}
if (0 == $zip->numFiles) {
$zip->close();
return null;
}
$foundFileIndex = self::locateFile($zip, 'composer.json');
if (false === $foundFileIndex) {
$zip->close();
return null;
}
$content = null;
$configurationFileName = $zip->getNameIndex($foundFileIndex);
$stream = $zip->getStream($configurationFileName);
if (false !== $stream) {
$content = stream_get_contents($stream);
}
$zip->close();
return $content;
}
/**
* Find a file by name, returning the one that has the shortest path.
*
* @param \ZipArchive $zip
* @param string $filename
*
* @return bool|int
*/
private static function locateFile(\ZipArchive $zip, $filename)
{
$indexOfShortestMatch = false;
$lengthOfShortestMatch = -1;
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
if (strcmp(basename($stat['name']), $filename) === 0) {
$directoryName = dirname($stat['name']);
if ($directoryName === '.') {
//if composer.json is in root directory
//it has to be the one to use.
return $i;
}
if (strpos($directoryName, '\\') !== false ||
strpos($directoryName, '/') !== false) {
//composer.json files below first directory are rejected
continue;
}
$length = strlen($stat['name']);
if ($indexOfShortestMatch === false || $length < $lengthOfShortestMatch) {
//Check it's not a directory.
$contents = $zip->getFromIndex($i);
if ($contents !== false) {
$indexOfShortestMatch = $i;
$lengthOfShortestMatch = $length;
}
}
}
}
return $indexOfShortestMatch;
}
}

@ -162,18 +162,18 @@ class AllFunctionalTest extends TestCase
}
};
for ($i = 0, $c = count($tokens); $i < $c; $i++) {
if ('' === $tokens[$i] && null === $section) {
foreach ($tokens as $token) {
if ('' === $token && null === $section) {
continue;
}
// Handle section headers.
if (null === $section) {
$section = $tokens[$i];
$section = $token;
continue;
}
$sectionData = $tokens[$i];
$sectionData = $token;
// Allow sections to validate, or modify their section data.
switch ($section) {

@ -152,11 +152,4 @@ class RuleSetTest extends TestCase
$this->assertContains('JOB : Install command rule (install foo 2.1)', $ruleSet->getPrettyString($pool));
}
private function getRuleMock()
{
return $this->getMockBuilder('Composer\DependencyResolver\Rule')
->disableOriginalConstructor()
->getMock();
}
}

@ -1448,6 +1448,22 @@ class JsonManipulatorTest extends TestCase
"repositories": {
}
}
',
),
'works on simple ones escaped slash' => array(
'{
"repositories": {
"foo\/bar": {
"bar": "baz"
}
}
}',
'foo/bar',
true,
'{
"repositories": {
}
}
',
),
'works on simple ones middle' => array(

@ -148,7 +148,6 @@ class ArrayLoaderTest extends TestCase
{
$package = $this->loader->load($config);
$dumper = new ArrayDumper;
$expectedConfig = $config;
$expectedConfig = $this->fixConfigWhenLoadConfigIsFalse($config);
$this->assertEquals($expectedConfig, $dumper->dump($package));
}

@ -40,15 +40,6 @@ class FossilDriverTest extends TestCase
$fs->removeDirectory($this->home);
}
private function getCmd($cmd)
{
if (Platform::isWindows()) {
return strtr($cmd, "'", '"');
}
return $cmd;
}
public static function supportProvider()
{
return array(

@ -71,15 +71,6 @@ class SvnDriverTest extends TestCase
$svn->initialize();
}
private function getCmd($cmd)
{
if (Platform::isWindows()) {
return strtr($cmd, "'", '"');
}
return $cmd;
}
public static function supportProvider()
{
return array(

@ -0,0 +1,80 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Test\Script;
use Composer\Composer;
use Composer\Config;
use Composer\Script\Event;
use Composer\Test\TestCase;
class EventTest extends TestCase
{
public function testEventSetsOriginatingEvent()
{
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
$composer = $this->createComposerInstance();
$originatingEvent = new \Composer\EventDispatcher\Event('originatingEvent');
$scriptEvent = new Event('test', $composer, $io, true);
$this->assertNull(
$scriptEvent->getOriginatingEvent(),
'originatingEvent is initialized as null'
);
$scriptEvent->setOriginatingEvent($originatingEvent);
$this->assertSame(
$originatingEvent,
$scriptEvent->getOriginatingEvent(),
'getOriginatingEvent() SHOULD return test event'
);
}
public function testEventCalculatesNestedOriginatingEvent()
{
$io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
$composer = $this->createComposerInstance();
$originatingEvent = new \Composer\EventDispatcher\Event('upperOriginatingEvent');
$intermediateEvent = new Event('intermediate', $composer, $io, true);
$intermediateEvent->setOriginatingEvent($originatingEvent);
$scriptEvent = new Event('test', $composer, $io, true);
$scriptEvent->setOriginatingEvent($intermediateEvent);
$this->assertNotSame(
$intermediateEvent,
$scriptEvent->getOriginatingEvent(),
'getOriginatingEvent() SHOULD NOT return intermediate events'
);
$this->assertSame(
$originatingEvent,
$scriptEvent->getOriginatingEvent(),
'getOriginatingEvent() SHOULD return upper-most event'
);
}
private function createComposerInstance()
{
$composer = new Composer;
$config = new Config;
$composer->setConfig($config);
$package = $this->getMockBuilder('Composer\Package\RootPackageInterface')->getMock();
$composer->setPackage($package);
return $composer;
}
}

@ -24,12 +24,9 @@ use RecursiveIteratorIterator;
*/
class GitHubTest extends TestCase
{
private $username = 'username';
private $password = 'password';
private $authcode = 'authcode';
private $message = 'mymessage';
private $origin = 'github.com';
private $token = 'githubtoken';
public function testUsernamePasswordAuthenticationFlow()
{

@ -24,7 +24,6 @@ class GitLabTest extends TestCase
{
private $username = 'username';
private $password = 'password';
private $authcode = 'authcode';
private $message = 'mymessage';
private $origin = 'gitlab.com';
private $token = 'gitlabtoken';

@ -0,0 +1,117 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Test\Util;
use Composer\Util\Zip;
use PHPUnit\Framework\TestCase;
/**
* @author Andreas Schempp <andreas.schempp@terminal42.ch>
*/
class ZipTest extends TestCase
{
public function testThrowsExceptionIfZipExcentionIsNotLoaded()
{
if (extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is loaded.');
}
$this->setExpectedException('\RuntimeException', 'The Zip Util requires PHP\'s zip extension');
Zip::getComposerJson('');
}
public function testReturnsNullifTheZipIsNotFound()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/invalid.zip');
$this->assertNull($result);
}
public function testReturnsNullIfTheZipIsEmpty()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/empty.zip');
$this->assertNull($result);
}
public function testReturnsNullIfTheZipHasNoComposerJson()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/nojson.zip');
$this->assertNull($result);
}
public function testReturnsNullIfTheComposerJsonIsInASubSubfolder()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/subfolder.zip');
$this->assertNull($result);
}
public function testReturnsComposerJsonInZipRoot()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/root.zip');
$this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result);
}
public function testReturnsComposerJsonInFirstFolder()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/folder.zip');
$this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result);
}
public function testReturnsRootComposerJsonAndSkipsSubfolders()
{
if (!extension_loaded('zip')) {
$this->markTestSkipped('The PHP zip extension is not loaded.');
return;
}
$result = Zip::getComposerJson(__DIR__.'/Fixtures/Zip/multiple.zip');
$this->assertEquals("{\n \"name\": \"foo/bar\"\n}\n", $result);
}
}
Loading…
Cancel
Save