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

Add a way to define configuration in atoum/*-edition packages #604

Closed
wants to merge 6 commits into from

Conversation

agallou
Copy link
Member

@agallou agallou commented Jun 5, 2016

This will allow us to create "editions" of atoum, will extensions preloaded and some stuff configured.

For example : https://github.com/agallou/atoum-standard-edition

By requirering only atoum/standard-edition this will :

  • install atoum/atoum
  • install atoum/stubs
  • install atoum/autoloop-extension
  • install atoum/visibility-extension
  • install atoum/config-extension
  • install atoum/reports-extension
  • load autoloop-extension
  • load visibility-extension
  • load config-extension
  • load reports-extension
  • if the TELEMETRY_ENABLED environement variable is defined, the telemetry report will be sent (with different anonymization settings depending of it's value (1, 2 ou 3).

we could also imagine

  • preconfiguring the coveralls report repending on an COVERALLS_API_KEY environnement variable
  • configure the autoloop using the files defined in the autoload from the project's composer.json
  • add a XUNIT_REPORT_PATH : that will generate the xunit report in the path specified in the environnement variable : that will also help the integration in CI environments.

you can see an example of usage here : https://github.com/agallou/atoum-std-edition-example (the repositories and atoum/atoum in the require section should not be here. They won't be if diffrent PR are merged).

This standard edition will help users set-up atoum.
This will also :

For now we still need to define manually a .bootstrap.atoum.php file, but if the PR #523 is also merged, the installation/configuration will even be easier.

@Grummfy
Copy link
Member

Grummfy commented Jun 5, 2016

thanks

@agallou
Copy link
Member Author

agallou commented Jun 6, 2016

https://github.com/agallou/atoum-standard-edition has been updated to ease the configuration of the xUnit report.

With this, for example, the configuration in Jenkins will be a lot easier. No config file will be needed.

only an environnement variable will be needed :

export XUNIT_REPORT_PATH=app/logs/xunit.xml
./vendor/bin/atoum                         

and to xml file will be created (so as the directory if it does not) :

tree app 
app
└── logs
    └── xunit.xml

1 directory, 1 file

@jubianchi
Copy link
Member

jubianchi commented Jun 11, 2016

This solution makes atoum coupled to eventual editions: I'm not really comfortable with that.

Here what I would like to propose as an alternative: edition would push their configuration to atoum using autoloader. Here is how.

The extension will have to declare an autoloader file:

{
    ...
    "autoloaders: {
        "files": [
            "configuration.php" 
        ]
    }
}

Inside this configuration.php file there will be the code used to pre-configure atoum:

<?php

use mageekguy\atoum;
use mageekguy\atoum\scripts;

if (defined('mageekguy\atoum\scripts\runner') === true) {
    scripts\runner::configureRunner(function(atoum\runner $runner) {
        $runner->addExtension(new atoum\blackfire\extension());
        //...
    });
}

Then in the project's .atoum.php file we can imagine something like:

<?php

use mageekguy\atoum;

$runner->getExtension(atoum\blackfire\extension::class)
    ->setClientConfiguration(/*...*/)
;

This would require less coupling but some work has to be done in atoum:

  • Add the mageekguy\atoum\scripts\runner::configureRunner method
  • Add the mageekguy\atoum\runner::getExtension method

What do you think ?

@agallou
Copy link
Member Author

agallou commented Jun 11, 2016

The getExtension could be very usefull. I will add this.

But using composer's autoloader will be problematic (i've also tried it when working on this PR).

The issue there is that atoum does not uses (yet?) composer's autoloader.

Samll change on your proposal, instead of passing a callback, i've tested by adding an array of files that will by loaded by the enableAutorun method :

Like this :

+++ b/classes/scripts/runner.php
@@ -29,8 +29,10 @@ class runner extends atoum\script\configurable
        protected $loop = false;
        protected $looper;

+
        protected static $autorunner = true;
        protected static $runnerFile = null;
+       protected static $autorunnerConfigurationFiles = array();

        public function __construct($name, atoum\adapter $adapter = null, atoum\scripts\runner\looper $looper = null)
        {
@@ -644,6 +646,10 @@ class runner extends atoum\script\configurable

                static::$autorunner = new static($name);

+               foreach (static::$autorunnerConfigurationFiles as $file) {
+                       static::$autorunner->useConfigFile($file);
+               }
+
                return static::$autorunner;
        }

@@ -652,6 +658,11 @@ class runner extends atoum\script\configurable
                static::$autorunner = false;
        }

+       public static function addAutorunnerConfigurationFile($file)
+       {
+               static::$autorunnerConfigurationFiles[] = $file;
+       }

the standard edition file has be changed to add an autoloader containing this :

<?php

use mageekguy\atoum;
use mageekguy\atoum\scripts;

if (defined('mageekguy\atoum\scripts\runner') === true) {
    scripts\runner::addAutorunnerConfigurationFile(__DIR__ . DIRECTORY_SEPARATOR . 'configuration.php');
}

This allows us to have configuration files similar to the .atoum.php ones.

By it doesn't work as is.

In order to make this work we need to add

require_once __DIR__ . '/../../../autoload.php';

in the vendor/atoum/atoum/scripts/runner.php file.

