I found myself in the need to create a Laravel package. Even when I'm familiar with the stack I never had to do this. Well there is always a first time for everything, right?
My first step was to research how to do such a thing, fortunately Laravel has very good documentation for this. So after reading the basics I needed to set up the development environment.
Composer
I alway start my journey of creating a new php repository initializing Composer running composer init
. After running the wizard it will generate something like:
{
"name": "adro/package",
"description": "An awesome package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Adro Rocker",
"email": "[email protected]"
}
],
"require": {}
}
After that you need to choose the right namespace for your package. An example would be:
"autoload": {
"psr-4": {
"Adro\\MyAwesomePackage\\": "src/"
}
}
Now you are good to start coding following the Laravel documentation.
Testing code
Wait, but how do I know my code is working? Right! for that we need to set up the test suite. In my use case I chose this tools:
- testbench, A Laravel Testing Helper for Packages Development.
- canvas, Code Generators for Laravel Applications and Packages.
- PHP_CodeSniffer, tokenizes PHP files and detects violations of a defined set of coding standards.
Testbench extends PHPUnit to help you test Laravel packages, so it was one of the most obvious dev dependencies to add. Since I wanted to integrate some artisan make:*
commands to scaffold some stuff in my package I used Canvas. According to the documentation Canvas replicates all of the make
artisan commands available in your basic Laravel application. And since I have suffer in the past reading really bad indented code I always like to set code standards, for that I use PHP_CodeSniffer.
Setting up PHPUnit/Testbench
PHPUnit by default looks for a config file, normally called phpunit.xml[.dist]
. This is how mine looks:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<php>
<env name="APP_ENV" value="testing"/>
</php>
<testsuites>
<testsuite name="Adro\\MyAwesomePackage\\Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
The <php><env name="APP_ENV" value="testing"/></php>
section is used to load environmental variables, in this case is loading the APP_ENV
with the value testing
Setting up PHP_CodeSniffer
<?xml version="1.0"?>
<ruleset name="Adro coding standard">
<description>Adro coding standard</description>
<!-- display progress -->
<arg value="p"/>
<arg name="colors"/>
<!-- inherit rules from: -->
<rule ref="PSR12"/>
<rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
<properties>
<property name="ignoreBlankLines" value="false"/>
</properties>
</rule>
<!-- Paths to check -->
<file>src</file>
</ruleset>
For more on how to configure CS you can read the wiki
Seeing code in action locally?
You can require a local package in a local Laravel project by defining a custom "repository" in the composer.json
file.
Add the following repositories
key section in composer.json
file of your Laravel app. Update the "url" with the directory where your package lives:
{
"repositories": [
{
"type": "path",
"url": "../path/to/my/packages/my-awesome-package"
}
]
}
You can now require your local package in the Laravel application using your chosen namespace of the package. In our example, this would be:
composer require adro/package