/** * 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); }
/** * 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; }
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); }
/** * 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()); }
/** * 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; }
/** * 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; }
/** * @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; }
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; }
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; }
/** * 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; }
/** * @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; }