Skip to content

Commit 5a45908

Browse files
committed
Merge pull request #1 from romainneutron/streams
Streams enhancement
2 parents 50008ac + d3d0b0e commit 5a45908

32 files changed

+651
-809
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
],
1414
"require": {
1515
"php": ">=5.3.3",
16+
"doctrine/collections": "~1",
1617
"pimple/pimple": "~1",
1718
"symfony/process": "~2",
1819
"symfony/filesystem": "~2",

composer.lock

Lines changed: 66 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Alchemy/Zippy/Adapter/AbstractAdapter.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@
1717

1818
abstract class AbstractAdapter implements AdapterInterface
1919
{
20+
protected $manager;
21+
22+
public function __construct(ResourceManager $manager)
23+
{
24+
$this->manager = $manager;
25+
}
26+
2027
/**
2128
* @inheritdoc
2229
*/
2330
public function open($path)
2431
{
25-
return new Archive($path, $this, new FileResource($path));
32+
return new Archive($path, $this, $this->manager);
2633
}
2734
}

src/Alchemy/Zippy/Adapter/AbstractBinaryAdapter.php

Lines changed: 6 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
namespace Alchemy\Zippy\Adapter;
1414

1515
use Alchemy\Zippy\Exception\InvalidArgumentException;
16-
use Alchemy\Zippy\Exception\IOException;
1716
use Alchemy\Zippy\Exception\RuntimeException;
1817
use Alchemy\Zippy\Archive\MemberInterface;
1918
use Alchemy\Zippy\Parser\ParserInterface;
2019
use Alchemy\Zippy\Parser\ParserFactory;
2120
use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactoryInterface;
2221
use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactory;
22+
use Alchemy\Zippy\Resource\ResourceManager;
2323
use Symfony\Component\Process\ExecutableFinder;
2424
use Symfony\Component\Process\ProcessBuilder;
2525

@@ -50,12 +50,14 @@ abstract class AbstractBinaryAdapter extends AbstractAdapter implements BinaryAd
5050
* Constructor
5151
*
5252
* @param ParserInterface $parser An output parser
53+
* @param ResourceManager $manager A resource manager
5354
* @param ProcessBuilderFactoryInterface $inflator A process builder factory for the inflator binary
5455
* @param ProcessBuilderFactoryInterface|null $deflator A process builder factory for the deflator binary
5556
*/
56-
public function __construct(ParserInterface $parser, ProcessBuilderFactoryInterface $inflator, ProcessBuilderFactoryInterface $deflator = null)
57+
public function __construct(ParserInterface $parser, ResourceManager $manager, ProcessBuilderFactoryInterface $inflator, ProcessBuilderFactoryInterface $deflator = null)
5758
{
5859
$this->parser = $parser;
60+
$this->manager = $manager;
5961
$this->deflator = $deflator;
6062
$this->inflator = $inflator;
6163
}
@@ -121,7 +123,7 @@ public function setInflator(ProcessBuilderFactoryInterface $processBuilder)
121123
*
122124
* @throws RuntimeException In case object could not be instanciated
123125
*/
124-
public static function newInstance($inflatorBinaryName = null, $deflatorBinaryName = null)
126+
public static function newInstance(ResourceManager $manager, $inflatorBinaryName = null, $deflatorBinaryName = null)
125127
{
126128
$finder = new ExecutableFinder();
127129

@@ -145,7 +147,7 @@ public static function newInstance($inflatorBinaryName = null, $deflatorBinaryNa
145147
);
146148
}
147149

148-
return new static($outputParser, $inflator, $deflator);
150+
return new static($outputParser, $manager, $inflator, $deflator);
149151
}
150152

