Package development #phpday

Package development #phpday

Registering your new awesome package to packagist is easy. But what about maintainability? What dependencies should you avoid? Have you considered reducing download size? How will you keep your users up to date with changes in newer versions? How do you best handle releases? How do you manage your package to behave in an optimal way both in other people's production environment as in your local package development environment?

These and many other tips for medium to high quality packages are included in this talk.

39eb3f3d313b13f05534e496285040b8?s=128

Hannes Van De Vreken

May 17, 2016
Tweet

Transcript

  1. Package development PHPDay, Verona ! @hannesvdvreken @phpday

  2. Hi, my name is Hannes.

  3. "

  4. None
  5. madewithlove.be

  6. None
  7. Package development Intermediate and advanced techniques

  8. 1. Beginner steps 2. Intermediate tips 3. Package stability

  9. 1. Beginner steps Everyone started out as a newbie.

  10. None
  11. BEGINNER STEPS phppackagechecklist.com

  12. None
  13. None
  14. None
  15. BEGINNER STEPS No renaming keep the old one, but create

    a new
  16. None
  17. None
  18. https:/ /seld.be/notes/common-files-in-php-packages

  19. None
  20. None
  21. BEGINNER STEPS Instructions to install composer require guzzlehttp/guzzle

  22. BEGINNER STEPS Instructions to install not: “add guzzlehttp/guzzle to your

    composer.json”
  23. None
  24. None
  25. BEGINNER STEPS - VERSIONS Class Sdk { public function __construct(Framework\Config)

    { … } } /** * Register method. */ public function register() { // Register SDK class. $this->container->share('twilio', function () { return new Sdk($this->container->make('config')) }); }
  26. BEGINNER STEPS - VERSIONS Class Sdk { public function __construct(array

    $options) { … } } /** * Register method. */ public function register() { // Register SDK class. $this->container->share('twilio', function () { $config = $this->app->get('config'); return new Sdk($config->get('services.twilio')); }); }
  27. None
  28. BEGINNER STEPS - CODE STYLE Recommendations: PSR-2

  29. BEGINNER STEPS - CODE STYLE Use of tooling phpcs, php-cs-fixer

  30. BEGINNER STEPS - CODE STYLE Do it early boy-scouting file-per-file

    git blame open pull requests
  31. None
  32. BEGINNER STEPS - TESTS/SPECS Not just the happy path

  33. BEGINNER STEPS - TESTS/SPECS It’s your insurance in multiple ways

  34. None
  35. None
  36. BEGINNER STEPS - VERSIONING semver.org read it

  37. BEGINNER STEPS - VERSIONING Release often

  38. None
  39. BEGINNER STEPS - CHANGELOG Document releases keepachangelog.com

  40. BEGINNER STEPS - CHANGELOG Release often

  41. BEGINNER STEPS - CHANGELOG # Change Log All notable changes

    to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased][unreleased] ### Changed - Improve argument against commit logs. ## [0.0.8] - 2015-02-17 ### Changed - Update year to match in every README example. - Reluctantly stop making fun of Brits only, since most of the world writes dates in a strange way. ### Fixed - Fix typos in recent README changes. - Update outdated unreleased diff link.
  42. BEGINNER STEPS - CHANGELOG keepachangelog.com

  43. None
  44. None
  45. BEGINNER STEPS - CHANGELOG upgrade.md

  46. None
  47. None
  48. BEGINNER STEPS GitHub PC test service packagist

  49. BEGINNER STEPS GitHub PC test service packagist git push

  50. BEGINNER STEPS GitHub PC test service packagist webhook webhook

  51. BEGINNER STEPS GitHub PC test service packagist analyses composer.json /stores

    version runs tests
  52. BEGINNER STEPS GitHub PC test service packagist status green!

  53. None
  54. BEGINNER STEPS - README.MD Code samples copy-paste

  55. BEGINNER STEPS - README.MD // open an image file $img

    = Image::make('public/foo.jpg'); // resize image instance $img->resize(320, 240); // insert a watermark $img->insert('public/watermark.png'); // save image in desired format $img->save('public/bar.jpg');
  56. None
  57. BEGINNER STEPS No license is the worst http:/ /choosealicense.com/

  58. None
  59. BEGINNER STEPS - CONTRIBUTING Instructions how to test how to

    make pull request philosophy
  60. BEGINNER STEPS Congrats, you’re no longer a newbie!

  61. BEGINNER STEPS - HINT 1 jonathantorres/construct

  62. BEGINNER STEPS - HINT 1 $ construct generate --help Arguments:

    name The vendor/project name Options: --test (-t) Testing framework (default: "phpunit") --license (-l) License (default: "MIT") --namespace (-s) Namespace for project (default: "Vendor\\Pro --git (-g) Initialize an empty Git repo --phpcs (-p) Generate a PHP Coding Standards Fixer config --keywords (-k) Comma separated list of Composer keywords --vagrant Generate a Vagrantfile
  63. BEGINNER STEPS - HINT 1 Or use a skeleton package

  64. BEGINNER STEPS - HINT 2 franzl/studio

  65. BEGINNER STEPS - HINT 2 $ studio load --help Usage:

    load <path> Arguments: path The path where the package files are located
  66. 2. Intermediate tips

  67. INTERMEDIATE TIPS - ENVIRONMENTS Packages have environments too

  68. INTERMEDIATE TIPS - ENVIRONMENTS dev/local test/ci production

  69. INTERMEDIATE TIPS - ENVIRONMENTS - DEV & CI not in

    production: composer require --dev also installs require-dev dependencies
  70. INTERMEDIATE TIPS - ENVIRONMENTS - CI CI only: code coverage

  71. INTERMEDIATE TIPS - ENVIRONMENTS - CI phpunit --coverage-html=/tmp/coverage/; vs phpunit

    --coverage-clover=/tmp/coverage.xml; ocular code-coverage:upload /tmp/coverage.xml;
  72. INTERMEDIATE TIPS - ENVIRONMENTS - PROD Keep your tests out

    of other people’s production
  73. INTERMEDIATE TIPS - CLEAN DISTS --prefer-dist

  74. INTERMEDIATE TIPS - CLEAN DISTS .gitattributes

  75. None
  76. INTERMEDIATE TIPS - CLEAN DISTS "autoload": { "psr-4": { "GuzzleHttp\\":

    "src/" } }, "autoload-dev": { "psr-4": { "GuzzleHttp\\Stubs\\": "tests/stubs/" } }
  77. INTERMEDIATE TIPS Composer scripts stop typing vendor/bin/

  78. INTERMEDIATE TIPS - COMPOSER SCRIPTS "scripts": { "cs": "php-cs-fixer fix"

    } $ composer cs
  79. INTERMEDIATE TIPS - COMPOSER SCRIPTS "scripts": { "test": ["phpunit", "phpspec

    run"] }
  80. INTERMEDIATE TIPS - COMPOSER BINS #!/usr/bin/env php <?php

  81. INTERMEDIATE TIPS - COMPOSER BINS "bin": ["construct"]

  82. INTERMEDIATE TIPS - COMPOSER BINS composer require --global not in

    CI
  83. INTERMEDIATE TIPS Code Style

  84. INTERMEDIATE TIPS - CODE STYLE Atomic commits easier to review

    w/o code style fixes
  85. INTERMEDIATE TIPS - CODE STYLE Recommendations: PSR-2 < Symfony CS

  86. None
  87. if (5 === count($list)) { Yoda conditions

  88. INTERMEDIATE TIPS - CODE STYLE $container = new Container; $container

    = new Container(); $options = [ 'ssl' => true, 'redirects' => false, ];
  89. None
  90. None
  91. INTERMEDIATE TIPS - RECAP - separate environments - composer scripts

    - code style
  92. Semver checker ^ vs ~ Marketing Communication (empathy) composer --sort-packages

  93. 3. Package stability

  94. STABILITY As package maintainer: Less major releases

  95. STABILITY If a dependency has new major version, your package

    needs new major version.
  96. Keep number of hard requirements low STABILITY

  97. STABILITY - SOFT-REQUIREMENTS Soft requirements eg: use decorators

  98. use Psr\Cache\CacheItemPool; class CacheDecorator implements … { … } STABILITY

    - SOFT-REQUIREMENTS
  99. { "name": "league/flysystem-eventable-filesystem", "require": { "php": ">=5.4.0", "league/event": "~1.0", "league/flysystem":

    "~1.0" }, … STABILITY - SOFT-REQUIREMENTS
  100. Depend on interface packages STABILITY - DECOUPLING

  101. STABILITY - SOFT-REQUIREMENTS Soft requirements eg: use decorators

  102. concept virtual package is a high level placeholder for a

    dependency on a more low level implementation STABILITY - DECOUPLING
  103. company/sdk requires (1.0.0) psr/cache-implementation requires (1.0.0) psr/cache

  104. psr/cache-implementation provides (1.0.0) requires (1.0.0) doctrine/cache requires (^1.3) doctrine/cache psr/cache

  105. company/sdk application requires (x.y.z) requires (1.0.0) psr/cache-implementation

  106. company/sdk requires (1.0.0) psr/cache-implementation provides (1.0.0) requires (1.0.0) application requires

    (x.y.z) requires (0.5.0) requires (1.0.0) cache/doctrine-adapter psr/cache requires (^1.3) doctrine/cache
  107. STABILITY - DECOUPLING - BENEFITS Users can choose low level

    packages they want
  108. STABILITY - DECOUPLING - BENEFITS Users don’t get locked-in to

    a major version
  109. Prefer having less hard dependencies STABILITY - RECAP

  110. Prefer requiring stabler packages STABILITY - RECAP

  111. STABILITY - RECAP Prefer requiring virtual packages

  112. STABILITY - BENEFITS As package maintainer: Less major releases

  113. DECOUPLING - OTHER CASES - File system (Flysystem) - Logging

    (PSR-3) - HTTP (PSR-7) - Caching (PSR-6)
  114. None
  115. RECAP 1. Beginner steps 2. Intermediate tips 3. Decouple for

    stability
  116. Thank you! @hannesvdvreken @phpday https:/ /joind.in/talk/e48d2

  117. Time for questions. @hannesvdvreken @phpday

  118. • http:/ /mwl.be REFERENCES