move json parsing instructions into single class object

main
everzet 13 years ago
parent 96122aada8
commit 1cca62dc97

@ -13,7 +13,9 @@ use Composer\Console\Application as ComposerApplication;
// initialize repository manager // initialize repository manager
$rm = new Repository\RepositoryManager(); $rm = new Repository\RepositoryManager();
$rm->setLocalRepository(new Repository\PlatformRepository(new Repository\FilesystemRepository('.composer/installed.json'))); $rm->setLocalRepository(new Repository\PlatformRepository(
new Repository\FilesystemRepository(new JsonFile('.composer/installed.json'))
));
$rm->setRepository('Packagist', new Repository\ComposerRepository('http://packagist.org')); $rm->setRepository('Packagist', new Repository\ComposerRepository('http://packagist.org'));
// initialize download manager // initialize download manager
@ -28,7 +30,7 @@ $im->setInstaller('library', new Installer\LibraryInstaller('vendor', $dm, $rm->
// load package // load package
$loader = new Package\Loader\JsonLoader(); $loader = new Package\Loader\JsonLoader();
$package = $loader->load('composer.json'); $package = $loader->load(new JsonFile('composer.json'));
// init locker // init locker

@ -53,8 +53,31 @@ class JsonFile
public function read() public function read()
{ {
$json = file_get_contents($this->path); $json = file_get_contents($this->path);
$config = json_decode($json, true);
if (!$config) { return static::parseJson($json);
}
/**
* Writes json file.
*
* @param array $hash writes hash into json file
*/
public function write(array $hash)
{
file_put_contents($this->path, json_encode($hash));
}
/**
* Parses json string and returns hash.
*
* @param string $json json string
*
* @return array
*/
public static function parseJson($json)
{
$hash = json_decode($json, true);
if (!$hash) {
switch (json_last_error()) { switch (json_last_error()) {
case JSON_ERROR_NONE: case JSON_ERROR_NONE:
$msg = 'No error has occurred, is your composer.json file empty?'; $msg = 'No error has occurred, is your composer.json file empty?';
@ -78,16 +101,6 @@ class JsonFile
throw new \UnexpectedValueException('Incorrect composer.json file: '.$msg); throw new \UnexpectedValueException('Incorrect composer.json file: '.$msg);
} }
return $config; return $hash;
}
/**
* Writes json file.
*
* @param array $hash writes hash into json file
*/
public function write(array $hash)
{
file_put_contents($this->path, json_encode($hash));
} }
} }

@ -12,6 +12,8 @@
namespace Composer\Package\Loader; namespace Composer\Package\Loader;
use Composer\Json\JsonFile;
/** /**
* @author Konstantin Kudryashiv <ever.zet@gmail.com> * @author Konstantin Kudryashiv <ever.zet@gmail.com>
*/ */
@ -19,42 +21,12 @@ class JsonLoader extends ArrayLoader
{ {
public function load($json) public function load($json)
{ {
$config = $this->loadJsonConfig($json); if ($json instanceof JsonFile) {
$json = $json->read();
return parent::load($config); } elseif (is_string($json)) {
} $json = JsonFile::parseJson($json);
private function loadJsonConfig($json)
{
if (is_file($json)) {
$json = file_get_contents($json);
} }
$config = json_decode($json, true); return parent::load($config);
if (!$config) {
switch (json_last_error()) {
case JSON_ERROR_NONE:
$msg = 'No error has occurred, is your composer.json file empty?';
break;
case JSON_ERROR_DEPTH:
$msg = 'The maximum stack depth has been exceeded';
break;
case JSON_ERROR_STATE_MISMATCH:
$msg = 'Invalid or malformed JSON';
break;
case JSON_ERROR_CTRL_CHAR:
$msg = 'Control character error, possibly incorrectly encoded';
break;
case JSON_ERROR_SYNTAX:
$msg = 'Syntax error';
break;
case JSON_ERROR_UTF8:
$msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
break;
}
throw new \UnexpectedValueException('Incorrect composer.json file: '.$msg);
}
return $config;
} }
} }

@ -14,6 +14,7 @@ namespace Composer\Repository;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Json\JsonFile;
/** /**
* @author Jordi Boggiano <j.boggiano@seld.be> * @author Jordi Boggiano <j.boggiano@seld.be>
@ -36,7 +37,8 @@ class ComposerRepository extends ArrayRepository
protected function initialize() protected function initialize()
{ {
parent::initialize(); parent::initialize();
$packages = @json_decode(file_get_contents($this->url.'/packages.json'), true); $json = new JsonFile($this->url.'/packages.json');
$packages = $json->read();
if (!$packages) { if (!$packages) {
throw new \UnexpectedValueException('Could not parse package list from the '.$this->url.' repository'); throw new \UnexpectedValueException('Could not parse package list from the '.$this->url.' repository');
} }

@ -12,6 +12,7 @@
namespace Composer\Repository; namespace Composer\Repository;
use Composer\Json\JsonFile;
use Composer\Package\PackageInterface; use Composer\Package\PackageInterface;
use Composer\Package\Loader\ArrayLoader; use Composer\Package\Loader\ArrayLoader;
use Composer\Package\Dumper\ArrayDumper; use Composer\Package\Dumper\ArrayDumper;
@ -28,25 +29,11 @@ class FilesystemRepository extends ArrayRepository implements WritableRepository
/** /**
* Initializes filesystem repository. * Initializes filesystem repository.
* *
* @param string $group registry (installer) group * @param JsonFile $repositoryFile repository json file
*/ */
public function __construct($repositoryFile) public function __construct(JsonFile $repositoryFile)
{ {
$this->file = $repositoryFile; $this->file = $repositoryFile;
$path = dirname($this->file);
if (!is_dir($path)) {
if (file_exists($path)) {
throw new \UnexpectedValueException(
$path.' exists and is not a directory.'
);
}
if (!mkdir($path, 0777, true)) {
throw new \UnexpectedValueException(
$path.' does not exist and could not be created.'
);
}
}
} }
/** /**
@ -56,8 +43,7 @@ class FilesystemRepository extends ArrayRepository implements WritableRepository
{ {
parent::initialize(); parent::initialize();
$packages = @json_decode(file_get_contents($this->file), true); $packages = $this->file->read();
if (is_array($packages)) { if (is_array($packages)) {
$loader = new ArrayLoader(); $loader = new ArrayLoader();
foreach ($packages as $package) { foreach ($packages as $package) {
@ -77,6 +63,6 @@ class FilesystemRepository extends ArrayRepository implements WritableRepository
$packages[] = $dumper->dump($package); $packages[] = $dumper->dump($package);
} }
file_put_contents($this->file, json_encode($packages)); $this->file->write($packages);
} }
} }

@ -16,6 +16,7 @@ use Composer\Package\MemoryPackage;
use Composer\Package\BasePackage; use Composer\Package\BasePackage;
use Composer\Package\Link; use Composer\Package\Link;
use Composer\Package\LinkConstraint\VersionConstraint; use Composer\Package\LinkConstraint\VersionConstraint;
use Composer\Json\JsonFile;
/** /**
* FIXME This is majorly broken and incomplete, it was an experiment * FIXME This is majorly broken and incomplete, it was an experiment
@ -45,7 +46,8 @@ class GitRepository extends ArrayRepository
if (!file_exists($this->url.'/composer.json')) { if (!file_exists($this->url.'/composer.json')) {
throw new \InvalidArgumentException('The repository at url '.$this->url.' does not contain a composer.json file.'); throw new \InvalidArgumentException('The repository at url '.$this->url.' does not contain a composer.json file.');
} }
$config = json_decode(file_get_contents($this->url.'/composer.json'), true); $json = new JsonFile($this->url.'/composer.json');
$fonfig = $json->read();
if (!$config) { if (!$config) {
throw new \UnexpectedValueException('Config file could not be parsed: '.$this->url.'/composer.json. Probably a JSON syntax error.'); throw new \UnexpectedValueException('Config file could not be parsed: '.$this->url.'/composer.json. Probably a JSON syntax error.');
} }

@ -13,43 +13,56 @@
namespace Composer\Repository; namespace Composer\Repository;
use Composer\Repository\FilesystemRepository; use Composer\Repository\FilesystemRepository;
use Composer\Package\MemoryPackage;
class FilesystemRepositoryTest extends \PHPUnit_Framework_TestCase class FilesystemRepositoryTest extends \PHPUnit_Framework_TestCase
{ {
private $dir; public function testRepositoryRead()
private $repositoryFile;
protected function setUp()
{ {
$this->dir = sys_get_temp_dir().'/.composer'; $json = $this->createJsonFileMock();
$this->repositoryFile = $this->dir.'/some_registry-reg.json';
if (file_exists($this->repositoryFile)) { $repository = new FilesystemRepository($json);
unlink($this->repositoryFile);
} $json
->expects($this->once())
->method('read')
->will($this->returnValue(array(
array('name' => 'package1', 'version' => '1.0.0-beta', 'type' => 'vendor')
)));
$packages = $repository->getPackages();
$this->assertSame(1, count($packages));
$this->assertSame('package1', $packages[0]->getName());
$this->assertSame('1.0.0.0-beta', $packages[0]->getVersion());
$this->assertSame('vendor', $packages[0]->getType());
} }
public function testRepositoryReadWrite() public function testRepositoryWrite()
{ {
$this->assertFileNotExists($this->repositoryFile); $json = $this->createJsonFileMock();
$repository = new FilesystemRepository($this->repositoryFile);
$repository->getPackages(); $repository = new FilesystemRepository($json);
$repository->write();
$this->assertFileExists($this->repositoryFile);
file_put_contents($this->repositoryFile, json_encode(array( $json
array('name' => 'package1', 'version' => '1.0.0-beta', 'type' => 'vendor') ->expects($this->once())
))); ->method('read')
->will($this->returnValue(array()));
$json
->expects($this->once())
->method('write')
->with(array(
array('name' => 'mypkg', 'type' => 'library', 'names' => array('mypkg'), 'version' => '0.1.10')
));
$repository = new FilesystemRepository($this->repositoryFile); $repository->addPackage(new MemoryPackage('mypkg', '0.1.10'));
$repository->getPackages();
$repository->write(); $repository->write();
$this->assertFileExists($this->repositoryFile); }
$data = json_decode(file_get_contents($this->repositoryFile), true); private function createJsonFileMock()
$this->assertEquals(array( {
array('name' => 'package1', 'type' => 'vendor', 'version' => '1.0.0.0-beta', 'names' => array('package1')) return $this->getMockBuilder('Composer\Json\JsonFile')
), $data); ->disableOriginalConstructor()
->getMock();
} }
} }

Loading…
Cancel
Save