Skip to content

Commit

Permalink
[FEATURE] Add ComposerReader to read information from composer.json
Browse files Browse the repository at this point in the history
This enables Tailor to automatically fetch the extension key if provided.
  • Loading branch information
o-ba authored Jan 12, 2021
1 parent 4a35cd6 commit 12b61aa
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 18 deletions.
45 changes: 28 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,21 @@ option. If set, the raw result will be returned. This can be
used for further processing e.g. by using some JSON processor.

Most of the commands require an extension key to work with.
However, since Tailor can be required as a dev dependency into
any single TYPO3 extension project it's also possible to define
the extension key as an environment variable with
`TYPO3_EXTENSION_KEY` globally. So you don't have to add it on
each command exceution manually.
There are multiple possibilities to provide an extension key.
These are - in the order in which they are checked:

**Note:** If no extension key is defined, neither as environment
variable nor as argument, commands which require an extension
key to be set, will throw an exception.
* As argument, e.g. `./vendor/bin/tailor ter:details my_key`
* As environment variable, `TYPO3_EXTENSION_KEY=my_key`
* In your `composer.json`, `[extra][typo3/cms][extension-key] = 'my_key'`

**Tip:** Definition of an extension key as argument precedes the
value from the environment variable. This means, even if you have
an extension key defined globally, you can still run all commands
for different extensions by adding them as argument to the command.
This means, even if you have an extension key defined globally,
either as environment variable or in your `composer.json`, you
can still run all commands for different extensions by adding
the desired extension key as argument to the command.

**Note:** If no extension key is defined, neither as an argument,
as environment variable, nor in your `composer.json`, commands
which require an extension key to be set, will throw an exception.

### Manage your personal access token

Expand Down Expand Up @@ -116,7 +117,7 @@ confirmation:
Key: my_extension
Owner: your_username

### Update the version of your extension in `ext_emconf.php`
### Update the version in your extension files

Prior to publishing a new version, you have to update the
version in your extensions `ext_emconf.php` file. This can
Expand Down Expand Up @@ -162,9 +163,9 @@ Using the root direcotry:

./vendor/bin/tailor ter:publish 1.2.0 my_extension

If the extension key is defined as environment variable,
it can also be skipped. So using the current root directory
the whole command simplifies to:
If the extension key is defined as environment variable or
in your `composer.json`, it can also be skipped. So using the
current root directory the whole command simplifies to:

./vendor/bin/tailor ter:publish 1.2.0

Expand Down Expand Up @@ -327,7 +328,7 @@ commands, requesting the TER API

## Publish a new version using tailor locally

**Step 1: Update the version in ext_emconf.php**
**Step 1: Update the version in your extension files**

./vendor/bin/tailor set-version 1.5.0

Expand Down Expand Up @@ -370,6 +371,11 @@ new tag.
The workflow furthermore requires the GitHub secrets
`TYPO3_EXTENSION_KEY` and `TYPO3_API_TOKEN` to be set.

**Note**: If your `composer.json` file contains your extension
key, you can remove the `TYPO3_EXTENSION_KEY` secret and the
assignment in the GitHub action, since Tailor automatically
fetches this key then.

The version is automatically fetched from the tag and
validated to match the required pattern.

Expand Down Expand Up @@ -460,6 +466,11 @@ The upload comment is taken from the message in the tag.
The job furthermore requires the GitLab variables
`TYPO3_EXTENSION_KEY` and `TYPO3_API_TOKEN` to be set.

**Note**: If your `composer.json` file contains your extension
key, you can remove the `TYPO3_EXTENSION_KEY` variable, the
check and the assignment in the GitLab pipeline, since Tailor
automatically fetches this key then.

The variable `CI_COMMIT_TAG` is set by GitLab automatically.

