@SuppressWarnings(PHPMD.StaticAccess) | Using standard Composer utility class, no alternatives

@param PackageInterface $package
@param string $binDir
@return string[]
@throws \Exception
549387
public function installBinaries(PackageInterface $package, $binDir)
    {
        $sourceDir = $package->getTargetDir();
        
        $sourceDir = file_exists(DIRECTORY_SEPARATOR . $sourceDir)
            ? (DIRECTORY_SEPARATOR . $sourceDir)
            : $sourceDir;

        $matches = array();

        $binaries = $package->getBinaries();

        foreach ($binaries as $binary) {
            if (file_exists($this->systemUtils->composePath($sourceDir, $binary))) {
                $matches[] = $this->systemUtils->composePath($sourceDir, $binary);
            }

            $globPattern = $this->systemUtils->composePath($sourceDir, '**', $binary);

            $matches = array_merge(
                $matches,
                $this->systemUtils->recursiveGlob($globPattern)
            );
        }

        if (!$matches) {
            $errorMessage = sprintf(
                'Could not locate binaries (%s) from downloaded source',
                implode(
                    ', ',
                    array_unique(
                        array_map(function ($item) {
                            return basename($item);
                        }, $binaries)
                    )
                )
            );
            
            throw new \Exception($errorMessage);
        }
        
        $fileRenames = $this->pluginConfig->getExecutableFileRenames();
        
        $this->fileSystem->ensureDirectoryExists($binDir);

        foreach (array_filter($matches, 'is_executable') as $fromPath) {
            $fileName = basename($fromPath);
            
            $toPath = $this->systemUtils->composePath(
                $binDir,
                $this->dataUtils->extractValue($fileRenames, $fileName, $fileName)
            );

            $this->fileSystem->copyThenRemove($fromPath, $toPath);

            $platformCode = $this->platformAnalyser->getPlatformCode();

            if ($platformCode !== OsDetector::TYPE_WIN32 && $platformCode !== OsDetector::TYPE_WIN64) {
                \Composer\Util\Silencer::call('chmod', $toPath, 0777 & ~umask());
            }
        }

        return $matches;
    }
1040418
public function getInstallPath(PackageInterface $package)
    {
        $type = $package->getType();

        // Both prettyName and name consists of vendor and name, module name
        // requires vendor prefix to be stripped
        $prettyName = $package->getPrettyName();

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

        // Naming conventions for ZF1 modules require that the camel cased
        // module name must match the class prefix - so it's up to module
        // author or publisher to ensure that module name is correct.
        // If an installer-name extra is specified in module composer.json
        // it will be used as a name part of the installation path.
        $extra = $package->getExtra();
        if (!empty($extra['installer-name'])) {
            $name = $extra['installer-name'];
        }

        $availableVars = compact('name', 'vendor', 'type');

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

        return $this->_templatePath('application/modules/{$name}', $availableVars);
    }
186432
public function isPackageInstalled(PackageInterface $package)
    {
        return $this->filesystem->exists($this->config->getInstallDir() . '/' . $package->getName() . '/.bower.json');
    }
99875
private function determineLockViolations(
        Composer $composer,
        CandidateInterface ...$candidates
    ): array {
        $violations = [];
        $lock       = $composer->getLocker()->getLockData();

        $lockedPackages = array_map(
            function (array $package) : string {
                return $package['name'];
            },
            $lock['packages'] ?? []
        );

        $lockedDevPackages = array_map(
            function (array $package) : string {
                return $package['name'];
            },
            $lock['packages-dev'] ?? []
        );

        foreach ($candidates as $candidate) {
            $package = $candidate->getPackage()->getName();

            if (in_array($package, $lockedDevPackages, true)) {
                $violations[] = new Violation(
                    sprintf(
                        'Code base is dependent on dev package %s.',
                        $package
                    ),
                    $candidate
                );
                continue;
            }

            if (!in_array($package, $lockedPackages, true)) {
                $violations[] = new Violation(
                    sprintf(
                        'Package is not installed: %s.',
                        $package
                    ),
                    $candidate
                );
            }
        }

        return $violations;
    }
