Returns the project type, either from composer extra section or it tries to detect from file structure.
Returns null if no project type is detected.

@param Composer $composer

@return null|ProjectTypeInterface
517232
public static function get(Composer $composer): ?ProjectTypeInterface
    {
        $rootDir = dirname($composer->getConfig()->getConfigSource()->getName());

        $classes = static::getClasses($composer);

        $composerProjectType = $composer->getPackage()->getExtra()['rikudou']['installer']['project-type'] ?? null;
        if ($composerProjectType && isset($classes[$composerProjectType])) {
            $class = $classes[$composerProjectType];

            return new $class;
        }

        foreach ($classes as $class) {
            /** @var ProjectTypeInterface $instance */
            $instance = new $class;
            foreach ($instance->getDirs() as $dir) {
                if (is_array($dir)) {
                    $exists = true;
                    foreach ($dir as $requiredDir) {
                        $exists = $exists && file_exists("{$rootDir}/{$requiredDir}");
                    }
                    if ($exists) {
                        return $instance;
                    }
                } else {
                    if (file_exists("{$rootDir}/{$dir}")) {
                        return $instance;
                    }
                }
            }
        }

        return null;
    }
745328
public static function getDecomposerVersion($composerArray, $packages)
    {
        if (isset($composerArray['require'][self::PACKAGE_NAME])) {
            return $composerArray['require'][self::PACKAGE_NAME];
        }

        if (isset($composerArray['require-dev'][self::PACKAGE_NAME])) {
            return $composerArray['require-dev'][self::PACKAGE_NAME];
        }

        foreach ($packages as $package) {
            if (isset($package['dependencies'][self::PACKAGE_NAME])) {
                return $package['dependencies'][self::PACKAGE_NAME];
            }

            if (isset($package['dev-dependencies'][self::PACKAGE_NAME])) {
                return $package['dev-dependencies'][self::PACKAGE_NAME];
            }
        }

        return 'unknown';
    }
903703
public static function getComposerJsonDecoded(string $path = null): array
    {
        $path     = $path ?? self::getProjectRootDirectory() . '/composer.json';
        $contents = (string)\file_get_contents($path);
        if ('' === $contents) {
            throw new \RuntimeException('composer.json is empty');
        }
        $decoded = \json_decode($contents, true);
        if (JSON_ERROR_NONE !== \json_last_error()) {
            throw new \RuntimeException('Failed loading composer.json: ' . \json_last_error_msg());
        }

        return $decoded;
    }
327713
public function activate(Composer $composer, IOInterface $io)
    {
        $this->io = $io;
        $this->composer = $composer;
        $rootDir = realpath($this->composer->getConfig()->get('vendor-dir') . '/../');
        $settings = $this->composer->getPackage()->getExtra()['application'] ?? [];
        $this->appInfo = new AppInfo($rootDir, $settings);
        $this->isProject = $composer->getPackage()->getType() === 'project';

        if ($this->isProject) {
            $this->packageInstaller = new PackageInstaller($this->appInfo, $io, $composer);
            $this->composer
                ->getInstallationManager()
                ->addInstaller($this->packageInstaller);
        }
    }
650145
protected function getCustomVendorPathFromComposer($composerConfigurationPath)
    {
        $composerFile = file_get_contents($composerConfigurationPath);
        $composerJson = json_decode($composerFile, true);

        return isset($composerJson['config']['vendor-dir']) ? $composerJson['config']['vendor-dir'] : 'vendor';
    }
1329671
public function create(Composer $composer): ViolationFilterInterface
    {
        $chain = new ViolationFilterChain(
            ...array_merge(
                $this->getSuggestsFilters($composer),
                $this->getIgnoreFilters($composer)
            )
        );

        return new ViolationFilterChain(
            $chain,
            new PackageRequirementsFilter(
                $composer->getLocker(),
                $chain
            )
        );
    }
981260
public function createTask($taskType)
    {
        try {
            $classname = "";
            $tasklwr = strtolower($taskType);
            foreach ($this->taskdefs as $name => $class) {
                if (strtolower($name) === $tasklwr) {
                    $classname = $class;
                    break;
                }
            }

            if ($classname === "") {
                return null;
            }

            $o = $this->createObject($classname);

            if ($o instanceof Task) {
                $task = $o;
            } else {
                $this->project->log("  (Using TaskAdapter for: $taskType)", Project::MSG_DEBUG);
                // not a real task, try adapter
                $taskA = new TaskAdapter();
                $taskA->setProxy($o);
                $task = $taskA;
            }
            $task->setProject($this->project);
            $task->setTaskType($taskType);
            // set default value, can be changed by the user
            $task->setTaskName($taskType);
            $this->project->log("  +Task: " . $taskType, Project::MSG_DEBUG);
        } catch (Exception $t) {
            throw new BuildException("Could not create task of type: " . $taskType, $t);
        }
        // everything fine return reference
        return $task;
    }
