Test Failed
Push — revert-1636-spawn-open-task ( d97d56 )
by Michiel
24:25 queued 03:05
created
tests/Phing/Task/Optional/PDODelimitersTest.php 5 patches
Indentation   -141 removed lines patch added patch discarded remove patch
@@ -70,144 +70,3 @@
 block discarded – undo
70 70
         // for some reason default splitter mangles spaces on subsequent lines
71 71
         $expected = [
72 72
             <<<'SQL'
73
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
74
-                SQL,
75
-            <<<'SQL'
76
-                delete
77
-                 from
78
-                 foo where bar = 'some value'
79
-                SQL,
80
-            <<<'SQL'
81
-                update dump -- I should not be ignored
82
-                 set message = 'I am a string with \\ backslash \' escapes and semicolons;'
83
-                SQL,
84
-            <<<'SQL'
85
-                create procedure setfoo(newfoo int)
86
-                 begin
87
-                 set @foo = newfoo;
88
-                 end
89
-                SQL,
90
-            <<<'SQL'
91
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
92
-                SQL,
93
-        ];
94
-        // and insists on "\n" linebreaks
95
-        foreach ($expected as &$query) {
96
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
97
-        }
98
-
99
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-normal.sql'));
100
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
101
-        $this->project->setProperty('bar.value', 'some value');
102
-        $this->project->executeTarget('test');
103
-
104
-        $this->assertEquals($expected, $this->queries);
105
-    }
106
-
107
-    public function testDelimiterTypeRow(): void
108
-    {
109
-        // for some reason default splitter mangles spaces on subsequent lines
110
-        $expected = [
111
-            <<<'SQL'
112
-                insert into "duh" (foo) values ('duh')
113
-                SQL,
114
-            <<<'SQL'
115
-                update "duh?" -- I should not be ignored
116
-                 set foo = 'some value'
117
-                SQL,
118
-            <<<'SQL'
119
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
120
-                SQL,
121
-        ];
122
-        // and insists on "\n" linebreaks
123
-        foreach ($expected as &$query) {
124
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
125
-        }
126
-
127
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-row.sql'));
128
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_ROW);
129
-        $this->mockTask->setDelimiter('duh');
130
-        $this->project->setProperty('foo.value', 'some value');
131
-        $this->project->executeTarget('test');
132
-
133
-        $this->assertEquals($expected, $this->queries);
134
-    }
135
-
136
-    /**
137
-     * Checks that PDOSQLExecTask properly understands PostgreSQL dialect
138
-     * (especially "dollar quoting") when working with 'pgsql:' URLs.
139
-     *
140
-     * @see http://www.phing.info/trac/ticket/499
141
-     * @see http://www.postgresql.org/docs/9.0/interactive/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING
142
-     */
143
-    public function testRequest499(): void
144
-    {
145
-        $expected = [
146
-            <<<'SQL'
147
-                select 1
148
-                # 2
149
-                SQL,
150
-            <<<'SQL'
151
-                select 'foo'
152
-                // 'bar'
153
-                SQL,
154
-            <<<'SQL'
155
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
156
-                SQL,
157
-            <<<'SQL'
158
-                create function foo(text)
159
-                returns boolean as
160
-                $function$
161
-                BEGIN
162
-                    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
163
-                END;
164
-                $function$
165
-                language plpgsql
166
-                SQL,
167
-            <<<'SQL'
168
-                CREATE FUNCTION phingPDOtest() RETURNS "trigger"
169
-                    AS $_X$
170
-                if (1)
171
-                {
172
-                    # All is well - just continue
173
-
174
-                    return;
175
-                }
176
-                else
177
-                {
178
-                    # Not good - this is probably a fatal error!
179
-                    elog(ERROR,"True is not true");
180
-
181
-                    return "SKIP";
182
-                }
183
-                $_X$
184
-                    LANGUAGE plperl
185
-                SQL,
186
-            "insert into foo (bar) \nvalues ('some value')",
187
-            <<<'SQL'
188
-                insert into foo (bar) values ($$ a dollar-quoted string containing a few quotes ' ", a $placeholder$ and a semicolon;$$)
189
-                SQL,
190
-            <<<'SQL'
191
-                create rule blah_insert
192
-                as on insert to blah do instead (
193
-                    insert into foo values (new.id, 'blah');
194
-                    insert into bar values (new.id, 'blah-blah');
195
-                )
196
-                SQL,
197
-            <<<'SQL'
198
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
199
-                SQL,
200
-        ];
201
-        foreach ($expected as &$query) {
202
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
203
-        }
204
-
205
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-pgsql.sql'));
206
-        $this->mockTask->setUrl('pgsql:host=localhost;dbname=phing');
207
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
208
-        $this->project->setProperty('bar.value', 'some value');
209
-        $this->project->executeTarget('test');
210
-
211
-        $this->assertEquals($expected, $this->queries);
212
-    }
213
-}
Please login to merge, or discard this patch.
Switch Indentation   -141 removed lines patch added patch discarded remove patch
@@ -70,144 +70,3 @@
 block discarded – undo
70 70
         // for some reason default splitter mangles spaces on subsequent lines
71 71
         $expected = [
72 72
             <<<'SQL'
73
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
74
-                SQL,
75
-            <<<'SQL'
76
-                delete
77
-                 from
78
-                 foo where bar = 'some value'
79
-                SQL,
80
-            <<<'SQL'
81
-                update dump -- I should not be ignored
82
-                 set message = 'I am a string with \\ backslash \' escapes and semicolons;'
83
-                SQL,
84
-            <<<'SQL'
85
-                create procedure setfoo(newfoo int)
86
-                 begin
87
-                 set @foo = newfoo;
88
-                 end
89
-                SQL,
90
-            <<<'SQL'
91
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
92
-                SQL,
93
-        ];
94
-        // and insists on "\n" linebreaks
95
-        foreach ($expected as &$query) {
96
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
97
-        }
98
-
99
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-normal.sql'));
100
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
101
-        $this->project->setProperty('bar.value', 'some value');
102
-        $this->project->executeTarget('test');
103
-
104
-        $this->assertEquals($expected, $this->queries);
105
-    }
106
-
107
-    public function testDelimiterTypeRow(): void
108
-    {
109
-        // for some reason default splitter mangles spaces on subsequent lines
110
-        $expected = [
111
-            <<<'SQL'
112
-                insert into "duh" (foo) values ('duh')
113
-                SQL,
114
-            <<<'SQL'
115
-                update "duh?" -- I should not be ignored
116
-                 set foo = 'some value'
117
-                SQL,
118
-            <<<'SQL'
119
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
120
-                SQL,
121
-        ];
122
-        // and insists on "\n" linebreaks
123
-        foreach ($expected as &$query) {
124
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
125
-        }
126
-
127
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-row.sql'));
128
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_ROW);
129
-        $this->mockTask->setDelimiter('duh');
130
-        $this->project->setProperty('foo.value', 'some value');
131
-        $this->project->executeTarget('test');
132
-
133
-        $this->assertEquals($expected, $this->queries);
134
-    }
135
-
136
-    /**
137
-     * Checks that PDOSQLExecTask properly understands PostgreSQL dialect
138
-     * (especially "dollar quoting") when working with 'pgsql:' URLs.
139
-     *
140
-     * @see http://www.phing.info/trac/ticket/499
141
-     * @see http://www.postgresql.org/docs/9.0/interactive/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING
142
-     */
143
-    public function testRequest499(): void
144
-    {
145
-        $expected = [
146
-            <<<'SQL'
147
-                select 1
148
-                # 2
149
-                SQL,
150
-            <<<'SQL'
151
-                select 'foo'
152
-                // 'bar'
153
-                SQL,
154
-            <<<'SQL'
155
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
156
-                SQL,
157
-            <<<'SQL'
158
-                create function foo(text)
159
-                returns boolean as
160
-                $function$
161
-                BEGIN
162
-                    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
163
-                END;
164
-                $function$
165
-                language plpgsql
166
-                SQL,
167
-            <<<'SQL'
168
-                CREATE FUNCTION phingPDOtest() RETURNS "trigger"
169
-                    AS $_X$
170
-                if (1)
171
-                {
172
-                    # All is well - just continue
173
-
174
-                    return;
175
-                }
176
-                else
177
-                {
178
-                    # Not good - this is probably a fatal error!
179
-                    elog(ERROR,"True is not true");
180
-
181
-                    return "SKIP";
182
-                }
183
-                $_X$
184
-                    LANGUAGE plperl
185
-                SQL,
186
-            "insert into foo (bar) \nvalues ('some value')",
187
-            <<<'SQL'
188
-                insert into foo (bar) values ($$ a dollar-quoted string containing a few quotes ' ", a $placeholder$ and a semicolon;$$)
189
-                SQL,
190
-            <<<'SQL'
191
-                create rule blah_insert
192
-                as on insert to blah do instead (
193
-                    insert into foo values (new.id, 'blah');
194
-                    insert into bar values (new.id, 'blah-blah');
195
-                )
196
-                SQL,
197
-            <<<'SQL'
198
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
199
-                SQL,
200
-        ];
201
-        foreach ($expected as &$query) {
202
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
203
-        }
204
-
205
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-pgsql.sql'));
206
-        $this->mockTask->setUrl('pgsql:host=localhost;dbname=phing');
207
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
208
-        $this->project->setProperty('bar.value', 'some value');
209
-        $this->project->executeTarget('test');
210
-
211
-        $this->assertEquals($expected, $this->queries);
212
-    }
213
-}
Please login to merge, or discard this patch.
Spacing   -141 removed lines patch added patch discarded remove patch
@@ -70,144 +70,3 @@
 block discarded – undo
70 70
         // for some reason default splitter mangles spaces on subsequent lines
71 71
         $expected = [
72 72
             <<<'SQL'
73
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
74
-                SQL,
75
-            <<<'SQL'
76
-                delete
77
-                 from
78
-                 foo where bar = 'some value'
79
-                SQL,
80
-            <<<'SQL'
81
-                update dump -- I should not be ignored
82
-                 set message = 'I am a string with \\ backslash \' escapes and semicolons;'
83
-                SQL,
84
-            <<<'SQL'
85
-                create procedure setfoo(newfoo int)
86
-                 begin
87
-                 set @foo = newfoo;
88
-                 end
89
-                SQL,
90
-            <<<'SQL'
91
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
92
-                SQL,
93
-        ];
94
-        // and insists on "\n" linebreaks
95
-        foreach ($expected as &$query) {
96
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
97
-        }
98
-
99
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-normal.sql'));
100
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
101
-        $this->project->setProperty('bar.value', 'some value');
102
-        $this->project->executeTarget('test');
103
-
104
-        $this->assertEquals($expected, $this->queries);
105
-    }
106
-
107
-    public function testDelimiterTypeRow(): void
108
-    {
109
-        // for some reason default splitter mangles spaces on subsequent lines
110
-        $expected = [
111
-            <<<'SQL'
112
-                insert into "duh" (foo) values ('duh')
113
-                SQL,
114
-            <<<'SQL'
115
-                update "duh?" -- I should not be ignored
116
-                 set foo = 'some value'
117
-                SQL,
118
-            <<<'SQL'
119
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
120
-                SQL,
121
-        ];
122
-        // and insists on "\n" linebreaks
123
-        foreach ($expected as &$query) {
124
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
125
-        }
126
-
127
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-row.sql'));
128
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_ROW);
129
-        $this->mockTask->setDelimiter('duh');
130
-        $this->project->setProperty('foo.value', 'some value');
131
-        $this->project->executeTarget('test');
132
-
133
-        $this->assertEquals($expected, $this->queries);
134
-    }
135
-
136
-    /**
137
-     * Checks that PDOSQLExecTask properly understands PostgreSQL dialect
138
-     * (especially "dollar quoting") when working with 'pgsql:' URLs.
139
-     *
140
-     * @see http://www.phing.info/trac/ticket/499
141
-     * @see http://www.postgresql.org/docs/9.0/interactive/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING
142
-     */
143
-    public function testRequest499(): void
144
-    {
145
-        $expected = [
146
-            <<<'SQL'
147
-                select 1
148
-                # 2
149
-                SQL,
150
-            <<<'SQL'
151
-                select 'foo'
152
-                // 'bar'
153
-                SQL,
154
-            <<<'SQL'
155
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
156
-                SQL,
157
-            <<<'SQL'
158
-                create function foo(text)
159
-                returns boolean as
160
-                $function$
161
-                BEGIN
162
-                    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
163
-                END;
164
-                $function$
165
-                language plpgsql
166
-                SQL,
167
-            <<<'SQL'
168
-                CREATE FUNCTION phingPDOtest() RETURNS "trigger"
169
-                    AS $_X$
170
-                if (1)
171
-                {
172
-                    # All is well - just continue
173
-
174
-                    return;
175
-                }
176
-                else
177
-                {
178
-                    # Not good - this is probably a fatal error!
179
-                    elog(ERROR,"True is not true");
180
-
181
-                    return "SKIP";
182
-                }
183
-                $_X$
184
-                    LANGUAGE plperl
185
-                SQL,
186
-            "insert into foo (bar) \nvalues ('some value')",
187
-            <<<'SQL'
188
-                insert into foo (bar) values ($$ a dollar-quoted string containing a few quotes ' ", a $placeholder$ and a semicolon;$$)
189
-                SQL,
190
-            <<<'SQL'
191
-                create rule blah_insert
192
-                as on insert to blah do instead (
193
-                    insert into foo values (new.id, 'blah');
194
-                    insert into bar values (new.id, 'blah-blah');
195
-                )
196
-                SQL,
197
-            <<<'SQL'
198
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
199
-                SQL,
200
-        ];
201
-        foreach ($expected as &$query) {
202
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
203
-        }
204
-
205
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-pgsql.sql'));
206
-        $this->mockTask->setUrl('pgsql:host=localhost;dbname=phing');
207
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
208
-        $this->project->setProperty('bar.value', 'some value');
209
-        $this->project->executeTarget('test');
210
-
211
-        $this->assertEquals($expected, $this->queries);
212
-    }
213
-}
Please login to merge, or discard this patch.
Braces   -141 removed lines patch added patch discarded remove patch
@@ -70,144 +70,3 @@
 block discarded – undo
70 70
         // for some reason default splitter mangles spaces on subsequent lines
71 71
         $expected = [
72 72
             <<<'SQL'
73
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
74
-                SQL,
75
-            <<<'SQL'
76
-                delete
77
-                 from
78
-                 foo where bar = 'some value'
79
-                SQL,
80
-            <<<'SQL'
81
-                update dump -- I should not be ignored
82
-                 set message = 'I am a string with \\ backslash \' escapes and semicolons;'
83
-                SQL,
84
-            <<<'SQL'
85
-                create procedure setfoo(newfoo int)
86
-                 begin
87
-                 set @foo = newfoo;
88
-                 end
89
-                SQL,
90
-            <<<'SQL'
91
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
92
-                SQL,
93
-        ];
94
-        // and insists on "\n" linebreaks
95
-        foreach ($expected as &$query) {
96
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
97
-        }
98
-
99
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-normal.sql'));
100
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
101
-        $this->project->setProperty('bar.value', 'some value');
102
-        $this->project->executeTarget('test');
103
-
104
-        $this->assertEquals($expected, $this->queries);
105
-    }
106
-
107
-    public function testDelimiterTypeRow(): void
108
-    {
109
-        // for some reason default splitter mangles spaces on subsequent lines
110
-        $expected = [
111
-            <<<'SQL'
112
-                insert into "duh" (foo) values ('duh')
113
-                SQL,
114
-            <<<'SQL'
115
-                update "duh?" -- I should not be ignored
116
-                 set foo = 'some value'
117
-                SQL,
118
-            <<<'SQL'
119
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
120
-                SQL,
121
-        ];
122
-        // and insists on "\n" linebreaks
123
-        foreach ($expected as &$query) {
124
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
125
-        }
126
-
127
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-row.sql'));
128
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_ROW);
129
-        $this->mockTask->setDelimiter('duh');
130
-        $this->project->setProperty('foo.value', 'some value');
131
-        $this->project->executeTarget('test');
132
-
133
-        $this->assertEquals($expected, $this->queries);
134
-    }
135
-
136
-    /**
137
-     * Checks that PDOSQLExecTask properly understands PostgreSQL dialect
138
-     * (especially "dollar quoting") when working with 'pgsql:' URLs.
139
-     *
140
-     * @see http://www.phing.info/trac/ticket/499
141
-     * @see http://www.postgresql.org/docs/9.0/interactive/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING
142
-     */
143
-    public function testRequest499(): void
144
-    {
145
-        $expected = [
146
-            <<<'SQL'
147
-                select 1
148
-                # 2
149
-                SQL,
150
-            <<<'SQL'
151
-                select 'foo'
152
-                // 'bar'
153
-                SQL,
154
-            <<<'SQL'
155
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
156
-                SQL,
157
-            <<<'SQL'
158
-                create function foo(text)
159
-                returns boolean as
160
-                $function$
161
-                BEGIN
162
-                    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
163
-                END;
164
-                $function$
165
-                language plpgsql
166
-                SQL,
167
-            <<<'SQL'
168
-                CREATE FUNCTION phingPDOtest() RETURNS "trigger"
169
-                    AS $_X$
170
-                if (1)
171
-                {
172
-                    # All is well - just continue
173
-
174
-                    return;
175
-                }
176
-                else
177
-                {
178
-                    # Not good - this is probably a fatal error!
179
-                    elog(ERROR,"True is not true");
180
-
181
-                    return "SKIP";
182
-                }
183
-                $_X$
184
-                    LANGUAGE plperl
185
-                SQL,
186
-            "insert into foo (bar) \nvalues ('some value')",
187
-            <<<'SQL'
188
-                insert into foo (bar) values ($$ a dollar-quoted string containing a few quotes ' ", a $placeholder$ and a semicolon;$$)
189
-                SQL,
190
-            <<<'SQL'
191
-                create rule blah_insert
192
-                as on insert to blah do instead (
193
-                    insert into foo values (new.id, 'blah');
194
-                    insert into bar values (new.id, 'blah-blah');
195
-                )
196
-                SQL,
197
-            <<<'SQL'
198
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
199
-                SQL,
200
-        ];
201
-        foreach ($expected as &$query) {
202
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
203
-        }
204
-
205
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-pgsql.sql'));
206
-        $this->mockTask->setUrl('pgsql:host=localhost;dbname=phing');
207
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
208
-        $this->project->setProperty('bar.value', 'some value');
209
-        $this->project->executeTarget('test');
210
-
211
-        $this->assertEquals($expected, $this->queries);
212
-    }
213
-}
Please login to merge, or discard this patch.
Upper-Lower-Casing   -141 removed lines patch added patch discarded remove patch
@@ -70,144 +70,3 @@
 block discarded – undo
70 70
         // for some reason default splitter mangles spaces on subsequent lines
71 71
         $expected = [
72 72
             <<<'SQL'
73
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
74
-                SQL,
75
-            <<<'SQL'
76
-                delete
77
-                 from
78
-                 foo where bar = 'some value'
79
-                SQL,
80
-            <<<'SQL'
81
-                update dump -- I should not be ignored
82
-                 set message = 'I am a string with \\ backslash \' escapes and semicolons;'
83
-                SQL,
84
-            <<<'SQL'
85
-                create procedure setfoo(newfoo int)
86
-                 begin
87
-                 set @foo = newfoo;
88
-                 end
89
-                SQL,
90
-            <<<'SQL'
91
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
92
-                SQL,
93
-        ];
94
-        // and insists on "\n" linebreaks
95
-        foreach ($expected as &$query) {
96
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
97
-        }
98
-
99
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-normal.sql'));
100
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
101
-        $this->project->setProperty('bar.value', 'some value');
102
-        $this->project->executeTarget('test');
103
-
104
-        $this->assertEquals($expected, $this->queries);
105
-    }
106
-
107
-    public function testDelimiterTypeRow(): void
108
-    {
109
-        // for some reason default splitter mangles spaces on subsequent lines
110
-        $expected = [
111
-            <<<'SQL'
112
-                insert into "duh" (foo) values ('duh')
113
-                SQL,
114
-            <<<'SQL'
115
-                update "duh?" -- I should not be ignored
116
-                 set foo = 'some value'
117
-                SQL,
118
-            <<<'SQL'
119
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
120
-                SQL,
121
-        ];
122
-        // and insists on "\n" linebreaks
123
-        foreach ($expected as &$query) {
124
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
125
-        }
126
-
127
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-row.sql'));
128
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_ROW);
129
-        $this->mockTask->setDelimiter('duh');
130
-        $this->project->setProperty('foo.value', 'some value');
131
-        $this->project->executeTarget('test');
132
-
133
-        $this->assertEquals($expected, $this->queries);
134
-    }
135
-
136
-    /**
137
-     * Checks that PDOSQLExecTask properly understands PostgreSQL dialect
138
-     * (especially "dollar quoting") when working with 'pgsql:' URLs.
139
-     *
140
-     * @see http://www.phing.info/trac/ticket/499
141
-     * @see http://www.postgresql.org/docs/9.0/interactive/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING
142
-     */
143
-    public function testRequest499(): void
144
-    {
145
-        $expected = [
146
-            <<<'SQL'
147
-                select 1
148
-                # 2
149
-                SQL,
150
-            <<<'SQL'
151
-                select 'foo'
152
-                // 'bar'
153
-                SQL,
154
-            <<<'SQL'
155
-                insert into foo (bar, "strange;name""indeed") values ('bar''s value containing ;', 'a value for strange named column')
156
-                SQL,
157
-            <<<'SQL'
158
-                create function foo(text)
159
-                returns boolean as
160
-                $function$
161
-                BEGIN
162
-                    RETURN ($1 ~ $q$[\t\r\n\v\\]$q$);
163
-                END;
164
-                $function$
165
-                language plpgsql
166
-                SQL,
167
-            <<<'SQL'
168
-                CREATE FUNCTION phingPDOtest() RETURNS "trigger"
169
-                    AS $_X$
170
-                if (1)
171
-                {
172
-                    # All is well - just continue
173
-
174
-                    return;
175
-                }
176
-                else
177
-                {
178
-                    # Not good - this is probably a fatal error!
179
-                    elog(ERROR,"True is not true");
180
-
181
-                    return "SKIP";
182
-                }
183
-                $_X$
184
-                    LANGUAGE plperl
185
-                SQL,
186
-            "insert into foo (bar) \nvalues ('some value')",
187
-            <<<'SQL'
188
-                insert into foo (bar) values ($$ a dollar-quoted string containing a few quotes ' ", a $placeholder$ and a semicolon;$$)
189
-                SQL,
190
-            <<<'SQL'
191
-                create rule blah_insert
192
-                as on insert to blah do instead (
193
-                    insert into foo values (new.id, 'blah');
194
-                    insert into bar values (new.id, 'blah-blah');
195
-                )
196
-                SQL,
197
-            <<<'SQL'
198
-                insert into dump (message) values ('I am a statement not ending with a delimiter')
199
-                SQL,
200
-        ];
201
-        foreach ($expected as &$query) {
202
-            $query = str_replace(["\n\n", "\r"], ["\n", ''], $query);
203
-        }
204
-
205
-        $this->mockTask->setSrc(new File(PHING_TEST_BASE . '/etc/tasks/ext/pdo/delimiters-pgsql.sql'));
206
-        $this->mockTask->setUrl('pgsql:host=localhost;dbname=phing');
207
-        $this->mockTask->setDelimiterType(PDOSQLExecTask::DELIM_NORMAL);
208
-        $this->project->setProperty('bar.value', 'some value');
209
-        $this->project->executeTarget('test');
210
-
211
-        $this->assertEquals($expected, $this->queries);
212
-    }
213
-}
Please login to merge, or discard this patch.
src/Phing/Phing.php 5 patches
Indentation   -1615 removed lines patch added patch discarded remove patch
@@ -83,1618 +83,3 @@
 block discarded – undo
83 83
      */
84 84
     public const DEFAULT_BUILD_FILENAME = 'build.xml';
85 85
     public const DEFAULT_BUILD_CONTENT = <<<'XML'
86
-        <?xml version="1.0" encoding="UTF-8" ?>
87
-
88
-        <project name="" description="" default="">
89
-            
90
-            <target name="" description="">
91
-                
92
-            </target>
93
-            
94
-        </project>
95
-        XML;
96
-    public const PHING_HOME = 'phing.home';
97
-    public const PHP_VERSION = 'php.version';
98
-    public const PHP_INTERPRETER = 'php.interpreter';
99
-
100
-    /**
101
-     * Our current message output status. Follows Project::MSG_XXX.
102
-     */
103
-    private static $msgOutputLevel = Project::MSG_INFO;
104
-    /**
105
-     * Set of properties that are passed in from commandline or invoking code.
106
-     *
107
-     * @var Properties
108
-     */
109
-    private static $definedProps;
110
-    /**
111
-     * Used by utility function getResourcePath().
112
-     */
113
-    private static $importPaths;
114
-    /**
115
-     * System-wide static properties (moved from System).
116
-     */
117
-    private static $properties = [];
118
-    /**
119
-     * Static system timer.
120
-     */
121
-    private static $timer;
122
-    /**
123
-     * The current Project.
124
-     */
125
-    private static $currentProject;
126
-    /**
127
-     * Whether to capture PHP errors to buffer.
128
-     */
129
-    private static $phpErrorCapture = false;
130
-    /**
131
-     * Array of captured PHP errors.
132
-     */
133
-    private static $capturedPhpErrors = [];
134
-    /**
135
-     * @var OUtputStream stream for standard output
136
-     */
137
-    private static $out;
138
-    /**
139
-     * @var OutputStream stream for error output
140
-     */
141
-    private static $err;
142
-    /**
143
-     * @var bool whether we are using a logfile
144
-     */
145
-    private static $isLogFileUsed = false;
146
-    /**
147
-     * Array to hold original ini settings that Phing changes (and needs
148
-     * to restore in restoreIni() method).
149
-     *
150
-     * @var array Struct of array(setting-name => setting-value)
151
-     *
152
-     * @see restoreIni()
153
-     */
154
-    private static $origIniSettings = [];
155
-    /**
156
-     * PhingFile that we are using for configuration.
157
-     */
158
-    private $buildFile;
159
-    /**
160
-     * The build targets.
161
-     */
162
-    private $targets = [];
163
-    /**
164
-     * Names of classes to add as listeners to project.
165
-     */
166
-    private $listeners = [];
167
-    /**
168
-     * keep going mode.
169
-     *
170
-     * @var bool
171
-     */
172
-    private $keepGoingMode = false;
173
-    private $loggerClassname;
174
-    /**
175
-     * The class to handle input (can be only one).
176
-     */
177
-    private $inputHandlerClassname;
178
-    /**
179
-     * Whether or not log output should be reduced to the minimum.
180
-     *
181
-     * @var bool
182
-     */
183
-    private $silent = false;
184
-    /**
185
-     * Indicates whether phing should run in strict mode.
186
-     */
187
-    private $strictMode = false;
188
-    /**
189
-     * Indicates if this phing should be run.
190
-     */
191
-    private $readyToRun = false;
192
-    /**
193
-     * Indicates we should only parse and display the project help information.
194
-     */
195
-    private $projectHelp = false;
196
-    /**
197
-     * Whether to values in a property file should override existing values.
198
-     */
199
-    private $propertyFileOverride = false;
200
-    /**
201
-     * Whether or not output to the log is to be unadorned.
202
-     */
203
-    private $emacsMode = false;
204
-
205
-    /**
206
-     * @var string
207
-     */
208
-    private $searchForThis;
209
-    private $propertyFiles = [];
210
-
211
-    /**
212
-     * Gets the stream to use for standard (non-error) output.
213
-     *
214
-     * @return OutputStream
215
-     */
216
-    public static function getOutputStream()
217
-    {
218
-        return self::$out;
219
-    }
220
-
221
-    /**
222
-     * Gets the stream to use for error output.
223
-     *
224
-     * @return OutputStream
225
-     */
226
-    public static function getErrorStream()
227
-    {
228
-        return self::$err;
229
-    }
230
-
231
-    /**
232
-     * Command line entry point. This method kicks off the building
233
-     * of a project object and executes a build using either a given
234
-     * target or the default target.
235
-     *
236
-     * @param array $args command line args
237
-     *
238
-     * @throws Exception
239
-     */
240
-    public static function fire($args): void
241
-    {
242
-        self::start($args);
243
-    }
244
-
245
-    /**
246
-     * Entry point allowing for more options from other front ends.
247
-     *
248
-     * This method encapsulates the complete build lifecycle.
249
-     *
250
-     * @param array $args                     the commandline args passed to phing shell script
251
-     * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this).
252
-     *                                        These additional properties will be available using the getDefinedProperty() method and will
253
-     *                                        be added to the project's "user" properties
254
-     *
255
-     * @throws Exception - if there is an error during build
256
-     *
257
-     * @see    runBuild()
258
-     * @see    execute()
259
-     */
260
-    public static function start($args, array $additionalUserProperties = null)
261
-    {
262
-        try {
263
-            $m = new self();
264
-            $m->execute($args);
265
-        } catch (Exception $exc) {
266
-            self::handleLogfile();
267
-            self::printMessage($exc);
268
-            self::statusExit(1);
269
-
270
-            return;
271
-        }
272
-
273
-        if (null !== $additionalUserProperties) {
274
-            foreach ($additionalUserProperties as $key => $value) {
275
-                $m::setDefinedProperty($key, $value);
276
-            }
277
-        }
278
-
279
-        // expect the worst
280
-        $exitCode = 1;
281
-
282
-        try {
283
-            try {
284
-                $m->runBuild();
285
-                $exitCode = 0;
286
-            } catch (ExitStatusException $ese) {
287
-                $exitCode = $ese->getCode();
288
-                if (0 !== $exitCode) {
289
-                    self::handleLogfile();
290
-
291
-                    throw $ese;
292
-                }
293
-            }
294
-        } catch (BuildException $exc) {
295
-            // avoid printing output twice: self::printMessage($exc);
296
-        } catch (Throwable $exc) {
297
-            self::printMessage($exc);
298
-        } finally {
299
-            self::handleLogfile();
300
-        }
301
-        self::statusExit($exitCode);
302
-    }
303
-
304
-    /**
305
-     * Setup/initialize Phing environment from commandline args.
306
-     *
307
-     * @param array $args commandline args passed to phing shell
308
-     *
309
-     * @throws ConfigurationException
310
-     */
311
-    public function execute($args): void
312
-    {
313
-        self::$definedProps = new Properties();
314
-        $this->searchForThis = null;
315
-
316
-        // 1) First handle any options which should always
317
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
318
-
319
-        if (in_array('-help', $args) || in_array('-h', $args)) {
320
-            static::printUsage();
321
-
322
-            return;
323
-        }
324
-
325
-        if (in_array('-version', $args) || in_array('-v', $args)) {
326
-            static::printVersion();
327
-
328
-            return;
329
-        }
330
-
331
-        if (in_array('-init', $args) || in_array('-i', $args)) {
332
-            $key = array_search('-init', $args) ?: array_search('-i', $args);
333
-            $path = $args[$key + 1] ?? null;
334
-
335
-            self::init($path);
336
-
337
-            return;
338
-        }
339
-
340
-        if (in_array('-diagnostics', $args)) {
341
-            Diagnostics::doReport(new PrintStream(self::$out));
342
-
343
-            return;
344
-        }
345
-
346
-        // 2) Next pull out stand-alone args.
347
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
348
-
349
-        if (
350
-            false !== ($key = array_search('-quiet', $args, true))
351
-            || false !== ($key = array_search(
352
-                '-q',
353
-                $args,
354
-                true
355
-            ))
356
-        ) {
357
-            self::$msgOutputLevel = Project::MSG_WARN;
358
-            unset($args[$key]);
359
-        }
360
-
361
-        if (
362
-            false !== ($key = array_search('-emacs', $args, true))
363
-            || false !== ($key = array_search('-e', $args, true))
364
-        ) {
365
-            $this->emacsMode = true;
366
-            unset($args[$key]);
367
-        }
368
-
369
-        if (false !== ($key = array_search('-verbose', $args, true))) {
370
-            self::$msgOutputLevel = Project::MSG_VERBOSE;
371
-            unset($args[$key]);
372
-        }
373
-
374
-        if (false !== ($key = array_search('-debug', $args, true))) {
375
-            self::$msgOutputLevel = Project::MSG_DEBUG;
376
-            unset($args[$key]);
377
-        }
378
-
379
-        if (
380
-            false !== ($key = array_search('-silent', $args, true))
381
-            || false !== ($key = array_search('-S', $args, true))
382
-        ) {
383
-            $this->silent = true;
384
-            unset($args[$key]);
385
-        }
386
-
387
-        if (false !== ($key = array_search('-propertyfileoverride', $args, true))) {
388
-            $this->propertyFileOverride = true;
389
-            unset($args[$key]);
390
-        }
391
-
392
-        // 3) Finally, cycle through to parse remaining args
393
-        //
394
-        $keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
395
-        $max = $keys ? max($keys) : -1;
396
-        for ($i = 0; $i <= $max; ++$i) {
397
-            if (!array_key_exists($i, $args)) {
398
-                // skip this argument, since it must have been removed above.
399
-                continue;
400
-            }
401
-
402
-            $arg = $args[$i];
403
-
404
-            if ('-logfile' == $arg) {
405
-                try {
406
-                    // see: http://phing.info/trac/ticket/65
407
-                    if (!isset($args[$i + 1])) {
408
-                        $msg = "You must specify a log file when using the -logfile argument\n";
409
-
410
-                        throw new ConfigurationException($msg);
411
-                    }
412
-
413
-                    $logFile = new File($args[++$i]);
414
-                    $out = new FileOutputStream($logFile); // overwrite
415
-                    self::setOutputStream($out);
416
-                    self::setErrorStream($out);
417
-                    self::$isLogFileUsed = true;
418
-                } catch (IOException $ioe) {
419
-                    $msg = 'Cannot write on the specified log file. Make sure the path exists and you have write permissions.';
420
-
421
-                    throw new ConfigurationException($msg, $ioe);
422
-                }
423
-            } elseif ('-buildfile' == $arg || '-file' == $arg || '-f' == $arg) {
424
-                if (!isset($args[$i + 1])) {
425
-                    $msg = 'You must specify a buildfile when using the -buildfile argument.';
426
-
427
-                    throw new ConfigurationException($msg);
428
-                }
429
-
430
-                $this->buildFile = new File($args[++$i]);
431
-            } elseif ('-listener' == $arg) {
432
-                if (!isset($args[$i + 1])) {
433
-                    $msg = 'You must specify a listener class when using the -listener argument';
434
-
435
-                    throw new ConfigurationException($msg);
436
-                }
437
-
438
-                $this->listeners[] = $args[++$i];
439
-            } elseif (StringHelper::startsWith('-D', $arg)) {
440
-                // Evaluating the property information //
441
-                // Checking whether arg. is not just a switch, and next arg. does not starts with switch identifier
442
-                if (('-D' == $arg) && (!StringHelper::startsWith('-', $args[$i + 1]))) {
443
-                    $name = $args[++$i];
444
-                } else {
445
-                    $name = substr($arg, 2);
446
-                }
447
-
448
-                $value = null;
449
-                $posEq = strpos($name, '=');
450
-                if (false !== $posEq) {
451
-                    $value = substr($name, $posEq + 1);
452
-                    $name = substr($name, 0, $posEq);
453
-                } elseif ($i < count($args) - 1 && !StringHelper::startsWith('-D', $args[$i + 1])) {
454
-                    $value = $args[++$i];
455
-                }
456
-                self::$definedProps->setProperty($name, $value);
457
-            } elseif ('-logger' == $arg) {
458
-                if (!isset($args[$i + 1])) {
459
-                    $msg = 'You must specify a classname when using the -logger argument';
460
-
461
-                    throw new ConfigurationException($msg);
462
-                }
463
-
464
-                $this->loggerClassname = $args[++$i];
465
-            } elseif ('-no-strict' == $arg) {
466
-                $this->strictMode = false;
467
-            } elseif ('-strict' == $arg) {
468
-                $this->strictMode = true;
469
-            } elseif ('-inputhandler' == $arg) {
470
-                if (null !== $this->inputHandlerClassname) {
471
-                    throw new ConfigurationException('Only one input handler class may be specified.');
472
-                }
473
-                if (!isset($args[$i + 1])) {
474
-                    $msg = 'You must specify a classname when using the -inputhandler argument';
475
-
476
-                    throw new ConfigurationException($msg);
477
-                }
478
-
479
-                $this->inputHandlerClassname = $args[++$i];
480
-            } elseif ('-propertyfile' === $arg) {
481
-                $i = $this->handleArgPropertyFile($args, $i);
482
-            } elseif ('-keep-going' === $arg || '-k' === $arg) {
483
-                $this->keepGoingMode = true;
484
-            } elseif ('-longtargets' == $arg) {
485
-                self::$definedProps->setProperty('phing.showlongtargets', 1);
486
-            } elseif ('-projecthelp' == $arg || '-targets' == $arg || '-list' == $arg || '-l' == $arg || '-p' == $arg) {
487
-                // set the flag to display the targets and quit
488
-                $this->projectHelp = true;
489
-            } elseif ('-find' == $arg) {
490
-                // eat up next arg if present, default to build.xml
491
-                if ($i < count($args) - 1) {
492
-                    $this->searchForThis = $args[++$i];
493
-                } else {
494
-                    $this->searchForThis = self::DEFAULT_BUILD_FILENAME;
495
-                }
496
-            } elseif ('-' == substr($arg, 0, 1)) {
497
-                // we don't have any more args
498
-                self::printUsage();
499
-                self::$err->write(PHP_EOL);
500
-
501
-                throw new ConfigurationException('Unknown argument: ' . $arg);
502
-            } else {
503
-                // if it's no other arg, it may be the target
504
-                $this->targets[] = $arg;
505
-            }
506
-        }
507
-
508
-        // if buildFile was not specified on the command line,
509
-        if (null === $this->buildFile) {
510
-            // but -find then search for it
511
-            if (null !== $this->searchForThis) {
512
-                $this->buildFile = $this->findBuildFile(self::getProperty('user.dir'), $this->searchForThis);
513
-            } else {
514
-                $this->buildFile = new File(self::DEFAULT_BUILD_FILENAME);
515
-            }
516
-        }
517
-
518
-        try {
519
-            // make sure buildfile (or buildfile.dist) exists
520
-            if (!$this->buildFile->exists()) {
521
-                $distFile = new File($this->buildFile->getAbsolutePath() . '.dist');
522
-                if (!$distFile->exists()) {
523
-                    throw new ConfigurationException(
524
-                        'Buildfile: ' . $this->buildFile->__toString() . ' does not exist!'
525
-                    );
526
-                }
527
-                $this->buildFile = $distFile;
528
-            }
529
-
530
-            // make sure it's not a directory
531
-            if ($this->buildFile->isDirectory()) {
532
-                throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is a dir!');
533
-            }
534
-        } catch (IOException $e) {
535
-            // something else happened, buildfile probably not readable
536
-            throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is not readable!');
537
-        }
538
-
539
-        $this->loadPropertyFiles();
540
-
541
-        $this->readyToRun = true;
542
-    }
543
-
544
-    /**
545
-     * Prints the usage of how to use this class.
546
-     */
547
-    public static function printUsage()
548
-    {
549
-        $msg = '';
550
-        $msg .= 'phing [options] [target [target2 [target3] ...]]' . PHP_EOL;
551
-        $msg .= 'Options: ' . PHP_EOL;
552
-        $msg .= '  -h -help               print this message' . PHP_EOL;
553
-        $msg .= '  -l -list               list available targets in this project' . PHP_EOL;
554
-        $msg .= '  -i -init [file]        generates an initial buildfile' . PHP_EOL;
555
-        $msg .= '  -v -version            print the version information and exit' . PHP_EOL;
556
-        $msg .= '  -q -quiet              be extra quiet' . PHP_EOL;
557
-        $msg .= '  -S -silent             print nothing but task outputs and build failures' . PHP_EOL;
558
-        $msg .= '  -verbose               be extra verbose' . PHP_EOL;
559
-        $msg .= '  -debug                 print debugging information' . PHP_EOL;
560
-        $msg .= '  -emacs, -e             produce logging information without adornments' . PHP_EOL;
561
-        $msg .= '  -diagnostics           print diagnostics information' . PHP_EOL;
562
-        $msg .= '  -strict                runs build in strict mode, considering a warning as error' . PHP_EOL;
563
-        $msg .= '  -no-strict             runs build normally (overrides buildfile attribute)' . PHP_EOL;
564
-        $msg .= '  -longtargets           show target descriptions during build' . PHP_EOL;
565
-        $msg .= '  -logfile <file>        use given file for log' . PHP_EOL;
566
-        $msg .= '  -logger <classname>    the class which is to perform logging' . PHP_EOL;
567
-        $msg .= '  -listener <classname>  add an instance of class as a project listener' . PHP_EOL;
568
-        $msg .= '  -f -buildfile <file>   use given buildfile' . PHP_EOL;
569
-        $msg .= '  -D<property>=<value>   use value for given property' . PHP_EOL;
570
-        $msg .= '  -keep-going, -k        execute all targets that do not depend' . PHP_EOL;
571
-        $msg .= '                         on failed target(s)' . PHP_EOL;
572
-        $msg .= '  -propertyfile <file>   load all properties from file' . PHP_EOL;
573
-        $msg .= '  -propertyfileoverride  values in property file override existing values' . PHP_EOL;
574
-        $msg .= '  -find <file>           search for buildfile towards the root of the' . PHP_EOL;
575
-        $msg .= '                         filesystem and use it' . PHP_EOL;
576
-        $msg .= '  -inputhandler <file>   the class to use to handle user input' . PHP_EOL;
577
-        //$msg .= "  -recursive <file>      search for buildfile downwards and use it" . PHP_EOL;
578
-        $msg .= PHP_EOL;
579
-        $msg .= 'Report bugs to https://github.com/phingofficial/phing/issues' . PHP_EOL;
580
-        self::$err->write($msg);
581
-    }
582
-
583
-    /**
584
-     * Prints the current Phing version.
585
-     */
586
-    public static function printVersion()
587
-    {
588
-        self::$out->write(self::getPhingVersion() . PHP_EOL);
589
-    }
590
-
591
-    /**
592
-     * Gets the current Phing version based on VERSION.TXT file.
593
-     *
594
-     * @throws ConfigurationException
595
-     */
596
-    public static function getPhingVersion(): string
597
-    {
598
-        $versionPath = self::getResourcePath('phing/etc/VERSION.TXT');
599
-        if (null === $versionPath) {
600
-            $versionPath = self::getResourcePath('etc/VERSION.TXT');
601
-        }
602
-        if (null === $versionPath) {
603
-            throw new ConfigurationException('No VERSION.TXT file found; try setting phing.home environment variable.');
604
-        }
605
-
606
-        try { // try to read file
607
-            $file = new File($versionPath);
608
-            $reader = new FileReader($file);
609
-            $phingVersion = trim($reader->read());
610
-        } catch (IOException $iox) {
611
-            throw new ConfigurationException("Can't read version information file");
612
-        }
613
-
614
-        $basePath = dirname(__DIR__, 2);
615
-
616
-        $version = new Version($phingVersion, $basePath);
617
-
618
-        return 'Phing ' . $version->getVersion();
619
-    }
620
-
621
-    /**
622
-     * Looks on include path for specified file.
623
-     *
624
-     * @param string $path
625
-     *
626
-     * @return null|string file found (null if no file found)
627
-     */
628
-    public static function getResourcePath($path): ?string
629
-    {
630
-        if (null === self::$importPaths) {
631
-            self::$importPaths = self::explodeIncludePath();
632
-        }
633
-
634
-        $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);
635
-
636
-        foreach (self::$importPaths as $prefix) {
637
-            $testPath = $prefix . DIRECTORY_SEPARATOR . $path;
638
-            if (file_exists($testPath)) {
639
-                return $testPath;
640
-            }
641
-        }
642
-
643
-        // Check for the property phing.home
644
-        $homeDir = self::getProperty(self::PHING_HOME);
645
-        if ($homeDir) {
646
-            $testPath = $homeDir . DIRECTORY_SEPARATOR . $path;
647
-            if (file_exists($testPath)) {
648
-                return $testPath;
649
-            }
650
-        }
651
-
652
-        // Check for the phing home of phar archive
653
-        if (0 === strpos(self::$importPaths[0], 'phar://')) {
654
-            $testPath = self::$importPaths[0] . '/../' . $path;
655
-            if (file_exists($testPath)) {
656
-                return $testPath;
657
-            }
658
-        }
659
-
660
-        // Do one additional check based on path of current file (Phing.php)
661
-        $maybeHomeDir = realpath(__DIR__ . DIRECTORY_SEPARATOR);
662
-        $testPath = $maybeHomeDir . DIRECTORY_SEPARATOR . $path;
663
-        if (file_exists($testPath)) {
664
-            return $testPath;
665
-        }
666
-
667
-        return null;
668
-    }
669
-
670
-    /**
671
-     * Explode an include path into an array.
672
-     *
673
-     * If no path provided, uses current include_path. Works around issues that
674
-     * occur when the path includes stream schemas.
675
-     *
676
-     * Pulled from Zend_Loader::explodeIncludePath() in ZF1.
677
-     *
678
-     * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
679
-     * @license   http://framework.zend.com/license/new-bsd New BSD License
680
-     *
681
-     * @param null|string $path
682
-     *
683
-     * @return array
684
-     */
685
-    public static function explodeIncludePath($path = null)
686
-    {
687
-        if (null === $path) {
688
-            $path = get_include_path();
689
-        }
690
-
691
-        if (PATH_SEPARATOR === ':') {
692
-            // On *nix systems, include_paths which include paths with a stream
693
-            // schema cannot be safely explode'd, so we have to be a bit more
694
-            // intelligent in the approach.
695
-            $paths = preg_split('#:(?!//)#', $path);
696
-        } else {
697
-            $paths = explode(PATH_SEPARATOR, $path);
698
-        }
699
-
700
-        return $paths;
701
-    }
702
-
703
-    /**
704
-     * Returns property value for a System property.
705
-     * System properties are "global" properties like application.startdir,
706
-     * and user.dir.  Many of these correspond to similar properties in Java
707
-     * or Ant.
708
-     *
709
-     * @param string $propName
710
-     *
711
-     * @return string value of found property (or null, if none found)
712
-     */
713
-    public static function getProperty($propName)
714
-    {
715
-        // some properties are detemined on each access
716
-        // some are cached, see below
717
-
718
-        // default is the cached value:
719
-        $val = self::$properties[$propName] ?? null;
720
-
721
-        // special exceptions
722
-        switch ($propName) {
723
-            case 'user.dir':
724
-                $val = getcwd();
725
-
726
-                break;
727
-        }
728
-
729
-        return $val;
730
-    }
731
-
732
-    /**
733
-     * Creates generic buildfile.
734
-     *
735
-     * @param string $path
736
-     */
737
-    public static function init($path)
738
-    {
739
-        if ($buildfilePath = self::initPath($path)) {
740
-            self::initWrite($buildfilePath);
741
-        }
742
-    }
743
-
744
-    /**
745
-     * Sets the stream to use for standard (non-error) output.
746
-     *
747
-     * @param OutputStream $stream the stream to use for standard output
748
-     */
749
-    public static function setOutputStream(OutputStream $stream)
750
-    {
751
-        self::$out = $stream;
752
-    }
753
-
754
-    /**
755
-     * Sets the stream to use for error output.
756
-     *
757
-     * @param OutputStream $stream the stream to use for error output
758
-     */
759
-    public static function setErrorStream(OutputStream $stream): void
760
-    {
761
-        self::$err = $stream;
762
-    }
763
-
764
-    /**
765
-     * Making output level a static property so that this property
766
-     * can be accessed by other parts of the system, enabling
767
-     * us to display more information -- e.g. backtraces -- for "debug" level.
768
-     *
769
-     * @return int
770
-     */
771
-    public static function getMsgOutputLevel()
772
-    {
773
-        return self::$msgOutputLevel;
774
-    }
775
-
776
-    /**
777
-     * Prints the message of the Exception if it's not null.
778
-     */
779
-    public static function printMessage(Throwable $t): void
780
-    {
781
-        if (null === self::$err) { // Make sure our error output is initialized
782
-            self::initializeOutputStreams();
783
-        }
784
-        if (self::getMsgOutputLevel() >= Project::MSG_VERBOSE) {
785
-            self::$err->write((string) $t . PHP_EOL);
786
-        } else {
787
-            self::$err->write($t->getMessage() . PHP_EOL);
788
-        }
789
-    }
790
-
791
-    /**
792
-     * Performs any shutdown routines, such as stopping timers.
793
-     *
794
-     * @throws IOException
795
-     */
796
-    public static function shutdown(): void
797
-    {
798
-        FileSystem::getFileSystem()::deleteFilesOnExit();
799
-        self::$msgOutputLevel = Project::MSG_INFO;
800
-        self::restoreIni();
801
-        self::getTimer()->stop();
802
-    }
803
-
804
-    /**
805
-     * Returns reference to DefaultClock object.
806
-     */
807
-    public static function getTimer(): DefaultClock
808
-    {
809
-        if (null === self::$timer) {
810
-            self::$timer = new DefaultClock();
811
-        }
812
-
813
-        return self::$timer;
814
-    }
815
-
816
-    /**
817
-     * This sets a property that was set via command line or otherwise passed into Phing.
818
-     *
819
-     * @param string $name
820
-     * @param mixed  $value
821
-     *
822
-     * @return mixed value of found property (or null, if none found)
823
-     */
824
-    public static function setDefinedProperty($name, $value)
825
-    {
826
-        return self::$definedProps->setProperty($name, $value);
827
-    }
828
-
829
-    /**
830
-     * Executes the build.
831
-     *
832
-     * @throws IOException
833
-     * @throws Throwable
834
-     */
835
-    public function runBuild(): void
836
-    {
837
-        if (!$this->readyToRun) {
838
-            return;
839
-        }
840
-
841
-        $project = new Project();
842
-
843
-        self::setCurrentProject($project);
844
-        set_error_handler(['Phing\Phing', 'handlePhpError']);
845
-
846
-        $error = null;
847
-
848
-        try {
849
-            $this->addBuildListeners($project);
850
-            $this->addInputHandler($project);
851
-
852
-            // set this right away, so that it can be used in logging.
853
-            $project->setUserProperty('phing.file', $this->buildFile->getAbsolutePath());
854
-            $project->setUserProperty('phing.dir', dirname($this->buildFile->getAbsolutePath()));
855
-            $project->setUserProperty('phing.version', static::getPhingVersion());
856
-            $project->fireBuildStarted();
857
-            $project->init();
858
-            $project->setKeepGoingMode($this->keepGoingMode);
859
-
860
-            $e = self::$definedProps->keys();
861
-            while (count($e)) {
862
-                $arg = (string) array_shift($e);
863
-                $value = (string) self::$definedProps->getProperty($arg);
864
-                $project->setUserProperty($arg, $value);
865
-            }
866
-            unset($e);
867
-
868
-            // first use the Configurator to create the project object
869
-            // from the given build file.
870
-
871
-            ProjectConfigurator::configureProject($project, $this->buildFile);
872
-
873
-            // Set the project mode
874
-            $project->setStrictMode(StringHelper::booleanValue($this->strictMode));
875
-
876
-            // make sure that minimum required phing version is satisfied
877
-            $this->comparePhingVersion($project->getPhingVersion());
878
-
879
-            if ($this->projectHelp) {
880
-                $this->printDescription($project);
881
-                $this->printTargets($project);
882
-
883
-                return;
884
-            }
885
-
886
-            // make sure that we have a target to execute
887
-            if (0 === count($this->targets)) {
888
-                $this->targets[] = $project->getDefaultTarget();
889
-            }
890
-
891
-            $project->executeTargets($this->targets);
892
-        } catch (Throwable $t) {
893
-            $error = $t;
894
-
895
-            throw $t;
896
-        } finally {
897
-            if (!$this->projectHelp) {
898
-                try {
899
-                    $project->fireBuildFinished($error);
900
-                } catch (Exception $e) {
901
-                    self::$err->write('Caught an exception while logging the end of the build.  Exception was:' . PHP_EOL);
902
-                    self::$err->write($e->getTraceAsString());
903
-                    if (null !== $error) {
904
-                        self::$err->write('There has been an error prior to that:' . PHP_EOL);
905
-                        self::$err->write($error->getTraceAsString());
906
-                    }
907
-
908
-                    throw new BuildException($error);
909
-                }
910
-            } elseif (null !== $error) {
911
-                $project->log($error->getMessage(), Project::MSG_ERR);
912
-            }
913
-
914
-            restore_error_handler();
915
-            self::unsetCurrentProject();
916
-        }
917
-    }
918
-
919
-    /**
920
-     * Import a class, supporting the following conventions:
921
-     * - PEAR style (@see http://pear.php.net/manual/en/standards.naming.php)
922
-     * - PSR-0 (@see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
923
-     *
924
-     * @param string $classname Name of class
925
-     * @param mixed  $classpath String or object supporting __toString()
926
-     *
927
-     * @throws BuildException - if cannot find the specified file
928
-     *
929
-     * @return string the unqualified classname (which can be instantiated)
930
-     */
931
-    public static function import($classname, $classpath = null)
932
-    {
933
-        // first check to see that the class specified hasn't already been included.
934
-        if (class_exists($classname)) {
935
-            return $classname;
936
-        }
937
-
938
-        $filename = strtr($classname, ['_' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR]) . '.php';
939
-
940
-        Phing::importFile($filename, $classpath);
941
-
942
-        return $classname;
943
-    }
944
-
945
-    /**
946
-     * Import a PHP file.
947
-     *
948
-     * This used to be named __import, however PHP has reserved all method names
949
-     * with a double underscore prefix for future use.
950
-     *
951
-     * @param string $path      Path to the PHP file
952
-     * @param mixed  $classpath String or object supporting __toString()
953
-     *
954
-     * @throws ConfigurationException
955
-     */
956
-    public static function importFile($path, $classpath = null)
957
-    {
958
-        if ($classpath) {
959
-            // Apparently casting to (string) no longer invokes __toString() automatically.
960
-            if (is_object($classpath)) {
961
-                $classpath = $classpath->__toString();
962
-            }
963
-
964
-            // classpaths are currently additive, but we also don't want to just
965
-            // indiscriminantly prepand/append stuff to the include_path.  This means
966
-            // we need to parse current incldue_path, and prepend any
967
-            // specified classpath locations that are not already in the include_path.
968
-            //
969
-            // NOTE:  the reason why we do it this way instead of just changing include_path
970
-            // and then changing it back, is that in many cases applications (e.g. Propel) will
971
-            // include/require class files from within method calls.  This means that not all
972
-            // necessary files will be included in this import() call, and hence we can't
973
-            // change the include_path back without breaking those apps.  While this method could
974
-            // be more expensive than switching & switching back (not sure, but maybe), it makes it
975
-            // possible to write far less expensive run-time applications (e.g. using Propel), which is
976
-            // really where speed matters more.
977
-
978
-            $curr_parts = Phing::explodeIncludePath();
979
-            $add_parts = Phing::explodeIncludePath($classpath);
980
-            $new_parts = array_diff($add_parts, $curr_parts);
981
-            if ($new_parts) {
982
-                set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
983
-            }
984
-        }
985
-
986
-        $ret = include_once $path;
987
-
988
-        if (false === $ret) {
989
-            $msg = "Error importing {$path}";
990
-            if (self::getMsgOutputLevel() >= Project::MSG_DEBUG) {
991
-                $x = new Exception('for-path-trace-only');
992
-                $msg .= $x->getTraceAsString();
993
-            }
994
-
995
-            throw new ConfigurationException($msg);
996
-        }
997
-    }
998
-
999
-    /**
1000
-     * Print the project description, if any.
1001
-     *
1002
-     * @throws IOException
1003
-     */
1004
-    public function printDescription(Project $project): void
1005
-    {
1006
-        if (null !== $project->getDescription()) {
1007
-            $project->log($project->getDescription());
1008
-        }
1009
-    }
1010
-
1011
-    /**
1012
-     * Print out a list of all targets in the current buildfile.
1013
-     */
1014
-    public function printTargets(Project $project)
1015
-    {
1016
-        $visibleTargets = array_filter($project->getTargets(), function (Target $target) {
1017
-            return !$target->isHidden() && !empty($target->getName());
1018
-        });
1019
-        $padding = array_reduce($visibleTargets, function (int $carry, Target $target) {
1020
-            return max(strlen($target->getName()), $carry);
1021
-        }, 0);
1022
-        $categories = [
1023
-            'Default target:' => array_filter($visibleTargets, function (Target $target) use ($project) {
1024
-                return trim(strval($target)) === $project->getDefaultTarget();
1025
-            }),
1026
-            'Main targets:' => array_filter($visibleTargets, function (Target $target) {
1027
-                return !empty($target->getDescription());
1028
-            }),
1029
-            'Subtargets:' => array_filter($visibleTargets, function (Target $target) {
1030
-                return empty($target->getDescription());
1031
-            }),
1032
-        ];
1033
-        foreach ($categories as $title => $targets) {
1034
-            $targetList = $this->generateTargetList($title, $targets, $padding);
1035
-            $project->log($targetList, Project::MSG_WARN);
1036
-        }
1037
-    }
1038
-
1039
-    /**
1040
-     * Unsets the current Project.
1041
-     */
1042
-    public static function unsetCurrentProject(): void
1043
-    {
1044
-        self::$currentProject = null;
1045
-    }
1046
-
1047
-    /**
1048
-     * Error handler for PHP errors encountered during the build.
1049
-     * This uses the logging for the currently configured project.
1050
-     *
1051
-     * @param $level
1052
-     * @param string $message
1053
-     * @param $file
1054
-     * @param $line
1055
-     */
1056
-    public static function handlePhpError($level, $message, $file, $line)
1057
-    {
1058
-        // don't want to print suppressed errors
1059
-        if (error_reporting() > 0) {
1060
-            if (self::$phpErrorCapture) {
1061
-                self::$capturedPhpErrors[] = [
1062
-                    'message' => $message,
1063
-                    'level' => $level,
1064
-                    'line' => $line,
1065
-                    'file' => $file,
1066
-                ];
1067
-            } else {
1068
-                $message = '[PHP Error] ' . $message;
1069
-                $message .= ' [line ' . $line . ' of ' . $file . ']';
1070
-
1071
-                switch ($level) {
1072
-                    case E_USER_DEPRECATED:
1073
-                    case E_DEPRECATED:
1074
-                    case E_STRICT:
1075
-                    case E_NOTICE:
1076
-                    case E_USER_NOTICE:
1077
-                        self::log($message, Project::MSG_VERBOSE);
1078
-
1079
-                        break;
1080
-
1081
-                    case E_WARNING:
1082
-                    case E_USER_WARNING:
1083
-                        self::log($message, Project::MSG_WARN);
1084
-
1085
-                        break;
1086
-
1087
-                    case E_ERROR:
1088
-                    case E_USER_ERROR:
1089
-                    default:
1090
-                        self::log($message, Project::MSG_ERR);
1091
-                } // switch
1092
-            } // if phpErrorCapture
1093
-        } // if not @
1094
-    }
1095
-
1096
-    /**
1097
-     * A static convenience method to send a log to the current (last-setup) Project.
1098
-     * If there is no currently-configured Project, then this will do nothing.
1099
-     *
1100
-     * @param string $message
1101
-     * @param int    $priority project::MSG_INFO, etc
1102
-     */
1103
-    public static function log($message, $priority = Project::MSG_INFO): void
1104
-    {
1105
-        $p = self::getCurrentProject();
1106
-        if ($p) {
1107
-            $p->log($message, $priority);
1108
-        }
1109
-    }
1110
-
1111
-    /**
1112
-     * Gets the current Project.
1113
-     *
1114
-     * @return Project current Project or NULL if none is set yet/still
1115
-     */
1116
-    public static function getCurrentProject()
1117
-    {
1118
-        return self::$currentProject;
1119
-    }
1120
-
1121
-    /**
1122
-     * Sets the current Project.
1123
-     *
1124
-     * @param Project $p
1125
-     */
1126
-    public static function setCurrentProject($p): void
1127
-    {
1128
-        self::$currentProject = $p;
1129
-    }
1130
-
1131
-    /**
1132
-     * Begins capturing PHP errors to a buffer.
1133
-     * While errors are being captured, they are not logged.
1134
-     */
1135
-    public static function startPhpErrorCapture(): void
1136
-    {
1137
-        self::$phpErrorCapture = true;
1138
-        self::$capturedPhpErrors = [];
1139
-    }
1140
-
1141
-    /**
1142
-     * Stops capturing PHP errors to a buffer.
1143
-     * The errors will once again be logged after calling this method.
1144
-     */
1145
-    public static function stopPhpErrorCapture(): void
1146
-    {
1147
-        self::$phpErrorCapture = false;
1148
-    }
1149
-
1150
-    /**
1151
-     * Clears the captured errors without affecting the starting/stopping of the capture.
1152
-     */
1153
-    public static function clearCapturedPhpErrors(): void
1154
-    {
1155
-        self::$capturedPhpErrors = [];
1156
-    }
1157
-
1158
-    /**
1159
-     * Gets any PHP errors that were captured to buffer.
1160
-     *
1161
-     * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level)
1162
-     */
1163
-    public static function getCapturedPhpErrors()
1164
-    {
1165
-        return self::$capturedPhpErrors;
1166
-    }
1167
-
1168
-    /**
1169
-     * This gets a property that was set via command line or otherwise passed into Phing.
1170
-     * "Defined" in this case means "externally defined".  The reason this method exists is to
1171
-     * provide a public means of accessing commandline properties for (e.g.) logger or listener
1172
-     * scripts.  E.g. to specify which logfile to use, PearLogger needs to be able to access
1173
-     * the pear.log.name property.
1174
-     *
1175
-     * @param string $name
1176
-     *
1177
-     * @return string value of found property (or null, if none found)
1178
-     */
1179
-    public static function getDefinedProperty($name)
1180
-    {
1181
-        return self::$definedProps->getProperty($name);
1182
-    }
1183
-
1184
-    /**
1185
-     * Retuns reference to all properties.
1186
-     */
1187
-    public static function &getProperties()
1188
-    {
1189
-        return self::$properties;
1190
-    }
1191
-
1192
-    /**
1193
-     * Start up Phing.
1194
-     * Sets up the Phing environment but does not initiate the build process.
1195
-     *
1196
-     * @throws exception - If the Phing environment cannot be initialized
1197
-     */
1198
-    public static function startup(): void
1199
-    {
1200
-        // setup STDOUT and STDERR defaults
1201
-        self::initializeOutputStreams();
1202
-
1203
-        // some init stuff
1204
-        self::getTimer()->start();
1205
-
1206
-        self::setSystemConstants();
1207
-        self::setIncludePaths();
1208
-        self::setIni();
1209
-    }
1210
-
1211
-    /**
1212
-     * @param $propName
1213
-     * @param $propValue
1214
-     *
1215
-     * @return string
1216
-     */
1217
-    public static function setProperty($propName, $propValue)
1218
-    {
1219
-        $propName = (string) $propName;
1220
-        $oldValue = self::getProperty($propName);
1221
-        self::$properties[$propName] = $propValue;
1222
-
1223
-        return $oldValue;
1224
-    }
1225
-
1226
-    /**
1227
-     * Returns buildfile's path.
1228
-     *
1229
-     * @param $path
1230
-     *
1231
-     * @throws ConfigurationException
1232
-     *
1233
-     * @return string
1234
-     */
1235
-    protected static function initPath($path)
1236
-    {
1237
-        // Fallback
1238
-        if (empty($path)) {
1239
-            $defaultDir = self::getProperty('application.startdir');
1240
-            $path = $defaultDir . DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1241
-        }
1242
-
1243
-        // Adding filename if necessary
1244
-        if (is_dir($path)) {
1245
-            $path .= DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1246
-        }
1247
-
1248
-        // Check if path is available
1249
-        $dirname = dirname($path);
1250
-        if (is_dir($dirname) && !is_file($path)) {
1251
-            return $path;
1252
-        }
1253
-
1254
-        // Path is valid, but buildfile already exists
1255
-        if (is_file($path)) {
1256
-            throw new ConfigurationException('Buildfile already exists.');
1257
-        }
1258
-
1259
-        throw new ConfigurationException('Invalid path for sample buildfile.');
1260
-    }
1261
-
1262
-    /**
1263
-     * Writes sample buildfile.
1264
-     *
1265
-     * If $buildfilePath does not exist, the buildfile is created.
1266
-     *
1267
-     * @param $buildfilePath buildfile's location
1268
-     *
1269
-     * @throws ConfigurationException
1270
-     */
1271
-    protected static function initWrite($buildfilePath): void
1272
-    {
1273
-        // Overwriting protection
1274
-        if (file_exists($buildfilePath)) {
1275
-            throw new ConfigurationException('Cannot overwrite existing file.');
1276
-        }
1277
-
1278
-        file_put_contents($buildfilePath, self::DEFAULT_BUILD_CONTENT);
1279
-    }
1280
-
1281
-    /**
1282
-     * This operation is expected to call `exit($int)`, which
1283
-     * is what the base version does.
1284
-     * However, it is possible to do something else.
1285
-     *
1286
-     * @param int $exitCode code to exit with
1287
-     */
1288
-    protected static function statusExit($exitCode): void
1289
-    {
1290
-        Phing::shutdown();
1291
-
1292
-        exit($exitCode);
1293
-    }
1294
-
1295
-    /**
1296
-     * Handle the -propertyfile argument.
1297
-     *
1298
-     * @throws ConfigurationException
1299
-     * @throws IOException
1300
-     */
1301
-    private function handleArgPropertyFile(array $args, int $pos): int
1302
-    {
1303
-        if (!isset($args[$pos + 1])) {
1304
-            throw new ConfigurationException('You must specify a filename when using the -propertyfile argument');
1305
-        }
1306
-
1307
-        $this->propertyFiles[] = $args[++$pos];
1308
-
1309
-        return $pos;
1310
-    }
1311
-
1312
-    /**
1313
-     * Search parent directories for the build file.
1314
-     *
1315
-     * Takes the given target as a suffix to append to each
1316
-     * parent directory in search of a build file.  Once the
1317
-     * root of the file-system has been reached an exception
1318
-     * is thrown.
1319
-     *
1320
-     * @param string $start  start file path
1321
-     * @param string $suffix suffix filename to look for in parents
1322
-     *
1323
-     * @throws ConfigurationException
1324
-     *
1325
-     * @return File A handle to the build file
1326
-     */
1327
-    private function findBuildFile($start, $suffix)
1328
-    {
1329
-        if (self::getMsgOutputLevel() >= Project::MSG_INFO) {
1330
-            self::$out->write('Searching for ' . $suffix . ' ...' . PHP_EOL);
1331
-        }
1332
-
1333
-        $parent = new File((new File($start))->getAbsolutePath());
1334
-        $file = new File($parent, $suffix);
1335
-
1336
-        // check if the target file exists in the current directory
1337
-        while (!$file->exists()) {
1338
-            // change to parent directory
1339
-            $parent = $parent->getParentFile();
1340
-
1341
-            // if parent is null, then we are at the root of the fs,
1342
-            // complain that we can't find the build file.
1343
-            if (null === $parent) {
1344
-                throw new ConfigurationException('Could not locate a build file!');
1345
-            }
1346
-            // refresh our file handle
1347
-            $file = new File($parent, $suffix);
1348
-        }
1349
-
1350
-        return $file;
1351
-    }
1352
-
1353
-    /**
1354
-     * @throws IOException
1355
-     */
1356
-    private function loadPropertyFiles(): void
1357
-    {
1358
-        foreach ($this->propertyFiles as $filename) {
1359
-            $fileParserFactory = new FileParserFactory();
1360
-            $fileParser = $fileParserFactory->createParser(pathinfo($filename, PATHINFO_EXTENSION));
1361
-            $p = new Properties(null, $fileParser);
1362
-
1363
-            try {
1364
-                $p->load(new File($filename));
1365
-            } catch (IOException $e) {
1366
-                self::$out->write('Could not load property file ' . $filename . ': ' . $e->getMessage());
1367
-            }
1368
-            foreach ($p->getProperties() as $prop => $value) {
1369
-                self::$definedProps->setProperty($prop, $value);
1370
-            }
1371
-        }
1372
-    }
1373
-
1374
-    /**
1375
-     * Close logfiles, if we have been writing to them.
1376
-     *
1377
-     * @since Phing 2.3.0
1378
-     */
1379
-    private static function handleLogfile(): void
1380
-    {
1381
-        if (self::$isLogFileUsed) {
1382
-            self::$err->close();
1383
-            self::$out->close();
1384
-        }
1385
-    }
1386
-
1387
-    /**
1388
-     * Sets the stdout and stderr streams if they are not already set.
1389
-     */
1390
-    private static function initializeOutputStreams()
1391
-    {
1392
-        if (null === self::$out) {
1393
-            if (!defined('STDOUT')) {
1394
-                self::$out = new OutputStream(fopen('php://stdout', 'w'));
1395
-            } else {
1396
-                self::$out = new OutputStream(STDOUT);
1397
-            }
1398
-        }
1399
-        if (null === self::$err) {
1400
-            if (!defined('STDERR')) {
1401
-                self::$err = new OutputStream(fopen('php://stderr', 'w'));
1402
-            } else {
1403
-                self::$err = new OutputStream(STDERR);
1404
-            }
1405
-        }
1406
-    }
1407
-
1408
-    /**
1409
-     * Restores [most] PHP INI values to their pre-Phing state.
1410
-     *
1411
-     * Currently the following settings are not restored:
1412
-     *  - max_execution_time (because getting current time limit is not possible)
1413
-     *  - memory_limit (which may have been increased by Phing)
1414
-     */
1415
-    private static function restoreIni(): void
1416
-    {
1417
-        foreach (self::$origIniSettings as $settingName => $settingValue) {
1418
-            switch ($settingName) {
1419
-                case 'error_reporting':
1420
-                    error_reporting($settingValue);
1421
-
1422
-                    break;
1423
-
1424
-                default:
1425
-                    ini_set($settingName, $settingValue);
1426
-            }
1427
-        }
1428
-    }
1429
-
1430
-    /**
1431
-     * Bind any registered build listeners to this project.
1432
-     *
1433
-     * This means adding the logger and any build listeners that were specified
1434
-     * with -listener arg.
1435
-     *
1436
-     * @throws BuildException
1437
-     * @throws ConfigurationException
1438
-     */
1439
-    private function addBuildListeners(Project $project)
1440
-    {
1441
-        // Add the default listener
1442
-        $project->addBuildListener($this->createLogger());
1443
-
1444
-        foreach ($this->listeners as $listenerClassname) {
1445
-            try {
1446
-                $clz = Phing::import($listenerClassname);
1447
-            } catch (Exception $e) {
1448
-                $msg = 'Unable to instantiate specified listener '
1449
-                    . 'class ' . $listenerClassname . ' : '
1450
-                    . $e->getMessage();
1451
-
1452
-                throw new ConfigurationException($msg);
1453
-            }
1454
-
1455
-            $listener = new $clz();
1456
-
1457
-            if ($listener instanceof StreamRequiredBuildLogger) {
1458
-                throw new ConfigurationException('Unable to add ' . $listenerClassname . ' as a listener, since it requires explicit error/output streams. (You can specify it as a -logger.)');
1459
-            }
1460
-            $project->addBuildListener($listener);
1461
-        }
1462
-    }
1463
-
1464
-    /**
1465
-     * Creates the default build logger for sending build events to the log.
1466
-     *
1467
-     * @throws BuildException
1468
-     *
1469
-     * @return BuildLogger The created Logger
1470
-     */
1471
-    private function createLogger()
1472
-    {
1473
-        if ($this->silent) {
1474
-            $logger = new SilentLogger();
1475
-            self::$msgOutputLevel = Project::MSG_WARN;
1476
-        } elseif (null !== $this->loggerClassname) {
1477
-            self::import($this->loggerClassname);
1478
-            // get class name part
1479
-            $classname = self::import($this->loggerClassname);
1480
-            $logger = new $classname();
1481
-            if (!($logger instanceof BuildLogger)) {
1482
-                throw new BuildException($classname . ' does not implement the BuildLogger interface.');
1483
-            }
1484
-        } else {
1485
-            $logger = new DefaultLogger();
1486
-        }
1487
-        $logger->setMessageOutputLevel(self::$msgOutputLevel);
1488
-        $logger->setOutputStream(self::$out);
1489
-        $logger->setErrorStream(self::$err);
1490
-        $logger->setEmacsMode($this->emacsMode);
1491
-
1492
-        return $logger;
1493
-    }
1494
-
1495
-    /**
1496
-     * Creates the InputHandler and adds it to the project.
1497
-     *
1498
-     * @param Project $project the project instance
1499
-     *
1500
-     * @throws ConfigurationException
1501
-     */
1502
-    private function addInputHandler(Project $project): void
1503
-    {
1504
-        if (null === $this->inputHandlerClassname) {
1505
-            $handler = new ConsoleInputHandler(STDIN, new ConsoleOutput());
1506
-        } else {
1507
-            try {
1508
-                $clz = Phing::import($this->inputHandlerClassname);
1509
-                $handler = new $clz();
1510
-                if (null !== $project && method_exists($handler, 'setProject')) {
1511
-                    $handler->setProject($project);
1512
-                }
1513
-            } catch (Exception $e) {
1514
-                $msg = 'Unable to instantiate specified input handler '
1515
-                    . 'class ' . $this->inputHandlerClassname . ' : '
1516
-                    . $e->getMessage();
1517
-
1518
-                throw new ConfigurationException($msg);
1519
-            }
1520
-        }
1521
-        $project->setInputHandler($handler);
1522
-    }
1523
-
1524
-    /**
1525
-     * @param string $version
1526
-     *
1527
-     * @throws BuildException
1528
-     * @throws ConfigurationException
1529
-     */
1530
-    private function comparePhingVersion($version): void
1531
-    {
1532
-        $current = strtolower(self::getPhingVersion());
1533
-        $current = trim(str_replace('phing', '', $current));
1534
-
1535
-        // make sure that version checks are not applied to trunk
1536
-        if ('dev' === $current) {
1537
-            return;
1538
-        }
1539
-
1540
-        if (-1 == version_compare($current, $version)) {
1541
-            throw new BuildException(
1542
-                sprintf('Incompatible Phing version (%s). Version "%s" required.', $current, $version)
1543
-            );
1544
-        }
1545
-    }
1546
-
1547
-    /**
1548
-     * Returns a formatted list of target names with an optional description.
1549
-     *
1550
-     * @param string   $title   Title for this list
1551
-     * @param Target[] $targets Targets in this list
1552
-     * @param int      $padding Padding for name column
1553
-     */
1554
-    private function generateTargetList(string $title, array $targets, int $padding): string
1555
-    {
1556
-        usort($targets, function (Target $a, Target $b) {
1557
-            return $a->getName() <=> $b->getName();
1558
-        });
1559
-
1560
-        $header = <<<HEADER
1561
-            {$title}
1562
-            -------------------------------------------------------------------------------
1563
-
1564
-            HEADER;
1565
-
1566
-        $getDetails = function (Target $target) use ($padding): string {
1567
-            $details = [];
1568
-            if (!empty($target->getDescription())) {
1569
-                $details[] = $target->getDescription();
1570
-            }
1571
-            if (!empty($target->getDependencies())) {
1572
-                $details[] = ' - depends on: ' . implode(', ', $target->getDependencies());
1573
-            }
1574
-            if (!empty($target->getIf())) {
1575
-                $details[] = ' - if property: ' . $target->getIf();
1576
-            }
1577
-            if (!empty($target->getUnless())) {
1578
-                $details[] = ' - unless property: ' . $target->getUnless();
1579
-            }
1580
-            $detailsToString = function (?string $name, ?string $detail) use ($padding): string {
1581
-                return sprintf(" %-{$padding}s  %s", $name, $detail);
1582
-            };
1583
-
1584
-            return implode(PHP_EOL, array_map($detailsToString, [$target->getName()], $details));
1585
-        };
1586
-
1587
-        return $header . implode(PHP_EOL, array_map($getDetails, $targets)) . PHP_EOL;
1588
-    }
1589
-
1590
-    /**
1591
-     * Set System constants which can be retrieved by calling Phing::getProperty($propName).
1592
-     */
1593
-    private static function setSystemConstants(): void
1594
-    {
1595
-        /*
1596
-         * PHP_OS returns on
1597
-         *   WindowsNT4.0sp6  => WINNT
1598
-         *   Windows2000      => WINNT
1599
-         *   Windows ME       => WIN32
1600
-         *   Windows 98SE     => WIN32
1601
-         *   FreeBSD 4.5p7    => FreeBSD
1602
-         *   Redhat Linux     => Linux
1603
-         *   Mac OS X         => Darwin
1604
-         */
1605
-        self::setProperty('host.os', PHP_OS);
1606
-
1607
-        // this is used by some tasks too
1608
-        self::setProperty('os.name', PHP_OS);
1609
-
1610
-        // it's still possible this won't be defined,
1611
-        // e.g. if Phing is being included in another app w/o
1612
-        // using the phing.php script.
1613
-        if (!defined('PHP_CLASSPATH')) {
1614
-            define('PHP_CLASSPATH', get_include_path());
1615
-        }
1616
-
1617
-        self::setProperty('php.classpath', PHP_CLASSPATH);
1618
-
1619
-        // try to determine the host filesystem and set system property
1620
-        // used by Fileself::getFileSystem to instantiate the correct
1621
-        // abstraction layer
1622
-
1623
-        if (PHP_OS_FAMILY === 'Windows') {
1624
-            self::setProperty('host.fstype', 'WINDOWS');
1625
-            self::setProperty('user.home', getenv('HOMEDRIVE') . getenv('HOMEPATH'));
1626
-        } else {
1627
-            self::setProperty('host.fstype', 'UNIX');
1628
-            self::setProperty('user.home', getenv('HOME'));
1629
-        }
1630
-        self::setProperty(self::PHP_INTERPRETER, PHP_BINARY);
1631
-        self::setProperty('file.separator', FileUtils::getSeparator());
1632
-        self::setProperty('line.separator', PHP_EOL);
1633
-        self::setProperty('path.separator', FileUtils::getPathSeparator());
1634
-        self::setProperty(self::PHP_VERSION, PHP_VERSION);
1635
-        self::setProperty('php.tmpdir', sys_get_temp_dir());
1636
-        self::setProperty('application.startdir', getcwd());
1637
-        self::setProperty('phing.startTime', gmdate('D, d M Y H:i:s', time()) . ' GMT');
1638
-
1639
-        // try to detect machine dependent information
1640
-        $sysInfo = [];
1641
-        if (function_exists('posix_uname') && 0 !== stripos(PHP_OS, 'WIN')) {
1642
-            $sysInfo = posix_uname();
1643
-        } else {
1644
-            $sysInfo['nodename'] = php_uname('n');
1645
-            $sysInfo['machine'] = php_uname('m');
1646
-            //this is a not so ideal substition, but maybe better than nothing
1647
-            $sysInfo['domain'] = $_SERVER['SERVER_NAME'] ?? 'unknown';
1648
-            $sysInfo['release'] = php_uname('r');
1649
-            $sysInfo['version'] = php_uname('v');
1650
-        }
1651
-
1652
-        self::setProperty('host.name', $sysInfo['nodename'] ?? 'unknown');
1653
-        self::setProperty('host.arch', $sysInfo['machine'] ?? 'unknown');
1654
-        self::setProperty('host.domain', $sysInfo['domain'] ?? 'unknown');
1655
-        self::setProperty('host.os.release', $sysInfo['release'] ?? 'unknown');
1656
-        self::setProperty('host.os.version', $sysInfo['version'] ?? 'unknown');
1657
-        unset($sysInfo);
1658
-    }
1659
-
1660
-    /**
1661
-     * Sets the include path to PHP_CLASSPATH constant (if this has been defined).
1662
-     *
1663
-     * @throws ConfigurationException - if the include_path could not be set (for some bizarre reason)
1664
-     */
1665
-    private static function setIncludePaths(): void
1666
-    {
1667
-        if (defined('PHP_CLASSPATH')) {
1668
-            $result = set_include_path(PHP_CLASSPATH);
1669
-            if (false === $result) {
1670
-                throw new ConfigurationException('Could not set PHP include_path.');
1671
-            }
1672
-            self::$origIniSettings['include_path'] = $result; // save original value for setting back later
1673
-        }
1674
-    }
1675
-
1676
-    /**
1677
-     * Sets PHP INI values that Phing needs.
1678
-     */
1679
-    private static function setIni(): void
1680
-    {
1681
-        self::$origIniSettings['error_reporting'] = error_reporting(E_ALL);
1682
-
1683
-        // We won't bother storing original max_execution_time, since 1) the value in
1684
-        // php.ini may be wrong (and there's no way to get the current value) and
1685
-        // 2) it would mean something very strange to set it to a value less than time script
1686
-        // has already been running, which would be the likely change.
1687
-
1688
-        set_time_limit(0);
1689
-
1690
-        self::$origIniSettings['short_open_tag'] = ini_set('short_open_tag', 'off');
1691
-        self::$origIniSettings['default_charset'] = ini_set('default_charset', 'iso-8859-1');
1692
-
1693
-        $mem_limit = (int) SizeHelper::fromHumanToBytes(ini_get('memory_limit'));
1694
-        if ($mem_limit < (32 * 1024 * 1024) && $mem_limit > -1) {
1695
-            // We do *not* need to save the original value here, since we don't plan to restore
1696
-            // this after shutdown (we don't trust the effectiveness of PHP's garbage collection).
1697
-            ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects
1698
-        }
1699
-    }
1700
-}
Please login to merge, or discard this patch.
Switch Indentation   -1615 removed lines patch added patch discarded remove patch
@@ -83,1618 +83,3 @@
 block discarded – undo
