Updated to Drupal 8.5. Core Media not yet in use.
[yaffs-website] / vendor / consolidation / robo / src / Task / Archive / Pack.php
diff --git a/vendor/consolidation/robo/src/Task/Archive/Pack.php b/vendor/consolidation/robo/src/Task/Archive/Pack.php
new file mode 100644 (file)
index 0000000..0970f8e
--- /dev/null
@@ -0,0 +1,257 @@
+<?php
+
+namespace Robo\Task\Archive;
+
+use Robo\Contract\PrintedInterface;
+use Robo\Result;
+use Robo\Task\BaseTask;
+use Symfony\Component\Finder\Finder;
+
+/**
+ * Creates a zip or tar archive.
+ *
+ * ``` php
+ * <?php
+ * $this->taskPack(
+ * <archiveFile>)
+ * ->add('README')                         // Puts file 'README' in archive at the root
+ * ->add('project')                        // Puts entire contents of directory 'project' in archinve inside 'project'
+ * ->addFile('dir/file.txt', 'file.txt')   // Takes 'file.txt' from cwd and puts it in archive inside 'dir'.
+ * ->run();
+ * ?>
+ * ```
+ */
+class Pack extends BaseTask implements PrintedInterface
+{
+    /**
+     * The list of items to be packed into the archive.
+     *
+     * @var array
+     */
+    private $items = [];
+
+    /**
+     * The full path to the archive to be created.
+     *
+     * @var string
+     */
+    private $archiveFile;
+
+    /**
+     * Construct the class.
+     *
+     * @param string $archiveFile The full path and name of the archive file to create.
+     *
+     * @since   1.0
+     */
+    public function __construct($archiveFile)
+    {
+        $this->archiveFile = $archiveFile;
+    }
+
+    /**
+     * Satisfy the parent requirement.
+     *
+     * @return bool Always returns true.
+     *
+     * @since   1.0
+     */
+    public function getPrinted()
+    {
+        return true;
+    }
+
+    /**
+     * @param string $archiveFile
+     *
+     * @return $this
+     */
+    public function archiveFile($archiveFile)
+    {
+        $this->archiveFile = $archiveFile;
+        return $this;
+    }
+
+    /**
+     * Add an item to the archive. Like file_exists(), the parameter
+     * may be a file or a directory.
+     *
+     * @var string
+     *             Relative path and name of item to store in archive
+     * @var string
+     *             Absolute or relative path to file or directory's location in filesystem
+     *
+     * @return $this
+     */
+    public function addFile($placementLocation, $filesystemLocation)
+    {
+        $this->items[$placementLocation] = $filesystemLocation;
+
+        return $this;
+    }
+
+    /**
+     * Alias for addFile, in case anyone has angst about using
+     * addFile with a directory.
+     *
+     * @var string
+     *             Relative path and name of directory to store in archive
+     * @var string
+     *             Absolute or relative path to directory or directory's location in filesystem
+     *
+     * @return $this
+     */
+    public function addDir($placementLocation, $filesystemLocation)
+    {
+        $this->addFile($placementLocation, $filesystemLocation);
+
+        return $this;
+    }
+
+    /**
+     * Add a file or directory, or list of same to the archive.
+     *
+     * @var string|array
+     *                   If given a string, should contain the relative filesystem path to the
+     *                   the item to store in archive; this will also be used as the item's
+     *                   path in the archive, so absolute paths should not be used here.
+     *                   If given an array, the key of each item should be the path to store
+     *                   in the archive, and the value should be the filesystem path to the
+     *                   item to store.
+     * @return $this
+     */
+    public function add($item)
+    {
+        if (is_array($item)) {
+            $this->items = array_merge($this->items, $item);
+        } else {
+            $this->addFile($item, $item);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Create a zip archive for distribution.
+     *
+     * @return \Robo\Result
+     *
+     * @since  1.0
+     */
+    public function run()
+    {
+        $this->startTimer();
+
+        // Use the file extension to determine what kind of archive to create.
+        $fileInfo = new \SplFileInfo($this->archiveFile);
+        $extension = strtolower($fileInfo->getExtension());
+        if (empty($extension)) {
+            return Result::error($this, "Archive filename must use an extension (e.g. '.zip') to specify the kind of archive to create.");
+        }
+
+        try {
+            // Inform the user which archive we are creating
+            $this->printTaskInfo("Creating archive {filename}", ['filename' => $this->archiveFile]);
+            if ($extension == 'zip') {
+                $result = $this->archiveZip($this->archiveFile, $this->items);
+            } else {
+                $result = $this->archiveTar($this->archiveFile, $this->items);
+            }
+            $this->printTaskSuccess("{filename} created.", ['filename' => $this->archiveFile]);
+        } catch (\Exception $e) {
+            $this->printTaskError("Could not create {filename}. {exception}", ['filename' => $this->archiveFile, 'exception' => $e->getMessage(), '_style' => ['exception' => '']]);
+            $result = Result::error($this, sprintf('Could not create %s. %s', $this->archiveFile, $e->getMessage()));
+        }
+        $this->stopTimer();
+        $result['time'] = $this->getExecutionTime();
+
+        return $result;
+    }
+
+    /**
+     * @param string $archiveFile
+     * @param array $items
+     *
+     * @return \Robo\Result
+     */
+    protected function archiveTar($archiveFile, $items)
+    {
+        if (!class_exists('Archive_Tar')) {
+            return Result::errorMissingPackage($this, 'Archive_Tar', 'pear/archive_tar');
+        }
+
+        $tar_object = new \Archive_Tar($archiveFile);
+        foreach ($items as $placementLocation => $filesystemLocation) {
+            $p_remove_dir = $filesystemLocation;
+            $p_add_dir = $placementLocation;
+            if (is_file($filesystemLocation)) {
+                $p_remove_dir = dirname($filesystemLocation);
+                $p_add_dir = dirname($placementLocation);
+                if (basename($filesystemLocation) != basename($placementLocation)) {
+                    return Result::error($this, "Tar archiver does not support renaming files during extraction; could not add $filesystemLocation as $placementLocation.");
+                }
+            }
+
+            if (!$tar_object->addModify([$filesystemLocation], $p_add_dir, $p_remove_dir)) {
+                return Result::error($this, "Could not add $filesystemLocation to the archive.");
+            }
+        }
+
+        return Result::success($this);
+    }
+
+    /**
+     * @param string $archiveFile
+     * @param array $items
+     *
+     * @return \Robo\Result
+     */
+    protected function archiveZip($archiveFile, $items)
+    {
+        if (!extension_loaded('zlib')) {
+            return Result::errorMissingExtension($this, 'zlib', 'zip packing');
+        }
+
+        $zip = new \ZipArchive($archiveFile, \ZipArchive::CREATE);
+        if (!$zip->open($archiveFile, \ZipArchive::CREATE)) {
+            return Result::error($this, "Could not create zip archive {$archiveFile}");
+        }
+        $result = $this->addItemsToZip($zip, $items);
+        $zip->close();
+
+        return $result;
+    }
+
+    /**
+     * @param \ZipArchive $zip
+     * @param array $items
+     *
+     * @return \Robo\Result
+     */
+    protected function addItemsToZip($zip, $items)
+    {
+        foreach ($items as $placementLocation => $filesystemLocation) {
+            if (is_dir($filesystemLocation)) {
+                $finder = new Finder();
+                $finder->files()->in($filesystemLocation)->ignoreDotFiles(false);
+
+                foreach ($finder as $file) {
+                    // Replace Windows slashes or resulting zip will have issues on *nixes.
+                    $relativePathname = str_replace('\\', '/', $file->getRelativePathname());
+
+                    if (!$zip->addFile($file->getRealpath(), "{$placementLocation}/{$relativePathname}")) {
+                        return Result::error($this, "Could not add directory $filesystemLocation to the archive; error adding {$file->getRealpath()}.");
+                    }
+                }
+            } elseif (is_file($filesystemLocation)) {
+                if (!$zip->addFile($filesystemLocation, $placementLocation)) {
+                    return Result::error($this, "Could not add file $filesystemLocation to the archive.");
+                }
+            } else {
+                return Result::error($this, "Could not find $filesystemLocation for the archive.");
+            }
+        }
+
+        return Result::success($this);
+    }
+}