Open-source News

Use Composer to require Git repositories within PHP projects

opensource.com - Mon, 05/16/2022 - 15:00
Use Composer to require Git repositories within PHP projects Jonathan Daggerhart Mon, 05/16/2022 - 03:00 Register or Login to like Register or Login to like

The dependency management tool Composer provides multiple ways to include Git repositories within a PHP: Hypertext Preprocessor (PHP) project.

In many cases, repositories have been created on Packagist, so requiring them with Composer is very straightforward. But what do you do when a repository has not been created as a package on Packagist? You use Composer to require the package directly from the repository. This article explains how.

Note: Some of the terminology in this post is confusing because multiple words are used to describe different things. Here is a quick vocabulary list that will help:

  • Project: The custom software you are building. This can be a website, a command-line utility, an application, or anything else you dream up.
     
  • Package: Any third-party software you want to download and use within your project. It can be a library, Drupal theme, WordPress plugin, or any other number of things.
     
  • Git repository: Also called the Git repo, this is the version-control host for a package. Common hosts include GitHub, GitLab, or Bitbucket, but any URL-accessible Git repository will work for this tutorial.
     
  • Composer repositories: In a composer.json file, there is an optional property named "repositories." This property is where you can define new places for Composer to look when downloading packages.

When adding a Git repo to your project with Composer, you can find yourself in two situations: Either the repo contains a composer.json file, which defines how the repo should be handled when required, or it does not. You can add the Git repository to your project in both cases, with different methods.

Git repo with composer.json

When a repository includes a composer.json file, it defines aspects of itself that are important to how Composer manages the package. Here is an example of a simple composer.json file a package may include:

{ "name": "mynamespace/my-custom-library", "type": "library" }

This example shows two important properties that a composer.json file can define:

  • Name: The package's namespaced name. In this case, "mynamespace" is the namespace for the package "my-custom-library."
  • Type: The type of package the repo represents. Package types are used for installation logic. Out of the box, Composer allows for the following package types: library, project, metapackage, and composer-plugin.

You can verify this by looking at the composer.json file of any popular GitHub project. They each define their package name and the package type near the top of the file. When a repository has this information defined in its composer.json file, requiring the repository within your project is quite simple.

More on Git What is Git? Git cheat sheet Markdown cheat sheet New Git articles Require a Git repository that has a composer.json file

After you've identified a Git repository with a composer.json file, you can require that repository as a package within your project.

Within your project's composer.json file, you need to define a new property (assuming it doesn't exist already) named "repositories." The value of the repositories property is an array of objects, each containing information about the repository you want to include in your project. Consider this composer.json file for your custom project.

{ "name": "mynamespace/my-project-that-uses-composer", "repositories": [ { "type": "vcs", "url": "https://github.com/mynamespace/my-custom-library.git" } ], "require": { "mynamespace/my-custom-library": "dev-master" } }

You are doing two important things here. First, you're defining a new repository that Composer can reference when requiring packages. And second, you're requiring the package from the newly defined repository.

Note: The package version is a part of the require statement and not a part of the repository property. You can require a specific branch of a repo by choosing a version named "dev-".

If you were to run composer install in the context of this file, Composer would look for a project at the defined URL. If that URL represents a Git repo that contains a composer.json file that defines its name and type, Composer will download that package to your project and place it in the appropriate location.

Custom package types

The example package shown above is of the type "library," but with WordPress and Drupal you're dealing with plugins, modules, and themes. When requiring special package types in your project, it's important to install them in specific locations within the project file structure. Wouldn't it be nice if you could convince Composer to treat these types of packages as special cases? Well, you're in luck. There is an official Composer plugin that will do that for you.

The Installers plugin for Composer contains the custom logic required for handling many different package types for a large variety of projects. It is extremely helpful when working with projects that have well-known and supported package installation steps.

