Example #1
0
 /**
  * Validates the config, and returns the result.
  *
  * @param string $file The path to the file
  *
  * @return array a triple containing the errors, publishable errors, and warnings
  */
 public function validate($file)
 {
     $errors = array();
     $publishErrors = array();
     $warnings = array();
     // validate json schema
     $laxValid = false;
     $valid = false;
     try {
         $json = new JsonFile($file, new RemoteFilesystem($this->io));
         $manifest = $json->read();
         $json->validateSchema(JsonFile::LAX_SCHEMA);
         $laxValid = true;
         $json->validateSchema();
         $valid = true;
     } catch (JsonValidationException $e) {
         foreach ($e->getErrors() as $message) {
             if ($laxValid) {
                 $publishErrors[] = $message;
             } else {
                 $errors[] = $message;
             }
         }
     } catch (\Exception $e) {
         $errors[] = $e->getMessage();
         return array($errors, $publishErrors, $warnings);
     }
     // validate actual data
     if (!empty($manifest['license'])) {
         $licenseValidator = new SpdxLicenseIdentifier();
         if (!$licenseValidator->validate($manifest['license'])) {
             $warnings[] = sprintf('License %s is not a valid SPDX license identifier, see http://www.spdx.org/licenses/ if you use an open license', json_encode($manifest['license']));
         }
     } else {
         $warnings[] = 'No license specified, it is recommended to do so';
     }
     if (!empty($manifest['name']) && preg_match('{[A-Z]}', $manifest['name'])) {
         $suggestName = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $manifest['name']);
         $suggestName = strtolower($suggestName);
         $warnings[] = sprintf('Name "%s" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using "%s" instead. As such you will not be able to submit it to Packagist.', $manifest['name'], $suggestName);
     }
     try {
         $loader = new ValidatingArrayLoader(new ArrayLoader());
         if (!isset($manifest['version'])) {
             $manifest['version'] = '1.0.0';
         }
         if (!isset($manifest['name'])) {
             $manifest['name'] = 'dummy/dummy';
         }
         $loader->load($manifest);
     } catch (InvalidPackageException $e) {
         $errors = array_merge($errors, $e->getErrors());
     }
     $warnings = array_merge($warnings, $loader->getWarnings());
     return array($errors, $publishErrors, $warnings);
 }
