4 * This file is part of Zippy.
6 * (c) Alchemy <info@alchemy.fr>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Alchemy\Zippy\Adapter;
14 use Alchemy\Zippy\Adapter\Resource\ResourceInterface;
15 use Alchemy\Zippy\Archive\Archive;
16 use Alchemy\Zippy\Archive\Member;
17 use Alchemy\Zippy\Exception\RuntimeException;
18 use Alchemy\Zippy\Exception\InvalidArgumentException;
19 use Alchemy\Zippy\Resource\Resource as ZippyResource;
20 use Symfony\Component\Process\Exception\ExceptionInterface as ProcessException;
22 abstract class AbstractTarAdapter extends AbstractBinaryAdapter
27 protected function doCreate($path, $files, $recursive)
29 return $this->doTarCreate($this->getLocalOptions(), $path, $files, $recursive);
35 protected function doListMembers(ResourceInterface $resource)
37 return $this->doTarListMembers($this->getLocalOptions(), $resource);
43 protected function doAdd(ResourceInterface $resource, $files, $recursive)
45 return $this->doTarAdd($this->getLocalOptions(), $resource, $files, $recursive);
51 protected function doRemove(ResourceInterface $resource, $files)
53 return $this->doTarRemove($this->getLocalOptions(), $resource, $files);
59 protected function doExtractMembers(ResourceInterface $resource, $members, $to, $overwrite = false)
61 return $this->doTarExtractMembers($this->getLocalOptions(), $resource, $members, $to, $overwrite);
67 protected function doExtract(ResourceInterface $resource, $to)
69 return $this->doTarExtract($this->getLocalOptions(), $resource, $to);
75 protected function doGetInflatorVersion()
85 if (!$process->isSuccessful()) {
86 throw new RuntimeException(sprintf(
87 'Unable to execute the following command %s {output: %s}',
88 $process->getCommandLine(), $process->getErrorOutput()
92 return $this->parser->parseInflatorVersion($process->getOutput() ?: '');
98 protected function doGetDeflatorVersion()
100 return $this->getInflatorVersion();
103 protected function doTarCreate($options, $path, $files = null, $recursive = true)
105 $files = (array) $files;
112 $builder->add('--no-recursion');
117 foreach ((array) $options as $option) {
118 $builder->add((string) $option);
121 if (0 === count($files)) {
122 $nullFile = defined('PHP_WINDOWS_VERSION_BUILD') ? 'NUL' : '/dev/null';
125 $builder->add($path);
127 $builder->add($nullFile);
129 $process = $builder->getProcess();
134 $builder->add(sprintf('--file=%s', $path));
137 $builder->add('--no-recursion');
140 $collection = $this->manager->handle(getcwd(), $files);
142 $builder->setWorkingDirectory($collection->getContext());
144 $collection->forAll(function($i, ZippyResource $resource) use ($builder) {
145 return $builder->add($resource->getTarget());
148 $process = $builder->getProcess();
152 } catch (ProcessException $e) {
153 $this->manager->cleanup($collection);
157 $this->manager->cleanup($collection);
160 if (!$process->isSuccessful()) {
161 throw new RuntimeException(sprintf(
162 'Unable to execute the following command %s {output: %s}',
163 $process->getCommandLine(),
164 $process->getErrorOutput()
168 return new Archive($this->createResource($path), $this, $this->manager);
171 protected function doTarListMembers($options, ResourceInterface $resource)
177 foreach ($this->getListMembersOptions() as $option) {
178 $builder->add($option);
184 ->add(sprintf('--file=%s', $resource->getResource()));
186 foreach ((array) $options as $option) {
187 $builder->add((string) $option);
190 $process = $builder->getProcess();
193 if (!$process->isSuccessful()) {
194 throw new RuntimeException(sprintf(
195 'Unable to execute the following command %s {output: %s}',
196 $process->getCommandLine(),
197 $process->getErrorOutput()
203 foreach ($this->parser->parseFileListing($process->getOutput() ?: '') as $member) {
204 $members[] = new Member(
217 protected function doTarAdd($options, ResourceInterface $resource, $files, $recursive = true)
219 $files = (array) $files;
226 $builder->add('--no-recursion');
231 ->add(sprintf('--file=%s', $resource->getResource()));
233 foreach ((array) $options as $option) {
234 $builder->add((string) $option);
237 // there will be an issue if the file starts with a dash
238 // see --add-file=FILE
239 $collection = $this->manager->handle(getcwd(), $files);
241 $builder->setWorkingDirectory($collection->getContext());
243 $collection->forAll(function($i, ZippyResource $resource) use ($builder) {
244 return $builder->add($resource->getTarget());
247 $process = $builder->getProcess();
251 } catch (ProcessException $e) {
252 $this->manager->cleanup($collection);
256 $this->manager->cleanup($collection);
258 if (!$process->isSuccessful()) {
259 throw new RuntimeException(sprintf(
260 'Unable to execute the following command %s {output: %s}',
261 $process->getCommandLine(),
262 $process->getErrorOutput()
269 protected function doTarRemove($options, ResourceInterface $resource, $files)
271 $files = (array) $files;
279 ->add(sprintf('--file=%s', $resource->getResource()));
281 foreach ((array) $options as $option) {
282 $builder->add((string) $option);
285 if (!$this->addBuilderFileArgument($files, $builder)) {
286 throw new InvalidArgumentException('Invalid files');
289 $process = $builder->getProcess();
293 if (!$process->isSuccessful()) {
294 throw new RuntimeException(sprintf(
295 'Unable to execute the following command %s {output: %s}',
296 $process->getCommandLine(),
297 $process->getErrorOutput()
304 protected function doTarExtract($options, ResourceInterface $resource, $to = null)
306 if (null !== $to && !is_dir($to)) {
307 throw new InvalidArgumentException(sprintf("%s is not a directory", $to));
316 ->add(sprintf('--file=%s', $resource->getResource()));
318 foreach ($this->getExtractOptions() as $option) {
323 foreach ((array) $options as $option) {
324 $builder->add((string) $option);
333 $process = $builder->getProcess();
337 if (!$process->isSuccessful()) {
338 throw new RuntimeException(sprintf(
339 'Unable to execute the following command %s {output: %s}',
340 $process->getCommandLine(),
341 $process->getErrorOutput()
345 return new \SplFileInfo($to ?: $resource->getResource());
349 * @param array $options
350 * @param ResourceInterface $resource
351 * @param array $members
353 * @param bool $overwrite
357 protected function doTarExtractMembers($options, ResourceInterface $resource, $members, $to = null, $overwrite = false)
359 if (null !== $to && !is_dir($to)) {
360 throw new InvalidArgumentException(sprintf("%s is not a directory", $to));
363 $members = (array) $members;
369 if ($overwrite == false) {
375 ->add(sprintf('--file=%s', $resource->getResource()));
377 foreach ($this->getExtractMembersOptions() as $option) {
382 foreach ((array) $options as $option) {
383 $builder->add((string) $option);
392 if (!$this->addBuilderFileArgument($members, $builder)) {
393 throw new InvalidArgumentException('Invalid files');
396 $process = $builder->getProcess();
400 if (!$process->isSuccessful()) {
401 throw new RuntimeException(sprintf(
402 'Unable to execute the following command %s {output: %s}',
403 $process->getCommandLine(),
404 $process->getErrorOutput()
412 * Returns an array of option for the listMembers command
416 abstract protected function getListMembersOptions();
419 * Returns an array of option for the extract command
423 abstract protected function getExtractOptions();
426 * Returns an array of option for the extractMembers command
430 abstract protected function getExtractMembersOptions();
433 * Gets adapter specific additional options
437 abstract protected function getLocalOptions();