Plan: apply() darf den Wert nicht als Regex-Ersatz behandeln
preg_replace deutet $1, \1 und \\ im ERSATZ als Rueckverweise, auch ohne Gruppen im Muster. Der Wert kommt von der Befehlszeile, das Ziel ist die Datei mit allen Zugangsdaten, und das Ergebnis waere still verstuemmelt statt abgelehnt — isValidLine() sieht weiterhin ein gueltiges KEY=value. Jetzt zeilenweise, ohne Regex auf dem Schreibweg. Dazu faengt der Befehl InvalidEnvContentException ab, statt dem Betreiber einen Stapelabzug zu zeigen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>feat/versandtakt
parent
d90676632e
commit
5c9ee2c6d5
|
|
@ -729,6 +729,7 @@ Datei `app/Console/Commands/BindHosts.php`:
|
|||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\Env\EnvFileEditor;
|
||||
use App\Services\Env\InvalidEnvContentException;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
|
|
@ -821,7 +822,16 @@ class BindHosts extends Command
|
|||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$backup = $env->write($this->apply($content, $missing));
|
||||
try {
|
||||
$backup = $env->write($this->apply($content, $missing));
|
||||
} catch (InvalidEnvContentException $e) {
|
||||
// Abgelehnt heißt hier: NICHTS geschrieben, und die Sicherung ist
|
||||
// erst gar nicht angelegt worden — der Editor prüft vor beidem.
|
||||
// Der Betreiber soll das als Satz erfahren, nicht als Stapelabzug.
|
||||
$this->error('Die Datei wurde nicht geschrieben: '.$e->getMessage());
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info('Geschrieben. Die vorherige Fassung liegt unter '.$backup);
|
||||
$this->line('Danach: php artisan config:cache && php artisan route:cache');
|
||||
|
|
@ -850,6 +860,12 @@ class BindHosts extends Command
|
|||
/**
|
||||
* Vorhandene Zeile ersetzen, sonst anhängen.
|
||||
*
|
||||
* Zeilenweise und ohne `preg_replace`: der Wert kommt von der Befehlszeile,
|
||||
* und `preg_replace` deutet `$1`, `\1` und `\\` im ERSATZ als Rückverweise.
|
||||
* Aus `--site 'www.example.test$1'` würde still `SITE_HOST=www.example.test`
|
||||
* — und diese Datei hält jedes Geheimnis dieser Installation. Ein leise
|
||||
* verstümmelter Wert darin ist schlimmer als eine Fehlermeldung.
|
||||
*
|
||||
* Ersetzen und nicht nur anhängen, weil ein leerer Schlüssel als fehlend
|
||||
* gilt: `APP_HOST=` steht dann schon da, und ein zweites `APP_HOST=…`
|
||||
* darunter wäre eine Datei mit zwei Antworten auf dieselbe Frage.
|
||||
|
|
@ -858,16 +874,25 @@ class BindHosts extends Command
|
|||
*/
|
||||
private function apply(string $content, array $values): string
|
||||
{
|
||||
foreach ($values as $key => $value) {
|
||||
$line = $key.'='.$value;
|
||||
$pattern = '/^'.preg_quote($key, '/').'=.*$/m';
|
||||
$lines = preg_split('/\R/', rtrim($content, "\r\n"));
|
||||
|
||||
$content = preg_match($pattern, $content) === 1
|
||||
? preg_replace($pattern, $line, $content, 1)
|
||||
: rtrim($content, "\n")."\n".$line."\n";
|
||||
foreach ($values as $key => $value) {
|
||||
$replaced = false;
|
||||
|
||||
foreach ($lines as $index => $line) {
|
||||
if (str_starts_with($line, $key.'=')) {
|
||||
$lines[$index] = $key.'='.$value;
|
||||
$replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! $replaced) {
|
||||
$lines[] = $key.'='.$value;
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
return implode("\n", $lines)."\n";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
|||
Loading…
Reference in New Issue