From 35d09fbc7c614836aa8792bf4ebec327ed5a50a7 Mon Sep 17 00:00:00 2001
From: Axel Hahn <ax2002@gmx.net>
Date: Sun, 16 Mar 2025 11:32:19 +0100
Subject: [PATCH] param support for build, installer, test runner

---
 build.php                  | 86 +++++++++++++++++++++++++++++++++-----
 inc_functions.php          |  6 +--
 inc_vars.php               | 19 ++++++++-
 installer.php              | 34 ++++++++++-----
 src/amcli.php              | 24 +++++++----
 src/simple.ini             | 48 ---------------------
 tests/00_start.php         | 79 ++++++++++++++++++++++++++++++----
 tests/100_set_metadata.php |  2 +-
 8 files changed, 209 insertions(+), 89 deletions(-)
 delete mode 100644 src/simple.ini

diff --git a/build.php b/build.php
index 869e9de..a652636 100755
--- a/build.php
+++ b/build.php
@@ -11,14 +11,55 @@ $TMPFILE="$selfdir/$dirBuild/amcli.php.tmp";
 $OUTFILE="$selfdir/$dirPackages/".str_replace('.php', '', basename($INFILE)).$myosextension;
 $OUTFILE2="$selfdir/$dirPackages/".str_replace('.php', '', basename($INFILE)).'_'.$myos.'_'.$myarchitecture.$myosextension;
 
+$FLAG_FORCEBUILD=false;
+$FLAG_FULLTEST=false;
 
 echo "
