Various changes, added more functions for executing packages (not finished) & updated documentation/project files.

This commit is contained in:
Netkas 2023-01-11 19:55:19 -05:00
parent c08bc485a5
commit ffcae1b8a0
20 changed files with 283 additions and 62 deletions

View file

@ -11,4 +11,6 @@
const DateTime = 'date_time';
const Install = 'install';
const Runtime = 'runtime';
}

View file

@ -7,8 +7,9 @@
use ncc\Managers\ProjectManager;
use ncc\Objects\CliHelpSection;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
class BuildMenu
class BuildCommand
{
/**
* Displays the main help menu
@ -103,7 +104,7 @@
new CliHelpSection(['build', '--config'], 'Builds the current project with a specified build configuration')
];
$options_padding = \ncc\Utilities\Functions::detectParametersPadding($options) + 4;
$options_padding = Functions::detectParametersPadding($options) + 4;
Console::out('Usage: ncc build [options]');
Console::out('Options:' . PHP_EOL);

View file

@ -0,0 +1,155 @@
<?php
namespace ncc\CLI\Commands;
use Exception;
use ncc\Managers\ExecutionPointerManager;
use ncc\Objects\CliHelpSection;
use ncc\Objects\Package\ExecutionUnit;
use ncc\ThirdParty\Symfony\Process\Process;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
class ExecCommand
{
/**
* Displays the main help menu
*
* @param $args
* @return void
*/
public static function start($args): void
{
$package = $args['package'] ?? null;
$version = $args['version'] ?? 'latest';
$entry = $args['entry'] ?? null;
if($package == null)
{
self::displayOptions();
exit(0);
}
$arguments = [];
$whitelist_arguments = [
'package',
'version',
'entry',
'help',
];
foreach($args as $key => $value)
{
if(!in_array($key, $whitelist_arguments))
$arguments[$key] = $value;
}
$execution_pointer_manager = new ExecutionPointerManager();
try
{
$units = $execution_pointer_manager->getUnits($package, $version);
}
catch(Exception $e)
{
Console::outException(sprintf('Cannot load execution units for package \'%s\'', $package), $e, 1);
return;
}
if(!isset($units[$entry]))
{
Console::outError(sprintf('Cannot find execution point \'%s\' in package \'%s\'', $entry, $package), true, 1);
return;
}
/** @var ExecutionUnit $exec_unit */
$exec_unit = $units[$entry];
$exec_path = '';
$process = new Process(array_merge([$exec_path], $arguments));
if($exec_unit->ExecutionPolicy->Execute->Pty !== null)
$process->setPty($exec_unit->ExecutionPolicy->Execute->Pty);
if($exec_unit->ExecutionPolicy->Execute->Tty !== null)
{
$process->setTty($exec_unit->ExecutionPolicy->Execute->Tty);
$process->setPty(false);
}
if($exec_unit->ExecutionPolicy->Execute->WorkingDirectory !== null)
$process->setWorkingDirectory($exec_unit->ExecutionPolicy->Execute->WorkingDirectory);
if($exec_unit->ExecutionPolicy->Execute->EnvironmentVariables !== null)
$process->setEnv($exec_unit->ExecutionPolicy->Execute->EnvironmentVariables);
if($exec_unit->ExecutionPolicy->Execute->Timeout !== null)
$process->setTimeout($exec_unit->ExecutionPolicy->Execute->Timeout);
if($exec_unit->ExecutionPolicy->Execute->IdleTimeout !== null)
$process->setIdleTimeout($exec_unit->ExecutionPolicy->Execute->IdleTimeout);
if($exec_unit->ExecutionPolicy->Execute->Options !== null)
$process->setOptions($exec_unit->ExecutionPolicy->Execute->Options);
if($process->isTty() || $process->isPty())
{
$process->start();
$process->wait();
}
else
{
$process->start();
while($process->isRunning())
{
if($exec_unit->ExecutionPolicy->Execute->Silent)
{
$process->wait();
}
else
{
$process->waitUntil(function($type, $buffer)
{
if($type == Process::ERR)
{
Console::outError($buffer);
}
else
{
Console::out($buffer);
}
});
}
}
}
exit(0);
}
/**
* Displays the main options section
*
* @return void
*/
private static function displayOptions(): void
{
$options = [
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
new CliHelpSection(['exec', '--package'], '(Required) The package to execute'),
new CliHelpSection(['--version'], '(default: latest) The version of the package to execute'),
new CliHelpSection(['--entry'], '(default: main) The entry point of the package to execute'),
];
$options_padding = Functions::detectParametersPadding($options) + 4;
Console::out('Usage: ncc exec --package <package> [options] [arguments]');
Console::out('Options:' . PHP_EOL);
foreach($options as $option)
{
Console::out(' ' . $option->toString($options_padding));
}
Console::out(PHP_EOL . 'Arguments:' . PHP_EOL);
Console::out(' <arguments> The arguments to pass to the program');
Console::out(PHP_EOL . 'Example Usage:' . PHP_EOL);
Console::out(' ncc exec --package com.example.program');
Console::out(' ncc exec --package com.example.program --version 1.0.0');
Console::out(' ncc exec --package com.example.program --version 1.0.0 --entry setup');
Console::out(' ncc exec --package com.example.program --foo --bar --extra=test');
}
}