```yaml
Expand Down
5 changes: 4 additions & 1 deletion src/Command/AbstractClientRequestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use TYPO3\Tailor\Dto\RequestConfiguration;
use TYPO3\Tailor\Environment\Variables;
use TYPO3\Tailor\Exception\ExtensionKeyMissingException;
use TYPO3\Tailor\Filesystem\ComposerReader;
use TYPO3\Tailor\Formatter\ConsoleFormatter;
use TYPO3\Tailor\HttpClientFactory;
use TYPO3\Tailor\Service\RequestService;
Expand Down Expand Up @@ -102,9 +103,11 @@ protected function getExtensionKey(InputInterface $input): string
$extensionKey = $key;
} elseif (Variables::has('TYPO3_EXTENSION_KEY')) {
$extensionKey = Variables::get('TYPO3_EXTENSION_KEY');
} elseif (($extensionKeyFromComposer = (new ComposerReader())->getExtensionKey()) !== '') {
$extensionKey = $extensionKeyFromComposer;
} else {
throw new ExtensionKeyMissingException(
'The extension key must either be set as argument or as environment variable',
'The extension key must either be set as argument, as environment variable or in the composer.json.',
1605706548
);
}
Expand Down
17 changes: 17 additions & 0 deletions src/Exception/InvalidComposerJsonException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 project - inspiring people to share!
* (c) 2020 Oliver Bartsch & Benni Mack
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace TYPO3\Tailor\Exception;

class InvalidComposerJsonException extends \InvalidArgumentException
{
}
45 changes: 45 additions & 0 deletions src/Filesystem/ComposerReader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 project - inspiring people to share!
* (c) 2020 Oliver Bartsch & Benni Mack
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace TYPO3\Tailor\Filesystem;

use TYPO3\Tailor\Exception\InvalidComposerJsonException;

/**
* Reading information from composer.json
*/
class ComposerReader
{
/** @var array */
protected $composerSchema = [];

public function __construct(string $path = '')
{
$filename = rtrim($path ?: (string)(getcwd() ?: '.'), '/') . '/composer.json';
if (!file_exists($filename)) {
return;
}
$content = @file_get_contents($filename);
if ($content === false) {
return;
}
$this->composerSchema = json_decode($content, true);
if (!$this->composerSchema || $this->composerSchema === []) {
throw new InvalidComposerJsonException('The composer.json found is invalid!', 1610442954);
}
}

public function getExtensionKey(): string
{
return $this->composerSchema['extra']['typo3/cms']['extension-key'] ?? '';
}
}
80 changes: 80 additions & 0 deletions tests/Unit/Filesystem/ComposerReaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

/*
* This file is part of the TYPO3 project - inspiring people to share!
* (c) 2020 Oliver Bartsch & Benni Mack
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace TYPO3\Tailor\Tests\Unit\Filesystem;

use PHPUnit\Framework\TestCase;
use TYPO3\Tailor\Exception\InvalidComposerJsonException;
use TYPO3\Tailor\Filesystem\ComposerReader;

class ComposerReaderTest extends TestCase
{
private const COMPOSER_FILE = 'tmp/composer.json';

protected function setUp(): void
{
parent::setUp();
mkdir('tmp');
}

protected function tearDown(): void
{
unlink(self::COMPOSER_FILE);
rmdir('tmp');
parent::tearDown();
}

/**
* @test
*/
public function throwsExceptionOnEmptyComposerJsonFile(): void
{
$this->expectExceptionCode(1610442954);
$this->expectException(InvalidComposerJsonException::class);
file_put_contents(self::COMPOSER_FILE, '');
new ComposerReader('tmp');
}

/**
* @test
*/
public function throwsExceptionOnInvalidComposerJsonFile(): void
{
$this->expectExceptionCode(1610442954);
$this->expectException(InvalidComposerJsonException::class);
$composerContent = file_get_contents(__DIR__ . '/../Fixtures/EmConf/emconf_valid.php');
file_put_contents(self::COMPOSER_FILE, $composerContent);
new ComposerReader('tmp');
}

/**
* @test
*/
public function returnEmptyStringIfExtensionKeyNotGiven(): void
{
$composerContent = file_get_contents(__DIR__ . '/../Fixtures/Composer/composer_no_extension_key.json');
file_put_contents(self::COMPOSER_FILE, $composerContent);
$subject = new ComposerReader('tmp');
self::assertEmpty($subject->getExtensionKey());
}

/**
* @test
*/
public function readCorrectExtensionKeyFromGivenComposerJsonFile(): void
{
$composerContent = file_get_contents(__DIR__ . '/../Fixtures/Composer/composer_with_extension_key.json');
file_put_contents(self::COMPOSER_FILE, $composerContent);
$subject = new ComposerReader('tmp');
self::assertSame('my-extension', $subject->getExtensionKey());
}
}
20 changes: 20 additions & 0 deletions tests/Unit/Fixtures/Composer/composer_no_extension_key.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "acme/my_extension",
"type": "typo3-cms-extension",
"description": "Great extension - everyone needs it",
"authors": [
{
"name": "John Doe",
"role": "Dev"
}
],
"license": [
"GPL-2.0-or-later"
],
"require": {
"typo3/cms-core": "^10.4"
},
"replace": {
"typo3-ter/news": "self.version"
}
}
25 changes: 25 additions & 0 deletions tests/Unit/Fixtures/Composer/composer_with_extension_key.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "acme/my_extension",
"type": "typo3-cms-extension",
"description": "Great extension - everyone needs it",
"authors": [
{
"name": "John Doe",
"role": "Dev"
}
],
"license": [
"GPL-2.0-or-later"
],
"require": {
"typo3/cms-core": "^10.4"
},
"replace": {
"typo3-ter/news": "self.version"
},
"extra": {
"typo3/cms": {
"extension-key": "my-extension"
}
}
}

0 comments on commit 12b61aa

Please sign in to comment.