Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support asset repo type and any repository without composer.json file #300

Merged
merged 1 commit into from
Nov 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/Composer/DriverFactoryAwareInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Packeton\Composer;

interface DriverFactoryAwareInterface
{
public function setDriverFactory(VcsDriverFactory $factory): void;
}
8 changes: 6 additions & 2 deletions src/Composer/PackagistFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,13 @@ public function createRepository(string $url, ?IOInterface $io = null, ?Config $
}

$repoConfig['url'] = $url;
if (isset($repoConfig['subDirectory']) || ($repoConfig['repoType'] ?? null) === RepTypes::MONO_REPO) {
$repoType = $repoConfig['repoType'] ?? null;
if (isset($repoConfig['subDirectory']) || $repoType === RepTypes::MONO_REPO) {
$repoConfig['driver'] = 'git-tree';
}
if ($repoType === RepTypes::ASSET) {
$repoConfig['driver'] = 'asset';
}

if (null !== $credentials || true === $this->githubNoApi) {
// Disable API if used ssh key
Expand All @@ -177,6 +181,6 @@ public function createRepository(string $url, ?IOInterface $io = null, ?Config $
$repoConfig['driver'] = $config->get('_driver');
}

return $this->repositoryFactory->create($repoConfig, $io, $config, $repoConfig['repoType'] ?? null);
return $this->repositoryFactory->create($repoConfig, $io, $config, $repoType);
}
}
108 changes: 108 additions & 0 deletions src/Composer/Repository/Vcs/AssetVcsDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

declare(strict_types=1);

namespace Packeton\Composer\Repository\Vcs;

use Composer\Config;
use Composer\IO\IOInterface;
use Composer\Repository\Vcs\VcsDriver;
use Packeton\Composer\DriverFactoryAwareInterface;
use Packeton\Composer\VcsDriverFactory;

class AssetVcsDriver extends VcsDriver implements DriverFactoryAwareInterface
{
private VcsDriver $driver;
private VcsDriverFactory $driverFactory;

public function initialize(): void
{
$repoConfig = $this->repoConfig;
$repoConfig['driver'] = 'vcs';
$repoConfig['repoType'] = 'vcs';

$this->driver = $this->driverFactory->createDriver(
repoConfig: $repoConfig,
io: $this->io,
config: $this->config,
httpDownloader: $this->httpDownloader,
process: $this->process,
classOrType: $repoConfig['driver'],
options: ['url' => $repoConfig['url']],
);
}

public function getComposerInformation(string $identifier): ?array
{
$composer = $this->repoConfig['customComposerJson'] ?? [];
if ($this->repoConfig['packageName'] ?? null) {
$composer['name'] = $this->repoConfig['packageName'];
}

if (empty($composer['time']) && null !== ($changeDate = $this->getChangeDate($identifier))) {
$composer['time'] = $changeDate->format(DATE_RFC3339);
}

return $composer;
}

public function getFileContent(string $file, string $identifier): ?string
{
return $this->driver->getFileContent($file, $identifier);
}

public function getChangeDate(string $identifier): ?\DateTimeImmutable
{
return $this->driver->getChangeDate($identifier);
}

public function getRootIdentifier(): string
{
return $this->driver->getRootIdentifier();
}

public function getBranches(): array
{
return $this->driver->getBranches();
}

public function getTags(): array
{
return $this->driver->getTags();
}

public function getDist(string $identifier): ?array
{
return $this->driver->getDist($identifier);
}

public function getSource(string $identifier): array
{
return $this->driver->getSource($identifier);
}

public function getUrl(): string
{
return $this->driver->getUrl();
}

public function hasComposerFile(string $identifier): bool
{
return true;
}

public function cleanup(): void
{
$this->driver->cleanup();
}

public static function supports(IOInterface $io, Config $config, string $url, bool $deep = false): bool
{
return false;
}

public function setDriverFactory(VcsDriverFactory $factory): void
{
$this->driverFactory = $factory;
}
}
11 changes: 9 additions & 2 deletions src/Composer/VcsDriverFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Composer\Config;
use Composer\IO\IOInterface;
use Composer\Repository\Vcs\VcsDriver;
use Composer\Util\HttpDownloader;
use Composer\Util\ProcessExecutor;

