Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
WyattCast44 committed Mar 5, 2023
1 parent 385d33f commit 7e2374f
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 16 deletions.
8 changes: 7 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@
"laravel/pint": "^1.0",
"pestphp/pest": "^1.21",
"illuminate/http": "^9.21",
"guzzlehttp/guzzle": "^7.4"
"guzzlehttp/guzzle": "^7.4",
"spatie/invade": "^1.1"
},
"config": {
"allow-plugins": {
"pestphp/pest-plugin": true
}
}
}
70 changes: 68 additions & 2 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Statix Server

Statix Server is a PHP package that provides a simple way to configure and start a local PHP server for your web development needs.

![Banner image](.art/banner.jpg)

## Requirements
Expand All @@ -8,6 +10,8 @@

## Installation

You can install the package via composer:

```bash
composer require statix/server
```
Expand All @@ -16,7 +20,7 @@ View on packagist: [https://packagist.org/packages/statix/server](https://packag

## Basic Usage

To get started, ensure the vendor autoload script is required and then create an instance of the `Server` class, once you have set any [configuration options](#configuration), you should call the `start` method to start the server.
To get started, require the vendor autoload script and create an instance of the `Server` class. After setting any [configuration options](#configuration), call the `start` method to start the server.

```php
use Statix\Server\Server;
Expand Down Expand Up @@ -74,7 +78,7 @@ $optionsSettableViaContructor = [
];
```

### Setting configuration via the named methods
### Setting configuration via named methods

You also have the option of calling named methods to set the configuration options as shown below.

Expand Down
28 changes: 20 additions & 8 deletions src/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public function __construct(array $configuration = [])
'root' => getcwd(),
'php' => null,
'router' => null,
'envFile' => null,
'withEnvVars' => [],
'withoutEnvVars' => [],
], $configuration);
Expand Down Expand Up @@ -263,12 +264,7 @@ public function withEnvFile(string $path): self
throw new Exception('Given path to env file does not exists: '.$path);
}

(Dotenv::createImmutable(
dirname($path),
basename($path)
))->safeLoad();

$this->envVarsToPass = array_merge($_ENV, getenv(), $_SERVER);
$this->configuration['envFile'] = (string) $path;

return $this;
}
Expand Down Expand Up @@ -329,13 +325,29 @@ private function buildServeCommand(): array

private function buildPassingEnvVarArray(): array
{
return array_merge(array_filter($this->envVarsToPass, function ($key) {
$passing = [];

if (($path = $this->configuration['envFile']) != null) {
$passing = array_merge($passing, Dotenv::parse(file_get_contents($path)));
}

// remove any keys that are in the withoutEnvVars array
$passing = array_filter($passing, function ($key) {
return ! in_array($key, $this->configuration['withoutEnvVars']);
}, ARRAY_FILTER_USE_KEY), $this->configuration['withEnvVars']);
}, ARRAY_FILTER_USE_KEY);

// merge in any keys that are in the withEnvVars array
$passing = array_merge($passing, $this->configuration['withEnvVars']);

return $passing;
}

private function initProcess(): Process
{
echo array_filter($this->buildPassingEnvVarArray(), function($key) {
return $key == 'APP_NAME';
}, ARRAY_FILTER_USE_KEY)['APP_NAME'];

$process = new Process(
$this->buildServeCommand(),
null,
Expand Down
91 changes: 91 additions & 0 deletions tests/ServerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,97 @@
})->toThrow(\Exception::class);
});

// withEnvFile
test('the default envFile configuration is null', function () {
$server = Server::new();

expect($server->getConfiguration('envFile'))
->toBeNull();
});

test('the withEnvFile method sets the path in the config array', function () {
$server = Server::new()
->withEnvFile($path = __DIR__ . '\resources\.env.example');

expect($server->getConfiguration('envFile'))
->toEqual($path);
});

test('the withEnvFile method throws an exception if the file does not exist', function () {
expect(function () {
return Server::new()
->withEnvFile($path = __DIR__ . '\resources\.env.fake');
})->toThrow(\Exception::class);
});

test('the withEnvFile method updates the envVarsToPass array', function () {
$server = Server::new()
->withEnvFile($path = __DIR__ . '\resources\.env.example');

$envVars = invade($server)->envVarsToPass;

expect(array_key_exists('APP_NAME', $envVars))->toBe(true);

expect($envVars['APP_NAME'])->toEqual('Server');
});

test('the withEnvFile method exposes the .env file to the process', function () {
$url = 'http://localhost:3000';

$server = Server::new([
'root' => './tests/resources',
'port' => '3000',
])
->router(__DIR__ . '\resources\router.php')
->withEnvFile(__DIR__ . '\resources\.env.example')
->runInBackground();

$response = (string) get($url)->body();

expect($response)->toContain('APP_NAME: Server');

$server->stop();
});

test('when the server reloads, the env file is reloaded', function () {
$url = 'http://localhost:3000';

// set the env file to a known state
file_put_contents(__DIR__ . '\resources\.env.example', 'APP_NAME="Server"');

// create the server
$server = Server::new([
'root' => './tests/resources',
'port' => '3000',
])->router(__DIR__ . '\resources\router.php')->withEnvFile(__DIR__ . '\resources\.env.example')->runInBackground();

// get the response
$response = (string) get($url)->body();

echo $response;

// check the response
expect($response)->toContain('APP_NAME: Server');

// change the env file
file_put_contents(__DIR__ . '\resources\.env.example', 'APP_NAME="Server2"');

sleep(5);

// reload the server
$server->restart();

// get the response
$response = (string) get($url)->body();

expect($response)->toContain('APP_NAME: Server2');

$server->stop();

// reset the env file
file_put_contents(__DIR__ . '\resources\.env.example', 'APP_NAME="Server"');
})->only();

// withEnvVars
test('the default withEnvVars array is null', function () {
expect(Server::new()->getConfiguration('withEnvVars'))
Expand Down
3 changes: 1 addition & 2 deletions tests/resources/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
APP_NAME="Server"
APP_ENV="local"
APP_NAME="Server2"
27 changes: 27 additions & 0 deletions tests/resources/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible"
content="IE=edge">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Test HTML Document</title>
</head>

<body>
<h1>Test PHP Script</h1>
<ul>Env Variables</ul>

<?php foreach ($envVars as $key => $value) : ?>
<li><?php echo $key ?>: <?php echo $value ?></li>
<?php endforeach; ?>

</ul>

<p>Timestamp: <?php echo time(); ?></p>

</body>

</html>
7 changes: 6 additions & 1 deletion tests/resources/router.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<?php

//
// get the env variables
$envVars = array_filter(array_merge($_SERVER, $_ENV, getenv()), function($key) {
return strpos($key, 'APP_') === 0;
}, ARRAY_FILTER_USE_KEY);

require __DIR__ . '\index.php';

0 comments on commit 7e2374f

Please sign in to comment.