Completed
Push — add/relase-scripts-package ( 6d2bc4 )
by Yaroslav
29:20 queued 22:51
created

Cmd::run()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 2
dl 0
loc 24
rs 9.2248
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class for running shell scripts
4
 *
5
 * @package automattic/jetpack-scripts
6
 */
7
8
namespace Automattic\Jetpack\Scripts;
9
10
/**
11
 * Class for running shell commands
12
 */
13
class Cmd {
14
	/**
15
	 * Shell command
16
	 *
17
	 * @var String
18
	 */
19
	public $cmd = '';
20
21
	/**
22
	 * Process pipes
23
	 *
24
	 * @var Array
25
	 */
26
	public $pipes = null;
27
28
	/**
29
	 * Proc itself
30
	 *
31
	 * @var Process
32
	 */
33
	public $resource = null;
34
35
	/**
36
	 * Timestamp when command was fired
37
	 *
38
	 * @var int
39
	 */
40
	private $strt_tm = 0;
41
42
	/**
43
	 * Command exit code
44
	 *
45
	 * @var int
46
	 */
47
	private $exitcode = null;
48
49
	/**
50
	 * Descriptors to use in new process
51
	 *
52
	 * @var Array
53
	 */
54
	private $descriptors = array(
55
		0 => array( 'pipe', 'r' ),
56
		1 => array( 'pipe', 'w' ),
57
		2 => array( 'pipe', 'w' ),
58
	);
59
60
	/**
61
	 * Opens a process with the provided shell command
62
	 *
63
	 * @param {String} $cmd shell command to run.
0 ignored issues
show
Documentation introduced by
The doc-type {String} could not be parsed: Unknown type name "{String}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
64
	 */
65
	public function __construct( $cmd = '' ) {
66
			$this->cmd = $cmd;
67
68
			// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.system_calls_proc_open
69
			$this->resource = proc_open( $this->cmd, $this->descriptors, $this->pipes, realpath( './' ) );
0 ignored issues
show
Documentation Bug introduced by
It seems like proc_open($this->cmd, $t...>pipes, realpath('./')) of type resource is incompatible with the declared type object<Automattic\Jetpack\Scripts\Process> of property $resource.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
70
			$this->strt_tm  = microtime( true );
0 ignored issues
show
Documentation Bug introduced by
The property $strt_tm was declared of type integer, but microtime(true) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
71
	}
72
73
	/**
74
	 * Class entry point
75
	 *
76
	 * @param {String} $cmd shell command to run.
0 ignored issues
show
Documentation introduced by
The doc-type {String} could not be parsed: Unknown type name "{String}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
77
	 * @param {bool}   $interactive wether or not to output interactively.
0 ignored issues
show
Documentation introduced by
The doc-type {bool} could not be parsed: Unknown type name "{bool}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
78
	 */
79
	public static function run( $cmd, $interactive = true ) {
80
		$proc = new Cmd( $cmd );
81
		// phpcs:ignore
82
		error_log( print_r( 'RUNNING: ' . $cmd, 1 ) );
83
84
		$out = '';
85
86
		while ( $proc->is_running() ) {
87
			if ( $interactive ) {
88
				$s = fgets( $proc->pipes[1] );
89
				while ( $s ) {
90
					$out = $out . $s;
91
					error_log( $s ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
92
					$s = fgets( $proc->pipes[1] );
93
				}
94
			}
95
		}
96
97
		return array(
98
			'output'    => trim( $interactive ? $out : stream_get_contents( $proc->pipes[1] ) ),
99
			'exit_code' => $proc->get_exitcode(),
100
			'stderr'    => stream_get_contents( $proc->pipes[2] ),
101
		);
102
	}
103
104
	/**
105
	 * Checks if the process is still running. Also populates an $exitcode once the process is done running
106
	 */
107
	public function is_running() {
108
		$status = proc_get_status( $this->resource );
109
110
		/**
111
		 * `proc_get_status` will only pull valid exitcode one
112
		 * time after process has ended, so cache the exitcode
113
		 * if the process is finished and $exitcode is uninitialized
114
		 */
115
		if ( false === $status['running'] && null === $this->exitcode ) {
116
			$this->exitcode = $status['exitcode'];
117
		}
118
		return $status['running'];
119
	}
120
121
	/**
122
	 * Exit code accessor
123
	 */
124
	public function get_exitcode() {
125
		return $this->exitcode;
126
	}
127
128
	/**
129
	 * Return elapsed time
130
	 */
131
	public function get_elapsed() {
132
		return microtime( true ) - $this->strt_tm;
133
	}
134
}
135