View file

@ -7,7 +7,7 @@
use Exception;
use ncc\Abstracts\LogLevel;
use ncc\Abstracts\NccBuildFlags;
use ncc\CLI\Commands\BuildMenu;
use ncc\CLI\Commands\BuildCommand;
use ncc\CLI\Management\ConfigMenu;
use ncc\CLI\Management\CredentialMenu;
use ncc\CLI\Management\PackageManagerMenu;
@ -114,7 +114,7 @@
exit(0);
case 'build':
BuildMenu::start(self::$args);
BuildCommand::start(self::$args);
exit(0);
case 'cred':

View file

@ -163,9 +163,10 @@
return;
}
Console::out('Entries:');
foreach($entries as $entry)
{
Console::out(sprintf('%s%s', $entry->getName(), ($entry->isEncrypted() ? ' (encrypted)' : '')));
Console::out(sprintf(' - %s (%s)', $entry->getName(), $entry->isEncrypted() ? ' (encrypted)' : ''));
}
Console::out('Total: ' . count($entries));

View file

@ -185,17 +185,25 @@
*/
public static function writePackage(string $path, Package $package, ProjectConfiguration $configuration, string $build_configuration=BuildConfigurationValues::DefaultConfiguration): string
{
Console::outVerbose(sprintf('Writing package to %s', $path));
// Write the package to disk
$FileSystem = new Filesystem();
$BuildConfiguration = $configuration->Build->getBuildConfiguration($build_configuration);
if(!$FileSystem->exists($path . $BuildConfiguration->OutputPath))
{
Console::outDebug(sprintf('creating output directory %s', $path . $BuildConfiguration->OutputPath));
$FileSystem->mkdir($path . $BuildConfiguration->OutputPath);
}
// Finally write the package to the disk
$FileSystem->mkdir($path . $BuildConfiguration->OutputPath);
$output_file = $path . $BuildConfiguration->OutputPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '.ncc';
if($FileSystem->exists($output_file))
{
Console::outDebug(sprintf('removing existing package %s', $output_file));
$FileSystem->remove($output_file);
}
$FileSystem->touch($output_file);
try
@ -210,35 +218,13 @@
return $output_file;
}
/**
* Compiles the special formatted constants
*
* @param Package $package
* @param int $timestamp
* @return array
*/
public static function compileRuntimeConstants(Package $package, int $timestamp): array
{
$compiled_constants = [];
foreach($package->Header->RuntimeConstants as $name => $value)
{
$compiled_constants[$name] = self::compileConstants($value, [
ConstantReferences::Assembly => $package->Assembly,
ConstantReferences::DateTime => $timestamp,
ConstantReferences::Build => null
]);
}
return $compiled_constants;
}
/**
* Compiles the constants in the package object
*
* @param Package $package
* @param array $refs
* @return void
* @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection
*/
public static function compilePackageConstants(Package &$package, array $refs): void
{
@ -247,6 +233,7 @@
$assembly = [];
foreach($package->Assembly->toArray() as $key => $value)
{
Console::outDebug(sprintf('compiling consts Assembly.%s (%s)', $key, implode(', ', array_keys($refs))));
$assembly[$key] = self::compileConstants($value, $refs);
}
$package->Assembly = Assembly::fromArray($assembly);
@ -258,11 +245,29 @@
$units = [];
foreach($package->ExecutionUnits as $executionUnit)
{
Console::outDebug(sprintf('compiling execution unit consts %s (%s)', $executionUnit->Name, implode(', ', array_keys($refs))));
$units[] = self::compileExecutionUnitConstants($executionUnit, $refs);
}
$package->ExecutionUnits = $units;
unset($units);
}
$compiled_constants = [];
foreach($package->Header->RuntimeConstants as $name => $value)
{
Console::outDebug(sprintf('compiling runtime const %s (%s)', $name, implode(', ', array_keys($refs))));
$compiled_constants[$name] = self::compileConstants($value, $refs);
}
$options = [];
foreach($package->Header->Options as $name => $value)
{
Console::outDebug(sprintf('compiling options const %s (%s)', $name, implode(', ', array_keys($refs))));
$options[$name] = self::compileConstants($value, $refs);
}
$package->Header->Options = $options;
$package->Header->RuntimeConstants = $compiled_constants;
}
/**
@ -344,6 +349,9 @@
if(isset($refs[ConstantReferences::Install]))
$value = ConstantCompiler::compileInstallConstants($value, $refs[ConstantReferences::Install]);
if(isset($refs[ConstantReferences::Runtime]))
$value = ConstantCompiler::compileRuntimeConstants($value);
return $value;
}
}

View file

@ -23,7 +23,6 @@
use ncc\Exceptions\VersionNotFoundException;
use ncc\Interfaces\CompilerInterface;
use ncc\Managers\PackageLockManager;
use ncc\ncc;
use ncc\Objects\Package;
use ncc\Objects\ProjectConfiguration;
use ncc\ThirdParty\nikic\PhpParser\ParserFactory;
@ -92,6 +91,10 @@
$this->package->Dependencies = $this->project->Build->Dependencies;
$this->package->MainExecutionPolicy = $this->project->Build->Main;
// Add the option to create a symbolic link to the package
if($this->project->Build->CreateSymlink)
$this->package->Header->Options['create_symlink'] = true;
// Add both the defined constants from the build configuration and the global constants.
// Global constants are overridden
$this->package->Header->RuntimeConstants = [];
@ -105,6 +108,7 @@
$this->package->Header->CompilerVersion = NCC_VERSION_NUMBER;
$this->package->Header->Options = $this->project->Project->Options;
Console::outDebug('scanning project files');
Console::outDebug('theseer\DirectoryScanner - Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de> All rights reserved.');

View file

@ -7,7 +7,6 @@
use ncc\Exceptions\IOException;
use ncc\Exceptions\RunnerExecutionException;
use ncc\Objects\ExecutionPointers\ExecutionPointer;
use ncc\Objects\InstallationPaths;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\ThirdParty\Symfony\Process\Process;

View file

@ -2,7 +2,6 @@
namespace ncc\Interfaces;
use ncc\Abstracts\Versions;
use ncc\Exceptions\MissingDependencyException;
use ncc\Exceptions\PackageLockException;
use ncc\Exceptions\PackageNotFoundException;

View file

@ -155,7 +155,8 @@
}
$bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name);
$bin_file .= match ($unit->ExecutionPolicy->Runner) {
$bin_file .= match ($unit->ExecutionPolicy->Runner)
{
Runners::bash => BashRunner::getFileExtension(),
Runners::php => PhpRunner::getFileExtension(),
Runners::perl => PerlRunner::getFileExtension(),
@ -183,6 +184,7 @@
if($temporary)
{
Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package));
$this->TemporaryUnits[] = [
'package' => $package,
'version' => $version,
@ -275,6 +277,22 @@
return $results;
}
public function getUnit(string $package, string $version, string $name): ExecutionUnit
{
Console::outVerbose(sprintf('getting execution unit %s for %s', $name, $package));
$package_id = $this->getPackageId($package, $version);
$package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx';
if(!file_exists($package_config_path))
throw new NoAvailableUnitsException('No ExecutionUnits available for ' . $package);
$execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path)));
$unit = $execution_pointers->getUnit($name);
}
/**
* Executes a unit
*

View file

@ -309,7 +309,6 @@
}
// Install execution units
// TODO: Implement symlink support
if(count($package->ExecutionUnits) > 0)
{
$execution_pointer_manager = new ExecutionPointerManager();
@ -325,6 +324,13 @@
IO::fwrite($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'exec', ZiProto::encode($unit_paths));
}
if(isset($package->Header->Options['create_symlink']) && $package->Header->Options['create_symlink'])
{
$paths = [
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'bin'
];
}
// Execute the post-installation stage after the installation is complete
try
{

View file

@ -6,6 +6,7 @@
use ncc\Abstracts\EncoderType;
use ncc\Abstracts\Versions;
use ncc\Utilities\Console;
class MagicBytes
{

View file

@ -81,7 +81,6 @@
$this->Packages[$package->Assembly->Package]->UpdateSource = $package->Header->UpdateSource;
$this->Packages[$package->Assembly->Package]->addVersion($package, $install_path, true);
$this->Packages[$package->Assembly->Package]->addVersion($package, $install_path, true);
$this->Packages[$package->Assembly->Package]->getDataPath();
$this->update();
}
@ -127,6 +126,7 @@
if(isset($this->Packages[$package]))
{
unset($this->Packages[$package]);
$this->update();
return true;
}

View file

@ -30,6 +30,13 @@
*/
public $Options;
/**
* An array of environment variables to pass on to the process
*
* @var array|null
*/
public $EnvironmentVariables;
/**
* Indicates if the output should be displayed or suppressed
*
@ -38,20 +45,32 @@
public $Silent;
/**
* Indicates if the process should run in Tty mode (Overrides Silent mode)
* Indicates if the process should run in Tty mode (Overrides Silent & Pty mode)
*
* @var bool|null
*/
public $Tty;
/**
* Indicates if the process should run in Pty mode (Overrides Silent mode)
*
* @var bool|null
*/
public $Pty;
/**
* The number of seconds to wait before giving up on the process, will automatically execute the error handler
* if one is set.
*
* @var int
* @var int|null
*/
public $Timeout;
/**
* @var int|null
*/
public $IdleTimeout;
/**
* Public Constructor
*/
@ -60,6 +79,7 @@
$this->Tty = false;
$this->Silent = false;
$this->Timeout = null;
$this->IdleTimeout = null;
$this->WorkingDirectory = "%CWD%";
}
@ -82,6 +102,9 @@
if($this->Options !== null)
$results[($bytecode ? Functions::cbc("options") : "options")] = $this->Options;
if($this->EnvironmentVariables !== null)
$results[($bytecode ? Functions::cbc("environment_variables") : "environment_variables")] = $this->EnvironmentVariables;
if($this->Silent !== null)
$results[($bytecode ? Functions::cbc("silent") : "silent")] = (bool)$this->Silent;
@ -91,6 +114,9 @@
if($this->Timeout !== null)
$results[($bytecode ? Functions::cbc("timeout") : "timeout")] = (int)$this->Timeout;
if($this->IdleTimeout !== null)
$results[($bytecode ? Functions::cbc("idle_timeout") : "idle_timeout")] = (int)$this->IdleTimeout;
return $results;
}
@ -107,9 +133,11 @@
$object->Target = Functions::array_bc($data, 'target');
$object->WorkingDirectory = Functions::array_bc($data, 'working_directory');
$object->Options = Functions::array_bc($data, 'options');
$object->EnvironmentVariables = Functions::array_bc($data, 'environment_variables');
$object->Silent = Functions::array_bc($data, 'silent');
$object->Tty = Functions::array_bc($data, 'tty');
$object->Timeout = Functions::array_bc($data, 'timeout');
$object->IdleTimeout = Functions::array_bc($data, 'idle_timeout');
return $object;
}

View file

@ -929,7 +929,7 @@
{
if (is_numeric($input))
{
if (strpos($input, '.') !== false)
if (str_contains($input, '.'))
return (float)$input;
if (ctype_digit($input))

View file

@ -32,7 +32,6 @@
*/
public static function set($key, $value): mixed
{
Console::outDebug($key);
self::$cache[$key] = $value;
return $value;
}
@ -45,7 +44,6 @@
*/
public static function get($key): mixed
{
Console::outDebug($key);
if(isset(self::$cache[$key]))
return self::$cache[$key];