Skip to content

civicrm/composer-compile-lib

v0.6
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
src
 
 
 
 
 
 
 
 
 
 

CiviCRM Composer Compilation Library

This package provides a handful of small tasks and helpers for use with composer-compile-plugin.

Design guidelines for this package:

  • To ensure easy operation in a new/unbooted system:
    • Use basic functions and static methods
    • Use primitive data sources (such as static JSON files)
  • To ensure that compilation steps report errors:
    • Every task/function must throw an exception if it doesn't work.
  • To allow pithy tasks:
    • If a task is outputting to a folder, and if the folder doesn't exist, then it should auto-create the folder.

The primary purpose here is demonstrative - to provide examples. Consequently, it is fairly minimal / lightweight / loosely-coupled. There is no dependency on CiviCRM. Conversely, CiviCRM packages may define other tasks which are not in this library.

Require the library

All the examples below require the civicrm/composer-compile-lib package. Load via CLI:

composer require civicrm/composer-compile-lib:'~0.2'

Or via composer.json:

  "require": {
    "civicrm/composer-compile-lib": "~0.2"
  }

Task: SCSS

In this example, we generate a file dist/sandwich.css by reading scss/sandwich.scss. The file may @import mixins and variables from the ./scss/ folder.

{
  "extra": {
    "compile": [
      {
        "title": "Prepare CSS (<comment>sandwich.css</comment>, <comment>salad.css</comment>)",
        "run": "@php-method \\CCL\\Tasks::scss",
        "watch-files": ["scss"],
        "scss-files": {
          "dist/sandwich.css": "scss/sandwich.scss",
          "dist/salad.css": "scss/salad.scss"
        },
        "scss-imports": ["scss"]
        "scss-import-prefixes": {"LOGICAL_PREFIX/": "physical/folder/"}
      }
    ]
  }
}

Note that a "task" simply calls a static PHP method (@php-method \\CCL\\Tasks::scss) with the JSON data as input. You can also call the method in a PHP script. For example, we could define a task based on a script:

{
  "extra": {
    "compile": [
      {
        "title": "Prepare CSS (<comment>sandwich.css</comment>, <comment>salad.css</comment>)",
        "run": "@php-script bin/compile-scss"
      }
    ]
  }
}

The following script generalizes the example from before -- it maps any SCSS files (scss/*.scss) to corresponding CSS files (dist/#1.css). This file-list is passed into \CCL\Tasks::scss for processing:

\CCL::assertTask();

$files = \CCL::globMap('scss/*.scss', 'dist/#1.css', 1);
\CCL\Tasks::scss([
  'scss-files' => $files,
  'scss-imports' => ['scss']
  'scss-import-prefixes' => ['LOGICAL_PREFIX/' => 'physical/folder/']
]);

Note that this implementation of \CCL\Tasks::scss() is fairly opinionated - it combines scssphp with php-autoprefixer. The output is written as two files, a larger files (*.css) and a smaller file (*.min.css).

Task: PHP Template

In this example, we use a PHP template to generate another PHP file. Specifically, we create Sandwich.php using the specification from Sandwich.json and EntityTemplate.php:

{
  "extra": {
    "compile": [
      {
        "title": "Sandwich (<comment>src/Sandwich.php</comment>)",
        "run": "@php-method \\CCL\\Tasks::template",
        "watch-files": ["src/Entity"],
        "tpl-items": [
          "src/Entity/Sandwich.php": "src/Entity/Sandwich.json",
          "src/Entity/Salad.php": "src/Entity/Salad.json"
        ],
        "tpl-file": "src/Entity/EntityTemplate.php"
      }
    ]
  }
}

As in the previous example, the task is simply a PHP method (@php-method \\CCL\\Tasks::template), so it can be used from a PHP script. The following script would extend the pattern, mapping any JSON files (src/Entity/*.json) to corresponding PHP files (src/Entity/#1.php):

$files = \CCL::globMap('src/Entity/*.json', 'src/Entity/#1.php', 1);
\CCL\Tasks::template([
  "tpl-file" => "src/Entity/EntityTemplate.php",
  "tpl-items" => $files,
]);

Functions

PHP's standard library has a lot of functions that would work for basic file manipulation (copy(), rename(), chdir(), etc). The problem is error-signaling -- you have to explicitly check error-output, and this grows cumbersome for improvised glue code. It's more convenient to have a default stop-on-error behavior, e.g. throwing exceptions.

symfony/filesystem provides wrappers which throw exceptions. But it puts them into a class Filesystem which, which requires more boilerplate.

For the most part, CCL simply mirrors symfony/filesystem using static methods in the CCL class. Compare:

// PHP Standard Library
if (!copy('old', 'new')) {
  throw new \Exception("...");
}

// Symfony Filesystem
$fs = new \Symfony\Component\Filesystem\Filesystem();
$fs->copy('old', 'new');

// Composer Compile Library
\CCL::copy('old', 'new');

This is more convenient for scripting one-liners. For example, the following tasks do simple file operations. If anything goes wrong, they raise an exception and stop the compilation process.

{
  "extra": {
    "compile": [
      {
        "title": "Smorgasboard of random helpers",
        "run": [
          // Create files and folders
          "@php-eval \\CCL::dumpFile('dist/timestamp.txt', date('Y-m-d H:i:s'));",
          "@php-eval \\CCL::mkdir('some/other/place');",

          // Concatenate a few files
          "@php-eval \\CCL::dumpFile('dist/bundle.js', \\CCL::cat(glob('js/*.js'));",
          "@php-eval \\CCL::chdir('css'); \\CCL::dumpFile('all.css', ['colors.css', 'layouts.css']);",

          // If you need reference material from another package...
          "@export TWBS={{pkg:twbs/bootstrap}}",
          "@php-eval \\CCL::copy(getenv('TWBS') .'/dist/bootstrap.css', 'web/main.css')"
        ]
      }
    ]
  }
}

The full function list:

// CCL wrapper functions

function chdir(string $dir);
function glob($pat, $flags = null);

// CCL distinct functions

function cat($files);
function mapkv($array, $func);
function globMap($globPat, $mapPat, $flip = false);

// Symfony wrapper functions

function appendToFile($filename, $content);
function dumpFile($filename, $content);
function mkdir($dirs, $mode = 511);
function touch($files, $time = null, $atime = null);

function copy($originFile, $targetFile, $overwriteNewerFiles = true);
function mirror($originDir, $targetDir, $iterator = null, $options = []);
function remove($files);
function rename($origin, $target, $overwrite = false);

function chgrp($files, $group, $recursive = false);
function chmod($files, $mode, $umask = 0, $recursive = false);
function chown($files, $user, $recursive = false);

function hardlink($originFile, $targetFiles);
function readlink($path, $canonicalize = false);
function symlink($originDir, $targetDir, $copyOnWindows = false);

function exists($files);

function tempnam($dir, $prefix);

For more details about each function, see CCL\Functions and symfony/filesystem.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages