Version 1
[yaffs-website] / vendor / alchemy / zippy / src / Adapter / AbstractTarAdapter.php
diff --git a/vendor/alchemy/zippy/src/Adapter/AbstractTarAdapter.php b/vendor/alchemy/zippy/src/Adapter/AbstractTarAdapter.php
new file mode 100644 (file)
index 0000000..34b3c80
--- /dev/null
@@ -0,0 +1,438 @@
+<?php
+
+/*
+ * This file is part of Zippy.
+ *
+ * (c) Alchemy <info@alchemy.fr>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Alchemy\Zippy\Adapter;
+
+use Alchemy\Zippy\Adapter\Resource\ResourceInterface;
+use Alchemy\Zippy\Archive\Archive;
+use Alchemy\Zippy\Archive\Member;
+use Alchemy\Zippy\Exception\RuntimeException;
+use Alchemy\Zippy\Exception\InvalidArgumentException;
+use Alchemy\Zippy\Resource\Resource as ZippyResource;
+use Symfony\Component\Process\Exception\ExceptionInterface as ProcessException;
+
+abstract class AbstractTarAdapter extends AbstractBinaryAdapter
+{
+    /**
+     * @inheritdoc
+     */
+    protected function doCreate($path, $files, $recursive)
+    {
+        return $this->doTarCreate($this->getLocalOptions(), $path, $files, $recursive);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doListMembers(ResourceInterface $resource)
+    {
+        return $this->doTarListMembers($this->getLocalOptions(), $resource);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doAdd(ResourceInterface $resource, $files, $recursive)
+    {
+        return $this->doTarAdd($this->getLocalOptions(), $resource, $files, $recursive);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doRemove(ResourceInterface $resource, $files)
+    {
+        return $this->doTarRemove($this->getLocalOptions(), $resource, $files);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doExtractMembers(ResourceInterface $resource, $members, $to, $overwrite = false)
+    {
+        return $this->doTarExtractMembers($this->getLocalOptions(), $resource, $members, $to, $overwrite);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doExtract(ResourceInterface $resource, $to)
+    {
+        return $this->doTarExtract($this->getLocalOptions(), $resource, $to);
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doGetInflatorVersion()
+    {
+        $process = $this
+            ->inflator
+            ->create()
+            ->add('--version')
+            ->getProcess();
+
+        $process->run();
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(), $process->getErrorOutput()
+            ));
+        }
+
+        return $this->parser->parseInflatorVersion($process->getOutput() ?: '');
+    }
+
+    /**
+     * @inheritdoc
+     */
+    protected function doGetDeflatorVersion()
+    {
+        return $this->getInflatorVersion();
+    }
+
+    protected function doTarCreate($options, $path, $files = null, $recursive = true)
+    {
+        $files = (array) $files;
+
+        $builder = $this
+            ->inflator
+            ->create();
+
+        if (!$recursive) {
+            $builder->add('--no-recursion');
+        }
+
+        $builder->add('-c');
+
+        foreach ((array) $options as $option) {
+            $builder->add((string) $option);
+        }
+
+        if (0 === count($files)) {
+            $nullFile = defined('PHP_WINDOWS_VERSION_BUILD') ? 'NUL' : '/dev/null';
+
+            $builder->add('-f');
+            $builder->add($path);
+            $builder->add('-T');
+            $builder->add($nullFile);
+
+            $process = $builder->getProcess();
+            $process->run();
+
+        } else {
+
+            $builder->add(sprintf('--file=%s', $path));
+
+            if (!$recursive) {
+                $builder->add('--no-recursion');
+            }
+
+            $collection = $this->manager->handle(getcwd(), $files);
+
+            $builder->setWorkingDirectory($collection->getContext());
+
+            $collection->forAll(function($i, ZippyResource $resource) use ($builder) {
+                return $builder->add($resource->getTarget());
+            });
+
+            $process = $builder->getProcess();
+
+            try {
+                $process->run();
+            } catch (ProcessException $e) {
+                $this->manager->cleanup($collection);
+                throw $e;
+            }
+
+            $this->manager->cleanup($collection);
+        }
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(),
+                $process->getErrorOutput()
+            ));
+        }
+
+        return new Archive($this->createResource($path), $this, $this->manager);
+    }
+
+    protected function doTarListMembers($options, ResourceInterface $resource)
+    {
+        $builder = $this
+            ->inflator
+            ->create();
+
+        foreach ($this->getListMembersOptions() as $option) {
+            $builder->add($option);
+        }
+
+        $builder
+            ->add('--list')
+            ->add('-v')
+            ->add(sprintf('--file=%s', $resource->getResource()));
+
+        foreach ((array) $options as $option) {
+            $builder->add((string) $option);
+        }
+
+        $process = $builder->getProcess();
+        $process->run();
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(),
+                $process->getErrorOutput()
+            ));
+        }
+
+        $members = array();
+
+        foreach ($this->parser->parseFileListing($process->getOutput() ?: '') as $member) {
+            $members[] = new Member(
+                    $resource,
+                    $this,
+                    $member['location'],
+                    $member['size'],
+                    $member['mtime'],
+                    $member['is_dir']
+            );
+        }
+
+        return $members;
+    }
+
+    protected function doTarAdd($options, ResourceInterface $resource, $files, $recursive = true)
+    {
+        $files = (array) $files;
+
+        $builder = $this
+            ->inflator
+            ->create();
+
+        if (!$recursive) {
+            $builder->add('--no-recursion');
+        }
+
+        $builder
+            ->add('--append')
+            ->add(sprintf('--file=%s', $resource->getResource()));
+
+        foreach ((array) $options as $option) {
+            $builder->add((string) $option);
+        }
+
+        // there will be an issue if the file starts with a dash
+        // see --add-file=FILE
+        $collection = $this->manager->handle(getcwd(), $files);
+
+        $builder->setWorkingDirectory($collection->getContext());
+
+        $collection->forAll(function($i, ZippyResource $resource) use ($builder) {
+            return $builder->add($resource->getTarget());
+        });
+
+        $process = $builder->getProcess();
+
+        try {
+            $process->run();
+        } catch (ProcessException $e) {
+            $this->manager->cleanup($collection);
+            throw $e;
+        }
+
+        $this->manager->cleanup($collection);
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(),
+                $process->getErrorOutput()
+            ));
+        }
+
+        return $files;
+    }
+
+    protected function doTarRemove($options, ResourceInterface $resource, $files)
+    {
+        $files = (array) $files;
+
+        $builder = $this
+            ->inflator
+            ->create();
+
+        $builder
+            ->add('--delete')
+            ->add(sprintf('--file=%s', $resource->getResource()));
+
+        foreach ((array) $options as $option) {
+            $builder->add((string) $option);
+        }
+
+        if (!$this->addBuilderFileArgument($files, $builder)) {
+            throw new InvalidArgumentException('Invalid files');
+        }
+
+        $process = $builder->getProcess();
+
+        $process->run();
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(),
+                $process->getErrorOutput()
+            ));
+        }
+
+        return $files;
+    }
+
+    protected function doTarExtract($options, ResourceInterface $resource, $to = null)
+    {
+        if (null !== $to && !is_dir($to)) {
+            throw new InvalidArgumentException(sprintf("%s is not a directory", $to));
+        }
+
+        $builder = $this
+            ->inflator
+            ->create();
+
+        $builder
+            ->add('--extract')
+            ->add(sprintf('--file=%s', $resource->getResource()));
+
+        foreach ($this->getExtractOptions() as $option) {
+            $builder
+                ->add($option);
+        }
+
+        foreach ((array) $options as $option) {
+            $builder->add((string) $option);
+        }
+
+        if (null !== $to) {
+            $builder
+                ->add('--directory')
+                ->add($to);
+        }
+
+        $process = $builder->getProcess();
+
+        $process->run();
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(),
+                $process->getErrorOutput()
+            ));
+        }
+
+        return new \SplFileInfo($to ?: $resource->getResource());
+    }
+
+    /**
+     * @param array             $options
+     * @param ResourceInterface $resource
+     * @param array             $members
+     * @param string            $to
+     * @param bool              $overwrite
+     *
+     * @return array
+     */
+    protected function doTarExtractMembers($options, ResourceInterface $resource, $members, $to = null, $overwrite = false)
+    {
+        if (null !== $to && !is_dir($to)) {
+            throw new InvalidArgumentException(sprintf("%s is not a directory", $to));
+        }
+
+        $members = (array) $members;
+
+        $builder = $this
+            ->inflator
+            ->create();
+
+        if ($overwrite == false) {
+            $builder->add('-k');
+        }
+
+        $builder
+            ->add('--extract')
+            ->add(sprintf('--file=%s', $resource->getResource()));
+
+        foreach ($this->getExtractMembersOptions() as $option) {
+            $builder
+                ->add($option);
+        }
+
+        foreach ((array) $options as $option) {
+            $builder->add((string) $option);
+        }
+
+        if (null !== $to) {
+            $builder
+                ->add('--directory')
+                ->add($to);
+        }
+
+        if (!$this->addBuilderFileArgument($members, $builder)) {
+            throw new InvalidArgumentException('Invalid files');
+        }
+
+        $process = $builder->getProcess();
+
+        $process->run();
+
+        if (!$process->isSuccessful()) {
+            throw new RuntimeException(sprintf(
+                'Unable to execute the following command %s {output: %s}',
+                $process->getCommandLine(),
+                $process->getErrorOutput()
+            ));
+        }
+
+        return $members;
+    }
+
+    /**
+     * Returns an array of option for the listMembers command
+     *
+     * @return array
+     */
+    abstract protected function getListMembersOptions();
+
+    /**
+     * Returns an array of option for the extract command
+     *
+     * @return array
+     */
+    abstract protected function getExtractOptions();
+
+    /**
+     * Returns an array of option for the extractMembers command
+     *
+     * @return array
+     */
+    abstract protected function getExtractMembersOptions();
+
+    /**
+     * Gets adapter specific additional options
+     *
+     * @return array
+     */
+    abstract protected function getLocalOptions();
+}