Search code examples
phpwordpressdependency-managementdirectory-structurecomposer-php

Controlling Exact Folder/Directory where Packages are Written by Composer for PHP


The Background

I'm trying to use Composer to manage dependencies for WordPress plugins. I've built several PHP libraries (RESTian & Sidecar) I want to include in subdirectories for each of several plugins we are building and those PHP libraries are hosted on GitHub. The WordPress plugins are (currently) hosted in private BitBucket repos as they are for clients but those plugins will also get published to WordPress plugin repository when we are ready to release them.

The Problem

I want a directory structure of /libraries/restian/ and /libraries/sidecar/ relative to the root of the plugin. For those who know WordPress they would ultimately look like this installed:

/wp-content/plugins/my-wp-plugin/libraries/restian/
/wp-content/plugins/my-wp-plugin/libraries/sidecar/

Problem is I've only been able to get Composer to put them within a /newclarity/ subdirectory which is more complexity than I want to add to the directory structure of the plugin ('newclarity' is our GitHub account):

/wp-content/plugins/my-wp-plugin/libraries/newclarity/restian/
/wp-content/plugins/my-wp-plugin/libraries/newclarity/sidecar/

The Source

Here is the composer.json file that I am using to research and test this:

{
  "name":"mikeschinkel/my-wp-plugin",
  "description":"My WordPress Plugin",
  "type":"wordpress-plugin",
  "config":{
    "vendor-dir":"libraries/"
  },
  "require": {
    "newclarity/restian":"dev-master",
    "newclarity/sidecar":"dev-master"
  },
  "repositories":[
    {
      "type":"git",
      "url":"https://github.com/newclarity/restian.git"
    },
    {
      "type":"git",
      "url":"https://github.com/newclarity/sidecar.git"
    }
  ]
}

And here are the current composer.json files from the libraries hosted at GitHub:

{
  "name": "newclarity/restian",
  "description": "RESTian: A base class library to simplify building RESTful/Web API clients in PHP",
  "require": {
      "php": ">=5.2.4"
  }
}

And:

{
  "name": "newclarity/sidecar",
  "description": "Sidecar: The Missing Plugin API for WordPress",
  "require":{
    "php":">=5.2.4"
  }
}

I've been researching this for over 4 hours now. Any help would be appreciated.

-Mike


Solution

  • So I came up with a solution that works, but it's inelegant and I was really hoping for a simple and elegant solution hence why I posted my question here on StackOverflow.

    After no better answer here I posted on the Composer forum as a feature request and had the request closed because "where code is installed in most cases should not matter." It's sad that some people feel that what they value are the only things worth valuing.

    Since it seems like there's no official way to do this and no interest on behalf of the Composer team to make it easier I decided to go ahead and post my solution in case others are beating their head against the wall in same way. It's ugly but it works.

    Instead of referencing a Git repo create an "inline package" for each repo; here's what it looks like (NOTE: I added '#' comments which are of course not valid JSON but only here to callout what I changed.):

    {
      "name":"mikeschinkel/my-wp-plugin",
      "description":"My WordPress Plugin",
      "type":"wordpress-plugin",
      "config":{
        "vendor-dir":"libraries"
      },
      "require": {
        "restian":"dev-master",  # Short name 'restian' used here.
        "sidecar":"dev-master"   # Short name 'sidecar' used here.
      },
      "repositories":[
        {
          "type":"package",      # type=package vs. type=git
          "package":{
            "name":"sidecar",    # Short name 'sidecar' used here.
            "version":"dev-master",
            "source":{           # This could be "dist" or "source"
              "type":"git",
              "url":"https://github.com/newclarity/sidecar",
              "reference":"master"
            }
          }
        },
        {
          "type":"package",      # type=package vs. type=git
          "package":{
            "name":"restian",    # Short name 'restian' used here.
            "version":"dev-master",
            "source":{           # This could be "dist" or "source"
              "type":"git",
              "url":"https://github.com/newclarity/restian",
              "reference":"master"
            }
          }
        }
      ]
    }
    

    Given that I'm new to Composer there might be numerous ways I could improve this; any suggestions are welcome. Either way I hope this helps others trying to achieve the same goal.