151153
/**
@@ -172,73 +174,4 @@ protected function addBuilderFileArgument(array $files, ProcessBuilder $builder)
172174

173175
return 0 !== $iterations;
174176
}
175-
176-
/**
177-
* Adds a resource to argument list
178-
*
179-
* @param Array $files An array of resource or resource URI
180-
* @param ProcessBuilder $builder A Builder instance
181-
*
182-
* @return AbstractBinaryAdapter
183-
*
184-
* @throws RuntimeException In case resource could not be opened or readed
185-
* @throws IOException In case Temporary direcory or fetched file could not be created
186-
* @throws InvalidArgumentException In case the provided resource is invalid
187-
*/
188-
protected function addBuilderResourceArgument(array $files, ProcessBuilder $builder)
189-
{
190-
array_walk($files, function($resource, $location) use ($builder) {
191-
$stream = null;
192-
$location = ltrim($location, '/');
193-
194-
if (is_resource($resource)) {
195-
$stream = $resource;
196-
} elseif (is_string($resource)) {
197-
$stream = fopen($resource, 'r');
198-
}
199-
200-
if (null === $stream) {
201-
throw new InvalidArgumentException('A resource must be either a resource or a path to the resource');
202-
}
203-
204-
if (false === $stream) {
205-
throw new RuntimeException(sprintf('Fail to open stream %s', $resource));
206-
}
207-
208-
if (is_numeric($location)) {
209-
$meta = stream_get_meta_data($stream);
210-
$location = basename($meta['uri']);
211-
}
212-
213-
$tempFileInfo = new \SplFileInfo(sprintf('%s/%s', getcwd(), $location));
214-
215-
if (!is_dir($tempFileInfo->getPath()) && !mkdir($tempFileInfo->getPath(), 0777, true)) {
216-
throw new IOException(sprintf('Fail to create directory %s', $tempFileInfo->getPath()));
217-
}
218-
219-
if (false === $content = stream_get_contents($stream)) {
220-
throw new RuntimeException(sprintf('Fail to fetch content from %s', $location));
221-
}
222-
223-
try {
224-
$tempFile = $tempFileInfo->openFile('w');
225-
226-
if (null !== $tempFile->fwrite($content)) {
227-
$builder->add($location);
228-
}
229-
230-
unset($tempFile, $tempFileInfo);
231-
} catch (\RuntimeException $e) {
232-
throw IOException(
233-
sprintf('failed to write %s', $tempFileInfo->getRealPath()),
234-
$e->getCode(),
235-
$e
236-
);
237-
}
238-
239-
fclose($stream);
240-
});
241-
242-
return $this;
243-
}
244177
}

src/Alchemy/Zippy/Adapter/AbstractTarAdapter.php

Lines changed: 3 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
use Alchemy\Zippy\Archive\Archive;
1818
use Alchemy\Zippy\Exception\InvalidArgumentException;
1919
use Alchemy\Zippy\Exception\RuntimeException;
20-
use Symfony\Component\Filesystem\Filesystem;
21-
use Symfony\Component\Filesystem\Exception\IOException;
20+
use Alchemy\Zippy\Resource\ResourceManager;
2221

2322
abstract class AbstractTarAdapter extends AbstractBinaryAdapter
2423
{
@@ -46,18 +45,11 @@ public function add(ResourceInterface $resource, $files, $recursive = true)
4645
return $this->doAdd($this->getLocalOptions(), $resource, $files, $recursive);
4746
}
4847

49-
/**
50-
* @inheritdoc
51-
*/
52-
public function addStream($path, $files)
53-
{
54-
return $this->doAddStream($this->getLocalOptions(), $path, $files);
55-
}
5648

5749
/**
5850
* @inheritdoc
5951
*/
60-
public function remove(ResourceInterface $resource, $files)
52+
public function remove($path, $files)
6153
{
6254
return $this->doRemove($this->getLocalOptions(), $resource, $files);
6355
}
@@ -178,7 +170,7 @@ protected function doCreate($options, $path, $files = null, $recursive = true)
178170
));
179171
}
180172

181-
return new Archive($path, $this, new FileResource($path));
173+
return new Archive($path, $this, $this->manager);
182174
}
183175