Expand All @@ -32,6 +33,7 @@ public function __construct(array $drivers = [])
'fossil' => 'Composer\Repository\Vcs\FossilDriver',
// svn must be last because identifying a subversion server for sure is practically impossible
'svn' => 'Composer\Repository\Vcs\SvnDriver',
'asset' => 'Packeton\Composer\Repository\Vcs\AssetVcsDriver',
];
}

Expand All @@ -54,10 +56,11 @@ public function setDriverClass(string $type, string $class): void
* @param string|null $classOrType
* @param array $options
*
* @return \Composer\Repository\Vcs\VcsDriver
* @return VcsDriver
*/
public function createDriver(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process, ?string $classOrType = null, array $options = [])
public function createDriver(array $repoConfig, IOInterface $io, Config $config, HttpDownloader $httpDownloader, ProcessExecutor $process, ?string $classOrType = null, array $options = []): VcsDriver
{
/** @var VcsDriver|null $driver */
$driver = null;
if ($classOrType && class_exists($classOrType)) {
$driver = new $classOrType($repoConfig, $io, $config, $process);
Expand Down Expand Up @@ -91,6 +94,10 @@ public function createDriver(array $repoConfig, IOInterface $io, Config $config,
throw new \UnexpectedValueException("VCS Driver not found for repository $repoUrl");
}

if ($driver instanceof DriverFactoryAwareInterface) {
$driver->setDriverFactory($this);
}

if (!($options['lazy'] ?? false)) {
$driver->initialize();
}
Expand Down
1 change: 1 addition & 0 deletions src/Entity/Package.php
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ public function getRepoConfig(): array
'oauth2' => $this->integration,
'externalRef' => $this->externalRef,
'customVersions' => $this->getCustomVersions(),
'customComposerJson' => $this->getCustomComposerJson(),
'packageName' => $this->name,
];

Expand Down
10 changes: 10 additions & 0 deletions src/Entity/PackageSerializedTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,16 @@ public function setCustomVersions($versions): void
$this->setSerialized('custom_versions', $versions);
}

public function getCustomComposerJson(): array
{
return $this->getSerialized('custom_composer_json', 'array', []);
}

public function setCustomComposerJson(?array $composer): void
{
$this->setSerialized('custom_composer_json', $composer);
}

public function isDisabledUpdate(): bool
{
return (bool) ($this->serializedFields['disabled_update'] ?? false);
Expand Down
66 changes: 66 additions & 0 deletions src/Form/Type/Package/AssetPackageType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Packeton\Form\Type\Package;

use Packeton\Form\Type\CredentialType;
use Packeton\Form\Type\JsonTextType;
use Packeton\Model\PackageManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Validator\Constraints\NotBlank;

class AssetPackageType extends AbstractType
{
use VcsPackageTypeTrait;

public function __construct(private readonly PackageManager $packageManager)
{
}

public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->remove('pullRequestReview');

$builder
->add('credentials', CredentialType::class)
->add('repository', TextType::class, [
'label' => 'Repository URL (Git/Svn/Hg)',
'attr' => [
'class' => 'package-repo-info',
'placeholder' => 'e.g.: https://github.com/fullcalendar/fullcalendar',
],
'constraints' => [new NotBlank()],
])
->add('name', TextType::class, [
'required' => true,
'constraints' => [new NotBlank()],
'attr' => ['class' => 'package-repo-info', 'placeholder' => 'npm-asset/select2'],
'disabled' => false === $options['is_created'],
]);

$placeholder = [
'name' => 'npm-asset/select2',
'description' => 'Select2 is a jQuery-based replacement for select boxes.',
'require' => ['php' => '>8.1'],
'autoload' => ['psr-4' => ['Packeton\\' => 'src/']]
];

$builder
->add('customComposerJson', JsonTextType::class, [
'required' => false,
'label' => 'composer.json config',
'attr' => ['rows' => 12, 'placeholder' => json_encode($placeholder, 448)]
]);

$builder->addEventListener(FormEvents::POST_SUBMIT, $this->updateRepository(...), 255);
}

public function getParent(): string
{
return BasePackageType::class;
}
}
1 change: 1 addition & 0 deletions src/Form/Type/Package/BasePackageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'Custom (JSON)' => RepTypes::CUSTOM,
'Proxy Repo' => RepTypes::PROXY,
'Virtual (only JSON metadata)' => RepTypes::VIRTUAL,
'VCS (Asset + Custom JSON)' => RepTypes::ASSET,
'Satis / Packagist.com / VCS Import' => 'import', // only redirect
];

