From 8efcf46b31bd58defa106f1f21c34b7c414033d1 Mon Sep 17 00:00:00 2001 From: Shivam Mathur Date: Wed, 15 Jul 2020 09:45:40 +0530 Subject: [PATCH] Add support for oci8 and pdo_oci --- __tests__/extensions.test.ts | 14 +++- dist/index.js | 31 ++++++++ src/extensions.ts | 31 ++++++++ src/scripts/ext/oci.ps1 | 45 ++++++++++++ src/scripts/ext/oci.sh | 133 +++++++++++++++++++++++++++++++++++ src/scripts/win32.ps1 | 4 +- 6 files changed, 254 insertions(+), 4 deletions(-) create mode 100644 src/scripts/ext/oci.ps1 create mode 100644 src/scripts/ext/oci.sh diff --git a/__tests__/extensions.test.ts b/__tests__/extensions.test.ts index 8448bc9c..70f9d0f6 100644 --- a/__tests__/extensions.test.ts +++ b/__tests__/extensions.test.ts @@ -11,7 +11,7 @@ describe('Extension tests', () => { }); it('checking addExtensionOnWindows', async () => { let win32: string = await extensions.addExtension( - 'Xdebug, pcov, sqlite, :intl, phalcon4, ast-beta, grpc-1.2.3, inotify-1.2.3alpha2', + 'Xdebug, pcov, sqlite, :intl, phalcon4, oci8, pdo_oci, ast-beta, grpc-1.2.3, inotify-1.2.3alpha2', '7.4', 'win32' ); @@ -20,6 +20,8 @@ describe('Extension tests', () => { expect(win32).toContain('Add-Extension sqlite3'); expect(win32).toContain('Remove-Extension intl'); expect(win32).toContain('phalcon.ps1 phalcon4'); + expect(win32).toContain('oci.ps1 oci8 7.4'); + expect(win32).toContain('oci.ps1 pdo_oci 7.4'); expect(win32).toContain('Add-Extension ast beta'); expect(win32).toContain('Add-Extension grpc stable 1.2.3'); expect(win32).toContain('Add-Extension inotify alpha 1.2.3'); @@ -107,6 +109,10 @@ describe('Extension tests', () => { expect(linux).toContain('phalcon.sh phalcon3 7.3'); expect(linux).toContain('phalcon.sh phalcon4 7.3'); + linux = await extensions.addExtension('oci8, pdo_oci', '7.3', 'linux'); + expect(linux).toContain('oci.sh oci8 7.3'); + expect(linux).toContain('oci.sh pdo_oci 7.3'); + linux = await extensions.addExtension('blackfire', '7.3', 'linux'); expect(linux).toContain('blackfire.sh 7.3 blackfire'); @@ -116,7 +122,7 @@ describe('Extension tests', () => { it('checking addExtensionOnDarwin', async () => { let darwin: string = await extensions.addExtension( - 'Xdebug, pcov, grpc, protobuf, swoole, sqlite, :intl, ast-beta, grpc-1.2.3', + 'Xdebug, pcov, grpc, protobuf, swoole, sqlite, oci8, pdo_oci, :intl, ast-beta, grpc-1.2.3', '7.2', 'darwin' ); @@ -136,6 +142,10 @@ describe('Extension tests', () => { darwin = await extensions.addExtension('phalcon4', '7.3', 'darwin'); expect(darwin).toContain('phalcon_darwin.sh phalcon4 7.3'); + darwin = await extensions.addExtension('oci8, pdo_oci', '7.3', 'darwin'); + expect(darwin).toContain('oci.sh oci8 7.3'); + expect(darwin).toContain('oci.sh pdo_oci 7.3'); + darwin = await extensions.addExtension('pcov', '5.6', 'darwin'); expect(darwin).toContain('sudo pecl install -f pcov'); diff --git a/dist/index.js b/dist/index.js index c486367e..56e48164 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3672,6 +3672,16 @@ async function addExtensionDarwin(extension_csv, version, pipe) { extension = 'sqlite3'; command = command_prefix + extension; break; + // match pdo_oci and oci8 + case /^pdo_oci$|^oci8$/.test(extension): + add_script += + '\nbash ' + + path.join(__dirname, '../src/scripts/ext/oci.sh') + + ' ' + + extension + + ' ' + + version; + return; // match 7.0phalcon3...7.3phalcon3 and 7.2phalcon4...7.4phalcon4 case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += @@ -3754,6 +3764,17 @@ async function addExtensionWindows(extension_csv, version) { extension = 'sqlite3'; add_script += '\nAdd-Extension ' + extension; break; + // match pdo_oci and oci8 + case /^pdo_oci$|^oci8$/.test(extension): + add_script += + '\n& ' + + path.join(__dirname, '../src/scripts/ext/oci.ps1') + + ' ' + + extension + + ' ' + + version + + '\n'; + break; // match 7.0phalcon3...7.3phalcon3 and 7.2phalcon4...7.4phalcon4 case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += @@ -3835,6 +3856,16 @@ async function addExtensionLinux(extension_csv, version, pipe) { version + pipe; break; + // match pdo_oci and oci8 + case /^pdo_oci$|^oci8$/.test(extension): + add_script += + '\nbash ' + + path.join(__dirname, '../src/scripts/ext/oci.sh') + + ' ' + + extension + + ' ' + + version; + return; // match 7.0phalcon3...7.3phalcon3 or 7.2phalcon4...7.4phalcon4 case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += diff --git a/src/extensions.ts b/src/extensions.ts index f827a205..25afc6d2 100644 --- a/src/extensions.ts +++ b/src/extensions.ts @@ -113,6 +113,16 @@ export async function addExtensionDarwin( extension = 'sqlite3'; command = command_prefix + extension; break; + // match pdo_oci and oci8 + case /^pdo_oci$|^oci8$/.test(extension): + add_script += + '\nbash ' + + path.join(__dirname, '../src/scripts/ext/oci.sh') + + ' ' + + extension + + ' ' + + version; + return; // match 7.0phalcon3...7.3phalcon3 and 7.2phalcon4...7.4phalcon4 case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += @@ -204,6 +214,17 @@ export async function addExtensionWindows( extension = 'sqlite3'; add_script += '\nAdd-Extension ' + extension; break; + // match pdo_oci and oci8 + case /^pdo_oci$|^oci8$/.test(extension): + add_script += + '\n& ' + + path.join(__dirname, '../src/scripts/ext/oci.ps1') + + ' ' + + extension + + ' ' + + version + + '\n'; + break; // match 7.0phalcon3...7.3phalcon3 and 7.2phalcon4...7.4phalcon4 case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += @@ -291,6 +312,16 @@ export async function addExtensionLinux( version + pipe; break; + // match pdo_oci and oci8 + case /^pdo_oci$|^oci8$/.test(extension): + add_script += + '\nbash ' + + path.join(__dirname, '../src/scripts/ext/oci.sh') + + ' ' + + extension + + ' ' + + version; + return; // match 7.0phalcon3...7.3phalcon3 or 7.2phalcon4...7.4phalcon4 case /^7\.[0-3]phalcon3$|^7\.[2-4]phalcon4$/.test(version_extension): add_script += diff --git a/src/scripts/ext/oci.ps1 b/src/scripts/ext/oci.ps1 new file mode 100644 index 00000000..d107deb5 --- /dev/null +++ b/src/scripts/ext/oci.ps1 @@ -0,0 +1,45 @@ +Param ( + [Parameter(Position = 0, Mandatory = $true)] + [ValidateNotNull()] + [ValidateSet('oci8', 'pdo_oci')] + [string] + $extension, + [Parameter(Position = 1, Mandatory = $true)] + [ValidateNotNull()] + [ValidateLength(1, [int]::MaxValue)] + [string] + $version +) + +$tick = ([char]8730) +$php_dir = 'C:\tools\php' +if($env:RUNNER -eq 'self-hosted') { $php_dir = "$php_dir$version" } +$ext_dir = "$php_dir\ext" +if(-not(Test-Path $php_dir\oci.dll)) { + $suffix = 'windows' + if(-not([Environment]::Is64BitOperatingSystem) -or $version -lt '7.0') { + $suffix = 'nt' + } + Invoke-WebRequest -UseBasicParsing -Uri https://download.oracle.com/otn_software/nt/instantclient/instantclient-basiclite-$suffix.zip -OutFile $php_dir\instantclient.zip + Expand-Archive -Path $php_dir\instantclient.zip -DestinationPath $php_dir -Force + Copy-Item $php_dir\instantclient*\* $php_dir +} +if ($extension -eq "pdo_oci") { + Enable-PhpExtension pdo_oci -Path $php_dir +} else { + $ociVersion = '2.2.0' + if ($version -eq '7.0') + { + $ociVersion = '2.1.8' + } + elseif ($version -lt '7.0') + { + $ociVersion = '2.0.12' + } + $PhpVersion = Get-Php -Path $php_dir + $ociUrl = Get-PeclArchiveUrl oci8 $ociVersion $phpVersion + Invoke-WebRequest -UseBasicParsing -Uri $ociUrl -OutFile $php_dir\oci8.zip + Expand-Archive -Path $php_dir\oci8.zip -DestinationPath $ext_dir -Force + Add-Content -Value "`r`nextension=php_oci8.dll" -Path $php_dir\php.ini +} +printf "\033[%s;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s \033[0m\n" "32" $tick $extension "Enabled" \ No newline at end of file diff --git a/src/scripts/ext/oci.sh b/src/scripts/ext/oci.sh new file mode 100644 index 00000000..fb18709b --- /dev/null +++ b/src/scripts/ext/oci.sh @@ -0,0 +1,133 @@ +# Function to log result of a operation. +add_log() { + mark=$1 + subject=$2 + message=$3 + if [ "$mark" = "$tick" ]; then + printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message" + else + printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message" + fi +} + +# Function to test if extension is loaded. +check_extension() { + extension=$1 + php -m | grep -i -q -w "$extension" +} + +# Function to get the tag for a php version. +get_tag() { + master_version='8.0' + tag='master' + if [ ! "$version" = "$master_version" ]; then + tag="php-$(php -v | head -n 1 | cut -f 2 -d ' ' | cut -f 1 -d '-')" + fi + echo "$tag" +} + +# Function to install instantclient and SDK. +install_client() { + sudo mkdir -p -m 777 "$oracle_home" + if [ ! -e "$oracle_client" ]; then + for package in basiclite sdk; do + if [ "$os" = 'Linux' ]; then + libs='/usr/lib/' + os_name='linux' + arch='linuxx64' + lib_ext='so' + elif [ "$os" = 'Darwin' ]; then + libs='/usr/local/lib/' + os_name='mac' + arch='macos' + lib_ext='dylib' + fi + curl -o "/opt/oracle/$package.zip" -sSL "https://download.oracle.com/otn_software/$os_name/instantclient/instantclient-$package-$arch.zip" + unzip "/opt/oracle/$package.zip" -d "$oracle_home" + done + sudo ln -sf /opt/oracle/instantclient*/*.$lib_ext* $libs + sudo ln -sf /opt/oracle/instantclient* "$oracle_client" + fi +} + +# Function to get PHP source. +get_php() { + [ ! -d "/opt/oracle/php-src-$tag" ] && curl -sSL "https://github.com/php/php-src/archive/$tag.tar.gz" | tar xzf - -C "$oracle_home/" +} + +# Function to get phpize location on darwin. +get_phpize() { + if [[ "$version" =~ 5.[3-5] ]]; then + echo '/opt/local/bin/phpize' + else + echo "/usr/local/bin/$(readlink /usr/local/bin/phpize)" + fi +} + +# Function to patch phpize to link to php headers on darwin. +patch_phpize() { + if [ "$os" = "Darwin" ]; then + sudo cp "$phpize_orig" "$phpize_orig.bck" + sudo sed -i '' 's~includedir=.*~includedir="$(xcrun --show-sdk-path)/usr/include/php"~g' "$phpize_orig" + fi +} + +# Function to restore phpize. +restore_phpize() { + if [ "$os" = "Darwin" ]; then + sudo mv "$phpize_orig.bck" "$phpize_orig" || true + fi +} + +# Function to patch pdo_oci. +patch_pdo_oci_config() { + curl -sSLO https://raw.githubusercontent.com/php/php-src/master/ext/pdo_oci/config.m4 + sudo sed -i '' "/PHP_CHECK_PDO_INCLUDES/d" config.m4 || sudo sed -i "/PHP_CHECK_PDO_INCLUDES/d" config.m4 +} + +# Function to install the dependencies. +install_dependencies() { + if [ "$os" = 'Linux' ]; then + if [ "$runner" = "self-hosted" ] || [ "$RUNNER" = "self-hosted" ]; then + sudo DEBIAN_FRONTEND=noninteractive apt-fast install -y autoconf automake libaio-dev gcc g++ php"$version"-dev + else + sudo DEBIAN_FRONTEND=noninteractive apt-fast install -y php"$version"-dev + fi + sudo update-alternatives --set php-config /usr/bin/php-config"$version" + sudo update-alternatives --set phpize /usr/bin/phpize"$version" + fi +} + +# Function to install the extension. +install_extension() { + if ! [ -e "$ext_dir/$ext.so" ]; then + ( + phpize_orig=$(get_phpize) + tag=$(get_tag) + get_php + patch_phpize + cd "/opt/oracle/php-src-$tag/ext/$ext" || exit 1 + [ "$ext" = "pdo_oci" ] && patch_pdo_oci_config + sudo phpize && ./configure --with-php-config="$(command -v php-config)" --with-"${ext/_/-}"=instantclient,"$oracle_client" + sudo make -j"$(nproc)" + sudo cp ./modules/* "$ext_dir/" + restore_phpize + ) + fi + echo "extension=$ext.so" | sudo tee "$scan_dir/99-$ext.ini" +} + +ext=$1 +version=$2 +tick='✓' +cross='✗' +oracle_home='/opt/oracle' +oracle_client=$oracle_home/instantclient +runner="${runner:-github}" && RUNNER="${RUNNER:-github}" +os=$(uname -s) +scan_dir=$(php --ini | grep additional | sed -e "s|.*: s*||") +ext_dir=$(php -i | grep "extension_dir => /" | sed -e "s|.*=> s*||") +install_client >/dev/null 2>&1 +install_dependencies >/dev/null 2>&1 +install_extension >/dev/null 2>&1 +(check_extension "$ext" && add_log "$tick" "$ext" "Installed and enabled") || add_log "$cross" "$ext" "Could not install $ext" \ No newline at end of file diff --git a/src/scripts/win32.ps1 b/src/scripts/win32.ps1 index 3b0646b5..0381f078 100644 --- a/src/scripts/win32.ps1 +++ b/src/scripts/win32.ps1 @@ -77,8 +77,8 @@ Function Get-CleanPSProfile { Function Install-PhpManager() { $repo = "mlocati/powershell-phpmanager" $tag = (Invoke-RestMethod https://api.github.com/repos/$repo/tags)[0].Name - $module_path = "$bin_dir\PhpManager\powershell-phpmanager-$tag\PhpManager" - if(-not (Test-Path $module_path\PhpManager.psm1 -PathType Leaf)) { + $module_path = "$bin_dir\PhpManager\powershell-phpmanager-$tag\PhpManager\PhpManager.psm1" + if(-not (Test-Path $module_path -PathType Leaf)) { $zip_file = "$bin_dir\PhpManager.zip" Invoke-WebRequest -UseBasicParsing -Uri https://github.com/$repo/archive/$tag.zip -OutFile $zip_file Expand-Archive -Path $zip_file -DestinationPath $bin_dir\PhpManager -Force