Skip to content

Commit 5bd7c8d

Browse files
First-class multiline string support
1 parent c9c7805 commit 5bd7c8d

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

src/Loader.php

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* It's responsible for loading variables by reading a file from disk and:
1212
* - stripping comments beginning with a `#`,
1313
* - parsing lines that look shell variable setters, e.g `export key = value`, `key="value"`.
14+
* - multiline variable look always start with a " and end with it, e.g: `key="value
15+
* value"`
1416
*/
1517
class Loader
1618
{
@@ -84,8 +86,15 @@ public function load()
8486

8587
$filePath = $this->filePath;
8688
$lines = $this->readLinesFromFile($filePath);
89+
90+
// multiline
91+
$multiline = false;
92+
$multilineBuffer = [];
93+
8794
foreach ($lines as $line) {
88-
if (!$this->isComment($line) && $this->looksLikeSetter($line)) {
95+
list($multiline, $line, $multilineBuffer) = $this->multilineProcess($multiline, $line, $multilineBuffer);
96+
97+
if (!$multiline && !$this->isComment($line) && $this->looksLikeSetter($line)) {
8998
$this->setEnvironmentVariable($line);
9099
}
91100
}
@@ -167,6 +176,34 @@ protected function readLinesFromFile($filePath)
167176
return $lines;
168177
}
169178

179+
/**
180+
* Used to make all multiline variable process.
181+
*
182+
* @param bool $multiline
183+
* @param string $line
184+
* @param array $buffer
185+
*
186+
* @return array
187+
*/
188+
protected function multilineProcess($multiline, $line, $buffer)
189+
{
190+
// check if $line can be multiline variable
191+
if ($this->looksLikeMultilineStart($line)) {
192+
$multiline = true;
193+
}
194+
if ($multiline) {
195+
array_push($buffer, $line);
196+
197+
if ($this->looksLikeMultilineStop($line)) {
198+
$multiline = false;
199+
$line = implode("\n", $buffer);
200+
$buffer = [];
201+
}
202+
}
203+
204+
return [$multiline, $line, $buffer];
205+
}
206+
170207
/**
171208
* Determine if the line in the file is a comment, e.g. begins with a #.
172209
*
@@ -193,6 +230,30 @@ protected function looksLikeSetter($line)
193230
return strpos($line, '=') !== false;
194231
}
195232

233+
/**
234+
* Determine if the given line can be the start of a multiline variable.
235+
*
236+
* @param string $line
237+
*
238+
* @return bool
239+
*/
240+
protected function looksLikeMultilineStart($line)
241+
{
242+
return strpos($line, '="') !== false && substr_count($line, '"') === 1;
243+
}
244+
245+
/**
246+
* Determine if the given line can be the start of a multiline variable.
247+
*
248+
* @param string $line
249+
*
250+
* @return bool
251+
*/
252+
protected function looksLikeMultilineStop($line)
253+
{
254+
return strpos($line, '"') !== false && substr_count($line, '="') === 0;
255+
}
256+
196257
/**
197258
* Split the compound string into parts.
198259
*

tests/Dotenv/DotenvTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,26 +263,38 @@ public function testDotenvAssertions()
263263
$this->assertEmpty(getenv('ASSERTVAR3'));
264264
$this->assertSame('0', getenv('ASSERTVAR4'));
265265
$this->assertSame('#foo', getenv('ASSERTVAR5'));
266+
$this->assertSame("val1\nval2", getenv('ASSERTVAR6'));
267+
$this->assertSame("val3", getenv('ASSERTVAR7'));
268+
$this->assertSame("val3", getenv('ASSERTVAR8'));
266269

267270
$dotenv->required([
268271
'ASSERTVAR1',
269272
'ASSERTVAR2',
270273
'ASSERTVAR3',
271274
'ASSERTVAR4',
272275
'ASSERTVAR5',
276+
'ASSERTVAR6',
277+
'ASSERTVAR7',
278+
'ASSERTVAR8',
279+
'ASSERTVAR9',
273280
]);
274281

275282
$dotenv->required([
276283
'ASSERTVAR1',
277284
'ASSERTVAR4',
278285
'ASSERTVAR5',
286+
'ASSERTVAR6',
287+
'ASSERTVAR7',
288+
'ASSERTVAR8',
279289
])->notEmpty();
280290

281291
$dotenv->required([
282292
'ASSERTVAR1',
283293
'ASSERTVAR4',
284294
'ASSERTVAR5',
285-
])->notEmpty()->allowedValues(['0', 'val1', '#foo']);
295+
'ASSERTVAR7',
296+
'ASSERTVAR8',
297+
])->notEmpty()->allowedValues(['0', 'val1', 'val3', '#foo']);
286298

287299
$this->assertTrue(true); // anything wrong an an exception will be thrown
288300
}

tests/fixtures/env/assertions.env

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,12 @@ ASSERTVAR1="val1"
22
ASSERTVAR2=""
33
ASSERTVAR3=" "
44
ASSERTVAR4="0" # empty looking value
5-
ASSERTVAR5=#foo
5+
ASSERTVAR5=#foo
6+
ASSERTVAR6="val1
7+
val2"
8+
ASSERTVAR7="
9+
val3" #
10+
ASSERTVAR8="val3
11+
"
12+
ASSERTVAR9="
13+
"

0 commit comments

Comments
 (0)