83 83
      */
84 84
     public const DEFAULT_BUILD_FILENAME = 'build.xml';
85 85
     public const DEFAULT_BUILD_CONTENT = <<<'XML'
86
-        <?xml version="1.0" encoding="UTF-8" ?>
87
-
88
-        <project name="" description="" default="">
89
-            
90
-            <target name="" description="">
91
-                
92
-            </target>
93
-            
94
-        </project>
95
-        XML;
96
-    public const PHING_HOME = 'phing.home';
97
-    public const PHP_VERSION = 'php.version';
98
-    public const PHP_INTERPRETER = 'php.interpreter';
99
-
100
-    /**
101
-     * Our current message output status. Follows Project::MSG_XXX.
102
-     */
103
-    private static $msgOutputLevel = Project::MSG_INFO;
104
-    /**
105
-     * Set of properties that are passed in from commandline or invoking code.
106
-     *
107
-     * @var Properties
108
-     */
109
-    private static $definedProps;
110
-    /**
111
-     * Used by utility function getResourcePath().
112
-     */
113
-    private static $importPaths;
114
-    /**
115
-     * System-wide static properties (moved from System).
116
-     */
117
-    private static $properties = [];
118
-    /**
119
-     * Static system timer.
120
-     */
121
-    private static $timer;
122
-    /**
123
-     * The current Project.
124
-     */
125
-    private static $currentProject;
126
-    /**
127
-     * Whether to capture PHP errors to buffer.
128
-     */
129
-    private static $phpErrorCapture = false;
130
-    /**
131
-     * Array of captured PHP errors.
132
-     */
133
-    private static $capturedPhpErrors = [];
134
-    /**
135
-     * @var OUtputStream stream for standard output
136
-     */
137
-    private static $out;
138
-    /**
139
-     * @var OutputStream stream for error output
140
-     */
141
-    private static $err;
142
-    /**
143
-     * @var bool whether we are using a logfile
144
-     */
145
-    private static $isLogFileUsed = false;
146
-    /**
147
-     * Array to hold original ini settings that Phing changes (and needs
148
-     * to restore in restoreIni() method).
149
-     *
150
-     * @var array Struct of array(setting-name => setting-value)
151
-     *
152
-     * @see restoreIni()
153
-     */
154
-    private static $origIniSettings = [];
155
-    /**
156
-     * PhingFile that we are using for configuration.
157
-     */
158
-    private $buildFile;
159
-    /**
160
-     * The build targets.
161
-     */
162
-    private $targets = [];
163
-    /**
164
-     * Names of classes to add as listeners to project.
165
-     */
166
-    private $listeners = [];
167
-    /**
168
-     * keep going mode.
169
-     *
170
-     * @var bool
171
-     */
172
-    private $keepGoingMode = false;
173
-    private $loggerClassname;
174
-    /**
175
-     * The class to handle input (can be only one).
176
-     */
177
-    private $inputHandlerClassname;
178
-    /**
179
-     * Whether or not log output should be reduced to the minimum.
180
-     *
181
-     * @var bool
182
-     */
183
-    private $silent = false;
184
-    /**
185
-     * Indicates whether phing should run in strict mode.
186
-     */
187
-    private $strictMode = false;
188
-    /**
189
-     * Indicates if this phing should be run.
190
-     */
191
-    private $readyToRun = false;
192
-    /**
193
-     * Indicates we should only parse and display the project help information.
194
-     */
195
-    private $projectHelp = false;
196
-    /**
197
-     * Whether to values in a property file should override existing values.
198
-     */
199
-    private $propertyFileOverride = false;
200
-    /**
201
-     * Whether or not output to the log is to be unadorned.
202
-     */
203
-    private $emacsMode = false;
204
-
205
-    /**
206
-     * @var string
207
-     */
208
-    private $searchForThis;
209
-    private $propertyFiles = [];
210
-
211
-    /**
212
-     * Gets the stream to use for standard (non-error) output.
213
-     *
214
-     * @return OutputStream
215
-     */
216
-    public static function getOutputStream()
217
-    {
218
-        return self::$out;
219
-    }
220
-
221
-    /**
222
-     * Gets the stream to use for error output.
223
-     *
224
-     * @return OutputStream
225
-     */
226
-    public static function getErrorStream()
227
-    {
228
-        return self::$err;
229
-    }
230
-
231
-    /**
232
-     * Command line entry point. This method kicks off the building
233
-     * of a project object and executes a build using either a given
234
-     * target or the default target.
235
-     *
236
-     * @param array $args command line args
237
-     *
238
-     * @throws Exception
239
-     */
240
-    public static function fire($args): void
241
-    {
242
-        self::start($args);
243
-    }
244
-
245
-    /**
246
-     * Entry point allowing for more options from other front ends.
247
-     *
248
-     * This method encapsulates the complete build lifecycle.
249
-     *
250
-     * @param array $args                     the commandline args passed to phing shell script
251
-     * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this).
252
-     *                                        These additional properties will be available using the getDefinedProperty() method and will
253
-     *                                        be added to the project's "user" properties
254
-     *
255
-     * @throws Exception - if there is an error during build
256
-     *
257
-     * @see    runBuild()
258
-     * @see    execute()
259
-     */
260
-    public static function start($args, array $additionalUserProperties = null)
261
-    {
262
-        try {
263
-            $m = new self();
264
-            $m->execute($args);
265
-        } catch (Exception $exc) {
266
-            self::handleLogfile();
267
-            self::printMessage($exc);
268
-            self::statusExit(1);
269
-
270
-            return;
271
-        }
272
-
273
-        if (null !== $additionalUserProperties) {
274
-            foreach ($additionalUserProperties as $key => $value) {
275
-                $m::setDefinedProperty($key, $value);
276
-            }
277
-        }
278
-
279
-        // expect the worst
280
-        $exitCode = 1;
281
-
282
-        try {
283
-            try {
284
-                $m->runBuild();
285
-                $exitCode = 0;
286
-            } catch (ExitStatusException $ese) {
287
-                $exitCode = $ese->getCode();
288
-                if (0 !== $exitCode) {
289
-                    self::handleLogfile();
290
-
291
-                    throw $ese;
292
-                }
293
-            }
294
-        } catch (BuildException $exc) {
295
-            // avoid printing output twice: self::printMessage($exc);
296
-        } catch (Throwable $exc) {
297
-            self::printMessage($exc);
298
-        } finally {
299
-            self::handleLogfile();
300
-        }
301
-        self::statusExit($exitCode);
302
-    }
303
-
304
-    /**
305
-     * Setup/initialize Phing environment from commandline args.
306
-     *
307
-     * @param array $args commandline args passed to phing shell
308
-     *
309
-     * @throws ConfigurationException
310
-     */
311
-    public function execute($args): void
312
-    {
313
-        self::$definedProps = new Properties();
314
-        $this->searchForThis = null;
315
-
316
-        // 1) First handle any options which should always
317
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
318
-
319
-        if (in_array('-help', $args) || in_array('-h', $args)) {
320
-            static::printUsage();
321
-
322
-            return;
323
-        }
324
-
325
-        if (in_array('-version', $args) || in_array('-v', $args)) {
326
-            static::printVersion();
327
-
328
-            return;
329
-        }
330
-
331
-        if (in_array('-init', $args) || in_array('-i', $args)) {
332
-            $key = array_search('-init', $args) ?: array_search('-i', $args);
333
-            $path = $args[$key + 1] ?? null;
334
-
335
-            self::init($path);
336
-
337
-            return;
338
-        }
339
-
340
-        if (in_array('-diagnostics', $args)) {
341
-            Diagnostics::doReport(new PrintStream(self::$out));
342
-
343
-            return;
344
-        }
345
-
346
-        // 2) Next pull out stand-alone args.
347
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
348
-
349
-        if (
350
-            false !== ($key = array_search('-quiet', $args, true))
351
-            || false !== ($key = array_search(
352
-                '-q',
353
-                $args,
354
-                true
355
-            ))
356
-        ) {
357
-            self::$msgOutputLevel = Project::MSG_WARN;
358
-            unset($args[$key]);
359
-        }
360
-
361
-        if (
362
-            false !== ($key = array_search('-emacs', $args, true))
363
-            || false !== ($key = array_search('-e', $args, true))
364
-        ) {
365
-            $this->emacsMode = true;
366
-            unset($args[$key]);
367
-        }
368
-
369
-        if (false !== ($key = array_search('-verbose', $args, true))) {
370
-            self::$msgOutputLevel = Project::MSG_VERBOSE;
371
-            unset($args[$key]);
372
-        }
373
-
374
-        if (false !== ($key = array_search('-debug', $args, true))) {
375
-            self::$msgOutputLevel = Project::MSG_DEBUG;
376
-            unset($args[$key]);
377
-        }
378
-
379
-        if (
380
-            false !== ($key = array_search('-silent', $args, true))
381
-            || false !== ($key = array_search('-S', $args, true))
382
-        ) {
383
-            $this->silent = true;
384
-            unset($args[$key]);
385
-        }
386
-
387
-        if (false !== ($key = array_search('-propertyfileoverride', $args, true))) {
388
-            $this->propertyFileOverride = true;
389
-            unset($args[$key]);
390
-        }
391
-
392
-        // 3) Finally, cycle through to parse remaining args
393
-        //
394
-        $keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
395
-        $max = $keys ? max($keys) : -1;
396
-        for ($i = 0; $i <= $max; ++$i) {
397
-            if (!array_key_exists($i, $args)) {
398
-                // skip this argument, since it must have been removed above.
399
-                continue;
400
-            }
401
-
402
-            $arg = $args[$i];
403
-
404
-            if ('-logfile' == $arg) {
405
-                try {
406
-                    // see: http://phing.info/trac/ticket/65
407
-                    if (!isset($args[$i + 1])) {
408
-                        $msg = "You must specify a log file when using the -logfile argument\n";
409
-
410
-                        throw new ConfigurationException($msg);
411
-                    }
412
-
413
-                    $logFile = new File($args[++$i]);
414
-                    $out = new FileOutputStream($logFile); // overwrite
415
-                    self::setOutputStream($out);
416
-                    self::setErrorStream($out);
417
-                    self::$isLogFileUsed = true;
418
-                } catch (IOException $ioe) {
419
-                    $msg = 'Cannot write on the specified log file. Make sure the path exists and you have write permissions.';
420
-
421
-                    throw new ConfigurationException($msg, $ioe);
422
-                }
423
-            } elseif ('-buildfile' == $arg || '-file' == $arg || '-f' == $arg) {
424
-                if (!isset($args[$i + 1])) {
425
-                    $msg = 'You must specify a buildfile when using the -buildfile argument.';
426
-
427
-                    throw new ConfigurationException($msg);
428
-                }
429
-
430
-                $this->buildFile = new File($args[++$i]);
431
-            } elseif ('-listener' == $arg) {
432
-                if (!isset($args[$i + 1])) {
433
-                    $msg = 'You must specify a listener class when using the -listener argument';
434
-
435
-                    throw new ConfigurationException($msg);
436
-                }
437
-
438
-                $this->listeners[] = $args[++$i];
439
-            } elseif (StringHelper::startsWith('-D', $arg)) {
440
-                // Evaluating the property information //
441
-                // Checking whether arg. is not just a switch, and next arg. does not starts with switch identifier
442
-                if (('-D' == $arg) && (!StringHelper::startsWith('-', $args[$i + 1]))) {
443
-                    $name = $args[++$i];
444
-                } else {
445
-                    $name = substr($arg, 2);
446
-                }
447
-
448
-                $value = null;
449
-                $posEq = strpos($name, '=');
450
-                if (false !== $posEq) {
451
-                    $value = substr($name, $posEq + 1);
452
-                    $name = substr($name, 0, $posEq);
453
-                } elseif ($i < count($args) - 1 && !StringHelper::startsWith('-D', $args[$i + 1])) {
454
-                    $value = $args[++$i];
455
-                }
456
-                self::$definedProps->setProperty($name, $value);
457
-            } elseif ('-logger' == $arg) {
458
-                if (!isset($args[$i + 1])) {
459
-                    $msg = 'You must specify a classname when using the -logger argument';
460
-
461
-                    throw new ConfigurationException($msg);
462
-                }
463
-
464
-                $this->loggerClassname = $args[++$i];
465
-            } elseif ('-no-strict' == $arg) {
466
-                $this->strictMode = false;
467
-            } elseif ('-strict' == $arg) {
468
-                $this->strictMode = true;
469
-            } elseif ('-inputhandler' == $arg) {
470
-                if (null !== $this->inputHandlerClassname) {
471
-                    throw new ConfigurationException('Only one input handler class may be specified.');
472
-                }
473
-                if (!isset($args[$i + 1])) {
474
-                    $msg = 'You must specify a classname when using the -inputhandler argument';
475
-
476
-                    throw new ConfigurationException($msg);
477
-                }
478
-
479
-                $this->inputHandlerClassname = $args[++$i];
480
-            } elseif ('-propertyfile' === $arg) {
481
-                $i = $this->handleArgPropertyFile($args, $i);
482
-            } elseif ('-keep-going' === $arg || '-k' === $arg) {
483
-                $this->keepGoingMode = true;
484
-            } elseif ('-longtargets' == $arg) {
485
-                self::$definedProps->setProperty('phing.showlongtargets', 1);
486
-            } elseif ('-projecthelp' == $arg || '-targets' == $arg || '-list' == $arg || '-l' == $arg || '-p' == $arg) {
487
-                // set the flag to display the targets and quit
488
-                $this->projectHelp = true;
489
-            } elseif ('-find' == $arg) {
490
-                // eat up next arg if present, default to build.xml
491
-                if ($i < count($args) - 1) {
492
-                    $this->searchForThis = $args[++$i];
493
-                } else {
494
-                    $this->searchForThis = self::DEFAULT_BUILD_FILENAME;
495
-                }
496
-            } elseif ('-' == substr($arg, 0, 1)) {
497
-                // we don't have any more args
498
-                self::printUsage();
499
-                self::$err->write(PHP_EOL);
500
-
501
-                throw new ConfigurationException('Unknown argument: ' . $arg);
502
-            } else {
503
-                // if it's no other arg, it may be the target
504
-                $this->targets[] = $arg;
505
-            }
506
-        }
507
-
508
-        // if buildFile was not specified on the command line,
509
-        if (null === $this->buildFile) {
510
-            // but -find then search for it
511
-            if (null !== $this->searchForThis) {
512
-                $this->buildFile = $this->findBuildFile(self::getProperty('user.dir'), $this->searchForThis);
513
-            } else {
514
-                $this->buildFile = new File(self::DEFAULT_BUILD_FILENAME);
515
-            }
516
-        }
517
-
518
-        try {
519
-            // make sure buildfile (or buildfile.dist) exists
520
-            if (!$this->buildFile->exists()) {
521
-                $distFile = new File($this->buildFile->getAbsolutePath() . '.dist');
522
-                if (!$distFile->exists()) {
523
-                    throw new ConfigurationException(
524
-                        'Buildfile: ' . $this->buildFile->__toString() . ' does not exist!'
525
-                    );
526
-                }
527
-                $this->buildFile = $distFile;
528
-            }
529
-
530
-            // make sure it's not a directory
531
-            if ($this->buildFile->isDirectory()) {
532
-                throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is a dir!');
533
-            }
534
-        } catch (IOException $e) {
535
-            // something else happened, buildfile probably not readable
536
-            throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is not readable!');
537
-        }
538
-
539
-        $this->loadPropertyFiles();
540
-
541
-        $this->readyToRun = true;
542
-    }
543
-
544
-    /**
545
-     * Prints the usage of how to use this class.
546
-     */
547
-    public static function printUsage()
548
-    {
549
-        $msg = '';
550
-        $msg .= 'phing [options] [target [target2 [target3] ...]]' . PHP_EOL;
551
-        $msg .= 'Options: ' . PHP_EOL;
552
-        $msg .= '  -h -help               print this message' . PHP_EOL;
553
-        $msg .= '  -l -list               list available targets in this project' . PHP_EOL;
554
-        $msg .= '  -i -init [file]        generates an initial buildfile' . PHP_EOL;
555
-        $msg .= '  -v -version            print the version information and exit' . PHP_EOL;
556
-        $msg .= '  -q -quiet              be extra quiet' . PHP_EOL;
557
-        $msg .= '  -S -silent             print nothing but task outputs and build failures' . PHP_EOL;
558
-        $msg .= '  -verbose               be extra verbose' . PHP_EOL;
559
-        $msg .= '  -debug                 print debugging information' . PHP_EOL;
560
-        $msg .= '  -emacs, -e             produce logging information without adornments' . PHP_EOL;
561
-        $msg .= '  -diagnostics           print diagnostics information' . PHP_EOL;
562
-        $msg .= '  -strict                runs build in strict mode, considering a warning as error' . PHP_EOL;
563
-        $msg .= '  -no-strict             runs build normally (overrides buildfile attribute)' . PHP_EOL;
564
-        $msg .= '  -longtargets           show target descriptions during build' . PHP_EOL;
565
-        $msg .= '  -logfile <file>        use given file for log' . PHP_EOL;
566
-        $msg .= '  -logger <classname>    the class which is to perform logging' . PHP_EOL;
567
-        $msg .= '  -listener <classname>  add an instance of class as a project listener' . PHP_EOL;
568
-        $msg .= '  -f -buildfile <file>   use given buildfile' . PHP_EOL;
569
-        $msg .= '  -D<property>=<value>   use value for given property' . PHP_EOL;
570
-        $msg .= '  -keep-going, -k        execute all targets that do not depend' . PHP_EOL;
571
-        $msg .= '                         on failed target(s)' . PHP_EOL;
572
-        $msg .= '  -propertyfile <file>   load all properties from file' . PHP_EOL;
573
-        $msg .= '  -propertyfileoverride  values in property file override existing values' . PHP_EOL;
574
-        $msg .= '  -find <file>           search for buildfile towards the root of the' . PHP_EOL;
575
-        $msg .= '                         filesystem and use it' . PHP_EOL;
576
-        $msg .= '  -inputhandler <file>   the class to use to handle user input' . PHP_EOL;
577
-        //$msg .= "  -recursive <file>      search for buildfile downwards and use it" . PHP_EOL;
578
-        $msg .= PHP_EOL;
579
-        $msg .= 'Report bugs to https://github.com/phingofficial/phing/issues' . PHP_EOL;
580
-        self::$err->write($msg);
581
-    }
582
-
583
-    /**
584
-     * Prints the current Phing version.
585
-     */
586
-    public static function printVersion()
587
-    {
588
-        self::$out->write(self::getPhingVersion() . PHP_EOL);
589
-    }
590
-
591
-    /**
592
-     * Gets the current Phing version based on VERSION.TXT file.
593
-     *
594
-     * @throws ConfigurationException
595
-     */
596
-    public static function getPhingVersion(): string
597
-    {
598
-        $versionPath = self::getResourcePath('phing/etc/VERSION.TXT');
599
-        if (null === $versionPath) {
600
-            $versionPath = self::getResourcePath('etc/VERSION.TXT');
601
-        }
602
-        if (null === $versionPath) {
603
-            throw new ConfigurationException('No VERSION.TXT file found; try setting phing.home environment variable.');
604
-        }
605
-
606
-        try { // try to read file
607
-            $file = new File($versionPath);
608
-            $reader = new FileReader($file);
609
-            $phingVersion = trim($reader->read());
610
-        } catch (IOException $iox) {
611
-            throw new ConfigurationException("Can't read version information file");
612
-        }
613
-
614
-        $basePath = dirname(__DIR__, 2);
615
-
616
-        $version = new Version($phingVersion, $basePath);
617
-
618
-        return 'Phing ' . $version->getVersion();
619
-    }
620
-
621
-    /**
622
-     * Looks on include path for specified file.
623
-     *
624
-     * @param string $path
625
-     *
626
-     * @return null|string file found (null if no file found)
627
-     */
628
-    public static function getResourcePath($path): ?string
629
-    {
630
-        if (null === self::$importPaths) {
631
-            self::$importPaths = self::explodeIncludePath();
632
-        }
633
-
634
-        $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);
635
-
636
-        foreach (self::$importPaths as $prefix) {
637
-            $testPath = $prefix . DIRECTORY_SEPARATOR . $path;
638
-            if (file_exists($testPath)) {
639
-                return $testPath;
640
-            }
641
-        }
642
-
643
-        // Check for the property phing.home
644
-        $homeDir = self::getProperty(self::PHING_HOME);
645
-        if ($homeDir) {
646
-            $testPath = $homeDir . DIRECTORY_SEPARATOR . $path;
647
-            if (file_exists($testPath)) {
648
-                return $testPath;
649
-            }
650
-        }
651
-
652
-        // Check for the phing home of phar archive
653
-        if (0 === strpos(self::$importPaths[0], 'phar://')) {
654
-            $testPath = self::$importPaths[0] . '/../' . $path;
655
-            if (file_exists($testPath)) {
656
-                return $testPath;
657
-            }
658
-        }
659
-
660
-        // Do one additional check based on path of current file (Phing.php)
661
-        $maybeHomeDir = realpath(__DIR__ . DIRECTORY_SEPARATOR);
662
-        $testPath = $maybeHomeDir . DIRECTORY_SEPARATOR . $path;
663
-        if (file_exists($testPath)) {
664
-            return $testPath;
665
-        }
666
-
667
-        return null;
668
-    }
669
-
670
-    /**
671
-     * Explode an include path into an array.
672
-     *
673
-     * If no path provided, uses current include_path. Works around issues that
674
-     * occur when the path includes stream schemas.
675
-     *
676
-     * Pulled from Zend_Loader::explodeIncludePath() in ZF1.
677
-     *
678
-     * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
679
-     * @license   http://framework.zend.com/license/new-bsd New BSD License
680
-     *
681
-     * @param null|string $path
682
-     *
683
-     * @return array
684
-     */
685
-    public static function explodeIncludePath($path = null)
686
-    {
687
-        if (null === $path) {
688
-            $path = get_include_path();
689
-        }
690
-
691
-        if (PATH_SEPARATOR === ':') {
692
-            // On *nix systems, include_paths which include paths with a stream
693
-            // schema cannot be safely explode'd, so we have to be a bit more
694
-            // intelligent in the approach.
695
-            $paths = preg_split('#:(?!//)#', $path);
696
-        } else {
697
-            $paths = explode(PATH_SEPARATOR, $path);
698
-        }
699
-
700
-        return $paths;
701
-    }
702
-
703
-    /**
704
-     * Returns property value for a System property.
705
-     * System properties are "global" properties like application.startdir,
706
-     * and user.dir.  Many of these correspond to similar properties in Java
707
-     * or Ant.
708
-     *
709
-     * @param string $propName
710
-     *
711
-     * @return string value of found property (or null, if none found)
712
-     */
713
-    public static function getProperty($propName)
714
-    {
715
-        // some properties are detemined on each access
716
-        // some are cached, see below
717
-
718
-        // default is the cached value:
719
-        $val = self::$properties[$propName] ?? null;
720
-
721
-        // special exceptions
722
-        switch ($propName) {
723
-            case 'user.dir':
724
-                $val = getcwd();
725
-
726
-                break;
727
-        }
728
-
729
-        return $val;
730
-    }
731
-
732
-    /**
733
-     * Creates generic buildfile.
734
-     *
735
-     * @param string $path
736
-     */
737
-    public static function init($path)
738
-    {
739
-        if ($buildfilePath = self::initPath($path)) {
740
-            self::initWrite($buildfilePath);
741
-        }
742
-    }
743
-
744
-    /**
745
-     * Sets the stream to use for standard (non-error) output.
746
-     *
747
-     * @param OutputStream $stream the stream to use for standard output
748
-     */
749
-    public static function setOutputStream(OutputStream $stream)
750
-    {
751
-        self::$out = $stream;
752
-    }
753
-
754
-    /**
755
-     * Sets the stream to use for error output.
756
-     *
757
-     * @param OutputStream $stream the stream to use for error output
758
-     */
759
-    public static function setErrorStream(OutputStream $stream): void
760
-    {
761
-        self::$err = $stream;
762
-    }
763
-
764
-    /**
765
-     * Making output level a static property so that this property
766
-     * can be accessed by other parts of the system, enabling
767
-     * us to display more information -- e.g. backtraces -- for "debug" level.
768
-     *
769
-     * @return int
770
-     */
771
-    public static function getMsgOutputLevel()
772
-    {
773
-        return self::$msgOutputLevel;
774
-    }
775
-
776
-    /**
777
-     * Prints the message of the Exception if it's not null.
778
-     */
779
-    public static function printMessage(Throwable $t): void
780
-    {
781
-        if (null === self::$err) { // Make sure our error output is initialized
782
-            self::initializeOutputStreams();
783
-        }
784
-        if (self::getMsgOutputLevel() >= Project::MSG_VERBOSE) {
785
-            self::$err->write((string) $t . PHP_EOL);
786
-        } else {
787
-            self::$err->write($t->getMessage() . PHP_EOL);
788
-        }
789
-    }
790
-
791
-    /**
792
-     * Performs any shutdown routines, such as stopping timers.
793
-     *
794
-     * @throws IOException
795
-     */
796
-    public static function shutdown(): void
797
-    {
798
-        FileSystem::getFileSystem()::deleteFilesOnExit();
799
-        self::$msgOutputLevel = Project::MSG_INFO;
800
-        self::restoreIni();
801
-        self::getTimer()->stop();
802
-    }
803
-
804
-    /**
805
-     * Returns reference to DefaultClock object.
806
-     */
807
-    public static function getTimer(): DefaultClock
808
-    {
809
-        if (null === self::$timer) {
810
-            self::$timer = new DefaultClock();
811
-        }
812
-
813
-        return self::$timer;
814
-    }
815
-
816
-    /**
817
-     * This sets a property that was set via command line or otherwise passed into Phing.
818
-     *
819
-     * @param string $name
820
-     * @param mixed  $value
821
-     *
822
-     * @return mixed value of found property (or null, if none found)
823
-     */
824
-    public static function setDefinedProperty($name, $value)
825
-    {
826
-        return self::$definedProps->setProperty($name, $value);
827
-    }
828
-
829
-    /**
830
-     * Executes the build.
831
-     *
832
-     * @throws IOException
833
-     * @throws Throwable
834
-     */
835
-    public function runBuild(): void
836
-    {
837
-        if (!$this->readyToRun) {
838
-            return;
839
-        }
840
-
841
-        $project = new Project();
842
-
843
-        self::setCurrentProject($project);
844
-        set_error_handler(['Phing\Phing', 'handlePhpError']);
845
-
846
-        $error = null;
847
-
848
-        try {
849
-            $this->addBuildListeners($project);
850
-            $this->addInputHandler($project);
851
-
852
-            // set this right away, so that it can be used in logging.
853
-            $project->setUserProperty('phing.file', $this->buildFile->getAbsolutePath());
854
-            $project->setUserProperty('phing.dir', dirname($this->buildFile->getAbsolutePath()));
855
-            $project->setUserProperty('phing.version', static::getPhingVersion());
856
-            $project->fireBuildStarted();
857
-            $project->init();
858
-            $project->setKeepGoingMode($this->keepGoingMode);
859
-
860
-            $e = self::$definedProps->keys();
861
-            while (count($e)) {
862
-                $arg = (string) array_shift($e);
863
-                $value = (string) self::$definedProps->getProperty($arg);
864
-                $project->setUserProperty($arg, $value);
865
-            }
866
-            unset($e);
867
-
868
-            // first use the Configurator to create the project object
869
-            // from the given build file.
870
-
871
-            ProjectConfigurator::configureProject($project, $this->buildFile);
872
-
873
-            // Set the project mode
874
-            $project->setStrictMode(StringHelper::booleanValue($this->strictMode));
875
-
876
-            // make sure that minimum required phing version is satisfied
877
-            $this->comparePhingVersion($project->getPhingVersion());
878
-
879
-            if ($this->projectHelp) {
880
-                $this->printDescription($project);
881
-                $this->printTargets($project);
882
-
883
-                return;
884
-            }
885
-
886
-            // make sure that we have a target to execute
887
-            if (0 === count($this->targets)) {
888
-                $this->targets[] = $project->getDefaultTarget();
889
-            }
890
-
891
-            $project->executeTargets($this->targets);
892
-        } catch (Throwable $t) {
893
-            $error = $t;
894
-
895
-            throw $t;
896
-        } finally {
897
-            if (!$this->projectHelp) {
898
-                try {
899
-                    $project->fireBuildFinished($error);
900
-                } catch (Exception $e) {
901
-                    self::$err->write('Caught an exception while logging the end of the build.  Exception was:' . PHP_EOL);
902
-                    self::$err->write($e->getTraceAsString());
903
-                    if (null !== $error) {
904
-                        self::$err->write('There has been an error prior to that:' . PHP_EOL);
905
-                        self::$err->write($error->getTraceAsString());
906
-                    }
907
-
908
-                    throw new BuildException($error);
909
-                }
910
-            } elseif (null !== $error) {
911
-                $project->log($error->getMessage(), Project::MSG_ERR);
912
-            }
913
-
914
-            restore_error_handler();
915
-            self::unsetCurrentProject();
916
-        }
917
-    }
918
-
919
-    /**
920
-     * Import a class, supporting the following conventions:
921
-     * - PEAR style (@see http://pear.php.net/manual/en/standards.naming.php)
922
-     * - PSR-0 (@see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
923
-     *
924
-     * @param string $classname Name of class
925
-     * @param mixed  $classpath String or object supporting __toString()
926
-     *
927
-     * @throws BuildException - if cannot find the specified file
928
-     *
929
-     * @return string the unqualified classname (which can be instantiated)
930
-     */
931
-    public static function import($classname, $classpath = null)
932
-    {
933
-        // first check to see that the class specified hasn't already been included.
934
-        if (class_exists($classname)) {
935
-            return $classname;
936
-        }
937
-
938
-        $filename = strtr($classname, ['_' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR]) . '.php';
939
-
940
-        Phing::importFile($filename, $classpath);
941
-
942
-        return $classname;
943
-    }
944
-
945
-    /**
946
-     * Import a PHP file.
947
-     *
948
-     * This used to be named __import, however PHP has reserved all method names
949
-     * with a double underscore prefix for future use.
950
-     *
951
-     * @param string $path      Path to the PHP file
952
-     * @param mixed  $classpath String or object supporting __toString()
953
-     *
954
-     * @throws ConfigurationException
955
-     */
956
-    public static function importFile($path, $classpath = null)
957
-    {
958
-        if ($classpath) {
959
-            // Apparently casting to (string) no longer invokes __toString() automatically.
960
-            if (is_object($classpath)) {
961
-                $classpath = $classpath->__toString();
962
-            }
963
-
964
-            // classpaths are currently additive, but we also don't want to just
965
-            // indiscriminantly prepand/append stuff to the include_path.  This means
966
-            // we need to parse current incldue_path, and prepend any
967
-            // specified classpath locations that are not already in the include_path.
968
-            //
969
-            // NOTE:  the reason why we do it this way instead of just changing include_path
970
-            // and then changing it back, is that in many cases applications (e.g. Propel) will
971
-            // include/require class files from within method calls.  This means that not all
972
-            // necessary files will be included in this import() call, and hence we can't
973
-            // change the include_path back without breaking those apps.  While this method could
974
-            // be more expensive than switching & switching back (not sure, but maybe), it makes it
975
-            // possible to write far less expensive run-time applications (e.g. using Propel), which is
976
-            // really where speed matters more.
977
-
978
-            $curr_parts = Phing::explodeIncludePath();
979
-            $add_parts = Phing::explodeIncludePath($classpath);
980
-            $new_parts = array_diff($add_parts, $curr_parts);
981
-            if ($new_parts) {
982
-                set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
983
-            }
984
-        }
985
-
986
-        $ret = include_once $path;
987
-
988
-        if (false === $ret) {
989
-            $msg = "Error importing {$path}";
990
-            if (self::getMsgOutputLevel() >= Project::MSG_DEBUG) {
991
-                $x = new Exception('for-path-trace-only');
992
-                $msg .= $x->getTraceAsString();
993
-            }
994
-
995
-            throw new ConfigurationException($msg);
996
-        }
997
-    }
998
-
999
-    /**
1000
-     * Print the project description, if any.
1001
-     *
1002
-     * @throws IOException
1003
-     */
1004
-    public function printDescription(Project $project): void
1005
-    {
1006
-        if (null !== $project->getDescription()) {
1007
-            $project->log($project->getDescription());
1008
-        }
1009
-    }
1010
-
1011
-    /**
1012
-     * Print out a list of all targets in the current buildfile.
1013
-     */
1014
-    public function printTargets(Project $project)
1015
-    {
1016
-        $visibleTargets = array_filter($project->getTargets(), function (Target $target) {
1017
-            return !$target->isHidden() && !empty($target->getName());
1018
-        });
1019
-        $padding = array_reduce($visibleTargets, function (int $carry, Target $target) {
1020
-            return max(strlen($target->getName()), $carry);
1021
-        }, 0);
1022
-        $categories = [
1023
-            'Default target:' => array_filter($visibleTargets, function (Target $target) use ($project) {
1024
-                return trim(strval($target)) === $project->getDefaultTarget();
1025
-            }),
1026
-            'Main targets:' => array_filter($visibleTargets, function (Target $target) {
1027
-                return !empty($target->getDescription());
1028
-            }),
1029
-            'Subtargets:' => array_filter($visibleTargets, function (Target $target) {
1030
-                return empty($target->getDescription());
1031
-            }),
1032
-        ];
1033
-        foreach ($categories as $title => $targets) {
1034
-            $targetList = $this->generateTargetList($title, $targets, $padding);
1035
-            $project->log($targetList, Project::MSG_WARN);
1036
-        }
1037
-    }
1038
-
1039
-    /**
1040
-     * Unsets the current Project.
1041
-     */
1042
-    public static function unsetCurrentProject(): void
1043
-    {
1044
-        self::$currentProject = null;
1045
-    }
1046
-
1047
-    /**
1048
-     * Error handler for PHP errors encountered during the build.
1049
-     * This uses the logging for the currently configured project.
1050
-     *
1051
-     * @param $level
1052
-     * @param string $message
1053
-     * @param $file
1054
-     * @param $line
1055
-     */
1056
-    public static function handlePhpError($level, $message, $file, $line)
1057
-    {
1058
-        // don't want to print suppressed errors
1059
-        if (error_reporting() > 0) {
1060
-            if (self::$phpErrorCapture) {
1061
-                self::$capturedPhpErrors[] = [
1062
-                    'message' => $message,
1063
-                    'level' => $level,
1064
-                    'line' => $line,
1065
-                    'file' => $file,
1066
-                ];
1067
-            } else {
1068
-                $message = '[PHP Error] ' . $message;
1069
-                $message .= ' [line ' . $line . ' of ' . $file . ']';
1070
-
1071
-                switch ($level) {
1072
-                    case E_USER_DEPRECATED:
1073
-                    case E_DEPRECATED:
1074
-                    case E_STRICT:
1075
-                    case E_NOTICE:
1076
-                    case E_USER_NOTICE:
1077
-                        self::log($message, Project::MSG_VERBOSE);
1078
-
1079
-                        break;
1080
-
1081
-                    case E_WARNING:
1082
-                    case E_USER_WARNING:
1083
-                        self::log($message, Project::MSG_WARN);
1084
-
1085
-                        break;
1086
-
1087
-                    case E_ERROR:
1088
-                    case E_USER_ERROR:
1089
-                    default:
1090
-                        self::log($message, Project::MSG_ERR);
1091
-                } // switch
1092
-            } // if phpErrorCapture
1093
-        } // if not @
1094
-    }
1095
-
1096
-    /**
1097
-     * A static convenience method to send a log to the current (last-setup) Project.
1098
-     * If there is no currently-configured Project, then this will do nothing.
1099
-     *
1100
-     * @param string $message
1101
-     * @param int    $priority project::MSG_INFO, etc
1102
-     */
1103
-    public static function log($message, $priority = Project::MSG_INFO): void
1104
-    {
1105
-        $p = self::getCurrentProject();
1106
-        if ($p) {
1107
-            $p->log($message, $priority);
1108
-        }
1109
-    }
1110
-
1111
-    /**
1112
-     * Gets the current Project.
1113
-     *
1114
-     * @return Project current Project or NULL if none is set yet/still
1115
-     */
1116
-    public static function getCurrentProject()
1117
-    {
1118
-        return self::$currentProject;
1119
-    }
1120
-
1121
-    /**
1122
-     * Sets the current Project.
1123
-     *
1124
-     * @param Project $p
1125
-     */
1126
-    public static function setCurrentProject($p): void
1127
-    {
1128
-        self::$currentProject = $p;
1129
-    }
1130
-
1131
-    /**
1132
-     * Begins capturing PHP errors to a buffer.
1133
-     * While errors are being captured, they are not logged.
1134
-     */
1135
-    public static function startPhpErrorCapture(): void
1136
-    {
1137
-        self::$phpErrorCapture = true;
1138
-        self::$capturedPhpErrors = [];
1139
-    }
1140
-
1141
-    /**
1142
-     * Stops capturing PHP errors to a buffer.
1143
-     * The errors will once again be logged after calling this method.
1144
-     */
1145
-    public static function stopPhpErrorCapture(): void
1146
-    {
1147
-        self::$phpErrorCapture = false;
1148
-    }
1149
-
1150
-    /**
1151
-     * Clears the captured errors without affecting the starting/stopping of the capture.
1152
-     */
1153
-    public static function clearCapturedPhpErrors(): void
1154
-    {
1155
-        self::$capturedPhpErrors = [];
1156
-    }
1157
-
1158
-    /**
1159
-     * Gets any PHP errors that were captured to buffer.
1160
-     *
1161
-     * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level)
1162
-     */
1163
-    public static function getCapturedPhpErrors()
1164
-    {
1165
-        return self::$capturedPhpErrors;
1166
-    }
1167
-
1168
-    /**
1169
-     * This gets a property that was set via command line or otherwise passed into Phing.
1170
-     * "Defined" in this case means "externally defined".  The reason this method exists is to
1171
-     * provide a public means of accessing commandline properties for (e.g.) logger or listener
1172
-     * scripts.  E.g. to specify which logfile to use, PearLogger needs to be able to access
1173
-     * the pear.log.name property.
1174
-     *
1175
-     * @param string $name
1176
-     *
1177
-     * @return string value of found property (or null, if none found)
1178
-     */
1179
-    public static function getDefinedProperty($name)
1180
-    {
1181
-        return self::$definedProps->getProperty($name);
1182
-    }
1183
-
1184
-    /**
1185
-     * Retuns reference to all properties.
1186
-     */
1187
-    public static function &getProperties()
1188
-    {
1189
-        return self::$properties;
1190
-    }
1191
-
1192
-    /**
1193
-     * Start up Phing.
1194
-     * Sets up the Phing environment but does not initiate the build process.
1195
-     *
1196
-     * @throws exception - If the Phing environment cannot be initialized
1197
-     */
1198
-    public static function startup(): void
1199
-    {
1200
-        // setup STDOUT and STDERR defaults
1201
-        self::initializeOutputStreams();
1202
-
1203
-        // some init stuff
1204
-        self::getTimer()->start();
1205
-
1206
-        self::setSystemConstants();
1207
-        self::setIncludePaths();
1208
-        self::setIni();
1209
-    }
1210
-
1211
-    /**
1212
-     * @param $propName
1213
-     * @param $propValue
1214
-     *
1215
-     * @return string
1216
-     */
1217
-    public static function setProperty($propName, $propValue)
1218
-    {
1219
-        $propName = (string) $propName;
1220
-        $oldValue = self::getProperty($propName);
1221
-        self::$properties[$propName] = $propValue;
1222
-
1223
-        return $oldValue;
1224
-    }
1225
-
1226
-    /**
1227
-     * Returns buildfile's path.
1228
-     *
1229
-     * @param $path
1230
-     *
1231
-     * @throws ConfigurationException
1232
-     *
1233
-     * @return string
1234
-     */
1235
-    protected static function initPath($path)
1236
-    {
1237
-        // Fallback
1238
-        if (empty($path)) {
1239
-            $defaultDir = self::getProperty('application.startdir');
1240
-            $path = $defaultDir . DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1241
-        }
1242
-
1243
-        // Adding filename if necessary
1244
-        if (is_dir($path)) {
1245
-            $path .= DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1246
-        }
1247
-
1248
-        // Check if path is available
1249
-        $dirname = dirname($path);
1250
-        if (is_dir($dirname) && !is_file($path)) {
1251
-            return $path;
1252
-        }
1253
-
1254
-        // Path is valid, but buildfile already exists
1255
-        if (is_file($path)) {
1256
-            throw new ConfigurationException('Buildfile already exists.');
1257
-        }
1258
-
1259
-        throw new ConfigurationException('Invalid path for sample buildfile.');
1260
-    }
1261
-
1262
-    /**
1263
-     * Writes sample buildfile.
1264
-     *
1265
-     * If $buildfilePath does not exist, the buildfile is created.
1266
-     *
1267
-     * @param $buildfilePath buildfile's location
1268
-     *
1269
-     * @throws ConfigurationException
1270
-     */
1271
-    protected static function initWrite($buildfilePath): void
1272
-    {
1273
-        // Overwriting protection
1274
-        if (file_exists($buildfilePath)) {
1275
-            throw new ConfigurationException('Cannot overwrite existing file.');
1276
-        }
1277
-
1278
-        file_put_contents($buildfilePath, self::DEFAULT_BUILD_CONTENT);
1279
-    }
1280
-
1281
-    /**
1282
-     * This operation is expected to call `exit($int)`, which
1283
-     * is what the base version does.
1284
-     * However, it is possible to do something else.
1285
-     *
1286
-     * @param int $exitCode code to exit with
1287
-     */
1288
-    protected static function statusExit($exitCode): void
1289
-    {
1290
-        Phing::shutdown();
1291
-
1292
-        exit($exitCode);
1293
-    }
1294
-
1295
-    /**
1296
-     * Handle the -propertyfile argument.
1297
-     *
1298
-     * @throws ConfigurationException
1299
-     * @throws IOException
1300
-     */
1301
-    private function handleArgPropertyFile(array $args, int $pos): int
1302
-    {
1303
-        if (!isset($args[$pos + 1])) {
1304
-            throw new ConfigurationException('You must specify a filename when using the -propertyfile argument');
1305
-        }
1306
-
1307
-        $this->propertyFiles[] = $args[++$pos];
1308
-
1309
-        return $pos;
1310
-    }
1311
-
1312
-    /**
1313
-     * Search parent directories for the build file.
1314
-     *
1315
-     * Takes the given target as a suffix to append to each
1316
-     * parent directory in search of a build file.  Once the
1317
-     * root of the file-system has been reached an exception
1318
-     * is thrown.
1319
-     *
1320
-     * @param string $start  start file path
1321
-     * @param string $suffix suffix filename to look for in parents
1322
-     *
1323
-     * @throws ConfigurationException
1324
-     *
1325
-     * @return File A handle to the build file
1326
-     */
1327
-    private function findBuildFile($start, $suffix)
1328
-    {
1329
-        if (self::getMsgOutputLevel() >= Project::MSG_INFO) {
1330
-            self::$out->write('Searching for ' . $suffix . ' ...' . PHP_EOL);
1331
-        }
1332
-
1333
-        $parent = new File((new File($start))->getAbsolutePath());
1334
-        $file = new File($parent, $suffix);
1335
-
1336
-        // check if the target file exists in the current directory
1337
-        while (!$file->exists()) {
1338
-            // change to parent directory
1339
-            $parent = $parent->getParentFile();
1340
-
1341
-            // if parent is null, then we are at the root of the fs,
1342
-            // complain that we can't find the build file.
1343
-            if (null === $parent) {
1344
-                throw new ConfigurationException('Could not locate a build file!');
1345
-            }
1346
-            // refresh our file handle
1347
-            $file = new File($parent, $suffix);
1348
-        }
1349
-
1350
-        return $file;
1351
-    }
1352
-
1353
-    /**
1354
-     * @throws IOException
1355
-     */
1356
-    private function loadPropertyFiles(): void
1357
-    {
1358
-        foreach ($this->propertyFiles as $filename) {
1359
-            $fileParserFactory = new FileParserFactory();
1360
-            $fileParser = $fileParserFactory->createParser(pathinfo($filename, PATHINFO_EXTENSION));
1361
-            $p = new Properties(null, $fileParser);
1362
-
1363
-            try {
1364
-                $p->load(new File($filename));
1365
-            } catch (IOException $e) {
1366
-                self::$out->write('Could not load property file ' . $filename . ': ' . $e->getMessage());
1367
-            }
1368
-            foreach ($p->getProperties() as $prop => $value) {
1369
-                self::$definedProps->setProperty($prop, $value);
1370
-            }
1371
-        }
1372
-    }
1373
-
1374
-    /**
1375
-     * Close logfiles, if we have been writing to them.
1376
-     *
1377
-     * @since Phing 2.3.0
1378
-     */
1379
-    private static function handleLogfile(): void
1380
-    {
1381
-        if (self::$isLogFileUsed) {
1382
-            self::$err->close();
1383
-            self::$out->close();
1384
-        }
1385
-    }
1386
-
1387
-    /**
1388
-     * Sets the stdout and stderr streams if they are not already set.
1389
-     */
1390
-    private static function initializeOutputStreams()
1391
-    {
1392
-        if (null === self::$out) {
1393
-            if (!defined('STDOUT')) {
1394
-                self::$out = new OutputStream(fopen('php://stdout', 'w'));
1395
-            } else {
1396
-                self::$out = new OutputStream(STDOUT);
1397
-            }
1398
-        }
1399
-        if (null === self::$err) {
1400
-            if (!defined('STDERR')) {
1401
-                self::$err = new OutputStream(fopen('php://stderr', 'w'));
1402
-            } else {
1403
-                self::$err = new OutputStream(STDERR);
1404
-            }
1405
-        }
1406
-    }
1407
-
1408
-    /**
1409
-     * Restores [most] PHP INI values to their pre-Phing state.
1410
-     *
1411
-     * Currently the following settings are not restored:
1412
-     *  - max_execution_time (because getting current time limit is not possible)
1413
-     *  - memory_limit (which may have been increased by Phing)
1414
-     */
1415
-    private static function restoreIni(): void
1416
-    {
1417
-        foreach (self::$origIniSettings as $settingName => $settingValue) {
1418
-            switch ($settingName) {
1419
-                case 'error_reporting':
1420
-                    error_reporting($settingValue);
1421
-
1422
-                    break;
1423
-
1424
-                default:
1425
-                    ini_set($settingName, $settingValue);
1426
-            }
1427
-        }
1428
-    }
1429
-
1430
-    /**
1431
-     * Bind any registered build listeners to this project.
1432
-     *
1433
-     * This means adding the logger and any build listeners that were specified
1434
-     * with -listener arg.
1435
-     *
1436
-     * @throws BuildException
1437
-     * @throws ConfigurationException
1438
-     */
1439
-    private function addBuildListeners(Project $project)
1440
-    {
1441
-        // Add the default listener
1442
-        $project->addBuildListener($this->createLogger());
1443
-
1444
-        foreach ($this->listeners as $listenerClassname) {
1445
-            try {
1446
-                $clz = Phing::import($listenerClassname);
1447
-            } catch (Exception $e) {
1448
-                $msg = 'Unable to instantiate specified listener '
1449
-                    . 'class ' . $listenerClassname . ' : '
1450
-                    . $e->getMessage();
1451
-
1452
-                throw new ConfigurationException($msg);
1453
-            }
1454
-
1455
-            $listener = new $clz();
1456
-
1457
-            if ($listener instanceof StreamRequiredBuildLogger) {
1458
-                throw new ConfigurationException('Unable to add ' . $listenerClassname . ' as a listener, since it requires explicit error/output streams. (You can specify it as a -logger.)');
1459
-            }
1460
-            $project->addBuildListener($listener);
1461
-        }
1462
-    }
1463
-
1464
-    /**
1465
-     * Creates the default build logger for sending build events to the log.
1466
-     *
1467
-     * @throws BuildException
1468
-     *
1469
-     * @return BuildLogger The created Logger
1470
-     */
1471
-    private function createLogger()
1472
-    {
1473
-        if ($this->silent) {
1474
-            $logger = new SilentLogger();
1475
-            self::$msgOutputLevel = Project::MSG_WARN;
1476
-        } elseif (null !== $this->loggerClassname) {
1477
-            self::import($this->loggerClassname);
1478
-            // get class name part
1479
-            $classname = self::import($this->loggerClassname);
1480
-            $logger = new $classname();
1481
-            if (!($logger instanceof BuildLogger)) {
1482
-                throw new BuildException($classname . ' does not implement the BuildLogger interface.');
1483
-            }
1484
-        } else {
1485
-            $logger = new DefaultLogger();
1486
-        }
1487
-        $logger->setMessageOutputLevel(self::$msgOutputLevel);
1488
-        $logger->setOutputStream(self::$out);
1489
-        $logger->setErrorStream(self::$err);
1490
-        $logger->setEmacsMode($this->emacsMode);
1491
-
1492
-        return $logger;
1493
-    }
1494
-
1495
-    /**
1496
-     * Creates the InputHandler and adds it to the project.
1497
-     *
1498
-     * @param Project $project the project instance
1499
-     *
1500
-     * @throws ConfigurationException
1501
-     */
1502
-    private function addInputHandler(Project $project): void
1503
-    {
1504
-        if (null === $this->inputHandlerClassname) {
1505
-            $handler = new ConsoleInputHandler(STDIN, new ConsoleOutput());
1506
-        } else {
1507
-            try {
1508
-                $clz = Phing::import($this->inputHandlerClassname);
1509
-                $handler = new $clz();
1510
-                if (null !== $project && method_exists($handler, 'setProject')) {
1511
-                    $handler->setProject($project);
1512
-                }
1513
-            } catch (Exception $e) {
1514
-                $msg = 'Unable to instantiate specified input handler '
1515
-                    . 'class ' . $this->inputHandlerClassname . ' : '
1516
-                    . $e->getMessage();
1517
-
1518
-                throw new ConfigurationException($msg);
1519
-            }
1520
-        }
1521
-        $project->setInputHandler($handler);
1522
-    }
1523
-
1524
-    /**
1525
-     * @param string $version
1526
-     *
1527
-     * @throws BuildException
1528
-     * @throws ConfigurationException
1529
-     */
1530
-    private function comparePhingVersion($version): void
1531
-    {
1532
-        $current = strtolower(self::getPhingVersion());
1533
-        $current = trim(str_replace('phing', '', $current));
1534
-
1535
-        // make sure that version checks are not applied to trunk
1536
-        if ('dev' === $current) {
1537
-            return;
1538
-        }
1539
-
1540
-        if (-1 == version_compare($current, $version)) {
1541
-            throw new BuildException(
1542
-                sprintf('Incompatible Phing version (%s). Version "%s" required.', $current, $version)
1543
-            );
1544
-        }
1545
-    }
1546
-
1547
-    /**
1548
-     * Returns a formatted list of target names with an optional description.
1549
-     *
1550
-     * @param string   $title   Title for this list
1551
-     * @param Target[] $targets Targets in this list
1552
-     * @param int      $padding Padding for name column
1553
-     */
1554
-    private function generateTargetList(string $title, array $targets, int $padding): string
1555
-    {
1556
-        usort($targets, function (Target $a, Target $b) {
1557
-            return $a->getName() <=> $b->getName();
1558
-        });
1559
-
1560
-        $header = <<<HEADER
1561
-            {$title}
1562
-            -------------------------------------------------------------------------------
1563
-
1564
-            HEADER;
1565
-
1566
-        $getDetails = function (Target $target) use ($padding): string {
1567
-            $details = [];
1568
-            if (!empty($target->getDescription())) {
1569
-                $details[] = $target->getDescription();
1570
-            }
1571
-            if (!empty($target->getDependencies())) {
1572
-                $details[] = ' - depends on: ' . implode(', ', $target->getDependencies());
1573
-            }
1574
-            if (!empty($target->getIf())) {
1575
-                $details[] = ' - if property: ' . $target->getIf();
1576
-            }
1577
-            if (!empty($target->getUnless())) {
1578
-                $details[] = ' - unless property: ' . $target->getUnless();
1579
-            }
1580
-            $detailsToString = function (?string $name, ?string $detail) use ($padding): string {
1581
-                return sprintf(" %-{$padding}s  %s", $name, $detail);
1582
-            };
1583
-
1584
-            return implode(PHP_EOL, array_map($detailsToString, [$target->getName()], $details));
1585
-        };
1586
-
1587
-        return $header . implode(PHP_EOL, array_map($getDetails, $targets)) . PHP_EOL;
1588
-    }
1589
-
1590
-    /**
1591
-     * Set System constants which can be retrieved by calling Phing::getProperty($propName).
1592
-     */
1593
-    private static function setSystemConstants(): void
1594
-    {
1595
-        /*
1596
-         * PHP_OS returns on
1597
-         *   WindowsNT4.0sp6  => WINNT
1598
-         *   Windows2000      => WINNT
1599
-         *   Windows ME       => WIN32
1600
-         *   Windows 98SE     => WIN32
1601
-         *   FreeBSD 4.5p7    => FreeBSD
1602
-         *   Redhat Linux     => Linux
1603
-         *   Mac OS X         => Darwin
1604
-         */
1605
-        self::setProperty('host.os', PHP_OS);
1606
-
1607
-        // this is used by some tasks too
1608
-        self::setProperty('os.name', PHP_OS);
1609
-
1610
-        // it's still possible this won't be defined,
1611
-        // e.g. if Phing is being included in another app w/o
1612
-        // using the phing.php script.
1613
-        if (!defined('PHP_CLASSPATH')) {
1614
-            define('PHP_CLASSPATH', get_include_path());
1615
-        }
1616
-
1617
-        self::setProperty('php.classpath', PHP_CLASSPATH);
1618
-
1619
-        // try to determine the host filesystem and set system property
1620
-        // used by Fileself::getFileSystem to instantiate the correct
1621
-        // abstraction layer
1622
-
1623
-        if (PHP_OS_FAMILY === 'Windows') {
1624
-            self::setProperty('host.fstype', 'WINDOWS');
1625
-            self::setProperty('user.home', getenv('HOMEDRIVE') . getenv('HOMEPATH'));
1626
-        } else {
1627
-            self::setProperty('host.fstype', 'UNIX');
1628
-            self::setProperty('user.home', getenv('HOME'));
1629
-        }
1630
-        self::setProperty(self::PHP_INTERPRETER, PHP_BINARY);
1631
-        self::setProperty('file.separator', FileUtils::getSeparator());
1632
-        self::setProperty('line.separator', PHP_EOL);
1633
-        self::setProperty('path.separator', FileUtils::getPathSeparator());
1634
-        self::setProperty(self::PHP_VERSION, PHP_VERSION);
1635
-        self::setProperty('php.tmpdir', sys_get_temp_dir());
1636
-        self::setProperty('application.startdir', getcwd());
1637
-        self::setProperty('phing.startTime', gmdate('D, d M Y H:i:s', time()) . ' GMT');
1638
-
1639
-        // try to detect machine dependent information
1640
-        $sysInfo = [];
1641
-        if (function_exists('posix_uname') && 0 !== stripos(PHP_OS, 'WIN')) {
1642
-            $sysInfo = posix_uname();
1643
-        } else {
1644
-            $sysInfo['nodename'] = php_uname('n');
1645
-            $sysInfo['machine'] = php_uname('m');
1646
-            //this is a not so ideal substition, but maybe better than nothing
1647
-            $sysInfo['domain'] = $_SERVER['SERVER_NAME'] ?? 'unknown';
1648
-            $sysInfo['release'] = php_uname('r');
1649
-            $sysInfo['version'] = php_uname('v');
1650
-        }
1651
-
1652
-        self::setProperty('host.name', $sysInfo['nodename'] ?? 'unknown');
1653
-        self::setProperty('host.arch', $sysInfo['machine'] ?? 'unknown');
1654
-        self::setProperty('host.domain', $sysInfo['domain'] ?? 'unknown');
1655
-        self::setProperty('host.os.release', $sysInfo['release'] ?? 'unknown');
1656
-        self::setProperty('host.os.version', $sysInfo['version'] ?? 'unknown');
1657
-        unset($sysInfo);
1658
-    }
1659
-
1660
-    /**
1661
-     * Sets the include path to PHP_CLASSPATH constant (if this has been defined).
1662
-     *
1663
-     * @throws ConfigurationException - if the include_path could not be set (for some bizarre reason)
1664
-     */
1665
-    private static function setIncludePaths(): void
1666
-    {
1667
-        if (defined('PHP_CLASSPATH')) {
1668
-            $result = set_include_path(PHP_CLASSPATH);
1669
-            if (false === $result) {
1670
-                throw new ConfigurationException('Could not set PHP include_path.');
1671
-            }
1672
-            self::$origIniSettings['include_path'] = $result; // save original value for setting back later
1673
-        }
1674
-    }
1675
-
1676
-    /**
1677
-     * Sets PHP INI values that Phing needs.
1678
-     */
1679
-    private static function setIni(): void
1680
-    {
1681
-        self::$origIniSettings['error_reporting'] = error_reporting(E_ALL);
1682
-
1683
-        // We won't bother storing original max_execution_time, since 1) the value in
1684
-        // php.ini may be wrong (and there's no way to get the current value) and
1685
-        // 2) it would mean something very strange to set it to a value less than time script
1686
-        // has already been running, which would be the likely change.
1687
-
1688
-        set_time_limit(0);
1689
-
1690
-        self::$origIniSettings['short_open_tag'] = ini_set('short_open_tag', 'off');
1691
-        self::$origIniSettings['default_charset'] = ini_set('default_charset', 'iso-8859-1');
1692
-
1693
-        $mem_limit = (int) SizeHelper::fromHumanToBytes(ini_get('memory_limit'));
1694
-        if ($mem_limit < (32 * 1024 * 1024) && $mem_limit > -1) {
1695
-            // We do *not* need to save the original value here, since we don't plan to restore
1696
-            // this after shutdown (we don't trust the effectiveness of PHP's garbage collection).
1697
-            ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects
1698
-        }
1699
-    }
1700
-}
Please login to merge, or discard this patch.
Spacing   -1615 removed lines patch added patch discarded remove patch
@@ -83,1618 +83,3 @@
 block discarded – undo
