ComposerGame 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 phpAll settings correct for using ComposerDownloading...
Composer successfully installed to: /Users/jkendall/dev/composer.pharUse 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-updateYou are using the latest composer version.
$ php composer.phar self-updateYou are using the latest composer version.
or
Keeping up to Date
$ composer self-updateYou are using the latest composer version.
(Always updates to the latest dev-master)
$ php composer.phar self-updateYou 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 installLoading composer repositories with package informationInstalling 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 fileGenerating 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 updateLoading composer repositories with package informationUpdating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock fileGenerating autoload files
composer update
Updating Dependencies
$ composer updateLoading composer repositories with package informationUpdating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock fileGenerating autoload files
‣Reads from composer.json
composer update
Updating Dependencies
$ composer updateLoading composer repositories with package informationUpdating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock fileGenerating autoload files
‣Reads from composer.json‣Updates dependencies
composer update
Updating Dependencies
$ composer updateLoading composer repositories with package informationUpdating dependencies (including require-dev) - Removing monolog/monolog (1.5.0) - Installing monolog/monolog (dev-master c933bb6) Cloning c933bb67a8a2e45c42d0626a0cd6569789bf6ed7
Writing lock fileGenerating 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 DependenciesOr use the command line
$ composer require ircmaxell/password-compat:1.0.3composer.json has been updatedLoading composer repositories with package informationUpdating dependencies (including require-dev) - Installing ircmaxell/password-compat (1.0.3) Downloading: 100%
Writing lock fileGenerating 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('Acme\\Test\\', __DIR__);
Pro Tip
Grab an autoloader instance and add more namespaces.
Kickstart a Project
$ composer create-project slim/slim-skeleton super-sweet-applicationInstalling slim/slim-skeleton (1.1.0) - Installing slim/slim-skeleton (1.1.0) Downloading: 100%
Created project in super-sweet-applicationLoading composer repositories with package informationInstalling 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 fileGenerating autoload files
composer create-project
Your Very 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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ] }}
Add the “name” keyand 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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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": [ "PhpCtagger\\Composer\\Script\\Ctagger::ctag" ], "post-update-cmd": [ "PhpCtagger\\Composer\\Script\\Ctagger::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 a VCS
Push it to a VCS‣ git, svn, or hg all work equally well
Push it to a VCS‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
Push it to a VCS‣ git, svn, or hg all work equally well
‣ For the sake of simplicity I’ll assume git/github
‣ Package versions:
Push it to a VCS‣ 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 a VCS‣ 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 a VCS‣ 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-vcsInstalling composer/satis (dev-master 059588ef0fd0977964ad13637e02012519686202) - Installing composer/satis (dev-master master) Cloning master
Created project in /Users/jkendall/dev/satisLoading composer repositories with package informationInstalling dependencies (including require-dev) from lock fileWarning: 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)
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!
http://about.me/jeremykendall
@jeremykendall
https://joind.in/8968