Composer plugin replacing placeholders in the scripts section by dynamic values

Overview

Composer Substitution Plugin

The Composer Substitution plugin replaces placeholders in the scripts section by dynamic values.

It also permits to cache these values during the command execution and adds the ability to escape them with the function of your choice.

Build Status AppVeyor Build Status Latest Stable Version Minimum PHP Version License

Installation

composer require villfa/composer-substitution-plugin

Requirements

  • PHP >= 5.3.2
  • Composer >= 1.0.0

Usage

You need to configure the plugin in the extra section of composer.json.

Here an example:

"extra": {
    "substitution": {
        "enable": true,
        "mapping": {
            "{MY_NAME}": {
                "type": "literal",
                "value": "John Doe",
                "escape": "addslashes"
            },
            "{PHP_VERSION}": {
                "type": "callback",
                "value": "phpversion"
            },
            "{DB_STATUS}": {
                "type": "include",
                "value": "./scripts/db.php",
                "cached": true
            },
            "{HOME}": {
                "type": "env",
                "value": "HOME"
            },
            "{COMPOSER_VERSION}": {
                "type": "constant",
                "value": "Composer\\Composer::VERSION"
            },
            "{NPROC}": {
                "type": "process",
                "value": "nproc"
            }
        }
    }
}

Then you can add the configured placeholders in the scripts section:

"scripts": {
    "welcome": "echo 'Hi {MY_NAME}, the database is {DB_STATUS}.'"
}

And now if you run the command:

$ composer run-script welcome
Hi John Doe, the database is OK.

Configuration

Configuration key Mandatory Type Default value Description
extra.substitution.enable yes bool false Enables the plugin when true
extra.substitution.mapping yes object empty object Mapping between placeholders (the keys) and substitution rules (the values). There is no restriction with the placeholders format.
extra.substitution.mapping.*.type yes string n/a Substitution type (see the related section below)
extra.substitution.mapping.*.value yes string n/a Substitution value (depends on the type)
extra.substitution.mapping.*.cached no bool false Indicates whether the value provided after the first substitution must be cached
extra.substitution.mapping.*.escape no string null Escaping function that will receive the substitute value as argument
extra.substitution.priority no integer 0 Plugin's event handler priority (see Composer documentation)

Substitution types

For each type of substitution the value replacing the placeholder comes from a different source.

  • literal: The value in configuration is used directly.
  • callback: The value is the string returned by a callback.
  • include: The value is the string returned by a PHP file.
  • env: The value is an ENV variable.
  • constant: The value comes from a constant or a class constant.
  • process: The value is the output of the processed command.

Real-life examples

PHPUnit Extra Constraints

This library defines a Composer script which uses PHP_CodeSniffer this way:

"scripts": {
    "phpcs": "phpcs --standard=PSR12 --parallel=$(nproc) src/ tests/",

Unfortunately it is not cross-platform because of the usage of nproc.

This is solved by the substitution plugin in combination with Linfo (See also the tiny script nproc.php). Here how it is configured:

"extra": {
    "substitution": {
        "enable": true,
        "mapping": {
            "$(nproc)": {
                "cached": true,
                "type": "include",
                "value": "./scripts/nproc.php"
            }
        }
    }
}

So now it also works on Windows without even touching the scripts section.

You might also like...
Provides the functionality to compare PHP values for equality.

sebastian/comparator This component provides the functionality to compare PHP values for equality. Installation You can add this library as a local, p

Humanize values that are readable only for developers.

PHP Humanizer Tests - 4.x Readme for 4.x version Humanize values to make them readable for regular people ;) Installation Run the following command: c

A PHP library to write values to .env (DotEnv) files

DotEnvWriter A PHP library to write values to .env (DotEnv) files Installation DotEnvWriter can be installed with Composer. composer require mirazmac/

Google-like values converter

Google-like values converter. Support for different types of conversions, for examples: 1 kilometer - meters 1 dollar - THB 1 kilogram - meters ...

Sanitize and escape every values in your PHP Application

PHP Sanitizer Sanitize and escape every values in your PHP Application. This solution will make PHP developer life easy, very easy and developers woul

Deeper is a easy way to compare if 2 objects is equal based on values in these objects. This library is heavily inspired in Golang's reflect.DeepEqual().

Deeper Deeper is a easy way to compare if 2 objects is equal based on values in these objects. This library is heavily inspired in Golang's reflect.De

Read and show values from form valid

