Answers.Body: <h1>Approaches</h1>
  
  <p>There are a few different patterns one could follow in connecting Civi extensions with composer:</p>
  
  <ol>
  <li>(Broad scope) <strong>Site build via composer</strong>: The entire web site is defined with a custom <code>composer.json</code> file. It doesn't matter what kind of dependency you need to pull in (CMS, CMS module, CMS theme, CRM, CRM extension, PHP library, CSS library, etc), it's all brought in through the same tools/workflows.</li>
  <li>(Medium scope) <strong>Use <code>composer</code> for the <code>extensionDir</code></strong>: Civi has a special folder (e.g. <code>sites/default/files/civicrm/ext</code>) for storing downloaded extensions. We could keep this folder but manage it differently -- e.g. rewrite <code>CRM_Extension_Downloader</code> as a wrapper for <code>composer</code>.</li>
  <li>(Narrow scope) <strong>Intra-extension dependency</strong>: If one particular extension requires a particular library, then the extension could have its own copy of <code>composer.json</code> and <code>vendor/</code>. The final zip file would embed <code>vendor/</code>.</li>
  </ol>
  
  <h1>Site build via composer</h1>
  
  <p>IMHO, this is the holy-grail. It's consistent with the architecture of PHP and <code>composer</code>, and it resolves problems that afflict dependency-management in Drupal (<code>libraries/</code> guffaw!) and CiviCRM (dependencies guffaw!) and probably Joomla/WordPress.</p>
  
  <p>It's worth drilling down on the architecture concern for a moment. Civi is deployed as a PHP app which shares a runtime with another PHP app. In PHP, the runtime can only load one version of a library -- e.g. you can load Guzzle v5.0 XOR v5.1 but not both, so it's important to pick a version of Guzzle that is acceptable to all libraries/modules/extensions. When using <code>composer</code> in narrow/piecemeal fashion, it doesn't get the full list of libraries/modules/extensions, so it cannot help you pick a version of Guzzle that satisfies the overall system. You're more likely to suffer from hidden version-conflicts (if, e.g., a Drupal module loads Guzzle v5.0 while your Civi extension loads Guzzle v5.1).</p>
  
  <p>The main challenge is that many of the relevant systems (Drupal, Joomla, WordPress, Civi, etc) predate <code>composer</code> and have some impedance mismatch with <code>composer</code> (e.g. <code>composer</code> lacks a GUI; Drupal has multisite PHP loading; post-install hooks work differently). Getting these communities to switch is a major undertaking.</p>
  
  <p>I think there are some fairly clear steps we can take toward supporting this model, but your question was really aimed at a different approach...</p>
  
  <h1>Intra-extension dependency</h1>
  
  <p>No one controls enough of the ecosystem to quickly switch a critical-mass of site-building to <code>composer</code>. And this version-conflict stuff may sound theoretical. In fact, you can get some mileage out of piecemeal dependency management. (Case in point: <code>civicrm-*.tar.gz</code> ships with its own bundled copy of <code>vendor/</code>!) And your comments indicate an interest in this approach.</p>
  
  <p>Unfortunately, you're basically on-your-own to make this work. Loosely, I'd try:</p>
  
  <ul>
  <li>In the <code>myextension.git</code> repo, add a <code>composer.json</code> file which lists any dependencies. Use <code>.gitignore</code> to avoid committing <code>vendor/</code>. In <code>myextension.php</code>, use <code>require_once __DIR__.'/vendor/autoload.php';</code>.</li>
  <li>When registering your extension on <code>civicrm.org</code>, do <em>not</em> specify a Github URL. Neither <code>github.com</code> nor <code>civicrm.org</code> is smart enough to build your releases automatically.</li>
  <li>Setup a CI tool which monitors your git repo and publishes the final <code>zip</code> archive. As a very loose example, I publish the <code>civix.phar</code> file with Jenkins (<a href="https://test.civicrm.org/job/Tool-Publish-civix/" rel="nofollow">job</a>, <a href="https://gist.github.com/totten/7abeb9eb9558c5bc9d4105b40c19b1e5" rel="nofollow">script</a>). You could write a similar script to run <code>composer install</code>, <code>zip</code>, and then publish the final file.</li>
  <li>Whenever you want to publish a new release, login to <code>civicrm.org</code> and manually create a new release node (with suitable <code>info.xml</code> and download URL).</li>
  </ul>
  
  <p>Unfortunately, there is a risk that your dependencies will conflict with others'. There's not a whole lot you can do about this... except pick obscure dependencies that aren't likely to conflict.</p>
  
  <p>(In theory, if you know that your extension and the conflicted one never use the conflicted dependencies within the same page-request, then you could do some fiddly bits in the class-loading to only load the correct one. But in a powerful system like Drupal/Civi, it's really hard to provide this guarantee, and the other party may not play-along.)</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-29T04:05:00.113Z
Answers.Text: Second thought: it's worth noting that -- as an extension author -- these two aren't mutually exclusive. You can do both: (a) add composer.json to your repo, (b) register on packagist.org, and (c) setup CI and publish zip files via civicrm.org. Old-school site-builders can get the package through civicrm.org/zip-files; new-school site-builders can get them through packagist.
Answers.UserDisplayName: Tim Otten
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-01-25T20:48:59.197Z
Answers.Text: "Unfortunately, there is a risk that your dependencies will conflict with others'. There's not a whole lot you can do about this... except pick obscure dependencies that aren't likely to conflict." -> so two extensions that use different versions of the same package are quite possiblly incompatible? I was imagining that is a problem that namespacing could solve...
Answers.UserDisplayName: michaelmcandrew
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-01-25T20:56:14.123Z
Answers.Text: That's fine for a dependency written specifically to work that way, but it's pretty atypical for a PHP library to handle versioning through their namespaces -- and changing third-party libraries to use that technique would be a hard sell because it would be a compatibility-break.
Answers.UserDisplayName: Tim Otten
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-29T00:56:48.930Z
Answers.LastActivityDate: 2016-09-25T22:01:16.293Z
Answers.LastEditDate: 2016-09-25T22:01:16.293Z
Answers.UserDisplayName: Tim Otten
Body: <p>I'm wanting to (re)develop an extension and I'd like to use some 3rd party libraries, eg. guzzle, that I would normally manage via composer.</p>
  
  <p>So my github repo will contain a composer.json file, but not the vendor directory. So would I need to package installable versions with the libraries included?</p>
  
  <p>Also, what if I were to install libraries that are already included (eg dependencies of the libraries I want might be already in use leading to a namespace clash).</p>
  
  <p>Is there a workflow for this sort of thing?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-04-23T01:36:07.837Z
Comments.Text: Are you using an architecture like https://github.com/drupal-composer/drupal-project or http://composer.rarst.net/recipe/site-stack to manage the entire site/build with `composer`? Or looking for a way to distribute one extension to the general-public via `composer`?
Comments.UserDisplayName: Tim Otten
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-04-23T05:47:40.043Z
Comments.Text: The latter - this project is already in use by quite a number of organisations and I want to do more on it. (to add to your useful links [Drupal composer_manager](https://www.drupal.org/project/composer_manager) is also related). Basically in development I want to use composer, but in production/packaged install via CiviCRM's normal extensions thing I'd like the user not to need to know about composer, and it "just work"
Comments.UserDisplayName: artfulrobot
Tags: <extension><developer>
Title: How to develop extension that relies on libs brought in by composer
ThreadText: # How to develop extension that relies on libs brought in by composer
  
  (Asked by: username_0 on 2016-04-22)
  
  I'm wanting to (re)develop an extension and I'd like to use some 3rd party libraries, eg. guzzle, that I would normally manage via composer.
  
  So my github repo will contain a composer.json file, but not the vendor directory. So would I need to package installable versions with the libraries included?
  
  Also, what if I were to install libraries that are already included (eg dependencies of the libraries I want might be already in use leading to a namespace clash).
  
  Is there a workflow for this sort of thing?
  
  **Tags:** extension, developer
  
  > **Comments:**
  > **username_1**: Are you using an architecture like https://github.com/drupal-composer/drupal-project or http://composer.rarst.net/recipe/site-stack to manage the entire site/build with `composer`? Or looking for a way to distribute one extension to the general-public via `composer`?  
  > **username_0**: The latter - this project is already in use by quite a number of organisations and I want to do more on it. (to add to your useful links [Drupal composer_manager](https://www.drupal.org/project/composer_manager) is also related). Basically in development I want to use composer, but in production/packaged install via CiviCRM's normal extensions thing I'd like the user not to need to know about composer, and it "just work"  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2016-04-29. Score: 9 | Accepted answer
  
  # Approaches
  
  There are a few different patterns one could follow in connecting Civi extensions with composer:
  
  1. (Broad scope) **Site build via composer**: The entire web site is defined with a custom `composer.json` file. It doesn't matter what kind of dependency you need to pull in (CMS, CMS module, CMS theme, CRM, CRM extension, PHP library, CSS library, etc), it's all brought in through the same tools/workflows.
  2. (Medium scope) **Use `composer` for the `extensionDir`**: Civi has a special folder (e.g. `sites/default/files/civicrm/ext`) for storing downloaded extensions. We could keep this folder but manage it differently -- e.g. rewrite `CRM_Extension_Downloader` as a wrapper for `composer`.
  3. (Narrow scope) **Intra-extension dependency**: If one particular extension requires a particular library, then the extension could have its own copy of `composer.json` and `vendor/`. The final zip file would embed `vendor/`.
  
  # Site build via composer
  
  IMHO, this is the holy-grail. It's consistent with the architecture of PHP and `composer`, and it resolves problems that afflict dependency-management in Drupal (`libraries/` guffaw!) and CiviCRM (dependencies guffaw!) and probably Joomla/WordPress.
  
  It's worth drilling down on the architecture concern for a moment. Civi is deployed as a PHP app which shares a runtime with another PHP app. In PHP, the runtime can only load one version of a library -- e.g. you can load Guzzle v5.0 XOR v5.1 but not both, so it's important to pick a version of Guzzle that is acceptable to all libraries/modules/extensions. When using `composer` in narrow/piecemeal fashion, it doesn't get the full list of libraries/modules/extensions, so it cannot help you pick a version of Guzzle that satisfies the overall system. You're more likely to suffer from hidden version-conflicts (if, e.g., a Drupal module loads Guzzle v5.0 while your Civi extension loads Guzzle v5.1).
  
  The main challenge is that many of the relevant systems (Drupal, Joomla, WordPress, Civi, etc) predate `composer` and have some impedance mismatch with `composer` (e.g. `composer` lacks a GUI; Drupal has multisite PHP loading; post-install hooks work differently). Getting these communities to switch is a major undertaking.
  
  I think there are some fairly clear steps we can take toward supporting this model, but your question was really aimed at a different approach...
  
  # Intra-extension dependency
  
  No one controls enough of the ecosystem to quickly switch a critical-mass of site-building to `composer`. And this version-conflict stuff may sound theoretical. In fact, you can get some mileage out of piecemeal dependency management. (Case in point: `civicrm-*.tar.gz` ships with its own bundled copy of `vendor/`!) And your comments indicate an interest in this approach.
  
  Unfortunately, you're basically on-your-own to make this work. Loosely, I'd try:
  
  * In the `myextension.git` repo, add a `composer.json` file which lists any dependencies. Use `.gitignore` to avoid committing `vendor/`. In `myextension.php`, use `require_once __DIR__.'/vendor/autoload.php';`.
  * When registering your extension on `civicrm.org`, do *not* specify a Github URL. Neither `github.com` nor `civicrm.org` is smart enough to build your releases automatically.
  * Setup a CI tool which monitors your git repo and publishes the final `zip` archive. As a very loose example, I publish the `civix.phar` file with Jenkins ([job](https://test.civicrm.org/job/Tool-Publish-civix/), [script](https://gist.github.com/totten/7abeb9eb9558c5bc9d4105b40c19b1e5)). You could write a similar script to run `composer install`, `zip`, and then publish the final file.
  * Whenever you want to publish a new release, login to `civicrm.org` and manually create a new release node (with suitable `info.xml` and download URL).
  
  Unfortunately, there is a risk that your dependencies will conflict with others'. There's not a whole lot you can do about this... except pick obscure dependencies that aren't likely to conflict.
  
  (In theory, if you know that your extension and the conflicted one never use the conflicted dependencies within the same page-request, then you could do some fiddly bits in the class-loading to only load the correct one. But in a powerful system like Drupal/Civi, it's really hard to provide this guarantee, and the other party may not play-along.)
  
  > **Comments:**
  > **username_1**: Second thought: it's worth noting that -- as an extension author -- these two aren't mutually exclusive. You can do both: (a) add composer.json to your repo, (b) register on packagist.org, and (c) setup CI and publish zip files via civicrm.org. Old-school site-builders can get the package through civicrm.org/zip-files; new-school site-builders can get them through packagist.  
  > **username_2**: "Unfortunately, there is a risk that your dependencies will conflict with others'. There's not a whole lot you can do about this... except pick obscure dependencies that aren't likely to conflict." -> so two extensions that use different versions of the same package are quite possiblly incompatible? I was imagining that is a problem that namespacing could solve...  
  > **username_1**: That's fine for a dependency written specifically to work that way, but it's pretty atypical for a PHP library to handle versioning through their namespaces -- and changing third-party libraries to use that technique would be a hard sell because it would be a compatibility-break.  
  
  ---
  
  