I am trying to setup a composer project that will enable me to setup my own framework and pulling out any given dependency stored in github private repos.
First some prerequisites:
I don't want to add code to packagist.
I want to make sure my vendor folder is as clean as possible.
Framework composer.json
{
"name": "mycompany/myframework",
"description": "YET another Framework",
"type": "project",
"repositories": [
{
"type": "package",
"package": {
"name": "mycompany/system",
"version": "0.0.2",
"type": "library",
"source": {
"url": "https://github.com/mycompany/system.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"mycompany/system": "0.0.2",
"mnsami/composer-custom-directory-installer": "1.1.*"
},
"license": "proprietary",
"authors": [...],
"extra":{
"installer-paths":{}
}
}
mycompany/system composer.json
{
"name": "mycompany/system",
"type": "library",
"description": "utility belt xD"
}
The code for the class in PHP ( from mycompany/sytem ) has the following structure:
namespace MYCOMPANY;
//this file name is called utils.php
//adherence to PSR-4 is assumed
class utils {
}
My goal is:
I want to tell composer that it should create the following structure :
vendor \ MYCOMPANY \ utils.php ( not vendor \ mycompany \system \utils.php )
Later on, I want to be able to add more repositories like this and store them under MYCOMPANY as well. The framwework will work around this setup.
Custom installation is handled by mnsami/composer-custom-directory-installer
I'm guessing I should keep, by rule of thumb, the different packages in their own directories, but, since there is no risk of overwriting because other files will have a different naming convention.
Edit
Can this be done?
If so, how?
Thank you in advance
After some hours of work and following on #NicoHaase's reply in the comments, I gave up on this issue.
I was trying to make a clean folder where I would put all the different classes from different repos, but composer just doesn't work that way.
I hope this will help others that want the same thing.
Related
I am in the midst of learning how to better maintain the code that I write. I have two projects that I am currently working on - both are in development and both are pushed to GitHub.
I am trying to include the one project in the other (by declaring it a dependency in the one project's composer.json file) - but after it is included, it is missing the proper autoload configurations.
I'll explain a little better: Project A's composer.json file has an autoload line for "psr-4" mapping the namespace to the "src" directory - all is good and working after I run:
composer install
I am then able to include the /vendor/autoload.php file and immediately start working with the project. When I look at the generated "autoload_psr4.php" file in that project's vendor directory, I can see the array contains a reference for the mapped namespace / directory per the composer.json file.
The problem comes when I try to include Project A within Project B as a dependency - everything looks to work after running the composer install - the vendor directory is created and the files are copied there - however when I look at the generated "autoload_psr4.php" file in project B it is missing the mapped namespace / directory per Project A's composer.json file.
Can someone point me in the direction for what I might be missing to get the autoload line to carry over into Project B?
Here's the two composer.json files:
Project A:
{
"name": "jfreynik/hydra-net",
"description": "Network classes for the Hydra framework.",
"type": "library",
"keywords": [ "http", "net", "rest" ],
"license": "MIT",
"require": {
"php": ">=5.3.0"
},
"autoload": {
"psr-4": {
"hydra\\net\\": "src/"
}
}
}
Project B:
{
"name": "jfreynik/simple-mvc",
"description": "A pretty simple MVC framework for building websites.",
"type": "framework",
"keywords": [ "MVC", "Website Framework" ],
"license": "MIT",
"repositories": [
{
"type":"package",
"package": {
"name": "jfreynik/hydra-net",
"version":"*-dev",
"source": {
"url": "https://github.com/jfreynik/hydra-net.git",
"type": "git",
"reference":"master"
}
}
}
],
"require": {
"jfreynik/hydra-net": "*-dev"
},
"minumum-stability": "dev"
}
Thank You!
The issue was that I was including Project A into Project B as a "package". I believe "packages" are not scanned for their contained composer.json files. (please correct me if I'm wrong) - by changing Project B's composer.json file to reference Project A as "vcs" then the autoloading works again. - Here is the adjusted composer.json file for Project B.
{
"name": "jfreynik/simple-mvc",
"description": "A pretty simple little MVC framework for building websites.",
"type": "framework",
"keywords": [ "MVC", "Website Framework" ],
"license": "MIT",
"repositories": [
{
"type":"vcs",
"url": "https://github.com/jfreynik/hydra-net"
}
],
"require": {
"jfreynik/hydra-net": "dev-master"
},
"minumum-stability": "dev"
}
I really had trouble finding working examples as I am really just starting to use composer and prior to this had only included professional packages from packagist. I have much to learn (even in regard to terminology) - so if anyone can add additional relevant information for the proper way to include 1 development project in another I will accept your answer.
So, I'm trying to use jcleblanc/reddit-php-sdk, but it follows no standards whatsoever and does not have a repository available, so I've had to manually define it myself in my composer.json file:
"repositories" : [{
"type": "package",
"package": {
"name": "jcleblanc/reddit-php-sdk",
"version": "dev-master",
"source": {
"url": "https://github.com/jcleblanc/reddit-php-sdk",
"type": "git",
"reference": "origin/master"
},
"autoload": {
"classmap": ["reddit-php-sdk/", "/", "reddit.php", "config.php"]
}
}
}],
Directory structure in vendor/ here:
However, when I then run composer dump-autoload, the classes in this project are not autoloaded, and don't appear in any of the autoload_*.php composer files. This means I of course get a "Class 'reddit' not found" error whenever I try and use it.
Solutions?
You can use Composer's file autoloading.
{
"autoload": {
"files": ["src/MyLibrary/functions.php"]
}
}
However, that's more geared towards helper function files and I've not tried it with a Class file (although there's no reason it shouldn't work).
Ended up forking the project myself, but it turns out the original project is broken anyway.
My compsoser.json uses 2 private repositories from our Organisation Github Account and is as follows.
{
"name": "API",
"repositories": [
{
"type": "vcs",
"url": "git#github.com/company/private.git"
},
{
"type": "vcs",
"url": "git#github.com/company/private2.git"
}
],
"require": {
"php": ">=5.3.3",
"zendframework/zendframework": ">2.1.3",
"doctrine/mongodb-odm": "dev-master",
"doctrine/doctrine-mongo-odm-module": "dev-master",
"company/private": "dev-master",
"company/private2": "dev-master"
}
}
We've setup SSH keys and added them to the authorized keys on our staging server. When we run git clone it works perfectly and isn't asking for any credentials.
However, when we run composer update the fetching of the repositories fails because composer doesn't have access to the repositories.
Since this is ran in a non-interactive way as this is part of a build script we can't enter credentials and like to have this automated.
What can we do to let composer have access to our private repo's during the build?
I understand the question title specifically mentions using type 'vcs' but this is an alternate method of using private git repos to deploy a project as a package.
"repositories": [
{
"type": "package",
"package": {
"name": "company/private",
"version": "0.1.0",
"type": "package",
"source": {
"url": "git#github.com:/company/private.git",
"type": "git",
"reference": "master"
}
}
}
],
"require": {
"company/private": "*"
}
The limitation is that you must manually change the version number every time you deploy if you want the latest version. However, this is also its advantage.
Defining a repo in this way will allow you to pull a specific tagged version. In this case the commit with tag 0.1.0 will be pulled on composer update.
You will need to add the SSH keys of the server you are deploying to in your github account.
You can configure composer to use key files to access private repository.
More info: https://getcomposer.org/doc/articles/handling-private-packages-with-satis.md#security
The URLs in your original question are missing a colon:
"url": "git#github.com/company/private.git"
should be
"url": "git#github.com:/company/private.git"
I just had the same problem and this fixed it.
"name": "{vendor}/{package-name}",
"repositories": [
{
"type": "package",
"package": {
"name": "{vendor}/{package-name}",
"version": "{arbitrary-version}",
"type": "package",
"source": {
"url": "git#github.com:{github-username}/{github-repository}.git",
"type": "git",
"reference": "{branch}"
}
}
}
]
"require": {
"{vendor}/{package-name}": "*"
}
I really appreciated the answers and guidance; however, could not get the solution to work for me. And, I think the answer could possibly use some added detail with regard to what appears to be going on here.
vendor: The vendor name used in the package's composer.json.
package-name: The package name user in the package's composer.json.
arbitrary-version: A random version number; does not need to exist as a version in GitHub.
github-username: The GitHub user account where the repo lives.
github-repository: The GitHub repository name.
branch: The GitHub branch to use when checking out the code.
The two things that gave me the greatest issue was the colon (:) does not (should not?) be followed by a forward slash (/). Don't forget to put .git at the end of the url.
Points of conjecture and uncertainty:
I'm not sure what would happen if you change the package.name member to something incorrect. In other words, I don't know if this is an internal reference for require alone; or, if there will be something else happening there.
I'm not sure if the branch actually changes anything and I'm not in a position to test.
I've read other questions about this topic and I just can't seem to get this to work. I'm trying to get a download of cforms as a custom package to install into wp-content/plugins/cforms. I've gotten this to work for the other packages that wpackagist supplies, and even some custom plugins developed in-house.
Here's what I have:
{
"name": "mycompany/wordpress-install",
"description": "Themes and plugins for our wordpress install.",
"authors": [
{
"name": "Me",
"email": "example#example.net"
}
],
"require": {
"deliciousdays/cforms": "14.5.2"
},
"repositories": [
{
"type": "package",
"package": {
"name": "deliciousdays/cforms",
"version": "14.5.2",
"dist": {
"url": "http://www.deliciousdays.com/download/cforms-v14.5.zip",
"type": "zip"
}
}
}
],
"extra": {
"installer-paths": {
"wp-content/plugins/cforms": ["deliciousdays/cforms"]
}
}
}
It's downloading cforms fine, but it's still putting it into vendor/deliciousdays/cforms when I want it in (obviously) wp-content/plugins/cforms. What am I doing wrong?
Try using this composer.json, it includes Wordpress (v3.9 as of right now).
It uses fancyguy/webroot-installer to install to certain directories.
This file is meant to be in the root wordpress directory. The extra section shows the "webroot-dir" to be "."; This will install into current directory, (Do not use "/" or "./"), if you would like it to install into a specific directory simply change "." to the name of the directory you'd like to install to.
"extra": {
"webroot-dir": ".",
"webroot-package": "wordpress"
}
So after running this file you should have the normal wordpress structure with cforms placed in the wp-content/plugins directory, to install a theme, you can copy the cforms section and change the type to "wordpress-theme" to have it installed into the themes directory.
I'm by no means an expert with composer, but I was able to get this working correctly.
{
"name": "mycompany/wordpress-install",
"description": "Themes and plugins for our wordpress install.",
"authors": [
{
"name": "Me",
"email": "example#example.net"
}
],
"repositories": [
{
"type": "composer",
"url": "http://wpackagist.org"
},
{
"type": "package",
"package": {
"name": "wordpress",
"type": "webroot",
"version": "3.9",
"dist": {
"type": "zip",
"url": "https://github.com/WordPress/WordPress/archive/3.9.zip"
}
}
},
{
"type": "package",
"package": {
"name": "cforms",
"type": "wordpress-plugin",
"version": "14.5.2",
"dist": {
"url": "http://www.deliciousdays.com/download/cforms-v14.5.zip",
"type": "zip"
}
}
}
],
"require": {
"php": ">=5.3.0",
"composer/installers": "~1.0",
"wordpress": "3.9",
"fancyguy/webroot-installer": "1.0.0",
"wpackagist/wordpress-seo": "*",
"cforms": "14.5.2"
},
"extra": {
"webroot-dir": ".",
"webroot-package": "wordpress"
}
}
Note that using wpackagist, you can view a list of installable plugins/themes at these links:
http://plugins.svn.wordpress.org/
http://themes.svn.wordpress.org/
If you would like to include plugins from the Wordpress Plugin Respository, you can add them in easily. For instance, if you wanted to add the Yoast Wordpress SEO plugin, you would add the following to require (Note that you need to know the slug of the plugin to add it):
"require": {
"php": ">=5.3.0",
"composer/installers": "~1.0",
"wordpress": "3.9",
"fancyguy/webroot-installer": "1.0.0",
"wpackagist/wordpress-seo": "*",
"cforms": "14.5.2"
}
Finally figured it out after trying lots of different things. I think I was missing two things:
In the package declaration I changed it to have the "type": "wordpress-plugin", and then in the requires I had to add "composers/installers": "~1.0" like so (also note that the extra was removed entirely):
{
"name": "mycompany/wordpress-install",
"description": "Themes and plugins for our wordpress install.",
"authors": [
{
"name": "Me",
"email": "example#example.net"
}
],
"require": {
"composer/installers": "~1.0.0",
"deliciousdays/cforms": "14.5.2"
},
"repositories": [
{
"type": "package",
"package": {
"name": "deliciousdays/cforms",
"version": "14.5.2",
"type": "wordpress-plugin",
"dist": {
"url": "http://www.deliciousdays.com/download/cforms-v14.5.zip",
"type": "zip"
}
}
}
]
}
I still have been unable to figure out how to get a custom package to install to a directory of my choosing even with the composer/installers require in there. It just seems to ignore everything until I've added a type to the object, and then it forces it to download into the location defined by that type, based on how composer/installers decided to map it.
But I think this will work for now... If anyone knows how to make it download into, say, "myfolder/something/cforms" I'll accept your answer.
it happens I have got an answer for you, because I ran into the same problem. Clearly, there is a big demand now to custom install packages.
The composer/installers ONLY work on defined frameworks and CMS(s), but doesn't work for normal composer packages.
I have implemented this composer plugin to install packages into user (custom) defined folders you can just include it in your composer.json, follow the example and tell me if you have more questions :)
https://github.com/mnsami/composer-custom-directory-installer
composer-custom-directory-installer
A composer plugin, to install differenty types of composer packages in custom directories outside the default composer default installation path which is in the vendor folder.
This is not another composer-installer library for supporting non-composer package types i.e. application .. etc. This is only to add the flexability of installing composer packages outside the vendor folder. This package only supports composer package types,
https://getcomposer.org/doc/04-schema.md#type
The type of the package. It defaults to library.
Package types are used for custom installation logic. If you have a package that needs some special logic, you can define a custom type. This could be a symfony-bundle, a wordpress-plugin or a typo3-module. These types will all be specific to certain projects, and they will need to provide an installer capable of installing packages of that type.
How to use
Include the composer plugin into your composer.json require section::
"require":{
"php": ">=5.3",
"mnsami/composer-custom-directory-installer": "1.1.*",
"monolog/monolog": "*"
}
In the extra section define the custom directory you want to the package to be installed in::
"extra":{
"installer-paths":{
"./monolog/": ["monolog/monolog"]
}
by adding the installer-paths part, you are telling composer to install the monolog package inside the monolog folder in your root directory.
As an added new feature, we have added more flexibility in defining your download directory same like the composer/installers, in other words you can use variables like {$vendor} and {$name} in your installer-path section:
"extra": {
"installer-paths": {
"./customlibs/{$vendor}/db/{$name}": ["doctrine/orm"]
}
}
the above will manage to install the doctrine/orm package in the root folder of your project, under customlibs.
Note
Composer type: project is not supported in this installer, as packages with type project only make sense to be used with application shells like symfony/framework-standard-edition, to be required by another package.
I've added my own repository to a Composer, it download properly into my another project.
Unfortunately Composer doesn't take my repository code under consideration while updating autoloading.
autoload_namespaces.php has many namespaces generated but any of them is my repository code.
I could add namespaces in my "autoloading" section in composer.json or I could also add it in PHP using Autoloader9287463497853476 object but those solutions (ideologically equal) doesn't interest me.
How can I force my Composer to generate autoloading for my repository code also?
If you add your package using the repository section of composer.json, i would sugest you to include there the code for autoload, as i used here:
"repositories": [
{
{
"type": "package",
"package": {
"name": "brand/name",
"type": "library",
"version": "1.0.0",
"dist": {
"url": "file:///path-to-file.zip",
"type": "zip",
"reference": "XXXX"
},
"autoload": {"psr-0": { "Name\\Space\\": "dest-folder" }
},
}
}
I hope it helps.