(or apply the patch of the #523 PR)

Without that, atoum will never load composer's autoloader, and the configuration will not be loaded.

So, about the autoloader :

  • if we require composer's autoloader inside atoum, we will be able to use an autoload file to configure the autorunner
  • if we don't require composer's autoloader, we will have to find another way to automatically load the configuration (like the way it's done for the moment in the PR). But like you said, this ties atoum with the editions.

What's your thought's about that ?
(and if we go for requiring composer's autoloader, what can we do to merge the PR #523 ?)

@agallou agallou force-pushed the edition_configuration branch 3 times, most recently from 2e3db4b to 437eac2 Compare June 19, 2016 13:04
@@ -652,6 +657,11 @@ public static function disableAutorun()
static::$autorunner = false;
}

public static function addAutorunnerConfigurationFile($file)
Copy link
Member

Choose a reason for hiding this comment

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

addConfigurationFile

}

if (1 != count($extensions)) {
throw new \Exception(sprintf("Extension '%s' Not found", $classname));
Copy link
Member

Choose a reason for hiding this comment

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

s/Not/not/

Copy link
Member

@jubianchi jubianchi Jun 19, 2016

Choose a reason for hiding this comment

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

@agallou use a more specific exception, invalidArgument for example ;)

public function getExtension($classname)
{
$extensions = array();
foreach ($this->getExtensions() as $extension) {
Copy link
Member

Choose a reason for hiding this comment

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

{ should be on its on line ;)


if (1 != count($extensions))
{
throw new \InvalidArgumentException(sprintf("Extension '%s' not found", $classname));
Copy link
Member

Choose a reason for hiding this comment

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

please, can you throw the mageekguy\atoum\exceptions\logic\invalidArgument

@agallou agallou force-pushed the edition_configuration branch 2 times, most recently from d311585 to 0ee9f32 Compare June 19, 2016 16:32
@jubianchi jubianchi changed the title add a way to define configuration in atoum/*-edition packages Add a way to define configuration in atoum/*-edition packages Jun 22, 2016
$extensions[] = $extension;
}

if (1 != count($extensions))
Copy link
Member

Choose a reason for hiding this comment

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

I think we should improve the addExtension method and move this check there: atoum should refuse to load an extension twice.

The addExtension already checks for an already existing extension instance but it should also check if an extension of the same class is already loaded.

Doing this, we could make the code in getExtension simpler: return early in the foreach loop and throw if we exit the loop without any matching extension.

@jubianchi
Copy link
Member

One last comment in the code.

Would you mind adding the removeExtension method in this PR ?

This simplifies the getExtension method
Could be called for example like this :
```
$runner->removeExtensionByClassName(mageekguy\atoum\visibility\extension::class);
```
@agallou
Copy link
Member Author

agallou commented Jun 25, 2016

@jubianchi PR updated :

  • the extension storage now only supports one extension of the same class (if another extension with the same class is passed, it will be ignore just like if we put the same object right now)
  • the getExtension is indeed now simpler
  • the removeExtension already exists a method to remove it from it's class name has been added (but wil the same limitations has the existing method : the asserters will be removed but not the arguments)

@jubianchi jubianchi modified the milestone: 2.9.0 Jul 11, 2016
jubianchi added a commit to jubianchi/atoum that referenced this pull request Sep 26, 2016
This is a partial port of what @agallou did in atoum#604: extensions
are indexed by class name.

* We can load an extension the way we already did:

```php
<?php

$extension = new mageekguy\atoum\blackfire\extension($script);
$extension
    ->setClientConfiguration(new \Blackfire\ClientConfiguration(
        $_ENV['BLACKFIRE_CLIENT_ID'],
        $_ENV['BLACKFIRE_CLIENT_TOKEN']
    ))
    ->addToRunner($runner)
;
```

* If we later try to re-register the same extension, only its
  configuration will be updated:

```php
<?php

$extension = new mageekguy\atoum\blackfire\extension($script);
$extension
    ->setClientConfiguration(new \Blackfire\ClientConfiguration(
        'foo',
        'bar'
    ))
    ->addToRunner($runner)
;
```

* We can also unload an extension, either using an instance or its
  class name:

```php
$extension = new mageekguy\atoum\blackfire\extension($script);
$extension->addToRunner($runner);

$runner->removeExtension($extension);
$runner->removeExtension(new mageekguy\atoum\blackfire\extension());
$runner->removeExtension(mageekguy\atoum\blackfire\extension::class);
```
@jubianchi
Copy link
Member

I'm closing this one in favor of #634 and #635.

Thanks for your work @agallou!

@jubianchi jubianchi closed this Sep 26, 2016
jubianchi added a commit to jubianchi/atoum that referenced this pull request Sep 27, 2016
This is a partial port of what @agallou did in atoum#604: extensions
are indexed by class name.

* We can load an extension the way we already did:

```php
<?php

$extension = new mageekguy\atoum\blackfire\extension($script);
$extension
    ->setClientConfiguration(new \Blackfire\ClientConfiguration(
        $_ENV['BLACKFIRE_CLIENT_ID'],
        $_ENV['BLACKFIRE_CLIENT_TOKEN']
    ))
    ->addToRunner($runner)
;
```

* If we later try to re-register the same extension, only its
  configuration will be updated:

```php
<?php

$extension = new mageekguy\atoum\blackfire\extension($script);
$extension
    ->setClientConfiguration(new \Blackfire\ClientConfiguration(
        'foo',
        'bar'
    ))
    ->addToRunner($runner)
;
```

* We can also unload an extension, either using an instance or its
  class name:

```php
$extension = new mageekguy\atoum\blackfire\extension($script);
$extension->addToRunner($runner);

$runner->removeExtension($extension);
$runner->removeExtension(new mageekguy\atoum\blackfire\extension());
$runner->removeExtension(mageekguy\atoum\blackfire\extension::class);
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants