This commit is contained in:
2025-05-12 14:25:25 +02:00
parent ab2db755ef
commit 9e378ca2b7
2719 changed files with 46505 additions and 60181 deletions

View File

@@ -18,8 +18,8 @@
"require": {
"php": "^7.2.5 || ^8.0",
"ext-pcre": "*",
"graham-campbell/result-type": "^1.1.2",
"phpoption/phpoption": "^1.9.2",
"graham-campbell/result-type": "^1.1.3",
"phpoption/phpoption": "^1.9.3",
"symfony/polyfill-ctype": "^1.24",
"symfony/polyfill-mbstring": "^1.24",
"symfony/polyfill-php80": "^1.24"
@@ -51,7 +51,7 @@
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": true
"forward-command": false
},
"branch-alias": {
"dev-master": "5.6-dev"

View File

@@ -80,7 +80,7 @@ class Dotenv
*
* @return \Dotenv\Dotenv
*/
public static function create(RepositoryInterface $repository, $paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
public static function create(RepositoryInterface $repository, $paths, $names = null, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$builder = $names === null ? StoreBuilder::createWithDefaultName() : StoreBuilder::createWithNoNames();
@@ -109,7 +109,7 @@ class Dotenv
*
* @return \Dotenv\Dotenv
*/
public static function createMutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
public static function createMutable($paths, $names = null, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$repository = RepositoryBuilder::createWithDefaultAdapters()->make();
@@ -126,7 +126,7 @@ class Dotenv
*
* @return \Dotenv\Dotenv
*/
public static function createUnsafeMutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
public static function createUnsafeMutable($paths, $names = null, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$repository = RepositoryBuilder::createWithDefaultAdapters()
->addAdapter(PutenvAdapter::class)
@@ -145,7 +145,7 @@ class Dotenv
*
* @return \Dotenv\Dotenv
*/
public static function createImmutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
public static function createImmutable($paths, $names = null, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$repository = RepositoryBuilder::createWithDefaultAdapters()->immutable()->make();
@@ -162,7 +162,7 @@ class Dotenv
*
* @return \Dotenv\Dotenv
*/
public static function createUnsafeImmutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
public static function createUnsafeImmutable($paths, $names = null, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$repository = RepositoryBuilder::createWithDefaultAdapters()
->addAdapter(PutenvAdapter::class)
@@ -182,7 +182,7 @@ class Dotenv
*
* @return \Dotenv\Dotenv
*/
public static function createArrayBacked($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null)
public static function createArrayBacked($paths, $names = null, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make();
@@ -199,7 +199,7 @@ class Dotenv
*
* @throws \Dotenv\Exception\InvalidFileException
*
* @return array<string,string|null>
* @return array<string, string|null>
*/
public static function parse(string $content)
{
@@ -215,7 +215,7 @@ class Dotenv
*
* @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException
*
* @return array<string,string|null>
* @return array<string, string|null>
*/
public function load()
{
@@ -229,7 +229,7 @@ class Dotenv
*
* @throws \Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException
*
* @return array<string,string|null>
* @return array<string, string|null>
*/
public function safeLoad()
{

View File

@@ -19,10 +19,11 @@ final class Loader implements LoaderInterface
* @param \Dotenv\Repository\RepositoryInterface $repository
* @param \Dotenv\Parser\Entry[] $entries
*
* @return array<string,string|null>
* @return array<string, string|null>
*/
public function load(RepositoryInterface $repository, array $entries)
{
/** @var array<string, string|null> */
return \array_reduce($entries, static function (array $vars, Entry $entry) use ($repository) {
$name = $entry->getName();

View File

@@ -14,7 +14,7 @@ interface LoaderInterface
* @param \Dotenv\Repository\RepositoryInterface $repository
* @param \Dotenv\Parser\Entry[] $entries
*
* @return array<string,string|null>
* @return array<string, string|null>
*/
public function load(RepositoryInterface $repository, array $entries);
}

View File

@@ -55,8 +55,8 @@ final class Resolver
return Regex::replaceCallback(
'/\A\${([a-zA-Z0-9_.]+)}/',
static function (array $matches) use ($repository) {
return Option::fromValue($repository->get($matches[1]))
->getOrElse($matches[0]);
/** @var string */
return Option::fromValue($repository->get($matches[1]))->getOrElse($matches[0]);
},
$str,
1

View File

@@ -30,7 +30,7 @@ final class Entry
*
* @return void
*/
public function __construct(string $name, Value $value = null)
public function __construct(string $name, ?Value $value = null)
{
$this->name = $name;
$this->value = $value;

View File

@@ -41,7 +41,7 @@ final class EntryParser
*
* @param string $entry
*
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry,string>
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry, string>
*/
public static function parse(string $entry)
{
@@ -49,7 +49,7 @@ final class EntryParser
[$name, $value] = $parts;
return self::parseName($name)->flatMap(static function (string $name) use ($value) {
/** @var Result<Value|null,string> */
/** @var Result<Value|null, string> */
$parsedValue = $value === null ? Success::create(null) : self::parseValue($value);
return $parsedValue->map(static function (?Value $value) use ($name) {
@@ -64,21 +64,21 @@ final class EntryParser
*
* @param string $line
*
* @return \GrahamCampbell\ResultType\Result<array{string,string|null},string>
* @return \GrahamCampbell\ResultType\Result<array{string, string|null},string>
*/
private static function splitStringIntoParts(string $line)
{
/** @var array{string,string|null} */
/** @var array{string, string|null} */
$result = Str::pos($line, '=')->map(static function () use ($line) {
return \array_map('trim', \explode('=', $line, 2));
})->getOrElse([$line, null]);
if ($result[0] === '') {
/** @var \GrahamCampbell\ResultType\Result<array{string,string|null},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, string|null},string> */
return Error::create(self::getErrorMessage('an unexpected equals', $line));
}
/** @var \GrahamCampbell\ResultType\Result<array{string,string|null},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, string|null},string> */
return Success::create($result);
}
@@ -90,7 +90,7 @@ final class EntryParser
*
* @param string $name
*
* @return \GrahamCampbell\ResultType\Result<string,string>
* @return \GrahamCampbell\ResultType\Result<string, string>
*/
private static function parseName(string $name)
{
@@ -103,11 +103,11 @@ final class EntryParser
}
if (!self::isValidName($name)) {
/** @var \GrahamCampbell\ResultType\Result<string,string> */
/** @var \GrahamCampbell\ResultType\Result<string, string> */
return Error::create(self::getErrorMessage('an invalid name', $name));
}
/** @var \GrahamCampbell\ResultType\Result<string,string> */
/** @var \GrahamCampbell\ResultType\Result<string, string> */
return Success::create($name);
}
@@ -152,12 +152,12 @@ final class EntryParser
*
* @param string $value
*
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string>
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value, string>
*/
private static function parseValue(string $value)
{
if (\trim($value) === '') {
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value, string> */
return Success::create(Value::blank());
}
@@ -170,11 +170,11 @@ final class EntryParser
}, Success::create([Value::blank(), self::INITIAL_STATE]))->flatMap(static function (array $result) {
/** @psalm-suppress DocblockTypeContradiction */
if (in_array($result[1], self::REJECT_STATES, true)) {
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value, string> */
return Error::create('a missing closing quote');
}
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value, string> */
return Success::create($result[0]);
})->mapError(static function (string $err) use ($value) {
return self::getErrorMessage($err, $value);
@@ -187,94 +187,94 @@ final class EntryParser
* @param int $state
* @param string $token
*
* @return \GrahamCampbell\ResultType\Result<array{string,bool,int},string>
* @return \GrahamCampbell\ResultType\Result<array{string, bool, int}, string>
*/
private static function processToken(int $state, string $token)
{
switch ($state) {
case self::INITIAL_STATE:
if ($token === '\'') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::SINGLE_QUOTED_STATE]);
} elseif ($token === '"') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::DOUBLE_QUOTED_STATE]);
} elseif ($token === '#') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::COMMENT_STATE]);
} elseif ($token === '$') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, true, self::UNQUOTED_STATE]);
} else {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, false, self::UNQUOTED_STATE]);
}
case self::UNQUOTED_STATE:
if ($token === '#') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::COMMENT_STATE]);
} elseif (\ctype_space($token)) {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::WHITESPACE_STATE]);
} elseif ($token === '$') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, true, self::UNQUOTED_STATE]);
} else {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, false, self::UNQUOTED_STATE]);
}
case self::SINGLE_QUOTED_STATE:
if ($token === '\'') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::WHITESPACE_STATE]);
} else {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, false, self::SINGLE_QUOTED_STATE]);
}
case self::DOUBLE_QUOTED_STATE:
if ($token === '"') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::WHITESPACE_STATE]);
} elseif ($token === '\\') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::ESCAPE_SEQUENCE_STATE]);
} elseif ($token === '$') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, true, self::DOUBLE_QUOTED_STATE]);
} else {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]);
}
case self::ESCAPE_SEQUENCE_STATE:
if ($token === '"' || $token === '\\') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]);
} elseif ($token === '$') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]);
} else {
$first = Str::substr($token, 0, 1);
if (\in_array($first, ['f', 'n', 'r', 't', 'v'], true)) {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create([\stripcslashes('\\'.$first).Str::substr($token, 1), false, self::DOUBLE_QUOTED_STATE]);
} else {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Error::create('an unexpected escape sequence');
}
}
case self::WHITESPACE_STATE:
if ($token === '#') {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::COMMENT_STATE]);
} elseif (!\ctype_space($token)) {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Error::create('unexpected whitespace');
} else {
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::WHITESPACE_STATE]);
}
case self::COMMENT_STATE:
/** @var \GrahamCampbell\ResultType\Result<array{string,bool,int},string> */
/** @var \GrahamCampbell\ResultType\Result<array{string, bool, int}, string> */
return Success::create(['', false, self::COMMENT_STATE]);
default:
throw new \Error('Parser entered invalid state.');