1214360
protected function getConfigPackagePath(string $dir, PackageInterface $package): ?string
    {
        $dir = preg_replace(
            '#^(' . preg_quote(getcwd() . DIRECTORY_SEPARATOR, '#') . ')#',
            '.' . DIRECTORY_SEPARATOR,
            $dir
        );

        $path = $this->getConfigPath($dir);
        if (file_exists($path))
        {
            $this->getLogger()->write(
                sprintf(
                    '  - Found in <info>%s</info>',
                    $package->getPrettyName()
                )
            );

            return $path;
        }

        return null;
    }
1203067
protected function getInstallerConfig(PackageInterface $package)
    {
        if ($this->installerConfig !== null) {
            return $this->installerConfig;
        }

        $type       = $package->getType();
        $prettyName = $package->getPrettyName();

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

        $extra = $package->getExtra();

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

        $loader = 'mu-plugins/' . $name . '.php';

        if (!empty($extra['installer-loader'])) {
            $loader = $extra['installer-loader'];
        }

        return compact('name', 'vendor', 'type', 'loader');
    }
155485
public function resetPackage(WritableRepositoryInterface $repository, PackageInterface $package)
    {
        $verbosityLevel = OutputUtils::resetVerbosity($this->appIO, OutputInterface::VERBOSITY_QUIET);

        $operation = new ResetOperation($package, 'Package reset due to changes in patches configuration');

        if (!$this->packageResetStrategy->shouldAllowReset($package)) {
            OutputUtils::resetVerbosity($this->appIO, $verbosityLevel);

            throw new \Vaimo\ComposerPatches\Exceptions\PackageResetException(
                sprintf('Package reset halted due to encountering local changes: %s', $package->getName())
            );
        }

        try {
            $this->installer->install($repository, $operation);
        } catch (\Exception $exception) {
            OutputUtils::resetVerbosity($this->appIO, $verbosityLevel);

            throw $exception;
        }

        OutputUtils::resetVerbosity($this->appIO, $verbosityLevel);
    }
125297
private function getContaoExtra(PackageInterface $package, $key)
    {
        $extras = $package->getExtra();

        if (!isset($extras['contao']) || !isset($extras['contao'][$key])) {
            return null;
        }

        return $extras['contao'][$key];
    }
379914
public static function createFromComposerPackage(CompletePackageInterface $package)
    {
        $class = new self();
        $class->type = $package->getType();
        $class->name = $package->getPrettyName();
        $class->description = $package->getDescription();
        $class->authors = $package->getAuthors();
        $class->keywords = $package->getKeywords();
        if ($package->getVersion() === '9999999-dev') {
            $class->version = sprintf('%s (%s)', $package->getPrettyVersion(), substr($package->getSourceReference(), 0, 6));
        } else {
            $class->version = $package->getPrettyVersion();
        }

        return $class;
    }
1326639
public function getInstallPath(PackageInterface $package)
    {
        $textpattern = new Textpattern();
        $path = $textpattern->getRelativePath();
        $themes = $path . '/admin-themes';

        // Textpattern <= 4.5.x uses 'theme' directory.
        if (!file_exists($themes)) {
            $themes = $path . '/theme';
        }

        return $themes . '/' . basename($package->getPrettyName());
    }
1105723
public function getInstallPath(PackageInterface $package)
	{
		$prefix = mb_substr($package->getPrettyName(), 0, 23);
		if ('myadmin/template-' !== $prefix) {
			throw new \InvalidArgumentException(
				'Unable to install template, myadmin templates '
				.'should always start their package name with '
				.'"myadmin/template-"'
			);
		}
		return 'data/templates/'.mb_substr($package->getPrettyName(), 23);
	}
935205
public function writelnInstalledPackage(PackageInterface $package)
    {
        $this->output->writeln(sprintf('bower <info>%s</info> <fg=cyan>%s</fg=cyan>',
            str_pad($package->getName() . '#' . $package->getVersion(), 21, ' ', STR_PAD_RIGHT),
            str_pad('install', 10, ' ', STR_PAD_LEFT)
        ));
    }
673396
private function getRequired(PackageInterface $package, bool $isRoot)
    {
        $required = [];

        if ($this->requireDependencies) {
            $required = $package->getRequires();
        }
        if (($isRoot || !$this->requireDependencyFilter) && $this->requireDevDependencies) {
            $required = array_merge($required, $package->getDevRequires());
        }

        return $required;
    }