248903
public function getInstallPath( PackageInterface $package, $frameworkType = '' ) {
		$type = $this->package->getType();

		$prettyName = $this->package->getPrettyName();
		if( strpos($prettyName, '/') !== false ) {
			list($vendor, $name) = explode('/', $prettyName);
		} else {
			$vendor = '';
			$name   = $prettyName;
		}

		$availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type'));

		$extra = $package->getExtra();
		if( !empty($extra['installer-name']) ) {
			$availableVars['name'] = $extra['installer-name'];
		}

		if( $this->composer->getPackage() ) {
			$extra = $this->composer->getPackage()->getExtra();
			if( !empty($extra['installer-paths']) ) {
				$customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type);
				if( $customPath !== false ) {
					return $this->templatePath($customPath, $availableVars);
				}
			}
		}

		$packageType = substr($type, strlen($frameworkType) + 1);
		if( !isset($this->locations[$packageType]) ) {
			throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type));
		}

		return $this->templatePath($this->locations[$packageType], $availableVars);
	}
719590
public function getComposer()
    {
        $composerFile = new SplFileInfo($this->composer);
        if (false === $composerFile->isFile()) {
            $message = sprintf('Composer binary not found at "%s"', $composerFile);
            $this->log($message, Project::MSG_WARN);
            $composerLocation = FileSystem::getFileSystem()->which('composer');
            if (!empty($composerLocation)) {
                $message = sprintf('Composer binary found at "%s", updating location', $composerLocation[0]);
                $this->log($message, Project::MSG_INFO);
                $this->setComposer($composerLocation);
            }
        }
        return $this->composer;
    }
1251757
public function getSourcePath(PackageInterface $package)
    {
        return !$package instanceof \Composer\Package\RootPackage
            ? $this->installationManager->getInstallPath($package)
            : realpath(dirname(\Composer\Factory::getComposerFile()));
    }
162773
public function find(Composer $composer, NpmBridge $bridge): array
    {
        $packages = $composer->getRepositoryManager()->getLocalRepository()
            ->getPackages();

        $dependantPackages = [];

        foreach ($packages as $package) {
            if ($bridge->isDependantPackage($package, false)) {
                $dependantPackages[] = $package;
            }
        }

        return $dependantPackages;
    }
765327
protected function setConfig(Composer $composer)
    {
        return new SharedPackageInstallerConfig(
            $composer->getConfig()->get('vendor-dir'),
            $composer->getConfig()->get('vendor-dir', 1),
            $composer->getPackage()->getExtra()
        );
    }
594513
public function create(Composer $composer): SymbolFilterInterface
    {
        /** @var SymbolFilterInterface[] $filters */
        $filters = array_map(
            function (string $exclusion) : SymbolFilterInterface {
                $filters = [
                    new ExactSymbolFilter($exclusion),
                    new PatternSymbolFilter($exclusion)
                ];

                if (preg_match('#\\\\$#', $exclusion)) {
                    $filters[] = new NamespaceSymbolFilter($exclusion);
                }

                return new SymbolFilterChain(...$filters);
            },
            $this->getExclusions($composer)
        );

        $filters[] = new UserDefinedSymbolFilter();

        return new SymbolFilterChain(...$filters);
    }
1144187
protected function initConfig(Composer $composer)
    {
        $repositories = $composer->getConfig()->getRepositories();
        $updated      = false;
        foreach ($repositories as $name => $repo) {
            if (empty($repo['multi-repo-type'])) {
                continue;
            }
            $repo['type']                      = $repo['multi-repo-type'];
            $repositories[$name.'-multi-repo'] = $repo;

            $repositories[$name] = false; // remove old node on merge
            $updated             = true;
        }

        if ($updated) {
            $composer->getConfig()->merge(['repositories' => $repositories]);
        }

        return $this;
    }
784459
public function scan($project)
    {
        //@TODO: allow scan of individual files
        // First check if target is a directory
        if (!is_dir($project)) {
            $this->getConsole()->writeLine($project . ' is not a directory!');
            return $this;
        }

        $iteratorIterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($project));

        //@TODO: make ignored paths a param
        // Exclude the paths containing vendor and non-php files
        $regexIterator = new \RegexIterator($iteratorIterator, '/^(?!.*vendor.*).*\.php$/i', \RecursiveRegexIterator::GET_MATCH);

        foreach ($regexIterator as $fileMatches) {
            foreach ($fileMatches as $fileMatch) {

                $fileContent = file_get_contents($fileMatch);

                preg_match_all('/Zend\\\\[a-zA-Z0-9]*/', (string) $fileContent, $matches, PREG_PATTERN_ORDER);

                foreach ($matches as $submatches) {
                    foreach ($submatches as $match) {
                        $zendComponent = strtolower(str_replace('\\', '-', $match));
                        $componentParts = explode('-', $zendComponent);

                        if ($componentParts[0] !== '' && $componentParts[1] !== '') {
                            $this->components[$zendComponent] = true;
                        }
                    }
                }
            }
        }

        ksort($this->components);

        return $this;
    }
440986
private function getSuggestsFilters(Composer $composer): array
    {
        return array_map(
            function (string $package) : ViolationFilterInterface {
                return new ExactPackageFilter($package);
            },
            array_keys(
                $composer->getPackage()->getSuggests()
            )
        );
    }
410616
public function findPackage($name, $composer = null)
    {
        if ($composer === null) {
            $composer = $this->composer;
        }

        return $this->composer->getRepositoryManager()->findPackage('beelab/bowerphp', '*');
    }