Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e090e9a
require php 8.4
Baptouuuu Nov 3, 2025
ccd068d
update dependencies
Baptouuuu Nov 3, 2025
8753d1b
bump static analysis
Baptouuuu Dec 11, 2025
dabbd10
remove warnings
Baptouuuu Dec 11, 2025
913b193
add Files::require()
Baptouuuu Dec 11, 2025
eaff2ff
let Attempts throw exceptions
Baptouuuu Dec 11, 2025
591deed
remove unused exception
Baptouuuu Dec 11, 2025
eac9e20
allow io capabilities composition
Baptouuuu Dec 11, 2025
69dcc98
add missing classes
Baptouuuu Dec 11, 2025
ce2b6eb
remove unused method
Baptouuuu Dec 11, 2025
df25b75
simplify type juggling
Baptouuuu Dec 13, 2025
777af53
add Files::mediaType() and Files::list()
Baptouuuu Dec 13, 2025
cde3a70
add missing class
Baptouuuu Dec 13, 2025
858aa89
add Files::exists()
Baptouuuu Dec 13, 2025
0c796a3
add Files::create()
Baptouuuu Dec 14, 2025
5b609bd
add Files::remove()
Baptouuuu Dec 14, 2025
2cfed6d
fix logic to remove directories when a / is missing
Baptouuuu Dec 14, 2025
1eb1073
better split the responsibilities on what can be done to which kind o…
Baptouuuu Dec 14, 2025
1b404fc
give access to the kind of created file
Baptouuuu Dec 14, 2025
3fed078
remove assumptions that links are not usable
Baptouuuu Dec 14, 2025
270f3c9
only allow to remove files and directories
Baptouuuu Dec 14, 2025
9aa756b
remove experimental flag
Baptouuuu Dec 14, 2025
45005a5
update changelog
Baptouuuu Dec 14, 2025
b863639
lay the structure for simulated files
Baptouuuu Dec 14, 2025
3e5a06b
make sure the directory path always end with a /
Baptouuuu Dec 14, 2025
e867073
forward simulated files capabilities to a simulated disk
Baptouuuu Dec 14, 2025
38f9c2d
add IO::simulation()
Baptouuuu Dec 14, 2025
5989eb2
typo
Baptouuuu Dec 14, 2025
aeb9c75
implement simulation disk
Baptouuuu Dec 14, 2025
ecb644e
Merge branch 'simulation' into next
Baptouuuu Dec 14, 2025
5e4b69f
extract stream implementation into a sub class
Baptouuuu Dec 15, 2025
a56e888
rename Native to AmbientAuthority for consistency
Baptouuuu Dec 15, 2025
dbaa209
prevent the simulated stream from being really closed
Baptouuuu Dec 15, 2025
de8f953
tag dependencies
Baptouuuu Jan 25, 2026
f2acbdd
replace time-continuum by time
Baptouuuu Jan 25, 2026
5f5f781
flag simulation disk as internal
Baptouuuu Jan 25, 2026
3707f2f
fix documentation
Baptouuuu Jan 25, 2026
abd238b
add extensive CI
Baptouuuu Jan 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/tests export-ignore
/fixtures export-ignore
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,3 @@ jobs:
uses: innmind/github-workflows/.github/workflows/psalm-matrix.yml@main
cs:
uses: innmind/github-workflows/.github/workflows/cs.yml@main
with:
php-version: '8.2'
12 changes: 12 additions & 0 deletions .github/workflows/extensive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Extensive CI

on:
push:
tags:
- '*'
paths:
- '.github/workflows/extensive.yml'

jobs:
blackbox:
uses: innmind/github-workflows/.github/workflows/extensive.yml@main
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## [Unreleased]

### Added

- `Innmind\IO\Files::require()`
- `Innmind\IO\Files::access()`
- `Innmind\IO\Files::create()`
- `Innmind\IO\Files::exists()`

### Changed

- Requires PHP `8.4`
- Requires `innmind/immutable:~6.0`
- Requires `innmind/time:~1.0`

## 3.5.1 - 2025-08-18

### Fixed
Expand Down
4 changes: 4 additions & 0 deletions blackbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
};