871513
public function getPackageTranslations(Package $package)
    {
        $localStats = $this->localFactory->getAvailablePackageStats($package);
        $remoteStats = $this->remoteProvider->getAvailablePackageStats($package->getPackageHandle(), $package->getPackageVersion());

        return $this->computeUpdates($localStats, $remoteStats, $package);
    }
559820
public function updatePackage(PackageInterface $package, InstallerInterface $installer)
    {
        if (!$this->isPackageInstalled($package)) {
            throw new RuntimeException(sprintf('Package %s is not installed.', $package->getName()));
        }
        if (is_null($package->getRequiredVersion())) {
            $decode = $this->config->getBowerFileContent();
            if (empty($decode['dependencies']) || empty($decode['dependencies'][$package->getName()])) {
                throw new InvalidArgumentException(sprintf('Package %s not found in bower.json', $package->getName()));
            }
            $package->setRequiredVersion($decode['dependencies'][$package->getName()]);
        }

        $bower = $this->config->getPackageBowerFileContent($package);
        $package->setInfo($bower);
        $package->setVersion($bower['version']);
        $package->setRequires(isset($bower['dependencies']) ? $bower['dependencies'] : null);

        $packageTag = $this->getPackageTag($package);
        $this->output->writelnInfoPackage($package, 'validate', sprintf('%s against %s#%s', $packageTag, $package->getName(), $package->getRequiredVersion()));

        $package->setRepository($this->repository);
        if ($packageTag == $package->getVersion()) {
            // if version is fully matching, there's no need to update
            return;
        }
        $package->setVersion($packageTag);

        $this->cachePackage($package);

        $this->output->writelnUpdatingPackage($package);
        $installer->update($package);

        $overrides = $this->config->getOverrideFor($package->getName());
        if (array_key_exists('dependencies', $overrides)) {
            $dependencies = $overrides['dependencies'];
        } else {
            $dependencies = $package->getRequires();
        }
        if (!empty($dependencies)) {
            foreach ($dependencies as $name => $requiredVersion) {
                $depPackage = new Package($name, $requiredVersion);
                if (!$this->isPackageInstalled($depPackage)) {
                    $this->installPackage($depPackage, $installer, true);
                } elseif ($this->isNeedUpdate($depPackage)) {
                    $this->updatePackage($depPackage, $installer);
                }
            }
        }
    }
1356432
private function getFileMap(PackageInterface $package, $directory)
    {
        $files = [];
        $root  = $this->getInstallPath($package);

        if (!file_exists($root . '/' . $directory)) {
            return [];
        }

        $iterator = new RecursiveDirectoryIterator($root . '/' . $directory, RecursiveDirectoryIterator::SKIP_DOTS);

        /** @var SplFileInfo $file */
        foreach (new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST) as $file) {
            if ($file->isFile()) {
                $path = str_replace($root . '/' . $directory . '/', '', $file->getPathname());

                $files[$directory . '/' . $path] = $path;
            }
        }

        return $files;
    }
599239
public function processPackage(PackageInterface $package)
    {
        $extra = $package->getExtra();
        $files = isset($extra[self::EXTRA_OPTION_NAME]) ? $extra[self::EXTRA_OPTION_NAME] : null;
        if ($package->getType() !== self::PACKAGE_TYPE && is_null($files)) {
            return;
        }

        $extension = [
            'name'    => $package->getName(),
            'version' => $package->getVersion(),
        ];
        if ($package->getVersion() === '9999999-dev') {
            $reference = $package->getSourceReference() ?: $package->getDistReference();
            if ($reference) {
                $extension['reference'] = $reference;
            }
        }
        $this->data['extensions'][$package->getName()] = $extension;

        $aliases = array_merge(
            $this->prepareAliases($package, 'psr-0'),
            $this->prepareAliases($package, 'psr-4')
        );
        $this->data['aliases'] = array_merge($this->data['aliases'], $aliases);
        foreach ((array) $files as $name => $path) {
            $config = $this->readExtensionConfig($package, $path);
            $config['aliases'] = array_merge(
                $aliases,
                isset($config['aliases']) ? (array) $config['aliases'] : []
            );
            $this->data['aliases'] = array_merge($this->data['aliases'], $config['aliases']);
            $this->data[$name] = isset($this->data[$name]) ? Helper::mergeConfig($this->data[$name], $config) : $config;
        }
    }