+  \e[1mCLI client\e[0m
+  DEVELOPMENT ENVIRONMENT
 
-    B U I L D E R
+  B U I L D E R
 
+...............................................................................
+";
+
+if ($argc > 1) {
+    parse_str(implode('&', array_slice($argv, 1)), $ARGS);
+}
+
+if(isset($ARGS['-h']) || isset($ARGS['--help'])){
+    echo "
+    - Merge PHP sources to a single file
+    - Compile binary
+    - Test binary
+    - Coy to architecture specific binary
+    - Create readme with buildinfos
+
+...............................................................................
+
+ ✨ \e[1mSYNTAX:\e[0m
+
+    ./build.php [OPTIONS]
+
+ 🔷 \e[1mOPTIONS:\e[0m
+
+    -h, --help     Show this help
+    -f, --force    Force rebuild on unchanged sources
+    -t, --test     Run full test suite: ./tests/00_start.php
+                   without '-t': run a  single check only.
 
 ";
+    exit(0);
+}
 
+if(isset($ARGS['-f']) || isset($ARGS['--force'])){
+    $FLAG_FORCEBUILD=true;
+}
+if(isset($ARGS['-t']) || isset($ARGS['--test'])){
+    $FLAG_FULLTEST=true;
+}
+
+_h1("Startup");
 _chdir($selfdir);
 _mkdir($dirPackages);
 
@@ -31,7 +72,12 @@ if(file_exists($OUTFILE)){
     if($ts_in>$ts_out){
         echo "✅ INFO: Source file \"$INFILE\" is newer than \"$OUTFILE\". Compiling changes...\n";
     } else {
-        echo "🔹 INFO: Source is unchanged since last build... rebuilding it anyway.\n";
+        if($FLAG_FORCEBUILD){
+            echo "🔹 INFO: Source is unchanged since last build... rebuilding it because of --force param.\n";
+        } else{
+            echo "Source is unchanged since last build. \n   Delete \"$OUTFILE\"\n   or use --force to force a rebuild.\n";
+            _abort("Aborting.");
+        }
     }
 } else {
     echo "✅ INFO: Target \"$OUTFILE\" does not exist yet.\n";
@@ -75,11 +121,21 @@ _exec("$SPC \
 
 _h1("Test generated binary");
 
-_exec("file \"$OUTFILE\"");
-_exec("\"$OUTFILE\" --ini=../tests/configs/metadata.ini");
+
+if ($FLAG_FULLTEST){
+    _h1("Run test suite");
+    _exec("php \"$selfdir/tests/00_start.php\"");
+} else {
+    _skip("don't run test suite. Use --test to run it. Starting simple test.");
+    _exec("file \"$OUTFILE\"");
+    _exec("\"$OUTFILE\" --ini=../tests/configs/metadata.ini");
+    }
 
 _h1("Write architecture specific binary");
-_exec("cp \"$OUTFILE\" '$OUTFILE2'");
+if(!copy($OUTFILE, $OUTFILE2)){
+    _abort("Could not copy $OUTFILE to $OUTFILE2");
+}
+_ok("file created: '$OUTFILE2'");
 
 _h1("Create readme");
 $readme="{$OUTFILE2}__README.md";
@@ -87,7 +143,7 @@ $versionSPC=system("$SPC --version");
 
 $versionAmcli=system("php $INFILE --version");
 
-file_put_contents($readme, 
+if (!file_put_contents($readme, 
     "# Build infos $versionAmcli
 
 Date        : $sBuildDate
@@ -110,13 +166,23 @@ Download    : `$cmdSpcDownload`
 Build       : `$cmdSpcBuild`
 
 see https://os-docs.iml.unibe.ch/appmonitor-cli-client/
-");
+")){
+    _abort("Could not write $readme");
+}
+_ok("file created.");
 
-echo "see $readme\n";
 
 // ----------------------------------------------------------------------
-
-_h1("Done: Build was successful.");
 @include "build_postactions.php";
 
+_h1("Summary");
+echo "The created files are:
+
+- $OUTFILE
+- $OUTFILE2
+- $readme
+";
+
+_h1("Build was successful.");
+
 // ----------------------------------------------------------------------
diff --git a/inc_functions.php b/inc_functions.php
index e226f40..6be89bd 100644
--- a/inc_functions.php
+++ b/inc_functions.php
@@ -35,7 +35,7 @@ function _h1($s): void
 function _abort($sMessage, $iExitcode = 1): never
 {
     global $aCol;
-    echo "❌ $aCol[red]$sMessage.$aCol[reset]\n";
+    echo "❌ $aCol[red]$sMessage$aCol[reset]\n";
     exit($iExitcode);
 }
 
@@ -93,13 +93,13 @@ function _exec($cmd): void
     
         // Read stdout and stderr in real-time
         while ($output = fgets($pipes[1])) {
-            echo $output;
+            echo "     > $output";
             flush();
         }
         fclose($pipes[1]);
     
         while ($error = fgets($pipes[2])) {
-            echo $error;
+            echo "  ERR> $error";
             flush();
         }
         fclose($pipes[2]);
diff --git a/inc_vars.php b/inc_vars.php
index 82b9265..346e35f 100644
--- a/inc_vars.php
+++ b/inc_vars.php
@@ -11,7 +11,24 @@ $dirPackages="built_packages";
 $php_version="8.4.4";
 
 // extensions - see https://static-php.dev/en/guide/extensions.html
-$php_libs="mysqli,openssl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,sockets";
+$aPhpLibs=[
+    "mysqli" => true,
+    "openssl" => true,
+    "pdo" => true,
+    "pdo_mysql" => true,
+    "pdo_pgsql" => true,
+    "pdo_sqlite" => true,
+    "sockets" => true,
+    "whatever" => false,
+];
+
+$php_libs="";
+foreach($aPhpLibs as $key => $bEnabled){
+    if($bEnabled){
+        $php_libs.=$bEnabled  ? ($php_libs ? ",":"").$key : '';
+    }
+}
+// $php_libs="mysqli,openssl,pdo,pdo_mysql,pdo_pgsql,pdo_sqlite,sockets";
 
 // TODO: how can it be dynamic?
 $myarchitecture="x86_64";
diff --git a/installer.php b/installer.php
index 92da17e..770197b 100755
--- a/installer.php
+++ b/installer.php
@@ -34,14 +34,12 @@ spc-windows-x64.exe                               2025-02-15 17:30:46      3.9M
 // MAIN
 // ----------------------------------------------------------------------
 echo "
+  \e[1mCLI client\e[0m
+  DEVELOPMENT ENVIRONMENT
 
-    I N S T A L L E R   *   U P D A T E R
-
-    - gets appmonitor sources or updates it
-    - gets spc binary
-    - spc downloads PHP and libs
-    - spc builds micro
+  I N S T A L L E R   *   U P D A T E R
 
+...............................................................................
 ";
 
 // ----------------------------------------------------------------------
@@ -52,15 +50,28 @@ if ($argc > 1) {
 
 if(isset($ARGS['-h']) || isset($ARGS['--help'])){
     echo "
-    HELP
+    - Get appmonitor sources or updates it
+    - Get spc binary
+    - Installations with spc doctor
+    - Download PHP and libs with spc
+    - Build Micro sfx with spc
+
+...............................................................................
+
+ ✨ \e[1mSYNTAX:\e[0m
+
+    ./installer.php [OPTIONS]
+
+ 🔷 \e[1mOPTIONS:\e[0m
 
     -h, --help     Show this help
-    -r, --reset    Reset; delete created folders of installer or build
+    -r, --reset    Reset; delete created folders of installer and build
 
 ";
     exit(0);
 }
 
+_h1("Init");
 _chdir($selfdir);
 
 if(isset($ARGS['-r']) || isset($ARGS['--reset'])){
@@ -89,8 +100,8 @@ if(!is_dir("appmonitor")){
     _exec("git pull -f $gitAppmonitor");
 }
 
-// ----------------------------------------------------------------------
 
+// ----------------------------------------------------------------------
 _h1("Generate include file with all available checks...");
 // _exec("ln -s $selfdir/$dirExternal/appmonitor/public_html/client $selfdir/src");
 
@@ -140,6 +151,7 @@ if(file_put_contents($incfile, $out)){
 
 _exec("php -l \"$incfile\"");
 
+
 // ----------------------------------------------------------------------
 _h1("Get / update spc");
 _chdir("$selfdir/$dirExternal/bin");
@@ -153,6 +165,7 @@ if (PHP_OS == "Linux") {
     _exec("chmod +x $SPC");
 }
 
+
 // ----------------------------------------------------------------------
 _h1("Spc - prepare environment");
 _chdir("$selfdir/$dirBuild");
@@ -180,4 +193,5 @@ if ($bDoBild){
     _skip("Micro already built - php $php_version - extensions \"$php_libs\"");
 }
 
-_h1("Done.");
+_h1("Done. You can run build.php to compile the binary.");  
+// ----------------------------------------------------------------------
diff --git a/src/amcli.php b/src/amcli.php
index 25df003..73f3e35 100755
--- a/src/amcli.php
+++ b/src/amcli.php
@@ -3,8 +3,13 @@
 /**
  * ======================================================================
  * 
- * IML APPMONITOR CLIENT 
- * AS CLI APP
+ *     _____ _____ __                   _____         _ _           
+ *    |     |     |  |      ___ ___ ___|     |___ ___|_| |_ ___ ___ 
+ *    |-   -| | | |  |__   | .'| . | . | | | | . |   | |  _| . |  _|
+ *    |_____|_|_|_|_____|  |__,|  _|  _|_|_|_|___|_|_|_|_| |___|_|  
+ *                             |_| |_|                              
+ *                                                                                                                             
+ *    CLIENT AS CLI APP
  * 
  * ---------------------------------------------------------------------
  * 2025-03-04  v0.1    Initial version
@@ -21,7 +26,7 @@ $argc = $_SERVER['argc'];
 $argv = $_SERVER['argv'];
 
 $FLAG_DEBUG = 0;
-$VERSION = "0.5";
+$VERSION = "0.7";
 
 $AMCLI_BUILD_DATE = "never";
 
@@ -98,7 +103,12 @@ function _showHelp(): void
     global $VERSION;
     $_self = str_replace('.php', '', basename(__FILE__));
     echo "
-\e[1m  IML Appmonitor as CLI client $VERSION\e[0m
+   _____ _____ __                   _____         _ _           
+  |     |     |  |      ___ ___ ___|     |___ ___|_| |_ ___ ___ 
+  |-   -| | | |  |__   | .'| . | . | | | | . |   | |  _| . |  _|
+  |_____|_|_|_|_____|  |__,|  _|  _|_|_|_|___|_|_|_|_| |___|_|  
+                           |_| |_|                              
+                                               \e[1mCLI client v$VERSION\e[0m
 
 This client performs appmonitor checks and puts the results as JSON to stdout.
 It contains all checks that are available in the PHP appmonitor client.
@@ -119,12 +129,12 @@ You find example snippets in the source code of this project in tests/config/.
 ...............................................................................
 
 
-✨ \e[1mSYNTAX:\e[0m
+ ✨ \e[1mSYNTAX:\e[0m
 
     $_self [OPTIONS] --ini=<INI-FILE>
 
 
-🔷 \e[1mOPTIONS:\e[0m
+ 🔷 \e[1mOPTIONS:\e[0m
 
     -h, --help        Print this help and exit
 
@@ -137,7 +147,7 @@ You find example snippets in the source code of this project in tests/config/.
     -V, --version     Show version and exit
 
 
-👉 \e[1mEXAMPLES:\e[0m
+ 👉 \e[1mEXAMPLES:\e[0m
 
     $_self -i=my.ini
     $_self --ini=my.ini
diff --git a/src/simple.ini b/src/simple.ini
deleted file mode 100644
index 02653f0..0000000
--- a/src/simple.ini
+++ /dev/null
@@ -1,48 +0,0 @@
-; =======================================================================
-;
-; APPMONITOR CLI CLIENT
-;
-; to understand the entries of metadata see JSON in 
-; <https://os-docs.iml.unibe.ch/appmonitor/Client/Description_of_response.html>
-;
-; for the checks see its parameters
-; <https://os-docs.iml.unibe.ch/appmonitor/PHP_client/Plugins/Checks/index.html>
-;
-; =======================================================================
-
-
-; -----------------------------------------------------------------------
-; METADATA
-; -----------------------------------------------------------------------
-
-[meta]
-host = "www.example.com"
-website = "Company website"
-ttl = 300
-tags[]="monitoring"
-
-
-[notifications]
-email[]="support@example.com"
-email[]="webmaster@example.com"
-
-; for slack use the following format
-slack["#support-channel"]="https://hooks.slack.com/services/XXXXXX/YYYYYY/ZZZZZ"
-
-; -----------------------------------------------------------------------
-; CHECKS
-; -----------------------------------------------------------------------
-
-["hello plugin"]
-description="I just wann say hello"
-function="hello"
-
-; JSON example ... variables cannot be expanded
-; params='{
-;     "message": "Here I am"
-; }'
-;
-; ... but in double quotes the expansion works
-params[message]="Here is ${USER}"
-
-; -----------------------------------------------------------------------
diff --git a/tests/00_start.php b/tests/00_start.php
index e36f200..57998bf 100755
--- a/tests/00_start.php
+++ b/tests/00_start.php
@@ -5,19 +5,80 @@ require_once __DIR__.'/../inc_functions.php';
 require_once __DIR__.'/../inc_vars.php';
 
 $AMCLI??=__DIR__.'/../src/amcli.php';
-// $AMCLI=__DIR__.'/../built_packages/amcli';
+$AMCLIBIN??=__DIR__.'/../built_packages/amcli';
 
-_chdir(__DIR__);
+// --------------------------------------------------------------------
 
-echo "\n\nSTART TESTS\n\n";
-foreach(glob("*.php") as $sFile){
-    if($sFile==basename(__FILE__)){
-        // SKIP
-    } else {
-        _h1("$sFile");
-        include $sFile;    
+/**
+ * Get array of files with tests
+ * @return array
+ */
+function getTests(): array
+{
+    $aReturn=[];
+    foreach(glob(__DIR__."/*.php") as $sFile){
+        if(basename($sFile)!=basename(__FILE__)){
+            $aReturn[]=$sFile;
+        }
+    }
+    return $aReturn;
+}
+
+// --------------------------------------------------------------------
+
+if ($argc > 1) {
+    parse_str(implode('&', array_slice($argv, 1)), $ARGS);
+}
+
+if(isset($ARGS['-h']) || isset($ARGS['--help'])){
+    echo "
+This ist the test suite for amcli calls.
+It executes all scripts in this directory. They perform checks for metadata, 
+help, all checks and ini features.
+
+ ✨ \e[1mSYNTAX:\e[0m
+
+    ./00_start.php [-b]
+
+ 🔷 \e[1mOPTIONS:\e[0m
+
+    -h, --help           Show this help
+    -b, --bin [=<FILE>]  Set amcli binary. If a FILE is given then use that one.
+                         Default is the php script
+                         $AMCLI
+
+                         Default of -b without file is
+                         $AMCLIBIN
+    -l, --list           list filenames of tests
+
+";
+    exit(0);
+}
+
+if(isset($ARGS['-l']) || isset($ARGS['--list'])){
+    foreach(getTests() as $sFile){
+        echo basename($sFile)."\n";
     }
+    exit(0);
+}
 
+if(isset($ARGS['-b']) || isset($ARGS['--bin'])){
+    $AMCLI=($ARGS['--bin'] ?? $ARGS['-b']) ?: $AMCLIBIN;
+    if(!file_exists($AMCLI)){
+        echo "ERROR: [$AMCLI] not found\n";
+        exit(1);
+    }
+}
+echo "Using $AMCLI for testing\n\n";
+
+// _chdir(__DIR__);
+
+echo "\n\nSTART TESTS\n\n";
+foreach(getTests() as $sFile){
+    _h1("$sFile");
+    include $sFile;
 }
 
 _h1("DONE");
+
+// --------------------------------------------------------------------
diff --git a/tests/100_set_metadata.php b/tests/100_set_metadata.php
index edbdd63..bacd9fa 100644
--- a/tests/100_set_metadata.php
+++ b/tests/100_set_metadata.php
@@ -5,7 +5,7 @@ echo "
 WHAT: Set application metadata
 ";
 
-$sInifile="configs/metadata.ini";
+$sInifile=__DIR__."/configs/metadata.ini";
 
 // --------------------------------------------------------------------
 // FUNCTION
-- 
GitLab