Example #2
0
 /**
  * Creates a Composer instance
  *
  * @param  IOInterface $io          IO instance
  * @param  mixed       $localConfig either a configuration array or a filename to read from, if null it will read from the default filename
  * @return Composer
  */
 public function createComposer(IOInterface $io, $localConfig = null)
 {
     // load Composer configuration
     if (null === $localConfig) {
         $localConfig = $this->getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, new RemoteFilesystem($io));
         if (!$file->exists()) {
             if ($localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . getcwd();
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the http://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $localConfig = $file->read();
     }
     // Configuration defaults
     $config = static::createConfig();
     $config->merge($localConfig);
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
     // initialize repository manager
     $rm = $this->createRepositoryManager($io, $config);
     // load default repository unless it's explicitly disabled
     $localConfig = $this->addPackagistRepository($localConfig);
     // load local repository
     $this->addLocalRepository($rm, $vendorDir);
     // load package
     $loader = new Package\Loader\RootPackageLoader($rm);
     $package = $loader->load($localConfig);
     // initialize download manager
     $dm = $this->createDownloadManager($io);
     // initialize installation manager
     $im = $this->createInstallationManager($rm, $dm, $vendorDir, $binDir, $io);
     // purge packages if they have been deleted on the filesystem
     $this->purgePackages($rm, $im);
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     $composer->setPackage($package);
     $composer->setRepositoryManager($rm);
     $composer->setDownloadManager($dm);
     $composer->setInstallationManager($im);
     // init locker if possible
     if (isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker(new JsonFile($lockFile, new RemoteFilesystem($io)), $rm, md5_file($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
Example #3
0
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $file = $input->getArgument('file');
     if (!file_exists($file)) {
         $output->writeln('<error>' . $file . ' not found.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $output->writeln('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     $laxValid = false;
     try {
         $json = new JsonFile($file, new RemoteFilesystem($this->getIO()));
         $json->read();
         $json->validateSchema(JsonFile::LAX_SCHEMA);
         $laxValid = true;
         $json->validateSchema();
     } catch (JsonValidationException $e) {
         if ($laxValid) {
             $output->writeln('<info>' . $file . ' is valid for simple usage with composer but has</info>');
             $output->writeln('<info>strict errors that make it unable to be published as a package:</info>');
         } else {
             $output->writeln('<error>' . $file . ' is invalid, the following errors were found:</error>');
         }
         foreach ($e->getErrors() as $message) {
             $output->writeln('<error>' . $message . '</error>');
         }
         return 1;
     } catch (\Exception $e) {
         $output->writeln('<error>' . $file . ' contains a JSON Syntax Error:</error>');
         $output->writeln('<error>' . $e->getMessage() . '</error>');
         return 1;
     }
     $output->writeln('<info>' . $file . ' is valid</info>');
 }
 /**
  * {@inheritDoc}
  */
 public function validate($value, Constraint $constraint)
 {
     $tempFile = tempnam(sys_get_temp_dir(), 'composer');
     file_put_contents($tempFile, $value);
     try {
         $jsonFile = new JsonFile($tempFile);
         $jsonFile->validateSchema(JsonFile::LAX_SCHEMA);
         unlink($tempFile);
     } catch (\Exception $exception) {
         unlink($tempFile);
         $from = array($tempFile);
         $to = array('composer.json');
         $this->context->addViolation(str_replace($from, $to, $exception->getMessage()));
     }
 }
 /**
  * Validates the config, and returns the result.
  *
  * @param string $file The path to the file
  *
  * @return array a triple containing the errors, publishable errors, and warnings
  */
 public function validate($file)
 {
     $errors = array();
     $publishErrors = array();
     $warnings = array();
     // validate json schema
     $laxValid = false;
     try {
         $json = new JsonFile($file, new RemoteFilesystem($this->io));
         $manifest = $json->read();
         $json->validateSchema(JsonFile::LAX_SCHEMA);
         $laxValid = true;
         $json->validateSchema();
     } catch (JsonValidationException $e) {
         foreach ($e->getErrors() as $message) {
             if ($laxValid) {
                 $publishErrors[] = $message;
             } else {
                 $errors[] = $message;
             }
         }
     } catch (\Exception $e) {
         $errors[] = $e->getMessage();
         return array($errors, $publishErrors, $warnings);
     }
     // validate actual data
     if (!empty($manifest['license'])) {
         // strip proprietary since it's not a valid SPDX identifier, but is accepted by composer
         if (is_array($manifest['license'])) {
             foreach ($manifest['license'] as $key => $license) {
                 if ('proprietary' === $license) {
                     unset($manifest['license'][$key]);
                 }
             }
         }
         $licenseValidator = new SpdxLicenseIdentifier();
         if ('proprietary' !== $manifest['license'] && array() !== $manifest['license'] && !$licenseValidator->validate($manifest['license'])) {
             $warnings[] = sprintf('License %s is not a valid SPDX license identifier, see http://www.spdx.org/licenses/ if you use an open license.' . "\nIf the software is closed-source, you may use \"proprietary\" as license.", json_encode($manifest['license']));
         }
     } else {
         $warnings[] = 'No license specified, it is recommended to do so. For closed-source software you may use "proprietary" as license.';
     }
     if (!empty($manifest['name']) && preg_match('{[A-Z]}', $manifest['name'])) {
         $suggestName = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $manifest['name']);
         $suggestName = strtolower($suggestName);
         $warnings[] = sprintf('Name "%s" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using "%s" instead. As such you will not be able to submit it to Packagist.', $manifest['name'], $suggestName);
     }
     if (!empty($manifest['type']) && $manifest['type'] == 'composer-installer') {
         $warnings[] = "The package type 'composer-installer' is deprecated. Please distribute your custom installers as plugins from now on. See http://getcomposer.org/doc/articles/plugins.md for plugin documentation.";
     }
     // check for require-dev overrides
     if (isset($manifest['require']) && isset($manifest['require-dev'])) {
         $requireOverrides = array_intersect_key($manifest['require'], $manifest['require-dev']);
         if (!empty($requireOverrides)) {
             $plural = count($requireOverrides) > 1 ? 'are' : 'is';
             $warnings[] = implode(', ', array_keys($requireOverrides)) . " {$plural} required both in require and require-dev, this can lead to unexpected behavior";
         }
     }
     try {
         $loader = new ValidatingArrayLoader(new ArrayLoader());
         if (!isset($manifest['version'])) {
             $manifest['version'] = '1.0.0';
         }
         if (!isset($manifest['name'])) {
             $manifest['name'] = 'dummy/dummy';
         }
         $loader->load($manifest);
     } catch (InvalidPackageException $e) {
         $errors = array_merge($errors, $e->getErrors());
     }
     $warnings = array_merge($warnings, $loader->getWarnings());
     return array($errors, $publishErrors, $warnings);
 }
Example #6
0
 /**
  * Creates a Composer instance
  *
  * @param  IOInterface               $io             IO instance
  * @param  array|string|null         $localConfig    either a configuration array or a filename to read from, if null it will
  *                                                   read from the default filename
  * @param  bool                      $disablePlugins Whether plugins should not be loaded
  * @param  bool                      $fullLoad       Whether to initialize everything or only main project stuff (used when loading the global composer)
  * @throws \InvalidArgumentException
  * @throws \UnexpectedValueException
  * @return Composer
  */
 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true)
 {
     $cwd = $cwd ?: getcwd();
     // load Composer configuration
     if (null === $localConfig) {
         $localConfig = static::getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, null, $io);
         if (!$file->exists()) {
             if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . $cwd;
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the https://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $jsonParser = new JsonParser();
         try {
             $jsonParser->parse(file_get_contents($localConfig), JsonParser::DETECT_KEY_CONFLICTS);
         } catch (\Seld\JsonLint\DuplicateKeyException $e) {
             $details = $e->getDetails();
             $io->writeError('<warning>Key ' . $details['key'] . ' is a duplicate in ' . $localConfig . ' at line ' . $details['line'] . '</warning>');
         }
         $localConfig = $file->read();
     }
     // Load config and override with local config/auth config
     $config = static::createConfig($io, $cwd);
     $config->merge($localConfig);
     if (isset($composerFile)) {
         $io->writeError('Loading config file ' . $composerFile, true, IOInterface::DEBUG);
         $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
         if ($localAuthFile->exists()) {
             $io->writeError('Loading config file ' . $localAuthFile->getPath(), true, IOInterface::DEBUG);
             $config->merge(array('config' => $localAuthFile->read()));
             $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
         }
     }
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     if ($fullLoad) {
         // load auth configs into the IO instance
         $io->loadConfiguration($config);
     }
     $rfs = self::createRemoteFilesystem($io, $config);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $io);
     $composer->setEventDispatcher($dispatcher);
     // initialize repository manager
     $rm = $this->createRepositoryManager($io, $config, $dispatcher, $rfs);
     $composer->setRepositoryManager($rm);
     // load local repository
     $this->addLocalRepository($io, $rm, $vendorDir);
     // force-set the version of the global package if not defined as
     // guessing it adds no value and only takes time
     if (!$fullLoad && !isset($localConfig['version'])) {
         $localConfig['version'] = '1.0.0';
     }
     // load package
     $parser = new VersionParser();
     $guesser = new VersionGuesser($config, new ProcessExecutor($io), $parser);
     $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, $guesser);
     $package = $loader->load($localConfig, 'Composer\\Package\\RootPackage', $cwd);
     $composer->setPackage($package);
     // initialize installation manager
     $im = $this->createInstallationManager();
     $composer->setInstallationManager($im);
     if ($fullLoad) {
         // initialize download manager
         $dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs);
         $composer->setDownloadManager($dm);
         // initialize autoload generator
         $generator = new AutoloadGenerator($dispatcher, $io);
         $composer->setAutoloadGenerator($generator);
     }
     // add installers to the manager (must happen after download manager is created since they read it out of $composer)
     $this->createDefaultInstallers($im, $composer, $io);
     if ($fullLoad) {
         $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins);
         $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins);
         $composer->setPluginManager($pm);
         $pm->loadInstalledPlugins();
         // once we have plugins and custom installers we can
         // purge packages from local repos if they have been deleted on the filesystem
         if ($rm->getLocalRepository()) {
             $this->purgePackages($rm->getLocalRepository(), $im);
         }
     }
     // init locker if possible
     if ($fullLoad && isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker($io, new JsonFile($lockFile, null, $io), $rm, $im, file_get_contents($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
 public function testSchemaValidation()
 {
     $json = new JsonFile(__DIR__ . '/../../../../composer.json');
     $this->assertTrue($json->validateSchema());
 }
Example #8
0
 /**
  * Creates a Composer instance
  *
  * @param IOInterface       $io          IO instance
  * @param array|string|null $localConfig either a configuration array or a filename to read from, if null it will
  *                                       read from the default filename
  * @throws \InvalidArgumentException
  * @return Composer
  */
 public function createComposer(IOInterface $io, $localConfig = null)
 {
     // load Composer configuration
     if (null === $localConfig) {
         $localConfig = static::getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, new RemoteFilesystem($io));
         if (!$file->exists()) {
             if ($localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . getcwd();
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the http://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $localConfig = $file->read();
     }
     // Configuration defaults
     $config = static::createConfig();
     $config->merge($localConfig);
     // reload oauth token from config if available
     if ($tokens = $config->get('github-oauth')) {
         foreach ($tokens as $domain => $token) {
             if (!preg_match('{^[a-z0-9]+$}', $token)) {
                 throw new \UnexpectedValueException('Your github oauth token for ' . $domain . ' contains invalid characters: "' . $token . '"');
             }
             $io->setAuthentication($domain, $token, 'x-oauth-basic');
         }
     }
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
     // initialize repository manager
     $rm = $this->createRepositoryManager($io, $config);
     // load local repository
     $this->addLocalRepository($rm, $vendorDir);
     // load package
     $loader = new Package\Loader\RootPackageLoader($rm, $config);
     $package = $loader->load($localConfig);
     // initialize download manager
     $dm = $this->createDownloadManager($io, $config);
     // initialize installation manager
     $im = $this->createInstallationManager();
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     $composer->setPackage($package);
     $composer->setRepositoryManager($rm);
     $composer->setDownloadManager($dm);
     $composer->setInstallationManager($im);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $io);
     $composer->setEventDispatcher($dispatcher);
     // initialize autoload generator
     $generator = new AutoloadGenerator($dispatcher);
     $composer->setAutoloadGenerator($generator);
     // add installers to the manager
     $this->createDefaultInstallers($im, $composer, $io);
     // purge packages if they have been deleted on the filesystem
     $this->purgePackages($rm, $im);
     // init locker if possible
     if (isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker(new JsonFile($lockFile, new RemoteFilesystem($io)), $rm, $im, md5_file($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
 private function createConfig()
 {
     $config = Factory::createConfig();
     $file = new JsonFile(Factory::getComposerFile());
     if (!$file->exists()) {
         return $config;
     }
     $file->validateSchema(JsonFile::LAX_SCHEMA);
     $config->merge($file->read());
     return $config;
 }
Example #10
0
 /**
  * Creates a Composer instance
  *
  * @param  IOInterface               $io             IO instance
  * @param  array|string|null         $localConfig    either a configuration array or a filename to read from, if null it will
  *                                                   read from the default filename
  * @param  bool                      $disablePlugins Whether plugins should not be loaded
  * @throws \InvalidArgumentException
  * @throws \UnexpectedValueException
  * @return Composer
  */
 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false)
 {
     // load Composer configuration
     if (null === $localConfig) {
         $localConfig = static::getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, new RemoteFilesystem($io));
         if (!$file->exists()) {
             if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . getcwd();
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the http://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $localConfig = $file->read();
     }
     // Load config and override with local config/auth config
     $config = static::createConfig($io);
     $config->merge($localConfig);
     if (isset($composerFile)) {
         if ($io && $io->isDebug()) {
             $io->write('Loading config file ' . $composerFile);
         }
         $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
         if ($localAuthFile->exists()) {
             if ($io && $io->isDebug()) {
                 $io->write('Loading config file ' . $localAuthFile->getPath());
             }
             $config->merge(array('config' => $localAuthFile->read()));
             $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
         }
     }
     // load auth configs into the IO instance
     $io->loadConfiguration($config);
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     // setup process timeout
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $io);
     // initialize repository manager
     $rm = $this->createRepositoryManager($io, $config, $dispatcher);
     // load local repository
     $this->addLocalRepository($rm, $vendorDir);
     // load package
     $parser = new VersionParser();
     $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, new ProcessExecutor($io));
     $package = $loader->load($localConfig);
     // initialize installation manager
     $im = $this->createInstallationManager();
     // Composer composition
     $composer->setPackage($package);
     $composer->setRepositoryManager($rm);
     $composer->setInstallationManager($im);
     // initialize download manager
     $dm = $this->createDownloadManager($io, $config, $dispatcher);
     $composer->setDownloadManager($dm);
     $composer->setEventDispatcher($dispatcher);
     // initialize autoload generator
     $generator = new AutoloadGenerator($dispatcher, $io);
     $composer->setAutoloadGenerator($generator);
     // add installers to the manager
     $this->createDefaultInstallers($im, $composer, $io);
     $globalRepository = $this->createGlobalRepository($config, $vendorDir);
     $pm = $this->createPluginManager($composer, $io, $globalRepository);
     $composer->setPluginManager($pm);
     if (!$disablePlugins) {
         $pm->loadInstalledPlugins();
     }
     // purge packages if they have been deleted on the filesystem
     $this->purgePackages($rm, $im);
     // init locker if possible
     if (isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io, $config)), $rm, $im, md5_file($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
Example #11
0
 /**
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @return int
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $file = $input->getArgument('file');
     if (!file_exists($file)) {
         $output->writeln('<error>' . $file . ' not found.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $output->writeln('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     $errors = array();
     $publishErrors = array();
     $warnings = array();
     // validate json schema
     $laxValid = false;
     $valid = false;
     try {
         $json = new JsonFile($file, new RemoteFilesystem($this->getIO()));
         $manifest = $json->read();
         $json->validateSchema(JsonFile::LAX_SCHEMA);
         $laxValid = true;
         $json->validateSchema();
         $valid = true;
     } catch (JsonValidationException $e) {
         foreach ($e->getErrors() as $message) {
             if ($laxValid) {
                 $publishErrors[] = '<error>Publish Error: ' . $message . '</error>';
             } else {
                 $errors[] = '<error>' . $message . '</error>';
             }
         }
     } catch (\Exception $e) {
         $output->writeln('<error>' . $file . ' contains a JSON Syntax Error:</error>');
         $output->writeln('<error>' . $e->getMessage() . '</error>');
         return 1;
     }
     // validate actual data
     if (!empty($manifest['license'])) {
         $licenseValidator = new SpdxLicenseIdentifier();
         if (!$licenseValidator->validate($manifest['license'])) {
             $warnings[] = sprintf('License %s is not a valid SPDX license identifier, see http://www.spdx.org/licenses/ if you use an open license', json_encode($manifest['license']));
         }
     } else {
         $warnings[] = 'No license specified, it is recommended to do so';
     }
     // output errors/warnings
     if (!$errors && !$publishErrors && !$warnings) {
         $output->writeln('<info>' . $file . ' is valid</info>');
     } elseif (!$errors && !$publishErrors) {
         $output->writeln('<info>' . $file . ' is valid, but with a few warnings</info>');
         $output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
     } elseif (!$errors) {
         $output->writeln('<info>' . $file . ' is valid for simple usage with composer but has</info>');
         $output->writeln('<info>strict errors that make it unable to be published as a package:</info>');
         $output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
     } else {
         $output->writeln('<error>' . $file . ' is invalid, the following errors/warnings were found:</error>');
     }
     $messages = array('error' => array_merge($errors, $publishErrors), 'warning' => $warnings);
     foreach ($messages as $style => $msgs) {
         foreach ($msgs as $msg) {
             $output->writeln('<' . $style . '>' . $msg . '</' . $style . '>');
         }
     }
     return $errors || $publishErrors ? 1 : 0;
 }
Example #12
0
 public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false)
 {
     if (null === $localConfig) {
         $localConfig = static::getComposerFile();
     }
     if (is_string($localConfig)) {
         $composerFile = $localConfig;
         $file = new JsonFile($localConfig, new RemoteFilesystem($io));
         if (!$file->exists()) {
             if ($localConfig === './composer.json' || $localConfig === 'composer.json') {
                 $message = 'Composer could not find a composer.json file in ' . getcwd();
             } else {
                 $message = 'Composer could not find the config file: ' . $localConfig;
             }
             $instructions = 'To initialize a project, please create a composer.json file as described in the http://getcomposer.org/ "Getting Started" section';
             throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
         }
         $file->validateSchema(JsonFile::LAX_SCHEMA);
         $localConfig = $file->read();
     }
     $config = static::createConfig();
     $config->merge($localConfig);
     $io->loadConfiguration($config);
     $vendorDir = $config->get('vendor-dir');
     $binDir = $config->get('bin-dir');
     ProcessExecutor::setTimeout((int) $config->get('process-timeout'));
     $composer = new Composer();
     $composer->setConfig($config);
     $dispatcher = new EventDispatcher($composer, $io);
     $rm = $this->createRepositoryManager($io, $config, $dispatcher);
     $this->addLocalRepository($rm, $vendorDir);
     $parser = new VersionParser();
     $loader = new Package\Loader\RootPackageLoader($rm, $config, $parser, new ProcessExecutor($io));
     $package = $loader->load($localConfig);
     $im = $this->createInstallationManager();
     $composer->setPackage($package);
     $composer->setRepositoryManager($rm);
     $composer->setInstallationManager($im);
     $dm = $this->createDownloadManager($io, $config, $dispatcher);
     $composer->setDownloadManager($dm);
     $composer->setEventDispatcher($dispatcher);
     $generator = new AutoloadGenerator($dispatcher);
     $composer->setAutoloadGenerator($generator);
     $this->createDefaultInstallers($im, $composer, $io);
     $globalRepository = $this->createGlobalRepository($config, $vendorDir);
     $pm = $this->createPluginManager($composer, $io, $globalRepository);
     $composer->setPluginManager($pm);
     if (!$disablePlugins) {
         $pm->loadInstalledPlugins();
     }
     $this->purgePackages($rm, $im);
     if (isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Package\Locker($io, new JsonFile($lockFile, new RemoteFilesystem($io)), $rm, $im, md5_file($composerFile));
         $composer->setLocker($locker);
     }
     return $composer;
 }
Example #13
0
 public function createComposer()
 {
     $cwd = sprintf('%s/%s', getcwd(), '.eva');
     $factory = new Factory();
     if (false) {
         $composer = $factory->createComposer($this->io, $config, true, $cwd);
     }
     //  -----------------
     //  -----------------
     //  -----------------
     $fullLoad = true;
     $composerFile = $cwd . '/manifest.composer.json';
     $file = new JsonFile($composerFile);
     $file->validateSchema(JsonFile::LAX_SCHEMA);
     $localConfig = $file->read();
     //  -----------------
     //  -----------------
     //  -----------------
     // Load config and override with local config/auth config
     //        $config = Factory::createConfig($this->io, $cwd);
     $vendorDir = $cwd . '/manifests/vendor';
     $config = $factory::createConfig($this->io, $cwd);
     $config->merge($localConfig);
     $config->merge(['config' => ['vendor-dir' => $vendorDir]]);
     $localAuthFile = new JsonFile(dirname(realpath($composerFile)) . '/auth.json');
     if ($localAuthFile->exists()) {
         if ($this->io && $this->io->isDebug()) {
             $this->io->writeError('Loading config file ' . $localAuthFile->getPath());
         }
         $config->merge(array('config' => $localAuthFile->read()));
         $config->setAuthConfigSource(new JsonConfigSource($localAuthFile, true));
     }
     // initialize composer
     $composer = new Composer();
     $composer->setConfig($config);
     // initialize event dispatcher
     $dispatcher = new EventDispatcher($composer, $this->io);
     $composer->setEventDispatcher($dispatcher);
     // initialize repository manager
     //        $rm = $this->createRepositoryManager($io, $config, $dispatcher);
     //        $composer->setRepositoryManager($rm);
     $rm = new RepositoryManager($this->io, $config, $dispatcher);
     $rm->setRepositoryClass('composer', ComposerRepository::class);
     $composer->setRepositoryManager($rm);
     // load local repository
     $rm->setLocalRepository(new InstalledFilesystemRepository(new JsonFile($vendorDir . '/composer/installed.json')));
     // load package
     $parser = new VersionParser();
     $guesser = new VersionGuesser($config, new ProcessExecutor($this->io), $parser);
     $loader = new RootPackageLoader($rm, $config, $parser, $guesser);
     $package = $loader->load($localConfig);
     $composer->setPackage($package);
     // initialize installation manager
     $im = new InstallationManager();
     $composer->setInstallationManager($im);
     if ($fullLoad) {
         // initialize download manager
         $dm = $factory->createDownloadManager($this->io, $config, $dispatcher);
         $composer->setDownloadManager($dm);
         // initialize autoload generator
         $generator = new AutoloadGenerator($dispatcher, $this->io);
         $composer->setAutoloadGenerator($generator);
     }
     // add installers to the manager (must happen after download manager is created since they read it out of $composer)
     $im->addInstaller(new Installer\LibraryInstaller($this->io, $composer, null));
     $im->addInstaller(new Installer\PearInstaller($this->io, $composer, 'pear-library'));
     $im->addInstaller(new Installer\PluginInstaller($this->io, $composer));
     $im->addInstaller(new Installer\MetapackageInstaller($this->io));
     //        if ($fullLoad) {
     //            $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins);
     //            $pm = $this->createPluginManager($io, $composer, $globalComposer);
     //            $composer->setPluginManager($pm);
     //
     //            if (!$disablePlugins) {
     //                $pm->loadInstalledPlugins();
     //            }
     //
     //            // once we have plugins and custom installers we can
     //            // purge packages from local repos if they have been deleted on the filesystem
     //            if ($rm->getLocalRepository()) {
     //                $this->purgePackages($rm->getLocalRepository(), $im);
     //            }
     //        }
     // init locker if possible
     if ($fullLoad && isset($composerFile)) {
         $lockFile = "json" === pathinfo($composerFile, PATHINFO_EXTENSION) ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
         $locker = new Locker($this->io, new JsonFile($lockFile, new RemoteFilesystem($this->io, $config)), $rm, $im, file_get_contents($composerFile));
         $composer->setLocker($locker);
     }
     //  -----------------
     //  -----------------
     //  -----------------
     return $composer;
 }
Example #14
0
 /**
  * Creates a Composer instance
  *
  * @return Composer
  */
 public function createComposer(IOInterface $io, $composerFile = null)
 {
     // load Composer configuration
     if (null === $composerFile) {
         $composerFile = getenv('COMPOSER') ?: 'composer.json';
     }
     $file = new JsonFile($composerFile);
     if (!$file->exists()) {
         if ($composerFile === 'composer.json') {
             $message = 'Composer could not find a composer.json file in ' . getcwd();
         } else {
             $message = 'Composer could not find the config file: ' . $composerFile;
         }
         $instructions = 'To initialize a project, please create a composer.json file as described on the http://packagist.org/ "Getting Started" section';
         throw new \InvalidArgumentException($message . PHP_EOL . $instructions);
     }
     // Configuration defaults
     $composerConfig = array('vendor-dir' => 'vendor', 'process-timeout' => 300);
     $packageConfig = $file->read();
     $file->validateSchema(JsonFile::LAX_SCHEMA);
     if (isset($packageConfig['config']) && is_array($packageConfig['config'])) {
         $packageConfig['config'] = array_merge($composerConfig, $packageConfig['config']);
     } else {
         $packageConfig['config'] = $composerConfig;
     }
     $vendorDir = getenv('COMPOSER_VENDOR_DIR') ?: $packageConfig['config']['vendor-dir'];
     if (!isset($packageConfig['config']['bin-dir'])) {
         $packageConfig['config']['bin-dir'] = $vendorDir . '/bin';
     }
     $binDir = getenv('COMPOSER_BIN_DIR') ?: $packageConfig['config']['bin-dir'];
     // setup process timeout
     $processTimeout = getenv('COMPOSER_PROCESS_TIMEOUT') ?: $packageConfig['config']['process-timeout'];
     ProcessExecutor::setTimeout((int) $processTimeout);
     // initialize repository manager
     $rm = $this->createRepositoryManager($io);
     // load default repository unless it's explicitly disabled
     $loadPackagist = true;
     if (isset($packageConfig['repositories'])) {
         foreach ($packageConfig['repositories'] as $repo) {
             if (isset($repo['packagist']) && $repo['packagist'] === false) {
                 $loadPackagist = false;
             }
         }
     }
     if ($loadPackagist) {
         $this->addPackagistRepository($rm);
     }
     // load local repository
     $this->addLocalRepository($rm, $vendorDir);
     // load package
     $loader = new Package\Loader\RootPackageLoader($rm);
     $package = $loader->load($packageConfig);
     // initialize download manager
     $dm = $this->createDownloadManager($io);
     // initialize installation manager
     $im = $this->createInstallationManager($rm, $dm, $vendorDir, $binDir, $io);
     // init locker
     $lockFile = substr($composerFile, -5) === '.json' ? substr($composerFile, 0, -4) . 'lock' : $composerFile . '.lock';
     $locker = new Package\Locker(new JsonFile($lockFile), $rm, md5_file($composerFile));
     // initialize composer
     $composer = new Composer();
     $composer->setPackage($package);
     $composer->setLocker($locker);
     $composer->setRepositoryManager($rm);
     $composer->setDownloadManager($dm);
     $composer->setInstallationManager($im);
     return $composer;
 }
Example #15
0
 /**
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @return int
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $file = $input->getArgument('file');
     if (!file_exists($file)) {
         $output->writeln('<error>' . $file . ' not found.</error>');
         return 1;
     }
     if (!is_readable($file)) {
         $output->writeln('<error>' . $file . ' is not readable.</error>');
         return 1;
     }
     $errors = array();
     $publishErrors = array();
     $warnings = array();
     // validate json schema
     $laxValid = false;
     $valid = false;
     try {
         $json = new JsonFile($file, new RemoteFilesystem($this->getIO()));
         $manifest = $json->read();
         $json->validateSchema(JsonFile::LAX_SCHEMA);
         $laxValid = true;
         $json->validateSchema();
         $valid = true;
     } catch (JsonValidationException $e) {
         foreach ($e->getErrors() as $message) {
             if ($laxValid) {
                 $publishErrors[] = '<error>Publish Error: ' . $message . '</error>';
             } else {
                 $errors[] = '<error>' . $message . '</error>';
             }
         }
     } catch (\Exception $e) {
         $output->writeln('<error>' . $e->getMessage() . '</error>');
         return 1;
     }
     // validate actual data
     if (!empty($manifest['license'])) {
         $licenseValidator = new SpdxLicenseIdentifier();
         if (!$licenseValidator->validate($manifest['license'])) {
             $warnings[] = sprintf('License %s is not a valid SPDX license identifier, see http://www.spdx.org/licenses/ if you use an open license', json_encode($manifest['license']));
         }
     } else {
         $warnings[] = 'No license specified, it is recommended to do so';
     }
     if (!empty($manifest['name']) && preg_match('{[A-Z]}', $manifest['name'])) {
         $suggestName = preg_replace('{(?:([a-z])([A-Z])|([A-Z])([A-Z][a-z]))}', '\\1\\3-\\2\\4', $manifest['name']);
         $suggestName = strtolower($suggestName);
         $warnings[] = sprintf('Name "%s" does not match the best practice (e.g. lower-cased/with-dashes). We suggest using "%s" instead. As such you will not be able to submit it to Packagist.', $manifest['name'], $suggestName);
     }
     // TODO validate package repositories' packages using the same technique as below
     try {
         $loader = new ValidatingArrayLoader(new ArrayLoader(), false);
         if (!isset($manifest['version'])) {
             $manifest['version'] = '1.0.0';
         }
         if (!isset($manifest['name'])) {
             $manifest['name'] = 'dummy/dummy';
         }
         $loader->load($manifest);
     } catch (\Exception $e) {
         $errors = array_merge($errors, explode("\n", $e->getMessage()));
     }
     // output errors/warnings
     if (!$errors && !$publishErrors && !$warnings) {
         $output->writeln('<info>' . $file . ' is valid</info>');
     } elseif (!$errors && !$publishErrors) {
         $output->writeln('<info>' . $file . ' is valid, but with a few warnings</info>');
         $output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
     } elseif (!$errors) {
         $output->writeln('<info>' . $file . ' is valid for simple usage with composer but has</info>');
         $output->writeln('<info>strict errors that make it unable to be published as a package:</info>');
         $output->writeln('<warning>See http://getcomposer.org/doc/04-schema.md for details on the schema</warning>');
     } else {
         $output->writeln('<error>' . $file . ' is invalid, the following errors/warnings were found:</error>');
     }
     $messages = array('error' => array_merge($errors, $publishErrors), 'warning' => $warnings);
     foreach ($messages as $style => $msgs) {
         foreach ($msgs as $msg) {
             $output->writeln('<' . $style . '>' . $msg . '</' . $style . '>');
         }
     }
     return $errors || $publishErrors ? 1 : 0;
 }