View File

@@ -54,7 +54,7 @@ final class Lines
* @param string $line
* @param string[] $buffer
*
* @return array{bool,string,string[]}
* @return array{bool,string, string[]}
*/
private static function multilineProcess(bool $multiline, string $line, array $buffer)
{

View File

@@ -36,11 +36,11 @@ final class Parser implements ParserInterface
*
* @param string[] $entries
*
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[],string>
* @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[], string>
*/
private static function process(array $entries)
{
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[],string> */
/** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[], string> */
return \array_reduce($entries, static function (Result $result, string $raw) {
return $result->flatMap(static function (array $entries) use ($raw) {
return EntryParser::parse($raw)->map(static function (Entry $entry) use ($entries) {

View File

@@ -12,7 +12,7 @@ final class ArrayAdapter implements AdapterInterface
/**
* The variables and their values.
*
* @var array<string,string>
* @var array<string, string>
*/
private $variables;

View File

@@ -23,7 +23,7 @@ final class ImmutableWriter implements WriterInterface
/**
* The record of loaded variables.
*
* @var array<string,string>
* @var array<string, string>
*/
private $loaded;

View File

@@ -23,7 +23,7 @@ final class ReplacingWriter implements WriterInterface
/**
* The record of seen variables.
*
* @var array<string,string>
* @var array<string, string>
*/
private $seen;

View File

@@ -65,7 +65,7 @@ final class RepositoryBuilder
*
* @return void
*/
private function __construct(array $readers = [], array $writers = [], bool $immutable = false, array $allowList = null)
private function __construct(array $readers = [], array $writers = [], bool $immutable = false, ?array $allowList = null)
{
$this->readers = $readers;
$this->writers = $writers;
@@ -244,7 +244,7 @@ final class RepositoryBuilder
*
* @return \Dotenv\Repository\RepositoryBuilder
*/
public function allowList(array $allowList = null)
public function allowList(?array $allowList = null)
{
return new self($this->readers, $this->writers, $this->immutable, $allowList);
}

View File

@@ -38,9 +38,9 @@ final class Reader
*
* @throws \Dotenv\Exception\InvalidEncodingException
*
* @return array<string,string>
* @return array<string, string>
*/
public static function read(array $filePaths, bool $shortCircuit = true, string $fileEncoding = null)
public static function read(array $filePaths, bool $shortCircuit = true, ?string $fileEncoding = null)
{
$output = [];
@@ -67,7 +67,7 @@ final class Reader
*
* @return \PhpOption\Option<string>
*/
private static function readFromFile(string $path, string $encoding = null)
private static function readFromFile(string $path, ?string $encoding = null)
{
/** @var Option<string> */
$content = Option::fromValue(@\file_get_contents($path), false);

View File

@@ -39,7 +39,7 @@ final class FileStore implements StoreInterface
*
* @return void
*/
public function __construct(array $filePaths, bool $shortCircuit, string $fileEncoding = null)
public function __construct(array $filePaths, bool $shortCircuit, ?string $fileEncoding = null)
{
$this->filePaths = $filePaths;
$this->shortCircuit = $shortCircuit;

View File

@@ -51,7 +51,7 @@ final class StoreBuilder
*
* @return void
*/
private function __construct(array $paths = [], array $names = [], bool $shortCircuit = false, string $fileEncoding = null)
private function __construct(array $paths = [], array $names = [], bool $shortCircuit = false, ?string $fileEncoding = null)
{
$this->paths = $paths;
$this->names = $names;
@@ -120,7 +120,7 @@ final class StoreBuilder
*
* @return \Dotenv\Store\StoreBuilder
*/
public function fileEncoding(string $fileEncoding = null)
public function fileEncoding(?string $fileEncoding = null)
{
return new self($this->paths, $this->names, $this->shortCircuit, $fileEncoding);
}

View File

@@ -30,7 +30,7 @@ final class Regex
* @param string $pattern
* @param string $subject
*
* @return \GrahamCampbell\ResultType\Result<bool,string>
* @return \GrahamCampbell\ResultType\Result<bool, string>
*/
public static function matches(string $pattern, string $subject)
{
@@ -45,7 +45,7 @@ final class Regex
* @param string $pattern
* @param string $subject
*
* @return \GrahamCampbell\ResultType\Result<int,string>
* @return \GrahamCampbell\ResultType\Result<int, string>
*/
public static function occurrences(string $pattern, string $subject)
{
@@ -57,14 +57,14 @@ final class Regex
/**
* Perform a preg replace callback, wrapping up the result.
*
* @param string $pattern
* @param callable $callback
* @param string $subject
* @param int|null $limit
* @param string $pattern
* @param callable(string[]): string $callback
* @param string $subject
* @param int|null $limit
*
* @return \GrahamCampbell\ResultType\Result<string,string>
* @return \GrahamCampbell\ResultType\Result<string, string>
*/
public static function replaceCallback(string $pattern, callable $callback, string $subject, int $limit = null)
public static function replaceCallback(string $pattern, callable $callback, string $subject, ?int $limit = null)
{
return self::pregAndWrap(static function (string $subject) use ($pattern, $callback, $limit) {
return (string) @\preg_replace_callback($pattern, $callback, $subject, $limit ?? -1);
@@ -77,7 +77,7 @@ final class Regex
* @param string $pattern
* @param string $subject
*
* @return \GrahamCampbell\ResultType\Result<string[],string>
* @return \GrahamCampbell\ResultType\Result<string[], string>
*/
public static function split(string $pattern, string $subject)
{
@@ -92,10 +92,10 @@ final class Regex
*
* @template V
*
* @param callable(string):V $operation
* @param string $subject
* @param callable(string): V $operation
* @param string $subject
*
* @return \GrahamCampbell\ResultType\Result<V,string>
* @return \GrahamCampbell\ResultType\Result<V, string>
*/
private static function pregAndWrap(callable $operation, string $subject)
{

View File

@@ -31,19 +31,28 @@ final class Str
* @param string $input
* @param string|null $encoding
*
* @return \GrahamCampbell\ResultType\Result<string,string>
* @return \GrahamCampbell\ResultType\Result<string, string>
*/
public static function utf8(string $input, string $encoding = null)
public static function utf8(string $input, ?string $encoding = null)
{
if ($encoding !== null && !\in_array($encoding, \mb_list_encodings(), true)) {
/** @var \GrahamCampbell\ResultType\Result<string,string> */
/** @var \GrahamCampbell\ResultType\Result<string, string> */
return Error::create(
\sprintf('Illegal character encoding [%s] specified.', $encoding)
);
}
$converted = $encoding === null ?
@\mb_convert_encoding($input, 'UTF-8') :
@\mb_convert_encoding($input, 'UTF-8', $encoding);
if (!is_string($converted)) {
/** @var \GrahamCampbell\ResultType\Result<string, string> */
return Error::create(
\sprintf('Conversion from encoding [%s] failed.', $encoding ?? 'NULL')
);
}
/**
* this is for support UTF-8 with BOM encoding
* @see https://en.wikipedia.org/wiki/Byte_order_mark
@@ -52,7 +61,8 @@ final class Str
if (\substr($converted, 0, 3) == "\xEF\xBB\xBF") {
$converted = \substr($converted, 3);
}
/** @var \GrahamCampbell\ResultType\Result<string,string> */
/** @var \GrahamCampbell\ResultType\Result<string, string> */
return Success::create($converted);
}
@@ -79,7 +89,7 @@ final class Str
*
* @return string
*/
public static function substr(string $input, int $start, int $length = null)
public static function substr(string $input, int $start, ?int $length = null)
{
return \mb_substr($input, $start, $length, 'UTF-8');
}

View File

@@ -31,8 +31,6 @@ class Validator
* @param \Dotenv\Repository\RepositoryInterface $repository
* @param string[] $variables
*
* @throws \Dotenv\Exception\ValidationException
*
* @return void
*/
public function __construct(RepositoryInterface $repository, array $variables)