#Modify a file
Important: 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.