Permalink
Browse files

Rework JsonFile API slightly, avoid tokenizing in php if the syntax i…

…s valid
  • Loading branch information...
1 parent 8727df5 commit bd54e43d37959b1cc506ef962bf810d9fbc383f1 @Seldaek committed Mar 5, 2012
View
@@ -18,7 +18,7 @@
}
],
"require": {
- "php": ">=5.3.0",
+ "php": ">=5.3.0",
"justinrainbow/json-schema": ">=1.1.0",
"seld/jsonlint": "*",
"symfony/console": "dev-master",
@@ -53,7 +53,9 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
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;
@@ -55,7 +55,8 @@ public function createComposer(IOInterface $io, $composerFile = null)
'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']);
@@ -66,30 +66,29 @@ public function exists()
/**
* 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 array $hash writes hash into json file
+ * @param int $options json_encode options (defaults to JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
*/
public function write(array $hash, $options = 448)
{
@@ -110,13 +109,45 @@ public function write(array $hash, $options = 448)
}
/**
+ * 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 @@ static public function encode($data, $options = 448)
* 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)
- {
- $data = static::validateSyntax($json);
-
- if ($validateSchema) {
- static::validateSchema($json);
+ public static function parseJson($json)
+ {
+ $data = json_decode($json, true);
+ if (null === $data && 'null' !== $json) {
+ self::validateSyntax($json);
}
return $data;
}
/**
- * validates a composer.json against the schema
- *
- * @param string $json
- * @return boolean
- * @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
- *
+ * Validates the syntax of a JSON string
+ *
* @param string $json
- * @return array
+ * @return Boolean true on success
* @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;
@@ -87,13 +87,8 @@ public function testParseErrorDetectMissingComma()
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()

0 comments on commit bd54e43

Please sign in to comment.