Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Composer: Stability and Semantic Versioning Demystified (Madison PHP)

Beau Simensen
November 16, 2013

Composer: Stability and Semantic Versioning Demystified (Madison PHP)

Understanding stability and semantic versioning makes a huge impact on daily life with Composer. Learn how to decode Composer's solver errors, get a better understanding of semantic versioning, how dependencies interact with each other when it comes to stability, and how to use Composer features like branch aliases to make things run more smoothly.

Beau Simensen

November 16, 2013
Tweet

More Decks by Beau Simensen

Other Decks in Programming

Transcript

  1. Composer: Stability and
    Semantic Versioning Demystified
    Madison PHP
    November 16th, 2013

    View Slide

  2. @beausimensen
    simensen on Freenode
    #composer
    #madisonphp

    View Slide

  3. View Slide

  4. Dependency Manager
    for PHP

    View Slide

  5. https://packagist.org

    View Slide

  6. Over 19,000 Packages

    View Slide

  7. composer.json

    View Slide

  8. {
    “name”: “acme/my-project”,
    “description”: “Acme’s My Project”,
    “license”: “MIT”,
    “require”: {
    “silex/silex”: “1.1.*”
    },
    “autoload”: {
    “psr-0”: {
    “Acme\\MyProject\\”: “src”
    }
    }
    }

    View Slide

  9. {
    “name”: “acme/my-project”,
    “description”: “Acme’s My Project”,
    “license”: “MIT”,
    “require”: {
    “silex/silex”: “1.1.*”
    },
    “autoload”: {
    “psr-0”: {
    “Acme\\MyProject\\”: “src”
    }
    }
    }

    View Slide

  10. {
    “name”: “acme/my-project”,
    “description”: “Acme’s My Project”,
    “license”: “MIT”,
    “require”: {
    “silex/silex”: “1.1.*”
    },
    “autoload”: {
    “psr-0”: {
    “Acme\\MyProject\\”: “src”
    }
    }
    }

    View Slide

  11. {
    “name”: “acme/my-project”,
    “description”: “Acme’s My Project”,
    “license”: “MIT”,
    “require”: {
    “silex/silex”: “1.1.*”
    },
    “autoload”: {
    “psr-0”: {
    “Acme\\MyProject\\”: “src”
    }
    }
    }

    View Slide

  12. $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev)
    - Installing psr/log (1.0.0)
    - Installing symfony/routing (v2.3.7)
    - Installing symfony/debug (v2.3.7)
    - Installing symfony/http-foundation (v2.3.7)
    - Installing symfony/event-dispatcher (v2.3.7)
    - Installing symfony/http-kernel (v2.3.7)
    - Installing pimple/pimple (v1.1.0)
    - Installing silex/silex (v1.1.2)
    Writing lock file
    Generating autoload files
    $

    View Slide

  13. Semantic Versioning
    http://semver.org/

    View Slide

  14. MAJOR.MINOR.PATCH

    View Slide

  15. MAJOR.MINOR.PATCH
    Which number do you increment and why?

    View Slide

  16. MAJOR.MINOR.PATCH
    When you make API incompatible changes

    View Slide

  17. MAJOR.MINOR.PATCH
    When you add backwards-compatible functionality

    View Slide

  18. MAJOR.MINOR.PATCH
    When you make backwards-compatible bug fixes

    View Slide

  19. Pre-Release Identifiers
    (Composer “Stability”)
    •1.0.0-alpha
    •1.0.0-beta.1
    •1.0.0-RC2
    •1.0.0 (stable)

    View Slide

  20. Version Constraints

    View Slide

  21. Exact Versions
    1.0.2

    View Slide

  22. Ranges
    >=1.0,<2.0

    View Slide

  23. Wildcards
    1.0.*

    View Slide

  24. Next Significant Release
    Tilde Operator

    View Slide

  25. Next Significant Release
    ~1.2
    >=1.2,<2.0

    View Slide

  26. Next Significant Release
    ~1.2.3
    >=1.2.3,<1.3

    View Slide

  27. Let’s You Know What
    You Are Getting Into

    View Slide

  28. Safe
    1.3.*
    Only get bug fixes.

    View Slide

  29. Reasonably Safe
    1.*
    Get bug fixes and new features.

    View Slide

  30. Crazy Sauce
    *
    Composer allows this, but don’t. Just don’t.

    View Slide

  31. Other Version Schemes
    Can Be Used
    But don’t expect Composer to read your mind and do
    anything smart with them.

    View Slide

  32. Version Constraint
    Considerations

    View Slide

  33. If the dependency specifications are too tight,
    you are in danger of version lock (the inability to
    upgrade a package without having to release new
    versions of every dependent package).
    — Semantic Versioning
    http://semver.org/

    View Slide

  34. If dependencies are specified too loosely, you will
    inevitably be bitten by version promiscuity
    (assuming compatibility with more future
    versions than is reasonable).
    — Semantic Versioning
    http://semver.org/

    View Slide

  35. Deep Dependency
    Resolution

    View Slide

  36. {
    “name”: “silex/silex”,
    “require”: {
    “pimple/pimple”: “1.*”
    }
    }

    View Slide

  37. {
    “name”: “silex/silex”,
    “require”: {
    “pimple/pimple”: “1.*”
    }
    }
    {
    “name”: “dflydev/doctrine-orm-service-provider”,
    “require”: {
    “pimple/pimple”: “1.*”,
    “doctrine/orm”: “~2.3”
    }
    }

    View Slide

  38. {
    “require”: {
    “dflydev/doctrine-orm-service-provider”: “1.0.*”,
    “silex/silex”: “1.1.*”,
    “pimple/pimple”: “1.0.*”,
    “doctrine/orm”: “2.4.*”
    }
    }
    {
    “name”: “silex/silex”,
    “require”: {
    “pimple/pimple”: “1.*”
    }
    }
    {
    “name”: “dflydev/doctrine-orm-service-provider”,
    “require”: {
    “pimple/pimple”: “1.*”,
    “doctrine/orm”: “~2.3”
    }
    }

    View Slide

  39. Conflicts

    View Slide

  40. {
    "require": {
    "silex/silex": "1.1.*",
    "pimple/pimple": "2.0.*@dev"
    }
    }

    View Slide

  41. $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    Problem 1
    - silex/silex v1.1.0 requires pimple/pimple 1.*
    -> satisfiable by pimple/pimple[1.0.0, 1.1.x-dev, v1.0.1, v1.0.2, v1.1.0].
    - silex/silex v1.1.1 requires pimple/pimple 1.*
    -> satisfiable by pimple/pimple[1.0.0, 1.1.x-dev, v1.0.1, v1.0.2, v1.1.0].
    - silex/silex v1.1.2 requires pimple/pimple ~1.0
    -> satisfiable by pimple/pimple[1.0.0, 1.1.x-dev, v1.0.1, v1.0.2, v1.1.0].
    - Can only install one of: pimple/pimple[2.0.x-dev, 1.0.0].
    - Can only install one of: pimple/pimple[2.0.x-dev, 1.1.x-dev].
    - Can only install one of: pimple/pimple[v1.0.1, 2.0.x-dev].
    - Can only install one of: pimple/pimple[v1.0.2, 2.0.x-dev].
    - Can only install one of: pimple/pimple[v1.1.0, 2.0.x-dev].
    - Installation request for pimple/pimple 2.0.*@dev
    -> satisfiable by pimple/pimple[2.0.x-dev].
    - Installation request for silex/silex 1.1.*
    -> satisfiable by silex/silex[v1.1.0, v1.1.1, v1.1.2].
    Potential causes:
    - A typo in the package name
    - The package is not available in a stable-enough version according to your
    minimum-stability setting.

    View Slide

  42. Where Do Versions
    Come From?

    View Slide

  43. Tags and Branches
    git, mercurial, subversion

    View Slide

  44. Tags

    View Slide

  45. Tags
    If it can be parsed for semantic versioning, awesome.

    View Slide

  46. Tags
    If it cannot be parsed for semantic versioning, it is
    treated as if it were an “exact” version.

    View Slide

  47. v2.0.1
    2.0.1
    (2.0.*)

    View Slide

  48. 2.0.1
    2.0.1
    (2.0.*)

    View Slide

  49. 2.0.1-RC1
    2.0.1-RC1
    (2.0.*@RC)

    View Slide

  50. 2.0.1g
    2.0.1g
    (2.0.1g)

    View Slide

  51. Branches

    View Slide

  52. Branches
    Composer automatically detects numbered branches as
    development versions.
    Branch named 2.0 is treated as 2.0.x-dev

    View Slide

  53. Branches
    Composer can alias a named branch to a specific
    development version.
    Branch named master is treated as 2.0.*@dev

    View Slide

  54. master
    dev-master

    View Slide

  55. testing
    dev-testing

    View Slide

  56. 2.0
    2.0.x-dev
    (2.0.*@dev)

    View Slide

  57. 2.0-experimental
    dev-2.0-experimental
    (2.0.*@dev won’t work!)

    View Slide

  58. Branch Aliases

    View Slide

  59. {
    “extra”: {
    “branch-alias”: {
    “dev-master”: “2.0.x-dev”
    }
    }
    }

    View Slide

  60. When starting a new library that is to be
    distributed via Packagist / Composer, be SURE to
    set up your dev-master branch alias.
    — Don Gilbert
    https://twitter.com/dilbert4life/status/380137097614458881

    View Slide

  61. How Do You Target
    Branches and Non-
    Stable Versions?

    View Slide

  62. {
    “require”: {
    “symfony/yaml”: “3.5-cat”,
    “silex/silex”: “1.1@dev”,
    “pimple/pimple”: “dev-master”
    }
    }

    View Slide

  63. Stability

    View Slide

  64. Stability
    Minimum stability controlled by the root package.
    (Minimum stability defaults to “stable”)

    View Slide

  65. Stability
    {
    “minimum-stability”: “alpha”
    }

    View Slide

  66. Stability
    Stability can be controlled on a package-by-package
    basis by the root package.

    View Slide

  67. Stability
    {
    “require”: {
    “silex/silex”: “~1.1@dev”,
    “symfony/http-foundation”: “@beta”
    },
    “minimum-stability”: “alpha”
    }

    View Slide

  68. Stability
    Composer solver errors are fun.

    View Slide

  69. {
    "require": {
    "pimple/pimple": "2.0.*"
    }
    }
    Stability

    View Slide

  70. $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    Problem 1
    - The requested package pimple/pimple 2.0.* could not be found.
    Potential causes:
    - A typo in the package name
    - The package is not available in a stable-enough version according to
    your minimum-stability setting
    Stability

    View Slide

  71. $ composer install
    Loading composer repositories with package information
    Installing dependencies (including require-dev)
    Your requirements could not be resolved to an installable set of packages.
    Problem 1
    - The requested package pimple/pimple 2.0.* could not be found.
    Potential causes:
    - A typo in the package name
    - The package is not available in a stable-enough version according to
    your minimum-stability setting
    Stability

    View Slide

  72. Stability
    Even if your package requires something @dev, users of
    your package won’t get it unless they explicitly ask for it.

    View Slide

  73. {
    “name”: “silex/silex”,
    “require”: {
    “pimple/pimple”: “1.*@dev”
    }
    }
    R

    View Slide

  74. R
    {
    “name”: “silex/silex”,
    “require”: {
    “pimple/pimple”: “1.*@dev”
    }
    }
    {
    “name”: “dflydev/doctrine-orm-service-provider”,
    “require”: {
    “pimple/pimple”: “1.*@beta”,
    “silex/silex”: “1.1.*”,
    “doctrine/orm”: “~2.3”
    }
    }

    View Slide

  75. {
    “require”: {
    “dflydev/doctrine-orm-service-provider”: “1.0.*”,
    “pimple/pimple”: “1.0.*”
    }
    }
    {
    “name”: “silex/silex”,
    “require”: {
    “pimple/pimple”: “1.*@dev”
    }
    }
    {
    “name”: “dflydev/doctrine-orm-service-provider”,
    “require”: {
    “pimple/pimple”: “1.*@beta”,
    “silex/silex”: “1.1.*”,
    “doctrine/orm”: “~2.3”
    }
    }
    R

    View Slide

  76. Questions?
    https://joind.in/10064
    @beausimensen

    View Slide