184176
protected function doListMembers($options, ResourceInterface $resource)
@@ -263,57 +255,6 @@ protected function doAdd($options, ResourceInterface $resource, $files, $recursi
263255
return $files;
264256
}
265257

266-
protected function doAddStream($options, $path, $files)
267-
{
268-
$files = (array) $files;
269-
270-
$builder = $this
271-
->inflator
272-
->create();
273-
274-
$builder
275-
->add('--append')
276-
->add(sprintf('--file=%s', $path));
277-
278-
$savedWorkingDirectory = getcwd();
279-
280-
$tempDir = sprintf('%s/%s', sys_get_temp_dir(), uniqid('zippy_'));
281-
282-
if (!is_dir($tempDir)) {
283-
mkdir($tempDir);
284-
}
285-
286-
// change working directory
287-
chdir($tempDir);
288-
289-
if (!$this->addBuilderResourceArgument($files, $builder)) {
290-
chdir($savedWorkingDirectory);
291-
throw new InvalidArgumentException('Invalid streams');
292-
}
293-
294-
$process = $builder->getProcess();
295-
296-
$process->run();
297-
298-
chdir($savedWorkingDirectory);
299-
300-
$filesystem = new Filesystem();
301-
302-
try {
303-
$filesystem->remove($tempDir);
304-
} catch (IOException $e) {
305-
306-
}
307-
308-
if (!$process->isSuccessful()) {
309-
throw new RuntimeException(sprintf(
310-
'Unable to execute the following command %s {output: %s}',
311-
$process->getCommandLine(),
312-
$process->getErrorOutput()
313-
));
314-
}
315-
}
316-
317258
protected function doRemove($options, $path, $files)
318259
{
319260
$files = (array) $files;

src/Alchemy/Zippy/Adapter/AdapterContainer.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
use Alchemy\Zippy\Adapter\GNUTar\TarGNUTarAdapter;
1919
use Alchemy\Zippy\Adapter\GNUTar\TarGzGNUTarAdapter;
2020
use Alchemy\Zippy\Adapter\GNUTar\TarBz2GNUTarAdapter;
21+
use Alchemy\Zippy\Resource\ResourceManager;
22+
use Alchemy\Zippy\Resource\RequestMapper;
23+
use Alchemy\Zippy\Resource\TeleporterContainer;
24+
use Alchemy\Zippy\Resource\ResourceTeleporter;
25+
use Alchemy\Zippy\Resource\TargetLocator;
26+
use Symfony\Component\Filesystem\Filesystem;
2127

2228
class AdapterContainer extends \Pimple
2329
{
@@ -33,6 +39,30 @@ public static function load()
3339
$container['zip.inflator'] = null;
3440
$container['zip.deflator'] = null;
3541

42+
$container['resource-manager'] = $container->share(function ($container) {
43+
return new ResourceManager($container['request-mapper'], $container['resource-teleporter'], $container['filesystem']);
44+
});
45+
46+
$container['request-mapper'] = $container->share(function ($container) {
47+
return new RequestMapper($container['target-locator']);
48+
});
49+
50+
$container['target-locator'] = $container->share(function () {
51+
return new TargetLocator();
52+
});
53+
54+
$container['teleporter-container'] = $container->share(function ($container) {
55+
return TeleporterContainer::load();
56+
});
57+
58+
$container['resource-teleporter'] = $container->share(function ($container) {
59+
return new ResourceTeleporter($container['teleporter-container']);
60+
});
61+
62+
$container['filesystem'] = $container->share(function () {
63+
return new Filesystem();
64+
});
65+
3666
$container['Alchemy\\Zippy\\Adapter\\ZipAdapter'] = $container->share(function ($container) {
3767
return ZipAdapter::newInstance($container['zip.inflator'], $container['zip.deflator']);
3868
});

0 commit comments

Comments
 (0)