3 namespace Robo\Task\Filesystem;
6 use Robo\Contract\CompletionInterface;
9 * Create a temporary directory that is automatically cleaned up
10 * once the task collection is is part of completes.
12 * Use WorkDir if you do not want the directory to be deleted.
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");
25 * // as shortcut (deleted when program exits)
26 * $tmpPath = $this->_tmpDir();
30 class TmpDir extends BaseDir implements CompletionInterface
50 protected $savedWorkingDirectory;
53 * @param string $prefix
55 * @param bool $includeRandomPart
57 public function __construct($prefix = 'tmp', $base = '', $includeRandomPart = true)
60 $base = sys_get_temp_dir();
62 $path = "{$base}/{$prefix}";
63 if ($includeRandomPart) {
64 $path = static::randomLocation($path);
66 parent::__construct(["$path"]);
70 * Add a random part to a path, ensuring that the directory does
71 * not (currently) exist.
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
78 protected static function randomLocation($path, $length = 12)
80 $random = static::randomString($length);
81 while (is_dir("{$path}_{$random}")) {
82 $random = static::randomString($length);
84 return "{$path}_{$random}";
88 * Generate a suitably random string to use as the suffix for our
89 * temporary directory.
95 protected static function randomString($length = 12)
97 return substr(str_shuffle('23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'), 0, max($length, 3));
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.
104 * @param bool $shouldChangeWorkingDirectory
108 public function cwd($shouldChangeWorkingDirectory = true)
110 $this->cwd = $shouldChangeWorkingDirectory;
118 public function run()
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]);
126 // Change the current working directory, if requested
132 return Result::success($this, '', ['path' => $this->getPath()]);
135 protected function restoreWorkingDirectory()
137 // Restore the current working directory, if we redirected it.
139 chdir($this->savedWorkingDirectory);
143 protected function deleteTmpDir()
145 foreach ($this->dirs as $dir) {
146 $this->fs->remove($dir);
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().
156 public function complete()
158 $this->restoreWorkingDirectory();
159 $this->deleteTmpDir();
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.
169 public function getPath()
171 return $this->dirs[0];