modifs.mineures sans commentaires
This commit is contained in:
		
							parent
							
								
									43952bb4a9
								
							
						
					
					
						commit
						c35ca7e5d4
					
				@ -124,27 +124,27 @@ 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) {
 | 
				
			||||||
      $self = app::get();
 | 
					      $runfile = app::get()->getRunfile();
 | 
				
			||||||
      if ($unlock) $self->getLockfile()->release();
 | 
					      if ($unlock) $runfile->release();
 | 
				
			||||||
      if ($stop) $self->getRunfile()->stop();
 | 
					      if ($stop) $runfile->wfStop();
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      static::_app_init();
 | 
					      static::_app_init();
 | 
				
			||||||
      if (static::USE_RUNFILE) {
 | 
					      if (static::USE_RUNFILE) {
 | 
				
			||||||
        $self = app::get();
 | 
					        $runfile = app::get()->getRunfile();
 | 
				
			||||||
        global $argc, $argv;
 | 
					        global $argc, $argv;
 | 
				
			||||||
        if ($argc === 2 && $argv[1] === "--Application-Runlock-release") {
 | 
					        if ($argc === 2 && $argv[1] === "--Application-Runlock-release") {
 | 
				
			||||||
          $self->getLockfile()->release();
 | 
					          $runfile->release();
 | 
				
			||||||
          exit(0);
 | 
					          exit(0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $useRunlock = static::USE_RUNLOCK;
 | 
					        $useRunlock = static::USE_RUNLOCK;
 | 
				
			||||||
        if ($useRunlock && $self->getLockfile()->warnIfLocked()) {
 | 
					        if ($useRunlock && $runfile->warnIfLocked()) {
 | 
				
			||||||
          exit(1);
 | 
					          exit(1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $self->getRunfile()->start();
 | 
					        $runfile->wfStart();
 | 
				
			||||||
        $stop = true;
 | 
					        $stop = true;
 | 
				
			||||||
        if ($useRunlock) {
 | 
					        if ($useRunlock) {
 | 
				
			||||||
          $self->getLockfile()->lock();
 | 
					          $runfile->lock();
 | 
				
			||||||
          $unlock = true;
 | 
					          $unlock = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										32
									
								
								src/A.php
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								src/A.php
									
									
									
									
									
								
							@ -63,4 +63,36 @@ class A {
 | 
				
			|||||||
  static final function mpselect(?array &$dest, ?array $merge, ?array $pkeys): void {
 | 
					  static final function mpselect(?array &$dest, ?array $merge, ?array $pkeys): void {
 | 
				
			||||||
    $dest = cl::mpselect($dest, $merge, $pkeys);
 | 
					    $dest = cl::mpselect($dest, $merge, $pkeys);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static final function append_nn(?array &$dest, $value, $key=null) {
 | 
				
			||||||
 | 
					    if ($value !== null) {
 | 
				
			||||||
 | 
					      if ($key === null) $dest[] = $value;
 | 
				
			||||||
 | 
					      else $dest[$key] = $value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static final function append_nz(?array &$dest, $value, $key=null) {
 | 
				
			||||||
 | 
					    if ($value !== null && $value !== false) {
 | 
				
			||||||
 | 
					      if ($key === null) $dest[] = $value;
 | 
				
			||||||
 | 
					      else $dest[$key] = $value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static final function prepend_nn(?array &$dest, $value) {
 | 
				
			||||||
 | 
					    if ($value !== null) {
 | 
				
			||||||
 | 
					      if ($dest === null) $dest = [];
 | 
				
			||||||
 | 
					      array_unshift($dest, $value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static final function prepend_nz(?array &$dest, $value) {
 | 
				
			||||||
 | 
					    if ($value !== null && $value !== false) {
 | 
				
			||||||
 | 
					      if ($dest === null) $dest = [];
 | 
				
			||||||
 | 
					      array_unshift($dest, $value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $value;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ namespace nur\sery\app;
 | 
				
			|||||||
use nur\sery\cl;
 | 
					use nur\sery\cl;
 | 
				
			||||||
use nur\sery\file\SharedFile;
 | 
					use nur\sery\file\SharedFile;
 | 
				
			||||||
use nur\sery\os\path;
 | 
					use nur\sery\os\path;
 | 
				
			||||||
 | 
					use nur\sery\output\msg;
 | 
				
			||||||
use nur\sery\php\time\DateTime;
 | 
					use nur\sery\php\time\DateTime;
 | 
				
			||||||
use nur\sery\str;
 | 
					use nur\sery\str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -43,9 +44,15 @@ class RunFile {
 | 
				
			|||||||
      "pg_pid" => null,
 | 
					      "pg_pid" => null,
 | 
				
			||||||
      "pid" => posix_getpid(),
 | 
					      "pid" => posix_getpid(),
 | 
				
			||||||
      "serial" => 0,
 | 
					      "serial" => 0,
 | 
				
			||||||
 | 
					      # lock
 | 
				
			||||||
 | 
					      "locked" => false,
 | 
				
			||||||
 | 
					      "date_lock" => null,
 | 
				
			||||||
 | 
					      "date_release" => null,
 | 
				
			||||||
 | 
					      # run
 | 
				
			||||||
      "date_start" => $dateStart,
 | 
					      "date_start" => $dateStart,
 | 
				
			||||||
      "date_stop" => null,
 | 
					      "date_stop" => null,
 | 
				
			||||||
      "exitcode" => null,
 | 
					      "exitcode" => null,
 | 
				
			||||||
 | 
					      # action
 | 
				
			||||||
      "action" => null,
 | 
					      "action" => null,
 | 
				
			||||||
      "action_date_start" => null,
 | 
					      "action_date_start" => null,
 | 
				
			||||||
      "action_current_step" => null,
 | 
					      "action_current_step" => null,
 | 
				
			||||||
@ -60,6 +67,93 @@ class RunFile {
 | 
				
			|||||||
    return $data;
 | 
					    return $data;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function willWrite(): array {
 | 
				
			||||||
 | 
					    $file = $this->file;
 | 
				
			||||||
 | 
					    $file->lockWrite();
 | 
				
			||||||
 | 
					    $data = $file->unserialize(null, false, true);
 | 
				
			||||||
 | 
					    if (!is_array($data)) {
 | 
				
			||||||
 | 
					      $data = $this->initData();
 | 
				
			||||||
 | 
					      $file->ftruncate();
 | 
				
			||||||
 | 
					      $file->serialize($data, false, true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    $file->ftruncate();
 | 
				
			||||||
 | 
					    return [$file, $data];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function serialize(SharedFile $file, array $data, ?array $merge=null): void {
 | 
				
			||||||
 | 
					    $file->serialize(self::merge($data, $merge), true, true);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected function update(callable $func): void {
 | 
				
			||||||
 | 
					    [$file, $data] = $this->willWrite();
 | 
				
			||||||
 | 
					    $merge = call_user_func($func, $data);
 | 
				
			||||||
 | 
					    $this->serialize($file, $data, $merge);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function haveWorked(int $serial, ?int &$currentSerial=null): bool {
 | 
				
			||||||
 | 
					    $data = $this->read();
 | 
				
			||||||
 | 
					    $currentSerial = $data["serial"];
 | 
				
			||||||
 | 
					    return $serial !== $currentSerial;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					  # verrouillage par défaut
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function isLocked(?array &$data=null): bool {
 | 
				
			||||||
 | 
					    $data = $this->read();
 | 
				
			||||||
 | 
					    return $data["locked"];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function warnIfLocked(?array $data=null): bool {
 | 
				
			||||||
 | 
					    if ($data === null) $data = $this->read();
 | 
				
			||||||
 | 
					    if ($data["locked"]) {
 | 
				
			||||||
 | 
					      msg::warning("$data[name]: possède le verrou depuis $data[date_lock]");
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function lock(): bool {
 | 
				
			||||||
 | 
					    $this->update(function ($data) use (&$locked) {
 | 
				
			||||||
 | 
					      if ($data["locked"]) {
 | 
				
			||||||
 | 
					        $locked = false;
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        $locked = true;
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					          "locked" => true,
 | 
				
			||||||
 | 
					          "date_lock" => new DateTime(),
 | 
				
			||||||
 | 
					          "date_release" => null,
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return $locked;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function release(): void {
 | 
				
			||||||
 | 
					    $this->update(function ($data) {
 | 
				
			||||||
 | 
					      return [
 | 
				
			||||||
 | 
					        "locked" => false,
 | 
				
			||||||
 | 
					        "date_release" => new DateTime(),
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					  # cycle de vie de l'application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /**
 | 
				
			||||||
 | 
					   * indiquer que l'application démarre. l'état est entièrement réinitialisé,
 | 
				
			||||||
 | 
					   * sauf le PID du leader qui est laissé en l'état
 | 
				
			||||||
 | 
					   */
 | 
				
			||||||
 | 
					  function wfStart(): void {
 | 
				
			||||||
 | 
					    $this->update(function (array $data) {
 | 
				
			||||||
 | 
					      return cl::merge($this->initData(), [
 | 
				
			||||||
 | 
					        "pg_pid" => $data["pg_pid"],
 | 
				
			||||||
 | 
					      ]);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** tester si l'application a déjà été démarrée */
 | 
					  /** tester si l'application a déjà été démarrée */
 | 
				
			||||||
  function wasStarted(): bool {
 | 
					  function wasStarted(): bool {
 | 
				
			||||||
    $data = $this->read();
 | 
					    $data = $this->read();
 | 
				
			||||||
@ -97,6 +191,13 @@ class RunFile {
 | 
				
			|||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** indiquer que l'application s'arrête */
 | 
				
			||||||
 | 
					  function wfStop(): void {
 | 
				
			||||||
 | 
					    $this->update(function (array $data) {
 | 
				
			||||||
 | 
					      return ["date_stop" => new DateTime()];
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** tester si l'application est déjà été stoppée */
 | 
					  /** tester si l'application est déjà été stoppée */
 | 
				
			||||||
  function wasStopped(): bool {
 | 
					  function wasStopped(): bool {
 | 
				
			||||||
    $data = $this->read();
 | 
					    $data = $this->read();
 | 
				
			||||||
@ -109,46 +210,20 @@ class RunFile {
 | 
				
			|||||||
    return $data["date_start"] !== null && $data["date_stop"] !== null;
 | 
					    return $data["date_start"] !== null && $data["date_stop"] !== null;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function haveWorked(int $serial, ?int &$currentSerial=null): bool {
 | 
					  /** après l'arrêt de l'application, mettre à jour le code de retour */
 | 
				
			||||||
    $data = $this->read();
 | 
					  function wfStopped(int $exitcode): void {
 | 
				
			||||||
    $currentSerial = $data["serial"];
 | 
					    $this->update(function (array $data) use ($exitcode) {
 | 
				
			||||||
    return $serial !== $currentSerial;
 | 
					      return [
 | 
				
			||||||
  }
 | 
					        "pg_pid" => null,
 | 
				
			||||||
 | 
					        "date_stop" => $data["date_stop"] ?? new DateTime(),
 | 
				
			||||||
  protected function willWrite(): array {
 | 
					        "exitcode" => $exitcode,
 | 
				
			||||||
    $file = $this->file;
 | 
					      ];
 | 
				
			||||||
    $file->lockWrite();
 | 
					 | 
				
			||||||
    $data = $file->unserialize(null, false, true);
 | 
					 | 
				
			||||||
    if (!is_array($data)) {
 | 
					 | 
				
			||||||
      $data = $this->initData();
 | 
					 | 
				
			||||||
      $file->ftruncate();
 | 
					 | 
				
			||||||
      $file->serialize($data, false, true);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    $file->ftruncate();
 | 
					 | 
				
			||||||
    return [$file, $data];
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected function serialize(SharedFile $file, array $data, ?array $merge=null): void {
 | 
					 | 
				
			||||||
    $file->serialize(self::merge($data, $merge), true, true);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  protected function update(callable $func): void {
 | 
					 | 
				
			||||||
    [$file, $data] = $this->willWrite();
 | 
					 | 
				
			||||||
    $merge = call_user_func($func, $data);
 | 
					 | 
				
			||||||
    $this->serialize($file, $data, $merge);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** indiquer que l'application démarre */
 | 
					 | 
				
			||||||
  function start(): void {
 | 
					 | 
				
			||||||
    $this->update(function (array $data) {
 | 
					 | 
				
			||||||
      # garder l'identifiant de process
 | 
					 | 
				
			||||||
      $pgPid = $data["pg_pid"] ?? null;
 | 
					 | 
				
			||||||
      return cl::merge($this->initData(), [
 | 
					 | 
				
			||||||
        "pg_pid" => $pgPid,
 | 
					 | 
				
			||||||
      ]);
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					  # gestion des actions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** indiquer le début d'une action */
 | 
					  /** indiquer le début d'une action */
 | 
				
			||||||
  function action(?string $title, ?int $maxSteps=null): void {
 | 
					  function action(?string $title, ?int $maxSteps=null): void {
 | 
				
			||||||
    $this->update(function (array $data) use ($title, $maxSteps) {
 | 
					    $this->update(function (array $data) use ($title, $maxSteps) {
 | 
				
			||||||
@ -171,23 +246,8 @@ class RunFile {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** indiquer que l'application s'arrête */
 | 
					  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
  function stop(): void {
 | 
					  # Divers
 | 
				
			||||||
    $this->update(function (array $data) {
 | 
					 | 
				
			||||||
      return ["date_stop" => new DateTime()];
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /** après l'arrêt de l'application, mettre à jour le code de retour */
 | 
					 | 
				
			||||||
  function stopped(int $exitcode): void {
 | 
					 | 
				
			||||||
    $this->update(function (array $data) use ($exitcode) {
 | 
					 | 
				
			||||||
      return [
 | 
					 | 
				
			||||||
        "pg_pid" => null,
 | 
					 | 
				
			||||||
        "date_stop" => $data["date_stop"] ?? new DateTime(),
 | 
					 | 
				
			||||||
        "exitcode" => $exitcode,
 | 
					 | 
				
			||||||
      ];
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function getLockFile(?string $name=null, ?string $title=null): LockFile {
 | 
					  function getLockFile(?string $name=null, ?string $title=null): LockFile {
 | 
				
			||||||
    $ext = self::LOCK_EXT;
 | 
					    $ext = self::LOCK_EXT;
 | 
				
			||||||
@ -197,7 +257,10 @@ class RunFile {
 | 
				
			|||||||
    return new LockFile($file, $name, $title);
 | 
					    return new LockFile($file, $name, $title);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /** démarrer un groupe de process */
 | 
					  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					  # Gestionnaire de tâches (tm_*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** démarrer un groupe de process dont le process courant est le leader */
 | 
				
			||||||
  function tm_startPg(): void {
 | 
					  function tm_startPg(): void {
 | 
				
			||||||
    $this->update(function (array $data) {
 | 
					    $this->update(function (array $data) {
 | 
				
			||||||
      posix_setsid();
 | 
					      posix_setsid();
 | 
				
			||||||
 | 
				
			|||||||
@ -17,13 +17,15 @@ class launcher {
 | 
				
			|||||||
    return $exitcode;
 | 
					    return $exitcode;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  static function _start(array $args, Runfile $runfile): void {
 | 
					  static function _start(array $args, Runfile $runfile): bool {
 | 
				
			||||||
 | 
					    if ($runfile->isLocked()) return false;
 | 
				
			||||||
    $pid = pcntl_fork();
 | 
					    $pid = pcntl_fork();
 | 
				
			||||||
    if ($pid == -1) {
 | 
					    if ($pid == -1) {
 | 
				
			||||||
      # parent, impossible de forker
 | 
					      # parent, impossible de forker
 | 
				
			||||||
      throw new StateException("unable to fork");
 | 
					      throw new StateException("unable to fork");
 | 
				
			||||||
    } elseif ($pid) {
 | 
					    } elseif ($pid) {
 | 
				
			||||||
      # parent, fork ok
 | 
					      # parent, fork ok
 | 
				
			||||||
 | 
					      return true;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      ## child, fork ok
 | 
					      ## child, fork ok
 | 
				
			||||||
      # Créer un groupe de process, pour pouvoir les tuer toutes en même temps
 | 
					      # Créer un groupe de process, pour pouvoir les tuer toutes en même temps
 | 
				
			||||||
@ -34,10 +36,12 @@ class launcher {
 | 
				
			|||||||
        $cmd = new Cmd($args);
 | 
					        $cmd = new Cmd($args);
 | 
				
			||||||
        #XXX fichier de log?
 | 
					        #XXX fichier de log?
 | 
				
			||||||
        #XXX charger /g/init.env
 | 
					        #XXX charger /g/init.env
 | 
				
			||||||
 | 
					        $cmd->addSource("/g/init.env");
 | 
				
			||||||
        $cmd->addRedir("null");
 | 
					        $cmd->addRedir("null");
 | 
				
			||||||
        $cmd->fork_exec($exitcode);
 | 
					        $cmd->fork_exec($exitcode);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
      } finally {
 | 
					      } finally {
 | 
				
			||||||
        $runfile->stopped($exitcode);
 | 
					        $runfile->wfStopped($exitcode);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -72,7 +76,7 @@ class launcher {
 | 
				
			|||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $runfile->stopped(-778);
 | 
					    $runfile->wfStopped(-778);
 | 
				
			||||||
    msg::asuccess();
 | 
					    msg::asuccess();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,16 +1,17 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\os\proc;
 | 
					namespace nur\sery\os\proc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\A;
 | 
					use nur\sery\A;
 | 
				
			||||||
use nur\base;
 | 
					use nur\sery\cv;
 | 
				
			||||||
use nur\sery\os\sh;
 | 
					use nur\sery\os\sh;
 | 
				
			||||||
use nur\shell;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class AbstractCmd implements ICmd {
 | 
					abstract class AbstractCmd implements ICmd {
 | 
				
			||||||
  private bool $needsStdin;
 | 
					  private bool $needsStdin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private bool $needsTty;
 | 
					  private bool $needsTty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected ?array $sources;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected ?array $vars;
 | 
					  protected ?array $vars;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected array $cmds;
 | 
					  protected array $cmds;
 | 
				
			||||||
@ -18,6 +19,7 @@ abstract class AbstractCmd implements ICmd {
 | 
				
			|||||||
  function __construct() {
 | 
					  function __construct() {
 | 
				
			||||||
    $this->needsStdin = true;
 | 
					    $this->needsStdin = true;
 | 
				
			||||||
    $this->needsTty = true;
 | 
					    $this->needsTty = true;
 | 
				
			||||||
 | 
					    $this->sources = null;
 | 
				
			||||||
    $this->vars = null;
 | 
					    $this->vars = null;
 | 
				
			||||||
    $this->cmds = [];
 | 
					    $this->cmds = [];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -74,13 +76,27 @@ abstract class AbstractCmd implements ICmd {
 | 
				
			|||||||
    $this->needsTty = $needsTty;
 | 
					    $this->needsTty = $needsTty;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function addSource(?string $source, bool $onlyIfExists=true): void {
 | 
				
			||||||
 | 
					    if ($source === null) return;
 | 
				
			||||||
 | 
					    if (!$onlyIfExists || file_exists($source)) {
 | 
				
			||||||
 | 
					      $source = implode(" ", ["source", sh::quote($source)]);
 | 
				
			||||||
 | 
					      $this->sources[] = $source;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function getSources(?string $sep=null): ?string {
 | 
				
			||||||
 | 
					    if ($this->sources === null) return null;
 | 
				
			||||||
 | 
					    if ($sep === null) $sep = "\n";
 | 
				
			||||||
 | 
					    return implode($sep, $this->sources);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function addLiteralVars($vars, ?string $sep=null): void {
 | 
					  function addLiteralVars($vars, ?string $sep=null): void {
 | 
				
			||||||
    if (base::z($vars)) return;
 | 
					    if (cv::z($vars)) return;
 | 
				
			||||||
    if (is_array($vars)) {
 | 
					    if (is_array($vars)) {
 | 
				
			||||||
      if ($sep === null) $sep = "\n";
 | 
					      if ($sep === null) $sep = "\n";
 | 
				
			||||||
      $vars = implode($sep, $vars);
 | 
					      $vars = implode($sep, $vars);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    A::append($this->vars, strval($vars));
 | 
					    $this->vars[] = strval($vars);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function addVars(?array $vars): void {
 | 
					  function addVars(?array $vars): void {
 | 
				
			||||||
@ -88,8 +104,8 @@ abstract class AbstractCmd implements ICmd {
 | 
				
			|||||||
    foreach ($vars as $name => $value) {
 | 
					    foreach ($vars as $name => $value) {
 | 
				
			||||||
      $var = [];
 | 
					      $var = [];
 | 
				
			||||||
      if (!is_array($value)) $var[] = "export ";
 | 
					      if (!is_array($value)) $var[] = "export ";
 | 
				
			||||||
      A::merge($var, [$name, "=", shell::quote($value)]);
 | 
					      A::merge($var, [$name, "=", sh::quote($value)]);
 | 
				
			||||||
      A::append($this->vars, implode("", $var));
 | 
					      $this->vars[] = implode("", $var);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -106,7 +122,7 @@ abstract class AbstractCmd implements ICmd {
 | 
				
			|||||||
    if ($cmd instanceof ICmd) {
 | 
					    if ($cmd instanceof ICmd) {
 | 
				
			||||||
      $cmd->addPrefix($prefix);
 | 
					      $cmd->addPrefix($prefix);
 | 
				
			||||||
    } elseif (is_array($prefix)) {
 | 
					    } elseif (is_array($prefix)) {
 | 
				
			||||||
      $prefix = shell::join($prefix);
 | 
					      $prefix = sh::join($prefix);
 | 
				
			||||||
      $cmd = "$prefix $cmd";
 | 
					      $cmd = "$prefix $cmd";
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      $cmd = "$prefix $cmd";
 | 
					      $cmd = "$prefix $cmd";
 | 
				
			||||||
@ -167,8 +183,8 @@ abstract class AbstractCmd implements ICmd {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function system(string &$output=null, int &$retcode=null): bool {
 | 
					  function system(string &$output=null, int &$retcode=null): bool {
 | 
				
			||||||
    $last_line = system($this->getCmd(), $retcode);
 | 
					    $lastLine = system($this->getCmd(), $retcode);
 | 
				
			||||||
    if ($last_line !== false) $output = $last_line;
 | 
					    if ($lastLine !== false) $output = $lastLine;
 | 
				
			||||||
    return $retcode == 0;
 | 
					    return $retcode == 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\os\proc;
 | 
					namespace nur\sery\os\proc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\A;
 | 
					use nur\sery\A;
 | 
				
			||||||
use nur\shell;
 | 
					use nur\sery\os\sh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class AbstractCmdList: une séquence de commandes séparées par ;, && ou ||
 | 
					 * Class AbstractCmdList: une séquence de commandes séparées par ;, && ou ||
 | 
				
			||||||
@ -24,7 +24,7 @@ abstract class AbstractCmdList extends AbstractCmd {
 | 
				
			|||||||
  function add($cmd, ?string $input=null, ?string $output=null): self {
 | 
					  function add($cmd, ?string $input=null, ?string $output=null): self {
 | 
				
			||||||
    if ($cmd !== null) {
 | 
					    if ($cmd !== null) {
 | 
				
			||||||
      if (!($cmd instanceof ICmd)) {
 | 
					      if (!($cmd instanceof ICmd)) {
 | 
				
			||||||
        shell::fix_cmd($cmd, null, $input, $output);
 | 
					        sh::verifix_cmd($cmd, null, $input, $output);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      $this->cmds[] = $cmd;
 | 
					      $this->cmds[] = $cmd;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -35,6 +35,7 @@ abstract class AbstractCmdList extends AbstractCmd {
 | 
				
			|||||||
    if ($sep === null) $sep = "\n";
 | 
					    if ($sep === null) $sep = "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $actualCmd = [];
 | 
					    $actualCmd = [];
 | 
				
			||||||
 | 
					    A::append_nn($actualCmd, $this->getSources($sep));
 | 
				
			||||||
    A::append_nn($actualCmd, $this->getVars($sep));
 | 
					    A::append_nn($actualCmd, $this->getVars($sep));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $parts = [];
 | 
					    $parts = [];
 | 
				
			||||||
@ -44,9 +45,8 @@ abstract class AbstractCmdList extends AbstractCmd {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      $parts[] = $cmd;
 | 
					      $parts[] = $cmd;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $psep = $this->sep;
 | 
					    $psep = $this->sep ?? $sep;
 | 
				
			||||||
    if ($psep === null) $psep = $sep;
 | 
					    $actualCmd[] = implode($psep, $parts);
 | 
				
			||||||
    A::append($actualCmd, implode($psep, $parts));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return implode($sep, $actualCmd);
 | 
					    return implode($sep, $actualCmd);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,8 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
namespace nur\sery\os\proc;
 | 
					namespace nur\sery\os\proc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use nur\A;
 | 
					use nur\sery\A;
 | 
				
			||||||
use nur\shell;
 | 
					use nur\sery\os\sh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Class CmdPipe: une suite de commandes qui doivent s'exécuter avec les sorties
 | 
					 * Class CmdPipe: une suite de commandes qui doivent s'exécuter avec les sorties
 | 
				
			||||||
@ -32,7 +32,7 @@ class CmdPipe extends AbstractCmd {
 | 
				
			|||||||
  function add($cmd): self {
 | 
					  function add($cmd): self {
 | 
				
			||||||
    if ($cmd !== null) {
 | 
					    if ($cmd !== null) {
 | 
				
			||||||
      if (!($cmd instanceof ICmd)) {
 | 
					      if (!($cmd instanceof ICmd)) {
 | 
				
			||||||
        shell::fix_cmd($cmd);
 | 
					        sh::verifix_cmd($cmd);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      $this->cmds[] = $cmd;
 | 
					      $this->cmds[] = $cmd;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -53,6 +53,7 @@ class CmdPipe extends AbstractCmd {
 | 
				
			|||||||
    if ($sep === null) $sep = "\n";
 | 
					    if ($sep === null) $sep = "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $actualCmd = [];
 | 
					    $actualCmd = [];
 | 
				
			||||||
 | 
					    A::append_nn($actualCmd, $this->getSources($sep));
 | 
				
			||||||
    A::append_nn($actualCmd, $this->getVars($sep));
 | 
					    A::append_nn($actualCmd, $this->getVars($sep));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $parts = [];
 | 
					    $parts = [];
 | 
				
			||||||
@ -73,7 +74,7 @@ class CmdPipe extends AbstractCmd {
 | 
				
			|||||||
      if ($output !== null) $parts[] = ">".escapeshellarg($output);
 | 
					      if ($output !== null) $parts[] = ">".escapeshellarg($output);
 | 
				
			||||||
      $cmd = implode(" ", $parts);
 | 
					      $cmd = implode(" ", $parts);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    A::append($actualCmd, $cmd);
 | 
					    $actualCmd[] = $cmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return implode($sep, $actualCmd);
 | 
					    return implode($sep, $actualCmd);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@ use nur\sery\app\LockFile;
 | 
				
			|||||||
use nur\sery\app\RunFile;
 | 
					use nur\sery\app\RunFile;
 | 
				
			||||||
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\ValueException;
 | 
					use nur\sery\ValueException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class app {
 | 
					class app {
 | 
				
			||||||
@ -67,7 +68,11 @@ class app {
 | 
				
			|||||||
    $this->projdir = $projdir = path::abspath($params["projdir"] ?? ".");
 | 
					    $this->projdir = $projdir = path::abspath($params["projdir"] ?? ".");
 | 
				
			||||||
    $this->appcode = $appcode = $params["appcode"] ?? "app";
 | 
					    $this->appcode = $appcode = $params["appcode"] ?? "app";
 | 
				
			||||||
    $this->apptype = $apptype = $params["apptype"] ?? "cli";
 | 
					    $this->apptype = $apptype = $params["apptype"] ?? "cli";
 | 
				
			||||||
    $this->name = $params["name"] ?? $appcode;
 | 
					    # si $name est une classe, enlever le package et normaliser
 | 
				
			||||||
 | 
					    $name = $params["name"] ?? $appcode;
 | 
				
			||||||
 | 
					    $name = preg_replace('/.*\\\\/', "", $name);
 | 
				
			||||||
 | 
					    $name = str::without_suffix("-app", str::camel2us($name));
 | 
				
			||||||
 | 
					    $this->name = $name;
 | 
				
			||||||
    $this->title = $params["title"] ?? null;
 | 
					    $this->title = $params["title"] ?? null;
 | 
				
			||||||
    $appcode = strtoupper($appcode);
 | 
					    $appcode = strtoupper($appcode);
 | 
				
			||||||
    # profile
 | 
					    # profile
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user