SlideShare ist ein Scribd-Unternehmen logo
1 von 172
Downloaden Sie, um offline zu lesen
Composer
Game Changing Dependency Management
php[architect] DevOps Summit Series Jeremy Kendall
I love to code
I love to code
I’m terribly forgetful
I love to code
I’m terribly forgetful
I take pictures
I love to code
I’m terribly forgetful
I take pictures
I work at OpenSky
Adding Dependencies is Easy
Adding Dependencies is Easy
‣ Copy and Paste
Adding Dependencies is Easy
‣ Copy and Paste
‣ DIY Solution
Adding Dependencies is Easy
‣ Copy and Paste
‣ DIY Solution
‣ SVN Externals
Adding Dependencies is Easy
‣ Copy and Paste
‣ DIY Solution
‣ SVN Externals
‣ Git Submodules
Managing them is Messy
What is Composer?
What is Composer?
‣ Dependency management tool
What is Composer?
‣ Dependency management tool
‣ Per-project
What is Composer?
‣ Dependency management tool
‣ Per-project
‣ Inspired by:
What is Composer?
‣ Dependency management tool
‣ Per-project
‣ Inspired by:
‣ node’s npm
What is Composer?
‣ Dependency management tool
‣ Per-project
‣ Inspired by:
‣ node’s npm
‣ ruby’s bundler
Benefits
Benefits
‣ Easily declare project dependencies
Benefits
‣ Easily declare project dependencies
‣ Updating dependency versions extremely simple
Benefits
‣ Easily declare project dependencies
‣ Updating dependency versions extremely simple
‣ Ensures your team is on the same page
Benefits
‣ Easily declare project dependencies
‣ Updating dependency versions extremely simple
‣ Ensures your team is on the same page
‣ Tons of excellent related features
Installing
Installing Locally
$ curl -sS https://getcomposer.org/installer | phpIn your project:
Installing Locally
$ curl -sS https://getcomposer.org/installer | phpIn your project:
$ curl -sS https://getcomposer.org/installer | php -- --install-dir=binSpecify a directory:
Installing Locally
$ curl -sS https://getcomposer.org/installer | phpIn your project:
$ curl -sS https://getcomposer.org/installer | php -- --install-dir=binSpecify a directory:
$ curl -sS https://getcomposer.org/installer | php
#!/usr/bin/env php
All settings correct for using Composer
Downloading...
Composer successfully installed to: /Users/jkendall/dev/
composer.phar
Use it: php composer.phar
What you’ll see:
Installing Globally
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
Recommended
Installing Globally
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/local/bin/composer
(You might need to use sudo)
Recommended
(There’s an installer for
Windows folks)
Keeping up to Date
$ composer self-update
You are using the latest composer version.
$ php composer.phar self-update
You are using the latest composer version.
or
Keeping up to Date
$ composer self-update
You are using the latest composer version.
(Always updates to the latest dev-master)
$ php composer.phar self-update
You are using the latest composer version.
or
Defining Dependencies
composer.json
{
"require": {
"monolog/monolog": "1.5.*"
}
}
composer.json
{
"require": {
"monolog/monolog": "1.5.*"
}
}
‣Place in the root of your project
composer.json
{
"require": {
"monolog/monolog": "1.5.*"
}
}
‣Place in the root of your project
‣“require” specifies package and version
composer.json
{
"require": {
"monolog/monolog": "1.5.*"
}
}
‣Place in the root of your project
‣“require” specifies package and version
‣monolog logging library
composer.json
{
"require": {
"monolog/monolog": "1.5.*"
}
}
‣Place in the root of your project
‣“require” specifies package and version
‣monolog logging library
‣Version >= 1.5.0 and < 1.6
composer.json
{
"require": {
"monolog/monolog": "1.5.*"
}
}
‣Place in the root of your project
‣“require” specifies package and version
‣monolog logging library
‣Version >= 1.5.0 and < 1.6
‣No fuss, no muss
Versions
‣ Exact version: 1.0.0, 12.2.4, etc.
Versions
‣ Exact version: 1.0.0, 12.2.4, etc.
‣ Wildcard: 3.*, 4.2.*
Versions
‣ Exact version: 1.0.0, 12.2.4, etc.
‣ Wildcard: 3.*, 4.2.*
‣ Range: >, >=, <=, !=
Versions
‣ Exact version: 1.0.0, 12.2.4, etc.
‣ Wildcard: 3.*, 4.2.*
‣ Range: >, >=, <=, !=
‣ Example: >=2.4
Versions
‣ Exact version: 1.0.0, 12.2.4, etc.
‣ Wildcard: 3.*, 4.2.*
‣ Range: >, >=, <=, !=
‣ Example: >=2.4
‣ Range: >=1.0,<1.7 (comma separated)
Versions
‣ Exact version: 1.0.0, 12.2.4, etc.
‣ Wildcard: 3.*, 4.2.*
‣ Range: >, >=, <=, !=
‣ Example: >=2.4
‣ Range: >=1.0,<1.7 (comma separated)
‣ Next Significant Release: ~1.3.3
Versions
Installing Dependencies
$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
- Installing psr/log (1.0.0)
Loading from cache
- Installing monolog/monolog (1.5.0)
Loading from cache
monolog/monolog suggests installing mlehner/gelf-php (Allow sending log messages to a GrayLog2 server)
monolog/monolog suggests installing raven/raven (Allow sending log messages to a Sentry server)
monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required))
Writing lock file
Generating autoload files
composer install
composer.lock
composer.lock
‣ install writes a dependency lock file
composer.lock
‣ install writes a dependency lock file
‣ List of exact versions installed
composer.lock
‣ install writes a dependency lock file
‣ List of exact versions installed
‣ Commit both composer.lock and composer.json
composer.lock
‣ install writes a dependency lock file
‣ List of exact versions installed
‣ Commit both composer.lock and composer.json
‣ composer install now checks the lock file, not
composer.json
composer.lock
‣ install writes a dependency lock file
‣ List of exact versions installed
‣ Commit both composer.lock and composer.json
‣ composer install now checks the lock file, not
composer.json
‣ Update dependencies with composer update
Updating Dependencies
Updating Dependencies
{
"require": {
"monolog/monolog": "1.6.*@dev"
}
}
Updating Dependencies
{
"require": {
"monolog/monolog": "1.6.*@dev"
}
}
‣Updates monolog library version
Updating Dependencies
{
"require": {
"monolog/monolog": "1.6.*@dev"
}
}
‣Updates monolog library version
‣Version >= 1.6.0 and < 1.7 (dev)
Updating Dependencies
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing monolog/monolog (1.5.0)
- Installing monolog/monolog (dev-master c933bb6)
Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock file
Generating autoload files
composer update
Updating Dependencies
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing monolog/monolog (1.5.0)
- Installing monolog/monolog (dev-master c933bb6)
Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock file
Generating autoload files
‣Reads from composer.json
composer update
Updating Dependencies
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing monolog/monolog (1.5.0)
- Installing monolog/monolog (dev-master c933bb6)
Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock file
Generating autoload files
‣Reads from composer.json
‣Updates dependencies
composer update
Updating Dependencies
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Removing monolog/monolog (1.5.0)
- Installing monolog/monolog (dev-master c933bb6)
Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock file
Generating autoload files
‣Reads from composer.json
‣Updates dependencies
‣Rewrites lock file
composer update
Adding New Dependencies
Edit composer.json . . .
{
"require": {
"monolog/monolog": "1.6.*@dev",
"ircmaxell/password-compat": "1.0.3"
}
}
Adding New Dependencies
Or use the command line
$ composer require ircmaxell/password-compat:1.0.3
composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing ircmaxell/password-compat (1.0.3)
Downloading: 100%
Writing lock file
Generating autoload files
composer require
Autoloading
Autoloading
‣ Composer generates vendor/autoload.php
Autoloading
‣ Composer generates vendor/autoload.php
‣ Add require ‘vendor/autoload.php’;
Autoloading
‣ Composer generates vendor/autoload.php
‣ Add require ‘vendor/autoload.php’;
‣ Immediately begin using your dependencies
Autoloading
{
"require": {
"monolog/monolog": "1.6.*@dev"
},
"autoload": {
"psr-0": {
"Beeblebrox": "src/"
}
}
}
Don’t forget to add your own code!
Autoloading
$loader = require 'vendor/autoload.php';
$loader->add('AcmeTest', __DIR__);
Pro Tip
Grab an autoloader instance and
add more namespaces.
Kickstart a Project
$ composer create-project slim/slim-skeleton super-sweet-application
Installing slim/slim-skeleton (1.1.0)
- Installing slim/slim-skeleton (1.1.0)
Downloading: 100%
Created project in super-sweet-application
Loading composer repositories with package information
Installing dependencies (including require-dev)
- Installing slim/slim (2.3.0)
Downloading: 100%
- Installing slim/extras (2.0.3)
Loading from cache
- Installing twig/twig (v1.13.1)
Loading from cache
Writing lock file
Generating autoload files
composer create-project
YourVery Own Library
Libraries
Libraries
‣ Everyone has written a library of some sort
Libraries
‣ Everyone has written a library of some sort
‣ Making up examples is not my strong suit
Libraries
‣ Everyone has written a library of some sort
‣ Making up examples is not my strong suit
‣ Let’s walk through a real library . . .
Libraries
‣ Everyone has written a library of some sort
‣ Making up examples is not my strong suit
‣ Let’s walk through a real library . . .
‣ . . . and check out some awesome Composer features
PHP Domain Parser
https://github.com/jeremykendall/php-domain-parser
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
Package requirements
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
Package requirements
Autoloading
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
Add the “name” key
and it’s installable
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
Additional
metadata
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
Don’t forget the license!
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
Full fledged library!
Now for the cool(er)
stuff . . .
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
require-dev
require-dev
require-dev
‣ Lists packages required for development (think tests)
require-dev
‣ Lists packages required for development (think tests)
‣ Only applies to the root package
require-dev
‣ Lists packages required for development (think tests)
‣ Only applies to the root package
‣ Both install and update install require-dev by default
require-dev
‣ Lists packages required for development (think tests)
‣ Only applies to the root package
‣ Both install and update install require-dev by default
‣ (Use the --no-dev flag to skip installing dev
dependencies)
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
bin
bin
bin
‣ cli scripts to pass along to package users
bin
‣ cli scripts to pass along to package users
‣ A set of files that should be treated as binaries
bin
‣ cli scripts to pass along to package users
‣ A set of files that should be treated as binaries
‣ Installs binaries to vendor/bin for any project that
depends on your project
bin
‣ cli scripts to pass along to package users
‣ A set of files that should be treated as binaries
‣ Installs binaries to vendor/bin for any project that
depends on your project
‣ php-domain-parser uses a bin to update the local copy
of the public suffix list
{
"name": "jeremykendall/php-domain-parser",
"description": "Public Suffix List based URL parsing implemented in PHP.",
"license": "MIT",
"authors": [
{
"name": "Jeremy Kendall",
"homepage": "http://about.me/jeremykendall",
"role": "Developer"
}
],
"bin": ["bin/pdp-psl"],
"keywords": ["Public Suffix List", "domain parsing", "url parsing"],
"require": {
"php": ">=5.3.0",
"ext-curl": "*"
},
	 "require-dev": {
	 	 "mikey179/vfsStream": "1.1.*",
	 	 "jeremykendall/phpctagger": "0.0.*"
	 },
	 "autoload": {
	 	 "psr-0":
	 	 	 {
	 	 	 "Pdp": "library/"
	 	 }
	 },
	 "scripts": {
	 	 "post-install-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ],
	 	 "post-update-cmd": [
	 	 	 "PhpCtaggerComposerScriptCtagger::ctag"
	 	 ]
	 }
}
scripts
scripts
scripts
‣ Used to execute custom code during the Composer
execution process
scripts
‣ Used to execute custom code during the Composer
execution process
‣ PHP callback (defined as a static method) . . .
scripts
‣ Used to execute custom code during the Composer
execution process
‣ PHP callback (defined as a static method) . . .
‣ . . . or any command-line executable command
scripts
‣ Used to execute custom code during the Composer
execution process
‣ PHP callback (defined as a static method) . . .
‣ . . . or any command-line executable command
‣ Only scripts defined in the root composer.json are
executed
scripts
‣ Used to execute custom code during the Composer
execution process
‣ PHP callback (defined as a static method) . . .
‣ . . . or any command-line executable command
‣ Only scripts defined in the root composer.json are
executed
‣ If a script is defined in a dependency, you can use it in
your composer.json
scripts
scripts
‣ Composer fires “named events” during execution
scripts
‣ Composer fires “named events” during execution
‣ Named events include:
scripts
‣ Composer fires “named events” during execution
‣ Named events include:
‣ pre- and post-install-cmd
scripts
‣ Composer fires “named events” during execution
‣ Named events include:
‣ pre- and post-install-cmd
‣ pre- and post-update-cmd
scripts
‣ Composer fires “named events” during execution
‣ Named events include:
‣ pre- and post-install-cmd
‣ pre- and post-update-cmd
‣ post-root-package-install
scripts
‣ Composer fires “named events” during execution
‣ Named events include:
‣ pre- and post-install-cmd
‣ pre- and post-update-cmd
‣ post-root-package-install
‣ Many more . . .
Running scripts
Running scripts
Execute Composer (script will execute if the named
event is triggered) or . . .
Running scripts
Execute Composer (script will execute if the named
event is triggered) or . . .
Running scripts
Execute Composer (script will execute if the named
event is triggered) or . . .
composer run-script <named event>
Example
public static function create(Event $event)
{
$dir = dirname($event->getComposer()->getConfig()->get('vendor-dir'));
$io = $event->getIO();
$io->write('Reviewing your Flaming Archer environment . . .', true);
$configExists = file_exists($dir . '/config.php');
$configDistExists = file_exists($dir . '/config-dist.php');
if (!$configExists && $configDistExists) {
$io->write('Creating config.php by copying config-dist.php . . .', true);
copy($dir . '/config-dist.php', $dir . '/config.php');
$io->write("Done! Please edit config.php.", true);
} else {
$io->write('Found config.php.', true);
}
}
https://github.com/jeremykendall/flaming-archer/blob/develop/library/Fa/Composer/Script/Config.php
You’ve built your library.
Now what?
Push it to aVCS
Push it to aVCS
‣ git, svn, or hg all work equally well
Push it to aVCS
‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
Push it to aVCS
‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
‣ Package versions:
Push it to aVCS
‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
‣ Package versions:
‣ Tags are package versions (1.0.0, v2.5.4, etc)
Push it to aVCS
‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
‣ Package versions:
‣ Tags are package versions (1.0.0, v2.5.4, etc)
‣ Branches are dev versions (dev-{branchname},
{branchname}-dev)
Push it to aVCS
‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
‣ Package versions:
‣ Tags are package versions (1.0.0, v2.5.4, etc)
‣ Branches are dev versions (dev-{branchname},
{branchname}-dev)
‣ For this reason, I strongly recommend using semantic
versioning: http://semver.org
Share!
Packagist
Packagist
Packagist
‣ The main package repository for Composer
Packagist
‣ The main package repository for Composer
‣ (Aside: Search Packagist before “rolling your own”)
Packagist
‣ The main package repository for Composer
‣ (Aside: Search Packagist before “rolling your own”)
‣ Packages published there need no special settings in
composer.json to be installable (see “repositories” key)
Packagist
‣ The main package repository for Composer
‣ (Aside: Search Packagist before “rolling your own”)
‣ Packages published there need no special settings in
composer.json to be installable (see “repositories” key)
‣ Submitting is dead simple
Packagist
‣ The main package repository for Composer
‣ (Aside: Search Packagist before “rolling your own”)
‣ Packages published there need no special settings in
composer.json to be installable (see “repositories” key)
‣ Submitting is dead simple
‣ Create account, hit big green submit button
Packagist
Packagist: Package Search
Packagist: Keyword Search
Packagist: Package
But what about internal
proprietary packages?
Satis to the Rescue
Satis to the Rescue
‣ Static composer repository generator
Satis to the Rescue
‣ Static composer repository generator
‣ Lightweight, static file based version of Packagist
Satis to the Rescue
‣ Static composer repository generator
‣ Lightweight, static file based version of Packagist
‣ Simple to configure
Satis to the Rescue
‣ Static composer repository generator
‣ Lightweight, static file based version of Packagist
‣ Simple to configure
‣ Flexible
$ composer create-project composer/satis --stability=dev --keep-vcs
Installing composer/satis (dev-master 059588ef0fd0977964ad13637e02012519686202)
- Installing composer/satis (dev-master master)
Cloning master
Created project in /Users/jkendall/dev/satis
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json . . .
- Installing symfony/process (dev-master 75c8101)
Cloning 75c810176f8e069714cef8696d7ecc3aa86e8168
- [ . . . ]
- Installing twig/twig (v1.13.1)
Loading from cache
symfony/console suggests installing symfony/event-dispatcher ()
Generating autoload files
composer create-project composer/satis --stability=dev --keep-vcs
Satis config.json
{
"name": "Satis Demo",
"homepage": "http://satis.dev",
"repositories": [
{ "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" },
{ "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" }
],
"require": {
"jeremykendall/php-domain-parser": ">=0.0.5",
"jeremykendall/phpctagger": ">0.0.6"
},
"archive": {
"directory": "dist",
"format": "tar"
}
}
Satis config.json
{
"name": "Satis Demo",
"homepage": "http://satis.dev",
"repositories": [
{ "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" },
{ "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" }
],
"require": {
"jeremykendall/php-domain-parser": ">=0.0.5",
"jeremykendall/phpctagger": ">0.0.6"
},
"archive": {
"directory": "dist",
"format": "tar"
}
}
Satis config.json
{
"name": "Satis Demo",
"homepage": "http://satis.dev",
"repositories": [
{ "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" },
{ "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" }
],
"require": {
"jeremykendall/php-domain-parser": ">=0.0.5",
"jeremykendall/phpctagger": ">0.0.6"
},
"archive": {
"directory": "dist",
"format": "tar"
}
}
Satis config.json
{
"name": "Satis Demo",
"homepage": "http://satis.dev",
"repositories": [
{ "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" },
{ "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" }
],
"require": {
"jeremykendall/php-domain-parser": ">=0.0.5",
"jeremykendall/phpctagger": ">0.0.6"
},
"archive": {
"directory": "dist",
"format": "tar"
}
}
Satis config.json
{
"name": "Satis Demo",
"homepage": "http://satis.dev",
"repositories": [
{ "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" },
{ "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" }
],
"require": {
"jeremykendall/php-domain-parser": ">=0.0.5",
"jeremykendall/phpctagger": ">0.0.6"
},
"archive": {
"directory": "dist",
"format": "tar"
}
}
Build Repo
$ php bin/satis build config.json web/
composer.json
{
"repositories": [
{ "type": "composer", "url": "http://satis.dev" }
],
"require": {
"jeremykendall/php-domain-parser": "0.0.7"
}
}
composer.json
{
"repositories": [
{ "type": "composer", "url": "http://satis.dev" }
],
"require": {
"jeremykendall/php-domain-parser": "0.0.7"
}
}
composer.json
{
"repositories": [
{ "type": "composer", "url": "http://satis.dev" }
],
"require": {
"jeremykendall/php-domain-parser": "0.0.7"
}
}
Satis Demo Project
Satis Demo Project
‣ Want to goof around with Satis?
Satis Demo Project
‣ Want to goof around with Satis?
‣ See: https://github.com/jeremykendall/satis-demo
Satis Demo Project
‣ Want to goof around with Satis?
‣ See: https://github.com/jeremykendall/satis-demo
‣ Clone, follow instructions in README, and WIN
Satis Demo Project
‣ Want to goof around with Satis?
‣ See: https://github.com/jeremykendall/satis-demo
‣ Clone, follow instructions in README, and WIN
‣ Satis really is dead simple to set up
Parting Tips and Tricks
composer install --no-dev --prefer-dist --optimize-autoloader
“example/package”: “2.3.x-dev#5aec89a”
Non-Composer and PEAR packages can be installed
(see “repositories” key documentation)
http://getcomposer.org
#composer on irc.freenode.org
There’s So Much More!
Credits
Credits
‣ Thanks to php[architect] for having me
IMMA LET YOU FINISH,
BUT RAFAEL DOHMS
HAS THE BEST
COMPOSER TALK OF
ALL TIME.
Credits
Credits
‣ Thanks to Rafael Dohms, the Composer presenter
Credits
‣ Thanks to Rafael Dohms, the Composer presenter
‣ Thanks to php[architect] for having me
Credits
‣ Thanks to Rafael Dohms, the Composer presenter
‣ Thanks to php[architect] for having me
‣ Thanks to Jordi Boggiano, Nils Adermann, and the
community for an amazing project (and all the
documentation I cribbed from)
Credits
‣ Thanks to Rafael Dohms, the Composer presenter
‣ Thanks to php[architect] for having me
‣ Thanks to Jordi Boggiano, Nils Adermann, and the
community for an amazing project (and all the
documentation I cribbed from)
‣ Thanks to our sponsors for help making this happen
Credits
‣ Thanks to Rafael Dohms, the Composer presenter
‣ Thanks to php[architect] for having me
‣ Thanks to Jordi Boggiano, Nils Adermann, and the
community for an amazing project (and all the
documentation I cribbed from)
‣ Thanks to our sponsors for help making this happen
‣ Thanks to all of you for being here
Thanks!
jeremy@jeremykendall.net
http://about.me/jeremykendall
@jeremykendall
https://joind.in/8968

