fe6c9298ee91f21ead6707fb8c15b7a10e73c394
[yaffs-website] / vendor / consolidation / robo / src / Common / ProgressIndicator.php
1 <?php
2 namespace Robo\Common;
3
4 /**
5  * Wrapper around \Symfony\Component\Console\Helper\ProgressBar
6  */
7 class ProgressIndicator
8 {
9     use Timer;
10
11     /**
12      * @var \Symfony\Component\Console\Helper\ProgressBar
13      */
14     protected $progressBar;
15
16     /**
17      * @var \Symfony\Component\Console\Output\OutputInterface
18      */
19     protected $output;
20
21     /**
22      * @var bool
23      */
24     protected $progressIndicatorRunning = false;
25
26     /**
27      * @var int
28      */
29     protected $autoDisplayInterval = 0;
30
31     /**
32      * @var int
33      */
34     protected $cachedSteps = 0;
35
36     /**
37      * @var int
38      */
39     protected $totalSteps = 0;
40
41     /**
42      * @var bool
43      */
44     protected $progressBarDisplayed = false;
45
46     /**
47      * @var \Robo\Contract\TaskInterface
48      */
49     protected $owner;
50
51     /**
52      * @param \Symfony\Component\Console\Helper\ProgressBar $progressBar
53      * @param \Symfony\Component\Console\Output\OutputInterface $output
54      */
55     public function __construct($progressBar, \Symfony\Component\Console\Output\OutputInterface $output)
56     {
57         $this->progressBar = $progressBar;
58         $this->output = $output;
59     }
60
61     /**
62      * @param int $interval
63      */
64     public function setProgressBarAutoDisplayInterval($interval)
65     {
66         if ($this->progressIndicatorRunning) {
67             return;
68         }
69         $this->autoDisplayInterval = $interval;
70     }
71
72     /**
73      * @return bool
74      */
75     public function hideProgressIndicator()
76     {
77         $result = $this->progressBarDisplayed;
78         if ($this->progressIndicatorRunning && $this->progressBarDisplayed) {
79             $this->progressBar->clear();
80             // Hack: progress indicator does not reset cursor to beginning of line on 'clear'
81             $this->output->write("\x0D");
82             $this->progressBarDisplayed = false;
83         }
84         return $result;
85     }
86
87     public function showProgressIndicator()
88     {
89         if ($this->progressIndicatorRunning && !$this->progressBarDisplayed && isset($this->progressBar)) {
90             $this->progressBar->display();
91             $this->progressBarDisplayed = true;
92             $this->advanceProgressIndicatorCachedSteps();
93         }
94     }
95
96     /**
97      * @param bool $visible
98      */
99     public function restoreProgressIndicator($visible)
100     {
101         if ($visible) {
102             $this->showProgressIndicator();
103         }
104     }
105
106     /**
107      * @param int $totalSteps
108      * @param \Robo\Contract\TaskInterface $owner
109      */
110     public function startProgressIndicator($totalSteps, $owner)
111     {
112         if (!isset($this->progressBar)) {
113             return;
114         }
115
116         $this->progressIndicatorRunning = true;
117         if (!isset($this->owner)) {
118             $this->owner = $owner;
119             $this->startTimer();
120             $this->totalSteps = $totalSteps;
121             $this->autoShowProgressIndicator();
122         }
123     }
124
125     public function autoShowProgressIndicator()
126     {
127         if (($this->autoDisplayInterval < 0) || !isset($this->progressBar) || !$this->output->isDecorated()) {
128             return;
129         }
130         if ($this->autoDisplayInterval <= $this->getExecutionTime()) {
131             $this->autoDisplayInterval = -1;
132             $this->progressBar->start($this->totalSteps);
133             $this->showProgressIndicator();
134         }
135     }
136
137     /**
138      * @return bool
139      */
140     public function inProgress()
141     {
142         return $this->progressIndicatorRunning;
143     }
144
145     /**
146      * @param \Robo\Contract\TaskInterface $owner
147      */
148     public function stopProgressIndicator($owner)
149     {
150         if ($this->progressIndicatorRunning && ($this->owner === $owner)) {
151             $this->cleanup();
152         }
153     }
154
155     protected function cleanup()
156     {
157         $this->progressIndicatorRunning = false;
158         $this->owner = null;
159         if ($this->progressBarDisplayed) {
160             $this->progressBar->finish();
161             // Hack: progress indicator does not always finish cleanly
162             $this->output->writeln('');
163             $this->progressBarDisplayed = false;
164         }
165         $this->stopTimer();
166     }
167
168     /**
169      * Erase progress indicator and ensure it never returns.  Used
170      * only during error handlers or to permanently remove the progress bar.
171      */
172     public function disableProgressIndicator()
173     {
174         $this->cleanup();
175         // ProgressIndicator is shared, so this permanently removes
176         // the program's ability to display progress bars.
177         $this->progressBar = null;
178     }
179
180     /**
181      * @param int $steps
182      */
183     public function advanceProgressIndicator($steps = 1)
184     {
185         $this->cachedSteps += $steps;
186         if ($this->progressIndicatorRunning) {
187             $this->autoShowProgressIndicator();
188             // We only want to call `advance` if the progress bar is visible,
189             // because it always displays itself when it is advanced.
190             if ($this->progressBarDisplayed) {
191                 return $this->advanceProgressIndicatorCachedSteps();
192             }
193         }
194     }
195
196     protected function advanceProgressIndicatorCachedSteps()
197     {
198         $this->progressBar->advance($this->cachedSteps);
199         $this->cachedSteps = 0;
200     }
201 }