DEV Community

temori1919
temori1919

Posted on

Let's make a Composer packages - chapter.1

Introduction

I'm sure no one is using PHP and hasn't taken care of Composer, but it's an article for people who want to publish their own packages, not just the ones that are published.

I hope it helps people who want to do OSS activities but are wondering what the specific steps are.: Blush:
(* I haven't released the package so far, so I'd be happy if you could give me some advice.)

temori/distancexport
Alt Text
The above package edits the migration destination column and migration source column in spreadsheet format when data needs to be migrated between DBs or data with different table names or column names is migrated. I created it because I thought it would be convenient if possible.

final goals

We will publish it to packagist and aim to install the package with composer require [package name].

Environment

The development environment is always prepared with docker.
I think you can develop it in your favorite environment.

By the way, I am developing in the environment of the following repository.
temori1919/docker-lamp

Project creation

First, create a directory for packages.
At a minimum, I think the following directory structure is fine.

I have created directories under the package directory withvendor name and package name, but I think it doesn't matter if the root directory is the package name.

package
└── vendorname
    └── Package name
        ├── LICENSE
        ├── README.md # Since it describes the outline of the package, you can create it after it is completed.
        ├── composer.json # This file is generated by the composer command described later.
        ├── .gitignore # Create any files you want to exclude from git
        ├── src # Directory to store the package source
        └── tests # Directory to store test code (OK without it)
Enter fullscreen mode Exit fullscreen mode

After creating the directory, create composer.json with thecomposer init command.

It's the usual that file that defines an external package.

$ cd path/to/package/vendorname/packagename

Execute the # command to start creating the file interactively
$ composer init

  Welcome to the Composer config generator

This command will guide you through creating your composer.json config.

#Enter the vendorname/package name and enter (what you enter here will be the vendorname/package name when you publish it externally)
Package name (<vendor>/<name>) [some/mypackage]:
# Describes the outline of the package, but it can be blank. (It will be displayed in the outline of packagist described later)
Description []:
#Producer, it's okay to skip with n
Author [some <some@address.com>, n to skip]:
#Minimum stability, Enter as it is is no problem
# This is the place to describe the stability of the package to be created.
# By default, "stable" can only be used with "dev", "alpha", "beta", "RC", and "stable".
Minimum Stability []:
#Package type, just enter OK
#The default is "library" (the type installed under vendor), and there are also "project", "metapackage", and "composer-plugin".
Package Type (e.g. library, project, metapackage, composer-plugin) []:
#License type (Please specify the license that suits your purpose)
License []:
# Find the package you plan to use
# I don't plan to use it for the time being, so just enter
Would you like to define your dependencies (require) interactively [yes]?
Search for a package:
#This is the above dev package
# If you plan to use it, you can search here, but you can add it later, so enter it for the time being.
Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:

It will be a confirmation of the contents described in the # command
# If there is no problem, Enter (you can also modify the file directly later)
{
    "name": "some/mypackage",
    "license": "MIT",
    "require": {}
}

Do you confirm generation [yes]?
Enter fullscreen mode Exit fullscreen mode

I think you have composer.json directly under the package directory.

mypackage/composer.json
Enter fullscreen mode Exit fullscreen mode

The directory is now ready.

Implement package processing

Creating directories and dummy projects

Create classes and methods under the src directory.

When developing a package, composer require the package in the local directory and proceed with the development.

First, create a dummy project to install the package to be developed.
It will be in the same level as the package directory created earlier.

├── package
└── dummy-project
Enter fullscreen mode Exit fullscreen mode
  • There is no problem in creating a project using FW.

Go to the created project, create composer.json and add the following.

  • If you created a project using FW, add it to the already placed composer.json.
cd dummy-project
Enter fullscreen mode Exit fullscreen mode
    "repositories": [
        {
            "type": "path",
            "url": "../package/vendorname/packagename"
        }
    ]
Enter fullscreen mode Exit fullscreen mode

Now with the vendor/packagename you specified for composer in it

composer require vendorname/packagename
Enter fullscreen mode Exit fullscreen mode

Type the command and the local directory will be installed as a package.

You can change the installation destination by changing the type ofcomposer.json. If repositories is not specified, the default will search for packages from packagist.
It is possible to change the installation destination such as reading from a local directory with path and installing directly from a repository hosting service such as github with vcs.

See below for details.

https://getcomposer.org/doc/05-repositories.md#types

Installing with type set topath will generate a symbolic link to the local package directory in the vendor directory containing the packages in the installed project.

When coding a package, if you change the package under vendor in the project, it will be reflected in the source of the package directory created in the same hierarchy as the project, so when using the IDE, code jump etc. will occur. It's convenient.

