[Env] initial commit

This commit is contained in:
azjezz 2020-08-18 04:51:44 +01:00 committed by Saif Eddin G
parent 4e279e27f8
commit 7fb0bce8ae
21 changed files with 455 additions and 0 deletions

23
src/Psl/Env/args.php Normal file
View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
/**
* Returns the arguments which this program was started with (normally passed via the command line).
*
* @psalm-return list<string>
*/
function args(): array
{
/** @psalm-var list<string>|null $args */
$args = $GLOBALS['argv'] ?? null;
// @codeCoverageIgnoreStart
if (null === $args) {
return [];
}
// @codeCoverageIgnoreEnd
return $args;
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use function getcwd;
use Psl;
/**
* Returns the current working directory
*
* @throws Psl\Exception\InvariantViolationException If unable to retrieve the current working directory.
*/
function current_dir(): string
{
$directory = getcwd();
Psl\invariant(false !== $directory, 'Unable to retrieve current working directory.');
return $directory;
}

View File

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use Psl;
use Psl\Iter;
/**
* Returns the full filesystem path of the current running executable.
*
* @throws Psl\Exception\InvariantViolationException If unable to retrieve the current running executable.
*/
function current_exec(): string
{
$files = get_included_files();
$executable = Iter\first($files);
Psl\invariant(null !== $executable, 'Unable to retrieve the full filesystem path of the current running executable.');
return $executable;
}

24
src/Psl/Env/get_var.php Normal file
View File

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use function getenv;
use Psl;
use Psl\Str;
/**
* Fetches the environment variable $key from the current process.
*
* @throws Psl\Exception\InvariantViolationException If $key is empty, or contains an ASCII equals sign `=` or the NUL character `\0`.
*/
function get_var(string $key): ?string
{
Psl\invariant(!Str\is_empty($key) && !Str\contains($key, '=') && !Str\contains($key, "\0"), 'Invalid environment variable key provided.');
/** @var false|string $value */
$value = getenv($key);
return false === $value ? null : $value;
}

19
src/Psl/Env/get_vars.php Normal file
View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use function getenv;
use Psl;
use Psl\Type;
/**
* Returns an iterator of (variable, value) pairs of strings, for all the environment variables of the current process.
*
* @psalm-return array<string, string>
*/
function get_vars(): array
{
return getenv();
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use const PATH_SEPARATOR;
use Psl\Str;
/**
* Joins a collection of paths appropriately for the PATH environment variable.
*
* @param string ...$paths
*/
function join_paths(string ...$paths): string
{
return Str\join($paths, PATH_SEPARATOR);
}

View File

@ -0,0 +1,22 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use Psl;
use Psl\Str;
use function putenv;
/**
* Removes an environment variable from the environment of the currently running process.
*
* @throws Psl\Exception\InvariantViolationException If $key is empty, or contains an ASCII equals sign `=` or the NUL character `\0`.
*/
function remove_var(string $key): void
{
Psl\invariant(!Str\is_empty($key) && !Str\contains($key, '=') && !Str\contains($key, "\0"), 'Invalid environment variable key provided.');
putenv($key);
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use function chdir;
use Psl;
/**
* Changes the current working directory to the specified path.
*
* @param string $directory
*
* @throws Psl\Exception\InvariantViolationException If the operation fails.
*/
function set_current_dir(string $directory): void
{
Psl\invariant(chdir($directory), 'Unable to change directory');
}

23
src/Psl/Env/set_var.php Normal file
View File

@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use Psl;
use Psl\Str;
use function putenv;
/**
* Sets the environment variable $key to the value $value for the currently running process.
*
* @throws Psl\Exception\InvariantViolationException If $key is empty, contains an ASCII equals sign `=` or the NUL character `\0`, or when the $value contains the NUL character.
*/
function set_var(string $key, string $value): void
{
Psl\invariant(!Str\is_empty($key) && !Str\contains($key, '=') && !Str\contains($key, "\0"), 'Invalid environment variable key provided.');
Psl\invariant(!Str\contains($value, "\0"), 'Invalid environment variable value provided.');
putenv(Str\format('%s=%s', $key, $value));
}

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use const PATH_SEPARATOR;
use Psl\Str;
/**
* Parses input according to platform conventions for the PATH environment variable.
*
* @return string[]
*/
function split_paths(string $path): array
{
/** @psalm-suppress MissingThrowsDocblock - we don't provide the $limit argument */
return Str\split($path, PATH_SEPARATOR);
}

24
src/Psl/Env/temp_dir.php Normal file
View File

@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace Psl\Env;
use Psl;
use function sys_get_temp_dir;
/**
* Returns the value of the "TMPDIR" environment variable if it is set, otherwise it returns /tmp.
*
* @note On windows, we can't count on the environment variables "TEMP" or "TMP", and so must make the Win32 API call to get the default
* directory for temporary files.
*
* @note The return value of this function can be overridden using the sys_temp_dir ini directive.
*
* @see https://www.php.net/manual/en/function.sys-get-temp-dir.php
* @see https://github.com/php/php-src/blob/fd0b57d48bab3924a31d3d0b038f0d5de6eab3e3/main/php_open_temporary_file.c#L204
*/
function temp_dir(): string
{
return sys_get_temp_dir();
}

View File

@ -290,6 +290,17 @@ final class Loader
'Psl\Json\encode',
'Psl\Json\decode',
'Psl\Json\typed',
'Psl\Env\args',
'Psl\Env\current_dir',
'Psl\Env\current_exec',
'Psl\Env\get_var',
'Psl\Env\get_vars',
'Psl\Env\join_paths',
'Psl\Env\remove_var',
'Psl\Env\set_current_dir',
'Psl\Env\set_var',
'Psl\Env\split_paths',
'Psl\Env\temp_dir',
];
public const INTERFACES = [

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
final class ArgsTest extends TestCase
{
public function testArgs(): void
{
self::assertSame($GLOBALS['argv'], Env\args());
}
}

View File

@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
class CurrentDirTest extends TestCase
{
public function testCurrentDir(): void
{
self::assertSame(getcwd(), Env\current_dir());
Env\set_current_dir(__DIR__);
self::assertSame(__DIR__, Env\current_dir());
}
}

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
class CurrentExecTest extends TestCase
{
public function testCurrentExe(): void
{
self::assertSame(realpath(__DIR__ . '/../../../vendor/phpunit/phpunit/phpunit'), Env\current_exec());
}
}

View File

@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
class GetVarTest extends TestCase
{
/**
* @backupGlobals
*/
public function testGetVar(): void
{
self::assertNull(Env\get_var('FOO'));
Env\set_var('FOO', 'BAR');
self::assertSame('BAR', Env\get_var('FOO'));
Env\remove_var('FOO');
}
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
class GetVarsTest extends TestCase
{
/**
* @backupGlobals
*/
public function testGetVars(): void
{
$expected = getenv();
self::assertSame($expected, Env\get_vars());
Env\set_var('FOO', 'BAR');
self::assertNotSame($expected, Env\get_vars());
self::assertSame(getenv(), Env\get_vars());
Env\remove_var('FOO');
}
}

View File

@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
use Psl\Str;
class JoinPathsTest extends TestCase
{
public function testJoinPaths(): void
{
self::assertSame(Str\format('/home/azjezz%s/tmp', PATH_SEPARATOR), Env\join_paths('/home/azjezz', '/tmp'));
self::assertSame('/home/azjezz', Env\join_paths('/home/azjezz'));
}
}

View File

@ -0,0 +1,52 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
use Psl\Exception\InvariantViolationException;
class RemoveVarTest extends TestCase
{
/**
* @backupGlobals
*/
public function testRemoveVar(): void
{
self::assertNull(Env\get_var('FOO'));
Env\set_var('FOO', 'BAR');
self::assertSame('BAR', Env\get_var('FOO'));
Env\remove_var('FOO');
self::assertNull(Env\get_var('FOO'));
}
public function testRemoveVarThrowsIfTheKeyIsInvalid(): void
{
$this->expectException(InvariantViolationException::class);
$this->expectExceptionMessage('Invalid environment variable key provided.');
Env\remove_var('a=b');
}
public function testRemoveVarThrowsIfTheKeyIsEmpty(): void
{
$this->expectException(InvariantViolationException::class);
$this->expectExceptionMessage('Invalid environment variable key provided.');
Env\remove_var('');
}
public function testRemoveVarThrowsIfTheKeyContainsNUL(): void
{
$this->expectException(InvariantViolationException::class);
$this->expectExceptionMessage('Invalid environment variable key provided.');
Env\remove_var("\0");
}
}

View File

@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
use Psl\Str;
class SplitPathsTest extends TestCase
{
public function testSplitPaths(): void
{
self::assertSame(['/home/azjezz', '/tmp'], Env\split_paths(Str\format('/home/azjezz%s/tmp', PATH_SEPARATOR)));
self::assertSame(['/home/azjezz', '/tmp'], Env\split_paths(Env\join_paths('/home/azjezz', '/tmp')));
self::assertSame(['/home/azjezz'], Env\split_paths('/home/azjezz'));
}
}

View File

@ -0,0 +1,16 @@
<?php
declare(strict_types=1);
namespace Psl\Tests\Env;
use PHPUnit\Framework\TestCase;
use Psl\Env;
class TempDirTest extends TestCase
{
public function testTempDir(): void
{
static::assertSame(sys_get_temp_dir(), Env\temp_dir());
}
}