83 83
      */
84 84
     public const DEFAULT_BUILD_FILENAME = 'build.xml';
85 85
     public const DEFAULT_BUILD_CONTENT = <<<'XML'
86
-        <?xml version="1.0" encoding="UTF-8" ?>
87
-
88
-        <project name="" description="" default="">
89
-            
90
-            <target name="" description="">
91
-                
92
-            </target>
93
-            
94
-        </project>
95
-        XML;
96
-    public const PHING_HOME = 'phing.home';
97
-    public const PHP_VERSION = 'php.version';
98
-    public const PHP_INTERPRETER = 'php.interpreter';
99
-
100
-    /**
101
-     * Our current message output status. Follows Project::MSG_XXX.
102
-     */
103
-    private static $msgOutputLevel = Project::MSG_INFO;
104
-    /**
105
-     * Set of properties that are passed in from commandline or invoking code.
106
-     *
107
-     * @var Properties
108
-     */
109
-    private static $definedProps;
110
-    /**
111
-     * Used by utility function getResourcePath().
112
-     */
113
-    private static $importPaths;
114
-    /**
115
-     * System-wide static properties (moved from System).
116
-     */
117
-    private static $properties = [];
118
-    /**
119
-     * Static system timer.
120
-     */
121
-    private static $timer;
122
-    /**
123
-     * The current Project.
124
-     */
125
-    private static $currentProject;
126
-    /**
127
-     * Whether to capture PHP errors to buffer.
128
-     */
129
-    private static $phpErrorCapture = false;
130
-    /**
131
-     * Array of captured PHP errors.
132
-     */
133
-    private static $capturedPhpErrors = [];
134
-    /**
135
-     * @var OUtputStream stream for standard output
136
-     */
137
-    private static $out;
138
-    /**
139
-     * @var OutputStream stream for error output
140
-     */
141
-    private static $err;
142
-    /**
143
-     * @var bool whether we are using a logfile
144
-     */
145
-    private static $isLogFileUsed = false;
146
-    /**
147
-     * Array to hold original ini settings that Phing changes (and needs
148
-     * to restore in restoreIni() method).
149
-     *
150
-     * @var array Struct of array(setting-name => setting-value)
151
-     *
152
-     * @see restoreIni()
153
-     */
154
-    private static $origIniSettings = [];
155
-    /**
156
-     * PhingFile that we are using for configuration.
157
-     */
158
-    private $buildFile;
159
-    /**
160
-     * The build targets.
161
-     */
162
-    private $targets = [];
163
-    /**
164
-     * Names of classes to add as listeners to project.
165
-     */
166
-    private $listeners = [];
167
-    /**
168
-     * keep going mode.
169
-     *
170
-     * @var bool
171
-     */
172
-    private $keepGoingMode = false;
173
-    private $loggerClassname;
174
-    /**
175
-     * The class to handle input (can be only one).
176
-     */
177
-    private $inputHandlerClassname;
178
-    /**
179
-     * Whether or not log output should be reduced to the minimum.
180
-     *
181
-     * @var bool
182
-     */
183
-    private $silent = false;
184
-    /**
185
-     * Indicates whether phing should run in strict mode.
186
-     */
187
-    private $strictMode = false;
188
-    /**
189
-     * Indicates if this phing should be run.
190
-     */
191
-    private $readyToRun = false;
192
-    /**
193
-     * Indicates we should only parse and display the project help information.
194
-     */
195
-    private $projectHelp = false;
196
-    /**
197
-     * Whether to values in a property file should override existing values.
198
-     */
199
-    private $propertyFileOverride = false;
200
-    /**
201
-     * Whether or not output to the log is to be unadorned.
202
-     */
203
-    private $emacsMode = false;
204
-
205
-    /**
206
-     * @var string
207
-     */
208
-    private $searchForThis;
209
-    private $propertyFiles = [];
210
-
211
-    /**
212
-     * Gets the stream to use for standard (non-error) output.
213
-     *
214
-     * @return OutputStream
215
-     */
216
-    public static function getOutputStream()
217
-    {
218
-        return self::$out;
219
-    }
220
-
221
-    /**
222
-     * Gets the stream to use for error output.
223
-     *
224
-     * @return OutputStream
225
-     */
226
-    public static function getErrorStream()
227
-    {
228
-        return self::$err;
229
-    }
230
-
231
-    /**
232
-     * Command line entry point. This method kicks off the building
233
-     * of a project object and executes a build using either a given
234
-     * target or the default target.
235
-     *
236
-     * @param array $args command line args
237
-     *
238
-     * @throws Exception
239
-     */
240
-    public static function fire($args): void
241
-    {
242
-        self::start($args);
243
-    }
244
-
245
-    /**
246
-     * Entry point allowing for more options from other front ends.
247
-     *
248
-     * This method encapsulates the complete build lifecycle.
249
-     *
250
-     * @param array $args                     the commandline args passed to phing shell script
251
-     * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this).
252
-     *                                        These additional properties will be available using the getDefinedProperty() method and will
253
-     *                                        be added to the project's "user" properties
254
-     *
255
-     * @throws Exception - if there is an error during build
256
-     *
257
-     * @see    runBuild()
258
-     * @see    execute()
259
-     */
260
-    public static function start($args, array $additionalUserProperties = null)
261
-    {
262
-        try {
263
-            $m = new self();
264
-            $m->execute($args);
265
-        } catch (Exception $exc) {
266
-            self::handleLogfile();
267
-            self::printMessage($exc);
268
-            self::statusExit(1);
269
-
270
-            return;
271
-        }
272
-
273
-        if (null !== $additionalUserProperties) {
274
-            foreach ($additionalUserProperties as $key => $value) {
275
-                $m::setDefinedProperty($key, $value);
276
-            }
277
-        }
278
-
279
-        // expect the worst
280
-        $exitCode = 1;
281
-
282
-        try {
283
-            try {
284
-                $m->runBuild();
285
-                $exitCode = 0;
286
-            } catch (ExitStatusException $ese) {
287
-                $exitCode = $ese->getCode();
288
-                if (0 !== $exitCode) {
289
-                    self::handleLogfile();
290
-
291
-                    throw $ese;
292
-                }
293
-            }
294
-        } catch (BuildException $exc) {
295
-            // avoid printing output twice: self::printMessage($exc);
296
-        } catch (Throwable $exc) {
297
-            self::printMessage($exc);
298
-        } finally {
299
-            self::handleLogfile();
300
-        }
301
-        self::statusExit($exitCode);
302
-    }
303
-
304
-    /**
305
-     * Setup/initialize Phing environment from commandline args.
306
-     *
307
-     * @param array $args commandline args passed to phing shell
308
-     *
309
-     * @throws ConfigurationException
310
-     */
311
-    public function execute($args): void
312
-    {
313
-        self::$definedProps = new Properties();
314
-        $this->searchForThis = null;
315
-
316
-        // 1) First handle any options which should always
317
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
318
-
319
-        if (in_array('-help', $args) || in_array('-h', $args)) {
320
-            static::printUsage();
321
-
322
-            return;
323
-        }
324
-
325
-        if (in_array('-version', $args) || in_array('-v', $args)) {
326
-            static::printVersion();
327
-
328
-            return;
329
-        }
330
-
331
-        if (in_array('-init', $args) || in_array('-i', $args)) {
332
-            $key = array_search('-init', $args) ?: array_search('-i', $args);
333
-            $path = $args[$key + 1] ?? null;
334
-
335
-            self::init($path);
336
-
337
-            return;
338
-        }
339
-
340
-        if (in_array('-diagnostics', $args)) {
341
-            Diagnostics::doReport(new PrintStream(self::$out));
342
-
343
-            return;
344
-        }
345
-
346
-        // 2) Next pull out stand-alone args.
347
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
348
-
349
-        if (
350
-            false !== ($key = array_search('-quiet', $args, true))
351
-            || false !== ($key = array_search(
352
-                '-q',
353
-                $args,
354
-                true
355
-            ))
356
-        ) {
357
-            self::$msgOutputLevel = Project::MSG_WARN;
358
-            unset($args[$key]);
359
-        }
360
-
361
-        if (
362
-            false !== ($key = array_search('-emacs', $args, true))
363
-            || false !== ($key = array_search('-e', $args, true))
364
-        ) {
365
-            $this->emacsMode = true;
366
-            unset($args[$key]);
367
-        }
368
-
369
-        if (false !== ($key = array_search('-verbose', $args, true))) {
370
-            self::$msgOutputLevel = Project::MSG_VERBOSE;
371
-            unset($args[$key]);
372
-        }
373
-
374
-        if (false !== ($key = array_search('-debug', $args, true))) {
375
-            self::$msgOutputLevel = Project::MSG_DEBUG;
376
-            unset($args[$key]);
377
-        }
378
-
379
-        if (
380
-            false !== ($key = array_search('-silent', $args, true))
381
-            || false !== ($key = array_search('-S', $args, true))
382
-        ) {
383
-            $this->silent = true;
384
-            unset($args[$key]);
385
-        }
386
-
387
-        if (false !== ($key = array_search('-propertyfileoverride', $args, true))) {
388
-            $this->propertyFileOverride = true;
389
-            unset($args[$key]);
390
-        }
391
-
392
-        // 3) Finally, cycle through to parse remaining args
393
-        //
394
-        $keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
395
-        $max = $keys ? max($keys) : -1;
396
-        for ($i = 0; $i <= $max; ++$i) {
397
-            if (!array_key_exists($i, $args)) {
398
-                // skip this argument, since it must have been removed above.
399
-                continue;
400
-            }
401
-
402
-            $arg = $args[$i];
403
-
404
-            if ('-logfile' == $arg) {
405
-                try {
406
-                    // see: http://phing.info/trac/ticket/65
407
-                    if (!isset($args[$i + 1])) {
408
-                        $msg = "You must specify a log file when using the -logfile argument\n";
409
-
410
-                        throw new ConfigurationException($msg);
411
-                    }
412
-
413
-                    $logFile = new File($args[++$i]);
414
-                    $out = new FileOutputStream($logFile); // overwrite
415
-                    self::setOutputStream($out);
416
-                    self::setErrorStream($out);
417
-                    self::$isLogFileUsed = true;
418
-                } catch (IOException $ioe) {
419
-                    $msg = 'Cannot write on the specified log file. Make sure the path exists and you have write permissions.';
420
-
421
-                    throw new ConfigurationException($msg, $ioe);
422
-                }
423
-            } elseif ('-buildfile' == $arg || '-file' == $arg || '-f' == $arg) {
424
-                if (!isset($args[$i + 1])) {
425
-                    $msg = 'You must specify a buildfile when using the -buildfile argument.';
426
-
427
-                    throw new ConfigurationException($msg);
428
-                }
429
-
430
-                $this->buildFile = new File($args[++$i]);
431
-            } elseif ('-listener' == $arg) {
432
-                if (!isset($args[$i + 1])) {
433
-                    $msg = 'You must specify a listener class when using the -listener argument';
434
-
435
-                    throw new ConfigurationException($msg);
436
-                }
437
-
438
-                $this->listeners[] = $args[++$i];
439
-            } elseif (StringHelper::startsWith('-D', $arg)) {
440
-                // Evaluating the property information //
441
-                // Checking whether arg. is not just a switch, and next arg. does not starts with switch identifier
442
-                if (('-D' == $arg) && (!StringHelper::startsWith('-', $args[$i + 1]))) {
443
-                    $name = $args[++$i];
444
-                } else {
445
-                    $name = substr($arg, 2);
446
-                }
447
-
448
-                $value = null;
449
-                $posEq = strpos($name, '=');
450
-                if (false !== $posEq) {
451
-                    $value = substr($name, $posEq + 1);
452
-                    $name = substr($name, 0, $posEq);
453
-                } elseif ($i < count($args) - 1 && !StringHelper::startsWith('-D', $args[$i + 1])) {
454
-                    $value = $args[++$i];
455
-                }
456
-                self::$definedProps->setProperty($name, $value);
457
-            } elseif ('-logger' == $arg) {
458
-                if (!isset($args[$i + 1])) {
459
-                    $msg = 'You must specify a classname when using the -logger argument';
460
-
461
-                    throw new ConfigurationException($msg);
462
-                }
463
-
464
-                $this->loggerClassname = $args[++$i];
465
-            } elseif ('-no-strict' == $arg) {
466
-                $this->strictMode = false;
467
-            } elseif ('-strict' == $arg) {
468
-                $this->strictMode = true;
469
-            } elseif ('-inputhandler' == $arg) {
470
-                if (null !== $this->inputHandlerClassname) {
471
-                    throw new ConfigurationException('Only one input handler class may be specified.');
472
-                }
473
-                if (!isset($args[$i + 1])) {
474
-                    $msg = 'You must specify a classname when using the -inputhandler argument';
475
-
476
-                    throw new ConfigurationException($msg);
477
-                }
478
-
479
-                $this->inputHandlerClassname = $args[++$i];
480
-            } elseif ('-propertyfile' === $arg) {
481
-                $i = $this->handleArgPropertyFile($args, $i);
482
-            } elseif ('-keep-going' === $arg || '-k' === $arg) {
483
-                $this->keepGoingMode = true;
484
-            } elseif ('-longtargets' == $arg) {
485
-                self::$definedProps->setProperty('phing.showlongtargets', 1);
486
-            } elseif ('-projecthelp' == $arg || '-targets' == $arg || '-list' == $arg || '-l' == $arg || '-p' == $arg) {
487
-                // set the flag to display the targets and quit
488
-                $this->projectHelp = true;
489
-            } elseif ('-find' == $arg) {
490
-                // eat up next arg if present, default to build.xml
491
-                if ($i < count($args) - 1) {
492
-                    $this->searchForThis = $args[++$i];
493
-                } else {
494
-                    $this->searchForThis = self::DEFAULT_BUILD_FILENAME;
495
-                }
496
-            } elseif ('-' == substr($arg, 0, 1)) {
497
-                // we don't have any more args
498
-                self::printUsage();
499
-                self::$err->write(PHP_EOL);
500
-
501
-                throw new ConfigurationException('Unknown argument: ' . $arg);
502
-            } else {
503
-                // if it's no other arg, it may be the target
504
-                $this->targets[] = $arg;
505
-            }
506
-        }
507
-
508
-        // if buildFile was not specified on the command line,
509
-        if (null === $this->buildFile) {
510
-            // but -find then search for it
511
-            if (null !== $this->searchForThis) {
512
-                $this->buildFile = $this->findBuildFile(self::getProperty('user.dir'), $this->searchForThis);
513
-            } else {
514
-                $this->buildFile = new File(self::DEFAULT_BUILD_FILENAME);
515
-            }
516
-        }
517
-
518
-        try {
519
-            // make sure buildfile (or buildfile.dist) exists
520
-            if (!$this->buildFile->exists()) {
521
-                $distFile = new File($this->buildFile->getAbsolutePath() . '.dist');
522
-                if (!$distFile->exists()) {
523
-                    throw new ConfigurationException(
524
-                        'Buildfile: ' . $this->buildFile->__toString() . ' does not exist!'
525
-                    );
526
-                }
527
-                $this->buildFile = $distFile;
528
-            }
529
-
530
-            // make sure it's not a directory
531
-            if ($this->buildFile->isDirectory()) {
532
-                throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is a dir!');
533
-            }
534
-        } catch (IOException $e) {
535
-            // something else happened, buildfile probably not readable
536
-            throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is not readable!');
537
-        }
538
-
539
-        $this->loadPropertyFiles();
540
-
541
-        $this->readyToRun = true;
542
-    }
543
-
544
-    /**
545
-     * Prints the usage of how to use this class.
546
-     */
547
-    public static function printUsage()
548
-    {
549
-        $msg = '';
550
-        $msg .= 'phing [options] [target [target2 [target3] ...]]' . PHP_EOL;
551
-        $msg .= 'Options: ' . PHP_EOL;
552
-        $msg .= '  -h -help               print this message' . PHP_EOL;
553
-        $msg .= '  -l -list               list available targets in this project' . PHP_EOL;
554
-        $msg .= '  -i -init [file]        generates an initial buildfile' . PHP_EOL;
555
-        $msg .= '  -v -version            print the version information and exit' . PHP_EOL;
556
-        $msg .= '  -q -quiet              be extra quiet' . PHP_EOL;
557
-        $msg .= '  -S -silent             print nothing but task outputs and build failures' . PHP_EOL;
558
-        $msg .= '  -verbose               be extra verbose' . PHP_EOL;
559
-        $msg .= '  -debug                 print debugging information' . PHP_EOL;
560
-        $msg .= '  -emacs, -e             produce logging information without adornments' . PHP_EOL;
561
-        $msg .= '  -diagnostics           print diagnostics information' . PHP_EOL;
562
-        $msg .= '  -strict                runs build in strict mode, considering a warning as error' . PHP_EOL;
563
-        $msg .= '  -no-strict             runs build normally (overrides buildfile attribute)' . PHP_EOL;
564
-        $msg .= '  -longtargets           show target descriptions during build' . PHP_EOL;
565
-        $msg .= '  -logfile <file>        use given file for log' . PHP_EOL;
566
-        $msg .= '  -logger <classname>    the class which is to perform logging' . PHP_EOL;
567
-        $msg .= '  -listener <classname>  add an instance of class as a project listener' . PHP_EOL;
568
-        $msg .= '  -f -buildfile <file>   use given buildfile' . PHP_EOL;
569
-        $msg .= '  -D<property>=<value>   use value for given property' . PHP_EOL;
570
-        $msg .= '  -keep-going, -k        execute all targets that do not depend' . PHP_EOL;
571
-        $msg .= '                         on failed target(s)' . PHP_EOL;
572
-        $msg .= '  -propertyfile <file>   load all properties from file' . PHP_EOL;
573
-        $msg .= '  -propertyfileoverride  values in property file override existing values' . PHP_EOL;
574
-        $msg .= '  -find <file>           search for buildfile towards the root of the' . PHP_EOL;
575
-        $msg .= '                         filesystem and use it' . PHP_EOL;
576
-        $msg .= '  -inputhandler <file>   the class to use to handle user input' . PHP_EOL;
577
-        //$msg .= "  -recursive <file>      search for buildfile downwards and use it" . PHP_EOL;
578
-        $msg .= PHP_EOL;
579
-        $msg .= 'Report bugs to https://github.com/phingofficial/phing/issues' . PHP_EOL;
580
-        self::$err->write($msg);
581
-    }
582
-
583
-    /**
584
-     * Prints the current Phing version.
585
-     */
586
-    public static function printVersion()
587
-    {
588
-        self::$out->write(self::getPhingVersion() . PHP_EOL);
589
-    }
590
-
591
-    /**
592
-     * Gets the current Phing version based on VERSION.TXT file.
593
-     *
594
-     * @throws ConfigurationException
595
-     */
596
-    public static function getPhingVersion(): string
597
-    {
598
-        $versionPath = self::getResourcePath('phing/etc/VERSION.TXT');
599
-        if (null === $versionPath) {
600
-            $versionPath = self::getResourcePath('etc/VERSION.TXT');
601
-        }
602
-        if (null === $versionPath) {
603
-            throw new ConfigurationException('No VERSION.TXT file found; try setting phing.home environment variable.');
604
-        }
605
-
606
-        try { // try to read file
607
-            $file = new File($versionPath);
608
-            $reader = new FileReader($file);
609
-            $phingVersion = trim($reader->read());
610
-        } catch (IOException $iox) {
611
-            throw new ConfigurationException("Can't read version information file");
612
-        }
613
-
614
-        $basePath = dirname(__DIR__, 2);
615
-
616
-        $version = new Version($phingVersion, $basePath);
617
-
618
-        return 'Phing ' . $version->getVersion();
619
-    }
620
-
621
-    /**
622
-     * Looks on include path for specified file.
623
-     *
624
-     * @param string $path
625
-     *
626
-     * @return null|string file found (null if no file found)
627
-     */
628
-    public static function getResourcePath($path): ?string
629
-    {
630
-        if (null === self::$importPaths) {
631
-            self::$importPaths = self::explodeIncludePath();
632
-        }
633
-
634
-        $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);
635
-
636
-        foreach (self::$importPaths as $prefix) {
637
-            $testPath = $prefix . DIRECTORY_SEPARATOR . $path;
638
-            if (file_exists($testPath)) {
639
-                return $testPath;
640
-            }
641
-        }
642
-
643
-        // Check for the property phing.home
644
-        $homeDir = self::getProperty(self::PHING_HOME);
645
-        if ($homeDir) {
646
-            $testPath = $homeDir . DIRECTORY_SEPARATOR . $path;
647
-            if (file_exists($testPath)) {
648
-                return $testPath;
649
-            }
650
-        }
651
-
652
-        // Check for the phing home of phar archive
653
-        if (0 === strpos(self::$importPaths[0], 'phar://')) {
654
-            $testPath = self::$importPaths[0] . '/../' . $path;
655
-            if (file_exists($testPath)) {
656
-                return $testPath;
657
-            }
658
-        }
659
-
660
-        // Do one additional check based on path of current file (Phing.php)
661
-        $maybeHomeDir = realpath(__DIR__ . DIRECTORY_SEPARATOR);
662
-        $testPath = $maybeHomeDir . DIRECTORY_SEPARATOR . $path;
663
-        if (file_exists($testPath)) {
664
-            return $testPath;
665
-        }
666
-
667
-        return null;
668
-    }
669
-
670
-    /**
671
-     * Explode an include path into an array.
672
-     *
673
-     * If no path provided, uses current include_path. Works around issues that
674
-     * occur when the path includes stream schemas.
675
-     *
676
-     * Pulled from Zend_Loader::explodeIncludePath() in ZF1.
677
-     *
678
-     * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
679
-     * @license   http://framework.zend.com/license/new-bsd New BSD License
680
-     *
681
-     * @param null|string $path
682
-     *
683
-     * @return array
684
-     */
685
-    public static function explodeIncludePath($path = null)
686
-    {
687
-        if (null === $path) {
688
-            $path = get_include_path();
689
-        }
690
-
691
-        if (PATH_SEPARATOR === ':') {
692
-            // On *nix systems, include_paths which include paths with a stream
693
-            // schema cannot be safely explode'd, so we have to be a bit more
694
-            // intelligent in the approach.
695
-            $paths = preg_split('#:(?!//)#', $path);
696
-        } else {
697
-            $paths = explode(PATH_SEPARATOR, $path);
698
-        }
699
-
700
-        return $paths;
701
-    }
702
-
703
-    /**
704
-     * Returns property value for a System property.
705
-     * System properties are "global" properties like application.startdir,
706
-     * and user.dir.  Many of these correspond to similar properties in Java
707
-     * or Ant.
708
-     *
709
-     * @param string $propName
710
-     *
711
-     * @return string value of found property (or null, if none found)
712
-     */
713
-    public static function getProperty($propName)
714
-    {
715
-        // some properties are detemined on each access
716
-        // some are cached, see below
717
-
718
-        // default is the cached value:
719
-        $val = self::$properties[$propName] ?? null;
720
-
721
-        // special exceptions
722
-        switch ($propName) {
723
-            case 'user.dir':
724
-                $val = getcwd();
725
-
726
-                break;
727
-        }
728
-
729
-        return $val;
730
-    }
731
-
732
-    /**
733
-     * Creates generic buildfile.
734
-     *
735
-     * @param string $path
736
-     */
737
-    public static function init($path)
738
-    {
739
-        if ($buildfilePath = self::initPath($path)) {
740
-            self::initWrite($buildfilePath);
741
-        }
742
-    }
743
-
744
-    /**
745
-     * Sets the stream to use for standard (non-error) output.
746
-     *
747
-     * @param OutputStream $stream the stream to use for standard output
748
-     */
749
-    public static function setOutputStream(OutputStream $stream)
750
-    {
751
-        self::$out = $stream;
752
-    }
753
-
754
-    /**
755
-     * Sets the stream to use for error output.
756
-     *
757
-     * @param OutputStream $stream the stream to use for error output
758
-     */
759
-    public static function setErrorStream(OutputStream $stream): void
760
-    {
761
-        self::$err = $stream;
762
-    }
763
-
764
-    /**
765
-     * Making output level a static property so that this property
766
-     * can be accessed by other parts of the system, enabling
767
-     * us to display more information -- e.g. backtraces -- for "debug" level.
768
-     *
769
-     * @return int
770
-     */
771
-    public static function getMsgOutputLevel()
772
-    {
773
-        return self::$msgOutputLevel;
774
-    }
775
-
776
-    /**
777
-     * Prints the message of the Exception if it's not null.
778
-     */
779
-    public static function printMessage(Throwable $t): void
780
-    {
781
-        if (null === self::$err) { // Make sure our error output is initialized
782
-            self::initializeOutputStreams();
783
-        }
784
-        if (self::getMsgOutputLevel() >= Project::MSG_VERBOSE) {
785
-            self::$err->write((string) $t . PHP_EOL);
786
-        } else {
787
-            self::$err->write($t->getMessage() . PHP_EOL);
788
-        }
789
-    }
790
-
791
-    /**
792
-     * Performs any shutdown routines, such as stopping timers.
793
-     *
794
-     * @throws IOException
795
-     */
796
-    public static function shutdown(): void
797
-    {
798
-        FileSystem::getFileSystem()::deleteFilesOnExit();
799
-        self::$msgOutputLevel = Project::MSG_INFO;
800
-        self::restoreIni();
801
-        self::getTimer()->stop();
802
-    }
803
-
804
-    /**
805
-     * Returns reference to DefaultClock object.
806
-     */
807
-    public static function getTimer(): DefaultClock
808
-    {
809
-        if (null === self::$timer) {
810
-            self::$timer = new DefaultClock();
811
-        }
812
-
813
-        return self::$timer;
814
-    }
815
-
816
-    /**
817
-     * This sets a property that was set via command line or otherwise passed into Phing.
818
-     *
819
-     * @param string $name
820
-     * @param mixed  $value
821
-     *
822
-     * @return mixed value of found property (or null, if none found)
823
-     */
824
-    public static function setDefinedProperty($name, $value)
825
-    {
826
-        return self::$definedProps->setProperty($name, $value);
827
-    }
828
-
829
-    /**
830
-     * Executes the build.
831
-     *
832
-     * @throws IOException
833
-     * @throws Throwable
834
-     */
835
-    public function runBuild(): void
836
-    {
837
-        if (!$this->readyToRun) {
838
-            return;
839
-        }
840
-
841
-        $project = new Project();
842
-
843
-        self::setCurrentProject($project);
844
-        set_error_handler(['Phing\Phing', 'handlePhpError']);
845
-
846
-        $error = null;
847
-
848
-        try {
849
-            $this->addBuildListeners($project);
850
-            $this->addInputHandler($project);
851
-
852
-            // set this right away, so that it can be used in logging.
853
-            $project->setUserProperty('phing.file', $this->buildFile->getAbsolutePath());
854
-            $project->setUserProperty('phing.dir', dirname($this->buildFile->getAbsolutePath()));
855
-            $project->setUserProperty('phing.version', static::getPhingVersion());
856
-            $project->fireBuildStarted();
857
-            $project->init();
858
-            $project->setKeepGoingMode($this->keepGoingMode);
859
-
860
-            $e = self::$definedProps->keys();
861
-            while (count($e)) {
862
-                $arg = (string) array_shift($e);
863
-                $value = (string) self::$definedProps->getProperty($arg);
864
-                $project->setUserProperty($arg, $value);
865
-            }
866
-            unset($e);
867
-
868
-            // first use the Configurator to create the project object
869
-            // from the given build file.
870
-
871
-            ProjectConfigurator::configureProject($project, $this->buildFile);
872
-
873
-            // Set the project mode
874
-            $project->setStrictMode(StringHelper::booleanValue($this->strictMode));
875
-
876
-            // make sure that minimum required phing version is satisfied
877
-            $this->comparePhingVersion($project->getPhingVersion());
878
-
879
-            if ($this->projectHelp) {
880
-                $this->printDescription($project);
881
-                $this->printTargets($project);
882
-
883
-                return;
884
-            }
885
-
886
-            // make sure that we have a target to execute
887
-            if (0 === count($this->targets)) {
888
-                $this->targets[] = $project->getDefaultTarget();
889
-            }
890
-
891
-            $project->executeTargets($this->targets);
892
-        } catch (Throwable $t) {
893
-            $error = $t;
894
-
895
-            throw $t;
896
-        } finally {
897
-            if (!$this->projectHelp) {
898
-                try {
899
-                    $project->fireBuildFinished($error);
900
-                } catch (Exception $e) {
901
-                    self::$err->write('Caught an exception while logging the end of the build.  Exception was:' . PHP_EOL);
902
-                    self::$err->write($e->getTraceAsString());
903
-                    if (null !== $error) {
904
-                        self::$err->write('There has been an error prior to that:' . PHP_EOL);
905
-                        self::$err->write($error->getTraceAsString());
906
-                    }
907
-
908
-                    throw new BuildException($error);
909
-                }
910
-            } elseif (null !== $error) {
911
-                $project->log($error->getMessage(), Project::MSG_ERR);
912
-            }
913
-
914
-            restore_error_handler();
915
-            self::unsetCurrentProject();
916
-        }
917
-    }
918
-
919
-    /**
920
-     * Import a class, supporting the following conventions:
921
-     * - PEAR style (@see http://pear.php.net/manual/en/standards.naming.php)
922
-     * - PSR-0 (@see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
923
-     *
924
-     * @param string $classname Name of class
925
-     * @param mixed  $classpath String or object supporting __toString()
926
-     *
927
-     * @throws BuildException - if cannot find the specified file
928
-     *
929
-     * @return string the unqualified classname (which can be instantiated)
930
-     */
931
-    public static function import($classname, $classpath = null)
932
-    {
933
-        // first check to see that the class specified hasn't already been included.
934
-        if (class_exists($classname)) {
935
-            return $classname;
936
-        }
937
-
938
-        $filename = strtr($classname, ['_' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR]) . '.php';
939
-
940
-        Phing::importFile($filename, $classpath);
941
-
942
-        return $classname;
943
-    }
944
-
945
-    /**
946
-     * Import a PHP file.
947
-     *
948
-     * This used to be named __import, however PHP has reserved all method names
949
-     * with a double underscore prefix for future use.
950
-     *
951
-     * @param string $path      Path to the PHP file
952
-     * @param mixed  $classpath String or object supporting __toString()
953
-     *
954
-     * @throws ConfigurationException
955
-     */
956
-    public static function importFile($path, $classpath = null)
957
-    {
958
-        if ($classpath) {
959
-            // Apparently casting to (string) no longer invokes __toString() automatically.
960
-            if (is_object($classpath)) {
961
-                $classpath = $classpath->__toString();
962
-            }
963
-
964
-            // classpaths are currently additive, but we also don't want to just
965
-            // indiscriminantly prepand/append stuff to the include_path.  This means
966
-            // we need to parse current incldue_path, and prepend any
967
-            // specified classpath locations that are not already in the include_path.
968
-            //
969
-            // NOTE:  the reason why we do it this way instead of just changing include_path
970
-            // and then changing it back, is that in many cases applications (e.g. Propel) will
971
-            // include/require class files from within method calls.  This means that not all
972
-            // necessary files will be included in this import() call, and hence we can't
973
-            // change the include_path back without breaking those apps.  While this method could
974
-            // be more expensive than switching & switching back (not sure, but maybe), it makes it
975
-            // possible to write far less expensive run-time applications (e.g. using Propel), which is
976
-            // really where speed matters more.
977
-
978
-            $curr_parts = Phing::explodeIncludePath();
979
-            $add_parts = Phing::explodeIncludePath($classpath);
980
-            $new_parts = array_diff($add_parts, $curr_parts);
981
-            if ($new_parts) {
982
-                set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
983
-            }
984
-        }
985
-
986
-        $ret = include_once $path;
987
-
988
-        if (false === $ret) {
989
-            $msg = "Error importing {$path}";
990
-            if (self::getMsgOutputLevel() >= Project::MSG_DEBUG) {
991
-                $x = new Exception('for-path-trace-only');
992
-                $msg .= $x->getTraceAsString();
993
-            }
994
-
995
-            throw new ConfigurationException($msg);
996
-        }
997
-    }
998
-
999
-    /**
1000
-     * Print the project description, if any.
1001
-     *
1002
-     * @throws IOException
1003
-     */
1004
-    public function printDescription(Project $project): void
1005
-    {
1006
-        if (null !== $project->getDescription()) {
1007
-            $project->log($project->getDescription());
1008
-        }
1009
-    }
1010
-
1011
-    /**
1012
-     * Print out a list of all targets in the current buildfile.
1013
-     */
1014
-    public function printTargets(Project $project)
1015
-    {
1016
-        $visibleTargets = array_filter($project->getTargets(), function (Target $target) {
1017
-            return !$target->isHidden() && !empty($target->getName());
1018
-        });
1019
-        $padding = array_reduce($visibleTargets, function (int $carry, Target $target) {
1020
-            return max(strlen($target->getName()), $carry);
1021
-        }, 0);
1022
-        $categories = [
1023
-            'Default target:' => array_filter($visibleTargets, function (Target $target) use ($project) {
1024
-                return trim(strval($target)) === $project->getDefaultTarget();
1025
-            }),
1026
-            'Main targets:' => array_filter($visibleTargets, function (Target $target) {
1027
-                return !empty($target->getDescription());
1028
-            }),
1029
-            'Subtargets:' => array_filter($visibleTargets, function (Target $target) {
1030
-                return empty($target->getDescription());
1031
-            }),
1032
-        ];
1033
-        foreach ($categories as $title => $targets) {
1034
-            $targetList = $this->generateTargetList($title, $targets, $padding);
1035
-            $project->log($targetList, Project::MSG_WARN);
1036
-        }
1037
-    }
1038
-
1039
-    /**
1040
-     * Unsets the current Project.
1041
-     */
1042
-    public static function unsetCurrentProject(): void
1043
-    {
1044
-        self::$currentProject = null;
1045
-    }
1046
-
1047
-    /**
1048
-     * Error handler for PHP errors encountered during the build.
1049
-     * This uses the logging for the currently configured project.
1050
-     *
1051
-     * @param $level
1052
-     * @param string $message
1053
-     * @param $file
1054
-     * @param $line
1055
-     */
1056
-    public static function handlePhpError($level, $message, $file, $line)
1057
-    {
1058
-        // don't want to print suppressed errors
1059
-        if (error_reporting() > 0) {
1060
-            if (self::$phpErrorCapture) {
1061
-                self::$capturedPhpErrors[] = [
1062
-                    'message' => $message,
1063
-                    'level' => $level,
1064
-                    'line' => $line,
1065
-                    'file' => $file,
1066
-                ];
1067
-            } else {
1068
-                $message = '[PHP Error] ' . $message;
1069
-                $message .= ' [line ' . $line . ' of ' . $file . ']';
1070
-
1071
-                switch ($level) {
1072
-                    case E_USER_DEPRECATED:
1073
-                    case E_DEPRECATED:
1074
-                    case E_STRICT:
1075
-                    case E_NOTICE:
1076
-                    case E_USER_NOTICE:
1077
-                        self::log($message, Project::MSG_VERBOSE);
1078
-
1079
-                        break;
1080
-
1081
-                    case E_WARNING:
1082
-                    case E_USER_WARNING:
1083
-                        self::log($message, Project::MSG_WARN);
1084
-
1085
-                        break;
1086
-
1087
-                    case E_ERROR:
1088
-                    case E_USER_ERROR:
1089
-                    default:
1090
-                        self::log($message, Project::MSG_ERR);
1091
-                } // switch
1092
-            } // if phpErrorCapture
1093
-        } // if not @
1094
-    }
1095
-
1096
-    /**
1097
-     * A static convenience method to send a log to the current (last-setup) Project.
1098
-     * If there is no currently-configured Project, then this will do nothing.
1099
-     *
1100
-     * @param string $message
1101
-     * @param int    $priority project::MSG_INFO, etc
1102
-     */
1103
-    public static function log($message, $priority = Project::MSG_INFO): void
1104
-    {
1105
-        $p = self::getCurrentProject();
1106
-        if ($p) {
1107
-            $p->log($message, $priority);
1108
-        }
1109
-    }
1110
-
1111
-    /**
1112
-     * Gets the current Project.
1113
-     *
1114
-     * @return Project current Project or NULL if none is set yet/still
1115
-     */
1116
-    public static function getCurrentProject()
1117
-    {
1118
-        return self::$currentProject;
1119
-    }
1120
-
1121
-    /**
1122
-     * Sets the current Project.
1123
-     *
1124
-     * @param Project $p
1125
-     */
1126
-    public static function setCurrentProject($p): void
1127
-    {
1128
-        self::$currentProject = $p;
1129
-    }
1130
-
1131
-    /**
1132
-     * Begins capturing PHP errors to a buffer.
1133
-     * While errors are being captured, they are not logged.
1134
-     */
1135
-    public static function startPhpErrorCapture(): void
1136
-    {
1137
-        self::$phpErrorCapture = true;
1138
-        self::$capturedPhpErrors = [];
1139
-    }
1140
-
1141
-    /**
1142
-     * Stops capturing PHP errors to a buffer.
1143
-     * The errors will once again be logged after calling this method.
1144
-     */
1145
-    public static function stopPhpErrorCapture(): void
1146
-    {
1147
-        self::$phpErrorCapture = false;
1148
-    }
1149
-
1150
-    /**
1151
-     * Clears the captured errors without affecting the starting/stopping of the capture.
1152
-     */
1153
-    public static function clearCapturedPhpErrors(): void
1154
-    {
1155
-        self::$capturedPhpErrors = [];
1156
-    }
1157
-
1158
-    /**
1159
-     * Gets any PHP errors that were captured to buffer.
1160
-     *
1161
-     * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level)
1162
-     */
1163
-    public static function getCapturedPhpErrors()
1164
-    {
1165
-        return self::$capturedPhpErrors;
1166
-    }
1167
-
1168
-    /**
1169
-     * This gets a property that was set via command line or otherwise passed into Phing.
1170
-     * "Defined" in this case means "externally defined".  The reason this method exists is to
1171
-     * provide a public means of accessing commandline properties for (e.g.) logger or listener
1172
-     * scripts.  E.g. to specify which logfile to use, PearLogger needs to be able to access
1173
-     * the pear.log.name property.
1174
-     *
1175
-     * @param string $name
1176
-     *
1177
-     * @return string value of found property (or null, if none found)
1178
-     */
1179
-    public static function getDefinedProperty($name)
1180
-    {
1181
-        return self::$definedProps->getProperty($name);
1182
-    }
1183
-
1184
-    /**
1185
-     * Retuns reference to all properties.
1186
-     */
1187
-    public static function &getProperties()
1188
-    {
1189
-        return self::$properties;
1190
-    }
1191
-
1192
-    /**
1193
-     * Start up Phing.
1194
-     * Sets up the Phing environment but does not initiate the build process.
1195
-     *
1196
-     * @throws exception - If the Phing environment cannot be initialized
1197
-     */
1198
-    public static function startup(): void
1199
-    {
1200
-        // setup STDOUT and STDERR defaults
1201
-        self::initializeOutputStreams();
1202
-
1203
-        // some init stuff
1204
-        self::getTimer()->start();
1205
-
1206
-        self::setSystemConstants();
1207
-        self::setIncludePaths();
1208
-        self::setIni();
1209
-    }
1210
-
1211
-    /**
1212
-     * @param $propName
1213
-     * @param $propValue
1214
-     *
1215
-     * @return string
1216
-     */
1217
-    public static function setProperty($propName, $propValue)
1218
-    {
1219
-        $propName = (string) $propName;
1220
-        $oldValue = self::getProperty($propName);
1221
-        self::$properties[$propName] = $propValue;
1222
-
1223
-        return $oldValue;
1224
-    }
1225
-
1226
-    /**
1227
-     * Returns buildfile's path.
1228
-     *
1229
-     * @param $path
1230
-     *
1231
-     * @throws ConfigurationException
1232
-     *
1233
-     * @return string
1234
-     */
1235
-    protected static function initPath($path)
1236
-    {
1237
-        // Fallback
1238
-        if (empty($path)) {
1239
-            $defaultDir = self::getProperty('application.startdir');
1240
-            $path = $defaultDir . DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1241
-        }
1242
-
1243
-        // Adding filename if necessary
1244
-        if (is_dir($path)) {
1245
-            $path .= DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1246
-        }
1247
-
1248
-        // Check if path is available
1249
-        $dirname = dirname($path);
1250
-        if (is_dir($dirname) && !is_file($path)) {
1251
-            return $path;
1252
-        }
1253
-
1254
-        // Path is valid, but buildfile already exists
1255
-        if (is_file($path)) {
1256
-            throw new ConfigurationException('Buildfile already exists.');
1257
-        }
1258
-
1259
-        throw new ConfigurationException('Invalid path for sample buildfile.');
1260
-    }
1261
-
1262
-    /**
1263
-     * Writes sample buildfile.
1264
-     *
1265
-     * If $buildfilePath does not exist, the buildfile is created.
1266
-     *
1267
-     * @param $buildfilePath buildfile's location
1268
-     *
1269
-     * @throws ConfigurationException
1270
-     */
1271
-    protected static function initWrite($buildfilePath): void
1272
-    {
1273
-        // Overwriting protection
1274
-        if (file_exists($buildfilePath)) {
1275
-            throw new ConfigurationException('Cannot overwrite existing file.');
1276
-        }
1277
-
1278
-        file_put_contents($buildfilePath, self::DEFAULT_BUILD_CONTENT);
1279
-    }
1280
-
1281
-    /**
1282
-     * This operation is expected to call `exit($int)`, which
1283
-     * is what the base version does.
1284
-     * However, it is possible to do something else.
1285
-     *
1286
-     * @param int $exitCode code to exit with
1287
-     */
1288
-    protected static function statusExit($exitCode): void
1289
-    {
1290
-        Phing::shutdown();
1291
-
1292
-        exit($exitCode);
1293
-    }
1294
-
1295
-    /**
1296
-     * Handle the -propertyfile argument.
1297
-     *
1298
-     * @throws ConfigurationException
1299
-     * @throws IOException
1300
-     */
1301
-    private function handleArgPropertyFile(array $args, int $pos): int
1302
-    {
1303
-        if (!isset($args[$pos + 1])) {
1304
-            throw new ConfigurationException('You must specify a filename when using the -propertyfile argument');
1305
-        }
1306
-
1307
-        $this->propertyFiles[] = $args[++$pos];
1308
-
1309
-        return $pos;
1310
-    }
1311
-
1312
-    /**
1313
-     * Search parent directories for the build file.
1314
-     *
1315
-     * Takes the given target as a suffix to append to each
1316
-     * parent directory in search of a build file.  Once the
1317
-     * root of the file-system has been reached an exception
1318
-     * is thrown.
1319
-     *
1320
-     * @param string $start  start file path
1321
-     * @param string $suffix suffix filename to look for in parents
1322
-     *
1323
-     * @throws ConfigurationException
1324
-     *
1325
-     * @return File A handle to the build file
1326
-     */
1327
-    private function findBuildFile($start, $suffix)
1328
-    {
1329
-        if (self::getMsgOutputLevel() >= Project::MSG_INFO) {
1330
-            self::$out->write('Searching for ' . $suffix . ' ...' . PHP_EOL);
1331
-        }
1332
-
1333
-        $parent = new File((new File($start))->getAbsolutePath());
1334
-        $file = new File($parent, $suffix);
1335
-
1336
-        // check if the target file exists in the current directory
1337
-        while (!$file->exists()) {
1338
-            // change to parent directory
1339
-            $parent = $parent->getParentFile();
1340
-
1341
-            // if parent is null, then we are at the root of the fs,
1342
-            // complain that we can't find the build file.
1343
-            if (null === $parent) {
1344
-                throw new ConfigurationException('Could not locate a build file!');
1345
-            }
1346
-            // refresh our file handle
1347
-            $file = new File($parent, $suffix);
1348
-        }
1349
-
1350
-        return $file;
1351
-    }
1352
-
1353
-    /**
1354
-     * @throws IOException
1355
-     */
1356
-    private function loadPropertyFiles(): void
1357
-    {
1358
-        foreach ($this->propertyFiles as $filename) {
1359
-            $fileParserFactory = new FileParserFactory();
1360
-            $fileParser = $fileParserFactory->createParser(pathinfo($filename, PATHINFO_EXTENSION));
1361
-            $p = new Properties(null, $fileParser);
1362
-
1363
-            try {
1364
-                $p->load(new File($filename));
1365
-            } catch (IOException $e) {
1366
-                self::$out->write('Could not load property file ' . $filename . ': ' . $e->getMessage());
1367
-            }
1368
-            foreach ($p->getProperties() as $prop => $value) {
1369
-                self::$definedProps->setProperty($prop, $value);
1370
-            }
1371
-        }
1372
-    }
1373
-
1374
-    /**
1375
-     * Close logfiles, if we have been writing to them.
1376
-     *
1377
-     * @since Phing 2.3.0
1378
-     */
1379
-    private static function handleLogfile(): void
1380
-    {
1381
-        if (self::$isLogFileUsed) {
1382
-            self::$err->close();
1383
-            self::$out->close();
1384
-        }
1385
-    }
1386
-
1387
-    /**
1388
-     * Sets the stdout and stderr streams if they are not already set.
1389
-     */
1390
-    private static function initializeOutputStreams()
1391
-    {
1392
-        if (null === self::$out) {
1393
-            if (!defined('STDOUT')) {
1394
-                self::$out = new OutputStream(fopen('php://stdout', 'w'));
1395
-            } else {
1396
-                self::$out = new OutputStream(STDOUT);
1397
-            }
1398
-        }
1399
-        if (null === self::$err) {
1400
-            if (!defined('STDERR')) {
1401
-                self::$err = new OutputStream(fopen('php://stderr', 'w'));
1402
-            } else {
1403
-                self::$err = new OutputStream(STDERR);
1404
-            }
1405
-        }
1406
-    }
1407
-
1408
-    /**
1409
-     * Restores [most] PHP INI values to their pre-Phing state.
1410
-     *
1411
-     * Currently the following settings are not restored:
1412
-     *  - max_execution_time (because getting current time limit is not possible)
1413
-     *  - memory_limit (which may have been increased by Phing)
1414
-     */
1415
-    private static function restoreIni(): void
1416
-    {
1417
-        foreach (self::$origIniSettings as $settingName => $settingValue) {
1418
-            switch ($settingName) {
1419
-                case 'error_reporting':
1420
-                    error_reporting($settingValue);
1421
-
1422
-                    break;
1423
-
1424
-                default:
1425
-                    ini_set($settingName, $settingValue);
1426
-            }
1427
-        }
1428
-    }
1429
-
1430
-    /**
1431
-     * Bind any registered build listeners to this project.
1432
-     *
1433
-     * This means adding the logger and any build listeners that were specified
1434
-     * with -listener arg.
1435
-     *
1436
-     * @throws BuildException
1437
-     * @throws ConfigurationException
1438
-     */
1439
-    private function addBuildListeners(Project $project)
1440
-    {
1441
-        // Add the default listener
1442
-        $project->addBuildListener($this->createLogger());
1443
-
1444
-        foreach ($this->listeners as $listenerClassname) {
1445
-            try {
1446
-                $clz = Phing::import($listenerClassname);
1447
-            } catch (Exception $e) {
1448
-                $msg = 'Unable to instantiate specified listener '
1449
-                    . 'class ' . $listenerClassname . ' : '
1450
-                    . $e->getMessage();
1451
-
1452
-                throw new ConfigurationException($msg);
1453
-            }
1454
-
1455
-            $listener = new $clz();
1456
-
1457
-            if ($listener instanceof StreamRequiredBuildLogger) {
1458
-                throw new ConfigurationException('Unable to add ' . $listenerClassname . ' as a listener, since it requires explicit error/output streams. (You can specify it as a -logger.)');
1459
-            }
1460
-            $project->addBuildListener($listener);
1461
-        }
1462
-    }
1463
-
1464
-    /**
1465
-     * Creates the default build logger for sending build events to the log.
1466
-     *
1467
-     * @throws BuildException
1468
-     *
1469
-     * @return BuildLogger The created Logger
1470
-     */
1471
-    private function createLogger()
1472
-    {
1473
-        if ($this->silent) {
1474
-            $logger = new SilentLogger();
1475
-            self::$msgOutputLevel = Project::MSG_WARN;
1476
-        } elseif (null !== $this->loggerClassname) {
1477
-            self::import($this->loggerClassname);
1478
-            // get class name part
1479
-            $classname = self::import($this->loggerClassname);
1480
-            $logger = new $classname();
1481
-            if (!($logger instanceof BuildLogger)) {
1482
-                throw new BuildException($classname . ' does not implement the BuildLogger interface.');
1483
-            }
1484
-        } else {
1485
-            $logger = new DefaultLogger();
1486
-        }
1487
-        $logger->setMessageOutputLevel(self::$msgOutputLevel);
1488
-        $logger->setOutputStream(self::$out);
1489
-        $logger->setErrorStream(self::$err);
1490
-        $logger->setEmacsMode($this->emacsMode);
1491
-
1492
-        return $logger;
1493
-    }
1494
-
1495
-    /**
1496
-     * Creates the InputHandler and adds it to the project.
1497
-     *
1498
-     * @param Project $project the project instance
1499
-     *
1500
-     * @throws ConfigurationException
1501
-     */
1502
-    private function addInputHandler(Project $project): void
1503
-    {
1504
-        if (null === $this->inputHandlerClassname) {
1505
-            $handler = new ConsoleInputHandler(STDIN, new ConsoleOutput());
1506
-        } else {
1507
-            try {
1508
-                $clz = Phing::import($this->inputHandlerClassname);
1509
-                $handler = new $clz();
1510
-                if (null !== $project && method_exists($handler, 'setProject')) {
1511
-                    $handler->setProject($project);
1512
-                }
1513
-            } catch (Exception $e) {
1514
-                $msg = 'Unable to instantiate specified input handler '
1515
-                    . 'class ' . $this->inputHandlerClassname . ' : '
1516
-                    . $e->getMessage();
1517
-
1518
-                throw new ConfigurationException($msg);
1519
-            }
1520
-        }
1521
-        $project->setInputHandler($handler);
1522
-    }
1523
-
1524
-    /**
1525
-     * @param string $version
1526
-     *
1527
-     * @throws BuildException
1528
-     * @throws ConfigurationException
1529
-     */
1530
-    private function comparePhingVersion($version): void
1531
-    {
1532
-        $current = strtolower(self::getPhingVersion());
1533
-        $current = trim(str_replace('phing', '', $current));
1534
-
1535
-        // make sure that version checks are not applied to trunk
1536
-        if ('dev' === $current) {
1537
-            return;
1538
-        }
1539
-
1540
-        if (-1 == version_compare($current, $version)) {
1541
-            throw new BuildException(
1542
-                sprintf('Incompatible Phing version (%s). Version "%s" required.', $current, $version)
1543
-            );
1544
-        }
1545
-    }
1546
-
1547
-    /**
1548
-     * Returns a formatted list of target names with an optional description.
1549
-     *
1550
-     * @param string   $title   Title for this list
1551
-     * @param Target[] $targets Targets in this list
1552
-     * @param int      $padding Padding for name column
1553
-     */
1554
-    private function generateTargetList(string $title, array $targets, int $padding): string
1555
-    {
1556
-        usort($targets, function (Target $a, Target $b) {
1557
-            return $a->getName() <=> $b->getName();
1558
-        });
1559
-
1560
-        $header = <<<HEADER
1561
-            {$title}
1562
-            -------------------------------------------------------------------------------
1563
-
1564
-            HEADER;
1565
-
1566
-        $getDetails = function (Target $target) use ($padding): string {
1567
-            $details = [];
1568
-            if (!empty($target->getDescription())) {
1569
-                $details[] = $target->getDescription();
1570
-            }
1571
-            if (!empty($target->getDependencies())) {
1572
-                $details[] = ' - depends on: ' . implode(', ', $target->getDependencies());
1573
-            }
1574
-            if (!empty($target->getIf())) {
1575
-                $details[] = ' - if property: ' . $target->getIf();
1576
-            }
1577
-            if (!empty($target->getUnless())) {
1578
-                $details[] = ' - unless property: ' . $target->getUnless();
1579
-            }
1580
-            $detailsToString = function (?string $name, ?string $detail) use ($padding): string {
1581
-                return sprintf(" %-{$padding}s  %s", $name, $detail);
1582
-            };
1583
-
1584
-            return implode(PHP_EOL, array_map($detailsToString, [$target->getName()], $details));
1585
-        };
1586
-
1587
-        return $header . implode(PHP_EOL, array_map($getDetails, $targets)) . PHP_EOL;
1588
-    }
1589
-
1590
-    /**
1591
-     * Set System constants which can be retrieved by calling Phing::getProperty($propName).
1592
-     */
1593
-    private static function setSystemConstants(): void
1594
-    {
1595
-        /*
1596
-         * PHP_OS returns on
1597
-         *   WindowsNT4.0sp6  => WINNT
1598
-         *   Windows2000      => WINNT
1599
-         *   Windows ME       => WIN32
1600
-         *   Windows 98SE     => WIN32
1601
-         *   FreeBSD 4.5p7    => FreeBSD
1602
-         *   Redhat Linux     => Linux
1603
-         *   Mac OS X         => Darwin
1604
-         */
1605
-        self::setProperty('host.os', PHP_OS);
1606
-
1607
-        // this is used by some tasks too
1608
-        self::setProperty('os.name', PHP_OS);
1609
-
1610
-        // it's still possible this won't be defined,
1611
-        // e.g. if Phing is being included in another app w/o
1612
-        // using the phing.php script.
1613
-        if (!defined('PHP_CLASSPATH')) {
1614
-            define('PHP_CLASSPATH', get_include_path());
1615
-        }
1616
-
1617
-        self::setProperty('php.classpath', PHP_CLASSPATH);
1618
-
1619
-        // try to determine the host filesystem and set system property
1620
-        // used by Fileself::getFileSystem to instantiate the correct
1621
-        // abstraction layer
1622
-
1623
-        if (PHP_OS_FAMILY === 'Windows') {
1624
-            self::setProperty('host.fstype', 'WINDOWS');
1625
-            self::setProperty('user.home', getenv('HOMEDRIVE') . getenv('HOMEPATH'));
1626
-        } else {
1627
-            self::setProperty('host.fstype', 'UNIX');
1628
-            self::setProperty('user.home', getenv('HOME'));
1629
-        }
1630
-        self::setProperty(self::PHP_INTERPRETER, PHP_BINARY);
1631
-        self::setProperty('file.separator', FileUtils::getSeparator());
1632
-        self::setProperty('line.separator', PHP_EOL);
1633
-        self::setProperty('path.separator', FileUtils::getPathSeparator());
1634
-        self::setProperty(self::PHP_VERSION, PHP_VERSION);
1635
-        self::setProperty('php.tmpdir', sys_get_temp_dir());
1636
-        self::setProperty('application.startdir', getcwd());
1637
-        self::setProperty('phing.startTime', gmdate('D, d M Y H:i:s', time()) . ' GMT');
1638
-
1639
-        // try to detect machine dependent information
1640
-        $sysInfo = [];
1641
-        if (function_exists('posix_uname') && 0 !== stripos(PHP_OS, 'WIN')) {
1642
-            $sysInfo = posix_uname();
1643
-        } else {
1644
-            $sysInfo['nodename'] = php_uname('n');
1645
-            $sysInfo['machine'] = php_uname('m');
1646
-            //this is a not so ideal substition, but maybe better than nothing
1647
-            $sysInfo['domain'] = $_SERVER['SERVER_NAME'] ?? 'unknown';
1648
-            $sysInfo['release'] = php_uname('r');
1649
-            $sysInfo['version'] = php_uname('v');
1650
-        }
1651
-
1652
-        self::setProperty('host.name', $sysInfo['nodename'] ?? 'unknown');
1653
-        self::setProperty('host.arch', $sysInfo['machine'] ?? 'unknown');
1654
-        self::setProperty('host.domain', $sysInfo['domain'] ?? 'unknown');
1655
-        self::setProperty('host.os.release', $sysInfo['release'] ?? 'unknown');
1656
-        self::setProperty('host.os.version', $sysInfo['version'] ?? 'unknown');
1657
-        unset($sysInfo);
1658
-    }
1659
-
1660
-    /**
1661
-     * Sets the include path to PHP_CLASSPATH constant (if this has been defined).
1662
-     *
1663
-     * @throws ConfigurationException - if the include_path could not be set (for some bizarre reason)
1664
-     */
1665
-    private static function setIncludePaths(): void
1666
-    {
1667
-        if (defined('PHP_CLASSPATH')) {
1668
-            $result = set_include_path(PHP_CLASSPATH);
1669
-            if (false === $result) {
1670
-                throw new ConfigurationException('Could not set PHP include_path.');
1671
-            }
1672
-            self::$origIniSettings['include_path'] = $result; // save original value for setting back later
1673
-        }
1674
-    }
1675
-
1676
-    /**
1677
-     * Sets PHP INI values that Phing needs.
1678
-     */
1679
-    private static function setIni(): void
1680
-    {
1681
-        self::$origIniSettings['error_reporting'] = error_reporting(E_ALL);
1682
-
1683
-        // We won't bother storing original max_execution_time, since 1) the value in
1684
-        // php.ini may be wrong (and there's no way to get the current value) and
1685
-        // 2) it would mean something very strange to set it to a value less than time script
1686
-        // has already been running, which would be the likely change.
1687
-
1688
-        set_time_limit(0);
1689
-
1690
-        self::$origIniSettings['short_open_tag'] = ini_set('short_open_tag', 'off');
1691
-        self::$origIniSettings['default_charset'] = ini_set('default_charset', 'iso-8859-1');
1692
-
1693
-        $mem_limit = (int) SizeHelper::fromHumanToBytes(ini_get('memory_limit'));
1694
-        if ($mem_limit < (32 * 1024 * 1024) && $mem_limit > -1) {
1695
-            // We do *not* need to save the original value here, since we don't plan to restore
1696
-            // this after shutdown (we don't trust the effectiveness of PHP's garbage collection).
1697
-            ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects
1698
-        }
1699
-    }
1700
-}
Please login to merge, or discard this patch.
Braces   -1615 removed lines patch added patch discarded remove patch
@@ -83,1618 +83,3 @@
 block discarded – undo
