Skip to content

Commit

Permalink
Merge pull request #300 from vtsykun/feat/asset-repo-support
Browse files Browse the repository at this point in the history
Support asset repo type and any repository without composer.json file
  • Loading branch information
vtsykun authored Nov 9, 2024
2 parents b6a0c7f + e08eeb5 commit 719ab1a
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 17 deletions.
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

0 comments on commit 719ab1a

Please sign in to comment.