Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
* develop: (35 commits)
  remove dead code
  only cover the sources
  add use case
  specify next release
  typo
  add missing types
  update documentation
  change assertion method to display invalid generated data
  remove tests already covered by the Content properties
  remove unused lazy stream
  remove Content\OfStream
  add Content::oneShot()
  update license
  make sure there is always at least 1 chunk
  make sure Content::ofLines() and ::ofChunks() hold the properties
  make sure Content::none() hold the properties
  rename Content\IO to Content\AtPath
  remove unused Content\AtPath
  add Content\IO
  add File\Content properties
  ...
  • Loading branch information
Baptouuuu committed Oct 21, 2023
2 parents 61d8e34 + f4fe99c commit b899174
Show file tree
Hide file tree
Showing 84 changed files with 1,747 additions and 2,941 deletions.
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,34 @@
# Changelog

## 7.0.0 - 2023-10-21

### Added

- `Innmind\Filesystem\File\Content::chunks()`

### Changed

- `Innmind\Filesystem\Name` constructor is now private, use `::of()` named constructor instead
- `Innmind\Filesystem\File\File` constructor is now private, use `::of()` named constructor instead
- `Innmind\Filesystem\File\Content` is now a final class and its different implementations are declared internal, use the `Content` named constructors instead
- `Innmind\Filesystem\Directory` no longer extends `File`, all previous function typed against `File` are now typed `File|Directory`
- `Innmind\Filesystem\File` is now a final class instead of an interface
- `Innmind\Filesystem\Directory` is now a final class instead of an interface
- `Innmind\Filesystem\Directory::files()` has been renamed to `::all()`

### Fixed

- An inconsistency in `File\Content` that must contain at least one line but it wasn't applied after a `Content::filter()`

### Removed

- `Innmind\Filesystem\Adapter\HashedName`
- `Innmind\Filesystem\Adapter::all()`
- `Innmind\Filesystem\Chunk`
- `Innmind\Filesystem\File\Content\Chunkable`
- Possibility to use a `Innmind\Immutable\Set` of files inside a `Directory`
- `Innmind\Filesystem\Stream\LazyStream`

## 6.6.0 - 2023-09-16

### Added
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016
Copyright (c) 2023

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,17 @@ The whole model is structured around files, directories, contents and adapters.
Example:
```php
use Innmind\Filesystem\{
File\File,
File,
File\Content,
Directory\Directory,
Directory,
Adapter\Filesystem,
};
use Innmind\Url\Path;

$directory = Directory::named('uploads')->add(
File::named(
$_FILES['my_upload']['name'],
Content\AtPath::of(Path::of($_FILES['my_upload']['tmp_name'])),
Content::ofString(\file_get_contents($_FILES['my_upload']['tmp_name'])),
),
);
$adapter = Filesystem::mount(Path::of('/var/www/web/'));
Expand Down
5 changes: 1 addition & 4 deletions blackbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
Runner\CodeCoverage,
};

// because the generated trees can be quite large
\ini_set('memory_limit', '-1');

Application::new($argv)
->disableMemoryLimit()
->disableMemoryLimit() // because the generated trees can be quite large
->scenariiPerProof(20)
->when(
\getenv('ENABLE_COVERAGE') !== false,
Expand Down
3 changes: 3 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
ignore:
- proofs/*
- fixtures/*
- properties/*
- properties/**/*
- .php-cs-fixer.dist.php
- blackbox.php
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
"innmind/stream": "~4.1",
"innmind/media-type": "~2.1",
"innmind/url": "~4.2",
"psr/log": "~3.0"
"psr/log": "~3.0",
"innmind/io": "~2.2",
"innmind/time-continuum": "~3.4"
},
"autoload": {
"psr-4": {
Expand Down
70 changes: 18 additions & 52 deletions documentation/testing/own_adapter.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,27 @@
# Your own adapter

This library allows you to extend its behaviour by creating new implementations of the exposed interfaces (`File`, `Directory` and `Adapter`). The interfaces are strict enough to guide you through the expected behaviour but the type system can't express all of them, leaving the door open to inconsistencies between implementations. That's why the library expose a set of properties (as declared by [`innmind/black-box`](https://packagist.org/packages/innmind/black-box)) to help you make sure your implementations fulfill the expected behaviours.
This library allows you to extend its behaviour by creating new implementations of the exposed interface `Adapter`. The interface is strict enough to guide you through the expected behaviour but the type system can't express all of them, leaving the door open to inconsistencies between implementations. That's why the library expose a set of properties (as declared by [`innmind/black-box`](https://packagist.org/packages/innmind/black-box)) to help you make sure your implementations fulfill the expected behaviours.

You can test properties on your adapter as follow (with PHPUnit):
You can test properties on your adapter as follow:

```php
use Properties\Innmind\Filesystem\Adapter;
use Innmind\BlackBox\PHPUnit\BlackBox;
use PHPUnit\Framework\TestCase;

