Modify a file¶
You can't modify a file in place, meaning you can't read and write to the same file at once. You need to write to a different file first.
Replace a line¶
use Innmind\Filesystem\{
Adapter\Filesystem,
File,
Name,
};
use Innmind\Url\Path;
use Innmind\Immutable\{
Str,
Predicate\Instance,
};
// replace the "unreleased" title with the new version
$insertRelease = static function(Str $line): Str {
if ($line->startsWith('## [Unreleased]')) {
return Str::of('## 1.0.0 - 2022-01-30');
}
return $line;
};
// replace the old changelog with the new one containing
// the new release version
$release = static function(File $changelog) use ($insertRelease): File {
return $changelog->withContent(
$changelog->content()->map(
static fn($line) => $line->map($insertRelease),
),
);
}
$filesystem = Filesystem::mount(Path::of('some/repository/'));
$tmp = Filesystem::mount(Path::of('/tmp/'));
$filesystem
->get(Name::of('CHANGELOG.md'))
->keep(Instance::of(File::class))
->map($release)
->flatMap(static function($changelog) use ($tmp) {
// this operation is due to the fact that you cannot read and
// write to the same file at once
$tmp->add($changelog);
return $tmp->get($changelog->name());
})
->match(
static fn($changelog) => $filesystem->add($changelog),
static fn() => null, // the changelog doesn't exist
);
This example modifies the CHANGELOG.md
file to replace the ## [Unreleased]
title with a version number.
Insert a new line¶
use Innmind\Filesystem\{
Adapter\Filesystem,
File,
File\Content,
File\Content\Line,
Name,
};
use Innmind\Url\Path;
use Innmind\Immutable\{
Sequence,
Str,
Predicate\Instance,
};
// Insert "Jane Doe" after the user "John Doe"
$updateUser = static function(Line $user): Content {
if ($user->toString() === 'John Doe') {
return Content::ofLines(Sequence::of(
$user,
Line::of(Str::of('Jane Doe')),
));
}
return Content::ofLines(Sequence::of($user));
};
$update = static function(File $users) use ($updateUser): File {
return $users->withContent(
$users->content()->flatMap(static fn($line) => $updateUser($line)),
);
};
$filesystem = Filesystem::mount(Path::of('/var/data/'));
$tmp = Filesystem::mount(Path::of('/tmp/'));
$filesystem
->get(Name::of('users.csv'))
->keep(Instance::of(File::class))
->map($update)
->flatMap(static function($users) use ($tmp) {
// this operation is due to the fact that you cannot read and
// write to the same file at once
$tmp->add($users);
return $tmp->get($users->name());
})
->match(
static fn($users) => $filesystem->add($users),
static fn() => null, // the csv doesn't exist
);
This example will insert the user Jane Doe
after John Doe
wherever he is in the users.csv
file. If the file doesn't exist then nothing happens.
Merge two files¶
use Innmind\Filesystem\{
Adapter\Filesystem,
File,
File\Content,
Name,
};
use Innmind\Url\Path;
use Innmind\Immutable\{
Maybe,
Predicate\Instance,
};
$merge = static function(File $file1, File $file2): File {
return File::named(
'all_users.csv',
Content::ofLines(
$file1->content()->lines()->append(
$file2->content()->lines(),
),
),
);
};
$filesystem = Filesystem::mount(Path::of('/var/data/'));
$users1 = $filesystem
->get(Name::of('users1.csv'))
->keep(Instance::of(File::class));
$users2 = $filesystem
->get(Name::of('users2.csv'))
->keep(Instance::of(File::class));
Maybe::all($users1, $users2)
->map(static fn($file1, $file2) => $merge($file1, $file2))
->match(
static fn($merged) => $filesystem->add($merged),
static fn() => null,
);
This example will create a file all_users.csv
containing both files users1.csv
and users2.csv
. If one of the files or both of them doesn't exist then the new file won't be created.