Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composer, Laravel and local packages

My issue is I have a package which isn't a repository and I am trying to get it to play nice with Laravel and composer. It is still located under the vendor folder, the only issue is that if I simply set:

"psr-0": {
        "Test\\Test": "vendor/test/test/src/"
    }

This will load the service provider but none of the controllers etc will autoload. What is the correct way to implement a package with larval that does not have it's own repository. Or does this go against the nature of packages and this should simply be structured under the applications controllers.

The package was created by me using workbench but I found i did not really need this as a separate repository but it would still be good to keep it as a package. Therefore the structure is exactly the same as a regular package:

vendor
    testvendor
        testpackage
            public
            src
            tests
            .gitignore
            composer.json
            phpunit.xml

UPDATE:

As a solution for the time being I am using:

"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php",
        "vendor/package"
    ]
},

As an entry in the class map. Looking forward I will probably refactor this into the app folder or create a repository for this package.

like image 213
Hard-Boiled Wonderland Avatar asked Mar 19 '14 14:03

Hard-Boiled Wonderland


2 Answers

If you have some classes that you're calling "package", you're not supposed to add those files to your vendor folder. This folder is managed by composer and at any time you might loose it. Create a subfolder in your application and put those files there.

You have to be sure your PSR-0 autoloading will work for every single file in your folder structure. So, if your root is vendor/test/test/src/ and your namespace is

Test\\Test

All your files must be in

vendor/test/test/src/Test/Test/ClassFileName.php

PSR-4 is easier to deal and understand, this

"psr-4": {
    "Test\\Test\\": "vendor/test/test/src/"
}

Means that your files would have to be like:

vendor/test/test/src/ClassFileName.php

Doublecheck your namespaces. It's easy to make mistakes when using namespaces with PSR-0 and remember that

composer dump-autoload

Must be ran every time you change things in composer.json or create new files. If it's a simple class autoloading, every time you create a file, if it's a PSR-X autoloading, everytime you create or update a namespace in your composer.json file.

If what you have is is really a package you should use Composer: when your package is structured as a composer package (check Laravel's composer.json as an example), the correct way of adding it to your application, if it's not list in Packagist, is via repositories.

You can have (non-packagist) packages in a public VCS repository:

{
    "require": {
        "monolog/monolog": "dev-bugfix"
    },

    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/igorw/monolog"
        }
    ]
}

You can have (non-packagist) packages in a protected by password VCS repository (git, bitbucket...):

{
    "require": {
        "vendor/my-private-repo": "dev-master"
    },
    "repositories": [
        {
            "type": "vcs",
            "url":  "[email protected]:vendor/my-private-repo.git"
        }
    ]
}

You can have your packages zipped in your hard drive and load them via the artifact repository type:

"repositories": [
    {
        "type": "artifact",
        "url": "path/to/directory/with/zips/"
    }
],
like image 102
Antonio Carlos Ribeiro Avatar answered Oct 02 '22 02:10

Antonio Carlos Ribeiro


Though @Antonio Carlos Ribeiro's answer is really nice, I had problem with installing custom packages locally(which is also stated in the last part of his answer)

Let's assume this is the directory structure of the package we are trying to install:

D:/test_pack
    src/
    composer.json

If you do not want to upload your custom package (that most likely you have developed, yourself) to online repositories you can use one of the following two methods:

Method I

(You have to specify version for your package, otherwise you'll get this error: The requested package could not be found in any version, there may be a typo in the package name.)

1) In composer.json, Add version to your package. your package's json should look something like this:

{
"name": "gandalf/test_pack",//This is your package's name
"description": "some desc",
"version": "1.0.0",//This is the version that you have to specify
"authors": [
    {
        "name": "gandalf the grey",
        "email": "[email protected]"
    }
],
"minimum-stability": "dev",
"require": {
    "laravel/framework": "~5.4"
},
"autoload": {
    "psr-4": {
        "Gandalf\\BotPack\\": "src/"
    }
} }

2) zip your package(let's assume the zip file is in D:/test_pack/test_packa.zip)

3) In laravel's composer.json add your package name (in our case gandalf/test_pack into require part of json) and add the repository array to the composer.json file and in that array specify the directory in which your package's zip file exists(in our case D:/test_pack) . like this

{
    ...,
    "require": {//adding our package name to laravel's composer.json
        ...,
        "gandalf/test_pack": "*"//package's name
    },
    ...,

    "repositories": [
        {
            "type": "artifact",
            "url": "D:/test_pack"
        }
    ]
}

Method II(My Favorite method, You have to initialize your package directory as git local repository using git init and then git add . and git commit -m "your message")

1) initialize the package directory as git directory and commit all your changes to the local repository

(let's say D:/test_pack is the directory that contains your package(src/ directory and composer.json))

go to D:/test_pack directory and run these commands

git init
git add .
git commit -m "your message for this commit"

2) In your packages composer.json file add minimum-stability

    {
        "name": "gandalf/test_pack",
        "description": "some desc",
        "authors": [
            {
                "name": "gandalf the grey",
                "email": "[email protected]"
            }
        ],
        "minimum-stability": "dev",//setting minimum-stability
        "require": {
               //dependencies that your package needs
        },
        "autoload": {
            "psr-4": {
                "Gandalf\\BotPack\\": "src/"
            }
        }
    }

3)In laravel's composer.json file require the "dev-master" of your package

{
    ...,
    "require": {
        ...,//some dependencies that laravel needs
        "gandalf/test_pack": "dev-master"//requiring dev-master from repository
    },

    "repositories": [
        {
            "type": "git",
            "url": "D:/test_pack"//path of the local repository directory which contains your package
        }
    ]
}
like image 43
Cid Avatar answered Oct 02 '22 01:10

Cid