Skip to content

Commit

Permalink
Merge pull request #1 from php-task-runner/initial-implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
claudiu-cristea authored Jun 3, 2020
2 parents 9ac15e4 + 31eb898 commit 7c9b72f
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 5 deletions.
29 changes: 29 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
language: php
sudo: false

php:
- 7.1
- 7.2
- 7.3
- 7.4

env:
- TEST_SUITE=PHP_CodeSniffer
- TEST_SUITE=PHPUnit

# Only run the coding standards check once.
matrix:
exclude:
- php: 7.1
env: TEST_SUITE=PHP_CodeSniffer
- php: 7.2
env: TEST_SUITE=PHP_CodeSniffer
- php: 7.3
env: TEST_SUITE=PHP_CodeSniffer

before_script:
- composer install

script:
- test ${TEST_SUITE} == "PHP_CodeSniffer" || ./vendor/bin/phpunit tests/
- test ${TEST_SUITE} == "PHPUnit" || ./vendor/bin/phpcs
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[![Build Status](https://travis-ci.com/php-task-runner/scss.svg?branch=master)](https://travis-ci.com/php-task-runner/scss)

This repository provides SCSS commands for OpenEuropa [Task Runner](
https://github.com/openeuropa/task-runner).

## Commands

* `assets:compile-scss`: Compile SCSS to CSS.
11 changes: 6 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
"keywords": ["task-runner"],
"type": "library",
"require": {
"php": ">=7.1",
"php": "~7.1",
"consolidation/robo": "^1.4.11",
"openeuropa/task-runner": "dev-master",
"openeuropa/task-runner": "^1.0.0-beta6",
"scssphp/scssphp": "~1.1"
},
"require-dev": {
"phpunit/phpunit": "~6 || ~7 || ~8 || ~9",
"squizlabs/php_codesniffer": "^3.0@dev"
"phpunit/phpunit": "~7 || ~8 || ~9",
"slevomat/coding-standard": "~6",
"squizlabs/php_codesniffer": "~3"
},
"license": "EUPL-1.2",
"authors": [
Expand All @@ -27,7 +28,7 @@
},
"autoload-dev": {
"psr-4": {
"TaskRunner\\Scss\\Tests\\": "./tests/"
"TaskRunner\\Scss\\Tests\\": "./tests/src/"
}
},
"config": {
Expand Down
36 changes: 36 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="TaskRunner/Scss">
<description>PHP CodeSniffer configuration for the php-task-runner/scss library.</description>
<config name="installed_paths" value="../../slevomat/coding-standard"/>
<rule ref="PSR12">
<exclude name="Generic.Files.LineLength.TooLong" />
<exclude name="PSR2.Classes.ClassDeclaration.CloseBraceAfterBody" />
</rule>
<rule ref="SlevomatCodingStandard.TypeHints.DeclareStrictTypes">
<properties>
<property name="newlinesCountBetweenOpenTagAndDeclare" value="2" />
<property name="newlinesCountAfterDeclare" value="2" />
<property name="spacesCountAroundEqualsSign" value="0" />
</properties>
</rule>
<rule ref="SlevomatCodingStandard.Arrays.DisallowImplicitArrayCreation" />
<rule ref="SlevomatCodingStandard.ControlStructures.DisallowContinueWithoutIntegerOperandInSwitch" />
<rule ref="SlevomatCodingStandard.ControlStructures.RequireNullCoalesceOperator" />
<rule ref="SlevomatCodingStandard.Operators.DisallowEqualOperators" />
<rule ref="SlevomatCodingStandard.Namespaces.UnusedUses" />
<rule ref="SlevomatCodingStandard.Namespaces.UseFromSameNamespace" />
<rule ref="SlevomatCodingStandard.PHP.UselessParentheses" />
<rule ref="SlevomatCodingStandard.Variables.UnusedVariable" />
<rule ref="SlevomatCodingStandard.Arrays.TrailingArrayComma" />
<rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses" />
<rule ref="SlevomatCodingStandard.Namespaces.NamespaceDeclaration" />
<rule ref="SlevomatCodingStandard.Namespaces.NamespaceSpacing" />
<rule ref="SlevomatCodingStandard.Classes.ClassConstantVisibility" />
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHintSpacing" />
<rule ref="SlevomatCodingStandard.TypeHints.NullableTypeForNullDefaultValue" />
<rule ref="SlevomatCodingStandard.Namespaces.UseDoesNotStartWithBackslash" />
<file>src</file>
<file>tests</file>
<arg name="report" value="full"/>
<arg value="p"/>
</ruleset>
98 changes: 98 additions & 0 deletions src/TaskRunner/Commands/ScssCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php

declare(strict_types=1);

namespace TaskRunner\Scss\TaskRunner\Commands;

use Consolidation\AnnotatedCommand\CommandData;
use OpenEuropa\TaskRunner\Commands\AbstractCommands;
use Robo\Collection\CollectionBuilder;
use Robo\Task\Assets\loadTasks;
use Symfony\Component\Console\Input\InputOption;

/**
* Command wrapper for the "taskScss" task that is included in Robo.
*
* @see \Robo\Task\Assets\loadTasks
*/
class ScssCommands extends AbstractCommands
{
use loadTasks;

/**
* List of formatters that is offered by the ScssPhp compiler.
*
* @see \ScssPhp\ScssPhp\Formatter
*/
protected const SCSS_FORMATTERS = ['compact', 'compressed', 'crunched', 'expanded', 'nested'];

/**
* Compile SCSS to CSS.
*
* @command assets:compile-scss
*
* @param string $input_file The path to the SCSS file to process
* @param string $output_file The path where to store the compiled CSS file
* @option style Set the output format (compact, compressed, crunched, expanded, or nested)
* @option import-dir Set an import path
*
* @param array $options
*
* @return \Robo\Collection\CollectionBuilder
*/
public function compileScss(string $input_file, string $output_file, array $options = [
'style' => InputOption::VALUE_REQUIRED,
'import-dir' => [],
]): CollectionBuilder
{
$scss = $this->taskScss([$input_file => $output_file]);

if ($options['style']) {
$scss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\' . ucfirst($options['style']));
}

foreach ($options['import-dir'] as $import_dir) {
$scss->addImportPath($import_dir);
}

return $this->collectionBuilder()->addTask($scss);
}

/**
* @hook pre-validate assets:compile-scss
*/
public function preValidateCompileScss(CommandData $commandData): void
{
$input = $commandData->input();
$style = $input->getOption('style');
if ($style) {
// Ensure case insensitive matching for the style option.
$input->setOption('style', strtolower($style));
}
}

/**
* @hook validate assets:compile-scss
*/
public function validateCompileScss(CommandData $commandData): void
{
$input = $commandData->input();
$input_file = $input->getArgument('input_file');
if (!is_file($input_file) || !is_readable($input_file)) {
throw new \Exception(sprintf('Input file "%s" does not exist or is not readable', $input_file));
}

$style = $input->getOption('style');
if ($style && !in_array($style, self::SCSS_FORMATTERS)) {
throw new \Exception(sprintf('Unknown style "%s"', $style));
}

$import_dirs = $input->getOption('import-dir');
foreach ($import_dirs as $import_dir) {
if (!is_dir($import_dir) || !is_readable($import_dir)) {
throw new \Exception(sprintf('Import dir "%s" does not exist or is not readable', $import_dir));
}
}
}

}
10 changes: 10 additions & 0 deletions tests/fixtures/example.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Example SCSS file to test the `assets:compile-scss` command.
$dark: #111;
nav {
ul {
margin: 0;
li {
color: $dark;
}
}
}
116 changes: 116 additions & 0 deletions tests/src/ScssCommandsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

declare(strict_types=1);

namespace TaskRunner\Scss\Tests;

use Composer\Autoload\ClassLoader;
use OpenEuropa\TaskRunner\TaskRunner;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\BufferedOutput;

/**
* Tests the command wrappers for Robo "assets" tasks.
*
* @coversDefaultClass \TaskRunner\Scss\TaskRunner\Commands\ScssCommands
* @phpcs:disable SlevomatCodingStandard.Arrays.TrailingArrayComma
*/
final class ScssCommandsTest extends TestCase
{

/**
* @param string $style
* The CSS style to be generated.
* @param string $expected
* The expected compiled CSS.
*
* @covers ::compileScss
* @dataProvider compileScssDataProvider
*/
public function testCompileScss(string $style, string $expected): void
{
$command = sprintf(
'assets:compile-scss --working-dir=%s --style=%s %s %s',
sys_get_temp_dir(),
$style,
__DIR__ . '/../fixtures/example.scss',
'output.css'
);
$input = new StringInput($command);
$output = new BufferedOutput();
$runner = new TaskRunner($input, $output, $this->getClassLoader());
$runner->run();

$actual = file_get_contents(sys_get_temp_dir() . '/output.css');
$this->assertEquals($expected, $actual);
}

/**
* Data provider for ::testCompileScss().
*
* @return array[]
* An array of test cases, each test case an array with two elements:
* - A string containing the CSS style to be generated.
* - A string containing the expected compiled CSS.
*/
public function compileScssDataProvider(): array
{
return [
[
'compact',
<<<CSS
nav ul { margin:0; }
nav ul li { color:#111; }
CSS
],
[
'compressed',
<<<CSS
nav ul{margin:0}nav ul li{color:#111}
CSS
],
[
'crunched',
<<<CSS
nav ul{margin:0}nav ul li{color:#111}
CSS
],
[
'expanded',
<<<CSS
nav ul {
margin: 0;
}
nav ul li {
color: #111;
}
CSS
],
[
'nested',
<<<CSS
nav ul {
margin: 0; }
nav ul li {
color: #111; }
CSS
],
];
}

/**
* Returns the Composer classloader.
*
* @return \Composer\Autoload\ClassLoader
*/
protected function getClassLoader(): ClassLoader
{
return require __DIR__ . '/../../vendor/autoload.php';
}
}

0 comments on commit 7c9b72f

Please sign in to comment.