Application::new($argv)
->when(
\getenv('BLACKBOX_SET_SIZE') !== false,
static fn(Application $app) => $app->scenariiPerProof((int) \getenv('BLACKBOX_SET_SIZE')),
)
->when(
\getenv('ENABLE_COVERAGE') !== false,
static fn(Application $app) => $app
Expand Down
15 changes: 8 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
"issues": "http://github.com/innmind/io/issues"
},
"require": {
"php": "~8.2",
"innmind/immutable": "~5.13",
"innmind/url": "~4.3",
"innmind/time-continuum": "^4.0.2",
"innmind/ip": "~3.2",
"innmind/validation": "~2.0"
"php": "~8.4",
"innmind/immutable": "~6.0",
"innmind/mutable": "~1.0",
"innmind/url": "~5.0",
"innmind/time": "~1.0",
"innmind/ip": "~4.0",
"innmind/validation": "~3.0"
},
"autoload": {
"psr-4": {
Expand All @@ -33,7 +34,7 @@
}
},
"require-dev": {
"innmind/static-analysis": "^1.2.1",
"innmind/static-analysis": "~1.3",
"innmind/black-box": "~6.1",
"innmind/coding-standard": "~2.0"
}
Expand Down
4 changes: 2 additions & 2 deletions documentation/sockets.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ This is the default behaviour.
### `->timeoutAfter()`

```php
use Innmind\TimeContinuum\Period;
use Innmind\Time\Period;

$server = $server->timeoutAfter(Period::second(1));
```
Expand Down Expand Up @@ -172,7 +172,7 @@ This is default behaviour.
### `->timeoutAfter()`

```php
use Innmind\TimeContinuum\Period;
use Innmind\Time\Period;

$client = $client->timeoutAfter(Period::second(1));
```
Expand Down
2 changes: 1 addition & 1 deletion documentation/streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ This is default behaviour.
### `->timeoutAfter()`

```php
use Innmind\TimeContinuum\Period;
use Innmind\Time\Period;

$read = $read->timeoutAfter(Period::second(1));
```
Expand Down
2 changes: 1 addition & 1 deletion documentation/use-cases/socket/heartbeat.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use Innmind\IO\{
Frame,
Sockets\Internet\Transport,
};
use Innmind\TimeContinuum\Period;
use Innmind\Time\Period;
use Innmind\Url\Url;
use Innmind\Immutable\{
Str,
Expand Down
2 changes: 1 addition & 1 deletion documentation/use-cases/socket/read.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use Innmind\IO\{
Frame,
Sockets\Internet\Transport,
};
use Innmind\TimeContinuum\Period;
use Innmind\Time\Period;
use Innmind\Url\Url;

$status = IO::fromAmbienAuthority()
Expand Down
3 changes: 3 additions & 0 deletions fixtures/to-load.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

return 42;
43 changes: 34 additions & 9 deletions proofs/files.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static function($assert, $chunks, $size) {
->number($loaded->size())
->int()
->greaterThan(0);
$loaded
$_ = $loaded
->dropEnd(1)
->foreach(static fn($chunk) => $assert->same(
$size,
Expand All @@ -72,7 +72,7 @@ static function($assert, $chunks, $size) {
$assert->same(
$data,
$loaded
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);
},
Expand All @@ -90,7 +90,7 @@ static function($assert, $chunks, $size, $encoding) {
$data = \implode('', $chunks);
\file_put_contents($tmp, $data);

IO::fromAmbientAuthority()
$_ = IO::fromAmbientAuthority()
->files()
->read(Path::of($tmp))
->toEncoding($encoding)
Expand Down Expand Up @@ -128,7 +128,7 @@ static function($assert, $lines) {
->number($loaded->size())
->int()
->greaterThan(0);
$loaded
$_ = $loaded
->dropEnd(1)
->foreach(static fn($line) => $assert->true(
$line->endsWith("\n"),
Expand All @@ -143,7 +143,7 @@ static function($assert, $lines) {
$assert->same(
$data,
$loaded
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);

Expand Down Expand Up @@ -175,7 +175,7 @@ static function($assert, $lines, $encoding) {
$data = \implode("\n", $lines);
\file_put_contents($tmp, $data);

IO::fromAmbientAuthority()
$_ = IO::fromAmbientAuthority()
->files()
->read(Path::of($tmp))
->toEncoding($encoding)
Expand Down Expand Up @@ -298,14 +298,14 @@ static function($assert, $chunks) {
$expected,
$read
->lines()
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);
$assert->same(
$expected,
$read
->lines()
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
'Temporary file should be accessible multiple times',
);
Expand Down Expand Up @@ -386,7 +386,7 @@ static function($assert, $chunks, $encoding) {
$tmp
->read()
->chunks(8192)
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);
},
Expand Down Expand Up @@ -430,4 +430,29 @@ static function($assert, $chunks) {
);
},
);

yield test(
'IO::files()->require()',
static function($assert) {
$assert->same(
42,
IO::fromAmbientAuthority()
->files()
->require(Path::of('fixtures/to-load.php'))
->match(
static fn($value) => $value,
static fn() => null,
),
);
$assert->false(
IO::fromAmbientAuthority()
->files()
->require(Path::of('fixtures/unknown.php'))
->match(
static fn() => true,
static fn() => false,
),
);
},
);
};
2 changes: 1 addition & 1 deletion proofs/frames.php
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ static function($assert, $lines) use ($reader) {
->maybe(static fn($lines, $line) => $line->maybe()->map($lines)),
)
->flatMap(Frame::maybe(...));
$values = $frame($reader(Str::of($data)))->match(
$values = $frame($reader(Str::of($data, Str\Encoding::ascii)))->match(
static fn($values) => $values,
static fn() => null,
);
Expand Down
6 changes: 3 additions & 3 deletions proofs/sockets.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Frame,
Sockets\Unix\Address,
};
use Innmind\TimeContinuum\Period;
use Innmind\Time\Period;
use Innmind\Url\Path;
use Innmind\Immutable\{
Sequence,
Expand Down Expand Up @@ -99,8 +99,8 @@ static function($assert) {
);

$assert->same('foo', $result);
$client->close()->memoize();
$server->close()->memoize();
$_ = $client->close()->memoize();
$_ = $server->close()->memoize();
},
);
};
10 changes: 5 additions & 5 deletions proofs/streams.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ static function($assert, $lines) {
$assert->same(
\implode("\n", $lines),
$load()
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);
},
Expand Down Expand Up @@ -207,7 +207,7 @@ static function($assert, $lines) {
$assert->same(
\implode("\n", $lines),
$load()
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);
},
Expand Down Expand Up @@ -248,7 +248,7 @@ static function($assert, $lines) {
$assert->same(
\implode("\n", $lines),
$sequence
->fold(new Concat)
->fold(Concat::monoid)
->toString(),
);
},
Expand Down Expand Up @@ -285,7 +285,7 @@ static function($assert, $a, $b, $encoding) {
->chunks();

$assert->same(2, $chunks->size());
$chunks->foreach(static fn($chunk) => $assert->same(
$_ = $chunks->foreach(static fn($chunk) => $assert->same(
$encoding,
$chunk->value()->encoding(),
));
Expand Down Expand Up @@ -338,7 +338,7 @@ static function($assert, $a, $b, $encoding) {
->chunks();

$assert->same(2, $chunks->size());
$chunks->foreach(static fn($chunk) => $assert->same(
$_ = $chunks->foreach(static fn($chunk) => $assert->same(
$encoding,
$chunk->value()->encoding(),
));
Expand Down
8 changes: 0 additions & 8 deletions src/Exception/FailedToLoadStream.php

This file was deleted.

49 changes: 49 additions & 0 deletions src/Files.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
Files\Read,
Files\Temporary,
Files\Write,
Files\File,
Files\Directory,
Files\Link,
Files\Kind,
Internal\Capabilities,
};
use Innmind\Url\Path;
use Innmind\Immutable\{
Str,
Attempt,
Maybe,
Sequence,
};

Expand Down Expand Up @@ -41,6 +46,14 @@ public function write(Path $path): Write
return Write::of($this->capabilities, $path);
}

/**
* @return Maybe<mixed>
*/
public function require(Path $path): Maybe
{
return $this->capabilities->files()->require($path);
}

/**
* @param Sequence<Str> $chunks
*
Expand All @@ -60,4 +73,40 @@ public function temporary(Sequence $chunks): Attempt
->map(static fn() => Temporary::of($capabilities, $tmp)),
);
}

/**
* @return Attempt<File|Directory|Link>
*/
public function access(Path $path): Attempt
{
return $this
->capabilities
->files()
->kind($path)
->map(fn($kind) => match ($kind) {
Kind::directory => Directory::of($this->capabilities, $path),
Kind::file => File::of($this->capabilities, $path),
Kind::link => Link::of(),
});
}

/**
* @return Attempt<File|Directory>
*/
public function create(Path $path): Attempt
{
return $this
->capabilities
->files()
->create($path)
->map(fn() => match ($path->directory()) {
true => Directory::of($this->capabilities, $path),
false => File::of($this->capabilities, $path),
});
}

public function exists(Path $path): bool
{
return $this->capabilities->files()->exists($path);
}
}
Loading