Skip to content

Commit

Permalink
Add first version
Browse files Browse the repository at this point in the history
  • Loading branch information
Mathias STRASSER committed Oct 31, 2019
1 parent 0e67c83 commit 48d7bde
Show file tree
Hide file tree
Showing 13 changed files with 579 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
###> project ###
/composer.lock
/vendor/
###< project ###
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# PHP Make

Pake is a simple task runner.

Pake is a Make-like program implemented in PHP.
Tasks and dependencies are specified in standard PHP syntax.

Pakefiles (pake's version of Makefiles) are completely defined in standard PHP syntax.

## Installation

These commands requires you to have Composer installed globally.
Open a command console, enter your project directory and execute the following
commands to download the latest stable version:

```sh
composer require --dev roukmoute/pake
```

## Usage

### Example

First, you must write a `Pakefile` file which contains the build rules.
Here's a simple example:

```php
<?php

use PhpCsFixer\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;

task(
'default',
function () {
return ['fix', 'example'];
}
);

desc('PHP Coding Standards Fixer');
task(
'fix',
function () {
$application = new Application();
$application->setAutoExit(false);
$application->run(new ArrayInput(['fix']));
}
);
```

This Pakefile has two tasks:

- A task named `fix`, which – upon invocation – will fix your code to follow
standards in PHP:
```sh
▶ php ./vendor/bin/pake fix
```
- A task named `default`. This task does nothing by itself, but it has exactly
one dependency, namely the `fix` task.
Invoking the `default` task will cause Pake to invoke the `fix` task as well.

Running the `pake` command without any options will cause it to run the
`default` task in the Pakefile:

```sh
▶ php ./vendor/bin/pake
Loaded config default from ".php_cs.dist".
Using cache file ".php_cs.cache".
....unit fix output here...
```

Type `pake --help` for all available options.
21 changes: 21 additions & 0 deletions bin/pake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env php
<?php
if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
echo 'Warning: Pake should be invoked via the CLI version of PHP, not the ' . PHP_SAPI . ' SAPI' . PHP_EOL;
}

setlocale(LC_ALL, 'C');
require __DIR__ . '/../vendor/autoload.php';

use Pake\Console\Application;

error_reporting(-1);
if (defined('HHVM_VERSION')) {
sprintf('HHVM is not supported by Pake, please use PHP instead. Aborting.%s', PHP_EOL);
exit(1);
}

putenv('PAKE_BINARY='.realpath($_SERVER['argv'][0]));

$application = new Application();
$application->run();
37 changes: 37 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "roukmoute/pake",
"description": "A make-like build utility for PHP. A simple modern task runner.",
"type": "library",
"require": {
"php": ">= 7.3",
"symfony/console": "^4.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.15",
"phpunit/phpunit": "^8.4",
"roukmoute/dto-tester": "^0.3.0"
},
"license": "MIT",
"authors": [
{
"name": "Mathias STRASSER",
"email": "contact@roukmoute.fr"
}
],
"minimum-stability": "stable",
"config": {
"sort-packages": true
},
"autoload": {
"files": [ "runtime/Pake.php" ],
"psr-4": {
"Pake\\": "src/",
"Runtime\\": "Runtime/"
}
},
"autoload-dev": {
"psr-4": {
"PHPUnit\\": "tests/phpunit"
}
}
}
27 changes: 27 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"
failOnRisky="true"
failOnWarning="true"
>
<testsuites>
<testsuite name="Pake Test Suite">
<directory>./tests/PHPUnit</directory>
</testsuite>
</testsuites>

<filter>
<whitelist>
<directory>./</directory>
<exclude>
<directory>./runtime</directory>
<directory>./tests/PHPUnit</directory>
<directory>./vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
15 changes: 15 additions & 0 deletions runtime/Pake.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

if (!function_exists('desc')) {
function desc(string $description)
{
Pake\Pake::desc($description);
}
}

if (!function_exists('task')) {
function task(string $name, callable $callable)
{
Pake\Pake::task($name, $callable);
}
}
102 changes: 102 additions & 0 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php

declare(strict_types=1);

namespace Pake\Console;

use Pake\Console\Command\OptionCommand;
use Pake\Pake;
use Pake\Task;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Exception\CommandNotFoundException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class Application extends BaseApplication
{
private const DEFAULT_PAKEFILES = [
'pakefile',
'Pakefile',
'pakefile.php',
'Pakefile.php',
];

private static $logo = <<<TEXT
_____ _
| __ \ | |
| |__) | ____ | | __ ___
| ___/ / _ | | |/ / / _ \
| | | (_| | | < | __/
|_| \____| |_|\_\ \___|
TEXT;

public const VERSION = '1.0.0-DEV';

public function __construct()
{
parent::__construct('Pake', self::VERSION);

$this->rawLoadPakefile();

$command = new OptionCommand();

$this->add($command);
$this->setDefaultCommand($command->getName());
}

public function doRun(InputInterface $input, OutputInterface $output)
{
try {
return parent::doRun($input, $output);
} catch (CommandNotFoundException $exception) {
if (!in_array(
$this->getCommandName($input),
array_map(
function (Task $task) {
return $task->name();
},
Pake::tasks()->getArrayCopy()
)
)) {
throw $exception;
}
foreach (Pake::tasks() as $task) {
if ($this->getCommandName($input) === $task->name()) {
return $task->callable()();
}
}
}
}

public function getHelp()
{
return self::$logo;
}

private function rawLoadPakefile()
{
include $this->loadRakefile();
}

private function loadRakefile(): string
{
$pakefile = $this->findPakefileLocation();
if (!$pakefile) {
throw new \RuntimeException(
sprintf('No Pakefile found (looking for: %s)', implode(', ', self::DEFAULT_PAKEFILES))
);
}

return $pakefile;
}

private function findPakefileLocation(): ?string
{
$here = getcwd();
foreach (self::DEFAULT_PAKEFILES as $filename) {
if (file_exists($here . \DIRECTORY_SEPARATOR . $filename)) {
return $filename;
}
}
}
}
Loading

0 comments on commit 48d7bde

Please # to comment.