Creating classes and methods

By the way, I am creating the main class with the package name.

With this package, the name and structure are as follows.

├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml
├── resources
│ ├── assets
│ │ ├── css
│ │ │ ├── jexcel.css
│ │ │ └── jsuites.css
│ │ └── js
│ │ ├── jexcel.js
│ │ └── jsuites.js
│ └── views
│ └── index.php
├── src
│ ├── DataBases
│ │ ├── BaseDriver.php
│ │ ├── Connect.php
│ │ └── Drivers
│ │ ├── Mysql.php
│ │ └── Pgsql.php
│ ├── Distancexport.php
│ ├── Provider.php
│ └── Renders
│ └── AssetResponse.php
└── tests
    └── DistancexportTest.php
Enter fullscreen mode Exit fullscreen mode

Distancexport.php is the class file that is the starting point of the package.

Also, the resources directory is created because it was necessary to draw a view for this package.

After creating the class, add the autoload setting to the package composer.json.

{
    "name": "some / mypackage",
    "license": "MIT",
    "require": {},
    "autoload": {
        "psr-4": {
            "Some\\Mypackage\\":"src/",
            "Some\\Tests\\":"tests/"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This will autoload the src subordinate in the Some\Mypackage namespace.

As for tests, it is assumed that the test code is stored under the directory, so it will be autoloaded in the namespace of Some\Tests.

Also, although it is a namespace that is named when creating a class, the file cannot be read unless it is the namespace set by autoloading.

The namespace described in composer.json must be added to the file that describes the namespace to be implemented in the package.
(* In the above example, Some\Mypackage\ClassName)

If you need an external package, describe it in require and it will be installed when youcomposer require or install on the project side.

Make a README.md

Create a README.

I mainly describe the following items.

  • package name --Badges that display versions, licenses, etc. It's easy to understand visually, and above all, it's cool: smiley:
  • Overview Describe the outline of the package --If the package has a UI, gif animations and images If you have a UI, it would be easier to understand if you had an image. It may also be the created image.
  • table of contents Place a table of contents with links for each heading.
  • Characteristic It is a feature of the package. --Requirements It will be the place to describe the corresponding version etc. --How to install How to install the package. Describe with a command so that you can copy and paste. --How to use --License

The package released this time has the following items.
https://github.com/temori1919/distancexport/blob/master/README.md

I used the following services for badges.

shields

You can easily create badges with packages published on packegist.

Of course, some badges can be created even if they are not published.

Alt Text

The above is the version of packagist, but if you enter the published vendor name and package name, the URL will be generated with md or html.

As for the version, it can be generated only after it is published to packagist, so I think that it will be created after publishing the package and tagging the version described later.

You can also change the style and wording of the badge.

Create a repository on GitHub and push

Let's push the source to the repository.
Create a LICENSE file after pushing.

Click Create new file to create a new file on GitHub.
If you enter LICENSE in the file name, you will be able to select the license file template.
Alt Text

After that, select the license that suits your purpose and generate the file.

Specify the version with ## tag
I think that the following tag creation screen will be displayed by tags->Create a new release, so I will generate tags.

Alt Text

Specify Tag version.

I try to start from v1.0.0.
It doesn't matter with or without v.

composer recognizes it as a version even with v.

The Target branch is selected next to theTag version, but the current latest commit of the master branch is the this tagged version.

If there is a title, detailed contents, etc., there is no problem even if it is not described.

Publish to packagist

Finally, publish the GitHub repository to packagist.

If you do not have an account, please create one.
You can also log in with your GitHub account.

Alt Text

Display the page to submit the package from the Submit button in the header.

Enter the URL of the repository in Repository URL and press the Check button.

The GitHub repository and packagist are now linked.
Tag information added on GitHub will also be linked as a package version of packagist.

The README.md added to the repository is also reflected in the package TOP page of packagist.

Register the packagist api token on the GitHub webhook

Register the URL of the packagist api on the GitHub webhook.

By utilizing Webhook, when you update the repository of GitHub, you will be able to automatically reflect the change on the packagist side.

Alt Text

Press Show API Token to show the token.
Click the the docs link below it to see how to register your GitHub webhook.

Register WebHook on GitHub using the token that displays the URL described in the above document.

Alt Text

Enter as described in the documentation.

This completes all the work involved in the release.

Finally

If you follow the steps, I don't think publishing a package is such a high hurdle.

Next time, I will continue with the procedure to publish the Laravel package.

Let's make a Composer packages - chapter.2 -- Laravel package

Top comments (0)