This project allows you to define package types like drupal-theme, drupal-module, wordpress-plugin, wordpress-theme, and many more, for a variety of projects. In the case of a drupal-theme package, the Installers plugin will place the required repo within the /themes/contrib folder of your Drupal installation.

Here is an example of a composer.json file that might live within a Drupal theme project as its own Git repository:

{ "name": "mynamespace/whatever-i-call-my-theme", "type": "drupal-theme", "description": "Drupal 8 theme", "license": "GPL-2.0+" }

Note that the only meaningful difference here is that the type is now drupal-theme. With the drupal-theme type defined, any project that uses the Installers plugin can easily require your repo in its Drupal project, and it will be treated as a contributed theme.

Require any Git repository with Composer

What happens when the repo you want to include in your project does not define anything about itself with a composer.json file? When a repo does not define its name or type, you have to define that information for the repo within your project's composer.json file. Take a look at this example:

{ "name": "mynamespace/my-project-that-uses-composer", "repositories": [ { "type": "package", "package": { "name": "mynamespace/my-custom-theme", "version": "1.2.3", "type": "drupal-theme", "source": { "url": "https://github.com/mynamespace/my-custom-theme.git", "type": "git", "reference": "master" } } } ], "require": { "mynamespace/my-custom-theme": "^1", "composer/installers": "^1" } }

Notice that your repository type is now "package." That is where you will define everything about the package you want to require.

Create a new object named "package" where you define all the essential information that Composer needs to know to be able to include this arbitrary git repo within your project, including:

  • Name: The namespaced package name. It should probably match the repository you're requiring but doesn't have to.
  • Type: The type of package. This reflects how you want Composer to treat this repository.
  • Version: A version number for the repo. You will need to make this up.
  • Source: An object that contains the following repository information:
    • URL: The Git or other version-control system (VCS) URL where the package repo can be found
    • Type: The VCS type for the package, such as git, svn, cvs, and so on
    • Reference: The branch or tag you want to download

I recommend reviewing the official documentation on Composer package repositories. Note that it is possible to include zip files as Composer packages as well. Essentially, you are now responsible for all parts of how Composer treats this repository. Since the repository itself is not providing Composer with any information, you are responsible for determining almost everything, including the current version number for the package.

This approach allows you to include almost anything as a Composer package in your project, but it has some notable drawbacks:

  • Composer will not update the package unless you change the version field.
     
  • Composer will not update the commit references. If you use master as a reference, you will have to delete the package to force an update, and you will have to deal with an unstable lock file.
Custom package versions

Maintaining the package version in your composer.json file isn't always necessary. Composer is smart enough to look for GitHub releases and use them as the package versions. But eventually you will likely want to include a simple project that has only a few branches and no official releases.

When a repository does not have releases, you will be responsible for deciding what version the repository branch represents to your project. In other words, if you want composer to update the package, you will need to increment the "version” defined in your project's composer.json file before running composer update.

Overriding a Git repository's composer.json

When defining a new Composer repository of the type package, you can override a package's own composer.json definitions. Consider a Git repository that defines itself as a library in its composer.json, but you know that the code is actually a drupal-theme. You can use the above approach to include the Git repository within your project as a drupal-theme, allowing Composer to treat the code appropriately when required.

Example: Require Guzzle as a drupal-theme just to prove that you can.

{ "name": "mynamespace/my-project-that-uses-composer", "repositories": [ { "type": "package", "package": { "name": "mynamespace/guzzle-theme", "version": "1.2.3", "type": "drupal-theme", "source": { "url": "https://github.com/guzzle/guzzle.git", "type": "git", "reference": "master" } } } ], "require": { "mynamespace/guzzle-theme": "^1", "composer/installers": "^1" } }

This works! You've downloaded the Guzzle library and placed it within the /themes folder of your Drupal project. This is not a very practical example, but it highlights how much control the package type approach provides.

Summary

