diff --git a/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.md b/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.md index d43c900c4..0a46de6de 100644 --- a/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.md +++ b/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.md @@ -30,6 +30,7 @@ Class HttpServer - `->`[`addHandler()`](#method-addhandler) - `->`[`clearHandlers()`](#method-clearhandlers) - _Remove all handlers._ - `->`[`setRequestLogHandler()`](#method-setrequestloghandler) +- `->`[`setErrorHandler()`](#method-seterrorhandler) - `->`[`isRunning()`](#method-isrunning) - `->`[`isFailed()`](#method-isfailed) - `->`[`isStopped()`](#method-isstopped) @@ -222,6 +223,15 @@ setRequestLogHandler([ callable|null $handler): void --- + + +### setErrorHandler() +```php +setErrorHandler([ callable|null $handler): void +``` + +--- + ### isRunning() diff --git a/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.ru.md b/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.ru.md index 9dc933685..7510c3400 100644 --- a/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.ru.md +++ b/exts/jphp-httpserver-ext/api-docs/classes/php/http/HttpServer.ru.md @@ -30,6 +30,7 @@ Class HttpServer - `->`[`addHandler()`](#method-addhandler) - `->`[`clearHandlers()`](#method-clearhandlers) - _Remove all handlers._ - `->`[`setRequestLogHandler()`](#method-setrequestloghandler) +- `->`[`setErrorHandler()`](#method-seterrorhandler) - `->`[`isRunning()`](#method-isrunning) - `->`[`isFailed()`](#method-isfailed) - `->`[`isStopped()`](#method-isstopped) @@ -222,6 +223,15 @@ setRequestLogHandler([ callable|null $handler): void --- + + +### setErrorHandler() +```php +setErrorHandler([ callable|null $handler): void +``` + +--- + ### isRunning() diff --git a/exts/jphp-httpserver-ext/src/main/java/org/develnext/jphp/ext/httpserver/classes/PHttpServer.java b/exts/jphp-httpserver-ext/src/main/java/org/develnext/jphp/ext/httpserver/classes/PHttpServer.java index 9b6bc0547..7d017e80b 100644 --- a/exts/jphp-httpserver-ext/src/main/java/org/develnext/jphp/ext/httpserver/classes/PHttpServer.java +++ b/exts/jphp-httpserver-ext/src/main/java/org/develnext/jphp/ext/httpserver/classes/PHttpServer.java @@ -1,5 +1,6 @@ package org.develnext.jphp.ext.httpserver.classes; +import javax.servlet.RequestDispatcher; import org.develnext.jphp.ext.httpserver.HttpServerExtension; import org.eclipse.jetty.server.*; import org.eclipse.jetty.server.handler.*; @@ -442,6 +443,23 @@ public void setRequestLogHandler(Environment env, @Nullable Invoker invoker) { } } + @Signature + public void setErrorHandler(Environment env, @Nullable Invoker invoker) { + if (invoker == null) { + server.setErrorHandler(null); + } else { + ErrorHandler errorHandler = new ErrorHandler(); + + server.setErrorHandler(new ErrorHandler() { + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { + Throwable th = (Throwable)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION); + invoker.callAny(th, new PHttpServerRequest(env, Request.getBaseRequest(request)), new PHttpServerResponse(env, response)); + } + }); + } + } + public static class InvokeHandler extends AbstractHandler { private final Invoker invoker; diff --git a/exts/jphp-httpserver-ext/src/main/resources/JPHP-INF/sdk/php/http/HttpServer.php b/exts/jphp-httpserver-ext/src/main/resources/JPHP-INF/sdk/php/http/HttpServer.php index 2f11803c5..67e59740a 100644 --- a/exts/jphp-httpserver-ext/src/main/resources/JPHP-INF/sdk/php/http/HttpServer.php +++ b/exts/jphp-httpserver-ext/src/main/resources/JPHP-INF/sdk/php/http/HttpServer.php @@ -1,6 +1,8 @@ addVendorClassPath($vendor); $exec->addPackageClassPath($event->package()); - $buildFileName = "{$event->package()->getName()}-{$event->package()->getVersion('last')}.jar"; + $buildFileName = "{$event->package()->getName()}-{$event->package()->getVersion('last')}"; - if ($build['fileName']) { - $buildFileName = $build['fileName']; + if ($build['file-name']) { + $buildFileName = $build['file-name']; } $buildDir = $event->package()->getConfigBuildPath(); Tasks::createDir("$buildDir"); - Tasks::createFile("$buildDir/$buildFileName"); + Tasks::createFile("$buildDir/$buildFileName.jar"); - $zip = new ZipArchive("$buildDir/$buildFileName"); + $zip = new ZipArchive("$buildDir/$buildFileName.jar"); $zip->open(); - Tasks::createDir("$buildDir/app"); + Tasks::createDir("$buildDir/.app"); $metaInfServices = []; @@ -91,7 +94,7 @@ function build(Event $event) fs::scan($classPath, function ($filename) use ($zip, $classPath, &$metaInfServices, $buildDir) { $name = fs::relativize($filename, $classPath); - $file = "$buildDir/app/$name"; + $file = "$buildDir/.app/$name"; Console::log("--> add file: {$classPath}/{$name}"); @@ -120,7 +123,7 @@ function build(Event $event) if (str::startsWith($name, "META-INF/services/")) { $metaInfServices[$name] = flow((array) $metaInfServices[$name], str::lines($stream->readFully()))->toArray(); } else { - $file = "$buildDir/app/{$name}"; + $file = "$buildDir/.app/{$name}"; //Console::log("--> add jar file: $name"); @@ -131,18 +134,18 @@ function build(Event $event) } } - Tasks::cleanDir("$buildDir/app/JPHP-INF/sdk"); - Tasks::deleteFile("$buildDir/app/JPHP-INF/sdk"); + Tasks::cleanDir("$buildDir/.app/JPHP-INF/sdk"); + Tasks::deleteFile("$buildDir/.app/JPHP-INF/sdk"); - fs::delete("$buildDir/app/META-INF/manifest.mf"); - fs::delete("$buildDir/app/META-INF/Manifest.mf"); - fs::delete("$buildDir/app/META-INF/MANIFEST.MF"); + fs::delete("$buildDir/.app/META-INF/manifest.mf"); + fs::delete("$buildDir/.app/META-INF/Manifest.mf"); + fs::delete("$buildDir/.app/META-INF/MANIFEST.MF"); if (!$launcher['disable-launcher']) { Console::log("-> create jphp app launcher"); - Tasks::createDir("$buildDir/app/JPHP-INF/"); - Tasks::createDir("$buildDir/app/META-INF/"); + Tasks::createDir("$buildDir/.app/JPHP-INF/"); + Tasks::createDir("$buildDir/.app/META-INF/"); $includes = (array) $vendor->fetchPaths()['includes']; @@ -152,14 +155,14 @@ function build(Event $event) $launcher['bootstrap'] = arr::pop($includes); } - fs::formatAs("$buildDir/app/JPHP-INF/launcher.conf", [ + fs::formatAs("$buildDir/.app/JPHP-INF/launcher.conf", [ 'bootstrap.files' => flow($includes)->map(function ($one) { return "res://$one"; })->toString('|'), 'bootstrap.file' => $launcher['bootstrap'] ? "res://{$launcher['bootstrap']}" : 'res://JPHP-INF/.bootstrap.php' ], 'ini'); - Tasks::createFile("$buildDir/app/META-INF/MANIFEST.MF"); + Tasks::createFile("$buildDir/.app/META-INF/MANIFEST.MF"); - Stream::putContents("$buildDir/app/META-INF/MANIFEST.MF", str::join([ + Stream::putContents("$buildDir/.app/META-INF/MANIFEST.MF", str::join([ "Manifest-Version: 1.0", "Created-By: jppm (JPHP Packager " . $event->packager()->getVersion() . ")", "Main-Class: " . ($launcher['mainClass'] ?? 'php.runtime.launcher.Launcher'), @@ -171,24 +174,65 @@ function build(Event $event) } foreach ($metaInfServices as $name => $lines) { - fs::ensureParent("$buildDir/app/$name"); - Stream::putContents("$buildDir/app/$name", str::join($lines, "\n")); + fs::ensureParent("$buildDir/.app/$name"); + Stream::putContents("$buildDir/.app/$name", str::join($lines, "\n")); } - fs::scan("$buildDir/app", function (File $file) use ($zip, $buildDir) { + fs::scan("$buildDir/.app", function (File $file) use ($zip, $buildDir) { if ($file->isFile()) { - $zip->addFile($file, fs::relativize($file, "$buildDir/app")); + $zip->addFile($file, fs::relativize($file, "$buildDir/.app")); } }); $zip->close(); - $time = Time::millis() - $time; + Tasks::deleteFile("$buildDir/.app"); - if (!$launcher['disable-launcher']) { - Console::log("\n Use 'java -jar \"$buildDir/$buildFileName\"' to run the result app."); + foreach ($event->package()->getAny('app.assets', []) as $asset) { + Tasks::deleteFile("$buildDir/" . fs::name($asset)); + + if (fs::isDir($asset)) { + Tasks::copy($asset, "$buildDir/" . fs::name($asset)); + } else { + Tasks::copy($asset, "$buildDir/"); + } + } + + switch (str::lower($event->package()->getAny('app.build.result'))) { + case 'tar': + Console::log("-> pack build dir to tar.gz archive ..."); + + $archFile = File::createTemp($buildFileName, ".tar.gz"); + $archFile->deleteOnExit(); + + $tar = new TarArchive(new GzipOutputStream($archFile)); + $tar->open(); + + fs::scan("$buildDir/", function ($file) use ($buildDir, $tar) { + Console::log("-> pack '{0}'", fs::relativize($file, $buildDir . "/")); + if (fs::isFile($file)) { + $tar->addFile($file, fs::relativize($file, $buildDir . "/")); + } else { + $tar->addEmptyEntry(new TarArchiveEntry(fs::relativize($file, $buildDir . "/"))); + } + }); + + $tar->close(); + + Tasks::cleanDir("$buildDir/"); + Tasks::copy($archFile, "$buildDir/"); + fs::rename("$buildDir/" . fs::name($archFile), "{$buildFileName}.tar.gz"); + + break; + + default: + if (!$launcher['disable-launcher']) { + Console::log("\n Use 'java -jar \"$buildDir/$buildFileName.jar\"' to run the result app."); + } } + $time = Time::millis() - $time; + Console::log("\n-----"); Console::log("Building time: {0} sec.", round($time / 1000, 2)); Console::log("Building is SUCCESSFUL. :)"); diff --git a/packager/package.php.yml b/packager/package.php.yml index 0b78babb3..b41d31d89 100644 --- a/packager/package.php.yml +++ b/packager/package.php.yml @@ -1,5 +1,5 @@ name: jppm -version: 0.2.7 +version: 0.2.8 plugins: [GitHub, Hub, Doc] @@ -14,7 +14,8 @@ github: > JPHP Package Manager v%version% **What's new** - + Improve the `tasks` section in package yml. + + Improve App Plugin. + + Improve internal api. **Downloads** + For Windows: [JPPM Windows Installer](%github.address%/releases/download/jppm-%version%/jppm-setup-%version%.exe) diff --git a/packager/src-php/Tasks.php b/packager/src-php/Tasks.php index 88d0dd870..9129e7aae 100644 --- a/packager/src-php/Tasks.php +++ b/packager/src-php/Tasks.php @@ -20,6 +20,43 @@ static function run(string $name, array $args = [], ...$flags) $app->invokeTask($name, $args, ...arr::combine($flags, $flags)); } + /** + * Copy file or directory. + * + * @param string $path + * @param string $intoDir + * @param bool $ignoreErrs + */ + static function copy(string $path, string $intoDir, bool $ignoreErrs = false) + { + if (fs::isFile($path)) { + if (fs::copy($path, "$intoDir/" . fs::name($path), 1024 * 128) < 0) { + Console::error("Failed to copy file '{0}' into dir '{1}'", $path, $intoDir); + if (!$ignoreErrs) { + exit(-1); + } + } + } else if (fs::isDir($path)) { + fs::scan($path, function ($file) use ($path, $intoDir, $ignoreErrs) { + $name = fs::relativize($file, $path); + + if (fs::isDir($file)) { + fs::makeDir("$intoDir/$name"); + return; + } + + fs::ensureParent("$intoDir/$name"); + + if (fs::copy($file, "$intoDir/$name", 1024 * 128) < 0) { + Console::error("Failed to copy file '{0}' into dir '{1}'", $path, $intoDir); + if (!$ignoreErrs) { + exit(-1); + } + } + }); + } + } + /** * @param string $path * @param string $content @@ -35,7 +72,7 @@ static function createFile(string $path, string $content = '', bool $ignoreErrs Stream::putContents($path, $content); return true; } catch (IOException $e) { - Console::error("Failed to create file '{0}', cause = {0}", $path, $e->getMessage()); + Console::error("Failed to create file '{0}', cause = {1}", $path, $e->getMessage()); if (!$ignoreErrs) { exit(-1); }