class MyAdapterTest extends TestCase
{
use BlackBox;

/**
* This test will make sure each property is held by your adapter
*
* @dataProvider properties
*/
public function testHoldProperty($property)
{
$this
->forAll($property)
->then(function($property) {
$adapter = /* instanciate your implementation here */;

if (!$property->applicableTo($adapter)) {
$this->markTestSkipped();
}

$property->ensureHeldBy($adapter);
});
use Innmind\BlackBox\Set;

return static function() {
yield properties(
'YourAdapter',
Adapter::properties(),
Set\Call::of(fn() => /* instanciate YourAdapter here */),
);

foreach (Adapter::alwaysApplicable() as $property) {
yield property(
$property,
Set\Call::of(fn() => /* instanciate YourAdapter here */),
)->named('YourAdapter');
}

/**
* This test will try to prove your adapter hold any sequence of property
*
* This is useful to find bugs due to state mismanage
*/
public function testHoldProperties()
{
$this
->forAll(Adapter::properties())
->then(function($properties) {
$properties->ensureHeldBy(/* instanciate your implementation here */);
});
}

public function properties(): iterable
{
foreach (Adapter::list() as $property) {
yield [$property];
}
}
}
};
```

You can use the same logic to test `Directory` implementations with `Properties\Innmind\Filesystem\Directory`.

**Note**: there is no properties for the `File` interface as it doesn't expose any behaviour.
Then you can [run your proofs](https://github.com/Innmind/BlackBox/blob/develop/documentation/organize.md) via BlackBox.
6 changes: 3 additions & 3 deletions documentation/use_cases/load_ftp_files.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ use Innmind\Immutable\Sequence;
/**
* @return Sequence<File>
*/
function flatten(File $file): Sequence
function flatten(File|Directory $file): Sequence
{
if ($file instanceof Directory) {
// bring all the files from sub directories to the same level
return $file->files()->flatMap(flatten(...));
return $file->all()->flatMap(flatten(...));
}

return Sequence::of($file);
}

Filesystem::mount(Path::of('/path/to/ftp/directory/'))
->root()
->files()
->all()
->flatMap(flatten(...))
->foreach(static fn(File $csv) => doYourStuff($csv));
```
Expand Down
29 changes: 19 additions & 10 deletions documentation/use_cases/modify_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ use Innmind\Filesystem\{
Name,
};
use Innmind\Url\Path;
use Innmind\Immutable\Str;
use Innmind\Immutable\{
Str,
Predicate\Instance,
};

// replace the "unreleased" title with the new version
$insertRelease = static function(Str $line): Str {
Expand All @@ -33,7 +36,8 @@ $filesystem = Filesystem::mount(Path::of('some/repository/'));
$tmp = Filesystem::mount(Path::of('/tmp/'));
$filesystem
->get(Name::of('CHANGELOG.md'))
->map(static fn($changelog) => $release($changelog))
->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
Expand Down Expand Up @@ -63,18 +67,19 @@ 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\Lines::of(Sequence::of(
return Content::ofLines(Sequence::of(
$user,
Line::of(Str::of('Jane Doe')),
));
}

return Content\Lines::of(Sequence::of($user));
return Content::ofLines(Sequence::of($user));
};
$update = static function(File $users) use ($updateUser): File {
return $users->withContent(
Expand All @@ -85,7 +90,8 @@ $filesystem = Filesystem::mount(Path::of('/var/data/'));
$tmp = Filesystem::mount(Path::of('/tmp/'));
$filesystem
->get(Name::of('users.csv'))
->map(static fn($users) => $update($users))
->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
Expand All @@ -111,19 +117,22 @@ use Innmind\Filesystem\{
Name,
};
use Innmind\Url\Path;
use Innmind\Immutable\Maybe;
use Innmind\Immutable\{
Maybe,
Predicate\Instance,
};

$merge = static function(File $file1, File $file2): File {
return File\File::named(
return File::named(
'all_users.csv',
Content\Lines::of(
Content::ofLines(
$file1->content()->lines()->append($file2->content()->lines()),
),
);
};
$filesystem = Filesystem::mount(Path::of('/var/data/'));
$users1 = $filesystem->get(Name::of('users1.csv'));
$users2 = $filesystem->get(Name::of('users2.csv'));
$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(
Expand Down
16 changes: 8 additions & 8 deletions documentation/use_cases/persist_hand_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
```php
use Innmind\Filesystem\{
Adapter\Filesystem,
File\File,
File,
File\Content,
};
use Innmind\Url\Path;

$filesystem = Filesystem::mount(Path::of('/var/data/'));
$filesystem->add(File::named('some name'), Content\None::of());
$filesystem->add(File::named('some name'), Content::none());
```

This is equivalent of running the cli command `touch '/var/data/some name'`.
Expand All @@ -21,8 +21,8 @@ This is equivalent of running the cli command `touch '/var/data/some name'`.
```php
use Innmind\Filesystem\{
Adapter\Filesystem,
File\File,
File\Content\Lines,
File,
File\Content,
File\Content\Line,
};
use Innmind\Url\Path;
Expand All @@ -34,7 +34,7 @@ use Innmind\Immutable\{
$filesystem = Filesystem::mount(Path::of('/var/data/'));
$filesystem->add(File::named(
'some name',
Lines::of(Sequence::of(
Content::ofLines(Sequence::of(
Line::of(Str::of('first line')),
Line::of(Str::of('second line')),
Line::of(Str::of('etc...')),
Expand All @@ -49,15 +49,15 @@ When the file is persisted the _end of line_ character will automatically added
```php
use Innmind\Filesystem\{
Adapter\Filesystem,
File\File,
File,
File\Content,
Directory\Directory,
Directory,
};
use Innmind\Url\Path;

$filesystem = Filesystem::mount(Path::of('/var/data/'));
$filesystem->add(
Directory::named('whatever')->add(File::named('some name'), Content\None::of()),
Directory::named('whatever')->add(File::named('some name'), Content::none()),
);
```

Expand Down
4 changes: 2 additions & 2 deletions documentation/use_cases/persist_process_output.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This example uses the [`innmind/operating-system`](https://packagist.org/package

```php
use Innmind\Filesystem\{
File\File,
File,
File\Content,
Adapter\Filesystem,
};
Expand All @@ -14,7 +14,7 @@ use Innmind\Url\Path;

$os = Factory::build();
$filesystem = Filesystem::mount(Path::of('/var/data/'));
$fileContent = Content\Chunks::of(
$fileContent = Content::ofChunks(
$os
->control()
->processes()
Expand Down
17 changes: 13 additions & 4 deletions documentation/use_cases/persist_uploaded_file.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,29 @@

```php
use Innmind\Filesystem\{
File\File,
File,
File\Content,
Directory\Directory,
Directory,
Adapter\Filesystem,
};
use Innmind\IO\IO;
use Innmind\Stream\Streams;
use Innmind\Url\Path;

$streams = Streams::fromAmbienAuthority();
$io = IO::of($streams->watch()->waitForever(...))

$filesystem = Filesystem::mount(Path::of('/var/data/'));
$filesystem->add(
Directory::named('uploads')->add(
File::named(
$_FILES['my_upload']['name'],
Content\AtPath::of(Path::of($_FILES['my_upload']['tmp_name'])),
Content::atPath(
$streams->readable(),
$io->readable(),
Path::of($_FILES['my_upload']['tmp_name']),
),
),
)
),
);
```
Loading

0 comments on commit b899174

Please sign in to comment.