Skip to content

Commit

Permalink
Drastically simplify using Composer Runtime API (#65)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Moshe Weitzman <weitzman@tejasa.com>
  • Loading branch information
webflo and weitzman committed May 8, 2024
1 parent ba98770 commit 1fa6548
Show file tree
Hide file tree
Showing 15 changed files with 206 additions and 34 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
matrix:
operating-system: ['ubuntu-latest']
php-versions: ['7.2', '7.3', '7.4', '8.0']
php-versions: ['8.1']
steps:
- name: Checkout
uses: actions/checkout@v2
Expand All @@ -21,5 +21,8 @@ jobs:
- name: Install dependencies
run: composer install

- name: Install fixtures
run: composer install-fixtures

- name: Run unit tests
run: ./vendor/bin/phpunit
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/composer.lock
/vendor/
/.phpunit.result.cache
/tests/fixtures/custom-vendor/foo
/tests/fixtures/default/web
/tests/fixtures/default/vendor
/tests/fixtures/*/composer.lock
31 changes: 4 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,22 @@
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/webflo/drupal-finder/ci.yml)](https://github.com/webflo/drupal-finder/actions/workflows/ci.yml)
[![Packagist](https://img.shields.io/packagist/v/webflo/drupal-finder.svg)](https://packagist.org/packages/webflo/drupal-finder)

Drupal Finder provides a class to locate a Drupal installation in a given path.
Drupal Finder provides a class to locate a Drupal installation based on Composer metadata.

## Usage

```PHP
$drupalFinder = new \DrupalFinder\DrupalFinder(getcwd());
$drupalFinder = new \DrupalFinder\DrupalFinderComposerRuntime();

$drupalRoot = $drupalFinder->getDrupalRoot();
$composerRoot = $drupalFinder->getComposerRoot();
$vendorDir = $drupalFinder->getVendorDir();
```

### Environment variables

If a set of environment variables is specified, then Drupal Finder uses those
values to determine the paths of the pertinent directories:

- `DRUPAL_FINDER_DRUPAL_ROOT`
- `DRUPAL_FINDER_COMPOSER_ROOT`
- `DRUPAL_FINDER_VENDOR_DIR`

For example:

- `DRUPAL_FINDER_DRUPAL_ROOT=/var/www/web`
- `DRUPAL_FINDER_COMPOSER_ROOT=/var/www`
- `DRUPAL_FINDER_VENDOR_DIR=/var/www/vendor`

This is useful for situations where you are containerizing an application,
directories may be in odd places, or a composer.json might be missing since it
is unneeded in a final build artifact.

You are not required to set all the environment variables to use this
feature. If you set an environment variable, then its associated getter
function will return the value assigned to the environment variable.

## Examples

- [Drupal Console Launcher](https://github.com/hechoendrupal/drupal-console-launcher)
- [Drush Launcher](https://github.com/drush-ops/drush-launcher)
- [Drush](https://github.com/drush-ops/drush)
- [phpstan-drupal](https://github.com/mglaman/phpstan-drupal)

## License

Expand Down
34 changes: 28 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webflo/drupal-finder",
"description": "Helper class to locate a Drupal installation from a given path.",
"description": "Helper class to locate a Drupal installation.",
"license": "GPL-2.0-or-later",
"type": "library",
"authors": [
Expand All @@ -10,20 +10,42 @@
}
],
"require": {
"ext-json": "*"
"composer-runtime-api": "^2.2",
"php": ">=8.1"
},
"autoload": {
"classmap": [
"src/DrupalFinder.php"
]
"psr-4": {
"DrupalFinder\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"DrupalFinder\\Tests\\": "tests/"
}
},
"require-dev": {
"phpunit/phpunit": "^8.5.14",
"phpunit/phpunit": "^10.4",
"mikey179/vfsstream": "^1.6"
},
"config": {
"platform": {
"php": "8.1"
}
},
"scripts": {
"install-fixtures": [
"cd tests/fixtures/custom-vendor && composer install",
"cd tests/fixtures/default && composer install"
],
"uninstall-fixtures": [
"rm -rf tests/fixtures/*/composer.lock",
"rm -rf tests/fixtures/custom-vendor/foo",
"rm -rf tests/fixtures/default/web",
"rm -rf tests/fixtures/default/vendor"
],
"reinstall-fixtures": [
"@uninstall-fixtures",
"@install-fixtures"
]
}
}
1 change: 1 addition & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<testsuites>
<testsuite name="DrupalFinder Test Suite">
<directory>./tests</directory>
<exclude>./tests/fixtures</exclude>
</testsuite>
</testsuites>
</phpunit>
4 changes: 4 additions & 0 deletions src/DrupalFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

namespace DrupalFinder;