Composer offers plenty of options for including arbitrary packages within a project. Determining how those packages are included in the project primarily comes down to who defines the package information. If the Git repository includes a composer.json file that defines its name and type, you can have Composer rely on the repository itself for the definition.

But if you want to include a repository that does not define its name and type, then it is up to your project to define and maintain that information for your own internal use. Alternatively, if a repository doesn't define a composer.json file, consider submitting a pull request that adds it.

This article originally appeared on the Daggerhart Lab blog and is republished with permission.

This dependency management tool makes it easier to require a repository even when it hasn't been created as a package.

Image by:

CC BY 3.0 US Mapbox Uncharted ERG

Git What to read next This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License. Register or Login to post a comment.

How to Install Graylog Log Management Tool on RHEL Systems

Tecmint - Mon, 05/16/2022 - 13:08
The post How to Install Graylog Log Management Tool on RHEL Systems first appeared on Tecmint: Linux Howtos, Tutorials & Guides .

Graylog is an industry-leading opensource log management solution for collecting, storing, indexing, and analyzing real-time data from applications and a myriad of devices in IT infrastructures such as servers, routers, and firewalls. Graylog helps

The post How to Install Graylog Log Management Tool on RHEL Systems first appeared on Tecmint: Linux Howtos, Tutorials & Guides.

Red Hat's “Corporate Banking Innovation Survey”: Industry transformation & challenges — now and what's next

Red Hat News - Mon, 05/16/2022 - 12:00

The newly released, inaugural edition of the Corporate Banking Innovation Survey report and accompanying webinar, highlighted top-of-mind corporate banking trends and forward-looking perspectives from a global assembly of industry leaders.

PAPPL 1.2 Released With Full Localization Support, More IPP Features

Phoronix - Mon, 05/16/2022 - 08:36
PAPPL as the free software project started by CUPS founder Michael Sweet after departing Apple more than two years ago, this C-based framework/library for creating CUPS Printer Applications is out with a major feature release...

Linux Patches Aim To Mitigate An Inconsistent Performance / NUMA Imbalancing Issue

Phoronix - Sun, 05/15/2022 - 19:57
An interesting Linux kernel patch series was posted this week to address inconsistent NUMA imbalancing behavior for at least some workloads. In such cases these patches address performance differences seen over the past number of Linux kernel releases going on for a while...

Linux Adding A Quirk To Improve Power Management For Intel Arc "Alchemist" GPUs

Phoronix - Sun, 05/15/2022 - 18:28
In addition to Linux 5.19 being the kernel set to have DG2/Alchemist graphics support in better shape with the IDs now (finally) being added and compute support being ready, this next kernel should boast improved power management handling for these "Alchemist" Arc Graphics GPUs...

AMD/Xilinx Solarflare Network Driver Restructuring Queued For Linux 5.19

Phoronix - Sun, 05/15/2022 - 18:06
The Solarflare "SFC" network driver within the Linux kernel for their high performance network adapters, owned by Xilinx and now owned by AMD, is seeing some restructuring with the next version of the Linux kernel. The intention is on shifting older network hardware to a separate kernel module/driver so improvements and new hardware support can be the focus with this main Solarflare Linux network driver...

Qualcomm MSM Driver With Linux 5.19 Adds DSC, Preps For Mesa Driver Within A VM

Phoronix - Sun, 05/15/2022 - 17:32
MSM DRM driver and Freedreno creator Rob Clark continues leading the charge on open-source Qualcomm Adreno graphics/display support for Linux in this effort that started out as a reverse-engineering project years ago. This past week Rob sent in the last batch of MSM Direct Rendering Manager driver updates intended for the Linux 5.19 kernel...

LongArch Patches Updated A Tenth Time For The Linux Kernel

Phoronix - Sun, 05/15/2022 - 06:26
With the tenth iteration of the LoongArch CPU architecture patches published on Saturday, it's looking like work is settling down and this Chinese MIPS-derived, RISC-V-inspired architecture could soon be going mainline...

Pages