83 83
      */
84 84
     public const DEFAULT_BUILD_FILENAME = 'build.xml';
85 85
     public const DEFAULT_BUILD_CONTENT = <<<'XML'
86
-        <?xml version="1.0" encoding="UTF-8" ?>
87
-
88
-        <project name="" description="" default="">
89
-            
90
-            <target name="" description="">
91
-                
92
-            </target>
93
-            
94
-        </project>
95
-        XML;
96
-    public const PHING_HOME = 'phing.home';
97
-    public const PHP_VERSION = 'php.version';
98
-    public const PHP_INTERPRETER = 'php.interpreter';
99
-
100
-    /**
101
-     * Our current message output status. Follows Project::MSG_XXX.
102
-     */
103
-    private static $msgOutputLevel = Project::MSG_INFO;
104
-    /**
105
-     * Set of properties that are passed in from commandline or invoking code.
106
-     *
107
-     * @var Properties
108
-     */
109
-    private static $definedProps;
110
-    /**
111
-     * Used by utility function getResourcePath().
112
-     */
113
-    private static $importPaths;
114
-    /**
115
-     * System-wide static properties (moved from System).
116
-     */
117
-    private static $properties = [];
118
-    /**
119
-     * Static system timer.
120
-     */
121
-    private static $timer;
122
-    /**
123
-     * The current Project.
124
-     */
125
-    private static $currentProject;
126
-    /**
127
-     * Whether to capture PHP errors to buffer.
128
-     */
129
-    private static $phpErrorCapture = false;
130
-    /**
131
-     * Array of captured PHP errors.
132
-     */
133
-    private static $capturedPhpErrors = [];
134
-    /**
135
-     * @var OUtputStream stream for standard output
136
-     */
137
-    private static $out;
138
-    /**
139
-     * @var OutputStream stream for error output
140
-     */
141
-    private static $err;
142
-    /**
143
-     * @var bool whether we are using a logfile
144
-     */
145
-    private static $isLogFileUsed = false;
146
-    /**
147
-     * Array to hold original ini settings that Phing changes (and needs
148
-     * to restore in restoreIni() method).
149
-     *
150
-     * @var array Struct of array(setting-name => setting-value)
151
-     *
152
-     * @see restoreIni()
153
-     */
154
-    private static $origIniSettings = [];
155
-    /**
156
-     * PhingFile that we are using for configuration.
157
-     */
158
-    private $buildFile;
159
-    /**
160
-     * The build targets.
161
-     */
162
-    private $targets = [];
163
-    /**
164
-     * Names of classes to add as listeners to project.
165
-     */
166
-    private $listeners = [];
167
-    /**
168
-     * keep going mode.
169
-     *
170
-     * @var bool
171
-     */
172
-    private $keepGoingMode = false;
173
-    private $loggerClassname;
174
-    /**
175
-     * The class to handle input (can be only one).
176
-     */
177
-    private $inputHandlerClassname;
178
-    /**
179
-     * Whether or not log output should be reduced to the minimum.
180
-     *
181
-     * @var bool
182
-     */
183
-    private $silent = false;
184
-    /**
185
-     * Indicates whether phing should run in strict mode.
186
-     */
187
-    private $strictMode = false;
188
-    /**
189
-     * Indicates if this phing should be run.
190
-     */
191
-    private $readyToRun = false;
192
-    /**
193
-     * Indicates we should only parse and display the project help information.
194
-     */
195
-    private $projectHelp = false;
196
-    /**
197
-     * Whether to values in a property file should override existing values.
198
-     */
199
-    private $propertyFileOverride = false;
200
-    /**
201
-     * Whether or not output to the log is to be unadorned.
202
-     */
203
-    private $emacsMode = false;
204
-
205
-    /**
206
-     * @var string
207
-     */
208
-    private $searchForThis;
209
-    private $propertyFiles = [];
210
-
211
-    /**
212
-     * Gets the stream to use for standard (non-error) output.
213
-     *
214
-     * @return OutputStream
215
-     */
216
-    public static function getOutputStream()
217
-    {
218
-        return self::$out;
219
-    }
220
-
221
-    /**
222
-     * Gets the stream to use for error output.
223
-     *
224
-     * @return OutputStream
225
-     */
226
-    public static function getErrorStream()
227
-    {
228
-        return self::$err;
229
-    }
230
-
231
-    /**
232
-     * Command line entry point. This method kicks off the building
233
-     * of a project object and executes a build using either a given
234
-     * target or the default target.
235
-     *
236
-     * @param array $args command line args
237
-     *
238
-     * @throws Exception
239
-     */
240
-    public static function fire($args): void
241
-    {
242
-        self::start($args);
243
-    }
244
-
245
-    /**
246
-     * Entry point allowing for more options from other front ends.
247
-     *
248
-     * This method encapsulates the complete build lifecycle.
249
-     *
250
-     * @param array $args                     the commandline args passed to phing shell script
251
-     * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this).
252
-     *                                        These additional properties will be available using the getDefinedProperty() method and will
253
-     *                                        be added to the project's "user" properties
254
-     *
255
-     * @throws Exception - if there is an error during build
256
-     *
257
-     * @see    runBuild()
258
-     * @see    execute()
259
-     */
260
-    public static function start($args, array $additionalUserProperties = null)
261
-    {
262
-        try {
263
-            $m = new self();
264
-            $m->execute($args);
265
-        } catch (Exception $exc) {
266
-            self::handleLogfile();
267
-            self::printMessage($exc);
268
-            self::statusExit(1);
269
-
270
-            return;
271
-        }
272
-
273
-        if (null !== $additionalUserProperties) {
274
-            foreach ($additionalUserProperties as $key => $value) {
275
-                $m::setDefinedProperty($key, $value);
276
-            }
277
-        }
278
-
279
-        // expect the worst
280
-        $exitCode = 1;
281
-
282
-        try {
283
-            try {
284
-                $m->runBuild();
285
-                $exitCode = 0;
286
-            } catch (ExitStatusException $ese) {
287
-                $exitCode = $ese->getCode();
288
-                if (0 !== $exitCode) {
289
-                    self::handleLogfile();
290
-
291
-                    throw $ese;
292
-                }
293
-            }
294
-        } catch (BuildException $exc) {
295
-            // avoid printing output twice: self::printMessage($exc);
296
-        } catch (Throwable $exc) {
297
-            self::printMessage($exc);
298
-        } finally {
299
-            self::handleLogfile();
300
-        }
301
-        self::statusExit($exitCode);
302
-    }
303
-
304
-    /**
305
-     * Setup/initialize Phing environment from commandline args.
306
-     *
307
-     * @param array $args commandline args passed to phing shell
308
-     *
309
-     * @throws ConfigurationException
310
-     */
311
-    public function execute($args): void
312
-    {
313
-        self::$definedProps = new Properties();
314
-        $this->searchForThis = null;
315
-
316
-        // 1) First handle any options which should always
317
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
318
-
319
-        if (in_array('-help', $args) || in_array('-h', $args)) {
320
-            static::printUsage();
321
-
322
-            return;
323
-        }
324
-
325
-        if (in_array('-version', $args) || in_array('-v', $args)) {
326
-            static::printVersion();
327
-
328
-            return;
329
-        }
330
-
331
-        if (in_array('-init', $args) || in_array('-i', $args)) {
332
-            $key = array_search('-init', $args) ?: array_search('-i', $args);
333
-            $path = $args[$key + 1] ?? null;
334
-
335
-            self::init($path);
336
-
337
-            return;
338
-        }
339
-
340
-        if (in_array('-diagnostics', $args)) {
341
-            Diagnostics::doReport(new PrintStream(self::$out));
342
-
343
-            return;
344
-        }
345
-
346
-        // 2) Next pull out stand-alone args.
347
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
348
-
349
-        if (
350
-            false !== ($key = array_search('-quiet', $args, true))
351
-            || false !== ($key = array_search(
352
-                '-q',
353
-                $args,
354
-                true
355
-            ))
356
-        ) {
357
-            self::$msgOutputLevel = Project::MSG_WARN;
358
-            unset($args[$key]);
359
-        }
360
-
361
-        if (
362
-            false !== ($key = array_search('-emacs', $args, true))
363
-            || false !== ($key = array_search('-e', $args, true))
364
-        ) {
365
-            $this->emacsMode = true;
366
-            unset($args[$key]);
367
-        }
368
-
369
-        if (false !== ($key = array_search('-verbose', $args, true))) {
370
-            self::$msgOutputLevel = Project::MSG_VERBOSE;
371
-            unset($args[$key]);
372
-        }
373
-
374
-        if (false !== ($key = array_search('-debug', $args, true))) {
375
-            self::$msgOutputLevel = Project::MSG_DEBUG;
376
-            unset($args[$key]);
377
-        }
378
-
379
-        if (
380
-            false !== ($key = array_search('-silent', $args, true))
381
-            || false !== ($key = array_search('-S', $args, true))
382
-        ) {
383
-            $this->silent = true;
384
-            unset($args[$key]);
385
-        }
386
-
387
-        if (false !== ($key = array_search('-propertyfileoverride', $args, true))) {
388
-            $this->propertyFileOverride = true;
389
-            unset($args[$key]);
390
-        }
391
-
392
-        // 3) Finally, cycle through to parse remaining args
393
-        //
394
-        $keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
395
-        $max = $keys ? max($keys) : -1;
396
-        for ($i = 0; $i <= $max; ++$i) {
397
-            if (!array_key_exists($i, $args)) {
398
-                // skip this argument, since it must have been removed above.
399
-                continue;
400
-            }
401
-
402
-            $arg = $args[$i];
403
-
404
-            if ('-logfile' == $arg) {
405
-                try {
406
-                    // see: http://phing.info/trac/ticket/65
407
-                    if (!isset($args[$i + 1])) {
408
-                        $msg = "You must specify a log file when using the -logfile argument\n";
409
-
410
-                        throw new ConfigurationException($msg);
411
-                    }
412
-
413
-                    $logFile = new File($args[++$i]);
414
-                    $out = new FileOutputStream($logFile); // overwrite
415
-                    self::setOutputStream($out);
416
-                    self::setErrorStream($out);
417
-                    self::$isLogFileUsed = true;
418
-                } catch (IOException $ioe) {
419
-                    $msg = 'Cannot write on the specified log file. Make sure the path exists and you have write permissions.';
420
-
421
-                    throw new ConfigurationException($msg, $ioe);
422
-                }
423
-            } elseif ('-buildfile' == $arg || '-file' == $arg || '-f' == $arg) {
424
-                if (!isset($args[$i + 1])) {
425
-                    $msg = 'You must specify a buildfile when using the -buildfile argument.';
426
-
427
-                    throw new ConfigurationException($msg);
428
-                }
429
-
430
-                $this->buildFile = new File($args[++$i]);
431
-            } elseif ('-listener' == $arg) {
432
-                if (!isset($args[$i + 1])) {
433
-                    $msg = 'You must specify a listener class when using the -listener argument';
434
-
435
-                    throw new ConfigurationException($msg);
436
-                }
437
-
438
-                $this->listeners[] = $args[++$i];
439
-            } elseif (StringHelper::startsWith('-D', $arg)) {
440
-                // Evaluating the property information //
441
-                // Checking whether arg. is not just a switch, and next arg. does not starts with switch identifier
442
-                if (('-D' == $arg) && (!StringHelper::startsWith('-', $args[$i + 1]))) {
443
-                    $name = $args[++$i];
444
-                } else {
445
-                    $name = substr($arg, 2);
446
-                }
447
-
448
-                $value = null;
449
-                $posEq = strpos($name, '=');
450
-                if (false !== $posEq) {
451
-                    $value = substr($name, $posEq + 1);
452
-                    $name = substr($name, 0, $posEq);
453
-                } elseif ($i < count($args) - 1 && !StringHelper::startsWith('-D', $args[$i + 1])) {
454
-                    $value = $args[++$i];
455
-                }
456
-                self::$definedProps->setProperty($name, $value);
457
-            } elseif ('-logger' == $arg) {
458
-                if (!isset($args[$i + 1])) {
459
-                    $msg = 'You must specify a classname when using the -logger argument';
460
-
461
-                    throw new ConfigurationException($msg);
462
-                }
463
-
464
-                $this->loggerClassname = $args[++$i];
465
-            } elseif ('-no-strict' == $arg) {
466
-                $this->strictMode = false;
467
-            } elseif ('-strict' == $arg) {
468
-                $this->strictMode = true;
469
-            } elseif ('-inputhandler' == $arg) {
470
-                if (null !== $this->inputHandlerClassname) {
471
-                    throw new ConfigurationException('Only one input handler class may be specified.');
472
-                }
473
-                if (!isset($args[$i + 1])) {
474
-                    $msg = 'You must specify a classname when using the -inputhandler argument';
475
-
476
-                    throw new ConfigurationException($msg);
477
-                }
478
-
479
-                $this->inputHandlerClassname = $args[++$i];
480
-            } elseif ('-propertyfile' === $arg) {
481
-                $i = $this->handleArgPropertyFile($args, $i);
482
-            } elseif ('-keep-going' === $arg || '-k' === $arg) {
483
-                $this->keepGoingMode = true;
484
-            } elseif ('-longtargets' == $arg) {
485
-                self::$definedProps->setProperty('phing.showlongtargets', 1);
486
-            } elseif ('-projecthelp' == $arg || '-targets' == $arg || '-list' == $arg || '-l' == $arg || '-p' == $arg) {
487
-                // set the flag to display the targets and quit
488
-                $this->projectHelp = true;
489
-            } elseif ('-find' == $arg) {
490
-                // eat up next arg if present, default to build.xml
491
-                if ($i < count($args) - 1) {
492
-                    $this->searchForThis = $args[++$i];
493
-                } else {
494
-                    $this->searchForThis = self::DEFAULT_BUILD_FILENAME;
495
-                }
496
-            } elseif ('-' == substr($arg, 0, 1)) {
497
-                // we don't have any more args
498
-                self::printUsage();
499
-                self::$err->write(PHP_EOL);
500
-
501
-                throw new ConfigurationException('Unknown argument: ' . $arg);
502
-            } else {
503
-                // if it's no other arg, it may be the target
504
-                $this->targets[] = $arg;
505
-            }
506
-        }
507
-
508
-        // if buildFile was not specified on the command line,
509
-        if (null === $this->buildFile) {
510
-            // but -find then search for it
511
-            if (null !== $this->searchForThis) {
512
-                $this->buildFile = $this->findBuildFile(self::getProperty('user.dir'), $this->searchForThis);
513
-            } else {
514
-                $this->buildFile = new File(self::DEFAULT_BUILD_FILENAME);
515
-            }
516
-        }
517
-
518
-        try {
519
-            // make sure buildfile (or buildfile.dist) exists
520
-            if (!$this->buildFile->exists()) {
521
-                $distFile = new File($this->buildFile->getAbsolutePath() . '.dist');
522
-                if (!$distFile->exists()) {
523
-                    throw new ConfigurationException(
524
-                        'Buildfile: ' . $this->buildFile->__toString() . ' does not exist!'
525
-                    );
526
-                }
527
-                $this->buildFile = $distFile;
528
-            }
529
-
530
-            // make sure it's not a directory
531
-            if ($this->buildFile->isDirectory()) {
532
-                throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is a dir!');
533
-            }
534
-        } catch (IOException $e) {
535
-            // something else happened, buildfile probably not readable
536
-            throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is not readable!');
537
-        }
538
-
539
-        $this->loadPropertyFiles();
540
-
541
-        $this->readyToRun = true;
542
-    }
543
-
544
-    /**
545
-     * Prints the usage of how to use this class.
546
-     */
547
-    public static function printUsage()
548
-    {
549
-        $msg = '';
550
-        $msg .= 'phing [options] [target [target2 [target3] ...]]' . PHP_EOL;
551
-        $msg .= 'Options: ' . PHP_EOL;
552
-        $msg .= '  -h -help               print this message' . PHP_EOL;
553
-        $msg .= '  -l -list               list available targets in this project' . PHP_EOL;
554
-        $msg .= '  -i -init [file]        generates an initial buildfile' . PHP_EOL;
555
-        $msg .= '  -v -version            print the version information and exit' . PHP_EOL;
556
-        $msg .= '  -q -quiet              be extra quiet' . PHP_EOL;
557
-        $msg .= '  -S -silent             print nothing but task outputs and build failures' . PHP_EOL;
558
-        $msg .= '  -verbose               be extra verbose' . PHP_EOL;
559
-        $msg .= '  -debug                 print debugging information' . PHP_EOL;
560
-        $msg .= '  -emacs, -e             produce logging information without adornments' . PHP_EOL;
561
-        $msg .= '  -diagnostics           print diagnostics information' . PHP_EOL;
562
-        $msg .= '  -strict                runs build in strict mode, considering a warning as error' . PHP_EOL;
563
-        $msg .= '  -no-strict             runs build normally (overrides buildfile attribute)' . PHP_EOL;
564
-        $msg .= '  -longtargets           show target descriptions during build' . PHP_EOL;
565
-        $msg .= '  -logfile <file>        use given file for log' . PHP_EOL;
566
-        $msg .= '  -logger <classname>    the class which is to perform logging' . PHP_EOL;
567
-        $msg .= '  -listener <classname>  add an instance of class as a project listener' . PHP_EOL;
568
-        $msg .= '  -f -buildfile <file>   use given buildfile' . PHP_EOL;
569
-        $msg .= '  -D<property>=<value>   use value for given property' . PHP_EOL;
570
-        $msg .= '  -keep-going, -k        execute all targets that do not depend' . PHP_EOL;
571
-        $msg .= '                         on failed target(s)' . PHP_EOL;
572
-        $msg .= '  -propertyfile <file>   load all properties from file' . PHP_EOL;
573
-        $msg .= '  -propertyfileoverride  values in property file override existing values' . PHP_EOL;
574
-        $msg .= '  -find <file>           search for buildfile towards the root of the' . PHP_EOL;
575
-        $msg .= '                         filesystem and use it' . PHP_EOL;
576
-        $msg .= '  -inputhandler <file>   the class to use to handle user input' . PHP_EOL;
577
-        //$msg .= "  -recursive <file>      search for buildfile downwards and use it" . PHP_EOL;
578
-        $msg .= PHP_EOL;
579
-        $msg .= 'Report bugs to https://github.com/phingofficial/phing/issues' . PHP_EOL;
580
-        self::$err->write($msg);
581
-    }
582
-
583
-    /**
584
-     * Prints the current Phing version.
585
-     */
586
-    public static function printVersion()
587
-    {
588
-        self::$out->write(self::getPhingVersion() . PHP_EOL);
589
-    }
590
-
591
-    /**
592
-     * Gets the current Phing version based on VERSION.TXT file.
593
-     *
594
-     * @throws ConfigurationException
595
-     */
596
-    public static function getPhingVersion(): string
597
-    {
598
-        $versionPath = self::getResourcePath('phing/etc/VERSION.TXT');
599
-        if (null === $versionPath) {
600
-            $versionPath = self::getResourcePath('etc/VERSION.TXT');
601
-        }
602
-        if (null === $versionPath) {
603
-            throw new ConfigurationException('No VERSION.TXT file found; try setting phing.home environment variable.');
604
-        }
605
-
606
-        try { // try to read file
607
-            $file = new File($versionPath);
608
-            $reader = new FileReader($file);
609
-            $phingVersion = trim($reader->read());
610
-        } catch (IOException $iox) {
611
-            throw new ConfigurationException("Can't read version information file");
612
-        }
613
-
614
-        $basePath = dirname(__DIR__, 2);
615
-
616
-        $version = new Version($phingVersion, $basePath);
617
-
618
-        return 'Phing ' . $version->getVersion();
619
-    }
620
-
621
-    /**
622
-     * Looks on include path for specified file.
623
-     *
624
-     * @param string $path
625
-     *
626
-     * @return null|string file found (null if no file found)
627
-     */
628
-    public static function getResourcePath($path): ?string
629
-    {
630
-        if (null === self::$importPaths) {
631
-            self::$importPaths = self::explodeIncludePath();
632
-        }
633
-
634
-        $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);
635
-
636
-        foreach (self::$importPaths as $prefix) {
637
-            $testPath = $prefix . DIRECTORY_SEPARATOR . $path;
638
-            if (file_exists($testPath)) {
639
-                return $testPath;
640
-            }
641
-        }
642
-
643
-        // Check for the property phing.home
644
-        $homeDir = self::getProperty(self::PHING_HOME);
645
-        if ($homeDir) {
646
-            $testPath = $homeDir . DIRECTORY_SEPARATOR . $path;
647
-            if (file_exists($testPath)) {
648
-                return $testPath;
649
-            }
650
-        }
651
-
652
-        // Check for the phing home of phar archive
653
-        if (0 === strpos(self::$importPaths[0], 'phar://')) {
654
-            $testPath = self::$importPaths[0] . '/../' . $path;
655
-            if (file_exists($testPath)) {
656
-                return $testPath;
657
-            }
658
-        }
659
-
660
-        // Do one additional check based on path of current file (Phing.php)
661
-        $maybeHomeDir = realpath(__DIR__ . DIRECTORY_SEPARATOR);
662
-        $testPath = $maybeHomeDir . DIRECTORY_SEPARATOR . $path;
663
-        if (file_exists($testPath)) {
664
-            return $testPath;
665
-        }
666
-
667
-        return null;
668
-    }
669
-
670
-    /**
671
-     * Explode an include path into an array.
672
-     *
673
-     * If no path provided, uses current include_path. Works around issues that
674
-     * occur when the path includes stream schemas.
675
-     *
676
-     * Pulled from Zend_Loader::explodeIncludePath() in ZF1.
677
-     *
678
-     * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
679
-     * @license   http://framework.zend.com/license/new-bsd New BSD License
680
-     *
681
-     * @param null|string $path
682
-     *
683
-     * @return array
684
-     */
685
-    public static function explodeIncludePath($path = null)
686
-    {
687
-        if (null === $path) {
688
-            $path = get_include_path();
689
-        }
690
-
691
-        if (PATH_SEPARATOR === ':') {
692
-            // On *nix systems, include_paths which include paths with a stream
693
-            // schema cannot be safely explode'd, so we have to be a bit more
694
-            // intelligent in the approach.
695
-            $paths = preg_split('#:(?!//)#', $path);
696
-        } else {
697
-            $paths = explode(PATH_SEPARATOR, $path);
698
-        }
699
-
700
-        return $paths;
701
-    }
702
-
703
-    /**
704
-     * Returns property value for a System property.
705
-     * System properties are "global" properties like application.startdir,
706
-     * and user.dir.  Many of these correspond to similar properties in Java
707
-     * or Ant.
708
-     *
709
-     * @param string $propName
710
-     *
711
-     * @return string value of found property (or null, if none found)
712
-     */
713
-    public static function getProperty($propName)
714
-    {
715
-        // some properties are detemined on each access
716
-        // some are cached, see below
717
-
718
-        // default is the cached value:
719
-        $val = self::$properties[$propName] ?? null;
720
-
721
-        // special exceptions
722
-        switch ($propName) {
723
-            case 'user.dir':
724
-                $val = getcwd();
725
-
726
-                break;
727
-        }
728
-
729
-        return $val;
730
-    }
731
-
732
-    /**
733
-     * Creates generic buildfile.
734
-     *
735
-     * @param string $path
736
-     */
737
-    public static function init($path)
738
-    {
739
-        if ($buildfilePath = self::initPath($path)) {
740
-            self::initWrite($buildfilePath);
741
-        }
742
-    }
743
-
744
-    /**
745
-     * Sets the stream to use for standard (non-error) output.
746
-     *
747
-     * @param OutputStream $stream the stream to use for standard output
748
-     */
749
-    public static function setOutputStream(OutputStream $stream)
750
-    {
751
-        self::$out = $stream;
752
-    }
753
-
754
-    /**
755
-     * Sets the stream to use for error output.
756
-     *
757
-     * @param OutputStream $stream the stream to use for error output
758
-     */
759
-    public static function setErrorStream(OutputStream $stream): void
760
-    {
761
-        self::$err = $stream;
762
-    }
763
-
764
-    /**
765
-     * Making output level a static property so that this property
766
-     * can be accessed by other parts of the system, enabling
767
-     * us to display more information -- e.g. backtraces -- for "debug" level.
768
-     *
769
-     * @return int
770
-     */
771
-    public static function getMsgOutputLevel()
772
-    {
773
-        return self::$msgOutputLevel;
774
-    }
775
-
776
-    /**
777
-     * Prints the message of the Exception if it's not null.
778
-     */
779
-    public static function printMessage(Throwable $t): void
780
-    {
781
-        if (null === self::$err) { // Make sure our error output is initialized
782
-            self::initializeOutputStreams();
783
-        }
784
-        if (self::getMsgOutputLevel() >= Project::MSG_VERBOSE) {
785
-            self::$err->write((string) $t . PHP_EOL);
786
-        } else {
787
-            self::$err->write($t->getMessage() . PHP_EOL);
788
-        }
789
-    }
790
-
791
-    /**
792
-     * Performs any shutdown routines, such as stopping timers.
793
-     *
794
-     * @throws IOException
795
-     */
796
-    public static function shutdown(): void
797
-    {
798
-        FileSystem::getFileSystem()::deleteFilesOnExit();
799
-        self::$msgOutputLevel = Project::MSG_INFO;
800
-        self::restoreIni();
801
-        self::getTimer()->stop();
802
-    }
803
-
804
-    /**
805
-     * Returns reference to DefaultClock object.
806
-     */
807
-    public static function getTimer(): DefaultClock
808
-    {
809
-        if (null === self::$timer) {
810
-            self::$timer = new DefaultClock();
811
-        }
812
-
813
-        return self::$timer;
814
-    }
815
-
816
-    /**
817
-     * This sets a property that was set via command line or otherwise passed into Phing.
818
-     *
819
-     * @param string $name
820
-     * @param mixed  $value
821
-     *
822
-     * @return mixed value of found property (or null, if none found)
823
-     */
824
-    public static function setDefinedProperty($name, $value)
825
-    {
826
-        return self::$definedProps->setProperty($name, $value);
827
-    }
828
-
829
-    /**
830
-     * Executes the build.
831
-     *
832
-     * @throws IOException
833
-     * @throws Throwable
834
-     */
835
-    public function runBuild(): void
836
-    {
837
-        if (!$this->readyToRun) {
838
-            return;
839
-        }
840
-
841
-        $project = new Project();
842
-
843
-        self::setCurrentProject($project);
844
-        set_error_handler(['Phing\Phing', 'handlePhpError']);
845
-
846
-        $error = null;
847
-
848
-        try {
849
-            $this->addBuildListeners($project);
850
-            $this->addInputHandler($project);
851
-
852
-            // set this right away, so that it can be used in logging.
853
-            $project->setUserProperty('phing.file', $this->buildFile->getAbsolutePath());
854
-            $project->setUserProperty('phing.dir', dirname($this->buildFile->getAbsolutePath()));
855
-            $project->setUserProperty('phing.version', static::getPhingVersion());
856
-            $project->fireBuildStarted();
857
-            $project->init();
858
-            $project->setKeepGoingMode($this->keepGoingMode);
859
-
860
-            $e = self::$definedProps->keys();
861
-            while (count($e)) {
862
-                $arg = (string) array_shift($e);
863
-                $value = (string) self::$definedProps->getProperty($arg);
864
-                $project->setUserProperty($arg, $value);
865
-            }
866
-            unset($e);
867
-
868
-            // first use the Configurator to create the project object
869
-            // from the given build file.
870
-
871
-            ProjectConfigurator::configureProject($project, $this->buildFile);
872
-
873
-            // Set the project mode
874
-            $project->setStrictMode(StringHelper::booleanValue($this->strictMode));
875
-
876
-            // make sure that minimum required phing version is satisfied
877
-            $this->comparePhingVersion($project->getPhingVersion());
878
-
879
-            if ($this->projectHelp) {
880
-                $this->printDescription($project);
881
-                $this->printTargets($project);
882
-
883
-                return;
884
-            }
885
-
886
-            // make sure that we have a target to execute
887
-            if (0 === count($this->targets)) {
888
-                $this->targets[] = $project->getDefaultTarget();
889
-            }
890
-
891
-            $project->executeTargets($this->targets);
892
-        } catch (Throwable $t) {
893
-            $error = $t;
894
-
895
-            throw $t;
896
-        } finally {
897
-            if (!$this->projectHelp) {
898
-                try {
899
-                    $project->fireBuildFinished($error);
900
-                } catch (Exception $e) {
901
-                    self::$err->write('Caught an exception while logging the end of the build.  Exception was:' . PHP_EOL);
902
-                    self::$err->write($e->getTraceAsString());
903
-                    if (null !== $error) {
904
-                        self::$err->write('There has been an error prior to that:' . PHP_EOL);
905
-                        self::$err->write($error->getTraceAsString());
906
-                    }
907
-
908
-                    throw new BuildException($error);
909
-                }
910
-            } elseif (null !== $error) {
911
-                $project->log($error->getMessage(), Project::MSG_ERR);
912
-            }
913
-
914
-            restore_error_handler();
915
-            self::unsetCurrentProject();
916
-        }
917
-    }
918
-
919
-    /**
920
-     * Import a class, supporting the following conventions:
921
-     * - PEAR style (@see http://pear.php.net/manual/en/standards.naming.php)
922
-     * - PSR-0 (@see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
923
-     *
924
-     * @param string $classname Name of class
925
-     * @param mixed  $classpath String or object supporting __toString()
926
-     *
927
-     * @throws BuildException - if cannot find the specified file
928
-     *
929
-     * @return string the unqualified classname (which can be instantiated)
930
-     */
931
-    public static function import($classname, $classpath = null)
932
-    {
933
-        // first check to see that the class specified hasn't already been included.
934
-        if (class_exists($classname)) {
935
-            return $classname;
936
-        }
937
-
938
-        $filename = strtr($classname, ['_' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR]) . '.php';
939
-
940
-        Phing::importFile($filename, $classpath);
941
-
942
-        return $classname;
943
-    }
944
-
945
-    /**
946
-     * Import a PHP file.
947
-     *
948
-     * This used to be named __import, however PHP has reserved all method names
949
-     * with a double underscore prefix for future use.
950
-     *
951
-     * @param string $path      Path to the PHP file
952
-     * @param mixed  $classpath String or object supporting __toString()
953
-     *
954
-     * @throws ConfigurationException
955
-     */
956
-    public static function importFile($path, $classpath = null)
957
-    {
958
-        if ($classpath) {
959
-            // Apparently casting to (string) no longer invokes __toString() automatically.
960
-            if (is_object($classpath)) {
961
-                $classpath = $classpath->__toString();
962
-            }
963
-
964
-            // classpaths are currently additive, but we also don't want to just
965
-            // indiscriminantly prepand/append stuff to the include_path.  This means
966
-            // we need to parse current incldue_path, and prepend any
967
-            // specified classpath locations that are not already in the include_path.
968
-            //
969
-            // NOTE:  the reason why we do it this way instead of just changing include_path
970
-            // and then changing it back, is that in many cases applications (e.g. Propel) will
971
-            // include/require class files from within method calls.  This means that not all
972
-            // necessary files will be included in this import() call, and hence we can't
973
-            // change the include_path back without breaking those apps.  While this method could
974
-            // be more expensive than switching & switching back (not sure, but maybe), it makes it
975
-            // possible to write far less expensive run-time applications (e.g. using Propel), which is
976
-            // really where speed matters more.
977
-
978
-            $curr_parts = Phing::explodeIncludePath();
979
-            $add_parts = Phing::explodeIncludePath($classpath);
980
-            $new_parts = array_diff($add_parts, $curr_parts);
981
-            if ($new_parts) {
982
-                set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
983
-            }
984
-        }
985
-
986
-        $ret = include_once $path;
987
-
988
-        if (false === $ret) {
989
-            $msg = "Error importing {$path}";
990
-            if (self::getMsgOutputLevel() >= Project::MSG_DEBUG) {
991
-                $x = new Exception('for-path-trace-only');
992
-                $msg .= $x->getTraceAsString();
993
-            }
994
-
995
-            throw new ConfigurationException($msg);
996
-        }
997
-    }
998
-
999
-    /**
1000
-     * Print the project description, if any.
1001
-     *
1002
-     * @throws IOException
1003
-     */
1004
-    public function printDescription(Project $project): void
1005
-    {
1006
-        if (null !== $project->getDescription()) {
1007
-            $project->log($project->getDescription());
1008
-        }
1009
-    }
1010
-
1011
-    /**
1012
-     * Print out a list of all targets in the current buildfile.
1013
-     */
1014
-    public function printTargets(Project $project)
1015
-    {
1016
-        $visibleTargets = array_filter($project->getTargets(), function (Target $target) {
1017
-            return !$target->isHidden() && !empty($target->getName());
1018
-        });
1019
-        $padding = array_reduce($visibleTargets, function (int $carry, Target $target) {
1020
-            return max(strlen($target->getName()), $carry);
1021
-        }, 0);
1022
-        $categories = [
1023
-            'Default target:' => array_filter($visibleTargets, function (Target $target) use ($project) {
1024
-                return trim(strval($target)) === $project->getDefaultTarget();
1025
-            }),
1026
-            'Main targets:' => array_filter($visibleTargets, function (Target $target) {
1027
-                return !empty($target->getDescription());
1028
-            }),
1029
-            'Subtargets:' => array_filter($visibleTargets, function (Target $target) {
1030
-                return empty($target->getDescription());
1031
-            }),
1032
-        ];
1033
-        foreach ($categories as $title => $targets) {
1034
-            $targetList = $this->generateTargetList($title, $targets, $padding);
1035
-            $project->log($targetList, Project::MSG_WARN);
1036
-        }
1037
-    }
1038
-
1039
-    /**
1040
-     * Unsets the current Project.
1041
-     */
1042
-    public static function unsetCurrentProject(): void
1043
-    {
1044
-        self::$currentProject = null;
1045
-    }
1046
-
1047
-    /**
1048
-     * Error handler for PHP errors encountered during the build.
1049
-     * This uses the logging for the currently configured project.
1050
-     *
1051
-     * @param $level
1052
-     * @param string $message
1053
-     * @param $file
1054
-     * @param $line
1055
-     */
1056
-    public static function handlePhpError($level, $message, $file, $line)
1057
-    {
1058
-        // don't want to print suppressed errors
1059
-        if (error_reporting() > 0) {
1060
-            if (self::$phpErrorCapture) {
1061
-                self::$capturedPhpErrors[] = [
1062
-                    'message' => $message,
1063
-                    'level' => $level,
1064
-                    'line' => $line,
1065
-                    'file' => $file,
1066
-                ];
1067
-            } else {
1068
-                $message = '[PHP Error] ' . $message;
1069
-                $message .= ' [line ' . $line . ' of ' . $file . ']';
1070
-
1071
-                switch ($level) {
1072
-                    case E_USER_DEPRECATED:
1073
-                    case E_DEPRECATED:
1074
-                    case E_STRICT:
1075
-                    case E_NOTICE:
1076
-                    case E_USER_NOTICE:
1077
-                        self::log($message, Project::MSG_VERBOSE);
1078
-
1079
-                        break;
1080
-
1081
-                    case E_WARNING:
1082
-                    case E_USER_WARNING:
1083
-                        self::log($message, Project::MSG_WARN);
1084
-
1085
-                        break;
1086
-
1087
-                    case E_ERROR:
1088
-                    case E_USER_ERROR:
1089
-                    default:
1090
-                        self::log($message, Project::MSG_ERR);
1091
-                } // switch
1092
-            } // if phpErrorCapture
1093
-        } // if not @
1094
-    }
1095
-
1096
-    /**
1097
-     * A static convenience method to send a log to the current (last-setup) Project.
1098
-     * If there is no currently-configured Project, then this will do nothing.
1099
-     *
1100
-     * @param string $message
1101
-     * @param int    $priority project::MSG_INFO, etc
1102
-     */
1103
-    public static function log($message, $priority = Project::MSG_INFO): void
1104
-    {
1105
-        $p = self::getCurrentProject();
1106
-        if ($p) {
1107
-            $p->log($message, $priority);
1108
-        }
1109
-    }
1110
-
1111
-    /**
1112
-     * Gets the current Project.
1113
-     *
1114
-     * @return Project current Project or NULL if none is set yet/still
1115
-     */
1116
-    public static function getCurrentProject()
1117
-    {
1118
-        return self::$currentProject;
1119
-    }
1120
-
1121
-    /**
1122
-     * Sets the current Project.
1123
-     *
1124
-     * @param Project $p
1125
-     */
1126
-    public static function setCurrentProject($p): void
1127
-    {
1128
-        self::$currentProject = $p;
1129
-    }
1130
-
1131
-    /**
1132
-     * Begins capturing PHP errors to a buffer.
1133
-     * While errors are being captured, they are not logged.
1134
-     */
1135
-    public static function startPhpErrorCapture(): void
1136
-    {
1137
-        self::$phpErrorCapture = true;
1138
-        self::$capturedPhpErrors = [];
1139
-    }
1140
-
1141
-    /**
1142
-     * Stops capturing PHP errors to a buffer.
1143
-     * The errors will once again be logged after calling this method.
1144
-     */
1145
-    public static function stopPhpErrorCapture(): void
1146
-    {
1147
-        self::$phpErrorCapture = false;
1148
-    }
1149
-
1150
-    /**
1151
-     * Clears the captured errors without affecting the starting/stopping of the capture.
1152
-     */
1153
-    public static function clearCapturedPhpErrors(): void
1154
-    {
1155
-        self::$capturedPhpErrors = [];
1156
-    }
1157
-
1158
-    /**
1159
-     * Gets any PHP errors that were captured to buffer.
1160
-     *
1161
-     * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level)
1162
-     */
1163
-    public static function getCapturedPhpErrors()
1164
-    {
1165
-        return self::$capturedPhpErrors;
1166
-    }
1167
-
1168
-    /**
1169
-     * This gets a property that was set via command line or otherwise passed into Phing.
1170
-     * "Defined" in this case means "externally defined".  The reason this method exists is to
1171
-     * provide a public means of accessing commandline properties for (e.g.) logger or listener
1172
-     * scripts.  E.g. to specify which logfile to use, PearLogger needs to be able to access
1173
-     * the pear.log.name property.
1174
-     *
1175
-     * @param string $name
1176
-     *
1177
-     * @return string value of found property (or null, if none found)
1178
-     */
1179
-    public static function getDefinedProperty($name)
1180
-    {
1181
-        return self::$definedProps->getProperty($name);
1182
-    }
1183
-
1184
-    /**
1185
-     * Retuns reference to all properties.
1186
-     */
1187
-    public static function &getProperties()
1188
-    {
1189
-        return self::$properties;
1190
-    }
1191
-
1192
-    /**
1193
-     * Start up Phing.
1194
-     * Sets up the Phing environment but does not initiate the build process.
1195
-     *
1196
-     * @throws exception - If the Phing environment cannot be initialized
1197
-     */
1198
-    public static function startup(): void
1199
-    {
1200
-        // setup STDOUT and STDERR defaults
1201
-        self::initializeOutputStreams();
1202
-
1203
-        // some init stuff
1204
-        self::getTimer()->start();
1205
-
1206
-        self::setSystemConstants();
1207
-        self::setIncludePaths();
1208
-        self::setIni();
1209
-    }
1210
-
1211
-    /**
1212
-     * @param $propName
1213
-     * @param $propValue
1214
-     *
1215
-     * @return string
1216
-     */
1217
-    public static function setProperty($propName, $propValue)
1218
-    {
1219
-        $propName = (string) $propName;
1220
-        $oldValue = self::getProperty($propName);
1221
-        self::$properties[$propName] = $propValue;
1222
-
1223
-        return $oldValue;
1224
-    }
1225
-
1226
-    /**
1227
-     * Returns buildfile's path.
1228
-     *
1229
-     * @param $path
1230
-     *
1231
-     * @throws ConfigurationException
1232
-     *
1233
-     * @return string
1234
-     */
1235
-    protected static function initPath($path)
1236
-    {
1237
-        // Fallback
1238
-        if (empty($path)) {
1239
-            $defaultDir = self::getProperty('application.startdir');
1240
-            $path = $defaultDir . DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1241
-        }
1242
-
1243
-        // Adding filename if necessary
1244
-        if (is_dir($path)) {
1245
-            $path .= DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1246
-        }
1247
-
1248
-        // Check if path is available
1249
-        $dirname = dirname($path);
1250
-        if (is_dir($dirname) && !is_file($path)) {
1251
-            return $path;
1252
-        }
1253
-
1254
-        // Path is valid, but buildfile already exists
1255
-        if (is_file($path)) {
1256
-            throw new ConfigurationException('Buildfile already exists.');
1257
-        }
1258
-
1259
-        throw new ConfigurationException('Invalid path for sample buildfile.');
1260
-    }
1261
-
1262
-    /**
1263
-     * Writes sample buildfile.
1264
-     *
1265
-     * If $buildfilePath does not exist, the buildfile is created.
1266
-     *
1267
-     * @param $buildfilePath buildfile's location
1268
-     *
1269
-     * @throws ConfigurationException
1270
-     */
1271
-    protected static function initWrite($buildfilePath): void
1272
-    {
1273
-        // Overwriting protection
1274
-        if (file_exists($buildfilePath)) {
1275
-            throw new ConfigurationException('Cannot overwrite existing file.');
1276
-        }
1277
-
1278
-        file_put_contents($buildfilePath, self::DEFAULT_BUILD_CONTENT);
1279
-    }
1280
-
1281
-    /**
1282
-     * This operation is expected to call `exit($int)`, which
1283
-     * is what the base version does.
1284
-     * However, it is possible to do something else.
1285
-     *
1286
-     * @param int $exitCode code to exit with
1287
-     */
1288
-    protected static function statusExit($exitCode): void
1289
-    {
1290
-        Phing::shutdown();
1291
-
1292
-        exit($exitCode);
1293
-    }
1294
-
1295
-    /**
1296
-     * Handle the -propertyfile argument.
1297
-     *
1298
-     * @throws ConfigurationException
1299
-     * @throws IOException
1300
-     */
1301
-    private function handleArgPropertyFile(array $args, int $pos): int
1302
-    {
1303
-        if (!isset($args[$pos + 1])) {
1304
-            throw new ConfigurationException('You must specify a filename when using the -propertyfile argument');
1305
-        }
1306
-
1307
-        $this->propertyFiles[] = $args[++$pos];
1308
-
1309
-        return $pos;
1310
-    }
1311
-
1312
-    /**
1313
-     * Search parent directories for the build file.
1314
-     *
1315
-     * Takes the given target as a suffix to append to each
1316
-     * parent directory in search of a build file.  Once the
1317
-     * root of the file-system has been reached an exception
1318
-     * is thrown.
1319
-     *
1320
-     * @param string $start  start file path
1321
-     * @param string $suffix suffix filename to look for in parents
1322
-     *
1323
-     * @throws ConfigurationException
1324
-     *
1325
-     * @return File A handle to the build file
1326
-     */
1327
-    private function findBuildFile($start, $suffix)
1328
-    {
1329
-        if (self::getMsgOutputLevel() >= Project::MSG_INFO) {
1330
-            self::$out->write('Searching for ' . $suffix . ' ...' . PHP_EOL);
1331
-        }
1332
-
1333
-        $parent = new File((new File($start))->getAbsolutePath());
1334
-        $file = new File($parent, $suffix);
1335
-
1336
-        // check if the target file exists in the current directory
1337
-        while (!$file->exists()) {
1338
-            // change to parent directory
1339
-            $parent = $parent->getParentFile();
1340
-
1341
-            // if parent is null, then we are at the root of the fs,
1342
-            // complain that we can't find the build file.
1343
-            if (null === $parent) {
1344
-                throw new ConfigurationException('Could not locate a build file!');
1345
-            }
1346
-            // refresh our file handle
1347
-            $file = new File($parent, $suffix);
1348
-        }
1349
-
1350
-        return $file;
1351
-    }
1352
-
1353
-    /**
1354
-     * @throws IOException
1355
-     */
1356
-    private function loadPropertyFiles(): void
1357
-    {
1358
-        foreach ($this->propertyFiles as $filename) {
1359
-            $fileParserFactory = new FileParserFactory();
1360
-            $fileParser = $fileParserFactory->createParser(pathinfo($filename, PATHINFO_EXTENSION));
1361
-            $p = new Properties(null, $fileParser);
1362
-
1363
-            try {
1364
-                $p->load(new File($filename));
1365
-            } catch (IOException $e) {
1366
-                self::$out->write('Could not load property file ' . $filename . ': ' . $e->getMessage());
1367
-            }
1368
-            foreach ($p->getProperties() as $prop => $value) {
1369
-                self::$definedProps->setProperty($prop, $value);
1370
-            }
1371
-        }
1372
-    }
1373
-
1374
-    /**
1375
-     * Close logfiles, if we have been writing to them.
1376
-     *
1377
-     * @since Phing 2.3.0
1378
-     */
1379
-    private static function handleLogfile(): void
1380
-    {
1381
-        if (self::$isLogFileUsed) {
1382
-            self::$err->close();
1383
-            self::$out->close();
1384
-        }
1385
-    }
1386
-
1387
-    /**
1388
-     * Sets the stdout and stderr streams if they are not already set.
1389
-     */
1390
-    private static function initializeOutputStreams()
1391
-    {
1392
-        if (null === self::$out) {
1393
-            if (!defined('STDOUT')) {
1394
-                self::$out = new OutputStream(fopen('php://stdout', 'w'));
1395
-            } else {
1396
-                self::$out = new OutputStream(STDOUT);
1397
-            }
1398
-        }
1399
-        if (null === self::$err) {
1400
-            if (!defined('STDERR')) {
1401
-                self::$err = new OutputStream(fopen('php://stderr', 'w'));
1402
-            } else {
1403
-                self::$err = new OutputStream(STDERR);
1404
-            }
1405
-        }
1406
-    }
1407
-
1408
-    /**
1409
-     * Restores [most] PHP INI values to their pre-Phing state.
1410
-     *
1411
-     * Currently the following settings are not restored:
1412
-     *  - max_execution_time (because getting current time limit is not possible)
1413
-     *  - memory_limit (which may have been increased by Phing)
1414
-     */
1415
-    private static function restoreIni(): void
1416
-    {
1417
-        foreach (self::$origIniSettings as $settingName => $settingValue) {
1418
-            switch ($settingName) {
1419
-                case 'error_reporting':
1420
-                    error_reporting($settingValue);
1421
-
1422
-                    break;
1423
-
1424
-                default:
1425
-                    ini_set($settingName, $settingValue);
1426
-            }
1427
-        }
1428
-    }
1429
-
1430
-    /**
1431
-     * Bind any registered build listeners to this project.
1432
-     *
1433
-     * This means adding the logger and any build listeners that were specified
1434
-     * with -listener arg.
1435
-     *
1436
-     * @throws BuildException
1437
-     * @throws ConfigurationException
1438
-     */
1439
-    private function addBuildListeners(Project $project)
1440
-    {
1441
-        // Add the default listener
1442
-        $project->addBuildListener($this->createLogger());
1443
-
1444
-        foreach ($this->listeners as $listenerClassname) {
1445
-            try {
1446
-                $clz = Phing::import($listenerClassname);
1447
-            } catch (Exception $e) {
1448
-                $msg = 'Unable to instantiate specified listener '
1449
-                    . 'class ' . $listenerClassname . ' : '
1450
-                    . $e->getMessage();
1451
-
1452
-                throw new ConfigurationException($msg);
1453
-            }
1454
-
1455
-            $listener = new $clz();
1456
-
1457
-            if ($listener instanceof StreamRequiredBuildLogger) {
1458
-                throw new ConfigurationException('Unable to add ' . $listenerClassname . ' as a listener, since it requires explicit error/output streams. (You can specify it as a -logger.)');
1459
-            }
1460
-            $project->addBuildListener($listener);
1461
-        }
1462
-    }
1463
-
1464
-    /**
1465
-     * Creates the default build logger for sending build events to the log.
1466
-     *
1467
-     * @throws BuildException
1468
-     *
1469
-     * @return BuildLogger The created Logger
1470
-     */
1471
-    private function createLogger()
1472
-    {
1473
-        if ($this->silent) {
1474
-            $logger = new SilentLogger();
1475
-            self::$msgOutputLevel = Project::MSG_WARN;
1476
-        } elseif (null !== $this->loggerClassname) {
1477
-            self::import($this->loggerClassname);
1478
-            // get class name part
1479
-            $classname = self::import($this->loggerClassname);
1480
-            $logger = new $classname();
1481
-            if (!($logger instanceof BuildLogger)) {
1482
-                throw new BuildException($classname . ' does not implement the BuildLogger interface.');
1483
-            }
1484
-        } else {
1485
-            $logger = new DefaultLogger();
1486
-        }
1487
-        $logger->setMessageOutputLevel(self::$msgOutputLevel);
1488
-        $logger->setOutputStream(self::$out);
1489
-        $logger->setErrorStream(self::$err);
1490
-        $logger->setEmacsMode($this->emacsMode);
1491
-
1492
-        return $logger;
1493
-    }
1494
-
1495
-    /**
1496
-     * Creates the InputHandler and adds it to the project.
1497
-     *
1498
-     * @param Project $project the project instance
1499
-     *
1500
-     * @throws ConfigurationException
1501
-     */
1502
-    private function addInputHandler(Project $project): void
1503
-    {
1504
-        if (null === $this->inputHandlerClassname) {
1505
-            $handler = new ConsoleInputHandler(STDIN, new ConsoleOutput());
1506
-        } else {
1507
-            try {
1508
-                $clz = Phing::import($this->inputHandlerClassname);
1509
-                $handler = new $clz();
1510
-                if (null !== $project && method_exists($handler, 'setProject')) {
1511
-                    $handler->setProject($project);
1512
-                }
1513
-            } catch (Exception $e) {
1514
-                $msg = 'Unable to instantiate specified input handler '
1515
-                    . 'class ' . $this->inputHandlerClassname . ' : '
1516
-                    . $e->getMessage();
1517
-
1518
-                throw new ConfigurationException($msg);
1519
-            }
1520
-        }
1521
-        $project->setInputHandler($handler);
1522
-    }
1523
-
1524
-    /**
1525
-     * @param string $version
1526
-     *
1527
-     * @throws BuildException
1528
-     * @throws ConfigurationException
1529
-     */
1530
-    private function comparePhingVersion($version): void
1531
-    {
1532
-        $current = strtolower(self::getPhingVersion());
1533
-        $current = trim(str_replace('phing', '', $current));
1534
-
1535
-        // make sure that version checks are not applied to trunk
1536
-        if ('dev' === $current) {
1537
-            return;
1538
-        }
1539
-
1540
-        if (-1 == version_compare($current, $version)) {
1541
-            throw new BuildException(
1542
-                sprintf('Incompatible Phing version (%s). Version "%s" required.', $current, $version)
1543
-            );
1544
-        }
1545
-    }
1546
-
1547
-    /**
1548
-     * Returns a formatted list of target names with an optional description.
1549
-     *
1550
-     * @param string   $title   Title for this list
1551
-     * @param Target[] $targets Targets in this list
1552
-     * @param int      $padding Padding for name column
1553
-     */
1554
-    private function generateTargetList(string $title, array $targets, int $padding): string
1555
-    {
1556
-        usort($targets, function (Target $a, Target $b) {
1557
-            return $a->getName() <=> $b->getName();
1558
-        });
1559
-
1560
-        $header = <<<HEADER
1561
-            {$title}
1562
-            -------------------------------------------------------------------------------
1563
-
1564
-            HEADER;
1565
-
1566
-        $getDetails = function (Target $target) use ($padding): string {
1567
-            $details = [];
1568
-            if (!empty($target->getDescription())) {
1569
-                $details[] = $target->getDescription();
1570
-            }
1571
-            if (!empty($target->getDependencies())) {
1572
-                $details[] = ' - depends on: ' . implode(', ', $target->getDependencies());
1573
-            }
1574
-            if (!empty($target->getIf())) {
1575
-                $details[] = ' - if property: ' . $target->getIf();
1576
-            }
1577
-            if (!empty($target->getUnless())) {
1578
-                $details[] = ' - unless property: ' . $target->getUnless();
1579
-            }
1580
-            $detailsToString = function (?string $name, ?string $detail) use ($padding): string {
1581
-                return sprintf(" %-{$padding}s  %s", $name, $detail);
1582
-            };
1583
-
1584
-            return implode(PHP_EOL, array_map($detailsToString, [$target->getName()], $details));
1585
-        };
1586
-
1587
-        return $header . implode(PHP_EOL, array_map($getDetails, $targets)) . PHP_EOL;
1588
-    }
1589
-
1590
-    /**
1591
-     * Set System constants which can be retrieved by calling Phing::getProperty($propName).
1592
-     */
1593
-    private static function setSystemConstants(): void
1594
-    {
1595
-        /*
1596
-         * PHP_OS returns on
1597
-         *   WindowsNT4.0sp6  => WINNT
1598
-         *   Windows2000      => WINNT
1599
-         *   Windows ME       => WIN32
1600
-         *   Windows 98SE     => WIN32
1601
-         *   FreeBSD 4.5p7    => FreeBSD
1602
-         *   Redhat Linux     => Linux
1603
-         *   Mac OS X         => Darwin
1604
-         */
1605
-        self::setProperty('host.os', PHP_OS);
1606
-
1607
-        // this is used by some tasks too
1608
-        self::setProperty('os.name', PHP_OS);
1609
-
1610
-        // it's still possible this won't be defined,
1611
-        // e.g. if Phing is being included in another app w/o
1612
-        // using the phing.php script.
1613
-        if (!defined('PHP_CLASSPATH')) {
1614
-            define('PHP_CLASSPATH', get_include_path());
1615
-        }
1616
-
1617
-        self::setProperty('php.classpath', PHP_CLASSPATH);
1618
-
1619
-        // try to determine the host filesystem and set system property
1620
-        // used by Fileself::getFileSystem to instantiate the correct
1621
-        // abstraction layer
1622
-
1623
-        if (PHP_OS_FAMILY === 'Windows') {
1624
-            self::setProperty('host.fstype', 'WINDOWS');
1625
-            self::setProperty('user.home', getenv('HOMEDRIVE') . getenv('HOMEPATH'));
1626
-        } else {
1627
-            self::setProperty('host.fstype', 'UNIX');
1628
-            self::setProperty('user.home', getenv('HOME'));
1629
-        }
1630
-        self::setProperty(self::PHP_INTERPRETER, PHP_BINARY);
1631
-        self::setProperty('file.separator', FileUtils::getSeparator());
1632
-        self::setProperty('line.separator', PHP_EOL);
1633
-        self::setProperty('path.separator', FileUtils::getPathSeparator());
1634
-        self::setProperty(self::PHP_VERSION, PHP_VERSION);
1635
-        self::setProperty('php.tmpdir', sys_get_temp_dir());
1636
-        self::setProperty('application.startdir', getcwd());
1637
-        self::setProperty('phing.startTime', gmdate('D, d M Y H:i:s', time()) . ' GMT');
1638
-
1639
-        // try to detect machine dependent information
1640
-        $sysInfo = [];
1641
-        if (function_exists('posix_uname') && 0 !== stripos(PHP_OS, 'WIN')) {
1642
-            $sysInfo = posix_uname();
1643
-        } else {
1644
-            $sysInfo['nodename'] = php_uname('n');
1645
-            $sysInfo['machine'] = php_uname('m');
1646
-            //this is a not so ideal substition, but maybe better than nothing
1647
-            $sysInfo['domain'] = $_SERVER['SERVER_NAME'] ?? 'unknown';
1648
-            $sysInfo['release'] = php_uname('r');
1649
-            $sysInfo['version'] = php_uname('v');
1650
-        }
1651
-
1652
-        self::setProperty('host.name', $sysInfo['nodename'] ?? 'unknown');
1653
-        self::setProperty('host.arch', $sysInfo['machine'] ?? 'unknown');
1654
-        self::setProperty('host.domain', $sysInfo['domain'] ?? 'unknown');
1655
-        self::setProperty('host.os.release', $sysInfo['release'] ?? 'unknown');
1656
-        self::setProperty('host.os.version', $sysInfo['version'] ?? 'unknown');
1657
-        unset($sysInfo);
1658
-    }
1659
-
1660
-    /**
1661
-     * Sets the include path to PHP_CLASSPATH constant (if this has been defined).
1662
-     *
1663
-     * @throws ConfigurationException - if the include_path could not be set (for some bizarre reason)
1664
-     */
1665
-    private static function setIncludePaths(): void
1666
-    {
1667
-        if (defined('PHP_CLASSPATH')) {
1668
-            $result = set_include_path(PHP_CLASSPATH);
1669
-            if (false === $result) {
1670
-                throw new ConfigurationException('Could not set PHP include_path.');
1671
-            }
1672
-            self::$origIniSettings['include_path'] = $result; // save original value for setting back later
1673
-        }
1674
-    }
1675
-
1676
-    /**
1677
-     * Sets PHP INI values that Phing needs.
1678
-     */
1679
-    private static function setIni(): void
1680
-    {
1681
-        self::$origIniSettings['error_reporting'] = error_reporting(E_ALL);
1682
-
1683
-        // We won't bother storing original max_execution_time, since 1) the value in
1684
-        // php.ini may be wrong (and there's no way to get the current value) and
1685
-        // 2) it would mean something very strange to set it to a value less than time script
1686
-        // has already been running, which would be the likely change.
1687
-
1688
-        set_time_limit(0);
1689
-
1690
-        self::$origIniSettings['short_open_tag'] = ini_set('short_open_tag', 'off');
1691
-        self::$origIniSettings['default_charset'] = ini_set('default_charset', 'iso-8859-1');
1692
-
1693
-        $mem_limit = (int) SizeHelper::fromHumanToBytes(ini_get('memory_limit'));
1694
-        if ($mem_limit < (32 * 1024 * 1024) && $mem_limit > -1) {
1695
-            // We do *not* need to save the original value here, since we don't plan to restore
1696
-            // this after shutdown (we don't trust the effectiveness of PHP's garbage collection).
1697
-            ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects
1698
-        }
1699
-    }
1700
-}
Please login to merge, or discard this patch.
Upper-Lower-Casing   -1615 removed lines patch added patch discarded remove patch
@@ -83,1618 +83,3 @@
 block discarded – undo