Weitere ähnliche Inhalte

Mehr von Jeremy Kendall

Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkJeremy Kendall
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
PHP 102: Out with the Bad, In with the Good
PHP 102: Out with the Bad, In with the GoodPHP 102: Out with the Bad, In with the Good
PHP 102: Out with the Bad, In with the GoodJeremy Kendall
 
Intro to #memtech PHP 2011-12-05
Intro to #memtech PHP   2011-12-05Intro to #memtech PHP   2011-12-05
Intro to #memtech PHP 2011-12-05Jeremy Kendall
 
TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25Jeremy Kendall
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormJeremy Kendall
 
Zero to ZF in 10 Minutes
Zero to ZF in 10 MinutesZero to ZF in 10 Minutes
Zero to ZF in 10 MinutesJeremy Kendall
 
Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief exampleJeremy Kendall
 
A Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormA Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormJeremy Kendall
 
Zero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutesZero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutesJeremy Kendall
 

Mehr von Jeremy Kendall (12)

Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Php 101: PDO
Php 101: PDOPhp 101: PDO
Php 101: PDO
 
PHP 102: Out with the Bad, In with the Good
PHP 102: Out with the Bad, In with the GoodPHP 102: Out with the Bad, In with the Good
PHP 102: Out with the Bad, In with the Good
 