Expand Down
13 changes: 2 additions & 11 deletions src/Form/Type/Package/PackageType.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

class PackageType extends AbstractType
{
use VcsPackageTypeTrait;

/**
* @var PackageManager
*/
Expand Down Expand Up @@ -57,17 +59,6 @@ public function getParent(): string
return BasePackageType::class;
}

/**
* @param FormEvent $event
*/
public function updateRepository(FormEvent $event): void
{
$package = $event->getData();
if ($package instanceof Package) {
$this->packageManager->updatePackageUrl($package);
}
}

/**
* {@inheritdoc}
*/
Expand Down
19 changes: 19 additions & 0 deletions src/Form/Type/Package/VcsPackageTypeTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace Packeton\Form\Type\Package;

use Packeton\Entity\Package;
use Symfony\Component\Form\FormEvent;

trait VcsPackageTypeTrait
{
public function updateRepository(FormEvent $event): void
{
$package = $event->getData();
if ($package instanceof Package) {
$this->packageManager->updatePackageUrl($package);
}
}
}
15 changes: 14 additions & 1 deletion src/Package/RepTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Packeton\Package;

use Packeton\Form\Type\Package\ArtifactPackageType;
use Packeton\Form\Type\Package\AssetPackageType;
use Packeton\Form\Type\Package\CustomPackageType;
use Packeton\Form\Type\Package\IntegrationPackageType;
use Packeton\Form\Type\Package\MonoRepoPackageType;
Expand All @@ -20,15 +21,17 @@ class RepTypes
public const CUSTOM = 'custom';
public const VIRTUAL = 'virtual';
public const PROXY = 'proxy';
public const ASSET = 'asset';

private static $types = [
private static array $types = [
self::ARTIFACT,
self::MONO_REPO,
self::INTEGRATION,
self::VCS,
self::CUSTOM,
self::VIRTUAL,
self::PROXY,
self::ASSET
];

public static function getFormType(?string $type): string
Expand All @@ -39,6 +42,7 @@ public static function getFormType(?string $type): string
self::INTEGRATION => IntegrationPackageType::class,
self::CUSTOM, self::VIRTUAL => CustomPackageType::class,
self::PROXY => ProxyPackageType::class,
self::ASSET => AssetPackageType::class,
default => PackageType::class,
};
}
Expand Down Expand Up @@ -74,7 +78,16 @@ public static function normalizeType(?string $type): string
self::CUSTOM => self::CUSTOM,
self::VIRTUAL => self::VIRTUAL,
self::PROXY => self::PROXY,
self::ASSET => self::ASSET,
default => self::VCS,
};
}

/**
* @return string[]
*/
public static function getAllTypes(): array
{
return self::$types;
}
}
2 changes: 1 addition & 1 deletion src/Package/Updater.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public function setSerializerCachePath(?string $serializerCachePath): void
*/
public static function supportRepoTypes(): iterable
{
return [RepTypes::VCS, RepTypes::ARTIFACT, RepTypes::INTEGRATION, RepTypes::CUSTOM, RepTypes::VIRTUAL, RepTypes::PROXY];
return [RepTypes::VCS, RepTypes::ARTIFACT, RepTypes::INTEGRATION, RepTypes::CUSTOM, RepTypes::VIRTUAL, RepTypes::PROXY, RepTypes::ASSET];
}

/**
Expand Down