83 83
      */
84 84
     public const DEFAULT_BUILD_FILENAME = 'build.xml';
85 85
     public const DEFAULT_BUILD_CONTENT = <<<'XML'
86
-        <?xml version="1.0" encoding="UTF-8" ?>
87
-
88
-        <project name="" description="" default="">
89
-            
90
-            <target name="" description="">
91
-                
92
-            </target>
93
-            
94
-        </project>
95
-        XML;
96
-    public const PHING_HOME = 'phing.home';
97
-    public const PHP_VERSION = 'php.version';
98
-    public const PHP_INTERPRETER = 'php.interpreter';
99
-
100
-    /**
101
-     * Our current message output status. Follows Project::MSG_XXX.
102
-     */
103
-    private static $msgOutputLevel = Project::MSG_INFO;
104
-    /**
105
-     * Set of properties that are passed in from commandline or invoking code.
106
-     *
107
-     * @var Properties
108
-     */
109
-    private static $definedProps;
110
-    /**
111
-     * Used by utility function getResourcePath().
112
-     */
113
-    private static $importPaths;
114
-    /**
115
-     * System-wide static properties (moved from System).
116
-     */
117
-    private static $properties = [];
118
-    /**
119
-     * Static system timer.
120
-     */
121
-    private static $timer;
122
-    /**
123
-     * The current Project.
124
-     */
125
-    private static $currentProject;
126
-    /**
127
-     * Whether to capture PHP errors to buffer.
128
-     */
129
-    private static $phpErrorCapture = false;
130
-    /**
131
-     * Array of captured PHP errors.
132
-     */
133
-    private static $capturedPhpErrors = [];
134
-    /**
135
-     * @var OUtputStream stream for standard output
136
-     */
137
-    private static $out;
138
-    /**
139
-     * @var OutputStream stream for error output
140
-     */
141
-    private static $err;
142
-    /**
143
-     * @var bool whether we are using a logfile
144
-     */
145
-    private static $isLogFileUsed = false;
146
-    /**
147
-     * Array to hold original ini settings that Phing changes (and needs
148
-     * to restore in restoreIni() method).
149
-     *
150
-     * @var array Struct of array(setting-name => setting-value)
151
-     *
152
-     * @see restoreIni()
153
-     */
154
-    private static $origIniSettings = [];
155
-    /**
156
-     * PhingFile that we are using for configuration.
157
-     */
158
-    private $buildFile;
159
-    /**
160
-     * The build targets.
161
-     */
162
-    private $targets = [];
163
-    /**
164
-     * Names of classes to add as listeners to project.
165
-     */
166
-    private $listeners = [];
167
-    /**
168
-     * keep going mode.
169
-     *
170
-     * @var bool
171
-     */
172
-    private $keepGoingMode = false;
173
-    private $loggerClassname;
174
-    /**
175
-     * The class to handle input (can be only one).
176
-     */
177
-    private $inputHandlerClassname;
178
-    /**
179
-     * Whether or not log output should be reduced to the minimum.
180
-     *
181
-     * @var bool
182
-     */
183
-    private $silent = false;
184
-    /**
185
-     * Indicates whether phing should run in strict mode.
186
-     */
187
-    private $strictMode = false;
188
-    /**
189
-     * Indicates if this phing should be run.
190
-     */
191
-    private $readyToRun = false;
192
-    /**
193
-     * Indicates we should only parse and display the project help information.
194
-     */
195
-    private $projectHelp = false;
196
-    /**
197
-     * Whether to values in a property file should override existing values.
198
-     */
199
-    private $propertyFileOverride = false;
200
-    /**
201
-     * Whether or not output to the log is to be unadorned.
202
-     */
203
-    private $emacsMode = false;
204
-
205
-    /**
206
-     * @var string
207
-     */
208
-    private $searchForThis;
209
-    private $propertyFiles = [];
210
-
211
-    /**
212
-     * Gets the stream to use for standard (non-error) output.
213
-     *
214
-     * @return OutputStream
215
-     */
216
-    public static function getOutputStream()
217
-    {
218
-        return self::$out;
219
-    }
220
-
221
-    /**
222
-     * Gets the stream to use for error output.
223
-     *
224
-     * @return OutputStream
225
-     */
226
-    public static function getErrorStream()
227
-    {
228
-        return self::$err;
229
-    }
230
-
231
-    /**
232
-     * Command line entry point. This method kicks off the building
233
-     * of a project object and executes a build using either a given
234
-     * target or the default target.
235
-     *
236
-     * @param array $args command line args
237
-     *
238
-     * @throws Exception
239
-     */
240
-    public static function fire($args): void
241
-    {
242
-        self::start($args);
243
-    }
244
-
245
-    /**
246
-     * Entry point allowing for more options from other front ends.
247
-     *
248
-     * This method encapsulates the complete build lifecycle.
249
-     *
250
-     * @param array $args                     the commandline args passed to phing shell script
251
-     * @param array $additionalUserProperties Any additional properties to be passed to Phing (alternative front-end might implement this).
252
-     *                                        These additional properties will be available using the getDefinedProperty() method and will
253
-     *                                        be added to the project's "user" properties
254
-     *
255
-     * @throws Exception - if there is an error during build
256
-     *
257
-     * @see    runBuild()
258
-     * @see    execute()
259
-     */
260
-    public static function start($args, array $additionalUserProperties = null)
261
-    {
262
-        try {
263
-            $m = new self();
264
-            $m->execute($args);
265
-        } catch (Exception $exc) {
266
-            self::handleLogfile();
267
-            self::printMessage($exc);
268
-            self::statusExit(1);
269
-
270
-            return;
271
-        }
272
-
273
-        if (null !== $additionalUserProperties) {
274
-            foreach ($additionalUserProperties as $key => $value) {
275
-                $m::setDefinedProperty($key, $value);
276
-            }
277
-        }
278
-
279
-        // expect the worst
280
-        $exitCode = 1;
281
-
282
-        try {
283
-            try {
284
-                $m->runBuild();
285
-                $exitCode = 0;
286
-            } catch (ExitStatusException $ese) {
287
-                $exitCode = $ese->getCode();
288
-                if (0 !== $exitCode) {
289
-                    self::handleLogfile();
290
-
291
-                    throw $ese;
292
-                }
293
-            }
294
-        } catch (BuildException $exc) {
295
-            // avoid printing output twice: self::printMessage($exc);
296
-        } catch (Throwable $exc) {
297
-            self::printMessage($exc);
298
-        } finally {
299
-            self::handleLogfile();
300
-        }
301
-        self::statusExit($exitCode);
302
-    }
303
-
304
-    /**
305
-     * Setup/initialize Phing environment from commandline args.
306
-     *
307
-     * @param array $args commandline args passed to phing shell
308
-     *
309
-     * @throws ConfigurationException
310
-     */
311
-    public function execute($args): void
312
-    {
313
-        self::$definedProps = new Properties();
314
-        $this->searchForThis = null;
315
-
316
-        // 1) First handle any options which should always
317
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
318
-
319
-        if (in_array('-help', $args) || in_array('-h', $args)) {
320
-            static::printUsage();
321
-
322
-            return;
323
-        }
324
-
325
-        if (in_array('-version', $args) || in_array('-v', $args)) {
326
-            static::printVersion();
327
-
328
-            return;
329
-        }
330
-
331
-        if (in_array('-init', $args) || in_array('-i', $args)) {
332
-            $key = array_search('-init', $args) ?: array_search('-i', $args);
333
-            $path = $args[$key + 1] ?? null;
334
-
335
-            self::init($path);
336
-
337
-            return;
338
-        }
339
-
340
-        if (in_array('-diagnostics', $args)) {
341
-            Diagnostics::doReport(new PrintStream(self::$out));
342
-
343
-            return;
344
-        }
345
-
346
-        // 2) Next pull out stand-alone args.
347
-        // Note: The order in which these are executed is important (if multiple of these options are specified)
348
-
349
-        if (
350
-            false !== ($key = array_search('-quiet', $args, true))
351
-            || false !== ($key = array_search(
352
-                '-q',
353
-                $args,
354
-                true
355
-            ))
356
-        ) {
357
-            self::$msgOutputLevel = Project::MSG_WARN;
358
-            unset($args[$key]);
359
-        }
360
-
361
-        if (
362
-            false !== ($key = array_search('-emacs', $args, true))
363
-            || false !== ($key = array_search('-e', $args, true))
364
-        ) {
365
-            $this->emacsMode = true;
366
-            unset($args[$key]);
367
-        }
368
-
369
-        if (false !== ($key = array_search('-verbose', $args, true))) {
370
-            self::$msgOutputLevel = Project::MSG_VERBOSE;
371
-            unset($args[$key]);
372
-        }
373
-
374
-        if (false !== ($key = array_search('-debug', $args, true))) {
375
-            self::$msgOutputLevel = Project::MSG_DEBUG;
376
-            unset($args[$key]);
377
-        }
378
-
379
-        if (
380
-            false !== ($key = array_search('-silent', $args, true))
381
-            || false !== ($key = array_search('-S', $args, true))
382
-        ) {
383
-            $this->silent = true;
384
-            unset($args[$key]);
385
-        }
386
-
387
-        if (false !== ($key = array_search('-propertyfileoverride', $args, true))) {
388
-            $this->propertyFileOverride = true;
389
-            unset($args[$key]);
390
-        }
391
-
392
-        // 3) Finally, cycle through to parse remaining args
393
-        //
394
-        $keys = array_keys($args); // Use keys and iterate to max(keys) since there may be some gaps
395
-        $max = $keys ? max($keys) : -1;
396
-        for ($i = 0; $i <= $max; ++$i) {
397
-            if (!array_key_exists($i, $args)) {
398
-                // skip this argument, since it must have been removed above.
399
-                continue;
400
-            }
401
-
402
-            $arg = $args[$i];
403
-
404
-            if ('-logfile' == $arg) {
405
-                try {
406
-                    // see: http://phing.info/trac/ticket/65
407
-                    if (!isset($args[$i + 1])) {
408
-                        $msg = "You must specify a log file when using the -logfile argument\n";
409
-
410
-                        throw new ConfigurationException($msg);
411
-                    }
412
-
413
-                    $logFile = new File($args[++$i]);
414
-                    $out = new FileOutputStream($logFile); // overwrite
415
-                    self::setOutputStream($out);
416
-                    self::setErrorStream($out);
417
-                    self::$isLogFileUsed = true;
418
-                } catch (IOException $ioe) {
419
-                    $msg = 'Cannot write on the specified log file. Make sure the path exists and you have write permissions.';
420
-
421
-                    throw new ConfigurationException($msg, $ioe);
422
-                }
423
-            } elseif ('-buildfile' == $arg || '-file' == $arg || '-f' == $arg) {
424
-                if (!isset($args[$i + 1])) {
425
-                    $msg = 'You must specify a buildfile when using the -buildfile argument.';
426
-
427
-                    throw new ConfigurationException($msg);
428
-                }
429
-
430
-                $this->buildFile = new File($args[++$i]);
431
-            } elseif ('-listener' == $arg) {
432
-                if (!isset($args[$i + 1])) {
433
-                    $msg = 'You must specify a listener class when using the -listener argument';
434
-
435
-                    throw new ConfigurationException($msg);
436
-                }
437
-
438
-                $this->listeners[] = $args[++$i];
439
-            } elseif (StringHelper::startsWith('-D', $arg)) {
440
-                // Evaluating the property information //
441
-                // Checking whether arg. is not just a switch, and next arg. does not starts with switch identifier
442
-                if (('-D' == $arg) && (!StringHelper::startsWith('-', $args[$i + 1]))) {
443
-                    $name = $args[++$i];
444
-                } else {
445
-                    $name = substr($arg, 2);
446
-                }
447
-
448
-                $value = null;
449
-                $posEq = strpos($name, '=');
450
-                if (false !== $posEq) {
451
-                    $value = substr($name, $posEq + 1);
452
-                    $name = substr($name, 0, $posEq);
453
-                } elseif ($i < count($args) - 1 && !StringHelper::startsWith('-D', $args[$i + 1])) {
454
-                    $value = $args[++$i];
455
-                }
456
-                self::$definedProps->setProperty($name, $value);
457
-            } elseif ('-logger' == $arg) {
458
-                if (!isset($args[$i + 1])) {
459
-                    $msg = 'You must specify a classname when using the -logger argument';
460
-
461
-                    throw new ConfigurationException($msg);
462
-                }
463
-
464
-                $this->loggerClassname = $args[++$i];
465
-            } elseif ('-no-strict' == $arg) {
466
-                $this->strictMode = false;
467
-            } elseif ('-strict' == $arg) {
468
-                $this->strictMode = true;
469
-            } elseif ('-inputhandler' == $arg) {
470
-                if (null !== $this->inputHandlerClassname) {
471
-                    throw new ConfigurationException('Only one input handler class may be specified.');
472
-                }
473
-                if (!isset($args[$i + 1])) {
474
-                    $msg = 'You must specify a classname when using the -inputhandler argument';
475
-
476
-                    throw new ConfigurationException($msg);
477
-                }
478
-
479
-                $this->inputHandlerClassname = $args[++$i];
480
-            } elseif ('-propertyfile' === $arg) {
481
-                $i = $this->handleArgPropertyFile($args, $i);
482
-            } elseif ('-keep-going' === $arg || '-k' === $arg) {
483
-                $this->keepGoingMode = true;
484
-            } elseif ('-longtargets' == $arg) {
485
-                self::$definedProps->setProperty('phing.showlongtargets', 1);
486
-            } elseif ('-projecthelp' == $arg || '-targets' == $arg || '-list' == $arg || '-l' == $arg || '-p' == $arg) {
487
-                // set the flag to display the targets and quit
488
-                $this->projectHelp = true;
489
-            } elseif ('-find' == $arg) {
490
-                // eat up next arg if present, default to build.xml
491
-                if ($i < count($args) - 1) {
492
-                    $this->searchForThis = $args[++$i];
493
-                } else {
494
-                    $this->searchForThis = self::DEFAULT_BUILD_FILENAME;
495
-                }
496
-            } elseif ('-' == substr($arg, 0, 1)) {
497
-                // we don't have any more args
498
-                self::printUsage();
499
-                self::$err->write(PHP_EOL);
500
-
501
-                throw new ConfigurationException('Unknown argument: ' . $arg);
502
-            } else {
503
-                // if it's no other arg, it may be the target
504
-                $this->targets[] = $arg;
505
-            }
506
-        }
507
-
508
-        // if buildFile was not specified on the command line,
509
-        if (null === $this->buildFile) {
510
-            // but -find then search for it
511
-            if (null !== $this->searchForThis) {
512
-                $this->buildFile = $this->findBuildFile(self::getProperty('user.dir'), $this->searchForThis);
513
-            } else {
514
-                $this->buildFile = new File(self::DEFAULT_BUILD_FILENAME);
515
-            }
516
-        }
517
-
518
-        try {
519
-            // make sure buildfile (or buildfile.dist) exists
520
-            if (!$this->buildFile->exists()) {
521
-                $distFile = new File($this->buildFile->getAbsolutePath() . '.dist');
522
-                if (!$distFile->exists()) {
523
-                    throw new ConfigurationException(
524
-                        'Buildfile: ' . $this->buildFile->__toString() . ' does not exist!'
525
-                    );
526
-                }
527
-                $this->buildFile = $distFile;
528
-            }
529
-
530
-            // make sure it's not a directory
531
-            if ($this->buildFile->isDirectory()) {
532
-                throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is a dir!');
533
-            }
534
-        } catch (IOException $e) {
535
-            // something else happened, buildfile probably not readable
536
-            throw new ConfigurationException('Buildfile: ' . $this->buildFile->__toString() . ' is not readable!');
537
-        }
538
-
539
-        $this->loadPropertyFiles();
540
-
541
-        $this->readyToRun = true;
542
-    }
543
-
544
-    /**
545
-     * Prints the usage of how to use this class.
546
-     */
547
-    public static function printUsage()
548
-    {
549
-        $msg = '';
550
-        $msg .= 'phing [options] [target [target2 [target3] ...]]' . PHP_EOL;
551
-        $msg .= 'Options: ' . PHP_EOL;
552
-        $msg .= '  -h -help               print this message' . PHP_EOL;
553
-        $msg .= '  -l -list               list available targets in this project' . PHP_EOL;
554
-        $msg .= '  -i -init [file]        generates an initial buildfile' . PHP_EOL;
555
-        $msg .= '  -v -version            print the version information and exit' . PHP_EOL;
556
-        $msg .= '  -q -quiet              be extra quiet' . PHP_EOL;
557
-        $msg .= '  -S -silent             print nothing but task outputs and build failures' . PHP_EOL;
558
-        $msg .= '  -verbose               be extra verbose' . PHP_EOL;
559
-        $msg .= '  -debug                 print debugging information' . PHP_EOL;
560
-        $msg .= '  -emacs, -e             produce logging information without adornments' . PHP_EOL;
561
-        $msg .= '  -diagnostics           print diagnostics information' . PHP_EOL;
562
-        $msg .= '  -strict                runs build in strict mode, considering a warning as error' . PHP_EOL;
563
-        $msg .= '  -no-strict             runs build normally (overrides buildfile attribute)' . PHP_EOL;
564
-        $msg .= '  -longtargets           show target descriptions during build' . PHP_EOL;
565
-        $msg .= '  -logfile <file>        use given file for log' . PHP_EOL;
566
-        $msg .= '  -logger <classname>    the class which is to perform logging' . PHP_EOL;
567
-        $msg .= '  -listener <classname>  add an instance of class as a project listener' . PHP_EOL;
568
-        $msg .= '  -f -buildfile <file>   use given buildfile' . PHP_EOL;
569
-        $msg .= '  -D<property>=<value>   use value for given property' . PHP_EOL;
570
-        $msg .= '  -keep-going, -k        execute all targets that do not depend' . PHP_EOL;
571
-        $msg .= '                         on failed target(s)' . PHP_EOL;
572
-        $msg .= '  -propertyfile <file>   load all properties from file' . PHP_EOL;
573
-        $msg .= '  -propertyfileoverride  values in property file override existing values' . PHP_EOL;
574
-        $msg .= '  -find <file>           search for buildfile towards the root of the' . PHP_EOL;
575
-        $msg .= '                         filesystem and use it' . PHP_EOL;
576
-        $msg .= '  -inputhandler <file>   the class to use to handle user input' . PHP_EOL;
577
-        //$msg .= "  -recursive <file>      search for buildfile downwards and use it" . PHP_EOL;
578
-        $msg .= PHP_EOL;
579
-        $msg .= 'Report bugs to https://github.com/phingofficial/phing/issues' . PHP_EOL;
580
-        self::$err->write($msg);
581
-    }
582
-
583
-    /**
584
-     * Prints the current Phing version.
585
-     */
586
-    public static function printVersion()
587
-    {
588
-        self::$out->write(self::getPhingVersion() . PHP_EOL);
589
-    }
590
-
591
-    /**
592
-     * Gets the current Phing version based on VERSION.TXT file.
593
-     *
594
-     * @throws ConfigurationException
595
-     */
596
-    public static function getPhingVersion(): string
597
-    {
598
-        $versionPath = self::getResourcePath('phing/etc/VERSION.TXT');
599
-        if (null === $versionPath) {
600
-            $versionPath = self::getResourcePath('etc/VERSION.TXT');
601
-        }
602
-        if (null === $versionPath) {
603
-            throw new ConfigurationException('No VERSION.TXT file found; try setting phing.home environment variable.');
604
-        }
605
-
606
-        try { // try to read file
607
-            $file = new File($versionPath);
608
-            $reader = new FileReader($file);
609
-            $phingVersion = trim($reader->read());
610
-        } catch (IOException $iox) {
611
-            throw new ConfigurationException("Can't read version information file");
612
-        }
613
-
614
-        $basePath = dirname(__DIR__, 2);
615
-
616
-        $version = new Version($phingVersion, $basePath);
617
-
618
-        return 'Phing ' . $version->getVersion();
619
-    }
620
-
621
-    /**
622
-     * Looks on include path for specified file.
623
-     *
624
-     * @param string $path
625
-     *
626
-     * @return null|string file found (null if no file found)
627
-     */
628
-    public static function getResourcePath($path): ?string
629
-    {
630
-        if (null === self::$importPaths) {
631
-            self::$importPaths = self::explodeIncludePath();
632
-        }
633
-
634
-        $path = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $path);
635
-
636
-        foreach (self::$importPaths as $prefix) {
637
-            $testPath = $prefix . DIRECTORY_SEPARATOR . $path;
638
-            if (file_exists($testPath)) {
639
-                return $testPath;
640
-            }
641
-        }
642
-
643
-        // Check for the property phing.home
644
-        $homeDir = self::getProperty(self::PHING_HOME);
645
-        if ($homeDir) {
646
-            $testPath = $homeDir . DIRECTORY_SEPARATOR . $path;
647
-            if (file_exists($testPath)) {
648
-                return $testPath;
649
-            }
650
-        }
651
-
652
-        // Check for the phing home of phar archive
653
-        if (0 === strpos(self::$importPaths[0], 'phar://')) {
654
-            $testPath = self::$importPaths[0] . '/../' . $path;
655
-            if (file_exists($testPath)) {
656
-                return $testPath;
657
-            }
658
-        }
659
-
660
-        // Do one additional check based on path of current file (Phing.php)
661
-        $maybeHomeDir = realpath(__DIR__ . DIRECTORY_SEPARATOR);
662
-        $testPath = $maybeHomeDir . DIRECTORY_SEPARATOR . $path;
663
-        if (file_exists($testPath)) {
664
-            return $testPath;
665
-        }
666
-
667
-        return null;
668
-    }
669
-
670
-    /**
671
-     * Explode an include path into an array.
672
-     *
673
-     * If no path provided, uses current include_path. Works around issues that
674
-     * occur when the path includes stream schemas.
675
-     *
676
-     * Pulled from Zend_Loader::explodeIncludePath() in ZF1.
677
-     *
678
-     * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
679
-     * @license   http://framework.zend.com/license/new-bsd New BSD License
680
-     *
681
-     * @param null|string $path
682
-     *
683
-     * @return array
684
-     */
685
-    public static function explodeIncludePath($path = null)
686
-    {
687
-        if (null === $path) {
688
-            $path = get_include_path();
689
-        }
690
-
691
-        if (PATH_SEPARATOR === ':') {
692
-            // On *nix systems, include_paths which include paths with a stream
693
-            // schema cannot be safely explode'd, so we have to be a bit more
694
-            // intelligent in the approach.
695
-            $paths = preg_split('#:(?!//)#', $path);
696
-        } else {
697
-            $paths = explode(PATH_SEPARATOR, $path);
698
-        }
699
-
700
-        return $paths;
701
-    }
702
-
703
-    /**
704
-     * Returns property value for a System property.
705
-     * System properties are "global" properties like application.startdir,
706
-     * and user.dir.  Many of these correspond to similar properties in Java
707
-     * or Ant.
708
-     *
709
-     * @param string $propName
710
-     *
711
-     * @return string value of found property (or null, if none found)
712
-     */
713
-    public static function getProperty($propName)
714
-    {
715
-        // some properties are detemined on each access
716
-        // some are cached, see below
717
-
718
-        // default is the cached value:
719
-        $val = self::$properties[$propName] ?? null;
720
-
721
-        // special exceptions
722
-        switch ($propName) {
723
-            case 'user.dir':
724
-                $val = getcwd();
725
-
726
-                break;
727
-        }
728
-
729
-        return $val;
730
-    }
731
-
732
-    /**
733
-     * Creates generic buildfile.
734
-     *
735
-     * @param string $path
736
-     */
737
-    public static function init($path)
738
-    {
739
-        if ($buildfilePath = self::initPath($path)) {
740
-            self::initWrite($buildfilePath);
741
-        }
742
-    }
743
-
744
-    /**
745
-     * Sets the stream to use for standard (non-error) output.
746
-     *
747
-     * @param OutputStream $stream the stream to use for standard output
748
-     */
749
-    public static function setOutputStream(OutputStream $stream)
750
-    {
751
-        self::$out = $stream;
752
-    }
753
-
754
-    /**
755
-     * Sets the stream to use for error output.
756
-     *
757
-     * @param OutputStream $stream the stream to use for error output
758
-     */
759
-    public static function setErrorStream(OutputStream $stream): void
760
-    {
761
-        self::$err = $stream;
762
-    }
763
-
764
-    /**
765
-     * Making output level a static property so that this property
766
-     * can be accessed by other parts of the system, enabling
767
-     * us to display more information -- e.g. backtraces -- for "debug" level.
768
-     *
769
-     * @return int
770
-     */
771
-    public static function getMsgOutputLevel()
772
-    {
773
-        return self::$msgOutputLevel;
774
-    }
775
-
776
-    /**
777
-     * Prints the message of the Exception if it's not null.
778
-     */
779
-    public static function printMessage(Throwable $t): void
780
-    {
781
-        if (null === self::$err) { // Make sure our error output is initialized
782
-            self::initializeOutputStreams();
783
-        }
784
-        if (self::getMsgOutputLevel() >= Project::MSG_VERBOSE) {
785
-            self::$err->write((string) $t . PHP_EOL);
786
-        } else {
787
-            self::$err->write($t->getMessage() . PHP_EOL);
788
-        }
789
-    }
790
-
791
-    /**
792
-     * Performs any shutdown routines, such as stopping timers.
793
-     *
794
-     * @throws IOException
795
-     */
796
-    public static function shutdown(): void
797
-    {
798
-        FileSystem::getFileSystem()::deleteFilesOnExit();
799
-        self::$msgOutputLevel = Project::MSG_INFO;
800
-        self::restoreIni();
801
-        self::getTimer()->stop();
802
-    }
803
-
804
-    /**
805
-     * Returns reference to DefaultClock object.
806
-     */
807
-    public static function getTimer(): DefaultClock
808
-    {
809
-        if (null === self::$timer) {
810
-            self::$timer = new DefaultClock();
811
-        }
812
-
813
-        return self::$timer;
814
-    }
815
-
816
-    /**
817
-     * This sets a property that was set via command line or otherwise passed into Phing.
818
-     *
819
-     * @param string $name
820
-     * @param mixed  $value
821
-     *
822
-     * @return mixed value of found property (or null, if none found)
823
-     */
824
-    public static function setDefinedProperty($name, $value)
825
-    {
826
-        return self::$definedProps->setProperty($name, $value);
827
-    }
828
-
829
-    /**
830
-     * Executes the build.
831
-     *
832
-     * @throws IOException
833
-     * @throws Throwable
834
-     */
835
-    public function runBuild(): void
836
-    {
837
-        if (!$this->readyToRun) {
838
-            return;
839
-        }
840
-
841
-        $project = new Project();
842
-
843
-        self::setCurrentProject($project);
844
-        set_error_handler(['Phing\Phing', 'handlePhpError']);
845
-
846
-        $error = null;
847
-
848
-        try {
849
-            $this->addBuildListeners($project);
850
-            $this->addInputHandler($project);
851
-
852
-            // set this right away, so that it can be used in logging.
853
-            $project->setUserProperty('phing.file', $this->buildFile->getAbsolutePath());
854
-            $project->setUserProperty('phing.dir', dirname($this->buildFile->getAbsolutePath()));
855
-            $project->setUserProperty('phing.version', static::getPhingVersion());
856
-            $project->fireBuildStarted();
857
-            $project->init();
858
-            $project->setKeepGoingMode($this->keepGoingMode);
859
-
860
-            $e = self::$definedProps->keys();
861
-            while (count($e)) {
862
-                $arg = (string) array_shift($e);
863
-                $value = (string) self::$definedProps->getProperty($arg);
864
-                $project->setUserProperty($arg, $value);
865
-            }
866
-            unset($e);
867
-
868
-            // first use the Configurator to create the project object
869
-            // from the given build file.
870
-
871
-            ProjectConfigurator::configureProject($project, $this->buildFile);
872
-
873
-            // Set the project mode
874
-            $project->setStrictMode(StringHelper::booleanValue($this->strictMode));
875
-
876
-            // make sure that minimum required phing version is satisfied
877
-            $this->comparePhingVersion($project->getPhingVersion());
878
-
879
-            if ($this->projectHelp) {
880
-                $this->printDescription($project);
881
-                $this->printTargets($project);
882
-
883
-                return;
884
-            }
885
-
886
-            // make sure that we have a target to execute
887
-            if (0 === count($this->targets)) {
888
-                $this->targets[] = $project->getDefaultTarget();
889
-            }
890
-
891
-            $project->executeTargets($this->targets);
892
-        } catch (Throwable $t) {
893
-            $error = $t;
894
-
895
-            throw $t;
896
-        } finally {
897
-            if (!$this->projectHelp) {
898
-                try {
899
-                    $project->fireBuildFinished($error);
900
-                } catch (Exception $e) {
901
-                    self::$err->write('Caught an exception while logging the end of the build.  Exception was:' . PHP_EOL);
902
-                    self::$err->write($e->getTraceAsString());
903
-                    if (null !== $error) {
904
-                        self::$err->write('There has been an error prior to that:' . PHP_EOL);
905
-                        self::$err->write($error->getTraceAsString());
906
-                    }
907
-
908
-                    throw new BuildException($error);
909
-                }
910
-            } elseif (null !== $error) {
911
-                $project->log($error->getMessage(), Project::MSG_ERR);
912
-            }
913
-
914
-            restore_error_handler();
915
-            self::unsetCurrentProject();
916
-        }
917
-    }
918
-
919
-    /**
920
-     * Import a class, supporting the following conventions:
921
-     * - PEAR style (@see http://pear.php.net/manual/en/standards.naming.php)
922
-     * - PSR-0 (@see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md).
923
-     *
924
-     * @param string $classname Name of class
925
-     * @param mixed  $classpath String or object supporting __toString()
926
-     *
927
-     * @throws BuildException - if cannot find the specified file
928
-     *
929
-     * @return string the unqualified classname (which can be instantiated)
930
-     */
931
-    public static function import($classname, $classpath = null)
932
-    {
933
-        // first check to see that the class specified hasn't already been included.
934
-        if (class_exists($classname)) {
935
-            return $classname;
936
-        }
937
-
938
-        $filename = strtr($classname, ['_' => DIRECTORY_SEPARATOR, '\\' => DIRECTORY_SEPARATOR]) . '.php';
939
-
940
-        Phing::importFile($filename, $classpath);
941
-
942
-        return $classname;
943
-    }
944
-
945
-    /**
946
-     * Import a PHP file.
947
-     *
948
-     * This used to be named __import, however PHP has reserved all method names
949
-     * with a double underscore prefix for future use.
950
-     *
951
-     * @param string $path      Path to the PHP file
952
-     * @param mixed  $classpath String or object supporting __toString()
953
-     *
954
-     * @throws ConfigurationException
955
-     */
956
-    public static function importFile($path, $classpath = null)
957
-    {
958
-        if ($classpath) {
959
-            // Apparently casting to (string) no longer invokes __toString() automatically.
960
-            if (is_object($classpath)) {
961
-                $classpath = $classpath->__toString();
962
-            }
963
-
964
-            // classpaths are currently additive, but we also don't want to just
965
-            // indiscriminantly prepand/append stuff to the include_path.  This means
966
-            // we need to parse current incldue_path, and prepend any
967
-            // specified classpath locations that are not already in the include_path.
968
-            //
969
-            // NOTE:  the reason why we do it this way instead of just changing include_path
970
-            // and then changing it back, is that in many cases applications (e.g. Propel) will
971
-            // include/require class files from within method calls.  This means that not all
972
-            // necessary files will be included in this import() call, and hence we can't
973
-            // change the include_path back without breaking those apps.  While this method could
974
-            // be more expensive than switching & switching back (not sure, but maybe), it makes it
975
-            // possible to write far less expensive run-time applications (e.g. using Propel), which is
976
-            // really where speed matters more.
977
-
978
-            $curr_parts = Phing::explodeIncludePath();
979
-            $add_parts = Phing::explodeIncludePath($classpath);
980
-            $new_parts = array_diff($add_parts, $curr_parts);
981
-            if ($new_parts) {
982
-                set_include_path(implode(PATH_SEPARATOR, array_merge($new_parts, $curr_parts)));
983
-            }
984
-        }
985
-
986
-        $ret = include_once $path;
987
-
988
-        if (false === $ret) {
989
-            $msg = "Error importing {$path}";
990
-            if (self::getMsgOutputLevel() >= Project::MSG_DEBUG) {
991
-                $x = new Exception('for-path-trace-only');
992
-                $msg .= $x->getTraceAsString();
993
-            }
994
-
995
-            throw new ConfigurationException($msg);
996
-        }
997
-    }
998
-
999
-    /**
1000
-     * Print the project description, if any.
1001
-     *
1002
-     * @throws IOException
1003
-     */
1004
-    public function printDescription(Project $project): void
1005
-    {
1006
-        if (null !== $project->getDescription()) {
1007
-            $project->log($project->getDescription());
1008
-        }
1009
-    }
1010
-
1011
-    /**
1012
-     * Print out a list of all targets in the current buildfile.
1013
-     */
1014
-    public function printTargets(Project $project)
1015
-    {
1016
-        $visibleTargets = array_filter($project->getTargets(), function (Target $target) {
1017
-            return !$target->isHidden() && !empty($target->getName());
1018
-        });
1019
-        $padding = array_reduce($visibleTargets, function (int $carry, Target $target) {
1020
-            return max(strlen($target->getName()), $carry);
1021
-        }, 0);
1022
-        $categories = [
1023
-            'Default target:' => array_filter($visibleTargets, function (Target $target) use ($project) {
1024
-                return trim(strval($target)) === $project->getDefaultTarget();
1025
-            }),
1026
-            'Main targets:' => array_filter($visibleTargets, function (Target $target) {
1027
-                return !empty($target->getDescription());
1028
-            }),
1029
-            'Subtargets:' => array_filter($visibleTargets, function (Target $target) {
1030
-                return empty($target->getDescription());
1031
-            }),
1032
-        ];
1033
-        foreach ($categories as $title => $targets) {
1034
-            $targetList = $this->generateTargetList($title, $targets, $padding);
1035
-            $project->log($targetList, Project::MSG_WARN);
1036
-        }
1037
-    }
1038
-
1039
-    /**
1040
-     * Unsets the current Project.
1041
-     */
1042
-    public static function unsetCurrentProject(): void
1043
-    {
1044
-        self::$currentProject = null;
1045
-    }
1046
-
1047
-    /**
1048
-     * Error handler for PHP errors encountered during the build.
1049
-     * This uses the logging for the currently configured project.
1050
-     *
1051
-     * @param $level
1052
-     * @param string $message
1053
-     * @param $file
1054
-     * @param $line
1055
-     */
1056
-    public static function handlePhpError($level, $message, $file, $line)
1057
-    {
1058
-        // don't want to print suppressed errors
1059
-        if (error_reporting() > 0) {
1060
-            if (self::$phpErrorCapture) {
1061
-                self::$capturedPhpErrors[] = [
1062
-                    'message' => $message,
1063
-                    'level' => $level,
1064
-                    'line' => $line,
1065
-                    'file' => $file,
1066
-                ];
1067
-            } else {
1068
-                $message = '[PHP Error] ' . $message;
1069
-                $message .= ' [line ' . $line . ' of ' . $file . ']';
1070
-
1071
-                switch ($level) {
1072
-                    case E_USER_DEPRECATED:
1073
-                    case E_DEPRECATED:
1074
-                    case E_STRICT:
1075
-                    case E_NOTICE:
1076
-                    case E_USER_NOTICE:
1077
-                        self::log($message, Project::MSG_VERBOSE);
1078
-
1079
-                        break;
1080
-
1081
-                    case E_WARNING:
1082
-                    case E_USER_WARNING:
1083
-                        self::log($message, Project::MSG_WARN);
1084
-
1085
-                        break;
1086
-
1087
-                    case E_ERROR:
1088
-                    case E_USER_ERROR:
1089
-                    default:
1090
-                        self::log($message, Project::MSG_ERR);
1091
-                } // switch
1092
-            } // if phpErrorCapture
1093
-        } // if not @
1094
-    }
1095
-
1096
-    /**
1097
-     * A static convenience method to send a log to the current (last-setup) Project.
1098
-     * If there is no currently-configured Project, then this will do nothing.
1099
-     *
1100
-     * @param string $message
1101
-     * @param int    $priority project::MSG_INFO, etc
1102
-     */
1103
-    public static function log($message, $priority = Project::MSG_INFO): void
1104
-    {
1105
-        $p = self::getCurrentProject();
1106
-        if ($p) {
1107
-            $p->log($message, $priority);
1108
-        }
1109
-    }
1110
-
1111
-    /**
1112
-     * Gets the current Project.
1113
-     *
1114
-     * @return Project current Project or NULL if none is set yet/still
1115
-     */
1116
-    public static function getCurrentProject()
1117
-    {
1118
-        return self::$currentProject;
1119
-    }
1120
-
1121
-    /**
1122
-     * Sets the current Project.
1123
-     *
1124
-     * @param Project $p
1125
-     */
1126
-    public static function setCurrentProject($p): void
1127
-    {
1128
-        self::$currentProject = $p;
1129
-    }
1130
-
1131
-    /**
1132
-     * Begins capturing PHP errors to a buffer.
1133
-     * While errors are being captured, they are not logged.
1134
-     */
1135
-    public static function startPhpErrorCapture(): void
1136
-    {
1137
-        self::$phpErrorCapture = true;
1138
-        self::$capturedPhpErrors = [];
1139
-    }
1140
-
1141
-    /**
1142
-     * Stops capturing PHP errors to a buffer.
1143
-     * The errors will once again be logged after calling this method.
1144
-     */
1145
-    public static function stopPhpErrorCapture(): void
1146
-    {
1147
-        self::$phpErrorCapture = false;
1148
-    }
1149
-
1150
-    /**
1151
-     * Clears the captured errors without affecting the starting/stopping of the capture.
1152
-     */
1153
-    public static function clearCapturedPhpErrors(): void
1154
-    {
1155
-        self::$capturedPhpErrors = [];
1156
-    }
1157
-
1158
-    /**
1159
-     * Gets any PHP errors that were captured to buffer.
1160
-     *
1161
-     * @return array array('message' => message, 'line' => line number, 'file' => file name, 'level' => error level)
1162
-     */
1163
-    public static function getCapturedPhpErrors()
1164
-    {
1165
-        return self::$capturedPhpErrors;
1166
-    }
1167
-
1168
-    /**
1169
-     * This gets a property that was set via command line or otherwise passed into Phing.
1170
-     * "Defined" in this case means "externally defined".  The reason this method exists is to
1171
-     * provide a public means of accessing commandline properties for (e.g.) logger or listener
1172
-     * scripts.  E.g. to specify which logfile to use, PearLogger needs to be able to access
1173
-     * the pear.log.name property.
1174
-     *
1175
-     * @param string $name
1176
-     *
1177
-     * @return string value of found property (or null, if none found)
1178
-     */
1179
-    public static function getDefinedProperty($name)
1180
-    {
1181
-        return self::$definedProps->getProperty($name);
1182
-    }
1183
-
1184
-    /**
1185
-     * Retuns reference to all properties.
1186
-     */
1187
-    public static function &getProperties()
1188
-    {
1189
-        return self::$properties;
1190
-    }
1191
-
1192
-    /**
1193
-     * Start up Phing.
1194
-     * Sets up the Phing environment but does not initiate the build process.
1195
-     *
1196
-     * @throws exception - If the Phing environment cannot be initialized
1197
-     */
1198
-    public static function startup(): void
1199
-    {
1200
-        // setup STDOUT and STDERR defaults
1201
-        self::initializeOutputStreams();
1202
-
1203
-        // some init stuff
1204
-        self::getTimer()->start();
1205
-
1206
-        self::setSystemConstants();
1207
-        self::setIncludePaths();
1208
-        self::setIni();
1209
-    }
1210
-
1211
-    /**
1212
-     * @param $propName
1213
-     * @param $propValue
1214
-     *
1215
-     * @return string
1216
-     */
1217
-    public static function setProperty($propName, $propValue)
1218
-    {
1219
-        $propName = (string) $propName;
1220
-        $oldValue = self::getProperty($propName);
1221
-        self::$properties[$propName] = $propValue;
1222
-
1223
-        return $oldValue;
1224
-    }
1225
-
1226
-    /**
1227
-     * Returns buildfile's path.
1228
-     *
1229
-     * @param $path
1230
-     *
1231
-     * @throws ConfigurationException
1232
-     *
1233
-     * @return string
1234
-     */
1235
-    protected static function initPath($path)
1236
-    {
1237
-        // Fallback
1238
-        if (empty($path)) {
1239
-            $defaultDir = self::getProperty('application.startdir');
1240
-            $path = $defaultDir . DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1241
-        }
1242
-
1243
-        // Adding filename if necessary
1244
-        if (is_dir($path)) {
1245
-            $path .= DIRECTORY_SEPARATOR . self::DEFAULT_BUILD_FILENAME;
1246
-        }
1247
-
1248
-        // Check if path is available
1249
-        $dirname = dirname($path);
1250
-        if (is_dir($dirname) && !is_file($path)) {
1251
-            return $path;
1252
-        }
1253
-
1254
-        // Path is valid, but buildfile already exists
1255
-        if (is_file($path)) {
1256
-            throw new ConfigurationException('Buildfile already exists.');
1257
-        }
1258
-
1259
-        throw new ConfigurationException('Invalid path for sample buildfile.');
1260
-    }
1261
-
1262
-    /**
1263
-     * Writes sample buildfile.
1264
-     *
1265
-     * If $buildfilePath does not exist, the buildfile is created.
1266
-     *
1267
-     * @param $buildfilePath buildfile's location
1268
-     *
1269
-     * @throws ConfigurationException
1270
-     */
1271
-    protected static function initWrite($buildfilePath): void
1272
-    {
1273
-        // Overwriting protection
1274
-        if (file_exists($buildfilePath)) {
1275
-            throw new ConfigurationException('Cannot overwrite existing file.');
1276
-        }
1277
-
1278
-        file_put_contents($buildfilePath, self::DEFAULT_BUILD_CONTENT);
1279
-    }
1280
-
1281
-    /**
1282
-     * This operation is expected to call `exit($int)`, which
1283
-     * is what the base version does.
1284
-     * However, it is possible to do something else.
1285
-     *
1286
-     * @param int $exitCode code to exit with
1287
-     */
1288
-    protected static function statusExit($exitCode): void
1289
-    {
1290
-        Phing::shutdown();
1291
-
1292
-        exit($exitCode);
1293
-    }
1294
-
1295
-    /**
1296
-     * Handle the -propertyfile argument.
1297
-     *
1298
-     * @throws ConfigurationException
1299
-     * @throws IOException
1300
-     */
1301
-    private function handleArgPropertyFile(array $args, int $pos): int
1302
-    {
1303
-        if (!isset($args[$pos + 1])) {
1304
-            throw new ConfigurationException('You must specify a filename when using the -propertyfile argument');
1305
-        }
1306
-
1307
-        $this->propertyFiles[] = $args[++$pos];
1308
-
1309
-        return $pos;
1310
-    }
1311
-
1312
-    /**
1313
-     * Search parent directories for the build file.
1314
-     *
1315
-     * Takes the given target as a suffix to append to each
1316
-     * parent directory in search of a build file.  Once the
1317
-     * root of the file-system has been reached an exception
1318
-     * is thrown.
1319
-     *
1320
-     * @param string $start  start file path
1321
-     * @param string $suffix suffix filename to look for in parents
1322
-     *
1323
-     * @throws ConfigurationException
1324
-     *
1325
-     * @return File A handle to the build file
1326
-     */
1327
-    private function findBuildFile($start, $suffix)
1328
-    {
1329
-        if (self::getMsgOutputLevel() >= Project::MSG_INFO) {
1330
-            self::$out->write('Searching for ' . $suffix . ' ...' . PHP_EOL);
1331
-        }
1332
-
1333
-        $parent = new File((new File($start))->getAbsolutePath());
1334
-        $file = new File($parent, $suffix);
1335
-
1336
-        // check if the target file exists in the current directory
1337
-        while (!$file->exists()) {
1338
-            // change to parent directory
1339
-            $parent = $parent->getParentFile();
1340
-
1341
-            // if parent is null, then we are at the root of the fs,
1342
-            // complain that we can't find the build file.
1343
-            if (null === $parent) {
1344
-                throw new ConfigurationException('Could not locate a build file!');
1345
-            }
1346
-            // refresh our file handle
1347
-            $file = new File($parent, $suffix);
1348
-        }
1349
-
1350
-        return $file;
1351
-    }
1352
-
1353
-    /**
1354
-     * @throws IOException
1355
-     */
1356
-    private function loadPropertyFiles(): void
1357
-    {
1358
-        foreach ($this->propertyFiles as $filename) {
1359
-            $fileParserFactory = new FileParserFactory();
1360
-            $fileParser = $fileParserFactory->createParser(pathinfo($filename, PATHINFO_EXTENSION));
1361
-            $p = new Properties(null, $fileParser);
1362
-
1363
-            try {
1364
-                $p->load(new File($filename));
1365
-            } catch (IOException $e) {
1366
-                self::$out->write('Could not load property file ' . $filename . ': ' . $e->getMessage());
1367
-            }
1368
-            foreach ($p->getProperties() as $prop => $value) {
1369
-                self::$definedProps->setProperty($prop, $value);
1370
-            }
1371
-        }
1372
-    }
1373
-
1374
-    /**
1375
-     * Close logfiles, if we have been writing to them.
1376
-     *
1377
-     * @since Phing 2.3.0
1378
-     */
1379
-    private static function handleLogfile(): void
1380
-    {
1381
-        if (self::$isLogFileUsed) {
1382
-            self::$err->close();
1383
-            self::$out->close();
1384
-        }
1385
-    }
1386
-
1387
-    /**
1388
-     * Sets the stdout and stderr streams if they are not already set.
1389
-     */
1390
-    private static function initializeOutputStreams()
1391
-    {
1392
-        if (null === self::$out) {
1393
-            if (!defined('STDOUT')) {
1394
-                self::$out = new OutputStream(fopen('php://stdout', 'w'));
1395
-            } else {
1396
-                self::$out = new OutputStream(STDOUT);
1397
-            }
1398
-        }
1399
-        if (null === self::$err) {
1400
-            if (!defined('STDERR')) {
1401
-                self::$err = new OutputStream(fopen('php://stderr', 'w'));
1402
-            } else {
1403
-                self::$err = new OutputStream(STDERR);
1404
-            }
1405
-        }
1406
-    }
1407
-
1408
-    /**
1409
-     * Restores [most] PHP INI values to their pre-Phing state.
1410
-     *
1411
-     * Currently the following settings are not restored:
1412
-     *  - max_execution_time (because getting current time limit is not possible)
1413
-     *  - memory_limit (which may have been increased by Phing)
1414
-     */
1415
-    private static function restoreIni(): void
1416
-    {
1417
-        foreach (self::$origIniSettings as $settingName => $settingValue) {
1418
-            switch ($settingName) {
1419
-                case 'error_reporting':
1420
-                    error_reporting($settingValue);
1421
-
1422
-                    break;
1423
-
1424
-                default:
1425
-                    ini_set($settingName, $settingValue);
1426
-            }
1427
-        }
1428
-    }
1429
-
1430
-    /**
1431
-     * Bind any registered build listeners to this project.
1432
-     *
1433
-     * This means adding the logger and any build listeners that were specified
1434
-     * with -listener arg.
1435
-     *
1436
-     * @throws BuildException
1437
-     * @throws ConfigurationException
1438
-     */
1439
-    private function addBuildListeners(Project $project)
1440
-    {
1441
-        // Add the default listener
1442
-        $project->addBuildListener($this->createLogger());
1443
-
1444
-        foreach ($this->listeners as $listenerClassname) {
1445
-            try {
1446
-                $clz = Phing::import($listenerClassname);
1447
-            } catch (Exception $e) {
1448
-                $msg = 'Unable to instantiate specified listener '
1449
-                    . 'class ' . $listenerClassname . ' : '
1450
-                    . $e->getMessage();
1451
-
1452
-                throw new ConfigurationException($msg);
1453
-            }
1454
-
1455
-            $listener = new $clz();
1456
-
1457
-            if ($listener instanceof StreamRequiredBuildLogger) {
1458
-                throw new ConfigurationException('Unable to add ' . $listenerClassname . ' as a listener, since it requires explicit error/output streams. (You can specify it as a -logger.)');
1459
-            }
1460
-            $project->addBuildListener($listener);
1461
-        }
1462
-    }
1463
-
1464
-    /**
1465
-     * Creates the default build logger for sending build events to the log.
1466
-     *
1467
-     * @throws BuildException
1468
-     *
1469
-     * @return BuildLogger The created Logger
1470
-     */
1471
-    private function createLogger()
1472
-    {
1473
-        if ($this->silent) {
1474
-            $logger = new SilentLogger();
1475
-            self::$msgOutputLevel = Project::MSG_WARN;
1476
-        } elseif (null !== $this->loggerClassname) {
1477
-            self::import($this->loggerClassname);
1478
-            // get class name part
1479
-            $classname = self::import($this->loggerClassname);
1480
-            $logger = new $classname();
1481
-            if (!($logger instanceof BuildLogger)) {
1482
-                throw new BuildException($classname . ' does not implement the BuildLogger interface.');
1483
-            }
1484
-        } else {
1485
-            $logger = new DefaultLogger();
1486
-        }
1487
-        $logger->setMessageOutputLevel(self::$msgOutputLevel);
1488
-        $logger->setOutputStream(self::$out);
1489
-        $logger->setErrorStream(self::$err);
1490
-        $logger->setEmacsMode($this->emacsMode);
1491
-
1492
-        return $logger;
1493
-    }
1494
-
1495
-    /**
1496
-     * Creates the InputHandler and adds it to the project.
1497
-     *
1498
-     * @param Project $project the project instance
1499
-     *
1500
-     * @throws ConfigurationException
1501
-     */
1502
-    private function addInputHandler(Project $project): void
1503
-    {
1504
-        if (null === $this->inputHandlerClassname) {
1505
-            $handler = new ConsoleInputHandler(STDIN, new ConsoleOutput());
1506
-        } else {
1507
-            try {
1508
-                $clz = Phing::import($this->inputHandlerClassname);
1509
-                $handler = new $clz();
1510
-                if (null !== $project && method_exists($handler, 'setProject')) {
1511
-                    $handler->setProject($project);
1512
-                }
1513
-            } catch (Exception $e) {
1514
-                $msg = 'Unable to instantiate specified input handler '
1515
-                    . 'class ' . $this->inputHandlerClassname . ' : '
1516
-                    . $e->getMessage();
1517
-
1518
-                throw new ConfigurationException($msg);
1519
-            }
1520
-        }
1521
-        $project->setInputHandler($handler);
1522
-    }
1523
-
1524
-    /**
1525
-     * @param string $version
1526
-     *
1527
-     * @throws BuildException
1528
-     * @throws ConfigurationException
1529
-     */
1530
-    private function comparePhingVersion($version): void
1531
-    {
1532
-        $current = strtolower(self::getPhingVersion());
1533
-        $current = trim(str_replace('phing', '', $current));
1534
-
1535
-        // make sure that version checks are not applied to trunk
1536
-        if ('dev' === $current) {
1537
-            return;
1538
-        }
1539
-
1540
-        if (-1 == version_compare($current, $version)) {
1541
-            throw new BuildException(
1542
-                sprintf('Incompatible Phing version (%s). Version "%s" required.', $current, $version)
1543
-            );
1544
-        }
1545
-    }
1546
-
1547
-    /**
1548
-     * Returns a formatted list of target names with an optional description.
1549
-     *
1550
-     * @param string   $title   Title for this list
1551
-     * @param Target[] $targets Targets in this list
1552
-     * @param int      $padding Padding for name column
1553
-     */
1554
-    private function generateTargetList(string $title, array $targets, int $padding): string
1555
-    {
1556
-        usort($targets, function (Target $a, Target $b) {
1557
-            return $a->getName() <=> $b->getName();
1558
-        });
1559
-
1560
-        $header = <<<HEADER
1561
-            {$title}
1562
-            -------------------------------------------------------------------------------
1563
-
1564
-            HEADER;
1565
-
1566
-        $getDetails = function (Target $target) use ($padding): string {
1567
-            $details = [];
1568
-            if (!empty($target->getDescription())) {
1569
-                $details[] = $target->getDescription();
1570
-            }
1571
-            if (!empty($target->getDependencies())) {
1572
-                $details[] = ' - depends on: ' . implode(', ', $target->getDependencies());
1573
-            }
1574
-            if (!empty($target->getIf())) {
1575
-                $details[] = ' - if property: ' . $target->getIf();
1576
-            }
1577
-            if (!empty($target->getUnless())) {
1578
-                $details[] = ' - unless property: ' . $target->getUnless();
1579
-            }
1580
-            $detailsToString = function (?string $name, ?string $detail) use ($padding): string {
1581
-                return sprintf(" %-{$padding}s  %s", $name, $detail);
1582
-            };
1583
-
1584
-            return implode(PHP_EOL, array_map($detailsToString, [$target->getName()], $details));
1585
-        };
1586
-
1587
-        return $header . implode(PHP_EOL, array_map($getDetails, $targets)) . PHP_EOL;
1588
-    }
1589
-
1590
-    /**
1591
-     * Set System constants which can be retrieved by calling Phing::getProperty($propName).
1592
-     */
1593
-    private static function setSystemConstants(): void
1594
-    {
1595
-        /*
1596
-         * PHP_OS returns on
1597
-         *   WindowsNT4.0sp6  => WINNT
1598
-         *   Windows2000      => WINNT
1599
-         *   Windows ME       => WIN32
1600
-         *   Windows 98SE     => WIN32
1601
-         *   FreeBSD 4.5p7    => FreeBSD
1602
-         *   Redhat Linux     => Linux
1603
-         *   Mac OS X         => Darwin
1604
-         */
1605
-        self::setProperty('host.os', PHP_OS);
1606
-
1607
-        // this is used by some tasks too
1608
-        self::setProperty('os.name', PHP_OS);
1609
-
1610
-        // it's still possible this won't be defined,
1611
-        // e.g. if Phing is being included in another app w/o
1612
-        // using the phing.php script.
1613
-        if (!defined('PHP_CLASSPATH')) {
1614
-            define('PHP_CLASSPATH', get_include_path());
1615
-        }
1616
-
1617
-        self::setProperty('php.classpath', PHP_CLASSPATH);
1618
-
1619
-        // try to determine the host filesystem and set system property
1620
-        // used by Fileself::getFileSystem to instantiate the correct
1621
-        // abstraction layer
1622
-
1623
-        if (PHP_OS_FAMILY === 'Windows') {
1624
-            self::setProperty('host.fstype', 'WINDOWS');
1625
-            self::setProperty('user.home', getenv('HOMEDRIVE') . getenv('HOMEPATH'));
1626
-        } else {
1627
-            self::setProperty('host.fstype', 'UNIX');
1628
-            self::setProperty('user.home', getenv('HOME'));
1629
-        }
1630
-        self::setProperty(self::PHP_INTERPRETER, PHP_BINARY);
1631
-        self::setProperty('file.separator', FileUtils::getSeparator());
1632
-        self::setProperty('line.separator', PHP_EOL);
1633
-        self::setProperty('path.separator', FileUtils::getPathSeparator());
1634
-        self::setProperty(self::PHP_VERSION, PHP_VERSION);
1635
-        self::setProperty('php.tmpdir', sys_get_temp_dir());
1636
-        self::setProperty('application.startdir', getcwd());
1637
-        self::setProperty('phing.startTime', gmdate('D, d M Y H:i:s', time()) . ' GMT');
1638
-
1639
-        // try to detect machine dependent information
1640
-        $sysInfo = [];
1641
-        if (function_exists('posix_uname') && 0 !== stripos(PHP_OS, 'WIN')) {
1642
-            $sysInfo = posix_uname();
1643
-        } else {
1644
-            $sysInfo['nodename'] = php_uname('n');
1645
-            $sysInfo['machine'] = php_uname('m');
1646
-            //this is a not so ideal substition, but maybe better than nothing
1647
-            $sysInfo['domain'] = $_SERVER['SERVER_NAME'] ?? 'unknown';
1648
-            $sysInfo['release'] = php_uname('r');
1649
-            $sysInfo['version'] = php_uname('v');
1650
-        }
1651
-
1652
-        self::setProperty('host.name', $sysInfo['nodename'] ?? 'unknown');
1653
-        self::setProperty('host.arch', $sysInfo['machine'] ?? 'unknown');
1654
-        self::setProperty('host.domain', $sysInfo['domain'] ?? 'unknown');
1655
-        self::setProperty('host.os.release', $sysInfo['release'] ?? 'unknown');
1656
-        self::setProperty('host.os.version', $sysInfo['version'] ?? 'unknown');
1657
-        unset($sysInfo);
1658
-    }
1659
-
1660
-    /**
1661
-     * Sets the include path to PHP_CLASSPATH constant (if this has been defined).
1662
-     *
1663
-     * @throws ConfigurationException - if the include_path could not be set (for some bizarre reason)
1664
-     */
1665
-    private static function setIncludePaths(): void
1666
-    {
1667
-        if (defined('PHP_CLASSPATH')) {
1668
-            $result = set_include_path(PHP_CLASSPATH);
1669
-            if (false === $result) {
1670
-                throw new ConfigurationException('Could not set PHP include_path.');
1671
-            }
1672
-            self::$origIniSettings['include_path'] = $result; // save original value for setting back later
1673
-        }
1674
-    }
1675
-
1676
-    /**
1677
-     * Sets PHP INI values that Phing needs.
1678
-     */
1679
-    private static function setIni(): void
1680
-    {
1681
-        self::$origIniSettings['error_reporting'] = error_reporting(E_ALL);
1682
-
1683
-        // We won't bother storing original max_execution_time, since 1) the value in
1684
-        // php.ini may be wrong (and there's no way to get the current value) and
1685
-        // 2) it would mean something very strange to set it to a value less than time script
1686
-        // has already been running, which would be the likely change.
1687
-
1688
-        set_time_limit(0);
1689
-
1690
-        self::$origIniSettings['short_open_tag'] = ini_set('short_open_tag', 'off');
1691
-        self::$origIniSettings['default_charset'] = ini_set('default_charset', 'iso-8859-1');
1692
-
1693
-        $mem_limit = (int) SizeHelper::fromHumanToBytes(ini_get('memory_limit'));
1694
-        if ($mem_limit < (32 * 1024 * 1024) && $mem_limit > -1) {
1695
-            // We do *not* need to save the original value here, since we don't plan to restore
1696
-            // this after shutdown (we don't trust the effectiveness of PHP's garbage collection).
1697
-            ini_set('memory_limit', '32M'); // nore: this may need to be higher for many projects
1698
-        }
1699
-    }
1700
-}
Please login to merge, or discard this patch.