1
0
Fork 0

Rework JsonFile API slightly, avoid tokenizing in php if the syntax is valid

pull/390/head
Jordi Boggiano 2012-03-05 22:01:47 +01:00
parent 8727df5f82
commit bd54e43d37
5 changed files with 58 additions and 57 deletions

View File

@ -53,7 +53,9 @@ EOT
}
try {
JsonFile::parseJson(file_get_contents($file), true);
$json = new JsonFile($file);
$json->read();
$json->validateSchema();
} catch (\Exception $e) {
$output->writeln('<error>'.$e->getMessage().'</error>');
return 1;

View File

@ -55,7 +55,8 @@ class Factory
'process-timeout' => 300,
);
$packageConfig = $file->read(true);
$packageConfig = $file->read();
$file->validateSchema();
if (isset($packageConfig['config']) && is_array($packageConfig['config'])) {
$packageConfig['config'] = array_merge($composerConfig, $packageConfig['config']);

View File

@ -66,30 +66,29 @@ class JsonFile
/**
* Reads json file.
*
* @param string $json path or json string
*
* @return array
*/
public function read($validate = false)
public function read()
{
$ctx = StreamContextFactory::getContext(array(
'http' => array(
'header' => 'User-Agent: Composer/'.Composer::VERSION."\r\n"
)));
)
));
$json = file_get_contents($this->path, false, $ctx);
if (!$json) {
throw new \RuntimeException('Could not read '.$this->path.', you are probably offline');
}
return static::parseJson($json, $validate);
return static::parseJson($json);
}
/**
* Writes json file.
*
* @param array $hash writes hash into json file
* @param int $options json_encode options
* @param int $options json_encode options (defaults to JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
*/
public function write(array $hash, $options = 448)
{
@ -109,14 +108,46 @@ class JsonFile
file_put_contents($this->path, static::encode($hash, $options). ($options & JSON_PRETTY_PRINT ? "\n" : ''));
}
/**
* Validates the schema of the current json file according to composer-schema.json rules
*
* @param string $json
* @return Boolean true on success
* @throws \UnexpectedValueException
*/
public function validateSchema()
{
$content = file_get_contents($this->path);
$data = json_decode($content);
if (null === $data && 'null' !== $content) {
self::validateSyntax($content);
}
$schema = json_decode(file_get_contents(__DIR__ . '/../../../res/composer-schema.json'));
$validator = new Validator();
$validator->check($data, $schema);
if (!$validator->isValid()) {
$msg = "\n";
foreach ((array) $validator->getErrors() as $error) {
$msg .= ($error['property'] ? $error['property'].' : ' : '').$error['message']."\n";
}
throw new \UnexpectedValueException('Your composer.json is invalid. The following errors were found:' . $msg);
}
return true;
}
/**
* Encodes an array into (optionally pretty-printed) JSON
*
* Original code for this function can be found at:
* This code is based on the function found at:
* http://recursive-design.com/blog/2008/03/11/format-json-with-php/
*
* @param mixed $data Data to encode into a formatted JSON string
* @param int $options json_encode options
* @param int $options json_encode options (defaults to JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
* @return string Encoded json
*/
static public function encode($data, $options = 448)
@ -218,61 +249,33 @@ class JsonFile
* Parses json string and returns hash.
*
* @param string $json json string
* @param boolean $validateSchema wether to validate the json schema
*
* @return mixed
*/
public static function parseJson($json, $validateSchema=false)
public static function parseJson($json)
{
$data = static::validateSyntax($json);
if ($validateSchema) {
static::validateSchema($json);
$data = json_decode($json, true);
if (null === $data && 'null' !== $json) {
self::validateSyntax($json);
}
return $data;
}
/**
* validates a composer.json against the schema
* Validates the syntax of a JSON string
*
* @param string $json
* @return boolean
* @return Boolean true on success
* @throws \UnexpectedValueException
*/
public static function validateSchema($json)
{
$data = json_decode($json);
$schema = json_decode(file_get_contents(__DIR__ . '/../../../res/composer-schema.json'));
$validator = new Validator();
$validator->check($data, $schema);
if (!$validator->isValid()) {
$msg = "\n";
foreach ((array) $validator->getErrors() as $error) {
$msg .= ($error['property'] ? $error['property'].' : ' : '').$error['message']."\n";
}
throw new \UnexpectedValueException('Your composer.json did not validate against the schema. The following mistakes were found:'.$msg);
}
}
/**
* validates the json syntax
*
* @param string $json
* @return array
* @throws \UnexpectedValueException
*/
public static function validateSyntax($json)
protected static function validateSyntax($json)
{
$parser = new JsonParser();
$result = $parser->lint($json);
if (null === $result) {
return json_decode($json, true);
return true;
}
throw $result;

View File

@ -87,13 +87,8 @@ class JsonFileTest extends \PHPUnit_Framework_TestCase
public function testSchemaValidation()
{
$json = file_get_contents(__DIR__.'/../../../../composer.json');
try {
$this->assertNull(JsonFile::validateSchema($json));
} catch (\UnexpectedValueException $e) {
$this->fail('invalid schema');
}
$json = new JsonFile(__DIR__.'/../../../../composer.json');
$this->assertTrue($json->validateSchema());
}
public function testParseErrorDetectMissingCommaMultiline()