A soup to nuts presentation on using Composer and repository servers to manage and leverage shared code libraries for personal projects to the largest enterprise.
2. Who Am I?
• Selling Source Direct Lead
Developer
• Coupla CTO
• Founder/Organizer of Las
Vegas PHP Users Group
• Co-Organizer of Las Vegas
Developers Users Group
• PHP Machinist Maintainer
• #VegasTech Enthusiast
Adam Englander
adamenglander@yahoo.com
@adam_englander
http://adamknowsstuff.com
https://github.com/derptest
3. What is Dependency
Management?
Dependency management for this context
is best described as the resolution and
installation of library dependencies for a
software project. This includes resolving
potential conflicts between libraries and
providing the dependencies for all libraries
on the dependency tree.
6. Legacy Solutions
PEAR
PECL
Version Control System Sub-repositories
(SVN, Git, Mercurial)
Directly adding dependencies to your
codebase
Custom dependency manager
Write monolithic code bases
7. PEAR – PHP Extension and
Application Library
Multiple
Repositories
Private Repositories
Sub-dependency
version resolution
Hundreds of libraries
One package install
per server
No common format
for defining project
dependencies
Not extensible
Each server had to
be aware of
repositories
Publishing required
8. PECL– PHP Extension
Community Library
Highly trusted
libraries
Hundreds of libraries
Sub-dependency
version resolution
One package install
per server
No common format
for defining project
dependencies
No private repos
Each server had to
be aware of
repositories
Publishing required
9. VCS Sub-Repositories
Project based
dependencies
Private Repositories
Potentially millions
of libraries
Normally requires
using the external
library’s VCS
No deep
dependency
management
Need to monitor
patches and
updates to external
libraries
10. Directly adding dependencies
to your codebase
Project based
dependencies
Private Repositories
Potentially millions
of libraries
Project codebases
have dependency
code making them
large and unwieldy
You have to
manually resolve all
dependencies
You have to test
interoperability of all
dependent libraries
11. Custom Repository
Manager
If you can dream it,
you can do it.
Difficult to write
You must implement
every feature and fix
every bug
12. Monolithic Code Base
No need for
dependency
management
Private Repositories
Harder to manage
Harder to test
Re-writing the same
code in multiple
projects.
Maintaining the the
same bug fixes in
multiple projects.
No leveraging of
community code
13. DRY – Don’t repeat yourself or anyone else for that
matter.
14. The Platform
Composer – The fully self-contained and
completely extensible client
Satis – The app for generating static
servable repository data.
Packagist – The server for managing
and maintaining dynamic repository
data.
Packagist.org – The public Packagist
server for open source libraries and
projects. 21K+ packages.
16. Composer Overview
Command line client application for:
Searching repositories for packages
Installing project skeletons
Executing install/update hooks
Managing project dependencies
Managing project metadata
Base code for servers
The only product on the platform
necessary for managing dependencies
in a project
17. Installation
There
Download the composer.phar from
http://getcomposer.org/download/
Use the installer script from
http://getcomposer.org/download/
Install from your *nix distro package
manager (yum/apt/pkgsrc/homebrew)
18. Search the repositories
vagrant:/$ composer search monolog
monolog/monolog Sends your logs to files, sockets, inboxes, databases and
various web services
symfony/monolog-bundle Symfony MonologBundle
symfony/monolog-bridge Symfony Monolog Bridge
flynsarmy/slim-monolog Monolog logging support Slim Framework
logentries/logentries-monolog-handler A handler for Monolog that sends
messages to Logentries.com.
kamisama/monolog-init Very basic and light Dependency Injector Container for
Monolog
ddtraceweb/monolog-parser A parser for monolog log entries
lexik/monolog-browser-bundle This Symfony2 bundle provides a Doctrine DBAL
handler for Monolog and a web UI to display log entries
graze/monolog-extensions Monolog extensions for use within Graze
bazo/nette-monolog-extension Nette monolog compiler extension
fancyguy/wordpress-monolog WordPress Monolog Integration
kmelia/monolog-stdout-handler A handler for Monolog that sends messages to
stdout (with color).
support
22. Managing Project
Dependencies:
Overview
A project can be initialized with the init
command
Project dependencies can be configured by
the command line or directly in the
composer.json file.
The validate command will validate the
composer.json file.
The composer.lock file will lock the
revision/change number of the
dependencies.
23. Managing Project
Dependencies:
Overview (continued)
The install command will install locked
versions if composer.lock is present or act
like the update command if not.
The update command will update the
library versions and the composer.lock file.
Running the Composer binary without any
commands will list the available
commands.
Running the help command will provide
help
24. Managing Project Metadata:
Overview
The composer specification allows for
the following metadata:
Description – package description
Type – I.E. project or library
Keywords – Aid in searching repositories
Homepage – Project homepage
License – License type for the package
Authors – Information about the authors
Support – Information for obtaining support
regarding the library
26. Managing Dependency
Conflicts
You can manually resolve conflicts
between in dependencies when:
Changing the version of one of the
dependent packages that causes the conflict
is not an option
The version you choose will not negatively
effect either dependent package.
"monolog/monolog": "1.7.0 as 1.6.0"
27. Applying Forks as
Dependencies
Alternate repositories can be used to
provide versions with aliases
One of the following must be true for
Composer to use an alternate repository:
The repository specifying the alias is listed
before the repository containing original
package in the composer.json file.
The repository containing original package does
not have a version specified by the alias (risky)
28. Applying Forks as
Dependencies: Example
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/my/monolog"
}
],
"require": {
"symfony/monolog-bundle": "2.0",
"monolog/monolog": "dev-myfix as 1.0.x-dev”
}
}
29. Managing Repositories
Repositories hold package information in
multiple types:
Packagist.org – Default repository
Composer (Packagist/Satis/Manual)
VCS (git/mercurial/subversion)
PEAR – Using PEAR channels
Artifact – Pre-built artifacts
Package – Using libraries that
All repositories except “Package” require a
composer.json file.
Repository additions must be on the root
package.
30. Packagist.org Repository
Will be the final repository searched
Enabled by default but can be disabled:
{
"repositories": [
{
"packagist": false
}
]
}
31. Composer Repository
Provides a packages.json file.
Defined by URL. Path contains file.
Example inclusion:
{
"repositories": [
{
"type": "composer",
"url": http://packages.example.com
}
]
}
32. VCS Repository
Composer client will scan VCS
repositories to find branches and tags
with a composer.json file in the root.
Package name from the composer.json
file.
Version is from the branch/tag name.
Branch versions will be prefixed with
dev-.
33. Pear Repository
Composer access to existing PEAR channels.
{
repositories: [
{
"type": "pear",
"url": “pear.phpunit.de”,
“vendor-alias”: “phpunit”
}
]
}
Access repository packages via channel or alias
“pear.phpunit.de/PHPUnit”: “>=3.7.0”
“phpunit/PHPUnit”: “>=3.7.0”
34. Artifact Repository
Scans directory of zip files with composer.json files in
the root of the zip.
Uses package and version in composer.json file.
{
"repositories": [
{
"type": "artifact",
"url": "path/to/zips/dir”
}
]
}
35. Package Repository
Defines the package and versions in the
composer.json file.
Uses the same format as packages.json
file from Composer repository.
Allows for providing shared code that is
not available by any of the other means.
38. Satis: Easy as Pie
Maintain a JSON based meta-data file
with the list of repositories to scour.
Execute the command and it will
provide:
Composer compliant packages.json file
HTML file with instructions on adding the
repository to a composer.json file as well as
a filterable list.
39. Satis: Repository Cache
If the archive section is configured in the
Satis meta-data file, Satis will scan all
repositories defined and create local
archives
If options require-dependencies is set to
true, it will also cache dependencies. This
only works on known packages in the
defined repositories.
Here’s a link to an excellent article on how
to affectively cache packagist.org:
http://tech.m6web.fr/composer-installationwithout-github.html
40. Satis Metadata Example
{
"name": "My Repository",
"homepage": "http://satis.my.org",
"repositories": [
{
"type": "vcs",
"url": "http://github.com/my/repo"
}
],
"require-all": true
}
41. Satis Conclusions
Simple to use
Easy to deploy
Full PHP
implementation
Uses static files for
hosting
Can cache
repositories from
VCS and Packagist
Requires
management of a
config file
Becomes unwieldy
for large numbers of
packages
Limited search and
package information
Requires shared
disk for HA
43. Packagist…and a bag of
chips
Web based package management
Optimized search via Solr
Allows for high availability via MySQL
API for remotely triggering package
scans
Package statistics
44. Packagist Conclusions
Web based
management
interface
Solr based search
HA capable
Virtually unlimited
package
management
No archives for non
Github/BitBucket
VCS repositories
Complex
architecture
Requires MySQL
and Solr knowledge
and management
Only VCS packages
45. Your one stop shop for open source projects and libraries
46. One Repository to Rule Them
All
21,762 packages (1/7/2014)
Default package manager for Composer
Free accounts to register/maintain
packages
Contains nearly every widely used open
source PHP package
Just use it!
47. Registering a package
Get a user
Log in
Click “Submit a Package”
Enter the URL for your public repository
Click “Check”
Optionally but suggested: Register a
commit hook to scan for updates on
commit.
Github has a pre-configured hook
BitBucket can use a POST hook