modifs.mineures sans commentaires
This commit is contained in:
parent
16376a473a
commit
a09f3a0a2b
|
@ -1,13 +1,26 @@
|
||||||
#!/usr/bin/php
|
#!/usr/bin/php
|
||||||
<?php
|
<?php
|
||||||
require $_composer_autoload_path?? __DIR__.'/../vendor/autoload.php';
|
$internalUse = $argv[1] ?? null;
|
||||||
|
if ($internalUse !== "--internal-use") exit("Wrong args");
|
||||||
|
$paramsfile = $argv[2] ?? null;
|
||||||
|
if (!file_exists($paramsfile)) exit("bad params file");
|
||||||
|
$argc -= 2;
|
||||||
|
$argv = array_merge(
|
||||||
|
array_slice($argv, 0, 1),
|
||||||
|
array_slice($argv, 3),
|
||||||
|
);
|
||||||
|
|
||||||
|
$app_params = unserialize(file_get_contents($paramsfile));
|
||||||
|
require $app_params["vendor"]["autoload"];
|
||||||
|
|
||||||
use nur\cli\Application;
|
use nur\cli\Application;
|
||||||
use nur\sery\wip\app\app;
|
use nur\sery\wip\app\app;
|
||||||
use nur\sery\app\launcher;
|
use nur\sery\app\launcher;
|
||||||
use nur\yaml;
|
use nur\yaml;
|
||||||
|
|
||||||
Application::run(new class extends Application {
|
class _LaunchApp extends Application {
|
||||||
|
const NAME = "_launch";
|
||||||
|
|
||||||
const ACTION_INFOS = 0, ACTION_START = 1, ACTION_STOP = 2;
|
const ACTION_INFOS = 0, ACTION_START = 1, ACTION_STOP = 2;
|
||||||
|
|
||||||
const ARGS = [
|
const ARGS = [
|
||||||
|
@ -44,8 +57,7 @@ Application::run(new class extends Application {
|
||||||
self::die("Cette application ne supporte pas l'usage de runfile");
|
self::die("Cette application ne supporte pas l'usage de runfile");
|
||||||
}
|
}
|
||||||
|
|
||||||
$app = app::with($appClass);
|
$runfile = app::with($appClass, self::$internal_use_app_params)->getRunfile();
|
||||||
$runfile = $app->getRunfile();
|
|
||||||
switch ($this->action) {
|
switch ($this->action) {
|
||||||
case self::ACTION_START:
|
case self::ACTION_START:
|
||||||
launcher::_start($args, $runfile);
|
launcher::_start($args, $runfile);
|
||||||
|
@ -58,4 +70,6 @@ Application::run(new class extends Application {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
_LaunchApp::internal_use_set_app_params($app_params);
|
||||||
|
_LaunchApp::run();
|
||||||
|
|
|
@ -19,9 +19,20 @@ use nur\sery\output\std\StdMessenger;
|
||||||
* Class Application: application de base
|
* Class Application: application de base
|
||||||
*/
|
*/
|
||||||
abstract class Application {
|
abstract class Application {
|
||||||
|
protected static ?array $internal_use_app_params = null;
|
||||||
|
|
||||||
|
static function internal_use_set_app_params($params) {
|
||||||
|
self::$internal_use_app_params = $params;
|
||||||
|
}
|
||||||
|
|
||||||
/** @var string répertoire du projet (celui qui contient composer.json */
|
/** @var string répertoire du projet (celui qui contient composer.json */
|
||||||
const PROJDIR = null;
|
const PROJDIR = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array répertoires vendor exprimés relativement à PROJDIR
|
||||||
|
*/
|
||||||
|
const VENDOR = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string code du projet, utilisé pour dériver le noms de certains des
|
* @var string code du projet, utilisé pour dériver le noms de certains des
|
||||||
* paramètres extraits de l'environnement, e.g XXX_DATADIR si le projet a pour
|
* paramètres extraits de l'environnement, e.g XXX_DATADIR si le projet a pour
|
||||||
|
@ -85,7 +96,7 @@ abstract class Application {
|
||||||
if ($projdir == "/") break;
|
if ($projdir == "/") break;
|
||||||
}
|
}
|
||||||
|
|
||||||
app::init(static::class);
|
app::init(static::class, self::$internal_use_app_params);
|
||||||
nmsg::set_messenger(new StdMessenger([
|
nmsg::set_messenger(new StdMessenger([
|
||||||
"min_level" => nmsg::DEBUG,
|
"min_level" => nmsg::DEBUG,
|
||||||
]));
|
]));
|
||||||
|
@ -124,9 +135,8 @@ abstract class Application {
|
||||||
$unlock = false;
|
$unlock = false;
|
||||||
$stop = false;
|
$stop = false;
|
||||||
register_shutdown_function(function () use (&$unlock, &$stop) {
|
register_shutdown_function(function () use (&$unlock, &$stop) {
|
||||||
$runfile = app::get()->getRunfile();
|
if ($unlock) app::get()->getRunfile()->release();
|
||||||
if ($unlock) $runfile->release();
|
if ($stop) app::get()->getRunfile()->wfStop();
|
||||||
if ($stop) $runfile->wfStop();
|
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
static::_app_init();
|
static::_app_init();
|
||||||
|
|
|
@ -175,14 +175,14 @@ class RunFile {
|
||||||
if ($data["date_stop"] !== null) return false;
|
if ($data["date_stop"] !== null) return false;
|
||||||
if (!posix_kill($data["pid"], 0)) {
|
if (!posix_kill($data["pid"], 0)) {
|
||||||
switch (posix_get_last_error()) {
|
switch (posix_get_last_error()) {
|
||||||
case PCNTL_ESRCH:
|
case 1: #PCNTL_EPERM:
|
||||||
# process inexistant
|
|
||||||
return false;
|
|
||||||
case PCNTL_EPERM:
|
|
||||||
# process auquel on n'a pas accès?! est-ce un autre process qui a
|
# process auquel on n'a pas accès?! est-ce un autre process qui a
|
||||||
# réutilisé le PID?
|
# réutilisé le PID?
|
||||||
return false;
|
return false;
|
||||||
case PCNTL_EINVAL:
|
case 3: #PCNTL_ESRCH:
|
||||||
|
# process inexistant
|
||||||
|
return false;
|
||||||
|
case 22: #PCNTL_EINVAL:
|
||||||
# ne devrait pas se produire
|
# ne devrait pas se produire
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -281,14 +281,14 @@ class RunFile {
|
||||||
$pid ??= $data["pid"];
|
$pid ??= $data["pid"];
|
||||||
if (!posix_kill($pid, 0)) {
|
if (!posix_kill($pid, 0)) {
|
||||||
switch (posix_get_last_error()) {
|
switch (posix_get_last_error()) {
|
||||||
case PCNTL_ESRCH:
|
case 1: #PCNTL_EPERM:
|
||||||
# process inexistant
|
|
||||||
return true;
|
|
||||||
case PCNTL_EPERM:
|
|
||||||
# process auquel on n'a pas accès?! est-ce un autre process qui a
|
# process auquel on n'a pas accès?! est-ce un autre process qui a
|
||||||
# réutilisé le PID?
|
# réutilisé le PID?
|
||||||
return false;
|
return false;
|
||||||
case PCNTL_EINVAL:
|
case 3: #PCNTL_ESRCH:
|
||||||
|
# process inexistant
|
||||||
|
return true;
|
||||||
|
case 22: #PCNTL_EINVAL:
|
||||||
# ne devrait pas se produire
|
# ne devrait pas se produire
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,32 @@
|
||||||
<?php
|
<?php
|
||||||
namespace nur\sery\app;
|
namespace nur\sery\app;
|
||||||
|
|
||||||
|
use nur\sery\file\TmpfileWriter;
|
||||||
use nur\sery\os\proc\Cmd;
|
use nur\sery\os\proc\Cmd;
|
||||||
use nur\sery\output\msg;
|
use nur\sery\output\msg;
|
||||||
use nur\sery\StateException;
|
use nur\sery\StateException;
|
||||||
|
use nur\sery\wip\app\app;
|
||||||
|
|
||||||
class launcher {
|
class launcher {
|
||||||
static function launch(string $appClass, ...$args): int {
|
static function launch(string $appClass, ...$args): int {
|
||||||
global $_composer_bin_dir;
|
$app = app::get();
|
||||||
if (isset($_composer_bin_dir)) {
|
$vendorBindir = $app->getVendorbindir();
|
||||||
$launch_php = "$_composer_bin_dir/_launch.php";
|
$launch_php = "$vendorBindir/_launch.php";
|
||||||
} else {
|
if (!file_exists($launch_php)) {
|
||||||
$launch_php = __DIR__."/../../lib/_launch.php";
|
$launch_php = __DIR__."/../../lib/_launch.php";
|
||||||
}
|
}
|
||||||
$cmd = new Cmd([$launch_php, $appClass, ...$args]);
|
$tmpfile = new TmpfileWriter();
|
||||||
//$cmd->addRedir("null");
|
$tmpfile->serialize($app->getParams());
|
||||||
|
|
||||||
|
$cmd = new Cmd([
|
||||||
|
$launch_php,
|
||||||
|
"--internal-use", $tmpfile->getFile(),
|
||||||
|
$appClass, ...$args,
|
||||||
|
]);
|
||||||
|
$cmd->addRedir("null");
|
||||||
$cmd->passthru($exitcode);
|
$cmd->passthru($exitcode);
|
||||||
|
|
||||||
|
$tmpfile->close();
|
||||||
return $exitcode;
|
return $exitcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +48,6 @@ class launcher {
|
||||||
# puis lancer la commande
|
# puis lancer la commande
|
||||||
$cmd = new Cmd($args);
|
$cmd = new Cmd($args);
|
||||||
#XXX fichier de log?
|
#XXX fichier de log?
|
||||||
#XXX charger /g/init.env
|
|
||||||
$cmd->addSource("/g/init.env");
|
$cmd->addSource("/g/init.env");
|
||||||
$cmd->addRedir("null");
|
$cmd->addRedir("null");
|
||||||
$cmd->fork_exec($exitcode);
|
$cmd->fork_exec($exitcode);
|
||||||
|
|
|
@ -79,7 +79,7 @@ abstract class AbstractCmd implements ICmd {
|
||||||
function addSource(?string $source, bool $onlyIfExists=true): void {
|
function addSource(?string $source, bool $onlyIfExists=true): void {
|
||||||
if ($source === null) return;
|
if ($source === null) return;
|
||||||
if (!$onlyIfExists || file_exists($source)) {
|
if (!$onlyIfExists || file_exists($source)) {
|
||||||
$source = implode(" ", ["source", sh::quote($source)]);
|
$source = implode(" ", [".", sh::quote($source)]);
|
||||||
$this->sources[] = $source;
|
$this->sources[] = $source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,9 @@ abstract class AbstractCmd implements ICmd {
|
||||||
* composition de plusieurs commandes
|
* composition de plusieurs commandes
|
||||||
*/
|
*/
|
||||||
protected function useExec(): bool {
|
protected function useExec(): bool {
|
||||||
return $this->vars === null && count($this->cmds) == 1;
|
return $this->sources === null
|
||||||
|
&& $this->vars === null
|
||||||
|
&& count($this->cmds) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function fork_exec(int &$retcode=null): bool {
|
function fork_exec(int &$retcode=null): bool {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
namespace nur\sery\os;
|
namespace nur\sery\os;
|
||||||
|
|
||||||
use nur\sery\cl;
|
use nur\sery\cl;
|
||||||
|
use nur\sery\StateException;
|
||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
|
|
||||||
class sh {
|
class sh {
|
||||||
|
@ -144,19 +145,19 @@ class sh {
|
||||||
$pid = pcntl_fork();
|
$pid = pcntl_fork();
|
||||||
if ($pid == -1) {
|
if ($pid == -1) {
|
||||||
// parent, impossible de forker
|
// parent, impossible de forker
|
||||||
throw new RuntimeException("unable to fork");
|
throw new StateException("unable to fork");
|
||||||
} elseif ($pid) {
|
} elseif ($pid) {
|
||||||
// parent, fork ok
|
// parent, fork ok
|
||||||
pcntl_waitpid($pid, $status);
|
pcntl_waitpid($pid, $status);
|
||||||
if (pcntl_wifexited($status)) {
|
if (pcntl_wifexited($status)) $retcode = pcntl_wexitstatus($status);
|
||||||
$retcode = pcntl_wexitstatus($status);
|
else $retcode = 127;
|
||||||
} else {
|
|
||||||
$retcode = 127;
|
|
||||||
}
|
|
||||||
return $retcode == 0;
|
return $retcode == 0;
|
||||||
}
|
}
|
||||||
// child, fork ok
|
// child, fork ok
|
||||||
pcntl_exec("/bin/sh", ["-c", $cmd]);
|
$shell = "/bin/bash";
|
||||||
|
if (!file_exists($shell)) $shell = "/bin/sh";
|
||||||
|
$shell = "/bin/sh";
|
||||||
|
pcntl_exec($shell, ["-c", $cmd]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,67 +5,109 @@ namespace nur\sery\wip\app;
|
||||||
use nur\cli\Application;
|
use nur\cli\Application;
|
||||||
use nur\sery\app\LockFile;
|
use nur\sery\app\LockFile;
|
||||||
use nur\sery\app\RunFile;
|
use nur\sery\app\RunFile;
|
||||||
|
use nur\sery\cl;
|
||||||
use nur\sery\os\path;
|
use nur\sery\os\path;
|
||||||
use nur\sery\os\sh;
|
use nur\sery\os\sh;
|
||||||
use nur\sery\str;
|
use nur\sery\str;
|
||||||
use nur\sery\ValueException;
|
use nur\sery\ValueException;
|
||||||
|
|
||||||
class app {
|
class app {
|
||||||
|
/**
|
||||||
|
* @var array répertoires vendor exprimés relativement à PROJDIR
|
||||||
|
*/
|
||||||
|
const DEFAULT_VENDOR = [
|
||||||
|
"bindir" => "vendor/bin",
|
||||||
|
"autoload" => "vendor/autoload.php",
|
||||||
|
];
|
||||||
|
|
||||||
private static function isa_Application($app): bool {
|
private static function isa_Application($app): bool {
|
||||||
if (!is_string($app)) return false;
|
if (!is_string($app)) return false;
|
||||||
return $app === Application::class || is_subclass_of($app, Application::class);
|
return $app === Application::class || is_subclass_of($app, Application::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static function verifix_name(string &$name): void {
|
||||||
|
# si $name est une classe, enlever le package et normaliser
|
||||||
|
$name = preg_replace('/.*\\\\/', "", $name);
|
||||||
|
$name = str::without_suffix("-app", str::camel2us($name, false, "-"));
|
||||||
|
}
|
||||||
|
|
||||||
/** @param Application|string */
|
/** @param Application|string */
|
||||||
static function with($app): self {
|
static function with($app, ?array $internal_use_params=null): self {
|
||||||
if ($app instanceof Application) {
|
if ($app instanceof Application) {
|
||||||
$projdir = $app::PROJDIR;
|
$params = [
|
||||||
$appcode = $app::APPCODE;
|
"projdir" => $app::PROJDIR,
|
||||||
$name = $app::NAME;
|
"vendor" => $app::VENDOR,
|
||||||
$title = $app::TITLE;
|
"appcode" => $app::APPCODE,
|
||||||
$datadir = $app::DATADIR;
|
"apptype" => "cli",
|
||||||
$etcdir = $app::ETCDIR;
|
"name" => $app::NAME,
|
||||||
$vardir = $app::VARDIR;
|
"title" => $app::TITLE,
|
||||||
$logdir = $app::LOGDIR;
|
"datadir" => $app::DATADIR,
|
||||||
|
"etcdir" => $app::ETCDIR,
|
||||||
|
"vardir" => $app::VARDIR,
|
||||||
|
"logdir" => $app::LOGDIR,
|
||||||
|
];
|
||||||
} elseif (self::isa_Application($app)) {
|
} elseif (self::isa_Application($app)) {
|
||||||
$projdir = constant("$app::PROJDIR");
|
$params = [
|
||||||
$appcode = constant("$app::APPCODE");
|
"projdir" => constant("$app::PROJDIR"),
|
||||||
$name = constant("$app::NAME");
|
"vendor" => constant("$app::VENDOR"),
|
||||||
$title = constant("$app::TITLE");
|
"appcode" => constant("$app::APPCODE"),
|
||||||
$datadir = constant("$app::DATADIR");
|
"apptype" => "cli",
|
||||||
$etcdir = constant("$app::ETCDIR");
|
"name" => constant("$app::NAME"),
|
||||||
$vardir = constant("$app::VARDIR");
|
"title" => constant("$app::TITLE"),
|
||||||
$logdir = constant("$app::LOGDIR");
|
"datadir" => constant("$app::DATADIR"),
|
||||||
|
"etcdir" => constant("$app::ETCDIR"),
|
||||||
|
"vardir" => constant("$app::VARDIR"),
|
||||||
|
"logdir" => constant("$app::LOGDIR"),
|
||||||
|
];
|
||||||
} elseif (is_array($app)) {
|
} elseif (is_array($app)) {
|
||||||
return new static($app);
|
$params = $app;
|
||||||
} else {
|
} else {
|
||||||
throw ValueException::invalid_type($app, Application::class);
|
throw ValueException::invalid_type($app, Application::class);
|
||||||
}
|
}
|
||||||
return new static([
|
if ($internal_use_params !== null) {
|
||||||
"projdir" => $projdir,
|
$params = array_merge($internal_use_params, cl::selectm($params, [
|
||||||
"appcode" => $appcode,
|
"name",
|
||||||
|
"title",
|
||||||
|
], [
|
||||||
"apptype" => "cli",
|
"apptype" => "cli",
|
||||||
"name" => $name,
|
]));
|
||||||
"title" => $title,
|
self::verifix_name($params["name"]);
|
||||||
"datadir" => $datadir,
|
}
|
||||||
"etcdir" => $etcdir,
|
return new static($params, $internal_use_params !== null);
|
||||||
"vardir" => $vardir,
|
|
||||||
"logdir" => $logdir,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static ?app $app = null;
|
protected static ?app $app = null;
|
||||||
|
|
||||||
static function init($app): void {
|
static function init($app, ?array $internal_use_params=null): void {
|
||||||
self::$app = static::with($app);
|
self::$app = static::with($app, $internal_use_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function get(): self {
|
static function get(): self {
|
||||||
return self::$app ??= new self(null);
|
return self::$app ??= new self(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct(?array $params) {
|
function __construct(?array $params, bool $internalUse_asis=false) {
|
||||||
|
if ($internalUse_asis) {
|
||||||
|
[
|
||||||
|
"projdir" => $this->projdir,
|
||||||
|
"vendor" => $this->vendor,
|
||||||
|
"appcode" => $this->appcode,
|
||||||
|
"apptype" => $this->apptype,
|
||||||
|
"name" => $this->name,
|
||||||
|
"title" => $this->title,
|
||||||
|
"profile" => $this->profile,
|
||||||
|
"cwd" => $this->cwd,
|
||||||
|
"datadir" => $this->datadir,
|
||||||
|
"etcdir" => $this->etcdir,
|
||||||
|
"vardir" => $this->vardir,
|
||||||
|
"logdir" => $this->logdir,
|
||||||
|
] = $params;
|
||||||
|
} else {
|
||||||
$this->projdir = $projdir = path::abspath($params["projdir"] ?? ".");
|
$this->projdir = $projdir = path::abspath($params["projdir"] ?? ".");
|
||||||
|
$vendor = $params["vendor"] ?? self::DEFAULT_VENDOR;
|
||||||
|
$vendor["bindir"] = path::reljoin($projdir, $vendor["bindir"]);
|
||||||
|
$vendor["autoload"] = path::reljoin($projdir, $vendor["autoload"]);
|
||||||
|
$this->vendor = $vendor;
|
||||||
$this->appcode = $appcode = $params["appcode"] ?? "app";
|
$this->appcode = $appcode = $params["appcode"] ?? "app";
|
||||||
$this->apptype = $apptype = $params["apptype"] ?? "cli";
|
$this->apptype = $apptype = $params["apptype"] ?? "cli";
|
||||||
$name = $params["name"] ?? null;
|
$name = $params["name"] ?? null;
|
||||||
|
@ -73,7 +115,6 @@ class app {
|
||||||
$name = $appcode;
|
$name = $appcode;
|
||||||
} else {
|
} else {
|
||||||
# si $name est une classe, enlever le package et normaliser
|
# si $name est une classe, enlever le package et normaliser
|
||||||
$name = $params["name"] ?? $appcode;
|
|
||||||
$name = preg_replace('/.*\\\\/', "", $name);
|
$name = preg_replace('/.*\\\\/', "", $name);
|
||||||
$name = str::without_suffix("-app", str::camel2us($name, false, "-"));
|
$name = str::without_suffix("-app", str::camel2us($name, false, "-"));
|
||||||
}
|
}
|
||||||
|
@ -112,6 +153,25 @@ class app {
|
||||||
if ($logdir === null) $logdir = "log";
|
if ($logdir === null) $logdir = "log";
|
||||||
$this->logdir = $logdir = path::reljoin($datadir, $logdir);
|
$this->logdir = $logdir = path::reljoin($datadir, $logdir);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** recréer le tableau des paramètres */
|
||||||
|
function getParams(): array {
|
||||||
|
return [
|
||||||
|
"projdir" => $this->projdir,
|
||||||
|
"vendor" => $this->vendor,
|
||||||
|
"appcode" => $this->appcode,
|
||||||
|
"apptype" => $this->apptype,
|
||||||
|
"name" => $this->name,
|
||||||
|
"title" => $this->title,
|
||||||
|
"profile" => $this->profile,
|
||||||
|
"cwd" => $this->cwd,
|
||||||
|
"datadir" => $this->datadir,
|
||||||
|
"etcdir" => $this->etcdir,
|
||||||
|
"vardir" => $this->vardir,
|
||||||
|
"logdir" => $this->logdir,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
protected string $projdir;
|
protected string $projdir;
|
||||||
|
|
||||||
|
@ -119,6 +179,16 @@ class app {
|
||||||
return $this->projdir;
|
return $this->projdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected array $vendor;
|
||||||
|
|
||||||
|
function getVendorBindir(): string {
|
||||||
|
return $this->vendor["bindir"];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVendorAutoload(): string {
|
||||||
|
return $this->vendor["autoload"];
|
||||||
|
}
|
||||||
|
|
||||||
protected string $appcode;
|
protected string $appcode;
|
||||||
|
|
||||||
function getAppcode(): string {
|
function getAppcode(): string {
|
||||||
|
|
Loading…
Reference in New Issue