Compare commits

...

186 Commits

Author SHA1 Message Date
Christoph M. Becker
e28c5e9b96 Prepare 2.2.0beta5 2019-04-18 16:24:57 +02:00
Christoph M. Becker
b359404509 Fix #58: Missing msys-crypto-1.1.dll
After discussion with @weltling, this time we only fix what is
definitely known to be broken, i.e. wget relying on OpenSSL 1.1 (which
does not work yet in msys2), the OpenSSL DLLs which have been x86
binaries, and finally we remove the gcc_s DLL which was also a x86
binary.
2019-04-16 23:38:44 +02:00
Christoph M. Becker
912853c55f Revert "Fix #58: Missing msys-crypto-1.1.dll"
This reverts commit 806f743f3c.
2019-04-16 23:31:05 +02:00
Christoph M. Becker
806f743f3c Fix #58: Missing msys-crypto-1.1.dll
While we're at it, we also bring all packages up to date.

Since wget 1.20.1-1 - 1.20.3-1 has issues with SSL, we're downgrading
to the latest working version, i.e. wget 1.19.5-1.
2019-04-16 19:35:37 +02:00
Christoph M. Becker
d13ff857f0 Back to dev 2019-04-08 12:44:33 +02:00
Christoph M. Becker
217ab7b4ca Prepare 2.2.0beta4 2019-04-08 12:42:25 +02:00
Anatol Belski
f740aface6 Remove unmatching sentence 2019-04-04 16:18:54 +02:00
Anatol Belski
f160e68fbc Update readme 2019-04-04 16:17:39 +02:00
Christoph M. Becker
9e3fcfdd77 Update phpsdk_rebase_msys2.cmd for x64 2019-04-04 15:06:29 +02:00
Christoph M. Becker
51d2eaa463 Upgrade msys2 to 64-bit
We update all existing packages right away.
2019-04-04 14:38:49 +02:00
Christoph M. Becker
15cc20920a Be more strict when looking for the desired VS (#56)
* Be more strict when looking for the desired VS

On systems where VS 2017 and VS 2019 are available, the starter script
may choose VS 2019 if vc15 is requested.  The documentation on vswhere
isn't particularly clear regarding the -version parameter, but it
states that a version range is expected.  Therefore we change the
shell setup script accordingly.

* Remove break constructs

These had been introduced to cater to multiple found VS installations,
to only use the first one.  Since the ranges are supposed to find only
a single installation, and since apparently the order of multiple
findings is not guaranteed, we remove the break constructs for better
readability of the source code.
2019-04-03 16:03:42 +02:00
Christoph M. Becker
df2eb74fee Fix phpsdk_deps
Rename `PHP_SDK_VC` to `PHP_SDK_VS` according to commit 76ede8f900.
2019-04-03 01:32:20 +02:00
Christoph M. Becker
f59fd45ee5 Don't repeat yourself
`Config::getCurrentStabilityName()` already retrieves the current
stability name, so there is no need to explicitly set it.
2019-03-31 14:37:17 +02:00
Christoph M. Becker
43107058f8 Work around old-style constructors in PGO training case
class.php of the pgo01org training case still uses PHP 4 style
constructors, which trigger deprecation notices and as such may
negatively affect the optimization.  Until this will be fixed upstream,
we're employing the workaround to modify the file during the PGO
initialization step.
2019-03-31 14:36:55 +02:00
Anatol Belski
b53316585a Fix var name 2019-03-31 13:19:05 +02:00
Anatol Belski
8b957129bd Fix loops 2019-03-31 13:05:27 +02:00
Anatol Belski
76ede8f900 Renames VC => VS
Rename starter scripts for 16
2019-03-31 12:51:55 +02:00
Anatol Belski
60cfe587d5 Show exact VC++ version 2019-03-11 16:30:07 +01:00
Anatol Belski
e6b4a0d34d Involve JIT in PGO training for master 2019-03-10 18:33:42 +01:00
Anatol Belski
dac0e43fec Add VS2019 command prompt starters 2019-02-24 20:08:23 +01:00
Anatol Belski
1d69f089ca Improve error handling on erroneous branch data 2019-02-21 19:33:12 +01:00
Anatol Belski
99112657d2 Update vswhere 2019-02-21 17:14:21 +01:00
Anatol Belski
7eaeba9e73 Back to dev 2019-02-11 22:24:57 -08:00
Anatol Belski
ad95ee0c7b Prepare 2.2.0beta3 2019-02-11 22:23:32 -08:00
Anatol Belski
55cdd86d3a Add missing bison files 2019-02-11 22:22:07 -08:00
Anatol Belski
1045633875 Back to dev 2019-02-11 22:10:05 -08:00
Anatol Belski
c6a2644a57 Prepare 2.2.0beta2 2019-02-11 22:09:08 -08:00
Anatol Belski
9ffa736cbc Update bison to 3.3.2 2019-02-11 21:59:18 -08:00
Anatol Belski
79fbcfee08 Upgrade bundled PHP to 7.3.2 2019-02-11 09:51:30 -08:00
Anatol Belski
f84b056d1c Make the major number optional and care about 8 2019-02-04 23:31:01 -08:00
Anatol Belski
0ab9b8ddc6 Add error check 2019-02-04 20:00:05 -08:00
Anatol Belski
794ef96470 Add 8.0 configs for PGO 2019-02-04 15:33:26 -08:00
Anatol Belski
cecf3df7f3 Back to dev 2019-01-12 22:05:55 +01:00
Anatol Belski
1e6ee7afaa Prepare 2.2.0beta1 2019-01-12 22:04:56 +01:00
Anatol Belski
05af1a3b06 Upgrade bundled PHP to 7.3.1 2019-01-12 18:41:21 +01:00
Anatol Belski
c748916f5c Back to dev
Also raise the version to 2.2.0 as some essential tool upgrades are to expect.
2019-01-12 16:17:01 +01:00
Anatol Belski
bebb84afd7 Prepare 2.1.10 2019-01-12 16:08:52 +01:00
Anatol Belski
841065efd4 One more version update 2019-01-08 17:57:31 +01:00
Anatol Belski
c726890170 Update versions in README 2019-01-08 17:55:26 +01:00
Anatol Belski
b2e52e36d8 Back to dev 2018-12-26 13:51:10 +01:00
Anatol Belski
b8713d8543 Prepare 2.1.10beta1 2018-12-26 13:49:56 +01:00
Anatol Belski
025290f6d3 Upgrade to re2c 1.1.1 2018-12-26 13:31:49 +01:00
Anatol Belski
1ed89bbba2 Upgrade to bison 3.2.4 2018-12-26 13:30:28 +01:00
Anatol Belski
1d4f4966af Convert eol 2018-09-29 21:01:31 +02:00
Anatol Belski
a5b1137938 Back to dev 2018-09-19 21:20:37 +02:00
Anatol Belski
908f5eeea7 Prepare 2.1.9 2018-09-19 21:19:41 +02:00
Anatol Belski
a7cc2823bf Back to dev 2018-09-12 12:04:30 +02:00
Anatol Belski
ff6a7245a3 Prepare 2.1.9beta1 2018-09-12 12:01:23 +02:00
Anatol Belski
9bb1377d59 Extend README 2018-09-10 17:26:47 +02:00
Anatol Belski
95d712bde7 Rebase MSYS2 DLLs 2018-09-10 17:22:44 +02:00
Anatol Belski
446f4272fe Add tool to rebase MSYS2 DLLs 2018-09-10 17:13:53 +02:00
Anatol Belski
f6b6bd96e0 Upgrade msys2 tools 2018-09-10 13:21:24 +02:00
Anatol Belski
94b3d07034 Upgrade grep 2018-09-10 12:12:14 +02:00
Anatol Belski
6797238516 Extend for MingW, too 2018-09-07 10:00:56 +02:00
Anatol Belski
02f2f372b6 Add note on child process debugging 2018-09-07 09:58:11 +02:00
Anatol Belski
04832718bb Extend debug notes 2018-09-07 09:47:03 +02:00
Anatol Belski
b52a0c281a Add note on debugging 2018-09-07 09:35:24 +02:00
Anatol Belski
bc3606fbaf Back to dev 2018-08-17 15:41:17 +02:00
Anatol Belski
41a63dc0b4 Prepare 2.1.8 2018-08-17 15:39:45 +02:00
Anatol Belski
99ae3ca016 Update MariaDB version 2018-08-17 12:35:35 +02:00
Anatol Belski
777542838c Update Nginx version 2018-08-17 12:35:01 +02:00
Anatol Belski
82987940a0 Update bundled PHP 2018-08-16 06:26:07 +02:00
Anatol Belski
45344d7691 Update wp-cli version 2018-08-16 06:21:57 +02:00
Anatol Belski
02a726256a Update Joomla version 2018-08-16 06:20:01 +02:00
Anatol Belski
0a7732ba09 Update Symfony demo version 2018-08-14 09:31:26 +02:00
Anatol Belski
8583bb4f00 Remove explicit composer requirement 2018-08-14 00:14:59 +02:00
Anatol Belski
d6fc46edfd Convert EOL 2018-08-08 16:16:38 +02:00
Anatol Belski
75740674e5 Extend the requirements note 2018-08-07 20:22:44 +02:00
Anatol Belski
e81199f9af Fix command 2018-08-07 17:55:42 +02:00
Anatol Belski
134556d419 Stick to a specific composer version
For now only, until Symfony demo app has fixed issues.
2018-08-07 17:22:18 +02:00
Anatol Belski
6121772665 Upgrade 7zip 2018-08-07 17:12:53 +02:00
Anatol Belski
61dff2296a Retry downloads 2018-08-07 15:46:00 +02:00
Gemorroj
1b8473489f some minor improvements drop unused imports, unused variables, dirname(__FILE__) -> __DIR__, cs fixes, ...
revert some non-obvious getters, explicit specification of abstract classes

null -> NULL

4 space -> tab
2018-08-07 15:43:01 +02:00
Anatol Belski
e494a28d4c Re-enable Drupal and Joomla training 2018-08-02 07:49:31 +02:00
Anatol Belski
22addaf53e Run more drupal training 2018-08-01 11:50:38 +02:00
Anatol Belski
bb8e318a4a Disable this specific URI for causing unnecessary 404s 2018-08-01 09:56:59 +02:00
Anatol Belski
87b60bc9d5 Handle rmtools branch guess through a short path 2018-08-01 09:10:32 +02:00
Anatol Belski
4936f1d7ca This works only if dealing with a git checkout 2018-07-31 21:31:31 +02:00
Anatol Belski
7d56095191 Add support section 2018-07-31 21:20:12 +02:00
Anatol Belski
27c3431e92 Add fallback for rmtools 2018-07-31 21:05:05 +02:00
Anatol Belski
e5ef707fa0 Missed semicolon 2018-07-31 20:21:20 +02:00
Anatol Belski
7df3de21ce Improve URL gathering 2018-07-31 19:57:37 +02:00
Anatol Belski
64b37312f7 Add special handling for master branch name 2018-07-31 19:29:43 +02:00
Anatol Belski
4a219a0d93 Deactivate Drupal training for now, need test 2018-07-31 19:19:19 +02:00
Anatol Belski
5d97e8e483 Add 7.4 ini 2018-07-31 17:36:25 +02:00
Anatol Belski
9a0f799055 Use normal verbosity 2018-07-26 15:27:32 +02:00
Anatol Belski
4f5028d87a Set some vars that are possible unavailable but required by some
frameworks
2018-07-26 14:58:52 +02:00
Anatol Belski
93437db5ae Fix typo 2018-07-26 14:24:10 +02:00
Anatol Belski
0572a3ec52 Rework initialization, use more default values 2018-07-26 13:05:30 +02:00
Anatol Belski
52badef774 Add more verbosity 2018-07-26 09:41:43 +02:00
Anatol Belski
b01fcd36e7 Remove false info 2018-07-26 09:36:20 +02:00
Anatol Belski
fbc6c40761 Redisable joomla case for now 2018-07-26 09:19:03 +02:00
Anatol Belski
7501f5e567 Disable app debug as that would make warnings to exceptions 2018-07-25 20:29:30 +02:00
Anatol Belski
e51c37a375 Fix EOL 2018-07-25 19:38:02 +02:00
Anatol Belski
bd0ab3474c Fix nginx config 2018-07-25 19:37:46 +02:00
Anatol Belski
056e5643fb Fix drupal init 2018-07-25 19:27:49 +02:00
Anatol Belski
e039de13c4 Further setup fixes 2018-07-25 17:43:33 +02:00
Anatol Belski
59926c2903 Fix method call 2018-07-25 17:27:51 +02:00
Anatol Belski
7d2b6cf86f MariaDB is not required 2018-07-25 17:24:35 +02:00
Anatol Belski
29d54c140e Add drupal, yet disabled 2018-07-25 17:17:31 +02:00
Anatol Belski
2ef8899939 Check also urls with appended query string 2018-07-25 15:21:17 +02:00
Anatol Belski
c259e440b6 Unblock Joomla training 2018-07-25 11:35:19 +02:00
Anatol Belski
5470b5ae58 Fix warning 2018-07-25 11:26:24 +02:00
Anatol Belski
795ac45864 Update Joomla URL 2018-07-25 11:00:06 +02:00
Anatol Belski
77408342bc Update version 2018-07-19 19:05:40 +02:00
Anatol Belski
f9aff35c14 Don't die hard if cleanup was failed.
For now at least. The core bug still needs to be fixed.
2018-07-12 12:12:27 +02:00
Anatol Belski
a827b2f18f Revert "Revert "Check return value""
This reverts commit 5352b3744a.
2018-07-12 10:38:00 +02:00
Anatol Belski
5352b3744a Revert "Check return value"
This reverts commit eb3904741a.
2018-07-11 19:13:54 +02:00
Anatol Belski
d816060d55 Make the random suffix shorter 2018-07-11 13:01:26 +02:00
Anatol Belski
da1e89d23a Append a unique string to the instance id 2018-07-11 11:49:47 +02:00
Anatol Belski
eb3904741a Check return value 2018-07-11 10:31:07 +02:00
Anatol Belski
6dc9fd3293 Update some versions 2018-07-09 19:22:15 +02:00
Anatol Belski
1d2dae619e Integrate file cache into the cache scenario 2018-07-09 19:21:46 +02:00
Anatol Belski
2a7f364792 Avoid terminating FCGI proceses after max requests
If a process is terminated before the data is dumped, it has two
consequences

- the data is possibly lost
- the shutdown sequence data are merged into db

Both cases are bad. Especially we don't want to optimize the shutdown
sequence as it is not relevant. Thus, let the processes run for a while,
get the training data dumped and then terminate those processes
manually.
2018-07-02 11:52:52 +02:00
Anatol Belski
36570ced8e Back to dev 2018-06-28 13:33:34 +02:00
Anatol Belski
7f75a93bdd Prepare 2.1.7beta1 2018-06-28 13:32:15 +02:00
Anatol Belski
44925fe946 It's a dev version 2018-06-28 12:51:50 +02:00
Anatol Belski
e8d07f824b Upgade README 2018-06-28 11:33:23 +02:00
Anatol Belski
a5426ba7bb Upgrade to bison 3.0.5 2018-06-28 11:15:39 +02:00
Anatol Belski
871816e56c Back to dev 2018-06-28 11:13:49 +02:00
Anatol Belski
70c3290c08 Prepare 2.1.6 2018-06-28 11:12:52 +02:00
Anatol Belski
d84784d37a Upgrade vswhere 2018-06-26 22:51:51 +02:00
Anatol Belski
8ad74abf3f Improve error handling for unknown cases 2018-05-11 17:05:39 +02:00
Anatol Belski
9ad145c154 Increase training runs number for symfony_demo_pdo_mysql 2018-05-11 14:11:37 +02:00
Anatol Belski
f3001d950e Fix option description 2018-05-11 13:45:33 +02:00
Anatol Belski
01ab6a1bad Add comment 2018-05-11 13:44:08 +02:00
Anatol Belski
659fb3a71d Produce a warning when unknown training case was requested 2018-05-11 13:31:02 +02:00
Anatol Belski
d7dcab4c2f Add comment 2018-05-11 12:35:42 +02:00
Anatol Belski
15ec0845c4 Allow selective training only with certain cases 2018-05-11 12:22:18 +02:00
Anatol Belski
a1bab3dc92 Back to dev 2018-05-09 11:23:46 +02:00
Anatol Belski
08b81a4ffc Prepare 2.1.5 2018-05-09 11:23:07 +02:00
Anatol Belski
569072060e Change the max runs values for perhaps colliding training scenarios 2018-05-04 14:46:42 +02:00
Anatol Belski
b13a2df162 Improve error handling for dependency path 2018-05-04 11:11:15 +02:00
Anatol Belski
96fa91e16a Back to dev 2018-05-02 14:16:19 +02:00
Anatol Belski
8ad971020a Prepare 2.1.4 2018-05-02 14:15:15 +02:00
Anatol Belski
386d36c251 Add Symfony training case with pdo_mysql 2018-04-04 15:32:46 +02:00
Anatol Belski
bd9c9ca4d8 Require pdo_mysql for pgo 2018-04-04 15:31:58 +02:00
Anatol Belski
1d6561c7d5 Add method to import an sql dump 2018-04-04 15:31:25 +02:00
Anatol Belski
307c5ed4bc Update fetch URLs for PGO servers 2018-04-04 12:40:18 +02:00
Anatol Belski
c6874e5109 Back to dev 2018-03-29 16:51:45 +02:00
Anatol Belski
c3cf4266ad Prepare 2.1.3 release 2018-03-29 16:50:36 +02:00
Anatol Belski
01e4fff84a Upgrade vswhere 2018-03-28 18:11:39 +02:00
Anatol Belski
4357adc956 Back to dev 2018-03-21 13:12:34 +01:00
Anatol Belski
0a33374aed Prepare 2.1.3beta1 2018-03-21 13:09:49 +01:00
Anatol Belski
ff16eebfce Update CA certs 2018-03-19 14:49:18 +01:00
Anatol Belski
afc302d27e Upgrade MSYS2 tools at once 2018-03-19 14:46:33 +01:00
Anatol Belski
e6c79ecad5 Update README 2018-03-19 13:03:44 +01:00
Anatol Belski
80dc35f668 Upgrade re2c 2018-03-19 13:03:22 +01:00
Anatol Belski
bd3e1603a9 Upgrade bundled PHP 2018-03-19 12:51:23 +01:00
Anatol Belski
8505dda9c4 Back to dev 2018-03-14 11:53:39 +01:00
Anatol Belski
b15cdb1f92 Prepare 2.1.2 2018-03-14 11:53:04 +01:00
Anatol Belski
91302e8142 Use SSL explicitly for communitation with windows.php.net 2018-03-12 14:03:00 +01:00
Anatol Belski
f655bcf7d1 Upgrade vswhere 2018-03-12 11:22:11 +01:00
Alexander Gabriel
89bc6e0eb8 Using PHP-X.Y would not work. 2018-03-05 11:29:18 +01:00
Anatol Belski
4d9b189d04 Increase version for dev 2018-02-20 15:33:05 +01:00
Anatol Belski
ff33ae5143 Prepare 2.1.1 2018-02-20 15:32:09 +01:00
Anatol Belski
3cf0f67f27 More robust network error handling 2018-02-20 14:37:15 +01:00
Anatol Belski
b0a93f01c5 Send user agent when fetching 2018-02-20 10:34:30 +01:00
Anatol Belski
e10c86c2d5 Avoid fetching series more than once in the same run 2018-02-20 09:31:08 +01:00
Anatol Belski
20ccc545bd Further notes on custom training case implementation 2018-02-02 17:03:02 +01:00
Anatol Belski
0be0ba3a84 Back to dev 2018-02-02 13:55:54 +01:00
Anatol Belski
c2e3b0ec40 Prepare 2.1.0 2018-02-02 13:54:32 +01:00
Anatol Belski
b0b61457b4 Add note on training case contributing 2018-02-02 13:18:06 +01:00
Anatol Belski
c4ba07a627 Make it a link 2018-02-02 13:15:12 +01:00
Anatol Belski
2c54b0baf5 Edits to PGO description 2018-02-02 13:13:39 +01:00
Anatol Belski
ca942978ee Upgrade 7za 2018-02-02 12:53:12 +01:00
Anatol Belski
6153bb9af2 Mention phpsdk_pgo 2018-02-02 12:44:38 +01:00
Anatol Belski
c4ce390679 Change wording 2018-02-02 09:57:11 +01:00
Anatol Belski
2040ea78bd Use new URLs 2018-02-02 09:42:46 +01:00
Anatol Belski
90f5c1633e Make it a link 2018-02-02 09:41:53 +01:00
Anatol Belski
5a44f0b05d Extend PGO doc 2018-02-02 09:40:14 +01:00
Anatol Belski
c84b3e6b9e Inc minor
The addition of the PGO features is what makes impact.
2018-02-02 08:41:50 +01:00
Anatol Belski
a861392d45 Fix typos 2018-02-02 08:40:11 +01:00
Anatol Belski
0474318721 Remove irrelevant part 2018-02-02 08:31:10 +01:00
Anatol Belski
b21fad7268 Update doc 2018-02-02 08:28:44 +01:00
Anatol Belski
5748dedb3b Update year and fix eol 2018-02-01 17:33:37 +01:00
Anatol Belski
4cea7a4f66 Upgrade bundled PHP 2018-02-01 17:25:23 +01:00
Anatol Belski
7e8235f1a1 Upgrade vswhere 2018-02-01 17:18:20 +01:00
Anatol Belski
1122cbd9d9 Merged PGO integration branch
Squashed commit of the following:

commit 0b963bf9926cfb23b82de5c5ecb802c23ee1d91b
Merge: b0b5b9c 1684c7e
Author: Anatol Belski <ab@php.net>
Date:   Fri Nov 17 15:11:22 2017 +0100

    Merge branch 'master' into pgo_integration

    * master:
      Back to dev
      Prepare 2.0.13
      Upgrade vswhere
      Upgrade bundled PHP
      Unset some tmp vars
      Note on unattended build
      Check for Windows SDK 10.0 for VC14, too
      Pass nologo to vcvarsall.bat
      Unify EOL
      Ensure starter scripts keep the current directory
      Update version in readme
      Add comment
      Fix curl error handling

commit b0b5b9c6e7c2695968b8c184ba4f1542d83261ec
Author: Anatol Belski <ab@php.net>
Date:   Mon Oct 30 14:58:33 2017 +0100

    Warn if a job file is not present, maybe SDK needs reinit

commit d84a2e8432d424471d5aeb77911f71b2d2bb377c
Author: Anatol Belski <ab@php.net>
Date:   Mon Oct 30 07:39:33 2017 +0100

    Add --scenario to the help

commit 9556fad5e5869a6d9ac150ace863c5c304d7c100
Author: Anatol Belski <ab@php.net>
Date:   Sat Oct 28 18:22:31 2017 +0200

    Add scenario based on https://github.com/01org/php_pgo_training_scripts

commit c4e32bbc7142680796a726980a089d98d310797a
Merge: 11dcbc8 1ba1bf1
Author: Anatol Belski <ab@php.net>
Date:   Thu Oct 26 19:32:24 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Back to dev
      Prepare 2.0.12
      Reflect re2c version
      Note about fetching
      Add note about UNIX flavors
      Reflect bison version
      Rephrase
      Back to dev
      Prepare beta3
      Rebase MSYS2 DLLs
      Turn back to dev
      Prepare 2.0.12beta2
      Add missing DLLs
      Back to dev
      Prepare 2.0.12beta1
      Upgrade vswhere
      Upgrade msys2 tools
      Back to dev
      2.0.11

commit 11dcbc88b754729c97aef70442bb1223a142ce09
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 15 11:23:34 2017 +0200

    Add locking to the PGO training and init actions

commit aca33a7e3813e894fa2a0457e31efabaf3e9d3fb
Merge: bcb8fcf c7c874e
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 15 10:48:06 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Improve messaging for locked dependency path

commit bcb8fcf366353b69c6091d30bf3f9859b890ea66
Merge: d86027f 97112e4
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 15 10:36:50 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Refactor lock also wrt shared/exclusive
      Folds

commit d86027fdcca2916c5a31cf24afa540ce90a18249
Merge: 253d590 a5afa11
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 15 09:22:41 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Integrate locking into the dep update process
      Fix and improve lock class
      Add locker class
      Lock while caching
      Folds

commit 253d5908fb57a4e79f08ecbc36a924f0abb42481
Merge: ea6d9d9 d802183
Author: Anatol Belski <ab@php.net>
Date:   Tue Sep 5 18:28:01 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Adjust description
      Support branch recognition when working under dev package

commit ea6d9d957407d98dd05651d87aa3bb173030e679
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 1 16:47:06 2017 +0200

    Increase runs number

commit 157af24f4b3bfc3fee123bdb1ae466cd5295260e
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 1 14:19:07 2017 +0200

    Prepare some debug piece

commit 74ce6dd35020fb7de6277335a17ac7487fddd23b
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 1 14:10:03 2017 +0200

    More for error logging

commit d17b00261ee7d1b70e202010d7946f411b10db7b
Merge: 30dc3ff a97d0bd
Author: Anatol Belski <ab@php.net>
Date:   Fri Sep 1 15:57:21 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Fix Arch determintion
      Add pretty option
      Rework dllmap script
      Note pwgen presence

commit 30dc3ff3c2944dfca7b6d7446ca0cf365c12746e
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 14:18:41 2017 +0200

    Fix binary path

commit e1f2d9c4aaa61ba176cdc22ecd667d617ce315a4
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 14:10:01 2017 +0200

    Extend the firewall template

commit 7cab2769a146fdbd85e4118589962f984d3ca521
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 13:40:57 2017 +0200

    Fix syntax error

commit 74760b1d339ed66ff02f09b1a3ccd11fb9823a8a
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 13:39:31 2017 +0200

    Fix syntax error

commit 9ee0f9f564edcf82893cc8cbe57942b816f54edc
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 13:37:50 2017 +0200

    Typehints

commit 6a86ff3399425224affd35ef97e58f416f9724cb
Merge: a71e63d de669c7
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 13:08:55 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Back to dev
      2.0.10

commit a71e63d44046d503af4a9cbc759ff41f2bc27246
Merge: 5021a30 ceececf
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 13:06:12 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Improve the pack command, show more info and translate the exit code

commit 5021a30fa1a1d9f2f28925504aa4f5b6cacedfae
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 28 12:42:15 2017 +0200

    Add possibility to mark cases inactive

    and turn off the mediawiki case for now.

commit 04f267114f3f5a9d2e53dc7b37dc16e948f71199
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 25 11:23:17 2017 +0200

    Rework HTTP code evaluation and URL setup

commit c6c405968e99c1ceb169eed45f07cef3259aa376
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 15:08:00 2017 +0200

    Further INI templating per scenario

commit 9be8f65856c5ff6d7f313d7b4693f5730e20dc9a
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 13:34:41 2017 +0200

    Decrease numbers yet more, otherwise it's an issue on 32-bit

    Still need to workout something for 64/32-bit separation

commit 6dfe66dcafc8c3c68448a1b1c1fe46d5a5d5ab8e
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 13:31:08 2017 +0200

    Fix wrong ini, no Opcache cli

commit c0556fac6bcb0c609367f93fae302f149d1cde48
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 13:25:26 2017 +0200

    Revert numbers and increase timeout

commit dbc86f72c8de1a7851632285e5eb1efcee1189ca
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 12:50:20 2017 +0200

    Show the training scenario being used

commit c67a5eea36bb97dc2bcae5097abc143c15676e81
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 12:45:23 2017 +0200

    Don't enable opcache on CLI and adjust some numbers

commit 0ec768ca40d11bd84b53b040a42aaf994d9a9f23
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 10:42:55 2017 +0200

    Set fastcgi_read_timeout

commit 6145b841b5f086b7c7f9a02f0d9fd1d41fae4cf2
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 24 10:30:43 2017 +0200

    Set select timeout

commit 600ea8518f5ca2bbbbcc65c8772d283da0da2a15
Author: Anatol Belski <ab@php.net>
Date:   Wed Aug 23 22:56:28 2017 +0200

    Keep FCGI childer some longer alive

commit f6a95c50c5bcb2673721bb63146f87a8fbdcf2c5
Author: Anatol Belski <ab@php.net>
Date:   Wed Aug 23 22:51:47 2017 +0200

    Exclude most of the extension not directly trained

commit 87f4d7393167944108b40b34a6eee1c250f4587d
Author: Anatol Belski <ab@php.net>
Date:   Wed Aug 23 18:36:54 2017 +0200

    Adjust error_log filename

commit e22caaeb390433d3cf6d6dc3322d6ab385780436
Author: Anatol Belski <ab@php.net>
Date:   Wed Aug 23 16:48:47 2017 +0200

    Write error log into the build dir

commit 7bd80a6952bbcef1bbd6e446964285731d898b8e
Merge: acadf54 64c2ac9
Author: Anatol Belski <ab@php.net>
Date:   Wed Aug 23 00:20:01 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Fix deps path recognition
      add deps package command
      reset errorlevel before tool run, set the current on exit

commit acadf54f1576aa81c25613a0121898675777edf7
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 22:40:12 2017 +0200

    Rework the server up routines a bit

commit 6948d0fb99f8f9d52c26d8a6f20aa8de5869b878
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 17:48:48 2017 +0200

    Increase/add startup timeouts

commit d494d3cec28072eb0bf50c5a778a36ec4e86e7ce
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 14:09:59 2017 +0200

    Add redirect URL to the stats

commit 1172928f360b6363bc559c176a3557a821c0e478
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 13:54:33 2017 +0200

    Fix warning

commit ec37bbca6d5ca5a42b4287cceb1decbe414a103a
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 13:48:15 2017 +0200

    Improve Mediawiki URL generation

commit 66280db114863ef221fb33a04734e227adadbb0b
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 13:41:51 2017 +0200

    Add more info about non 200 codes

commit 2fcab615715922ff83076e82ba24a7389a1f1d09
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 11:33:36 2017 +0200

    Set error_log = syslog

commit 0ac29c3d5dd3f5e929970f59c647100c4432ebab
Author: Anatol Belski <ab@php.net>
Date:   Tue Aug 22 11:09:44 2017 +0200

    Back to 8 max children

commit 67cced2a4220b8af809e8ebe7d508c84b7c85735
Author: Anatol Belski <ab@php.net>
Date:   Sat Aug 19 11:07:46 2017 +0200

    set explicit timeouts

commit 491abac200aae57f379be0393f7ed7b061af8089
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 18 23:43:22 2017 +0200

    Use generated config, if available

commit 2ae06304248b0b149a5a3201d619e7edcd330455
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 18 23:07:01 2017 +0200

    Revert "extend is initialized check"

    This reverts commit f365e530cff348bb656a9dd8c887143e9e0559a5.

commit f365e530cff348bb656a9dd8c887143e9e0559a5
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 18 12:36:16 2017 +0200

    extend is initialized check

commit 7905dccad49fc55c26e5d07a8f731c2e21bbbf26
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 18 10:50:25 2017 +0200

    lower default number of fcgi processes

commit 5df59c3a3f0f8c46520bf498e52bfe76506d54d9
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 18 02:59:08 2017 +0200

    some new keys can also be added to the env

commit 5ee2edca7a94a60505924ae998cc647fd332916a
Author: Anatol Belski <ab@php.net>
Date:   Fri Aug 18 00:15:27 2017 +0200

    fix image name

commit b3cadbd2061f0e9c10516fed07e03d6999bd9117
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 23:35:51 2017 +0200

    deactivate joomla training case for now

commit 23baf7931c3d08b6e95d8425cb197365429a0e7e
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 22:21:58 2017 +0200

    fix mysql availability for the external tools

commit 77f6519255bb6ab57bf9c5014ba7a3b8ea394eb2
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 20:25:12 2017 +0200

    fix path separator

commit 63bc4d515256f2bcd68a32b87b5dd095575e49b2
Merge: e4a51d6 eae3aab
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 18:19:40 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      revert the deps path reset part and sync

commit e4a51d67c417829ae78ae5c90fa3b7f9936bdb96
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 16:35:32 2017 +0200

    should be fixed by the previous commit

commit 77e0b65e218710baf456633f880564a8ab50fd37
Merge: 104f57c e7e92b3
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 16:34:33 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      yet more path recognition variant

commit 104f57c232e5f2689a6e7d10415fcb5e95d96003
Merge: aa62653 d158c3c
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 16:19:31 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      add possibility to reevaluate the deps path

commit aa62653187c356897cdd9f0967b8c6553e5e0ba9
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 16:19:08 2017 +0200

    reevaluate deps path

commit 5b54583f7a512a5d774907d9693950b6c82a5241
Merge: 295d9ca 69fb69f
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 15:34:07 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      no realpath needed

commit 295d9cad733884a9588a1949078f5fd4f61e98a6
Merge: c2e9b1d aee165f
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 14:06:43 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      refactor dependency dir recognition

commit c2e9b1d1645e6ff7f54ec308b82292ced9080e56
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 11:19:12 2017 +0200

    rephrase

commit d7f8be2b954fa3eddca8ba0ad7947230c2cdf45a
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 11:14:50 2017 +0200

    some PGO doc

commit 16434a8aff4fcff85d68ecb431691f6d50be5f6e
Author: Anatol Belski <ab@php.net>
Date:   Thu Aug 17 10:37:45 2017 +0200

    add template script for opening required ports

commit 4aa9cba50a9f44fa021f1680ddbfe8073aa4cfcc
Merge: d7f5e8c 0223331
Author: Anatol Belski <ab@php.net>
Date:   Sat Aug 12 14:36:23 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      upgrade vswhere
      extend .gitignore

commit d7f5e8cc6cd331814fe5650bb5a7a97e41453e73
Author: Anatol Belski <ab@php.net>
Date:   Wed Aug 9 22:58:34 2017 +0200

    add ready mode for pgo

commit 8b64fb7f5e43b488c8628440df28698443908e9b
Author: Anatol Belski <ab@php.net>
Date:   Mon Aug 7 18:30:19 2017 +0200

    add 7.3 inis

commit 323188a802abcb1a32fb5a14a64ba52fa51cfd19
Merge: e18835e 7d72596
Author: Anatol Belski <ab@php.net>
Date:   Wed Jul 26 17:04:27 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      back to dev
      prepare 2.0.9
      sync with eol change

commit e18835e055ecc41818d1b1bfac7ba7705153a515
Author: Anatol Belski <ab@php.net>
Date:   Sun Jul 23 21:00:44 2017 +0200

    EOL changes

commit 678173e046b0beac56182a31e16354c0533b0a50
Merge: dd2527b eaa6ff5
Author: Anatol Belski <ab@php.net>
Date:   Sun Jul 23 20:58:32 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      add more file types for eol mitigation
      extend redme

commit dd2527b248798bcbff1b0f675b40015069c07d4f
Merge: 0922158 0319dc0
Author: Anatol Belski <ab@php.net>
Date:   Sun Jul 23 20:43:00 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      add gitattributes
      add comment

commit 092215893e3480ec693fba67702b9b65d494402c
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 20:52:24 2017 +0200

    improve url extraction

commit f650e1e7ebef4d43fa0e9e9cc9054baa090be90b
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 20:35:45 2017 +0200

    add basic mediawiki support

commit 538fe384e708a3f5194eed153a933e73cd4278e8
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 20:34:49 2017 +0200

    comment out PostgreSQL for now

commit 84e7a027d366ada3aafe3d9cf988660d0060c73a
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 20:31:43 2017 +0200

    comment out debug piece

commit e096090f17f14a681a32285ad5ffdda45ca91cc8
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 18:19:25 2017 +0200

    some reworks, mainly to improve postgres handling

commit 263786e8300fa1a4f8b3ee1ab3a21d8bd8802dac
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 11:12:28 2017 +0200

    enable pgsql ext for training

commit 4471fc5dfce5a9c75b818540c8a0772a4445c4f7
Author: Anatol Belski <ab@php.net>
Date:   Fri Jul 21 09:42:18 2017 +0200

    remove debug output

commit fd1467850919d003d4e66beb18d4005ceb212774
Merge: ccb26ee 55fddef
Author: Anatol Belski <ab@php.net>
Date:   Thu Jul 20 23:55:26 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      back to dev
      prepare 2.0.8

commit ccb26eebeed1c637c4ce603bc68ff45aaebc680e
Author: Anatol Belski <ab@php.net>
Date:   Thu Jul 20 18:15:11 2017 +0200

    add Joomla support

commit 9e71002f9017c2ebc9509b75c3798207e18e8e87
Author: Anatol Belski <ab@php.net>
Date:   Thu Jul 20 15:56:23 2017 +0200

    add basic composer fetch

commit 21956c5dca4a7c0f99cc15cf3457b5d9722d3c6f
Merge: 63f3263 8e3d439
Author: Anatol Belski <ab@php.net>
Date:   Tue Jul 18 20:35:31 2017 +0200

    Merge branch 'master' into pgo_integration

    * master:
      Support also preview releases
      upgrade bundled php
      back to dev
      prepare 2.0.7
      improve branch name guessing
      fixed option handling, thanks Kalle
      upgrade to vswhere 2.0.2
      extend deps update comment
      task.exe commen

commit 63f3263b2b129d1de4e83533f9b6d2b8eb1712e4
Merge: a0d8788 9e5e7e6
Author: Anatol Belski <ab@php.net>
Date:   Fri Jun 16 02:43:11 2017 +0200

    Merge branch 'master' into pgo_integration

commit a0d8788233633231ac1f7a5208284edacbb7ec6b
Author: Anatol Belski <ab@php.net>
Date:   Wed Jun 7 17:48:25 2017 +0200

    change default pg port, add some util methods

commit 661fe8992638c4af92793f8464038ac5dc044f5b
Author: Anatol Belski <ab@php.net>
Date:   Wed Jun 7 14:24:14 2017 +0200

    basic Postgres stuff

commit 7b3b0b96184cfe89c052292ef6e71aa05f96b548
Author: Anatol Belski <ab@php.net>
Date:   Wed Jun 7 14:23:34 2017 +0200

    remove dead code

commit 00670fdc005244c26ff9248857de264e344d9348
Author: Anatol Belski <ab@php.net>
Date:   Wed Jun 7 13:23:34 2017 +0200

    respect mariadb port, user creation is still to go if needed

commit b73f3eda83152e526bd6eaba8a3c3470a696b300
Author: Anatol Belski <ab@php.net>
Date:   Wed Jun 7 13:22:28 2017 +0200

    fix wrong merge

commit 6ca5d948e173956618bd541a2daf26e92bfe7748
Merge: 7d8bd88 99efb73
Author: Anatol Belski <ab@php.net>
Date:   Mon Jun 5 21:01:47 2017 +0200

    Merge branch 'master' into pgo_integration

commit 7d8bd88b029b3c05e072f77d2c287bee51f58672
Author: Anatol Belski <ab@php.net>
Date:   Mon Jun 5 13:39:33 2017 +0200

    forcibly propagate errorlevel

commit d2f3bb5245640e3f5a1b44530be3ed2df775ee53
Author: Anatol Belski <ab@php.net>
Date:   Mon Jun 5 13:38:16 2017 +0200

    forcibly propagate errorlevel

commit 0d5c0dc71ce4dd4b4578d490cccd28ebcd830de3
Author: Anatol Belski <ab@php.net>
Date:   Sat Jun 3 10:21:41 2017 +0200

    hide warning

commit 276c3cdd6214d974e294bf177f601ebf8d33f92d
Author: Anatol Belski <ab@php.net>
Date:   Fri Jun 2 21:46:56 2017 +0200

    remove existing dir before renaming

commit 2bc6e2324de50d43c74e48e30a6a0799f892aa22
Author: Anatol Belski <ab@php.net>
Date:   Fri Jun 2 21:35:32 2017 +0200

    fix reinit and clean init mode

commit 8527d983cf43b32d5efbf3674cebfb62302e4e7a
Author: Anatol Belski <ab@php.net>
Date:   Fri Jun 2 21:11:48 2017 +0200

    lower wp-cli version, seems there are issues with 1.2.0

commit fbad30b92e9d498e2fadee4ac38f99c0ab825a17
Author: Anatol Belski <ab@php.net>
Date:   Fri Jun 2 21:07:30 2017 +0200

    more compact code using a worker for init preparation

commit 83c24e93f6ceaa2d55f070e92713a8b91362e27f
Author: Anatol Belski <ab@php.net>
Date:   Fri Jun 2 17:19:59 2017 +0200

    allow rename dest dir when unzip

commit 81f0d6f24db4af54a161e1cd1b258618cea47809
Author: Anatol Belski <ab@php.net>
Date:   Thu Jun 1 21:44:02 2017 +0200

    don't keep merged pgc files

commit 8b9fd7ee7c2437645755b69560630399e15ac31e
Author: Anatol Belski <ab@php.net>
Date:   Thu Jun 1 21:21:23 2017 +0200

    fix wptest dir name

commit e29b5bb7d89f7da5f71eabfa2c3f06e7a514a059
Author: Anatol Belski <ab@php.net>
Date:   Thu Jun 1 21:20:36 2017 +0200

    ups

commit d18fba6792e23f17fac605d1ea432fc3048e862d
Author: Anatol Belski <ab@php.net>
Date:   Thu Jun 1 20:56:27 2017 +0200

    full implement wordpress init/train

commit 2a5000c399f799ed3c56bbd61305c4fd7a395c09
Author: Anatol Belski <ab@php.net>
Date:   Wed May 31 19:43:45 2017 +0200

    more fine clean

commit 7b736c135fa3c1131d0a2f53b2de477f77904f12
Author: Anatol Belski <ab@php.net>
Date:   Wed May 31 19:12:06 2017 +0200

    cleanup the pgc files before training starts

commit 63ea1c84425ba56df8fd0f789a884bfe6c859018
Author: Anatol Belski <ab@php.net>
Date:   Wed May 31 18:03:48 2017 +0200

    Implement training with PGO data dumping

commit 57b529646182344f7962a966347957da97d6c934
Author: Anatol Belski <ab@php.net>
Date:   Wed May 31 16:12:02 2017 +0200

    fix nginx init

commit 76aee824bb21f2298bb484aa6d60d5448cb4c985
Author: Anatol Belski <ab@php.net>
Date:   Wed May 31 15:55:55 2017 +0200

    next round refactor already done stuff

commit c8ce3afec0225028375c81fcc40a13ba7e0cd23a
Author: Anatol Belski <ab@php.net>
Date:   Wed May 31 00:05:15 2017 +0200

    start to implement training, improve templating

commit 61837905abb18bef86ad56bc4b52132c0cd1e3a6
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 19:35:44 2017 +0200

    almost finished setting up the symfony demo case

commit 1a3c9ebfd428ba21a65dd9e2be34c6b3a2f88960
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 16:22:04 2017 +0200

    remove debug out

    remove echos

commit 70d937c18bae8b7baf4ed313c47f2001e8e43e1d
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 16:21:13 2017 +0200

    start with training case implementation

commit 414fd54cfe8b14500eb7663396cc4157d1c52d1d
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 14:34:27 2017 +0200

    improvements to db interface

commit e0b1a86dbed3377682b4057542809d343a3598e8
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 14:33:38 2017 +0200

    ignore *.swp

commit c9aa8cad0888d82753b32d6a4c0457b67bd2e81b
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 14:18:08 2017 +0200

    implement force, fix NGINX config

commit 6c61d14140e45552dabd45a13fad1844c9e84329
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 14:17:46 2017 +0200

    remove not required file

commit c1bec7398c130a288549a90ef1ed26bfe9d3fcc0
Author: Anatol Belski <ab@php.net>
Date:   Mon May 29 13:46:31 2017 +0200

    basic PHP setup and usable CLI

commit d2227d31799030334b0a635ea1fb0474dea23416
Author: Anatol Belski <ab@php.net>
Date:   Fri May 26 13:27:23 2017 +0200

    add license

commit f96743bd1a89d068c49954ac5e46a8e302e44d85
Author: Anatol Belski <ab@php.net>
Date:   Tue May 23 18:31:20 2017 +0200

    basic init/up/down for MariaDB and some bug fixes

commit 14bf57ceab9586e365ad43de2250629249f8a198
Author: Anatol Belski <ab@php.net>
Date:   Tue May 23 17:39:22 2017 +0200

    improve config handling, more on nginx management

commit 8c407130658ac56b2d360b664c35bb95f5ffb5ec
Author: Anatol Belski <ab@php.net>
Date:   Tue May 23 17:29:09 2017 +0200

    switch to json for internal conf

commit e744887d307e8e65a2666fd9baf1b94ae33f1e12
Author: Anatol Belski <ab@php.net>
Date:   Tue May 23 17:28:04 2017 +0200

    extend gitignore

commit 88dd8f0cd5928b25e8af919b61168056946b64b5
Author: Anatol Belski <ab@php.net>
Date:   Tue May 23 16:10:57 2017 +0200

    basic nginx init routines and expand on config

commit 0c4f660904370b3aa9d002118a8b923ffaa132e7
Author: Anatol Belski <ab@php.net>
Date:   Mon May 22 20:46:04 2017 +0200

    add unzip to fileops and some more refactoring

commit f1aeb9ac43dd817c0ac208714943162117329e3f
Author: Anatol Belski <ab@php.net>
Date:   Mon May 22 19:17:01 2017 +0200

    group ns

commit f92a4b45a58f6969fdb139278157ff5556cc9879
Author: Anatol Belski <ab@php.net>
Date:   Mon May 22 19:15:56 2017 +0200

    use curl for fetches

commit 09e01d62cb74aba6158943e0418c94f09e136248
Author: Anatol Belski <ab@php.net>
Date:   Mon May 22 17:58:55 2017 +0200

    fix branch name recognition when no cli opt passed

commit 50c54bdacc0bc0383ed5feb592bfc16092ffb173
Author: Anatol Belski <ab@php.net>
Date:   Mon May 22 17:22:50 2017 +0200

    simplify

commit 5e293210c678729c67c75ea4112f12832375bdf3
Author: Anatol Belski <ab@php.net>
Date:   Mon May 22 17:14:13 2017 +0200

    yet basic PGO stuff
2018-01-12 18:02:50 +01:00
Anatol Belski
7a054e9e6d Revert "Upgrade vswhere"
This reverts commit a6f819dd75.
2018-01-12 18:01:22 +01:00
Anatol Belski
a6f819dd75 Upgrade vswhere 2018-01-10 17:45:18 +01:00
Anatol Belski
b8b32aaa27 Avoid each() 2018-01-10 17:34:19 +01:00
Anatol Belski
dbeb065486 Use spl_autoload_register() 2018-01-10 17:33:51 +01:00
Anatol Belski
c2880591f3 Mention ConEmu 2017-11-24 10:34:24 +01:00
Anatol Belski
6911eacb83 Update example cmd 2017-11-24 10:32:22 +01:00
姚文强
218f23ab93 fix typo (#23)
Thanks :)
2017-11-24 10:31:19 +01:00
230 changed files with 49254 additions and 8204 deletions

4
.gitignore vendored
View File

@@ -20,3 +20,7 @@ oracle
#pgo-build
#rmtools*
phpsdk-local.bat
pgo/work
!pgo/tpl/php
!lib/php/libsdk/SDK/Build/PGO/Server/PHP
*.swp

18
LICENSE
View File

@@ -1,9 +1,9 @@
Copyright 2017 Anatol Belski
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Copyright 2017-2018 Anatol Belski
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

112
README.md
View File

@@ -1,6 +1,6 @@
# PHP SDK
PHP SDK is a tool kit for Windows PHP builds
PHP SDK is a tool kit for Windows PHP builds.
# License
@@ -8,31 +8,30 @@ The PHP SDK itself and the SDK own tools and code are licensed under the BSD 2-C
# Overview
The PHP SDK 2.0 is compatible with PHP 7.0 and above. The compatibility with [older versions](http://windows.php.net/downloads/php-sdk/php-sdk-binary-tools-20110915.zip "php-sdk-binary-tools-20110915.zip") is kept, also available from the [legacy branch](https://github.com/OSTC/php-sdk-binary-tools/tree/legacy). The toolset was significantly revamped. Newer tools are now available, better workflows are now possible. The toolset consists on a mix of the hand written scripts, selected MSYS2 parts and standalone programs.
The PHP SDK 2.0+ is compatible with PHP 7.0 and above. The compatibility with [older versions](http://windows.php.net/downloads/php-sdk/php-sdk-binary-tools-20110915.zip "php-sdk-binary-tools-20110915.zip") is kept, also available from the [legacy branch](https://github.com/Microsoft/php-sdk-binary-tools/tree/legacy). The toolset was significantly revamped. Newer tools are now available, better workflows are now possible. The toolset consists on a mix of the hand written scripts, selected MSYS2 parts and standalone programs.
# Requirements
- `Visual C++ 2015` or `Visual C++ 2017` must be installed prior SDK usage
- if `Cygwin` is installed, please read notes in the pitfalls section
- if a 64-bit build is intended, a 64-bit system is required. Cross compilation of 64-bit on 32-bit system is not supported at the moment
- A 64-bit build host
- `Visual C++ 2015` or `Visual C++ 2017` must be installed prior SDK usage (be sure to install the C++ dev, .NET dev and the Windows SDK components)
- if `Cygwin`, `MingW` or any other cross solution is installed, please read notes in the pitfalls section
- The PHP SDK was successfully tested on Windows 7 or later, earlier versions might work but are not recommended
# Tools
All the tools included are either scripts or 32-bit binaries. They are therefore runable on any of x86 or x64 supported Windows system.
## SDK
- starter scripts, named phpsdk-&lt;crt&gt;-&lt;arch&gt;.bat
- `phpsdk_buildtree` - initialize the development filesystem structure
- `phpsdk_deps` - handle dependency libraries
- `phpsdk_version` - show SDK version
- `phpsdk_dllmap` - create a JSON listing of DLLs contained in zip files
- `phpsdk_pgo` - run PGO training
- `phpsdk_version` - show SDK version
- `task.exe` - wrapper to hide the given command line
## Other tools
- `bison` 3.0.4, `re2c` 1.0.2, `lemon`
- `bison` 3.2.4, `re2c` 1.1.1, `lemon`
- `awk`, `gawk`, `sed`, `grep`
- `diff`, `diff3`, `patch`
- `md5sum`, `sha1sum`, `sha224sum`, `sha256sum`, `sha384sum`, `sha512sum`
@@ -47,6 +46,7 @@ These are not included with the PHP SDK, but might be useful. While Visual C++ i
- `Cppcheck` - used for static analysis
- `clang` - useful for experimental builds and for static analysis
- `ICC` - useful for experimental builds
- `ConEmu` - console emulator with tabs and more
# Usage
@@ -58,33 +58,33 @@ It is not required to hold the source in the PHP SDK directory. It could be usef
## Basic usage example
- `git clone https://github.com/OSTC/php-sdk-binary-tools.git c:\php-sdk`
- `git clone https://github.com/Microsoft/php-sdk-binary-tools.git c:\php-sdk`
- `cd c:\php-sdk`
- `git checkout php-sdk-2.0.12` or later
- `git checkout php-sdk-2.1.9` or later
- invoke `phpsdk-vc15-x64.bat`
- `phpsdk_buildtree phpmaster`
- `git clone https://github.com/php/php-src.git && cd php-src`, or fetch a zipball
- `phpsdk_deps --update --branch master`, use PHP-X.Y for a non master branch
- `phpsdk_deps --update --branch master`, use `phpsdk_deps --update --branch X.Y` for a non master branch
- do the build, eg. `buildconf && configure --enable-cli && nmake`
More extensive documentation can be found on the [wiki](https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2 "PHP wiki page").
## The old way
- `git clone https://github.com/OSTC/php-sdk-binary-tools.git c:\php-sdk`
- `git clone https://github.com/Microsoft/php-sdk-binary-tools.git c:\php-sdk`
- follow the instructions on the PHP [wiki page](https://wiki.php.net/internals/windows/stepbystepbuild "PHP wiki page")
# Customizing
## Custom environment setup
A sript called phpsdk-local.bat has to be put into the PHP SDK root. If present, it will be automatically picked up by the starter script. A template for such a script is included with the PHP SDK. This allows to automatically meet any required preparations, that are not foreseen by the standard PHP SDK startup. Be careful while creating your own phpsdk-local. It's your responsibility to ensure the regular PHP SDK startup isn't broken after phpsdk-local.bat was injected into the startup sequence.
A script called phpsdk-local.bat has to be put into the PHP SDK root. If present, it will be automatically picked up by the starter script. A template for such a script is included with the PHP SDK. This allows to automatically meet any required preparations, that are not foreseen by the standard PHP SDK startup. Be careful while creating your own phpsdk-local. It's your responsibility to ensure the regular PHP SDK startup isn't broken after phpsdk-local.bat was injected into the startup sequence.
## Console emulator integration
The starter scripts can be also easy integrated with the consoles other than standard cmd.exe. For the reference, here's an example ConEmu task
`C:\php-sdk\phpsdk-vc14-x64.bat -cur_console:d:C:\php-sdk\php70\vc14\x64\php-src`
`C:\php-sdk\phpsdk-vc15-x64.bat -cur_console:d:C:\php-sdk\php72\vc15\x64\php-src`
## Unattended builds
@@ -106,6 +106,82 @@ If the PHP SDK is kept as a git checkout, merely what is needed instead is to gi
The SDK tools are based on the KISS principle and should be kept so. Basic tools are implemented as simple batch script. The minimalistic `PHP` is available for internal SDK purposes. It can be used, if more complexity is required. A suitable PHP binary is bound with the PHP SDK. If you have an idea for some useful tool or workflow, please open a ticket or PR, so it can be discussed, implemented and added to the SDK. By contributing an implementation, you should also accept the SDK license.
# PGO
As of the version 2.1.0, the SDK includes a tool for the [PGO](https://docs.microsoft.com/en-us/cpp/build/reference/profile-guided-optimizations) optimization. Several training cases are included by default, which are based on the real life opensource applications. The PGO optimization can give an overall speedup up to 30%. The work on adding more training scenarios for the widely used opensource apps is ongoing. If you have a training scenario to share, please create a PR to this repo. Any new training cases are thoroughly validated through the extensive performance tests.
## Preparing PGO training environment
- the pgo folder in the SDK root dir contains templates and scenarios for PGO training
- adjust and execute [doc/phpsdk_pgo_prep_elevated.bat.example](doc/phpsdk_pgo_prep_elevated.bat.example) to open ports required for PHP SDK training servers
- run `phpsdk_pgo --init`
## Creating PGO build
- compile PHP configured using `--enable-pgi`
- run `phpsdk_pgo --train`
- run `nmake clean-pgo`
- rebuild PHP `--with-pgo`
## Adding custom PGO training scenario
A custom scenario can be used to produce a custom PHP binary dedicated to an arbitrary application.
The existing training cases can be found in [pgo/cases](pgo/cases). Assumed the case would be named `myapp`, the general steps to setup were
- create the case directory under `pgo/cases/myapp`
- create `pgo/cases/myapp/phpsdk_pgo.json` with the necessary definitions
- create `pgo/cases/myapp/nginx.partial.conf` with a partial NGINX template
- create `pgo/cases/myapp/TrainingCaseHandler.php` with a class as defined in the [interface](lib/php/libsdk/SDK/Build/PGO/Interfaces/TrainingCase.php)
After a training case is implemented and put under `pgo/cases`, the work environment needs to be reinitialized. The tool puts all the training data and necessary applications under `pgo/work`. Rename or remove that directory and rerun `phpsdk_pgo --init`.
To skip a training case, add a file named `inactive` into the case folder.
# Debugging PHP
This part covers debugging possibilities for the builds produced by the native VS compilers.
For the cross compiled builds produced with toolsets other than VC++, please check the
documentation for the corresponding toolsets. In any case, general principles on debugging
native programs apply.
Either a debug build of PHP or enabled debug symbols are required to be able to debug PHP.
A debug build is usually more suitable for the development process and can be produced by
adding `--enable-debug` to the configure options. A release build with debug symbols can
be produced by adding `--enable-debug-pack`. These options are mutually exclusive.
## Debugging with Visual Studio
- Configure with either `--enable-debug` or `--enable-debug-pack`.
- A debug build might bring better experience for dev, but sometimes you want to debug a release build.
- `nmake run ARGS=yourscript.php DEBUGGER=1`, that will open a Visual Studio window.
- Any additional runtime options for PHP or the script executed go to ARGS, too.
- Select `Debug -> New Breakpoint -> Function Breakpoint` and add a function where the debugger should break.
- Click `Start`.
Adding a breakpoint before starting debugging might be not necessary, if a crash is debugged. When such a script runs
under the debugger, the debugger will stop at the crashing point. In that case, a breakpoint can be added
around the crashed code directly.
## Debugging test suite with Visual Studio
The [Microsoft Child Process Debugging Power Tool](https://marketplace.visualstudio.com/items?itemName=vsdbgplat.MicrosoftChildProcessDebuggingPowerTool)
plugin for Visual Studio is required. After installing it, following these steps
- `nmake test TESTS=ext/myext/tests/sometest.phpt DEBUGGER=1`
- Select `Debug -> Other Debug Targets -> Child Process Debugging Settings` and enable child process debugging.
- If necessary, add a breakpoint and start debugging as described in the previous section.
## Debugging with WinDbg
PHP can also be debugged with the tools from the WinDbg package. There is currently no way
implemented in the Makefile to start the WinDbg integrated, so it needs to de done manually.
Either a debug build or a release build with debug symbols is still required, as described
previously.
# Support
- Join `#winphp-dev` on Freenode to discuss any ideas or questions
- File an issue on GitHub
# Pitfalls
- SDK or PHP sources put into paths including spaces might cause issue.
@@ -115,6 +191,8 @@ The SDK tools are based on the KISS principle and should be kept so. Basic tools
- Tools, based on MSYS2, only accept paths with forward slashes.
- Both Visual C++ toolset and the Windows SDK components have to be installed for the PHP SDK to work properly.
- The VC++ toolset is still requried, even if another compiler, fe. clang, is intended to be used.
- task.exe is not a console application, some systems might not propagate exit code except the batch is explicitly run from `cmd /c`, etc.
- `task.exe` is not a console application, some systems might not propagate exit code except the batch is explicitly run from `cmd /c`, etc.
- `7za` should be prefered over `unzip` and `zip` for compatibility reasons.
- If you experince some strange crashes on MSYS2 tools, try the phpsdk_rebase_msys2 tool. MSYS2 tools might be have unstable
on ASLR enabled systems.

View File

@@ -1 +1 @@
2.0.14-dev
2.2.0beta5

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/php/libcrypto-1_1.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/php/libssl-1_1.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -10,11 +10,11 @@ rem otherwise - retain the old behavior, create structs for all the known build
cmd /c "exit /b 0"
if "%PHP_SDK_ARCH%" NEQ "" (
if "%PHP_SDK_VC%" NEQ "" (
MD %_%\%PHP_SDK_VC%\%PHP_SDK_ARCH%\deps\bin
MD %_%\%PHP_SDK_VC%\%PHP_SDK_ARCH%\deps\lib
MD %_%\%PHP_SDK_VC%\%PHP_SDK_ARCH%\deps\include
cd %_%\%PHP_SDK_VC%\%PHP_SDK_ARCH%
if "%PHP_SDK_VS%" NEQ "" (
MD %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%\deps\bin
MD %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%\deps\lib
MD %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%\deps\include
cd %_%\%PHP_SDK_VS%\%PHP_SDK_ARCH%
goto exit
)
goto create_all

View File

@@ -1,6 +1,6 @@
<?php
include dirname(__FILE__) . "/../lib/php/libsdk/autoload.php";
include __DIR__ . "/../lib/php/autoload.php";
use SDK\{Config, Exception};
@@ -36,7 +36,7 @@ try {
switch ($name) {
default:
throw new Exception("Unknown switch '$name'");
break;
break;
case "h":
case "help":
@@ -126,19 +126,11 @@ try {
usage(3);
}
/* The current CRT needs to match the config one. */
$active_crt = getenv("PHP_SDK_VC");
$active_crt = getenv("PHP_SDK_VS");
if (Config::getCurrentCrtName() != $active_crt && !$force) {
throw new Exception("Active CRT '$active_crt' differs from the branch CRT '" . Config::getCurrentCrtName() . "'.");
}
if (NULL === Config::getCurrentStabilityName()) {
if ("master" == Config::getCurrentBranchName()) {
Config::setCurrentStabilityName("staging");
} else {
Config::setCurrentStabilityName("stable");
}
}
$branch_data = Config::getCurrentBranchData();
echo "\nConfiguration: " . Config::getCurrentBranchName() . "-$branch_data[crt]-$branch_data[arch]-$branch_data[stability]\n\n";

View File

@@ -29,10 +29,10 @@ $flags = 0;
$opt = getopt($sopt, $lopt);
foreach ($opt as $name => $val) {
switch ($name) {
case "p":
case "pretty":
$flags = JSON_PRETTY_PRINT;
break;
case "p":
case "pretty":
$flags = JSON_PRETTY_PRINT;
break;
}
}
@@ -85,16 +85,16 @@ foreach ($dirs as $path) {
$dlls = array();
for( $i = 0; $i < $zip->numFiles; $i++ ){
$stat = $zip->statIndex( $i );
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
if (substr($stat['name'], -3) != "dll") {
continue;
}
$dlls[] = basename($stat['name']);
}
$zip->close();
unset($zip);

View File

@@ -24,7 +24,7 @@ if "%PHP_SDK_ARCH%"=="x64" (
echo Build architecture: 32-bit
)
echo Visual C++: %PHP_SDK_VC_NUM%
echo Visual C++: %PHP_SDK_VC_TOOLSET_VER%
echo PHP-SDK path: %PHP_SDK_ROOT_PATH%

14
bin/phpsdk_pgo.bat Normal file
View File

@@ -0,0 +1,14 @@
@echo off
if "%PHP_SDK_PHP_CMD%"=="" (
call %~dp0phpsdk_setvars.bat
if "!PHP_SDK_PHP_CMD!"=="" (
echo PHP SDK is not setup
exit /b 3
)
)
cmd /c %PHP_SDK_PHP_CMD% %PHP_SDK_BIN_PATH%\phpsdk_pgo.php %*
exit /b %errorlevel%

134
bin/phpsdk_pgo.php Normal file
View File

@@ -0,0 +1,134 @@
<?php
include __DIR__ . "/../lib/php/autoload.php";
use SDK\Config;
use SDK\Exception;
use SDK\Build\PGO\Controller;
$sopt = "itudhs:frc:";
$lopt = array("init", "train", "up", "down", "help", "scenario:", "force", "ready", "cases:");
$cmd = NULL;
/* TODO For now we simply check the current php build, this could be extended to take arbitrary binaries. */
$deps_root = NULL;
$php_root = NULL;
$scenario = NULL;
$force = false;
$cases = NULL;
try {
$opt = getopt($sopt, $lopt);
foreach ($opt as $name => $val) {
switch ($name) {
case "i":
case "init":
$cmd = "init";
break;
case "ready":
$cmd = "check_init";
break;
case "t":
case "train":
$cmd = "train";
break;
case "u":
case "up":
$cmd = "up";
break;
case "d":
case "down":
$cmd = "down";
break;
case "s":
case "scenario":
$scenario = $val;
break;
case "f":
case "force":
$force = true;
break;
/* XXX This option is for now only integrated for training. It
would make sense to integrate it also with init. */
case "c":
case "cases":
$cases = explode(",", $val);
break;
case "h": case "help":
usage(0);
break;
}
}
if (NULL === $cmd) {
usage();
}
$deps_root = Config::getDepsLocalPath();
if ("check_init" != $cmd) {
/* XXX Need these checks for more safety, as long as the dist zipballs are not supported. */
if (!file_exists("Makefile")) {
throw new Exception("Makefile not found. Arbitrary php snapshots are not supported yet, switch to the php source dir.");
}
if (preg_match(",BUILD_DIR=(.+),", file_get_contents("Makefile"), $m)) {
$php_root = trim($m[1]);
}
if (!$php_root || !file_exists($php_root)) {
throw new Exception("Invalid php root dir encountered '$php_root'.");
}
}
$controller = new Controller($cmd, $scenario, $cases);
$controller->handle($force);
if ("check_init" == $cmd) {
/* 0 for success, fail otherwise. */
$ret = ($controller->isInitialized() === false);
exit((int)$ret);
}
/*$env = getenv();
$env["PATH"] = $deps_root . DIRECTORY_SEPARATOR . "bin;" . $env["PATH"];
$php = $php_root . DIRECTORY_SEPARATOR . "php.exe";
$php = $php_root . DIRECTORY_SEPARATOR . "php.exe";*/
} catch (Throwable $e) {
throw $e;
exit(3);
}
function usage(int $code = -1)
{
echo "PHP SDK PGO training tool.", PHP_EOL;
echo "Usage: ", PHP_EOL, PHP_EOL;
echo "Commands:", PHP_EOL;
echo " -i --init Initialize training environment.", PHP_EOL;
echo " -t --train Run training. This involves startup, training and shutdown.", PHP_EOL;
echo " -u --up Startup training environment.", PHP_EOL;
echo " -d --down Shutdown training environment.", PHP_EOL;
echo " -f --force Force requested operation. Not every option can be forced.", PHP_EOL;
echo " -s --scenario Run training with a specified scenario.", PHP_EOL;
echo " -c --cases Run training with specified cases only. If omited, all the active cases will be used.", PHP_EOL;
/*echo " -p --php-root PHP binary to train.", PHP_EOL;*/
$code = -1 == $code ? 0 : $code;
exit($code);
}
function msg(string $s, int $code = 0) {
echo $s, PHP_EOL;
exit($code);
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/

View File

@@ -0,0 +1,40 @@
@echo off
setlocal enableextensions enabledelayedexpansion
set PHPSDK_MSYS2_BASE_ADDR=0x100400000
set PHPSDK_MSYS2_BASE_DYNAMIC=0
:getopt
if /i "%1" equ "--help" goto help
if /i "%1" equ "--addr" (
set PHPSDK_MSYS2_BASE_ADDR=%2 & shift
for /l %%a in (1,1,100) do if "!PHPSDK_MSYS2_BASE_ADDR:~-1!"==" " set PHPSDK_MSYS2_BASE_ADDR=!PHPSDK_MSYS2_BASE_ADDR:~0,-1!
)
shift
if /i "%1" equ "--dynamic" (
set PHPSDK_MSYS2_BASE_DYNAMIC=1
shift
)
if not (%1)==() goto getopt
IF "1" EQU "%PHPSDK_MSYS2_BASE_DYNAMIC%" (
echo Rebasing MSYS2 DLLs to load at a dynamic address
editbin /NOLOGO /DYNAMICBASE %PHP_SDK_ROOT_PATH%\msys2\usr\bin\*.dll
) else (
echo Rebasing MSYS2 DLLs to load at %PHPSDK_MSYS2_BASE_ADDR%
editbin /NOLOGO /REBASE:BASE=%PHPSDK_MSYS2_BASE_ADDR%,DOWN %PHP_SDK_ROOT_PATH%\msys2\usr\bin\*.dll
)
set PHPSDK_MSYS2_BASE_ADDR=
set PHPSDK_MSYS2_BASE_DYNAMIC=
GOTO EXIT
:help
echo phpsdk_rebase_msys2 ^<address^>
echo Rebase MSYS2 DLLs to the given address. If ommited, default is 0x100400000.
:EXIT
exit /b %errorlevel%

View File

@@ -15,31 +15,33 @@ if "%2"=="" goto :help
cmd /c "exit /b 0"
set PHP_SDK_VC=%1
if /i not "%PHP_SDK_VC:~0,2%"=="vc" (
set PHP_SDK_VS=%1
if /i not "%PHP_SDK_VS:~0,2%"=="vc" (
if /i not "%PHP_SDK_VS:~0,2%"=="vs" (
:malformed_vc_string
echo Malformed CRT string "%1"
set PHP_SDK_VC=
goto out_error
echo Malformed CRT string "%1"
set PHP_SDK_VS=
goto out_error
)
)
if ""=="%PHP_SDK_VC:~2%" (
if ""=="%PHP_SDK_VS:~2%" (
goto malformed_vc_string
)
set /a TMP_CHK=%PHP_SDK_VC:~2%
set /a TMP_CHK=%PHP_SDK_VS:~2%
if 14 gtr %TMP_CHK% (
if "0"=="%TMP_CHK%" (
if not "0"=="%PHP_SDK_VC:~2%" (
if not "0"=="%PHP_SDK_VS:~2%" (
set TMP_CHK=
goto malformed_vc_string
)
)
echo At least vc14 is required
set PHP_SDK_VC=
set PHP_SDK_VS=
set TMP_CHK=
goto out_error
)
set PHP_SDK_VC_NUM=%TMP_CHK%
set PHP_SDK_VS_NUM=%TMP_CHK%
set TMP_CHK=
if /i not "%2"=="x64" (
@@ -66,28 +68,37 @@ if not errorlevel 1 (
set TMPKEY=
rem get vc base dir
if 15 gtr %PHP_SDK_VC_NUM% (
if 15 gtr %PHP_SDK_VS_NUM% (
if /i "%PHP_SDK_OS_ARCH%"=="x64" (
set TMPKEY=HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%PHP_SDK_VC:~2%.0\Setup\VC
set TMPKEY=HKLM\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%PHP_SDK_VS:~2%.0\Setup\VC
) else (
set TMPKEY=HKLM\SOFTWARE\Microsoft\VisualStudio\%PHP_SDK_VC:~2%.0\Setup\VC
set TMPKEY=HKLM\SOFTWARE\Microsoft\VisualStudio\%PHP_SDK_VS:~2%.0\Setup\VC
)
reg query !TMPKEY! /v ProductDir >nul 2>&1
if errorlevel 1 (
echo Couldn't determine VC%PHP_SDK_VC:~2% directory
echo Couldn't determine VC%PHP_SDK_VS:~2% directory
goto out_error;
)
for /f "tokens=2*" %%a in ('reg query !TMPKEY! /v ProductDir') do set PHP_SDK_VC_DIR=%%b
) else (
rem vc15 support only for now, could parse out and pass on later
for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo -version %PHP_SDK_VC_NUM% -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format text') do set PHP_SDK_VC_DIR=%%b\VC
rem build the version range, e.g. "[15,16)"
set /a PHP_SDK_VS_RANGE=PHP_SDK_VS_NUM + 1
set PHP_SDK_VS_RANGE="[%PHP_SDK_VS_NUM%,!PHP_SDK_VS_RANGE%!)"
for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo -version !PHP_SDK_VS_RANGE! -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format text') do (
set PHP_SDK_VC_DIR=%%b\VC
)
if not exist "!PHP_SDK_VC_DIR!" (
for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo -version %PHP_SDK_VC_NUM% -products Microsoft.VisualStudio.Product.BuildTools -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format text') do set PHP_SDK_VC_DIR=%%b\VC
for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo -version !PHP_SDK_VS_RANGE! -products Microsoft.VisualStudio.Product.BuildTools -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format text') do (
set PHP_SDK_VC_DIR=%%b\VC
)
if not exist "!PHP_SDK_VC_DIR!" (
rem check for a preview release
for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo -version %PHP_SDK_VC_NUM% -prerelease -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format text') do set PHP_SDK_VC_DIR=%%b\VC
for /f "tokens=1* delims=: " %%a in ('%~dp0\vswhere -nologo -version !PHP_SDK_VS_RANGE! -prerelease -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath -format text') do (
set PHP_SDK_VC_DIR=%%b\VC
)
if not exist "!PHP_SDK_VC_DIR!" (
echo Could not determine '%PHP_SDK_VC%' directory
echo Could not determine '%PHP_SDK_VS%' directory
goto out_error;
)
)
@@ -95,8 +106,9 @@ if 15 gtr %PHP_SDK_VC_NUM% (
set VSCMD_ARG_no_logo=nologo
)
set TMPKEY=
set PHP_SDK_VS_RANGE=
if 15 gtr %PHP_SDK_VC_NUM% (
if 15 gtr %PHP_SDK_VS_NUM% (
rem get sdk dir
rem if 10.0 is available, it's ok
if /i "%PHP_SDK_OS_ARCH%"=="x64" (
@@ -131,20 +143,20 @@ if 15 gtr %PHP_SDK_VC_NUM% (
)
if /i "%PHP_SDK_ARCH%"=="x64" (
if 15 gtr %PHP_SDK_VC_NUM% (
set PHP_SDK_VC_SHELL_CMD="!PHP_SDK_VC_DIR!\vcvarsall.bat" amd64
if 15 gtr %PHP_SDK_VS_NUM% (
set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\vcvarsall.bat" amd64
) else (
set PHP_SDK_VC_SHELL_CMD="!PHP_SDK_VC_DIR!\Auxiliary\Build\vcvarsall.bat" amd64
set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\Auxiliary\Build\vcvarsall.bat" amd64
)
) else (
if 15 gtr %PHP_SDK_VC_NUM% (
set PHP_SDK_VC_SHELL_CMD="!PHP_SDK_VC_DIR!\vcvarsall.bat" x86
if 15 gtr %PHP_SDK_VS_NUM% (
set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\vcvarsall.bat" x86
) else (
set PHP_SDK_VC_SHELL_CMD="!PHP_SDK_VC_DIR!\Auxiliary\Build\vcvarsall.bat" x86
set PHP_SDK_VS_SHELL_CMD="!PHP_SDK_VC_DIR!\Auxiliary\Build\vcvarsall.bat" x86
)
)
rem echo Visual Studio path %PHP_SDK_VC_DIR%
rem echo Visual Studio VC path %PHP_SDK_VC_DIR%
rem echo Windows SDK path %PHP_SDK_WIN_SDK_DIR%

View File

@@ -17,5 +17,12 @@ set PHP_SDK_PHP_CMD=%PHP_SDK_BIN_PATH%\php\do_php.bat
set PATH=%PHP_SDK_BIN_PATH%;%PHP_SDK_MSYS2_PATH%;%PATH%
for /f "tokens=1* delims=: " %%a in ('link /?') do (
set PHP_SDK_VC_TOOLSET_VER=%%b
goto break0
)
:break0
set PHP_SDK_VC_TOOLSET_VER=%PHP_SDK_VC_TOOLSET_VER:~-13%
exit /b %errorlevel%

BIN
bin/sqlite3.exe Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -1,9 +1,5 @@
@echo off
rem edit if PGO scripts are present and are to be used
rem set PHP_SDK_PGO_TOOLS_ROOT_PATH=%PHP_SDK_ROOT_PATH%\pgo
rem set PATH=%PHP_SDK_PGO_TOOLS_ROOT_PATH%\bin;%PATH%
set PGSQL_TEST_CONNSTR=host=127.0.0.1 dbname=test port=5432 user=test password=test
set PDO_PGSQL_TEST_DSN=pgsql:host=127.0.0.1 port=5432 dbname=test user=test password=test

View File

@@ -0,0 +1,47 @@
@echo off
rem These are default ports for the servers used for the training. If these
rem ports are changed in the config templates, the commands have to be
rem adjusted as well. New servers have to be added here as well. Run this
rem file on the elevated shell before starting the PGO environment setup
rem using the relevant port numbers, especially for unattended PGO builds.
rem We add opens inbound ports from the default PGO config templates and
rem and the one increment by 1, just co cover a simple case the port number
rem was incremented by the auto configuration.
rem
rem Alternatively, the firewall can be disabled on the build host.
rem The commands to disable\enable firewall are
rem netsh advfirewall set allprofiles state on
rem netsh advfirewall set allprofiles state off
@echo on
rem NGINX
netsh advfirewall firewall add rule name="NGINX for PGO" dir=in action=allow program="C:\php-snap-build\php-sdk\pgo\work\server\nginx\nginx.exe" profile=private
for \l %%p in (8081, 1, 8091) do (
netsh advfirewall firewall add rule name="Open Port %%p for PHP PGO" dir=in action=allow protocol=TCP localport=%%p profile=private
netsh advfirewall firewall add rule name="Open Port %%p for PHP PGO" dir=in action=allow protocol=UDP localport=%%p profile=private
)
netsh advfirewall firewall add rule name="Open Port 80 for PHP PGO" dir=in action=allow protocol=TCP localport=80 profile=private
netsh advfirewall firewall add rule name="Open Port 80 for PHP PGO" dir=in action=allow protocol=UDP localport=80 profile=private
rem MariaDB
netsh advfirewall firewall add rule name="MariaDB for PGO" dir=in action=allow program="c:\php-snap-build\php-sdk\pgo\work\server\mariadb\bin\mysqld.exe" profile=private
netsh advfirewall firewall add rule name="Open Port 3307 for PHP PGO" dir=in action=allow protocol=TCP localport=3307 profile=private
netsh advfirewall firewall add rule name="Open Port 3307 for PHP PGO" dir=in action=allow protocol=UDP localport=3307 profile=private
netsh advfirewall firewall add rule name="Open Port 3308 for PHP PGO" dir=in action=allow protocol=TCP localport=3308 profile=private
netsh advfirewall firewall add rule name="Open Port 3308 for PHP PGO" dir=in action=allow protocol=UDP localport=3308 profile=private
rem Postgres
netsh advfirewall firewall add rule name="Open Port 5434 for PHP PGO" dir=in action=allow protocol=TCP localport=5434 profile=private
netsh advfirewall firewall add rule name="Open Port 5434 for PHP PGO" dir=in action=allow protocol=UDP localport=5434 profile=private
netsh advfirewall firewall add rule name="Open Port 5435 for PHP PGO" dir=in action=allow protocol=TCP localport=5435 profile=private
netsh advfirewall firewall add rule name="Open Port 5435 for PHP PGO" dir=in action=allow protocol=UDP localport=5435 profile=private
rem PHP
netsh advfirewall firewall add rule name="Open Port 9001 for PHP PGO" dir=in action=allow protocol=TCP localport=9001 profile=private
netsh advfirewall firewall add rule name="Open Port 9001 for PHP PGO" dir=in action=allow protocol=UDP localport=9001 profile=private
netsh advfirewall firewall add rule name="Open Port 9002 for PHP PGO" dir=in action=allow protocol=TCP localport=9002 profile=private
netsh advfirewall firewall add rule name="Open Port 9002 for PHP PGO" dir=in action=allow protocol=UDP localport=9002 profile=private

View File

@@ -1,72 +1,72 @@
/**
* Run the passed command line hidden, suitable for a scheduled task.
* Author: Anatol Belski <ab@php.net>
* License: BSD 2-Clause
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define CMD_PRE "cmd.exe /c "
#define CMD_PRE_LEN (sizeof(CMD_PRE)-1)
#ifdef DEBUG
int
main(int argc, char **argv)
#else
int
APIENTRY WinMain(HINSTANCE inst, HINSTANCE prev_inst, LPTSTR in_cmd, int show)
#endif
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exit_code;
char *cmd = NULL;
size_t cmd_len = 0, arg_len = 0;
char *arg = strchr(GetCommandLine(), ' ');
if (!arg) {
return 3;
}
#ifdef DEBUG
printf("passed cmd: '%s'\n", arg);
#endif
arg_len = strlen(arg);
cmd_len = CMD_PRE_LEN + arg_len + 1;
cmd = malloc(cmd_len * sizeof(char));
memmove(cmd, CMD_PRE, CMD_PRE_LEN);
memmove(cmd + CMD_PRE_LEN, arg, arg_len);
cmd[cmd_len-1] = '\0';
#ifdef DEBUG
printf("constructed cmd: '%s'\n", cmd);
#endif
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
ZeroMemory( &pi, sizeof(pi) );
if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
CloseHandle( pi.hThread );
} else {
free(cmd);
printf( "Error: CreatePracess 0x%08lx \n", GetLastError() );
return 3;
}
WaitForSingleObject( pi.hProcess, INFINITE );
GetExitCodeProcess(pi.hProcess, &exit_code);
CloseHandle( pi.hProcess );
free(cmd);
return exit_code;
}
/**
* Run the passed command line hidden, suitable for a scheduled task.
* Author: Anatol Belski <ab@php.net>
* License: BSD 2-Clause
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define CMD_PRE "cmd.exe /c "
#define CMD_PRE_LEN (sizeof(CMD_PRE)-1)
#ifdef DEBUG
int
main(int argc, char **argv)
#else
int
APIENTRY WinMain(HINSTANCE inst, HINSTANCE prev_inst, LPTSTR in_cmd, int show)
#endif
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exit_code;
char *cmd = NULL;
size_t cmd_len = 0, arg_len = 0;
char *arg = strchr(GetCommandLine(), ' ');
if (!arg) {
return 3;
}
#ifdef DEBUG
printf("passed cmd: '%s'\n", arg);
#endif
arg_len = strlen(arg);
cmd_len = CMD_PRE_LEN + arg_len + 1;
cmd = malloc(cmd_len * sizeof(char));
memmove(cmd, CMD_PRE, CMD_PRE_LEN);
memmove(cmd + CMD_PRE_LEN, arg, arg_len);
cmd[cmd_len-1] = '\0';
#ifdef DEBUG
printf("constructed cmd: '%s'\n", cmd);
#endif
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
ZeroMemory( &pi, sizeof(pi) );
if (CreateProcess(NULL, cmd, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
CloseHandle( pi.hThread );
} else {
free(cmd);
printf( "Error: CreatePracess 0x%08lx \n", GetLastError() );
return 3;
}
WaitForSingleObject( pi.hProcess, INFINITE );
GetExitCodeProcess(pi.hProcess, &exit_code);
CloseHandle( pi.hProcess );
free(cmd);
return exit_code;
}

View File

@@ -3,12 +3,12 @@ rem Task batch example.
rem Create a task, put an action with the following data:
rem Action: start a program
rem Program/script: C:\php-sdk\bin\task.exe
rem Add arguments: "C:\php-sdk\phpsdk-starter.bat -c vc14 -a x64 -t C:\php-sdk\unattended-build-task.bat"
rem Add arguments: "C:\php-sdk\phpsdk-starter.bat -c vc15 -a x64 -t C:\php-sdk\unattended-build-task.bat"
rem Run the task
set LOG_NAME=%PHP_SDK_VC%-%PHP_SDK_ARCH%-task.log
pushd C:\php-sdk\php70\vc14\x64\php-src
pushd C:\php-sdk\php72\vc14\x64\php-src
git pull --rebase > %LOG_NAME% 2>&1

26
lib/php/autoload.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
spl_autoload_register(function($name) {
$fl = __DIR__ . DIRECTORY_SEPARATOR . "libsdk" . DIRECTORY_SEPARATOR . $name . ".php";
if (file_exists($fl)) {
require_once $fl;
}
});
spl_autoload_register(function($name) {
$fl = getenv("PHP_SDK_ROOT_PATH") . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "cases" . DIRECTORY_SEPARATOR . $name . ".php";
if (file_exists($fl)) {
require_once $fl;
}
});
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/

View File

@@ -2,7 +2,7 @@
namespace SDK\Build\Dependency;
use SDK\{Config, Exception, FileOps};
use SDK\{Exception, FileOps};
class Fetcher
{
@@ -13,14 +13,17 @@ class Fetcher
protected $stability;
protected $arch;
protected $series;
protected $scheme;
public function __construct(string $host, int $port, string $arch = NULL, string $stability = NULL, Series $series = NULL)
public function __construct(string $host, int $port, string $scheme = "https", string $arch = NULL, string $stability = NULL, Series $series = NULL)
{/*{{{*/
$this->stability = $stability;
$this->arch = $arch;
$this->host = $host;
$this->port = $port;
$this->scheme = $scheme;
$this->series = $series;
}/*}}}*/
public function getSeries() : Series
@@ -35,11 +38,23 @@ class Fetcher
/* TODO more robust implementation. */
/* TODO implement indicator. */
public function getByUri($uri) : string
public function getByUri(string $uri, int $retries = 3) : string
{/*{{{*/
$url = "http://{$this->host}:{$this->port}$uri";
$url = "{$this->scheme}://{$this->host}:{$this->port}$uri";
$ret = false;
return $this->download($url);
retry:
try {
$ret = $this->download($url);
} catch (Exception $e) {
if ($retries > 0) {
sleep(1);
$retries--;
goto retry;
}
}
return $ret;
}/*}}}*/
/*protected function fetch($uri) : string

View File

@@ -11,8 +11,10 @@ class Manager
protected $stability;
protected $arch;
protected $path;
protected $cache;
protected $series;
protected $fetcher;
protected $updatesFlag = NULL;
public function __construct(string $path, string $stability, string $arch)
{/*{{{*/
@@ -23,7 +25,8 @@ class Manager
$host = Config::getDepsHost();
$port = Config::getDepsPort();
$fetcher = new Fetcher($host, $port, $this->arch, $this->stability);
$scheme = Config::getDepsUriScheme();
$fetcher = new Fetcher($host, $port, $scheme, $this->arch, $this->stability);
$series = new Series($this->stability, $this->arch, $this->cache, NULL);
$fetcher->setSeries($series);
$series->setFetcher($fetcher);
@@ -39,7 +42,12 @@ class Manager
public function updatesAvailable() : bool
{/*{{{*/
return $this->series->updatesAvailable() || !file_exists(Config::getDepsLocalPath());
if (NULL !== $this->updatesFlag) {
return $this->updatesFlag;
}
$this->updatesFlag = $this->series->updatesAvailable() || !file_exists(Config::getDepsLocalPath());
return $this->updatesFlag;
}/*}}}*/
/* FIXME implement rollback */

View File

@@ -2,11 +2,12 @@
namespace SDK\Build\Dependency;
use SDK\Config;
use SDK\Exception;
use SDK\{Config, Exception, FileOps};
class Package
{
use FileOps;
protected $name;
protected $series;
protected $fetcher;
@@ -44,15 +45,8 @@ class Package
if (!$this->filepath || !file_exists($this->filepath)) {
throw new Exception("Invalid filepath '{$this->filepath}'");
}
$zip = new \ZipArchive;
$ret = $zip->open($this->filepath);
if (true === $ret) {
$zip->extractTo($path);
$zip->close();
} else {
throw new Exception("Failed to unpack, error code '$ret'");
}
$this->unzip($this->filepath, $path);
}/*}}}*/
public function cleanup() : void

View File

@@ -44,7 +44,6 @@ class Series
public function getName() : string
{/*{{{*/
$base = Config::getDepsBaseUri();
$branch_data = Config::getCurrentBranchData();
$file = "packages-" . Config::getCurrentBranchName() . "-{$branch_data['crt']}-{$this->arch}-{$this->stability}.txt";

View File

@@ -0,0 +1,246 @@
<?php
namespace SDK\Build\PGO\Abstracts;
use SDK\Build\PGO\PHP\CLI;
use SDK\{Config as SDKConfig, Exception};
abstract class PHP
{
protected $php_root;
protected $php_ext_root;
protected $opcache_file_cache;
protected $id;
protected $scenario;
protected $conf;
protected function setupPaths()
{
$this->php_root = $this->getRootDir();
if ($this->isDist()) {
$this->php_ext_root = $this->php_root . DIRECTORY_SEPARATOR . "ext";
if (!file_exists($this->php_ext_root)) {
throw new Exception("Extension dir '{$this->php_ext_root}' doesn't exist.");
}
} else {
$this->php_ext_root = $this->php_root;
}
if ("cache" == $this->scenario) {
$this->opcache_file_cache = SDKConfig::getTmpDir() . DIRECTORY_SEPARATOR . $this->id;
}
}
/* TODO Might be improved. */
public function isDist() : bool
{
return !file_exists("Makefile") && file_exists("php.exe");
}
protected function createEnv() : array
{
$env = getenv();
if (!$this->isDist()) {
$deps_root = SDKConfig::getDepsLocalPath();
foreach ($env as $k => $v) {
if (strtoupper($k) == "PATH") {
$env[$k] = $deps_root . DIRECTORY_SEPARATOR . "bin;" . $env[$k];
break;
}
}
}
$drive = getenv("HOMEDRIVE");
$path = getenv("HOMEPATH");
if (!$drive || !$path) {
$p = SDKConfig::getTmpDir();
$drive = substr($p, 0, 2);
$path = substr($p, 2);
putenv("HOMEDRIVE=$drive");
putenv("HOMEPATH=$path");
}
return $env;
}
public function getExtRootDir() : string
{
return $this->php_ext_root;
}
public function getRootDir() : string
{
if ($this->php_root) {
return $this->php_root;
}
/* XXX adapt for any possible PHP variants. */
$root = getenv("PHP_SDK_PGO_TEST_PHP_ROOT");
if (!$root) {
if (!$this->isDist()) {
$s = file_get_contents("Makefile");
if (preg_match(",BUILD_DIR=(.+),", $s, $m) > 0) {
$root = trim($m[1]);
}
}
}
if (!file_exists($root)) {
throw new Exception("'$root' doesn't exist.");
}
return $root;
}
public function getVersion(bool $short = false) : string
{
$ret = NULL;
$cli = new CLI($this->conf, $this->scenario);
$out = shell_exec($cli->getExeFilename() . " -n -v");
if ($short) {
if (preg_match(",PHP (\d+\.\d+),", $out, $m)) {
$ret = $m[1];
}
} else {
if (preg_match(",PHP ([^ ]+),", $out, $m)) {
$ret = $m[1];
}
}
if (NULL === $ret) {
throw new Exception("Failed to determine the test PHP version.");
}
return $ret;
}
public function isThreadSafe() : bool
{
$cli = new CLI($this->conf, $this->scenario);
$out = shell_exec($cli->getExeFilename() . " -n -v");
if (preg_match(",NTS,", $out, $m) > 0) {
return false;
}
return true;
}
public function is64bit() : bool
{
$cli = new CLI($this->conf, $this->scenario);
$out = shell_exec($cli->getExeFilename() . " -n -v");
if (preg_match(",x64,", $out, $m) > 0) {
return true;
}
return false;
}
/* Need to cleanup it somewhere. */
public function getIniFilename()
{
$ret = tempnam(sys_get_temp_dir(), "ini");
$tpl_vars = array(
$this->conf->buildTplVarName("php", "extension_dir") => $this->php_ext_root,
$this->conf->buildTplVarName("php", "error_log") => $this->getRootDir() . DIRECTORY_SEPARATOR . "pgo_run_error.log",
);
$k = $this->is64bit() ? "x64" : "x86";
$scenario_vars = (array)$this->conf->getSectionItem("php", "scenario", $this->scenario, "ini", $k);
if ($scenario_vars) {
foreach ($scenario_vars as $k => $v) {
//$tpl_vars[$this->conf->buildTplVarName("php", "scenario", $this->scenario, str_replace(array(".", "-"), "_", $k))] = $v;
$tpl_vars[$this->conf->buildTplVarName("php", str_replace(array(".", "-"), "_", $k))] = $v;
}
}
/* Special handling, otherwise it'll need functionality to extrapolate ini values. */
if ("cache" == $this->scenario) {
$tpl_vars[$this->conf->buildTplVarName("php", "opcache", "file_cache")] = $this->opcache_file_cache;
}
$this->conf->processTplFile(
$this->getIniTplFilename(),
$ret,
$tpl_vars
);
return $ret;
}
protected function getIniTplFilename()
{
$tpl_path = $this->conf->getTplDir("php");
$version = $this->getVersion(true);
$ts = $this->isThreadSafe() ? "ts" : "nts";
$construct = $tpl_path . DIRECTORY_SEPARATOR . "php-$version-pgo-$ts" . ("default" == $this->scenario ? "" : "-{$this->scenario}") . ".ini";
if (!file_exists($construct)) {
throw new Exception("Couldn't locate PHP config under '$construct'.");
}
return $construct;
}
public function exec(string $php_cmd, string $args = NULL, array $extra_env = array()) : int
{
$env = $this->createEnv();
$exe = $this->getExeFilename();
$ini = $this->getIniFilename();
$cert_path = getenv("PHP_SDK_ROOT_PATH") . "\\msys2\\usr\\ssl\\cert.pem";
$ini .= " -d curl.cainfo=$cert_path";
$spent_key = array();
foreach ($env as $k0 => &$v0) {
foreach ($extra_env as $k1 => $v1) {
if (strtoupper($k0) == strtoupper($k1)) {
/* XXX some more things could require extra handling. */
if (strtoupper($k0) == "PATH") {
$v0 = "$v1;$v0";
} else {
$v0 = $v1;
}
$spent_key[] = $k1;
break;
}
}
}
foreach ($extra_env as $k => $v) {
if (in_array($k, $spent_key)) {
continue;
}
$env[$k] = $v;
}
$cmd = "$exe -n -c $ini " . ($args ? "$args " : "") . $php_cmd;
$desc = array(
0 => array("file", "php://stdin", "r"),
1 => array("file", "php://stdout", "w"),
2 => array("file", "php://stderr", "w")
);
$p = proc_open($cmd, $desc, $pipes, $this->getRootDir(), $env);
return proc_close($p);
}
public function getIdString(): string
{
return $this->getVersion() . "-"
. SDKConfig::getCurrentCrtName() . "-"
. ($this->isThreadSafe() ? "ts" : "nts") . "-"
. ($this->is64bit() ? "x64" : "x86")
. "-" . substr(md5(uniqid()), 0, 8);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace SDK\Build\PGO\Abstracts;
use SDK\Build\PGO\Interfaces;
abstract class Server
{
public function getName() : string
{
return $this->name;
}
public function getPhp() : Interfaces\PHP
{
return $this->php;
}
}

View File

@@ -0,0 +1,151 @@
<?php
namespace SDK\Build\PGO\Abstracts;
use SDK\FileOps;
use SDK\Build\PGO\Tool;
abstract class TrainingCase
{
use FileOps;
const TYPE_WEB = "web";
const TYPE_CLI = "cli";
protected $stat = array();
/** @var \SDK\Build\PGO\Config */
protected $conf;
public function getType() : string
{
$type = $this->conf->getSectionItem($this->getName(), "type");
if (!$type) {
$type = "web";
}
return $type;
}
public function run() : void
{
$training = new Tool\Training($this->conf, $this);
$pgo = new Tool\PGO($this->conf, $this->php);
echo "Running " . $this->getName() . " training.\n";
$max_runs = $this->max_runs ?? 1;
$max_runs = (int)$max_runs > 0 ? $max_runs : 1;
$training->run($max_runs, $stat);
if ($this->getType() == "web") {
echo "HTTP responses:\n";
foreach ($stat["http_code"] as $code => $num) {
printf(" %d received %d times\n", $code, $num);
}
if (count($stat["not_ok"]) > 0) {
foreach($stat["not_ok"] as $st) {
echo "Code: $st[http_code], URL: $st[url]", ($st["redirect_url"] ? ", Redirected to: $st[redirect_url]" : ""), "\n";
}
printf("\033[31m WARNING: Not all HTTP responses have indicated success, the PGO data might be unsuitable!\033[0m\n");
}
}
echo $this->getName() . " training complete.\n";
echo "Dumping PGO data for " . $this->getName() . ".\n";
$pgo->dump();
echo "Finished dumping training data for " . $this->getName() . ".\n";
}
public function getHttpPort() : string
{
$port = $this->conf->getSectionItem($this->getName(), "http_port");
if (!$port) {
$port = $this->conf->getNextPort();
$this->conf->setSectionItem($this->getName(), "http_port", $port);
}
return $port;
}
public function getHttpHost() : string
{
$host = $this->conf->getSectionItem($this->getName(), "http_host");
if (!$host) {
$srv = $this->conf->getSrv(
$this->conf->getSectionItem($this->getName(), "srv_http")
);
if ($srv) {
$host = $this->conf->getSectionItem($srv->getName(), "host");
$this->conf->setSectionItem($this->getName(), "http_host", $host);
}
}
return $host;
}
protected function getDbConf(string $item) : string
{
$val = $this->conf->getSectionItem($this->getName(), "db_$item");
if (!$val) {
$srv = $this->conf->getSrv(
$this->conf->getSectionItem($this->getName(), "srv_db")
);
if ($srv) {
$val = $this->conf->getSectionItem($srv->getName(), $item);
$this->conf->setSectionItem($this->getName(), "db_$item", $val);
}
}
return $val;
}
public function getDbPass() : string
{
return $this->getDbConf("pass");
}
public function getDbUser() : string
{
return $this->getDbConf("user");
}
public function getDbHost() : string
{
return $this->getDbConf("host");
}
public function getDbPort() : string
{
return $this->getDbConf("port");
}
public function httpStatusOk(int $status) : bool
{
$ok = array();
$ok = array_merge($ok, range(200, 206));
$ok = array_merge($ok, range(300, 307));
return in_array($status, $ok);
}
public function probeUrl(string $url) : bool
{
$ret = false;
$c = curl_init($url);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_exec($c);
if (!curl_errno($c)) {
$st = curl_getinfo($c, CURLINFO_HTTP_CODE);
$ret = $this->httpStatusOk((int)$st);
}
curl_close($c);
return $ret;
}
}

View File

@@ -0,0 +1,369 @@
<?php
namespace SDK\Build\PGO;
use SDK\Exception;
class Config
{
const MODE_INIT = 0;
const MODE_RUN = 1;
const MODE_REINIT = 2; /* currently unused */
const MODE_CHECK_INIT = 3;
protected $mode;
protected $last_port = 8081;
protected $sections = array();
protected $scenario = "default";
protected $tpl_vars = array();
protected $srv = array();
public function __construct(int $mode = self::MODE_RUN)
{
if (self::MODE_CHECK_INIT == $mode) {
// XXX The check is simple right now, so this is sufficient.
return;
}
if (!$this->isInitialized()) {
$this->initWorkDir();
}
if (self::MODE_REINIT == $mode) {
$fn = $this->getWorkSectionsFilename();
if (file_exists($fn)) {
unlink($fn);
}
$mode = self::MODE_INIT;
}
$this->mode = $mode;
if (self::MODE_INIT == $mode) {
foreach (array("nginx", "mariadb", "postgresql", "php") as $i) {
$this->importSectionFromDir($i, $this->getTplDir() . DIRECTORY_SEPARATOR . $i);
}
} else if (self::MODE_RUN == $mode) {
$fn = $this->getWorkSectionsFilename();
if (!file_exists($fn)) {
throw new Exception("Required config doesn't exist under '$fn'.");
}
$s = file_get_contents($fn);
$this->sections = json_decode($s, true);
foreach($this->sections as $k => $v) {
$this->importTplVars($k, $v);
}
} else {
throw new Exception("Unknown config mode '$mode'.");
}
}
protected function initWorkDir() : void
{
if (!mkdir($this->getWorkDir())) {
throw new Exception("Failed to create " . $this->getWorkDir());
}
}
public function isInitialized()
{
/* XXX Could be some better check. */
return is_dir($this->getWorkDir());
}
public function getToolsDir() : string
{
$base = $this->getWorkDir();
return $base . DIRECTORY_SEPARATOR . "tools";
}
public function getWorkDir() : string
{
$base = getenv("PHP_SDK_ROOT_PATH");
return $base . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "work";
}
public function getPkgCacheDir() : string
{
$base = $this->getWorkDir();
return $base . DIRECTORY_SEPARATOR . "package_cache";
}
public function getJobDir(string $name = NULL) : string
{
$ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "job";
if ($name) {
$ret .= DIRECTORY_SEPARATOR . $name;
}
return $ret;
}
public function getSrvDir(string $name = NULL) : string
{
$ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "server";
if ($name) {
$ret .= DIRECTORY_SEPARATOR . $name;
}
return $ret;
}
public function getHtdocs(string $name = NULL) : string
{
$ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "htdocs";
if ($name) {
$ret .= DIRECTORY_SEPARATOR . $name;
}
return $ret;
}
public function getTplDir(string $name = NULL) : string
{
$ret = getenv("PHP_SDK_ROOT_PATH") . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "tpl";
if ($name) {
$ret .= DIRECTORY_SEPARATOR . $name;
}
return $ret;
}
public function getCaseWorkDir(string $name = NULL) : string
{
$ret = $this->getWorkDir() . DIRECTORY_SEPARATOR . "htdocs";
if ($name) {
$ret .= DIRECTORY_SEPARATOR . $name;
}
return $ret;
}
public function getCasesTplDir(string $name = NULL) : string
{
$ret = getenv("PHP_SDK_ROOT_PATH") . DIRECTORY_SEPARATOR . "pgo" . DIRECTORY_SEPARATOR . "cases";
if ($name) {
$ret .= DIRECTORY_SEPARATOR . $name;
}
return $ret;
}
public function sectionItemExists(...$args) : bool
{
$i = 0;
$k = strtolower($args[$i]);
$it = $this->sections;
while (array_key_exists($k, $it)) {
$it = $it[$k];
if (++$i >= count($args)) break;
$k = strtolower($args[$i]);
}
return $i == count($args);
}
public function getSectionItem(...$args)
{
$i = 0;
$k = strtolower($args[$i]);
$it = $this->sections;
while (array_key_exists($k, $it)) {
$it = $it[$k];
if (++$i >= count($args)) break;
$k = strtolower($args[$i]);
}
if ($i != count($args)) {
return NULL;
}
return $it;
}
public function setSectionItem(...$args) : void
{
$val = array_pop($args);
$i = 0;
$k = strtolower($args[$i]);
$it = &$this->sections;
while (true) {
$it = &$it[$k];
if (++$i >= count($args)) break;
$k = strtolower($args[$i]);
}
$it = $val;
$this->syncTplVars();
$this->dump();
}
public function importSectionFromDir(string $name, string $dir) : void
{
$fn = $dir . DIRECTORY_SEPARATOR . "phpsdk_pgo.json";
if (!file_exists($fn)) {
throw new Exception("Couldn't import section, file '$fn' doesn't exist.");
}
$s = file_get_contents($fn);
$this->setSectionItem($name, json_decode($s, true));
}
protected function syncTplVars() : void
{
$this->tpl_vars = array();
foreach ($this->sections as $k => $v) {
$this->importTplVars($k, $v);
}
}
public function buildTplVarName(...$args) : string
{
$tpl_k = array("PHP_SDK_PGO");
foreach ($args as $a) {
$tpl_k[] = strtoupper($a);
}
return implode("_", $tpl_k);
}
protected function importTplVars(string $section_name, array $section) : void
{
foreach($section as $k0 => $v0) {
if (is_array($v0)) {
if (substr($k0, -4) == ":env") {
/* Don't put env vars as tpl vars for now. */
continue;
}
$this->importTplVars($section_name . "_" . $k0, $v0);
} else {
$tpl_k = $this->buildTplVarName($section_name, $k0);
$this->tpl_vars[$tpl_k] = $v0;
}
}
}
public function processTpl(string $s, array $additional_vars = array()) : string
{
$vars = array_merge($this->tpl_vars, $additional_vars);
$s = str_replace(array_keys($vars), array_values($vars), $s);
return $s;
}
public function processTplFile(string $tpl_fn, string $dst_fn, array $additional_vars = array()) : void
{
if (!file_exists($tpl_fn)) {
throw new Exception("Template file '$tpl_fn' doesn't exist.");
}
$s = file_get_contents($tpl_fn);
if (false === $s) {
throw new Exception("Couldn't read '$tpl_fn'.");
}
$s = $this->processTpl($s, $additional_vars);
if (false === file_put_contents($dst_fn, $s)) {
throw new Exception("Failed to write '$dst_fn'.");
}
}
public function getWorkSectionsFilename()
{
return $this->getWorkDir() . DIRECTORY_SEPARATOR . "phpsdk_pgo.json";
}
public function dump(string $fn = NULL) : void
{
$fn = $fn ? $fn : $this->getWorkSectionsFilename();
$s = json_encode($this->sections, JSON_PRETTY_PRINT);
$ret = file_put_contents($fn, $s);
if (false === $ret || strlen($s) !== $ret) {
throw new Exception("Errors with writing to '$fn'.");
}
}
public function setScenario(string $scenario) : void
{
if (!in_array($scenario, array("default", "cache"), true)) {
throw new Exception("Unknown scenario '$scenario'.");
}
$this->scenario = $scenario;
}
public function getScenario() : string
{
return $this->scenario;
}
public function getNextPort() : int
{
return ++$this->last_port;
}
public function setLastPort(int $port) : void
{
$this->last_port = $port;
}
public function getSdkPhpCmd() : string
{
return getenv("PHP_SDK_PHP_CMD");
}
public function addSrv($item) : void
{
$name = strtolower($item->getName());
if (isset($this->srv[$name])) {
throw new Exception("Server '$name' already exists.");
}
/* XXX Additional checks could not harm. */
$this->srv[$name] = $item;
}
public function getSrv(?string $name = NULL)
{
$ret = NULL;
$name = strtolower($name);
if (!$name) {
return NULL;
} else if ("all" == $name) {
return $this->srv;
} else if (isset($this->srv[$name])) {
return $this->srv[$name];
}
return $ret;
}
}

View File

@@ -0,0 +1,272 @@
<?php
namespace SDK\Build\PGO;
use SDK\{Exception, Lock};
use SDK\Build\PGO\Config as PGOConfig;
use SDK\Build\PGO\Server\{MariaDB, NGINX, PostgreSQL};
use SDK\Build\PGO\PHP;
use SDK\Build\PGO\Tool\{PGO, PackageWorkman};
/* TODO add bench action */
class Controller
{
protected $cmd;
protected $scenario;
protected $conf;
protected $cases;
public function __construct(string $cmd, ?string $scenario, ?array $cases)
{
$this->cmd = $cmd;
if (NULL == $scenario) {
$scenario = "default";
}
$this->scenario = $scenario;
$this->cases = $cases;
}
protected function vitalizeSrv()
{
$all = $this->conf->getSrv("all");
if (empty($all)) {
$php_fcgi_tcp = new PHP\FCGI($this->conf, true);
$this->conf->addSrv(new NGINX($this->conf, $php_fcgi_tcp));
$this->conf->addSrv(new MariaDB($this->conf));
/* Uncomment to enable PostgreSQL*/
/* $this->conf->addSrv(new PostgreSQL($this->conf));*/
$all = $this->conf->getSrv("all");
}
return $all;
}
protected function setupConfig($cmd)
{
switch ($cmd) {
default:
throw new Exception("Unknown action '{$cmd}'.");
break;
case "check_init":
$cnf = new PGOConfig(PGOConfig::MODE_CHECK_INIT);
break;
case "init":
$cnf = new PGOConfig(PGOConfig::MODE_INIT);
break;
case "train":
case "up":
case "down":
$cnf = new PGOConfig(PGOConfig::MODE_RUN);
}
$cnf->setScenario($this->scenario);
return $cnf;
}
public function handle($force)
{
/*$mode = (int)("init" !== $this->cmd);
$mode = (PGOConfig::MODE_INIT == $mode && $force) ? PGOConfig::MODE_REINIT : $mode;
$this->conf = new PGOConfig("init" !== $this->cmd);
$this->conf->setScenario($this->scenario);*/
$this->conf = $this->setupConfig($this->cmd);
switch ($this->cmd) {
default:
throw new Exception("Unknown action '{$this->cmd}'.");
break;
case "init":
$lk = new Lock("pgo_init");
if (!$lk->locked()) {
echo "Another process runs initialization right now, waiting.", PHP_EOL;
$lk->exclusive(true);
echo "Another process finished running initialization, I quit as well.", PHP_EOL;
return;
}
$this->init($force);
break;
case "train":
$lk = new Lock("pgo_train");
if (!$lk->locked()) {
echo "Another process runs training right now, I have to wait.", PHP_EOL;
$lk->exclusive(true);
echo "Another process finished training, I may continue.", PHP_EOL;
}
$this->train();
break;
case "up":
$this->up();
break;
case "down":
$this->down($force);
break;
case "check_init":
// pass
break;
}
}
protected function initWorkDirs() : void
{
$dirs = array(
$this->conf->getSrvDir(),
$this->conf->getToolsDir(),
$this->conf->getHtdocs(),
$this->conf->getJobDir(),
$this->conf->getPkgCacheDir(),
);
foreach ($dirs as $dir) {
if (!is_dir($dir)) {
if (!mkdir($dir)) {
throw new Exception("Failed to create '$dir'.");
}
}
}
}
protected function prepareStandaloneTools(PackageWorkman $pw, bool $force = false) : void
{
$php = new PHP\CLI($this->conf);
$composer = $this->conf->getToolsDir() . DIRECTORY_SEPARATOR . "composer.phar";
if (!file_exists($composer) || $force) {
/* XXX this needs to go into the config, specifically for composer maybe even separate class. */
$url = "https://getcomposer.org/installer";
/* XXX remove the explicit version option when symfony demo is fixed. */
$tool = $this->conf->getToolsDir() . DIRECTORY_SEPARATOR . "composer-setup.php";
$pw->fetch($url, $tool, $force);
$php->exec("$tool --install-dir=" . $this->conf->getToolsDir());
unlink($tool);
}
}
public function init(bool $force = false)
{
echo "\nInitializing PGO training environment.\n\n";
$this->initWorkDirs();
$pw = new PackageWorkman($this->conf);
$this->prepareStandaloneTools($pw, $force);
$srvs = $this->vitalizeSrv();
foreach ($srvs as $srv) {
$srv->prepareInit($pw, $force);
}
foreach (new TrainingCaseIterator($this->conf) as $handler) {
$handler->prepareInit($pw, $force);
}
foreach ($srvs as $srv) {
$srv->init();
echo "\n";
}
echo "\n";
foreach (new TrainingCaseIterator($this->conf) as $handler) {
$handler->init();
echo "\n";
}
echo "PGO training environment Initialization complete.\n";
}
public function isInitialized()
{
return $this->conf->isinitialized();
}
public function train()
{
if (!$this->isInitialized()) {
throw new Exception("PGO training environment is not initialized.");
}
echo "\nStarting PGO training using scenario '{$this->scenario}'.\n\n";
$this->up();
/* Clean the PGO db files, only needed once.
Imply also, that any data created during init or
startup is wasted. It is done by dumpbing the data
from the current running processes and subsequently
removing the files. */
$php = $this->conf->getSrv("nginx")->getPhp();
$pgo = new PGO($this->conf, $php);
$pgo->waste();
$pgo->clean();
unset($pgo);
$cases = $this->cases;
foreach (new TrainingCaseIterator($this->conf) as $handler) {
$name = $handler->getName();
/* Just a white list handling for now. */
if (is_array($cases)) {
if (!in_array($name, $cases)) {
continue;
}
$key = array_search($name, $cases);
unset($cases[$key]);
}
echo "\n";
$handler->run();
}
if (is_array($cases) && !empty($cases)) {
echo "\n\033[31m WARNING: The cases " . implode(",", $cases) . " don't exist and was ignored!\033[0m\n\n";
}
/* All the PGC files are merged, simply clean them out. */
$pgo = new PGO($this->conf, $php);
$pgo->clean(true, false);
unset($pgo);
$this->down();
echo "PGO training complete.\n";
}
public function up()
{
if (!$this->isInitialized()) {
throw new Exception("PGO training environment is not initialized.");
}
echo "\nStarting up PGO environment.\n\n";
foreach ($this->vitalizeSrv("all") as $srv) {
$srv->up();
echo "\n";
}
sleep(1);
echo "The PGO environment is up.\n";
}
public function down(bool $force = false)
{
if (!$this->isInitialized()) {
throw new Exception("PGO training environment is not initialized.");
}
/* XXX check it was started of course. */
echo "\nShutting down PGO environment.\n\n";
foreach ($this->vitalizeSrv("all") as $srv) {
$srv->down($force);
echo "\n";
}
sleep(1);
echo "The PGO environment has been shut down.\n";
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Tool\PackageWorkman;
interface PHP
{
/* Prepare anything necessary to start initialization, like fetch required packages, etc. */
public function prepareInit(PackageWorkman $pw, bool $force = false) : void;
public function init() : void;
public function up() : void;
public function down(bool $force = false) : void;
public function getVersion(bool $short = false) : string;
public function getExeFilename() : string;
}

View File

@@ -0,0 +1,15 @@
<?php
namespace SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Tool\PackageWorkman;
interface Server
{
/* Prepare anything necessary to start initialization, like fetch required packages, etc. */
public function prepareInit(PackageWorkman $pw, bool $force = false) : void;
public function init() : void;
public function up() : void;
public function down(bool $force = false) : void;
public function getName() : string;
}

View File

@@ -0,0 +1,12 @@
<?php
namespace SDK\Build\PGO\Interfaces\Server;
use SDK\Build\PGO\Config;
use SDK\Build\PGO\Interfaces;
interface DB extends Interfaces\Server
{
public function __construct(Config $conf);
public function query(string $s, string $db = NULL) : void;
}

View File

@@ -0,0 +1,13 @@
<?php
namespace SDK\Build\PGO\Interfaces\Server;
use SDK\Build\PGO\Config;
use SDK\Build\PGO\Interfaces;
interface HTTP extends Interfaces\Server
{
public function __construct(Config $conf, Interfaces\PHP $php);
public function getPhp() : Interfaces\PHP;
public function addServer(string $part_tpl_fn, array $tpl_vars = array());
}

View File

@@ -0,0 +1,27 @@
<?php
namespace SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Config as PGOConfig;
use SDK\Build\PGO\Tool\PackageWorkman;
interface TrainingCase
{
public function __construct(PGOConfig $conf, ?Server $srv_http, ?Server\DB $srv_db);
/* Name of the training case, usually should be same as dirname and namespace. */
public function getName() : string;
/* Prepare anything necessary to start initialization, like fetch required packages, etc. */
public function prepareInit(PackageWorkman $pw, bool $force = false) : void;
/* Initialize the case, run only once on a new checkout. */
public function init() : void;
/* Run training. */
public function run() : void;
/* Get training type, it's like "web", "cli", etc.*/
public function getType() : string;
}

View File

@@ -0,0 +1,55 @@
<?php
namespace SDK\Build\PGO\PHP;
use SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Abstracts;
use SDK\Build\PGO\Config as PGOConfig;
use SDK\{Exception};
use SDK\Build\PGO\Tool\PackageWorkman;
class CLI extends Abstracts\PHP implements Interfaces\PHP
{
public function __construct(PGOConfig $conf)
{
$this->conf = $conf;
$this->scenario = $conf->getScenario();
// Don't do that, it'll be a recursive dependency.
// Once we need to train CLI, we'll need to split
// a new class, this one is a utility class.
//$this->id = $this->getIdString();
$this->setupPaths();
}
public function prepareInit(PackageWorkman $pw, bool $force = false) : void
{
/* pass */
}
public function init() : void
{
/* pass */
}
public function up() : void
{
/* pass */
}
public function down(bool $force = false) : void
{
/* pass */
}
public function getExeFilename() : string
{
$exe = $this->getRootDir() . DIRECTORY_SEPARATOR . "php.exe";
if (!file_exists($exe)) {
throw new Exception("Path '$exe' doesn't exist.");
}
return $exe;
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace SDK\Build\PGO\PHP;
use SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Abstracts;
use SDK\Build\PGO\Config as PGOConfig;
use SDK\{Exception, FileOps};
use SDK\Build\PGO\Tool\PackageWorkman;
class FCGI extends Abstracts\PHP implements Interfaces\PHP
{
use FileOps;
protected $is_tcp;
public function __construct(PGOConfig $conf, bool $is_tcp)
{
if (!$is_tcp) {
throw new Exception("FCGI training other than through TCP is not implemented yet.");
}
$this->conf = $conf;
$this->is_tcp = $is_tcp;
$this->scenario = $conf->getScenario();
$this->id = $this->getIdString();
$this->setupPaths();
}
public function getExeFilename() : string
{
$exe = $this->getRootDir() . DIRECTORY_SEPARATOR . "php-cgi.exe";
if (!file_exists($exe)) {
throw new Exception("Path '$exe' doesn't exist.");
}
return $exe;
}
protected function createEnv() : array
{
$env = parent::createEnv();
$fcgi_env = (array)$this->conf->getSectionItem("php", "fcgi:env");
foreach ($fcgi_env as $k => $v) {
$env[$k] = $v;
}
return $env;
}
public function prepareInit(PackageWorkman $pw, bool $force = false) : void
{
}
public function init() : void
{
/* echo "Initializing PHP FCGI.\n";
echo "PHP FCGI initialization done.\n";*/
}
public function up() : void
{
echo "Starting PHP FCGI.\n";
if ("cache" == $this->scenario) {
if (file_exists($this->opcache_file_cache)) {
$this->rm($this->opcache_file_cache);
}
if (!mkdir($this->opcache_file_cache)) {
throw new Exception("Failed to create '{$this->opcache_file_cache}'");
}
}
$exe = $this->getExeFilename();
$ini = $this->getIniFilename();
$host = $this->conf->getSectionItem("php", "fcgi", "host");
$port = $this->conf->getSectionItem("php", "fcgi", "port");
$cmd = "start /b $exe -n -c $ini -b $host:$port 2>&1";
$desc = array(
0 => array("file", "php://stdin", "r"),
1 => array("file", "php://stdout", "w"),
2 => array("file", "php://stderr", "w"),
);
$p = proc_open($cmd, $desc, $pipes, $this->getRootDir(), $this->createEnv());
/* Give some time, it might be slow on PGI enabled proc. */
sleep(3);
/*while(false !== ($s = fread($pipes[2], 1024))) {
echo "$s";
}*/
$c = proc_close($p);
if ($c) {
throw new Exception("PHP FCGI process exited with code '$c'.");
}
/* XXX for Opcache, setup also file cache. */
echo "PHP FCGI started.\n";
}
public function down(bool $force = false) : void
{
echo "Stopping PHP FCGI.\n";
exec("taskkill /f /im php-cgi.exe >nul 2>&1");
/* XXX Add cleanup interface. */
if ("cache" == $this->scenario) {
try {
$this->rm($this->opcache_file_cache);
} catch (\UnexpectedValueException $e) {
echo $e->getMessage(), "\n";
}
}
echo "PHP FCGI stopped.\n";
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace SDK\Build\PGO\Server;
use SDK\Build\PGO\Interfaces\Server\DB;
use SDK\Build\PGO\Abstracts\Server;
use SDK\Build\PGO\Config as PGOConfig;
use SDK\{Exception, FileOps};
use SDK\Build\PGO\Tool\PackageWorkman;
class MariaDB extends Server implements DB
{
use FileOps;
protected $conf;
protected $base;
protected $name = "MariaDB";
public function __construct(PGOConfig $conf)
{
$this->conf = $conf;
$this->base = $conf->getSrvDir(strtolower($this->name));
}
protected function setupDist()
{
/* pass */
}
public function prepareInit(PackageWorkman $pw, bool $force = false) : void
{
$url = $this->conf->getSectionItem($this->name, "pkg_url");
$pw->fetchAndUnzip($url, "mariadb.zip", $this->conf->getSrvDir(), "mariadb", $force);
}
public function init() : void
{
echo "Initializing " . $this->name . ".\n";
$this->setupDist();
$this->up();
$this->down(true);
echo $this->name . " initialization done.\n";
}
public function up() : void
{
echo "Starting " . $this->name . ".\n";
$cwd = getcwd();
chdir($this->base);
$port = $this->conf->getSectionItem($this->name, "port");
//$h = popen("start /b .\\bin\\mysqld.exe --port=$port >nul 2>&1", "r");
$h = popen("start /b .\\bin\\mysqld.exe --port=$port 2>&1", "r");
if (!is_resource($h)) {
chdir($cwd);
throw new Exception("Failed to start MariaDB.");
}
sleep(3);
while (!feof($h)) {
echo fread($h, 1024);
}
pclose($h);
chdir($cwd);
echo $this->name . " started.\n";
}
public function down(bool $force = false) : void
{
echo "Stopping " . $this->name . ".\n";
$cwd = getcwd();
chdir($this->base);
$user = $this->conf->getSectionItem($this->name, "user");
$pass = $this->conf->getSectionItem($this->name, "pass");
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$cmd = sprintf(".\\bin\\mysqladmin.exe --host=$host --port=$port -u $user %s--shutdown_timeout=0 shutdown", ($pass ? "-p$pass " : ""));
exec($cmd);
if ($force) {
sleep(1);
exec("taskkill /f /im mysqld.exe >nul 2>&1");
}
chdir($cwd);
echo $this->name . " stopped.\n";
}
public function query(string $s, string $db = NULL) : void
{
$ret = NULL;
$cwd = getcwd();
chdir($this->base);
$user = $this->conf->getSectionItem($this->name, "user");
$pass = $this->conf->getSectionItem($this->name, "pass");
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$pass_arg = $pass ? "-p$pass " : "";
$db_arg = $db ? "-D $db" : "";
shell_exec(".\\bin\\mysql.exe -u $user $pass_arg -h $host -P $port $db_arg -e \"$s\"");
//var_dump($this->base, getcwd(), ".\\bin\\mysql.exe -u $user $pass_arg -h $host -P $port -e \"$s\"");
chdir($cwd);
}
public function import(string $path, string $db = NULL) : void
{
$ret = NULL;
$cwd = getcwd();
chdir($this->base);
$user = $this->conf->getSectionItem($this->name, "user");
$pass = $this->conf->getSectionItem($this->name, "pass");
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$pass_arg = $pass ? "-p$pass " : "";
$db_arg = $db ? "-D $db" : "";
shell_exec(".\\bin\\mysql.exe -u $user $pass_arg -h $host -P $port $db_arg < \"$path\"");
chdir($cwd);
}
}

View File

@@ -0,0 +1,149 @@
<?php
namespace SDK\Build\PGO\Server;
use SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Abstracts;
use SDK\Build\PGO\{Config as PGOConfig};
use SDK\{Exception, FileOps};
use SDK\Build\PGO\Tool\PackageWorkman;
class NGINX extends Abstracts\Server implements Interfaces\Server\HTTP
{
use FileOps;
protected $name = "NGINX";
protected $conf;
protected $base;
protected $php;
public function __construct(PGOConfig $conf, Interfaces\PHP $php)
{
$this->conf = $conf;
$this->base = $conf->getSrvDir(strtolower($this->name));
$this->php = $php;
}
protected function setupDist() : void
{
$nginx_conf_in = $this->conf->getTplDir($this->name) . DIRECTORY_SEPARATOR . "nginx.conf";
$conf_fn = $this->base . DIRECTORY_SEPARATOR . "conf" . DIRECTORY_SEPARATOR . "nginx.conf";
$port = $this->conf->getSectionItem($this->name, "port");
if (!$port) {
$port = $this->conf->getNextPort();
$this->conf->setSectionItem($this->name, "port", $port);
}
$vars = array(
$this->conf->buildTplVarName($this->name, "docroot") => str_replace("\\", "/", $this->base . DIRECTORY_SEPARATOR . "html"),
);
$this->conf->processTplFile(
$nginx_conf_in,
$conf_fn,
$vars
);
}
public function prepareInit(PackageWorkman $pw, bool $force = false) : void
{
$url = $this->conf->getSectionItem($this->name, "pkg_url");
$pw->fetchAndUnzip($url, "nginx.zip", $this->conf->getSrvDir(), "nginx", $force);
}
public function init() : void
{
echo "Initializing " . $this->name . ".\n";
$this->setupDist();
$this->upMe();
$this->downMe(true);
echo $this->name . " initialization done.\n";
}
protected function upMe() : void
{
echo "Starting " . $this->name . ".\n";
$cwd = getcwd();
chdir($this->base);
$h = popen("start /b .\\nginx.exe 2>&1", "r");
if (!is_resource($h)) {
chdir($cwd);
throw new Exception("Failed to start MariaDB.");
}
sleep(3);
/* while (!feof($h)) {
echo fread($h, 1024);
}*/
pclose($h);
chdir($cwd);
echo $this->name . " started.\n";
}
public function up() : void
{
$this->php->up();
$this->upMe();
}
public function downMe(bool $force = false) : void
{
echo "Stopping " . $this->name . ".\n";
$cwd = getcwd();
chdir($this->base);
exec(".\\nginx.exe -s quit");
if ($force) {
sleep(1);
exec("taskkill /f /im nginx.exe >nul 2>&1");
}
chdir($cwd);
echo $this->name . " stopped.\n";
}
public function down(bool $force = false) : void
{
$this->php->down();
$this->downMe($force);
}
/* Use only for init phase! */
public function addServer(string $part_tpl_fn, array $tpl_vars = array())
{
if (!file_exists($part_tpl_fn)) {
throw new Exception("Template file '$part_tpl_fn' doesn't exist.");
}
/* We've already did a fresh (re)config, so use the work file now. */
$nginx_conf_in = $this->base . DIRECTORY_SEPARATOR . "conf" . DIRECTORY_SEPARATOR . "nginx.conf";
$cur_conf = file_get_contents($nginx_conf_in);
$in = file_get_contents($part_tpl_fn);
$out = $this->conf->processTpl($in, $tpl_vars);
$tpl = " # PHP_SDK_PGO_NGINX_SERVERS_INC_TPL";
$new_conf = str_replace($tpl, "$out\n$tpl", $cur_conf);
$conf_fn = $this->base . DIRECTORY_SEPARATOR . "conf" . DIRECTORY_SEPARATOR . "nginx.conf";
if (!file_put_contents($conf_fn, $new_conf)) {
throw new Exception("Couldn't write '$conf_fn'.");
}
}
}

View File

@@ -0,0 +1,136 @@
<?php
namespace SDK\Build\PGO\Server;
use SDK\Build\PGO\Interfaces\Server\DB;
use SDK\Build\PGO\Abstracts\Server;
use SDK\Build\PGO\Config as PGOConfig;
use SDK\{Exception, FileOps};
use SDK\Build\PGO\Tool\PackageWorkman;
class PostgreSQL extends Server implements DB
{
use FileOps;
protected $conf;
protected $base;
protected $data_dir;
protected $name = "PostgreSQL";
public function __construct(PGOConfig $conf)
{
$this->conf = $conf;
$this->base = $conf->getSrvDir(strtolower($this->name));
$this->data_dir = $this->base . DIRECTORY_SEPARATOR . "data";
}
protected function setupDist()
{
$user = $this->conf->getSectionItem($this->name, "user");
if (!$user) {
$user = trim(shell_exec("pwgen -1 -s 8"));
$this->conf->setSectionItem($this->getName(), "user", $user);
}
$pass = $this->conf->getSectionItem($this->name, "pass");
if (!$pass) {
$pass = trim(shell_exec("pwgen -1 -s 8"));
$this->conf->setSectionItem($this->getName(), "pass", $pass);
}
if (!is_dir($this->data_dir)) {
$pwfile = tempnam(sys_get_temp_dir(), "tmp");
if (strlen($pass) !== file_put_contents($pwfile, $pass)) {
throw new Exception("Couldn't write '$pwfile'.");
}
$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "initdb.exe --auth=trust --nosync --username=$user --pwfile=$pwfile --encoding=UTF8 " . $this->data_dir;
//$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "initdb.exe --auth=trust --nosync --username=$user --encoding=UTF8 " . $this->data_dir;
/*echo "$cmd\n";
echo file_get_contents($pwfile) . "\n";*/
exec($cmd);
unlink($pwfile);
}
}
public function prepareInit(PackageWorkman $pw, bool $force = false) : void
{
$url = $this->conf->getSectionItem($this->name, "pkg_url");
$pw->fetchAndUnzip($url, "postgresql.zip", $this->conf->getSrvDir(), "postgresql", $force);
}
public function init() : void
{
echo "Initializing " . $this->name . ".\n";
$this->setupDist();
$this->up();
$this->down(true);
echo $this->name . " initialization done.\n";
}
public function up() : void
{
echo "Starting " . $this->name . ".\n";
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "pg_ctl.exe start -D " . $this->data_dir . " -o \"-h $host -p $port\"";
$h = popen($cmd, "r");
/* XXX error check*/
pclose($h);
echo $this->name . " started.\n";
}
public function down(bool $force = false) : void
{
echo "Stopping " . $this->name . ".\n";
$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "pg_ctl.exe stop -D " . $this->data_dir . " -m fast";
exec($cmd);
if ($force) {
//sleep(1);
//exec("taskkill /f /im nginx.exe >nul 2>&1");
}
echo $this->name . " stopped.\n";
}
public function createDb(string $db_name) : void
{
$user = $this->conf->getSectionItem($this->name, "user");
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "createdb.exe -h $host -p $port -U $user $db_name";
exec($cmd);
}
public function dropDb(string $db_name) : void
{
$user = $this->conf->getSectionItem($this->name, "user");
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "dropdb.exe --if-exists -h $host -p $port -U $user $db_name";
exec($cmd);
}
public function query(string $s, string $db = NULL) : void
{
$ret = NULL;
$user = $this->conf->getSectionItem($this->name, "user");
$host = $this->conf->getSectionItem($this->name, "host");
$port = $this->conf->getSectionItem($this->name, "port");
$db_arg = $db ? "-d $db" : "";
$cmd = $this->base . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "psql.exe -h $host -p $port -U $user $db_arg -c \"$s\"";
shell_exec($cmd);
}
}

View File

@@ -0,0 +1,106 @@
<?php
namespace SDK\Build\PGO\Tool;
use SDK\Exception;
use SDK\Build\PGO\Config as PGOConfig;
use SDK\Build\PGO\Interfaces;
class PGO
{
protected $php;
protected $conf;
protected $idx = 0;
public function __construct(PGOConfig $conf, Interfaces\PHP $php)
{
$this->conf = $conf;
$this->php = $php;
}
protected function getPgcName(string $fname) : string
{
$bn = basename($fname, substr($fname, -4, 4));
$dn = dirname($fname);
return $dn . DIRECTORY_SEPARATOR . $bn . "!" . $this->idx . ".pgc";
}
protected function getPgdName(string $fname) : string
{
$bn = basename($fname, substr($fname, -4, 4));
$dn = dirname($fname);
return $dn . DIRECTORY_SEPARATOR . $bn . ".pgd";
}
protected function getWorkItems() : array
{
$exe = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.exe");
$dll = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.dll");
$dll = array_merge($dll, glob($this->php->getExtRootDir() . DIRECTORY_SEPARATOR . "php*.dll"));
/* find out next index */
$tpl = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "php{7,8,}{ts,}.dll", GLOB_BRACE)[0];
if (!$tpl) {
throw new Exception("Couldn't find php7[ts].dll in the PHP root dir.");
}
do {
if (!file_exists($this->getPgcName($tpl))) {
break;
}
$this->idx++;
} while (true);
return array_unique(array_merge($exe, $dll));
}
public function dump(bool $merge = true) : void
{
$its = $this->getWorkItems();
foreach ($its as $base) {
$pgc = $this->getPgcName($base);
$pgd = $this->getPgdName($base);
shell_exec("pgosweep $base $pgc");
//passthru("pgosweep $base $pgc");
if ($merge) {
shell_exec("pgomgr /merge:1000 $pgc $pgd");
//passthru("pgomgr /merge:1000 $pgc $pgd");
/* File is already spent, no need to keep it.
If seeing linker warnings about no pgc
were found for some object - most
likely the object were not included in
any training scenario. */
@unlink($pgc);
}
}
}
public function waste() : void
{
$this->dump(false);
}
public function clean(bool $clean_pgc = true, bool $clean_pgd = true) : void
{
if ($clean_pgc) {
$its = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.pgc");
$its = array_merge($its, glob($this->php->getExtRootDir() . DIRECTORY_SEPARATOR . "*" . DIRECTORY_SEPARATOR . "*.pgc"));
foreach (array_unique($its) as $pgc) {
unlink($pgc);
}
}
if ($clean_pgd) {
$its = glob($this->php->getRootDir() . DIRECTORY_SEPARATOR . "*.pgd");
$its = array_merge($its, glob($this->php->getExtRootDir() . DIRECTORY_SEPARATOR . "*" . DIRECTORY_SEPARATOR . "*.pgd"));
foreach (array_unique($its) as $pgd) {
shell_exec("pgomgr /clear $pgd");
//passthru("pgomgr /clear $pgd");
}
}
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace SDK\Build\PGO\Tool;
use SDK\{Exception, FileOps};
use SDK\Build\PGO\Config as PGOConfig;
class PackageWorkman
{
use FileOps;
protected $conf;
public function __construct(PGOConfig $conf)
{
$this->conf = $conf;
}
public function fetch(string $url, string $tgt_fn, bool $force = false) : void
{
$cache_fn = $this->conf->getPkgCacheDir() . DIRECTORY_SEPARATOR . basename($tgt_fn);
if ($force || !file_exists($cache_fn)) {
echo "Fetching '$url' into '$tgt_fn'\n";
$this->download($url, $cache_fn);
}
if ($force || !file_exists($tgt_fn)) {
if ($cache_fn != $tgt_fn && !$this->cp($cache_fn, $tgt_fn)) {
throw new Exception("Failed to copy '$cache_fn' to '$tgt_fn'.");
}
}
}
/* Only for zips! */
public function fetchAndUnzip(string $url, string $zip_bn, string $zip_tgt_dn, string $tgt_bn = NULL, bool $force = false) : void
{
$cache_fn = $this->conf->getPkgCacheDir() . DIRECTORY_SEPARATOR . $zip_bn;
if ($force || !file_exists($cache_fn)) {
$this->fetch($url, $cache_fn, $force);
}
$tgt_name = $zip_tgt_dn . ($tgt_bn ? DIRECTORY_SEPARATOR . $tgt_bn : "");
if ($force || $tgt_bn && !file_exists($tgt_name) || !$tgt_bn /* This means unzip always if no rename. */) {
echo "Unpacking '$cache_fn' to '$tgt_name'\n";
try {
$this->unzip($cache_fn, $zip_tgt_dn, $tgt_bn);
} catch (\Throwable $e) {
$this->rm($cache_fn);
throw $e;
}
}
}
}

View File

@@ -0,0 +1,121 @@
<?php
namespace SDK\Build\PGO\Tool;
use SDK\{Config as SDKConfig, Exception};
use SDK\Build\PGO\Config as PGOConfig;
use SDK\Build\PGO\Interfaces\TrainingCase;
class Training
{
protected $conf;
protected $t_case;
public function __construct(PGOConfig $conf, TrainingCase $t_case)
{
$this->conf = $conf;
$this->t_case = $t_case;
$type = $this->t_case->getType();
if (!in_array($type, array("web", "cli"))) {
throw new Exception("Unknown training type '$type'.");
}
}
public function getCase() : TrainingCase
{
return $this->t_case;
}
public function runWeb(int $max_runs, ?array &$stat = array()) : void
{
$url_list_fn = $this->t_case->getJobFilename();
if (!file_exists($url_list_fn)) {
printf("\033[31m WARNING: Job file '$url_list_fn' not found!\033[0m\n");
}
$a = file($url_list_fn, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$stat = array("http_code" => array(), "not_ok" => array());
for ($k = 0; $k < $max_runs; $k++) {
echo ".";
$ch = array();
$mh = curl_multi_init();
foreach ($a as $i => $u) {
$ch[$i] = curl_init($u);
curl_setopt($ch[$i], CURLOPT_CONNECTTIMEOUT_MS, 500000);
curl_setopt($ch[$i], CURLOPT_TIMEOUT_MS, 500000);
curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch[$i], CURLOPT_USERAGENT, SDKConfig::getSdkUserAgentName());
/* ??? */
/*curl_setopt($ch[$i], CURLOPT_FOLLOWLOCATION, true);*/
curl_multi_add_handle($mh, $ch[$i]);
}
$active = NULL;
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh, 42.0) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach ($ch as $h) {
curl_multi_remove_handle($mh, $h);
/* Gather some stats */
$info = curl_getinfo($h);
$http_code = $info["http_code"];
if (isset($stat["http_code"][$http_code])) {
$stat["http_code"][$http_code]++;
} else {
$stat["http_code"][$http_code] = 1;
}
if (!$this->t_case->httpStatusOk((int)$http_code)) {
$stat["not_ok"][] = $info;
//echo curl_multi_getcontent($h) ;
}
curl_close($h);
}
curl_multi_close($mh);
}
echo "\n";
}
/* TODO Extend with number runs. */
public function run(int $max_runs = 1, ?array &$stat = array()) : void
{
$type = $this->t_case->getType();
switch ($type) {
case "web":
$this->runWeb($max_runs, $stat);
break;
case "cli":
default:
throw new Exception("Unknown training type '$type'.");
}
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace SDK\Build\PGO;
use SDK\Build\PGO\Config as PGOConfig;
class TrainingCaseIterator implements \Iterator
{
protected $conf;
protected $items = array();
protected $idx;
protected $el;
public function __construct(PGOConfig $conf)
{
$this->rewind();
$this->conf = $conf;
$items = glob($this->conf->getCasesTplDir() . DIRECTORY_SEPARATOR . "*");
foreach ($items as $it) {
if (!is_dir($it)) {
continue;
}
if (!file_exists($this->getHandlerFilename($it))) {
echo "Test case handler isn't present in '$it'.\n";
continue;
}
if ($this->isInactive($it)) {
echo "The test case in '$it' is marked inactive.\n";
continue;
}
$this->items[] = $it;
}
}
protected function isInactive(string $base) : bool
{
return file_exists($base . DIRECTORY_SEPARATOR . "inactive");
}
protected function getHandlerFilename(string $base) : string
{
return $base . DIRECTORY_SEPARATOR . "TrainingCaseHandler.php";
}
public function current()
{
$base = $this->items[$this->idx];
$ns = basename($base);
/* Don't overwrite generated config. */
$it = $this->conf->getSectionItem($ns);
if (!$it) {
$this->conf->importSectionFromDir($ns, $base);
}
require_once $this->getHandlerFilename($base);
$srv_http = $this->conf->getSrv($this->conf->getSectionItem($ns, "srv_http"));
$srv_db = $this->conf->getSrv($this->conf->getSectionItem($ns, "srv_db"));
$class = "$ns\\TrainingCaseHandler";
$this->el = new $class($this->conf, $srv_http, $srv_db);
return $this->el;
}
public function next()
{
$this->idx++;
}
public function rewind()
{
$this->idx = 0;
}
public function valid()
{
return $this->idx < count($this->items);
}
public function key()
{
if (!is_object($this->el)) {
return NULL;
}
return $this->el->getName();
}
}

View File

@@ -2,10 +2,6 @@
namespace SDK;
use SDK\Config;
use SDK\Cache;
use SDK\Exception;
class Cache
{
protected $id;
@@ -48,7 +44,7 @@ class Cache
$old_sum = md5_file($p);
$new_sum = md5($content);
return $old_sum != $new_sum;
return $old_sum !== $new_sum;
}/*}}}*/
public function cacheContent(string $path, string $content, bool $relative = false) : void
@@ -64,7 +60,7 @@ class Cache
do {
$got = fwrite($fd, substr($content, $wrote));
if (false == $got) {
if (false === $got) {
break;
}
$wrote += $got;

View File

@@ -3,14 +3,13 @@
namespace SDK;
use SDK\Build\Dependency\Fetcher;
use SDK\Cache;
use SDK\Exception;
class Config
{
/* Config variables. */
protected static $depsHost = 'windows.php.net';
protected static $depsPort = 80;
protected static $depsPort = 443;
protected static $depsUriScheme = "https";
protected static $depsBaseUri = "/downloads/php-sdk/deps";
/* protected static $sdkNugetFeedUrl = "http://127.0.0.1/sdk/nuget"; */
@@ -34,6 +33,11 @@ class Config
return self::$depsPort;
}/*}}}*/
public static function getDepsUriScheme() : string
{/*{{{*/
return self::$depsUriScheme;
}/*}}}*/
public static function getDepsBaseUri() : string
{/*{{{*/
return self::$depsBaseUri;
@@ -124,13 +128,18 @@ class Config
{/*{{{*/
if (empty(self::$knownBranches)) {
$cache_file = "known_branches.txt";
$cache = new Cache(self::getDepsLocalPath());
$fetcher = new Fetcher(self::$depsHost, self::$depsPort);
$deps_path = self::getDepsLocalPath();
if (!$deps_path) {
throw new Exception("Couldn't determine dependencies path. Please either switch to the PHP source root or use -d option.");
}
$cache = new Cache($deps_path);
$fetcher = new Fetcher(self::$depsHost, self::$depsPort, self::$depsUriScheme);
$tmp = $fetcher->getByUri(self::$depsBaseUri . "/series/");
if (false !== $tmp) {
$data = array();
if (preg_match_all(",/packages-(.+)-(vc\d+)-(x86|x64)-(stable|staging)\.txt,U", $tmp, $m, PREG_SET_ORDER)) {
if (preg_match_all(",/packages-(.+)-(vc\d+)-(x86|x64)-(stable|staging)\.txt,U", $tmp, $m, PREG_SET_ORDER)
|| preg_match_all(",/packages-(.+)-(vs\d+)-(x86|x64)-(stable|staging)\.txt,U", $tmp, $m, PREG_SET_ORDER)) {
foreach ($m as $b) {
if (!isset($data[$b[1]])) {
$data[$b[1]] = array();
@@ -173,6 +182,11 @@ class Config
$branch = NULL;
$found = false;
$rmtools_branch = getenv("PHP_RMTOOLS_PHP_BUILD_BRANCH");
if ("master" == $rmtools_branch) {
return "master";
}
/* Try to figure out the branch. The worky scenarios are
- CWD is in php-src
- phpize is on the path
@@ -203,6 +217,19 @@ class Config
if (is_numeric($major) && is_numeric($minor)) {
$branch = "$major.$minor";
}
/* Verify that we use an available branch name. Master has some
version, but no dedicated series. For master, it rather
makes sense to use master as branch name. */
$git = trim(shell_exec("where git.exe"));
if ($git && is_dir(".git")) {
$cmd = "\"$git\" branch";
$ret = trim(shell_exec($cmd));
if (preg_match_all(",\*\s+master,", $ret) > 0) {
$branch = "master";
}
}
}
return $branch;
@@ -247,7 +274,8 @@ class Config
$data = $branches[$current_branch_name][$cur_crt];
} else {
/* Evaluate CRTs, to avoid ambiquity. */
list($crt, $data) = each($branches[$current_branch_name]);
$crt = key($branches[$current_branch_name]);
$data = $branches[$current_branch_name][$crt];
if ($crt != $cur_crt) {
throw new Exception("The passed CRT '$cur_crt' doesn't match any availbale for branch '$current_branch_name'");
}
@@ -266,10 +294,13 @@ class Config
}
}
if (!$ret["stability"]) {
if (!isset($ret["arch"]) || !$ret["arch"]) {
throw new Exception("Failed to find config with arch '" . self::getCurrentArchName() . "'");
}
if (!isset($ret["stability"]) || !$ret["stability"]) {
throw new Exception("Failed to find config with stability '" . self::getCurrentStabilityName() . "'");
}
if (!$ret["crt"]) {
if (!isset($ret["crt"]) || !$ret["crt"]) {
throw new Exception("Failed to find config with arch '" . self::getCurrentArchName() . "'");
}
@@ -376,6 +407,11 @@ class Config
return $path;
}/*}}}*/
public static function getSdkUserAgentName() : string
{/*{{{*/
return "PHP-SDK-BINARY-TOOLS/" . self::getSdkVersion();
}/*}}}*/
}
/*

View File

@@ -2,9 +2,6 @@
namespace SDK;
use SDK\Config;
use SDK\Exception;
trait FileOps
{
protected function md(string $name = "", bool $tmp = false) : string
@@ -116,41 +113,108 @@ trait FileOps
return $ret;
}/*}}}*/
protected function download(string $url, string $dest = NULL) : ?string
protected function download(string $url, string $dest_fn = NULL) : ?string
{/*{{{*/
$fd = NULL;
$ch = curl_init($url);
$retry = 0;
if ($dest) {
$fd = fopen($dest, "w+");
retry:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
if ($dest_fn) {
$fd = fopen($dest_fn, "w+");
curl_setopt($ch, CURLOPT_FILE, $fd);
} else {
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
}
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, Config::getSdkUserAgentName());
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
$ret = curl_exec($ch);
if (false === $ret) {
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (false === $ret || 200 !== $code) {
$err = curl_error($ch);
curl_close($ch);
if ($dest) {
if ($dest_fn) {
fclose($fd);
}
if ($retry++ < 3) {
goto retry;
}
throw new Exception($err);
}
curl_close($ch);
if ($dest) {
if ($dest_fn) {
fclose($fd);
return NULL;
}
return $ret;
}/*}}}*/
/* TODO More detailed zip errors. */
protected function unzip(string $zip_fn, string $dest_fn, string $dest_dn = NULL) : void
{/*{{{*/
$zip = new \ZipArchive;
$res = $zip->open($zip_fn);
if (true !== $res) {
throw new Exception("Failed to open '$zip_fn'.");
}
$res = $zip->extractTo($dest_fn);
if (true !== $res) {
$zip->close();
throw new Exception("Failed to unzip '$zip_fn'.");
}
/* Not robust, useful for zips containing one dir sibling only in the root. */
if ($dest_dn) {
$stat = $zip->statIndex(0);
if (false === $stat) {
$zip->close();
throw new Exception("Failed to stat first index in '$zip_fn'.");
}
$zip->close();
/* Index of zero might be not the zipped folder, unusual but true. */
/*$name = $stat["name"];
if ("/" != substr($name, -1)) {
throw new Exception("'$name' is not a directory.");
}
$name = substr($name, 0, -1);*/
$name = rtrim($stat["name"], "/");
while (strstr($name, '/') !== false) {
$name = dirname($name);
}
$old_dir = $dest_fn . DIRECTORY_SEPARATOR . $name;
$new_dir = $dest_fn . DIRECTORY_SEPARATOR . $dest_dn;
if (file_exists($new_dir)) {
if (!$this->rm($new_dir)) {
throw new Exception("Failed to remove '$new_dir'.");
}
}
/* if (!$this->mv($old_dir, $new_dir)) { */
if (!rename($old_dir, $new_dir)) {
throw new Exception("Failed to rename '$old_dir' to '$new_dir'.");
}
} else {
$zip->close();
}
}/*}}}*/
}
/*

View File

@@ -2,8 +2,6 @@
namespace SDK;
use SDK\{Config, Exception};
class Lock
{
protected $fd;
@@ -68,6 +66,9 @@ class Lock
} else {
$this->fd = fopen($this->fn, "wb");
}
if (false === $this->fd) {
throw new Exception("Failed to open lock under '$this->fn'");
}
$this->locked = flock($this->fd, $flags, $this->wouldBlock);
return $this->locked;
}/*}}}*/

View File

@@ -1,15 +0,0 @@
<?php
function __autoload($name)
{
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . $name . ".php";
}
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 fdm=marker
* vim<600: sw=4 ts=4
*/

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More