Intro to #memtech PHP 2011-12-05
Intro to #memtech PHP   2011-12-05Intro to #memtech PHP   2011-12-05
Intro to #memtech PHP 2011-12-05
 
TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25TDD in PHP - Memphis PHP 2011-08-25
TDD in PHP - Memphis PHP 2011-08-25
 
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_FormZend_Form to the Rescue - A Brief Introduction to Zend_Form
Zend_Form to the Rescue - A Brief Introduction to Zend_Form
 
Zero to ZF in 10 Minutes
Zero to ZF in 10 MinutesZero to ZF in 10 Minutes
Zero to ZF in 10 Minutes
 
Tdd in php a brief example
Tdd in php   a brief exampleTdd in php   a brief example
Tdd in php a brief example
 
A Brief Introduction to Zend_Form
A Brief Introduction to Zend_FormA Brief Introduction to Zend_Form
A Brief Introduction to Zend_Form
 
Zero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutesZero to Zend Framework in 10 minutes
Zero to Zend Framework in 10 minutes
 

Kürzlich hochgeladen

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 

Kürzlich hochgeladen (20)

DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

Composer: Game Changing Dependency Management

  • 1. Composer Game Changing Dependency Management php[architect] DevOps Summit Series Jeremy Kendall
  • 2.
  • 3. I love to code
  • 4. I love to code I’m terribly forgetful
  • 5. I love to code I’m terribly forgetful I take pictures
  • 6. I love to code I’m terribly forgetful I take pictures I work at OpenSky
  • 8. Adding Dependencies is Easy ‣ Copy and Paste
  • 9. Adding Dependencies is Easy ‣ Copy and Paste ‣ DIY Solution
  • 10. Adding Dependencies is Easy ‣ Copy and Paste ‣ DIY Solution ‣ SVN Externals
  • 11. Adding Dependencies is Easy ‣ Copy and Paste ‣ DIY Solution ‣ SVN Externals ‣ Git Submodules
  • 14. What is Composer? ‣ Dependency management tool
  • 15. What is Composer? ‣ Dependency management tool ‣ Per-project
  • 16. What is Composer? ‣ Dependency management tool ‣ Per-project ‣ Inspired by:
  • 17. What is Composer? ‣ Dependency management tool ‣ Per-project ‣ Inspired by: ‣ node’s npm
  • 18. What is Composer? ‣ Dependency management tool ‣ Per-project ‣ Inspired by: ‣ node’s npm ‣ ruby’s bundler
  • 20. Benefits ‣ Easily declare project dependencies
  • 21. Benefits ‣ Easily declare project dependencies ‣ Updating dependency versions extremely simple
  • 22. Benefits ‣ Easily declare project dependencies ‣ Updating dependency versions extremely simple ‣ Ensures your team is on the same page
  • 23. Benefits ‣ Easily declare project dependencies ‣ Updating dependency versions extremely simple ‣ Ensures your team is on the same page ‣ Tons of excellent related features
  • 25. Installing Locally $ curl -sS https://getcomposer.org/installer | phpIn your project:
  • 26. Installing Locally $ curl -sS https://getcomposer.org/installer | phpIn your project: $ curl -sS https://getcomposer.org/installer | php -- --install-dir=binSpecify a directory:
  • 27. Installing Locally $ curl -sS https://getcomposer.org/installer | phpIn your project: $ curl -sS https://getcomposer.org/installer | php -- --install-dir=binSpecify a directory: $ curl -sS https://getcomposer.org/installer | php #!/usr/bin/env php All settings correct for using Composer Downloading... Composer successfully installed to: /Users/jkendall/dev/ composer.phar Use it: php composer.phar What you’ll see:
  • 28. Installing Globally $ curl -sS https://getcomposer.org/installer | php $ mv composer.phar /usr/local/bin/composer Recommended
  • 29. Installing Globally $ curl -sS https://getcomposer.org/installer | php $ mv composer.phar /usr/local/bin/composer (You might need to use sudo) Recommended
  • 30. (There’s an installer for Windows folks)
  • 31. Keeping up to Date $ composer self-update You are using the latest composer version. $ php composer.phar self-update You are using the latest composer version. or
  • 32. Keeping up to Date $ composer self-update You are using the latest composer version. (Always updates to the latest dev-master) $ php composer.phar self-update You are using the latest composer version. or
  • 36. composer.json { "require": { "monolog/monolog": "1.5.*" } } ‣Place in the root of your project ‣“require” specifies package and version
  • 37. composer.json { "require": { "monolog/monolog": "1.5.*" } } ‣Place in the root of your project ‣“require” specifies package and version ‣monolog logging library
  • 38. composer.json { "require": { "monolog/monolog": "1.5.*" } } ‣Place in the root of your project ‣“require” specifies package and version ‣monolog logging library ‣Version >= 1.5.0 and < 1.6
  • 39. composer.json { "require": { "monolog/monolog": "1.5.*" } } ‣Place in the root of your project ‣“require” specifies package and version ‣monolog logging library ‣Version >= 1.5.0 and < 1.6 ‣No fuss, no muss
  • 41. ‣ Exact version: 1.0.0, 12.2.4, etc. Versions
  • 42. ‣ Exact version: 1.0.0, 12.2.4, etc. ‣ Wildcard: 3.*, 4.2.* Versions
  • 43. ‣ Exact version: 1.0.0, 12.2.4, etc. ‣ Wildcard: 3.*, 4.2.* ‣ Range: >, >=, <=, != Versions
  • 44. ‣ Exact version: 1.0.0, 12.2.4, etc. ‣ Wildcard: 3.*, 4.2.* ‣ Range: >, >=, <=, != ‣ Example: >=2.4 Versions
  • 45. ‣ Exact version: 1.0.0, 12.2.4, etc. ‣ Wildcard: 3.*, 4.2.* ‣ Range: >, >=, <=, != ‣ Example: >=2.4 ‣ Range: >=1.0,<1.7 (comma separated) Versions
  • 46. ‣ Exact version: 1.0.0, 12.2.4, etc. ‣ Wildcard: 3.*, 4.2.* ‣ Range: >, >=, <=, != ‣ Example: >=2.4 ‣ Range: >=1.0,<1.7 (comma separated) ‣ Next Significant Release: ~1.3.3 Versions
  • 47. Installing Dependencies $ composer install Loading composer repositories with package information Installing dependencies (including require-dev) - Installing psr/log (1.0.0) Loading from cache - Installing monolog/monolog (1.5.0) Loading from cache monolog/monolog suggests installing mlehner/gelf-php (Allow sending log messages to a GrayLog2 server) monolog/monolog suggests installing raven/raven (Allow sending log messages to a Sentry server) monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server) monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required)) Writing lock file Generating autoload files composer install
  • 49. composer.lock ‣ install writes a dependency lock file
  • 50. composer.lock ‣ install writes a dependency lock file ‣ List of exact versions installed
  • 51. composer.lock ‣ install writes a dependency lock file ‣ List of exact versions installed ‣ Commit both composer.lock and composer.json
  • 52. composer.lock ‣ install writes a dependency lock file ‣ List of exact versions installed ‣ Commit both composer.lock and composer.json ‣ composer install now checks the lock file, not composer.json
  • 53. composer.lock ‣ install writes a dependency lock file ‣ List of exact versions installed ‣ Commit both composer.lock and composer.json ‣ composer install now checks the lock file, not composer.json ‣ Update dependencies with composer update
  • 56. Updating Dependencies { "require": { "monolog/monolog": "1.6.*@dev" } } ‣Updates monolog library version
  • 57. Updating Dependencies { "require": { "monolog/monolog": "1.6.*@dev" } } ‣Updates monolog library version ‣Version >= 1.6.0 and < 1.7 (dev)
  • 58. Updating Dependencies $ composer update Loading composer repositories with package information Updating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7 Writing lock file Generating autoload files composer update
  • 59. Updating Dependencies $ composer update Loading composer repositories with package information Updating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7 Writing lock file Generating autoload files ‣Reads from composer.json composer update
  • 60. Updating Dependencies $ composer update Loading composer repositories with package information Updating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7 Writing lock file Generating autoload files ‣Reads from composer.json ‣Updates dependencies composer update
  • 61. Updating Dependencies $ composer update Loading composer repositories with package information Updating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7 Writing lock file Generating autoload files ‣Reads from composer.json ‣Updates dependencies ‣Rewrites lock file composer update
  • 62. Adding New Dependencies Edit composer.json . . . { "require": { "monolog/monolog": "1.6.*@dev", "ircmaxell/password-compat": "1.0.3" } }
  • 63. Adding New Dependencies Or use the command line $ composer require ircmaxell/password-compat:1.0.3 composer.json has been updated Loading composer repositories with package information Updating dependencies (including require-dev) - Installing ircmaxell/password-compat (1.0.3) Downloading: 100% Writing lock file Generating autoload files composer require
  • 65. Autoloading ‣ Composer generates vendor/autoload.php
  • 66. Autoloading ‣ Composer generates vendor/autoload.php ‣ Add require ‘vendor/autoload.php’;
  • 67. Autoloading ‣ Composer generates vendor/autoload.php ‣ Add require ‘vendor/autoload.php’; ‣ Immediately begin using your dependencies
  • 68. Autoloading { "require": { "monolog/monolog": "1.6.*@dev" }, "autoload": { "psr-0": { "Beeblebrox": "src/" } } } Don’t forget to add your own code!
  • 69. Autoloading $loader = require 'vendor/autoload.php'; $loader->add('AcmeTest', __DIR__); Pro Tip Grab an autoloader instance and add more namespaces.
  • 70. Kickstart a Project $ composer create-project slim/slim-skeleton super-sweet-application Installing slim/slim-skeleton (1.1.0) - Installing slim/slim-skeleton (1.1.0) Downloading: 100% Created project in super-sweet-application Loading composer repositories with package information Installing dependencies (including require-dev) - Installing slim/slim (2.3.0) Downloading: 100% - Installing slim/extras (2.0.3) Loading from cache - Installing twig/twig (v1.13.1) Loading from cache Writing lock file Generating autoload files composer create-project
  • 73. Libraries ‣ Everyone has written a library of some sort
  • 74. Libraries ‣ Everyone has written a library of some sort ‣ Making up examples is not my strong suit
  • 75. Libraries ‣ Everyone has written a library of some sort ‣ Making up examples is not my strong suit ‣ Let’s walk through a real library . . .
  • 76. Libraries ‣ Everyone has written a library of some sort ‣ Making up examples is not my strong suit ‣ Let’s walk through a real library . . . ‣ . . . and check out some awesome Composer features
  • 78. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } }
  • 79. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } Package requirements
  • 80. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } Package requirements Autoloading
  • 81. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } Add the “name” key and it’s installable
  • 82. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } Additional metadata
  • 83. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } Don’t forget the license!
  • 84. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } Full fledged library!
  • 85. Now for the cool(er) stuff . . .
  • 86. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } require-dev
  • 88. require-dev ‣ Lists packages required for development (think tests)
  • 89. require-dev ‣ Lists packages required for development (think tests) ‣ Only applies to the root package
  • 90. require-dev ‣ Lists packages required for development (think tests) ‣ Only applies to the root package ‣ Both install and update install require-dev by default
  • 91. require-dev ‣ Lists packages required for development (think tests) ‣ Only applies to the root package ‣ Both install and update install require-dev by default ‣ (Use the --no-dev flag to skip installing dev dependencies)
  • 92. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } bin
  • 93. bin
  • 94. bin ‣ cli scripts to pass along to package users
  • 95. bin ‣ cli scripts to pass along to package users ‣ A set of files that should be treated as binaries
  • 96. bin ‣ cli scripts to pass along to package users ‣ A set of files that should be treated as binaries ‣ Installs binaries to vendor/bin for any project that depends on your project
  • 97. bin ‣ cli scripts to pass along to package users ‣ A set of files that should be treated as binaries ‣ Installs binaries to vendor/bin for any project that depends on your project ‣ php-domain-parser uses a bin to update the local copy of the public suffix list
  • 98. { "name": "jeremykendall/php-domain-parser", "description": "Public Suffix List based URL parsing implemented in PHP.", "license": "MIT", "authors": [ { "name": "Jeremy Kendall", "homepage": "http://about.me/jeremykendall", "role": "Developer" } ], "bin": ["bin/pdp-psl"], "keywords": ["Public Suffix List", "domain parsing", "url parsing"], "require": { "php": ">=5.3.0", "ext-curl": "*" }, "require-dev": { "mikey179/vfsStream": "1.1.*", "jeremykendall/phpctagger": "0.0.*" }, "autoload": { "psr-0": { "Pdp": "library/" } }, "scripts": { "post-install-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ], "post-update-cmd": [ "PhpCtaggerComposerScriptCtagger::ctag" ] } } scripts
  • 100. scripts ‣ Used to execute custom code during the Composer execution process
  • 101. scripts ‣ Used to execute custom code during the Composer execution process ‣ PHP callback (defined as a static method) . . .
  • 102. scripts ‣ Used to execute custom code during the Composer execution process ‣ PHP callback (defined as a static method) . . . ‣ . . . or any command-line executable command
  • 103. scripts ‣ Used to execute custom code during the Composer execution process ‣ PHP callback (defined as a static method) . . . ‣ . . . or any command-line executable command ‣ Only scripts defined in the root composer.json are executed
  • 104. scripts ‣ Used to execute custom code during the Composer execution process ‣ PHP callback (defined as a static method) . . . ‣ . . . or any command-line executable command ‣ Only scripts defined in the root composer.json are executed ‣ If a script is defined in a dependency, you can use it in your composer.json
  • 106. scripts ‣ Composer fires “named events” during execution
  • 107. scripts ‣ Composer fires “named events” during execution ‣ Named events include:
  • 108. scripts ‣ Composer fires “named events” during execution ‣ Named events include: ‣ pre- and post-install-cmd
  • 109. scripts ‣ Composer fires “named events” during execution ‣ Named events include: ‣ pre- and post-install-cmd ‣ pre- and post-update-cmd
  • 110. scripts ‣ Composer fires “named events” during execution ‣ Named events include: ‣ pre- and post-install-cmd ‣ pre- and post-update-cmd ‣ post-root-package-install
  • 111. scripts ‣ Composer fires “named events” during execution ‣ Named events include: ‣ pre- and post-install-cmd ‣ pre- and post-update-cmd ‣ post-root-package-install ‣ Many more . . .
  • 113. Running scripts Execute Composer (script will execute if the named event is triggered) or . . .
  • 114. Running scripts Execute Composer (script will execute if the named event is triggered) or . . .
  • 115. Running scripts Execute Composer (script will execute if the named event is triggered) or . . . composer run-script <named event>
  • 116. Example public static function create(Event $event) { $dir = dirname($event->getComposer()->getConfig()->get('vendor-dir')); $io = $event->getIO(); $io->write('Reviewing your Flaming Archer environment . . .', true); $configExists = file_exists($dir . '/config.php'); $configDistExists = file_exists($dir . '/config-dist.php'); if (!$configExists && $configDistExists) { $io->write('Creating config.php by copying config-dist.php . . .', true); copy($dir . '/config-dist.php', $dir . '/config.php'); $io->write("Done! Please edit config.php.", true); } else { $io->write('Found config.php.', true); } } https://github.com/jeremykendall/flaming-archer/blob/develop/library/Fa/Composer/Script/Config.php
  • 117. You’ve built your library. Now what?
  • 118. Push it to aVCS
  • 119. Push it to aVCS ‣ git, svn, or hg all work equally well
  • 120. Push it to aVCS ‣ git, svn, or hg all work equally well ‣ For the sake of simplicity I’ll assume git/github
  • 121. Push it to aVCS ‣ git, svn, or hg all work equally well ‣ For the sake of simplicity I’ll assume git/github ‣ Package versions:
  • 122. Push it to aVCS ‣ git, svn, or hg all work equally well ‣ For the sake of simplicity I’ll assume git/github ‣ Package versions: ‣ Tags are package versions (1.0.0, v2.5.4, etc)
  • 123. Push it to aVCS ‣ git, svn, or hg all work equally well ‣ For the sake of simplicity I’ll assume git/github ‣ Package versions: ‣ Tags are package versions (1.0.0, v2.5.4, etc) ‣ Branches are dev versions (dev-{branchname}, {branchname}-dev)
  • 124. Push it to aVCS ‣ git, svn, or hg all work equally well ‣ For the sake of simplicity I’ll assume git/github ‣ Package versions: ‣ Tags are package versions (1.0.0, v2.5.4, etc) ‣ Branches are dev versions (dev-{branchname}, {branchname}-dev) ‣ For this reason, I strongly recommend using semantic versioning: http://semver.org
  • 125. Share!
  • 128. Packagist ‣ The main package repository for Composer
  • 129. Packagist ‣ The main package repository for Composer ‣ (Aside: Search Packagist before “rolling your own”)
  • 130. Packagist ‣ The main package repository for Composer ‣ (Aside: Search Packagist before “rolling your own”) ‣ Packages published there need no special settings in composer.json to be installable (see “repositories” key)
  • 131. Packagist ‣ The main package repository for Composer ‣ (Aside: Search Packagist before “rolling your own”) ‣ Packages published there need no special settings in composer.json to be installable (see “repositories” key) ‣ Submitting is dead simple
  • 132. Packagist ‣ The main package repository for Composer ‣ (Aside: Search Packagist before “rolling your own”) ‣ Packages published there need no special settings in composer.json to be installable (see “repositories” key) ‣ Submitting is dead simple ‣ Create account, hit big green submit button
  • 137. But what about internal proprietary packages?
  • 138. Satis to the Rescue
  • 139. Satis to the Rescue ‣ Static composer repository generator
  • 140. Satis to the Rescue ‣ Static composer repository generator ‣ Lightweight, static file based version of Packagist
  • 141. Satis to the Rescue ‣ Static composer repository generator ‣ Lightweight, static file based version of Packagist ‣ Simple to configure
  • 142. Satis to the Rescue ‣ Static composer repository generator ‣ Lightweight, static file based version of Packagist ‣ Simple to configure ‣ Flexible
  • 143. $ composer create-project composer/satis --stability=dev --keep-vcs Installing composer/satis (dev-master 059588ef0fd0977964ad13637e02012519686202) - Installing composer/satis (dev-master master) Cloning master Created project in /Users/jkendall/dev/satis Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Warning: The lock file is not up to date with the latest changes in composer.json . . . - Installing symfony/process (dev-master 75c8101) Cloning 75c810176f8e069714cef8696d7ecc3aa86e8168 - [ . . . ] - Installing twig/twig (v1.13.1) Loading from cache symfony/console suggests installing symfony/event-dispatcher () Generating autoload files composer create-project composer/satis --stability=dev --keep-vcs
  • 144. Satis config.json { "name": "Satis Demo", "homepage": "http://satis.dev", "repositories": [ { "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" }, { "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" } ], "require": { "jeremykendall/php-domain-parser": ">=0.0.5", "jeremykendall/phpctagger": ">0.0.6" }, "archive": { "directory": "dist", "format": "tar" } }
  • 145. Satis config.json { "name": "Satis Demo", "homepage": "http://satis.dev", "repositories": [ { "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" }, { "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" } ], "require": { "jeremykendall/php-domain-parser": ">=0.0.5", "jeremykendall/phpctagger": ">0.0.6" }, "archive": { "directory": "dist", "format": "tar" } }
  • 146. Satis config.json { "name": "Satis Demo", "homepage": "http://satis.dev", "repositories": [ { "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" }, { "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" } ], "require": { "jeremykendall/php-domain-parser": ">=0.0.5", "jeremykendall/phpctagger": ">0.0.6" }, "archive": { "directory": "dist", "format": "tar" } }
  • 147. Satis config.json { "name": "Satis Demo", "homepage": "http://satis.dev", "repositories": [ { "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" }, { "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" } ], "require": { "jeremykendall/php-domain-parser": ">=0.0.5", "jeremykendall/phpctagger": ">0.0.6" }, "archive": { "directory": "dist", "format": "tar" } }
  • 148. Satis config.json { "name": "Satis Demo", "homepage": "http://satis.dev", "repositories": [ { "type": "vcs", "url": "https://github.com/jeremykendall/php-domain-parser" }, { "type": "vcs", "url": "https://github.com/jeremykendall/phpctagger" } ], "require": { "jeremykendall/php-domain-parser": ">=0.0.5", "jeremykendall/phpctagger": ">0.0.6" }, "archive": { "directory": "dist", "format": "tar" } }
  • 149. Build Repo $ php bin/satis build config.json web/
  • 150. composer.json { "repositories": [ { "type": "composer", "url": "http://satis.dev" } ], "require": { "jeremykendall/php-domain-parser": "0.0.7" } }
  • 151. composer.json { "repositories": [ { "type": "composer", "url": "http://satis.dev" } ], "require": { "jeremykendall/php-domain-parser": "0.0.7" } }
  • 152. composer.json { "repositories": [ { "type": "composer", "url": "http://satis.dev" } ], "require": { "jeremykendall/php-domain-parser": "0.0.7" } }
  • 154. Satis Demo Project ‣ Want to goof around with Satis?
  • 155. Satis Demo Project ‣ Want to goof around with Satis? ‣ See: https://github.com/jeremykendall/satis-demo
  • 156. Satis Demo Project ‣ Want to goof around with Satis? ‣ See: https://github.com/jeremykendall/satis-demo ‣ Clone, follow instructions in README, and WIN
  • 157. Satis Demo Project ‣ Want to goof around with Satis? ‣ See: https://github.com/jeremykendall/satis-demo ‣ Clone, follow instructions in README, and WIN ‣ Satis really is dead simple to set up
  • 158. Parting Tips and Tricks
  • 159. composer install --no-dev --prefer-dist --optimize-autoloader
  • 161. Non-Composer and PEAR packages can be installed (see “repositories” key documentation)
  • 165. Credits ‣ Thanks to php[architect] for having me IMMA LET YOU FINISH, BUT RAFAEL DOHMS HAS THE BEST COMPOSER TALK OF ALL TIME.
  • 167. Credits ‣ Thanks to Rafael Dohms, the Composer presenter
  • 168. Credits ‣ Thanks to Rafael Dohms, the Composer presenter ‣ Thanks to php[architect] for having me
  • 169. Credits ‣ Thanks to Rafael Dohms, the Composer presenter ‣ Thanks to php[architect] for having me ‣ Thanks to Jordi Boggiano, Nils Adermann, and the community for an amazing project (and all the documentation I cribbed from)
  • 170. Credits ‣ Thanks to Rafael Dohms, the Composer presenter ‣ Thanks to php[architect] for having me ‣ Thanks to Jordi Boggiano, Nils Adermann, and the community for an amazing project (and all the documentation I cribbed from) ‣ Thanks to our sponsors for help making this happen
  • 171. Credits ‣ Thanks to Rafael Dohms, the Composer presenter ‣ Thanks to php[architect] for having me ‣ Thanks to Jordi Boggiano, Nils Adermann, and the community for an amazing project (and all the documentation I cribbed from) ‣ Thanks to our sponsors for help making this happen ‣ Thanks to all of you for being here