read-and-show-values-from-form-valid Escribe un programa PHP que permita al usuario rellenar un formulario de registro con los datos de nombre, contra

JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

JSONFinder - a library that can find json values in a mixed text or html documents, can filter and search the json tree, and converts php objects to json without 'ext-json' extension.

Miniset allows you to create compact sets of fields that either combine into a string of classes, or return a simple array of values

Miniset allows you to create compact sets of fields that either combine into a string of classes, or return a simple array of values. Miniset

Comments
  • "process" substitution executes command immediately after substitution

    The command is getting executed before continuing after the substitution. So, if you use the substitution in the middle and have other options after the substitution, the post-substitution options/flags/arguments won't be read.

    // composer.json
    {
      "scripts": {
        "bash": [
          "docker exec -ti {CONTAINER} bash"
        ]
      },
        "substitution": {
          "enable": true,
          "mapping": {
            "{CONTAINER}": {
              "type": "process",
              "value": "docker ps -aqf ancestor=special-tag"
            }
          }
        }
    }
    

    results in

    ivr (git)-[1337-ivr-tests]- % composer bash
    > docker exec -ti ae055d08efb2
     bash
    "docker exec" requires at least 2 arguments.
    See 'docker exec --help'.
    
    Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
    
    opened by jontroncoso 3
  • Callback substitution doesn't work with user-defined functions

    Callback substitution doesn't work with user-defined functions

    See this test: https://github.com/villfa/composer-substitution-plugin/blob/a0466de913f037bf9f285768cc222fcc27277c1f/tests/e2e/Callback/Basic/CallbackBasicTest.php#L23-L30

    bug 
    opened by villfa 1
  • [Composer 2.2] Update README about allow-plugins config

    [Composer 2.2] Update README about allow-plugins config

    See https://github.com/composer/composer/pull/10314

    It would be also the occasion to make extra.substitution.enable optional in order to make improve the UX by reducing the amount of configuration to set.

    opened by villfa 0
Owner
Fabien Villepinte
Fabien Villepinte
A collection of command line scripts for Magento 2 code generation, and a PHP module system for organizing command line scripts.

What is Pestle? Pestle is A PHP Framework for creating and organizing command line programs An experiment in implementing python style module imports

Alan Storm 526 Dec 5, 2022
The simplest way to create a dynamic sitemap for your self-coded website which you have made by using PHP/HTML/CSS/Js etc... Scripts.

Sitemap_index.xml The simplest way to create a dynamic sitemap for your self-coded website which you have made by using PHP/HTML/CSS/Js etc... Scripts

Tanish Raj 1 Oct 16, 2021
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.

composer-custom-directory-installer A composer plugin, to install differenty types of composer packages in custom directories outside the default comp

Mina Nabil Sami 136 Dec 30, 2022
It's basically a dynamic web browser extension that can display notifications with the help of an admin-controlled dynamic API.

D-NOTIFIER A self controlled dynamic API based web browser extension built by Sahil Kumar How It Works? It's basically a dynamic web browser extension

Sahil Kumar 1 Jan 6, 2022
Ied plugin composer - Inspired Plugin Composer: Create, publish and edit plugins from within Textpattern CMS.

ied_plugin_composer Create, publish and edit plugins from within Textpattern CMS. Creates a new page under the Extensions tab where you can edit and e

Stef Dawson 8 Oct 3, 2020
Opinionated version of Wikimedia composer-merge-plugin to work in pair with Bamarni composer-bin-plugin.

Composer Inheritance Plugin Opinionated version of Wikimedia composer-merge-plugin to work in pair with bamarni/composer-bin-plugin. Usage If you are

Théo FIDRY 25 Dec 2, 2022
Scripts-dev directive for composer

scriptsdev for Composer It's like require-dev, but for scripts Installation Just run composer require neronmoon/scriptsdev --dev Usage After installin

Vitaliy Krasnoperov 67 May 18, 2022
One-file composer scripts

Melody - One-file composer scripts Create a file named test.php: <?php <<<CONFIG packages: - "symfony/finder: ~2.8" CONFIG; $finder = Symfony\Com

SensioLabs 399 Aug 18, 2022
Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins.

Imposter Plugin Composer plugin that wraps all composer vendor packages inside your own namespace. Intended for WordPress plugins. Built with ♥ by Typ

Typist Tech 127 Dec 17, 2022
Composer Registrar Composer Plugin for Magento 2

This module add a global registration.php that replace the default glob search performed for each request to discover the components not installed from composer.

OpenGento 3 Mar 22, 2022