104318dedb02aee3e3c054e59962048c1d83afcc
[yaffs-website] / vendor / consolidation / robo / src / Task / Filesystem / TmpDir.php
1 <?php
2
3 namespace Robo\Task\Filesystem;
4
5 use Robo\Result;
6 use Robo\Contract\CompletionInterface;
7
8 /**
9  * Create a temporary directory that is automatically cleaned up
10  * once the task collection is is part of completes.
11  *
12  * Use WorkDir if you do not want the directory to be deleted.
13  *
14  * ``` php
15  * <?php
16  * // Delete on rollback or on successful completion.
17  * // Note that in this example, everything is deleted at
18  * // the end of $collection->run().
19  * $collection = $this->collectionBuilder();
20  * $tmpPath = $collection->tmpDir()->getPath();
21  * $collection->taskFilesystemStack()
22  *           ->mkdir("$tmpPath/log")
23  *           ->touch("$tmpPath/log/error.txt");
24  * $collection->run();
25  * // as shortcut (deleted when program exits)
26  * $tmpPath = $this->_tmpDir();
27  * ?>
28  * ```
29  */
30 class TmpDir extends BaseDir implements CompletionInterface
31 {
32     /**
33      * @var string
34      */
35     protected $base;
36
37     /**
38      * @var string
39      */
40     protected $prefix;
41
42     /**
43      * @var bool
44      */
45     protected $cwd;
46
47     /**
48      * @var string
49      */
50     protected $savedWorkingDirectory;
51
52     /**
53      * @param string $prefix
54      * @param string $base
55      * @param bool $includeRandomPart
56      */
57     public function __construct($prefix = 'tmp', $base = '', $includeRandomPart = true)
58     {
59         if (empty($base)) {
60             $base = sys_get_temp_dir();
61         }
62         $path = "{$base}/{$prefix}";
63         if ($includeRandomPart) {
64             $path = static::randomLocation($path);
65         }
66         parent::__construct(["$path"]);
67     }
68
69     /**
70      * Add a random part to a path, ensuring that the directory does
71      * not (currently) exist.
72      *
73      * @param string $path The base/prefix path to add a random component to
74      * @param int $length Number of digits in the random part
75      *
76      * @return string
77      */
78     protected static function randomLocation($path, $length = 12)
79     {
80         $random = static::randomString($length);
81         while (is_dir("{$path}_{$random}")) {
82             $random = static::randomString($length);
83         }
84         return "{$path}_{$random}";
85     }
86
87     /**
88      * Generate a suitably random string to use as the suffix for our
89      * temporary directory.
90      *
91      * @param int $length
92      *
93      * @return string
94      */
95     protected static function randomString($length = 12)
96     {
97         return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, max($length, 3));
98     }
99
100     /**
101      * Flag that we should cwd to the temporary directory when it is
102      * created, and restore the old working directory when it is deleted.
103      *
104      * @param bool $shouldChangeWorkingDirectory
105      *
106      * @return $this
107      */
108     public function cwd($shouldChangeWorkingDirectory = true)
109     {
110         $this->cwd = $shouldChangeWorkingDirectory;
111
112         return $this;
113     }
114
115     /**
116      * {@inheritdoc}
117      */
118     public function run()
119     {
120         // Save the current working directory
121         $this->savedWorkingDirectory = getcwd();
122         foreach ($this->dirs as $dir) {
123             $this->fs->mkdir($dir);
124             $this->printTaskInfo("Created {dir}...", ['dir' => $dir]);
125
126             // Change the current working directory, if requested
127             if ($this->cwd) {
128                 chdir($dir);
129             }
130         }
131
132         return Result::success($this, '', ['path' => $this->getPath()]);
133     }
134
135     protected function restoreWorkingDirectory()
136     {
137         // Restore the current working directory, if we redirected it.
138         if ($this->cwd) {
139             chdir($this->savedWorkingDirectory);
140         }
141     }
142
143     protected function deleteTmpDir()
144     {
145         foreach ($this->dirs as $dir) {
146             $this->fs->remove($dir);
147         }
148     }
149
150     /**
151      * Delete this directory when our collection completes.
152      * If this temporary directory is not part of a collection,
153      * then it will be deleted when the program terminates,
154      * presuming that it was created by taskTmpDir() or _tmpDir().
155      */
156     public function complete()
157     {
158         $this->restoreWorkingDirectory();
159         $this->deleteTmpDir();
160     }
161
162     /**
163      * Get a reference to the path to the temporary directory, so that
164      * it may be used to create other tasks.  Note that the directory
165      * is not actually created until the task runs.
166      *
167      * @return string
168      */
169     public function getPath()
170     {
171         return $this->dirs[0];
172     }
173 }