Skip to content
Open
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
# uses: shivammathur/setup-php@v2
- uses: shivammathur/setup-php@2cb9b829437ee246e9b3cac53555a39208ca6d28
with:
php-version: '8.2'
php-version: '8.4'
- uses: actions/checkout@v3
- name: Cache Composer packages
id: composer-cache
Expand Down
8 changes: 5 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ composer.phar
composer.lock
/vendor/

# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control
# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
# composer.lock
.idea

###> friendsofphp/php-cs-fixer ###
/.php-cs-fixer.cache
###< friendsofphp/php-cs-fixer ###
19 changes: 19 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

$finder = PhpCsFixer\Finder::create()
->in(__DIR__ . '/lib')
->in(__DIR__ . '/tests/Unit');

$config = new PhpCsFixer\Config();
$config->setUnsupportedPhpVersionAllowed(true);

return $config
->setParallelConfig(\PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
->setRules([
'@Symfony' => true,
'@PSR1' => true,
'@PSR2' => true,
'@PSR12' => true,
])->setFinder($finder);
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,13 @@ $stack->version; // 6.3.0
// You can also pass an already authenticated Github Client
$client = new \Github\Client();
$client->authenticate('some_access_token', null, \Github\AuthMethod::ACCESS_TOKEN);
$detector = $factory->create();
$detector = $factory->create($client);

$stack = $detector->getStack('einenlum/private-repo');

// optionally: detect the stack on a specific branch
$stack = $detector->getStack('einenlum/private-repo:branch-name');

$stack->type === StackType::SYMFONY;
$stack->version; // 6.3.0
```
Expand Down Expand Up @@ -117,6 +120,12 @@ services:
composer run test
```

## Run interactive shell with docker

```shell
docker run --rm -it -v "$PWD":/app -w /app php:8.4-cli bash
```

## Contribute

Each stack has its own Detector implementing a [StackDetectorInterface](src/StackDetectorInterface.php).
Expand Down
13 changes: 9 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,25 @@
],
"require-dev": {
"phpunit/phpunit": "^10.4",
"phpstan/phpstan": "^1.10"
"phpstan/phpstan": "^2.1",
"friendsofphp/php-cs-fixer": "^3.82"
},
"require": {
"php": "^8.4",
"einenlum/composer-version-parser": "^1.0",
"knplabs/github-api": "^3.12",
"symfony/http-client": "^6.3",
"symfony/http-client": "^7.0",
"nyholm/psr7": "^1.8"
},
"scripts": {
"unit-test": "phpunit tests",
"static-analysis": "phpstan",
"test-cs": "./vendor/bin/php-cs-fixer fix --dry-run --diff -v",
"test-cs-fix": "./vendor/bin/php-cs-fixer fix --diff -v",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just cs-fix or fix-cs here?

"test": [
"@unit-test",
"@static-analysis"
"@test-cs",
"@static-analysis",
"@unit-test"
]
},
"config": {
Expand Down
2 changes: 1 addition & 1 deletion lib/Composer/ComposerConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Einenlum\PhpStackDetector\Composer;

class ComposerConfig
readonly class ComposerConfig
{
/** @param array<string, mixed> $content */
public function __construct(public ComposerConfigType $type, public array $content)
Expand Down
6 changes: 3 additions & 3 deletions lib/Composer/ComposerConfigProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ComposerConfigProvider
private array $cache = [];

public function __construct(
private AdapterInterface $adapter
private readonly AdapterInterface $adapter,
) {
}

Expand Down Expand Up @@ -93,7 +93,7 @@ private function getConfig(string $baseUri, ?string $subDirectory, string $filen
private function setToCache(
string $baseUri,
?string $subDirectory,
?ComposerConfig $config
?ComposerConfig $config,
): void {
$cacheKey = $this->getCacheKey($baseUri, $subDirectory);

Expand All @@ -116,6 +116,6 @@ private function getFromCache(string $baseUri, ?string $subDirectory): ?Composer

private function getCacheKey(string $baseUri, ?string $subDirectory): string
{
return $baseUri . $subDirectory;
return $baseUri.$subDirectory;
}
}
15 changes: 9 additions & 6 deletions lib/Composer/PackageVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@

use Einenlum\ComposerVersionParser\Parser;

class PackageVersion
readonly class PackageVersion
{
public function __construct(
private ?string $requirement,
private ?string $version
private ?string $version,
) {
}

public function getVersion(): ?string
{
if ($this->version !== null) {
if (mb_strpos($this->version, 'v') === 0) {
if (null !== $this->version) {
if (0 === mb_strpos($this->version, 'v')) {
return mb_substr($this->version, 1);
}

Expand All @@ -26,8 +26,11 @@ public function getVersion(): ?string

/** @var string $requirement */
$requirement = $this->requirement;
$parser = new Parser();

return $parser->parse($requirement);
if (str_starts_with($requirement, '~v')) {
$requirement = mb_substr($requirement, 2);
}

return new Parser()->parse($requirement);
}
}
10 changes: 4 additions & 6 deletions lib/Composer/PackageVersionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,26 @@

namespace Einenlum\PhpStackDetector\Composer;

use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface;

class PackageVersionProvider
readonly class PackageVersionProvider
{
public function __construct(private ComposerConfigProvider $configProvider)
{
}

/**
* @param string ...$packageNames A list of packages to check in that order
* @param string[] $packageNames A list of packages to check in that order
*/
public function getVersionForPackage(
string $baseUri,
?string $subDirectory,
string ...$packageNames
array $packageNames,
): ?PackageVersion {
$config = $this->configProvider->getComposerConfig($baseUri, $subDirectory);
if (null === $config) {
return null;
}

if ($config->type === ComposerConfigType::LOCK) {
if (ComposerConfigType::LOCK === $config->type) {
foreach ($packageNames as $packageName) {
foreach ($config->content['packages'] as $package) {
if ($package['name'] === $packageName) {
Expand Down
18 changes: 14 additions & 4 deletions lib/DependencyTree.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,27 @@

namespace Einenlum\PhpStackDetector;

use Einenlum\PhpStackDetector\StackDetector\LunarDetector;
use Einenlum\PhpStackDetector\StackDetector\OctoberCMSDetector;
use Einenlum\PhpStackDetector\StackDetector\StatamicDetector;
use Einenlum\PhpStackDetector\StackDetector\TwillDetector;
use Einenlum\PhpStackDetector\StackDetector\WinterCMSDetector;

class DependencyTree
{
public const EXCLUSION_LIST = [
public const array CHILDREN_STACKS = [
'laravel/framework' => [
'statamic/cms',
StatamicDetector::PACKAGE_NAME,
OctoberCMSDetector::PACKAGE_NAME,
LunarDetector::PACKAGE_NAME,
TwillDetector::PACKAGE_NAME,
WinterCMSDetector::PACKAGE_NAME,
],
];

/** @return string[] */
public static function skipIfThesePackagesArePresent(string $packageName): array
public static function getChildStacksForPackage(string $packageName): array
{
return self::EXCLUSION_LIST[$packageName] ?? [];
return self::CHILDREN_STACKS[$packageName] ?? [];
}
}
28 changes: 9 additions & 19 deletions lib/Detector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@

namespace Einenlum\PhpStackDetector;

use Einenlum\PhpStackDetector\Composer\ComposerConfigProvider;
use Einenlum\PhpStackDetector\DirectoryCrawler\AdapterInterface;
use Einenlum\PhpStackDetector\DirectoryCrawler\GithubAdapter;
use Einenlum\PhpStackDetector\StackDetector\CraftCMSDetector;
use Einenlum\PhpStackDetector\StackDetector\LaravelDetector;
use Einenlum\PhpStackDetector\StackDetector\StatamicDetector;
use Einenlum\PhpStackDetector\StackDetector\SymfonyDetector;
use Einenlum\PhpStackDetector\StackDetector\WordpressDetector;
use Github\Client;

class Detector
readonly class Detector
{
/** @param StackDetectorInterface[] $stackDetectors */
public function __construct(private array $stackDetectors)
Expand All @@ -23,11 +13,11 @@ public function __construct(private array $stackDetectors)

/**
* @param string $baseUri The base URI of the project, e.g.
* /some/path/to/local/project
* or
* symfony/demo for a remote Github repository
* or
* symfony/demo:v1.1 for a remote Github repository with a reference
* /some/path/to/local/project
* or
* symfony/demo for a remote Github repository
* or
* symfony/demo:v1.1 for a remote Github repository with a reference
*/
public function getStack(string $baseUri, ?string $subFolder = null): ?Stack
{
Expand All @@ -36,7 +26,7 @@ public function getStack(string $baseUri, ?string $subFolder = null): ?Stack
foreach ($this->stackDetectors as $stackDetector) {
$stack = $stackDetector->getStack($baseUri, $subFolder);

if ($stack !== null) {
if (null !== $stack) {
return $stack;
}
}
Expand All @@ -46,10 +36,10 @@ public function getStack(string $baseUri, ?string $subFolder = null): ?Stack

private function cleanSubFolder(?string $subFolder): ?string
{
if ($subFolder === null) {
if (null === $subFolder) {
return null;
}

return trim($subFolder) === '/' ? null : $subFolder;
return '/' === trim($subFolder) ? null : $subFolder;
}
}
2 changes: 1 addition & 1 deletion lib/DirectoryCrawler/AdapterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public function getFileContent(string $baseUri, ?string ...$pathTree): string;

public function directoryExists(string $baseUri, ?string ...$pathTree): bool;

/** @return array<int, null|string> */
/** @return array<int, string|null> */
public function listFilesInDirectory(string $baseUri, ?string ...$pathTree): array;
}
4 changes: 1 addition & 3 deletions lib/DirectoryCrawler/FilesystemAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

class FilesystemAdapter implements AdapterInterface
{
/** {@inheritdoc} */
public function getFileContent(string $baseUri, ?string ...$pathTree): string
{
$fullUri = $this->getFullUri($baseUri, $pathTree);
Expand All @@ -31,7 +30,6 @@ public function directoryExists(string $baseUri, ?string ...$pathTree): bool
return is_dir($fullUri);
}

/** {@inheritdoc} */
public function listFilesInDirectory(string $baseUri, ?string ...$pathTree): array
{
if (!$this->directoryExists($baseUri, ...$pathTree)) {
Expand All @@ -46,7 +44,7 @@ public function listFilesInDirectory(string $baseUri, ?string ...$pathTree): arr
return array_values(array_diff($files, ['..', '.']));
}

/** @param (null|string)[] $pathTree */
/** @param (string|null)[] $pathTree */
private function getFullUri(string $baseUri, array $pathTree): string
{
$pathTree = array_filter($pathTree);
Expand Down
7 changes: 3 additions & 4 deletions lib/DirectoryCrawler/GithubAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
use Github\Client;
use Github\Exception\RuntimeException;

class GithubAdapter implements AdapterInterface
readonly class GithubAdapter implements AdapterInterface
{
/*
* If you need to check private repositories, the client should aleady
* If you need to check private repositories, the client should already
* be authenticated.
*/
public function __construct(private Client $client)
Expand Down Expand Up @@ -91,7 +91,6 @@ public function listFilesInDirectory(string $baseUri, ?string ...$pathTree): arr
);
}


/**
* @return array{organization: string, repository: string, reference: ?string}
*/
Expand All @@ -113,7 +112,7 @@ private function splitBaseUri(string $baseUri): array
];
}

/** @param (null|string)[] $pathTree */
/** @param (string|null)[] $pathTree */
private function getPathTreeAsString(array $pathTree): string
{
$paths = array_filter($pathTree);
Expand Down
4 changes: 2 additions & 2 deletions lib/Factory/GithubDetectorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ class GithubDetectorFactory
{
use HasStackDetectors;

public function create(Client $client = null): Detector
public function create(?Client $client = null): Detector
{
$client = $client ?: new \Github\Client();
$client = $client ?: new Client();
$adapter = new GithubAdapter($client);

$stackDetectors = $this->getStackDetectors($adapter);
Expand Down
Loading