/**
* @deprecated in drupal-finder:1.3.0 and is removed from drupal-finder:2.0.0.
* Use \DrupalFinder\DrupalFinderComposerRuntime instead.
*/
class DrupalFinder
{
/**
Expand Down
41 changes: 41 additions & 0 deletions src/DrupalFinderComposerRuntime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/**
* @file
* Contains \DrupalFinder\DrupalFinderComposerRuntime.
*/

namespace DrupalFinder;

use Composer\InstalledVersions;

class DrupalFinderComposerRuntime
{
/**
* Get the Drupal root path.
*/
public function getDrupalRoot(): ?string
{
$core = InstalledVersions::getInstallPath('drupal/core');
return $core ? realpath(dirname($core)) : null;
}

/**
* Get the path to the Composer root directory.
*/
public function getComposerRoot(): ?string
{
$root = InstalledVersions::getRootPackage();
return realpath($root['install_path']);
}

/**
* Get the vendor path.
*/
public function getVendorDir(): ?string
{
$reflection = new \ReflectionClass(InstalledVersions::class);
return realpath(dirname(dirname($reflection->getFileName())));
}

}
3 changes: 3 additions & 0 deletions tests/Drupal7FinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use DrupalFinder\DrupalFinder;
use org\bovigo\vfs\vfsStream;

/**
* @deprecated in drupal-finder:1.3.0 and is removed from drupal-finder:2.0.0.
*/
class Drupal7FinderTest extends DrupalFinderTestBase
{
protected static $fileStructure = [
Expand Down
3 changes: 3 additions & 0 deletions tests/Drupal8FinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
use org\bovigo\vfs\vfsStream;
use DrupalFinder\DrupalFinder;

/**
* @deprecated in drupal-finder:1.3.0 and is removed from drupal-finder:2.0.0.
*/
class Drupal8FinderTest extends DrupalFinderTestBase
{
protected static $fileStructure = [
Expand Down
39 changes: 39 additions & 0 deletions tests/DrupalFinderComposerRuntimeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace DrupalFinder\Tests;

use PHPUnit\Framework\TestCase;

class DrupalFinderComposerRuntimeTest extends TestCase {

protected const installFixtures = 'Execute "composer install-fixtures" first.';

/**
* @runInSeparateProcess
*/
public function testDefault() {
$basePath = realpath( __DIR__ . '/fixtures/default');
$this->assertDirectoryExists($basePath . '/vendor', static::installFixtures);
$this->assertDirectoryExists($basePath . '/web', static::installFixtures);

$result = json_decode(require $basePath . '/drupal-finder.php', TRUE);
$this->assertSame($result['getComposerRoot'], $basePath);
$this->assertSame($result['getVendorDir'], $basePath . '/vendor');
$this->assertSame($result['getDrupalRoot'], $basePath . '/web');
}

/**
* @runInSeparateProcess
*/
public function testCustomVendor() {
$basePath = realpath( __DIR__ . '/fixtures/custom-vendor');
$this->assertDirectoryExists($basePath . '/foo/bar', static::installFixtures);
$this->assertDirectoryExists($basePath . '/foo/bar/drupal', static::installFixtures);

$result = json_decode(require $basePath . '/drupal-finder.php', TRUE);
$this->assertSame($result['getComposerRoot'], $basePath);
$this->assertSame($result['getVendorDir'], $basePath . '/foo/bar');
$this->assertSame($result['getDrupalRoot'], $basePath . '/foo/bar/drupal');
}

}
3 changes: 3 additions & 0 deletions tests/DrupalFinderTestBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
use PHPUnit\Framework\SkippedTestError;
use PHPUnit\Framework\TestCase;

/**
* @deprecated in drupal-finder:1.3.0 and is removed from drupal-finder:2.0.0.
*/
abstract class DrupalFinderTestBase extends TestCase
{
/**
Expand Down
17 changes: 17 additions & 0 deletions tests/fixtures/custom-vendor/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"repositories": {
"drupal-finder": {
"type": "path",
"url": "../../../"
}
},
"require": {
"webflo/drupal-finder": "*",
"drupal/core": "^10"
},
"config": {
"vendor-dir": "foo/bar"
},
"minimum-stability": "dev",
"prefer-stable": true
}
14 changes: 14 additions & 0 deletions tests/fixtures/custom-vendor/drupal-finder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use DrupalFinder\DrupalFinderComposerRuntime;

require __DIR__ . '/foo/bar/autoload.php';

$finder = new DrupalFinderComposerRuntime();

return json_encode([
'getComposerRoot' => $finder->getComposerRoot(),
'getVendorDir' => $finder->getVendorDir(),
'getDrupalRoot' => $finder->getDrupalRoot(),
]
);
27 changes: 27 additions & 0 deletions tests/fixtures/default/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"repositories": {
"drupal-finder": {
"type": "path",
"url": "../../../"
}
},
"require": {
"composer/installers": "^2.2",
"drupal/core": "^10",
"webflo/drupal-finder": "*"
},
"config": {
"allow-plugins": {
"composer/installers": true
}
},
"extra": {
"installer-paths": {
"web/core": [
"type:drupal-core"
]
}
},
"minimum-stability": "dev",
"prefer-stable": true
}
14 changes: 14 additions & 0 deletions tests/fixtures/default/drupal-finder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use DrupalFinder\DrupalFinderComposerRuntime;

require __DIR__ . '/vendor/autoload.php';

$finder = new DrupalFinderComposerRuntime();

return json_encode([
'getComposerRoot' => $finder->getComposerRoot(),
'getVendorDir' => $finder->getVendorDir(),
'getDrupalRoot' => $finder->getDrupalRoot(),
]
);

0 comments on commit 1fa6548

Please sign in to comment.