diff --git a/.idea/php.xml b/.idea/php.xml
index 097e372..b37795f 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -12,6 +12,7 @@
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 79848e4..0b23720 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -28,6 +28,7 @@ features and reduced the number of exceptions down to 15 exceptions.
- Added new template PhpCliTemplate `phpcli`
- Added new template PhpLibraryTemplate `phplib`
- Added the ability to clean arrays in `\ncc\Utilities > Functions > cleanArray()`
+ - Added the ability to compile executable binaries for php using `gcc`
### Fixed
- Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()`
@@ -227,6 +228,12 @@ features and reduced the number of exceptions down to 15 exceptions.
going to list them all here, but you can find them in the commit history.
- Implemented a template engine and refactored the CLI menu for the Project Manager and added a new `template` command
- Refactored the entire package structure to ncc package structure 2.0 for memory efficiency and performance
+ - Refactored execution unit system to use a new execution pointer system
+ - Refactored `PhpRunner` to use the new execution pointer system
+ - Refactored `BashRunner` to use the new execution pointer system
+ - Refactored `LuaRunner` to use the new execution pointer system
+ - Refactored `PerlRunner` to use the new execution pointer system
+ - Refactored `PythonRunner` to use the new execution pointer system
### Removed
@@ -290,6 +297,9 @@ features and reduced the number of exceptions down to 15 exceptions.
- Removed unused `\ncc\Objects > NccUpdateInformation`
- Removed unused `\ncc\Objects > PhpConfiguration`
- Removed parameter `$throw_exception` from `\ncc\Objects\ProjectConfiguration > Project > validate()`
+ - Removed dependency `theseer\Autoload` in favor of ncc's own autoloader (screw you Arne Blankerts)
+ - Refactored ZiProto
+ - Removed runners `Python2` & `Python3` in favor of `Python`
diff --git a/Makefile b/Makefile
index 8783581..c9fe195 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,6 @@ AUTOLOAD_PATHS := $(addprefix $(SRC_PATH)/ncc/ThirdParty/, \
Symfony/Uid \
Symfony/Filesystem \
Symfony/Yaml \
- theseer/Autoload \
theseer/DirectoryScanner \
)
diff --git a/src/autoload/autoload.php b/src/autoload/autoload.php
index 41f8f86..3bdc01c 100644
--- a/src/autoload/autoload.php
+++ b/src/autoload/autoload.php
@@ -26,7 +26,6 @@
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Yaml' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
- $third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'Autoload' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'theseer' . DIRECTORY_SEPARATOR . 'DirectoryScanner' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
];
diff --git a/src/config/ncc-package.xml b/src/config/ncc-package.xml
new file mode 100644
index 0000000..f806314
--- /dev/null
+++ b/src/config/ncc-package.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+ ncc package binary
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/installer/extension b/src/installer/extension
index 2ccc72b..c182e5c 100644
--- a/src/installer/extension
+++ b/src/installer/extension
@@ -1,15 +1,11 @@
getMessage()), $e->getCode(), $e);
+ }
+ }
+ }
+
+ if(!function_exists('execute'))
+ {
+ /**
+ * Executes the main execution point of an imported package and returns the evaluated result
+ * This method may exit the program without returning a value
+ *
+ * @param string $package
+ * @return mixed
+ * @throws ConfigurationException
+ */
+ function execute(string $package): mixed
+ {
+ return Runtime::execute($package);
}
}
@@ -59,112 +74,10 @@
* Returns an array of constants defined by NCC
*
* @return array
- * @throws \ncc\Exceptions\RuntimeException
*/
function ncc_constants(): array
{
return ncc::getConstants();
}
}
-
- if(!function_exists('consts_get'))
- {
- /**
- * Returns the value of a constant defined in NCC's runtime environment
- *
- * @param string $package
- * @param string $name
- * @return string|null
- */
- function consts_get(string $package, string $name): ?string
- {
- return Runtime\Constants::get($package, $name);
- }
- }
-
- if(!function_exists('consts_set'))
- {
- /**
- * Sets the value of a constant defined in NCC's runtime environment
- *
- * @param string $package
- * @param string $name
- * @param string $value
- * @param bool $readonly
- * @return void
- * @throws ConstantReadonlyException
- * @throws InvalidConstantNameException
- */
- function consts_set(string $package, string $name, string $value, bool $readonly=false): void
- {
- Runtime\Constants::register($package, $name, $value, $readonly);
- }
- }
-
- if(!function_exists('consts_delete'))
- {
- /**
- * Deletes a constant defined in NCC's runtime environment
- *
- * @param string $package
- * @param string $name
- * @return void
- * @throws ConstantReadonlyException
- */
- function consts_delete(string $package, string $name): void
- {
- Runtime\Constants::delete($package, $name);
- }
- }
-
- if(!function_exists('get_data_path'))
- {
- /**
- * Returns the data path of the package
- *
- * @param string $package
- * @return string
- * @throws InvalidPackageNameException
- * @throws InvalidScopeException
- * @throws PackageLockException
- * @throws PackageNotFoundException
- */
- function get_data_path(string $package): string
- {
- return Runtime::getDataPath($package);
- }
- }
-
- if(!function_exists('get_constant'))
- {
- /**
- * Returns the value of a constant defined in NCC's runtime environment
- *
- * @param string $package
- * @param string $name
- * @return string|null
- */
- function get_constant(string $package, string $name): ?string
- {
- return Runtime::getConstant($package, $name);
- }
- }
-
- if(!function_exists('set_constant'))
- {
- /**
- * Sets the value of a constant defined in NCC's runtime environment
- *
- * @param string $package
- * @param string $name
- * @param string $value
- * @return void
- * @throws ConstantReadonlyException
- * @throws InvalidConstantNameException
- */
- function set_constant(string $package, string $name, string $value): void
- {
- Runtime::setConstant($package, $name, $value);
- }
- }
}
\ No newline at end of file
diff --git a/src/installer/hash_check.php b/src/installer/hash_check.php
index c60d740..bf63dce 100644
--- a/src/installer/hash_check.php
+++ b/src/installer/hash_check.php
@@ -12,9 +12,7 @@
// Start script
function scanContents($dir, &$results = array())
{
- $files = scandir($dir);
-
- foreach ($files as $key => $value)
+ foreach (scandir($dir, SCANDIR_SORT_NONE) as $key => $value)
{
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
if (!is_dir($path))
@@ -49,6 +47,6 @@
}
}
- file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin', \ncc\ZiProto\ZiProto::encode($hash_values));
+ file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin', \ncc\Extensions\ZiProto\ZiProto::encode($hash_values));
ncc\Utilities\Console::out('Created checksum.bin');
exit(0);
\ No newline at end of file
diff --git a/src/installer/installer b/src/installer/installer
index d889fc8..459a4cf 100644
--- a/src/installer/installer
+++ b/src/installer/installer
@@ -31,7 +31,7 @@
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
use ncc\Utilities\Validate;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
# Global Variables
$NCC_INSTALL_PATH=DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'ncc';
diff --git a/src/ncc/CLI/Commands/ExecCommand.php b/src/ncc/CLI/Commands/ExecCommand.php
index fc99d9b..f4a109c 100644
--- a/src/ncc/CLI/Commands/ExecCommand.php
+++ b/src/ncc/CLI/Commands/ExecCommand.php
@@ -1,30 +1,29 @@
getPackageLock()->getPackage($package);
+ $package_name = Runtime::import($package, $version);
}
catch(Exception $e)
{
- Console::outException('Package ' . $package . ' is not installed', $e, 1);
- return;
- }
-
- if($package_entry === null)
- {
- Console::outError('Package ' . $package . ' is not installed', true, 1);
+ Console::outException('Cannot import package ' . $package, $e, 1);
return;
}
try
{
- $version_entry = $package_entry->getVersion($version, true);
+ exit(Runtime::execute($package_name));
}
catch(Exception $e)
{
- Console::outException('Version ' . $version . ' is not installed', $e, 1);
- return;
- }
-
- try
- {
- $units = $execution_pointer_manager->getUnits($package_entry->getName(), $version_entry->getVersion());
- }
- catch(Exception $e)
- {
- Console::outException(sprintf('Cannot load execution units for package \'%s\'', $package), $e, 1);
- return;
- }
-
- if(!in_array($unit_name, $units))
- {
- Console::outError(sprintf('Unit \'%s\' is not configured for package \'%s\'', $unit_name, $package), true, 1);
- return;
- }
-
- $options = [];
-
- if($set_args != null)
- {
- global $argv;
- $args_index = array_search('--exec-args', $argv);
- $options = array_slice($argv, $args_index + 1);
- }
-
- try
- {
- exit($execution_pointer_manager->executeUnit($package_entry->getName(), $version_entry->getVersion(), $unit_name, $options));
- }
- catch(Exception $e)
- {
- Console::outException(sprintf('Cannot execute execution point \'%s\' in package \'%s\'', $unit_name, $package), $e, 1);
+ Console::outException($e->getMessage(), $e, 1);
return;
}
}
@@ -126,7 +79,6 @@ namespace ncc\CLI\Commands;
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
new CliHelpSection(['exec', '--package'], '(Required) The package to execute'),
new CliHelpSection(['--exec-version'], '(default: latest) The version of the package to execute'),
- new CliHelpSection(['--exec-unit'], '(default: main) The unit point of the package to execute'),
new CliHelpSection(['--exec-args'], '(optional) Anything past this point will be passed to the execution unit'),
];
@@ -144,7 +96,6 @@ namespace ncc\CLI\Commands;
Console::out(PHP_EOL . 'Example Usage:' . PHP_EOL);
Console::out(' ncc exec --package com.example.program');
Console::out(' ncc exec --package com.example.program --exec-version 1.0.0');
- Console::out(' ncc exec --package com.example.program --exec-version 1.0.0 --exec-unit setup');
Console::out(' ncc exec --package com.example.program --exec-args --foo --bar --extra=test');
}
}
\ No newline at end of file
diff --git a/src/ncc/CLI/Management/PackageManagerMenu.php b/src/ncc/CLI/Management/PackageManagerMenu.php
index c280459..f46006b 100644
--- a/src/ncc/CLI/Management/PackageManagerMenu.php
+++ b/src/ncc/CLI/Management/PackageManagerMenu.php
@@ -29,7 +29,7 @@
use ncc\Enums\Scopes;
use ncc\Exceptions\IOException;
use ncc\Managers\CredentialManager;
- use ncc\Managers\PackageManager;
+ use ncc\Managers\PackageManagerOld;
use ncc\Objects\CliHelpSection;
use ncc\Objects\Package;
use ncc\Objects\RemotePackageInput;
@@ -277,7 +277,7 @@
*/
private static function getInstallPackages($args): void
{
- $package_manager = new PackageManager();
+ $package_manager = new PackageManagerOld();
try
{
@@ -339,7 +339,7 @@
private static function installPackage($args): void
{
$package = ($args['package'] ?? $args['p']);
- $package_manager = new PackageManager();
+ $package_manager = new PackageManagerOld();
if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
@@ -618,7 +618,7 @@
Console::outError('Missing argument \'package\'', true, 1);
}
- $package_manager = new PackageManager();
+ $package_manager = new PackageManagerOld();
try
{
@@ -707,7 +707,7 @@
return;
}
- $package_manager = new PackageManager();
+ $package_manager = new PackageManagerOld();
foreach($package_manager->getInstalledPackages() as $package => $versions)
{
diff --git a/src/ncc/Classes/BashExtension/BashRunner.php b/src/ncc/Classes/BashExtension/BashRunner.php
index 4d7aa7c..5ebe324 100644
--- a/src/ncc/Classes/BashExtension/BashRunner.php
+++ b/src/ncc/Classes/BashExtension/BashRunner.php
@@ -1,59 +1,72 @@
getData()) . '.bash';
+ IO::fwrite($tmp, $unit->getData(), 0777);
+
+ try
{
- throw new PathNotFoundException($path);
+ $process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
+ $process->run(static function($type, $buffer) use ($unit)
+ {
+ if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
+ {
+ print($buffer);
+ }
+ });
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException(sprintf('There was an error executing the bash execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
+ }
+ finally
+ {
+ unlink($tmp);
}
- $execution_unit = new ExecutionUnit();
- $execution_unit->setExecutionPolicy($policy);
- $execution_unit->setData(IO::fread($path));
-
- return $execution_unit;
- }
-
- /**
- * @inheritDoc
- */
- public static function getFileExtension(): string
- {
- return '.bash';
+ return $process->getExitCode();
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/ExecutionUnitRunner.php b/src/ncc/Classes/ExecutionUnitRunner.php
new file mode 100644
index 0000000..0fe96f0
--- /dev/null
+++ b/src/ncc/Classes/ExecutionUnitRunner.php
@@ -0,0 +1,151 @@
+getExecutionPolicy()->getRunner())
+ {
+ Runners::PHP => (new ExecutableFinder())->find('php'),
+ Runners::BASH => (new ExecutableFinder())->find('bash'),
+ Runners::PYTHON => (new ExecutableFinder())->find('python'),
+ Runners::LUA => (new ExecutableFinder())->find('lua'),
+ Runners::PERL => (new ExecutableFinder())->find('perl'),
+
+ default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $unit->getExecutionPolicy()->getName(), $unit->getExecutionPolicy()->getRunner()))
+ };
+
+ $process = new Process(array_merge([$bin], $args, $unit->getExecutionPolicy()->getExecute()->getOptions()));
+ $process->setWorkingDirectory(ConstantCompiler::compileRuntimeConstants($unit->getExecutionPolicy()->getExecute()->getWorkingDirectory()));
+ $process->setEnv($unit->getExecutionPolicy()->getExecute()->getEnvironmentVariables());
+
+ if($unit->getExecutionPolicy()->getExecute()->isTty())
+ {
+ $process->setTty(true);
+ }
+
+ if($unit->getExecutionPolicy()->getExecute()->getTimeout() !== null)
+ {
+ $process->setTimeout($unit->getExecutionPolicy()->getExecute()->getTimeout());
+ }
+
+ if($unit->getExecutionPolicy()->getExecute()->getIdleTimeout() !== null)
+ {
+ $process->setIdleTimeout($unit->getExecutionPolicy()->getExecute()->getIdleTimeout());
+ }
+
+ return $process;
+ }
+
+ /**
+ * Executes a ExecutionUnit locally on the system
+ *
+ * @param string $package_path
+ * @param string $policy_name
+ * @param array $args
+ * @return int
+ * @throws IOException
+ * @throws OperationException
+ */
+ public static function executeFromSystem(string $package_path, string $policy_name, array $args=[]): int
+ {
+ $unit_path = $package_path . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $policy_name . '.unit';
+
+ if(!is_file($unit_path))
+ {
+ throw new IOException(sprintf('The execution policy %s does not exist in the package %s (%s)', $policy_name, $package_path, $unit_path));
+ }
+
+ try
+ {
+ $execution_unit = ExecutionUnit::fromArray(ZiProto::decode(IO::fread($unit_path)));
+ return match ($execution_unit->getExecutionPolicy()->getRunner())
+ {
+ Runners::PHP => PhpRunner::executeUnit($execution_unit, $args),
+ Runners::BASH => BashRunner::executeUnit($execution_unit, $args),
+ default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())),
+ };
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException(sprintf('There was an error executing the execution policy %s: %s', $policy_name, $e->getMessage()), $e);
+ }
+ }
+
+ /**
+ * Executes the execution policy directly from a package (if supported)
+ *
+ * @param PackageReader $package_reader
+ * @param string $policy_name
+ * @param array $args
+ * @return int
+ * @throws ConfigurationException
+ * @throws OperationException
+ */
+ public static function executeFromPackage(PackageReader $package_reader, string $policy_name, array $args=[]): int
+ {
+ $execution_unit = $package_reader->getExecutionUnit($policy_name);
+
+ try
+ {
+ return match ($execution_unit->getExecutionPolicy()->getRunner())
+ {
+ Runners::PHP => PhpRunner::executeUnit($execution_unit, $args, false),
+ Runners::BASH => BashRunner::executeUnit($execution_unit, $args),
+ default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())),
+ };
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException(sprintf('There was an error executing the execution policy from a package %s: %s', $policy_name, $e->getMessage()), $e);
+ }
+ }
+ }
\ No newline at end of file
diff --git a/src/ncc/Classes/LuaExtension/LuaRunner.php b/src/ncc/Classes/LuaExtension/LuaRunner.php
index e39125e..0915c9e 100644
--- a/src/ncc/Classes/LuaExtension/LuaRunner.php
+++ b/src/ncc/Classes/LuaExtension/LuaRunner.php
@@ -1,54 +1,74 @@
setExecutionPolicy($policy);
- $execution_unit->setData(IO::fread($path));
+ $tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.lua';
+ IO::fwrite($tmp, $unit->getData(), 0777);
- return $execution_unit;
- }
+ try
+ {
+ $process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
+ $process->run(static function($type, $buffer) use ($unit)
+ {
+ if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
+ {
+ print($buffer);
+ }
+ });
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException(sprintf('There was an error executing the lua execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
+ }
+ finally
+ {
+ unlink($tmp);
+ }
- /**
- * @inheritDoc
- */
- public static function getFileExtension(): string
- {
- return '.lua';
+ return $process->getExitCode();
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/NccExtension/NccCompiler.php b/src/ncc/Classes/NccExtension/NccCompiler.php
index 9c310a2..8ec7adb 100644
--- a/src/ncc/Classes/NccExtension/NccCompiler.php
+++ b/src/ncc/Classes/NccExtension/NccCompiler.php
@@ -28,22 +28,25 @@
use ncc\Classes\PackageWriter;
use ncc\CLI\Main;
use ncc\Enums\ComponentDataType;
+ use ncc\Enums\Flags\PackageFlags;
use ncc\Enums\LogLevel;
+ use ncc\Enums\Options\BuildConfigurationOptions;
use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\PathNotFoundException;
+ use ncc\Interfaces\CompilerInterface;
use ncc\Managers\ProjectManager;
use ncc\Objects\Package;
- use ncc\Objects\Package\Resource;
+ use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
use ncc\Utilities\Base64;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\IO;
use ncc\Utilities\Resolver;
- class NccCompiler
+ class NccCompiler implements CompilerInterface
{
/**
* @var ProjectManager
@@ -59,18 +62,35 @@
}
/**
+ * Returns the project manager
+ *
+ * @return ProjectManager
+ */
+ public function getProjectManager(): ProjectManager
+ {
+ return $this->project_manager;
+ }
+
+ /**
+ * @inheritDoc
* @param string $build_configuration
* @return string
* @throws ConfigurationException
* @throws IOException
* @throws NotSupportedException
* @throws PathNotFoundException
+ * @noinspection UnusedFunctionResultInspection
*/
public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string
{
$configuration = $this->project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
$package_path = $configuration->getOutputPath() . DIRECTORY_SEPARATOR . $this->project_manager->getProjectConfiguration()->getAssembly()->getPackage() . '.ncc';
- $package_writer = new PackageWriter($package_path);
+ $progress = 0;
+ $steps =
+ count($this->project_manager->getProjectConfiguration()->getExecutionPolicies()) +
+ count($this->project_manager->getComponents($build_configuration)) +
+ count($this->project_manager->getResources($build_configuration));
+ $package_writer = $this->createPackageWriter($package_path, $configuration);
Console::out(sprintf('Building project \'%s\'', $this->project_manager->getProjectConfiguration()->getAssembly()->getName()));
@@ -89,7 +109,7 @@
}
Console::outVerbose('Building package header...');
- $package_writer->setMetadata($this->buildMetadata($build_configuration));
+ $this->processMetadata($package_writer, $build_configuration);
Console::outVerbose('Adding assembly information...');
$package_writer->setAssembly($this->project_manager->getProjectConfiguration()->getAssembly());
@@ -104,16 +124,20 @@
// Process execution policies
if(count($this->project_manager->getProjectConfiguration()->getExecutionPolicies()) > 0)
{
- Console::out('Processing execution policies...');
+ Console::outVerbose('Processing execution policies...');
$execution_units = $this->project_manager->getExecutionUnits($build_configuration);
if(count($execution_units) === 0)
{
+ $progress = count($this->project_manager->getProjectConfiguration()->getExecutionPolicies());
+ Console::inlineProgressBar($progress, $steps);
Console::outWarning('The project contains execution policies but none of them are used');
}
foreach($execution_units as $unit)
{
+ $progress++;
+ Console::inlineProgressBar($progress, $steps);
$package_writer->addExecutionUnit($unit);
}
}
@@ -121,68 +145,119 @@
// Compile package components
foreach($this->project_manager->getComponents($build_configuration) as $component)
{
+ $progress++;
+ Console::inlineProgressBar($progress, $steps);
Console::outVerbose(sprintf('Compiling \'%s\'', $component));
- $package_writer->addComponent($this->buildComponent($component));
+
+ $this->processComponent($package_writer, $component);
}
// Compile package resources
foreach($this->project_manager->getResources($build_configuration) as $resource)
{
+ $progress++;
+ Console::inlineProgressBar($progress, $steps);
Console::outVerbose(sprintf('Processing \'%s\'', $resource));
- $package_writer->addResource($this->buildResource($resource));
+
+ $this->processResource($package_writer, $resource);
}
$package_writer->close();
return $package_path;
}
+ /**
+ * Creates a package writer with the specified options
+ *
+ * @param string $path
+ * @param BuildConfiguration $build_configuration
+ * @return PackageWriter
+ * @throws IOException
+ * @throws NotSupportedException
+ */
+ private function createPackageWriter(string $path, BuildConfiguration $build_configuration): PackageWriter
+ {
+ $package_writer = new PackageWriter($path);
+
+ if(isset($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]))
+ {
+ $package_writer->addFlag(PackageFlags::COMPRESSION);
+ switch(strtolower($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]))
+ {
+ case BuildConfigurationOptions\CompressionOptions::HIGH:
+ $package_writer->addFlag(PackageFlags::HIGH_COMPRESSION);
+ break;
+
+ case BuildConfigurationOptions\CompressionOptions::MEDIUM:
+ $package_writer->addFlag(PackageFlags::MEDIUM_COMPRESSION);
+ break;
+
+ case BuildConfigurationOptions\CompressionOptions::LOW:
+ $package_writer->addFlag(PackageFlags::LOW_COMPRESSION);
+ break;
+
+ default:
+ throw new NotSupportedException(sprintf('The compression level \'%s\' is not supported', $build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]));
+ }
+ }
+
+ return $package_writer;
+ }
+
/**
* Compiles a single component as a base64 encoded string
*
+ * @param PackageWriter $package_writer
* @param string $file_path
- * @return Package\Component
* @throws IOException
* @throws PathNotFoundException
+ * @noinspection UnusedFunctionResultInspection
*/
- public function buildComponent(string $file_path): Package\Component
+ public function processComponent(PackageWriter $package_writer, string $file_path): void
{
- return new Package\Component(
+ $package_writer->addComponent(new Package\Component(
Functions::removeBasename($file_path),
Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED
- );
+ ));
}
/**
+ * Packs a resource into the package
+ *
+ * @param PackageWriter $package_writer
* @param string $file_path
- * @return Resource
+ * @return void
* @throws IOException
* @throws PathNotFoundException
+ * @noinspection UnusedFunctionResultInspection
*/
- public function buildResource(string $file_path): Package\Resource
+ public function processResource(PackageWriter $package_writer, string $file_path): void
{
- return new Package\Resource(
- basename($file_path), IO::fread($file_path)
- );
+ $package_writer->addResource(new Package\Resource(
+ Functions::removeBasename($file_path), IO::fread($file_path)
+ ));
}
/**
- * Builds the package header
+ * Processes the package metadata
*
- * @param ProjectManager $project_manager
+ * @param PackageWriter $package_writer
* @param string $build_configuration
- * @return Package\Metadata
+ * @return void
* @throws ConfigurationException
+ * @throws IOException
+ * @noinspection UnusedFunctionResultInspection
*/
- public function buildMetadata(string $build_configuration=BuildConfigurationValues::DEFAULT): Package\Metadata
+ public function processMetadata(PackageWriter $package_writer, string $build_configuration=BuildConfigurationValues::DEFAULT): void
{
- $header = new Package\Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler());
+ $metadata = new Package\Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler());
- $header->setRuntimeConstants($this->project_manager->getRuntimeConstants($build_configuration));
- $header->setOptions($this->project_manager->getCompilerOptions($build_configuration));
- $header->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource());
- $header->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain());
- $header->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller());
+ $metadata->setRuntimeConstants($this->project_manager->getRuntimeConstants($build_configuration));
+ $metadata->setOptions($this->project_manager->getCompilerOptions($build_configuration));
+ $metadata->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource());
+ $metadata->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain());
+ $metadata->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller());
- return $header;
+ $package_writer->setMetadata($metadata);
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/PackageReader.php b/src/ncc/Classes/PackageReader.php
index 9cdd533..3c48ddf 100644
--- a/src/ncc/Classes/PackageReader.php
+++ b/src/ncc/Classes/PackageReader.php
@@ -25,14 +25,18 @@
namespace ncc\Classes;
+ use ncc\Enums\Flags\PackageFlags;
+ use ncc\Enums\PackageDirectory;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
use ncc\Objects\Package\Component;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\Package\Metadata;
+ use ncc\Objects\Package\Resource;
use ncc\Objects\ProjectConfiguration\Assembly;
+ use ncc\Objects\ProjectConfiguration\Dependency;
use ncc\Objects\ProjectConfiguration\Installer;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
use RuntimeException;
use ncc\Enums\PackageStructure;
@@ -53,6 +57,11 @@
*/
private $package_file;
+ /**
+ * @var array
+ */
+ private $cache;
+
/**
* PackageReader constructor.
*
@@ -72,18 +81,26 @@
throw new IOException(sprintf('Failed to open file \'%s\'', $file_path));
}
- $magic_bytes = fread($this->package_file, 7);
- $header = '';
+ $pre_header = '';
$diameter_hit = false;
- $this->header_length = 7;
- // Check for the magic bytes "ncc_pkg"
- if($magic_bytes !== 'ncc_pkg')
+ // Dynamically calculate header length until "ncc_pkg" is found
+ while (!feof($this->package_file))
{
- throw new IOException(sprintf('File \'%s\' is not a valid package file (invalid magic bytes)', $file_path));
+ $char = fread($this->package_file, 1);
+ $pre_header .= $char;
+
+ if (str_ends_with($pre_header, 'ncc_pkg'))
+ {
+ break;
+ }
}
+ // Calculate header length including "ncc_pkg"
+ $this->header_length = strlen($pre_header);
+
// Read everything after "ncc_pkg" up until the delimiter (0x1F 0x1F)
+ $header = '';
while(!feof($this->package_file))
{
$this->header_length++;
@@ -109,6 +126,7 @@
}
$this->headers = ZiProto::decode($header);
+ $this->cache = [];
}
/**
@@ -163,7 +181,7 @@
}
/**
- * Gets a resource from the package
+ * Returns a resource from the package by name
*
* @param string $name
* @return string
@@ -177,9 +195,28 @@
$location = explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
fseek($this->package_file, ($this->header_length + (int)$location[0]));
+
+ if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
+ {
+ return gzuncompress(fread($this->package_file, (int)$location[1]));
+ }
+
return fread($this->package_file, (int)$location[1]);
}
+ /**
+ * Returns a resource from the package by pointer
+ *
+ * @param int $pointer
+ * @param int $length
+ * @return string
+ */
+ public function getByPointer(int $pointer, int $length): string
+ {
+ fseek($this->package_file, ($this->header_length + $pointer));
+ return fread($this->package_file, $length);
+ }
+
/**
* Returns the package's assembly
*
@@ -188,12 +225,21 @@
*/
public function getAssembly(): Assembly
{
- if(!isset($this->headers[PackageStructure::DIRECTORY]['@assembly']))
+ $directory = sprintf('@%s', PackageDirectory::ASSEMBLY);
+
+ if(isset($this->cache[$directory]))
+ {
+ return $this->cache[$directory];
+ }
+
+ if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
{
throw new ConfigurationException('Package does not contain an assembly');
}
- return Assembly::fromArray(ZiProto::decode($this->get('@assembly')));
+ $assembly = Assembly::fromArray(ZiProto::decode($this->get($directory)));
+ $this->cache[$directory] = $assembly;
+ return $assembly;
}
/**
@@ -204,12 +250,21 @@
*/
public function getMetadata(): Metadata
{
- if(!isset($this->headers[PackageStructure::DIRECTORY]['@metadata']))
+ $directory = sprintf('@%s', PackageDirectory::METADATA);
+
+ if(isset($this->cache[$directory]))
+ {
+ return $this->cache[$directory];
+ }
+
+ if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
{
throw new ConfigurationException('Package does not contain metadata');
}
- return Metadata::fromArray(ZiProto::decode($this->get('@metadata')));
+ $metadata = Metadata::fromArray(ZiProto::decode($this->get($directory)));
+ $this->cache[$directory] = $metadata;
+ return $metadata;
}
/**
@@ -219,12 +274,21 @@
*/
public function getInstaller(): ?Installer
{
- if(!isset($this->headers[PackageStructure::DIRECTORY]['@installer']))
+ $directory = sprintf('@%s', PackageDirectory::INSTALLER);
+
+ if(isset($this->cache[$directory]))
+ {
+ return $this->cache[$directory];
+ }
+
+ if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
{
return null;
}
- return Installer::fromArray(ZiProto::decode($this->get('@installer')));
+ $installer = Installer::fromArray(ZiProto::decode($this->get($directory)));
+ $this->cache[$directory] = $installer;
+ return $installer;
}
/**
@@ -235,11 +299,13 @@
public function getDependencies(): array
{
$dependencies = [];
+ $directory = sprintf('@%s:', PackageDirectory::DEPENDENCIES);
+
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{
- if(str_starts_with($name, '@dependencies:'))
+ if(str_starts_with($name, $directory))
{
- $dependencies[] = str_replace('@dependencies:', '', $name);
+ $dependencies[] = str_replace($directory, '', $name);
}
}
@@ -250,18 +316,31 @@
* Returns a dependency from the package
*
* @param string $name
- * @return array
+ * @return Dependency
* @throws ConfigurationException
*/
- public function getDependency(string $name): array
+ public function getDependency(string $name): Dependency
{
- $dependency_name = sprintf('@dependencies:%s', $name);
+ $dependency_name = sprintf('@%s:%s', PackageDirectory::DEPENDENCIES, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY][$dependency_name]))
{
throw new ConfigurationException(sprintf('Dependency \'%s\' not found in package', $name));
}
- return ZiProto::decode($this->get('@dependencies:' . $name));
+ return Dependency::fromArray(ZiProto::decode($this->get($dependency_name)));
+ }
+
+ /**
+ * Returns a dependency from the package by pointer
+ *
+ * @param int $pointer
+ * @param int $length
+ * @return Dependency
+ * @throws ConfigurationException
+ */
+ public function getDependencyByPointer(int $pointer, int $length): Dependency
+ {
+ return Dependency::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
}
/**
@@ -272,11 +351,13 @@
public function getExecutionUnits(): array
{
$execution_units = [];
+ $directory = sprintf('@%s:', PackageDirectory::EXECUTION_UNITS);
+
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{
- if(str_starts_with($name, '@execution_units:'))
+ if(str_starts_with($name, $directory))
{
- $execution_units[] = str_replace('@execution_units:', '', $name);
+ $execution_units[] = str_replace($directory, '', $name);
}
}
@@ -292,7 +373,7 @@
*/
public function getExecutionUnit(string $name): ExecutionUnit
{
- $execution_unit_name = sprintf('@execution_units:%s', $name);
+ $execution_unit_name = sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY][$execution_unit_name]))
{
throw new ConfigurationException(sprintf('Execution unit \'%s\' not found in package', $name));
@@ -302,24 +383,55 @@
}
/**
- * Returns the package's components
+ * Returns an execution unit from the package by pointer
+ *
+ * @param int $pointer
+ * @param int $length
+ * @return ExecutionUnit
+ * @throws ConfigurationException
+ */
+ public function getExecutionUnitByPointer(int $pointer, int $length): ExecutionUnit
+ {
+ return ExecutionUnit::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
+ }
+
+ /**
+ * Returns the package's component pointers
*
* @return array
*/
public function getComponents(): array
{
$components = [];
+ $directory = sprintf('@%s:', PackageDirectory::COMPONENTS);
+
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{
- if(str_starts_with($name, '@components:'))
+ if(str_starts_with($name, $directory))
{
- $components[] = str_replace('@components:', '', $name);
+ $components[] = str_replace($directory, '', $name);
}
}
return $components;
}
+ public function getClassMap(): array
+ {
+ $class_map = [];
+ $directory = sprintf('@%s:', PackageDirectory::CLASS_POINTER);
+
+ foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
+ {
+ if(str_starts_with($name, $directory))
+ {
+ $class_map[] = str_replace($directory, '', $name);
+ }
+ }
+
+ return $class_map;
+ }
+
/**
* Returns a component from the package
*
@@ -329,28 +441,61 @@
*/
public function getComponent(string $name): Component
{
- $component_name = sprintf('@components:%s', $name);
+ $component_name = sprintf('@%s:%s', PackageDirectory::COMPONENTS, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY][$component_name]))
{
throw new ConfigurationException(sprintf('Component \'%s\' not found in package', $name));
}
- return Component::fromArray(ZiProto::decode($this->get('@components:' . $name)));
+ return Component::fromArray(ZiProto::decode($this->get($component_name)));
}
/**
- * Returns an array of resources from the package
+ * Returns a component from the package by pointer
+ *
+ * @param int $pointer
+ * @param int $length
+ * @return Component
+ * @throws ConfigurationException
+ */
+ public function getComponentByPointer(int $pointer, int $length): Component
+ {
+ return Component::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
+ }
+
+ /**
+ * Returns a component from the package by a class pointer
+ *
+ * @param string $class
+ * @return Component
+ * @throws ConfigurationException
+ */
+ public function getComponentByClass(string $class): Component
+ {
+ $class_name = sprintf('@%s:%s', PackageDirectory::CLASS_POINTER, $class);
+ if(!isset($this->headers[PackageStructure::DIRECTORY][$class_name]))
+ {
+ throw new ConfigurationException(sprintf('Class map \'%s\' not found in package', $class));
+ }
+
+ return Component::fromArray(ZiProto::decode($this->get($class_name)));
+ }
+
+ /**
+ * Returns an array of resource pointers from the package
*
* @return array
*/
public function getResources(): array
{
$resources = [];
+ $directory = sprintf('@%s:', PackageDirectory::RESOURCES);
+
foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{
- if(str_starts_with($name, '@resources:'))
+ if(str_starts_with($name, $directory))
{
- $resources[] = str_replace('@resources:', '', $name);
+ $resources[] = str_replace($directory, '', $name);
}
}
@@ -361,18 +506,31 @@
* Returns a resource from the package
*
* @param string $name
- * @return string
+ * @return Resource
* @throws ConfigurationException
*/
- public function getResource(string $name): string
+ public function getResource(string $name): Resource
{
- $resource_name = sprintf('@resources:%s', $name);
+ $resource_name = sprintf('@%s:%s', PackageDirectory::RESOURCES, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY][$resource_name]))
{
throw new ConfigurationException(sprintf('Resource \'%s\' not found in package', $name));
}
- return $this->get('@resources:' . $name);
+ return Resource::fromArray(ZiProto::decode($this->get($resource_name)));
+ }
+
+ /**
+ * Returns a resource from the package by pointer
+ *
+ * @param int $pointer
+ * @param int $length
+ * @return Resource
+ * @throws ConfigurationException
+ */
+ public function getResourceByPointer(int $pointer, int $length): Resource
+ {
+ return Resource::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
}
/**
diff --git a/src/ncc/Classes/PackageWriter.php b/src/ncc/Classes/PackageWriter.php
index 93ece92..2fdc3cc 100644
--- a/src/ncc/Classes/PackageWriter.php
+++ b/src/ncc/Classes/PackageWriter.php
@@ -25,6 +25,8 @@
namespace ncc\Classes;
+ use ncc\Enums\Flags\PackageFlags;
+ use ncc\Enums\PackageDirectory;
use ncc\Enums\PackageStructure;
use ncc\Enums\PackageStructureVersions;
use ncc\Exceptions\IOException;
@@ -35,7 +37,7 @@
use ncc\Objects\ProjectConfiguration\Assembly;
use ncc\Objects\ProjectConfiguration\Dependency;
use ncc\Objects\ProjectConfiguration\Installer;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class PackageWriter
{
@@ -59,6 +61,11 @@
*/
private $temporary_path;
+ /**
+ * @var bool
+ */
+ private $data_written;
+
/**
* PackageWriter constructor.
*
@@ -94,6 +101,7 @@
touch($file_path);
touch($file_path . '.tmp');
+ $this->data_written = false;
$this->temporary_path = $file_path . '.tmp';
$this->temp_file = @fopen($this->temporary_path, 'wb'); // Create a temporary data file
$this->package_file = @fopen($file_path, 'wb');
@@ -148,6 +156,11 @@
*/
public function setFlags(array $flags): void
{
+ if($this->data_written)
+ {
+ throw new IOException('Cannot set flags after data has been written to the package');
+ }
+
$this->headers[PackageStructure::FLAGS] = $flags;
}
@@ -156,9 +169,15 @@
*
* @param string $flag
* @return void
+ * @throws IOException
*/
public function addFlag(string $flag): void
{
+ if($this->data_written)
+ {
+ throw new IOException('Cannot add a flag after data has been written to the package');
+ }
+
if(!in_array($flag, $this->headers[PackageStructure::FLAGS], true))
{
$this->headers[PackageStructure::FLAGS][] = $flag;
@@ -173,6 +192,11 @@
*/
public function removeFlag(string $flag): void
{
+ if($this->data_written)
+ {
+ throw new IOException('Cannot remove a flag after data has been written to the package');
+ }
+
$this->headers[PackageStructure::FLAGS] = array_diff($this->headers[PackageStructure::FLAGS], [$flag]);
}
@@ -181,102 +205,159 @@
*
* @param string $name
* @param string $data
- * @return void
+ * @return array
* @throws IOException
*/
- public function add(string $name, string $data): void
+ public function add(string $name, string $data): array
{
if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
{
throw new IOException(sprintf('Resource \'%s\' already exists in package', $name));
}
- $this->headers[PackageStructure::DIRECTORY][$name] = sprintf("%d:%d", ftell($this->temp_file), strlen($data));
+ if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
+ {
+ if(in_array(PackageFlags::LOW_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
+ {
+ $data = gzcompress($data, 1);
+ }
+ else if(in_array(PackageFlags::MEDIUM_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
+ {
+ $data = gzcompress($data, 6);
+ }
+ else if(in_array(PackageFlags::HIGH_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
+ {
+ $data = gzcompress($data, 9);
+ }
+ else
+ {
+ $data = gzcompress($data);
+ }
+ }
+
+ $pointer = sprintf("%d:%d", ftell($this->temp_file), strlen($data));
+ $this->headers[PackageStructure::DIRECTORY][$name] = $pointer;
+ $this->data_written = true;
fwrite($this->temp_file, $data);
+
+ return explode(':', $pointer);
+ }
+
+ /**
+ * Adds a pointer to the package
+ *
+ * @param string $name
+ * @param int $offset
+ * @param int $length
+ * @return void
+ * @throws IOException
+ */
+ public function addPointer(string $name, int $offset, int $length): void
+ {
+ if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
+ {
+ throw new IOException(sprintf('Resource \'%s\' already exists in package', $name));
+ }
+
+ $this->headers[PackageStructure::DIRECTORY][$name] = sprintf("%d:%d", $offset, $length);
}
/**
* Sets the assembly of the package
*
* @param Assembly $assembly
- * @return void
+ * @return array
* @throws IOException
*/
- public function setAssembly(Assembly $assembly): void
+ public function setAssembly(Assembly $assembly): array
{
- $this->add('@assembly', ZiProto::encode($assembly->toArray()));
+ return $this->add(sprintf('@%s', PackageDirectory::ASSEMBLY), ZiProto::encode($assembly->toArray(true)));
}
/**
* Adds the metadata to the package
*
* @param Metadata $metadata
- * @return void
+ * @return array
* @throws IOException
*/
- public function setMetadata(Metadata $metadata): void
+ public function setMetadata(Metadata $metadata): array
{
- $this->add('@metadata', ZiProto::encode($metadata->toArray()));
+ return $this->add(sprintf('@%s', PackageDirectory::METADATA), ZiProto::encode($metadata->toArray(true)));
}
/**
* Sets the installer information of the package
*
* @param Installer $installer
- * @return void
+ * @return array
* @throws IOException
*/
- public function setInstaller(Installer $installer): void
+ public function setInstaller(Installer $installer): array
{
- $this->add('@installer', ZiProto::encode($installer->toArray()));
+ return $this->add(sprintf('@%s', PackageDirectory::INSTALLER), ZiProto::encode($installer->toArray(true)));
}
/**
* Adds a dependency configuration to the package
*
* @param Dependency $dependency
- * @return void
+ * @return array
* @throws IOException
*/
- public function addDependencyConfiguration(Dependency $dependency): void
+ public function addDependencyConfiguration(Dependency $dependency): array
{
- $this->add(sprintf('@dependencies:%s', $dependency->getName()), ZiProto::encode($dependency->toArray()));
+ return $this->add(sprintf('@%s:%s', PackageDirectory::DEPENDENCIES, $dependency->getName()), ZiProto::encode($dependency->toArray(true)));
}
/**
* Adds an execution unit to the package
*
* @param ExecutionUnit $unit
- * @return void
+ * @return array
* @throws IOException
*/
- public function addExecutionUnit(ExecutionUnit $unit): void
+ public function addExecutionUnit(ExecutionUnit $unit): array
{
- $this->add(sprintf('@execution_units:%s', $unit->getExecutionPolicy()->getName()), ZiProto::encode($unit->toArray()));
+ return $this->add(sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS, $unit->getExecutionPolicy()->getName()), ZiProto::encode($unit->toArray(true)));
}
/**
* Adds a component to the package
*
* @param Component $component
- * @return void
+ * @return array
* @throws IOException
*/
- public function addComponent(Component $component): void
+ public function addComponent(Component $component): array
{
- $this->add(sprintf('@components:%s', $component->getName()), ZiProto::encode($component->toArray()));
+ return $this->add(sprintf('@%s:%s', PackageDirectory::COMPONENTS, $component->getName()), ZiProto::encode($component->toArray(true)));
}
/**
* Adds a resource to the package
*
* @param Resource $resource
+ * @return array
+ * @throws IOException
+ */
+ public function addResource(Resource $resource): array
+ {
+ return $this->add(sprintf('@%s:%s', PackageDirectory::RESOURCES, $resource->getName()), $resource->getData());
+ }
+
+ /**
+ * Maps a class to a component in the package
+ *
+ * @param string $class
+ * @param int $offset
+ * @param int $length
* @return void
* @throws IOException
*/
- public function addResource(Resource $resource): void
+ public function mapClass(string $class, int $offset, int $length): void
{
- $this->add(sprintf('@resources:%s', $resource->getName()), $resource->getData());
+ $this->addPointer(sprintf('@%s:%s', PackageDirectory::CLASS_POINTER, $class), $offset, $length);
}
/**
@@ -327,5 +408,17 @@
{
// Ignore
}
+ finally
+ {
+ if(is_resource($this->package_file))
+ {
+ fclose($this->package_file);
+ }
+
+ if(is_resource($this->temp_file))
+ {
+ fclose($this->temp_file);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/PerlExtension/PerlRunner.php b/src/ncc/Classes/PerlExtension/PerlRunner.php
index f607e2f..57bc6b7 100644
--- a/src/ncc/Classes/PerlExtension/PerlRunner.php
+++ b/src/ncc/Classes/PerlExtension/PerlRunner.php
@@ -22,44 +22,51 @@
namespace ncc\Classes\PerlExtension;
+ use Exception;
+ use ncc\Classes\ExecutionUnitRunner;
use ncc\Exceptions\IOException;
+ use ncc\Exceptions\NotSupportedException;
+ use ncc\Exceptions\OperationException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
+ use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
use ncc\Utilities\IO;
+ use ncc\Utilities\PathFinder;
class PerlRunner implements RunnerInterface
{
-
/**
* @inheritDoc
- * @param string $path
- * @param ExecutionPolicy $policy
- * @return ExecutionUnit
* @throws IOException
- * @throws PathNotFoundException
+ * @throws OperationException
*/
- public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
+ public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
{
- $execution_unit = new ExecutionUnit();
+ $tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.pl';
+ IO::fwrite($tmp, $unit->getData(), 0777);
- if(!file_exists($path) && !is_file($path))
+ try
{
- throw new PathNotFoundException($path);
+ $process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
+ $process->run(static function($type, $buffer) use ($unit)
+ {
+ if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
+ {
+ print($buffer);
+ }
+ });
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException(sprintf('There was an error executing the perl execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
+ }
+ finally
+ {
+ unlink($tmp);
}
- $execution_unit->setExecutionPolicy($policy);
- $execution_unit->setData(IO::fread($path));
-
- return $execution_unit;
- }
-
- /**
- * @inheritDoc
- */
- public static function getFileExtension(): string
- {
- return '.pl';
+ return $process->getExitCode();
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/AstWalker.php b/src/ncc/Classes/PhpExtension/AstWalker.php
new file mode 100644
index 0000000..622f858
--- /dev/null
+++ b/src/ncc/Classes/PhpExtension/AstWalker.php
@@ -0,0 +1,257 @@
+jsonSerialize();
+ }
+ return $serialized;
+ }
+
+ return $node->jsonSerialize();
+ }
+
+ /**
+ * Returns an array of classes associated with the node recursively
+ *
+ * @param Node|array $node
+ * @param string $prefix
+ * @return array
+ */
+ public static function extractClasses(Node|array $node, string $prefix=''): array
+ {
+ if(is_array($node))
+ {
+ $classes = [];
+ foreach($node as $sub_node)
+ {
+ /** @noinspection SlowArrayOperationsInLoopInspection */
+ $classes = array_merge($classes, self::extractClasses($sub_node, $prefix));
+ }
+ return $classes;
+ }
+
+ $classes = [];
+
+ if ($node instanceof Node\Stmt\ClassLike)
+ {
+ $classes[] = $prefix . $node->name;
+ }
+
+ if ($node instanceof Node\Stmt\Namespace_)
+ {
+ if ($node->name && $node->name->parts)
+ {
+ $prefix .= implode('\\', $node->name->parts) . '\\';
+ }
+ else
+ {
+ $prefix = '';
+ }
+ }
+
+ foreach ($node->getSubNodeNames() as $node_name)
+ {
+ if ($node->$node_name instanceof Node)
+ {
+ /** @noinspection SlowArrayOperationsInLoopInspection */
+ $classes = array_merge($classes, self::extractClasses($node->$node_name, $prefix));
+ }
+ elseif (is_array($node->$node_name))
+ {
+ foreach ($node->$node_name as $sub_node)
+ {
+ if ($sub_node instanceof Node)
+ {
+ /** @noinspection SlowArrayOperationsInLoopInspection */
+ $classes = array_merge($classes, self::extractClasses($sub_node, $prefix));
+ }
+ }
+ }
+ }
+
+ return $classes;
+ }
+
+ /**
+ * Reconstructs nodes from an array representation recursively
+ *
+ * @param $value
+ * @return array|Comment|Node
+ * @noinspection PhpMissingReturnTypeInspection
+ * @throws ReflectionException
+ */
+ public static function decodeRecursive($value)
+ {
+ if (is_array($value))
+ {
+ if (isset($value['nodeType']))
+ {
+ if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc')
+ {
+ return self::decodeComment($value);
+ }
+
+ return self::decodeNode($value);
+ }
+
+ return self::decodeArray($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Decodes an array by recursively decoding each value
+ *
+ * @param array $array
+ * @return array
+ * @throws ReflectionException
+ */
+ private static function decodeArray(array $array) : array
+ {
+ $decoded_array = [];
+
+ foreach ($array as $key => $value)
+ {
+ $decoded_array[$key] = self::decodeRecursive($value);
+ }
+
+ return $decoded_array;
+ }
+
+ /**
+ * Returns the node from the node type
+ *
+ * @param array $value
+ * @return Node
+ * @throws ReflectionException
+ */
+ private static function decodeNode(array $value) : Node
+ {
+ $node_type = $value['nodeType'];
+ if (!is_string($node_type))
+ {
+ throw new RuntimeException('Node type must be a string');
+ }
+
+ /** @var Node $node */
+ $node = self::reflectionClassFromNodeType($node_type)->newInstanceWithoutConstructor();
+
+ if (isset($value['attributes'])) {
+ if (!is_array($value['attributes']))
+ {
+ throw new RuntimeException('Attributes must be an array');
+ }
+
+ $node->setAttributes(self::decodeArray($value['attributes']));
+ }
+
+ foreach ($value as $name => $sub_node) {
+ if ($name === 'nodeType' || $name === 'attributes')
+ {
+ continue;
+ }
+
+ $node->$name = self::decodeRecursive($sub_node);
+ }
+
+ return $node;
+ }
+
+ /**
+ * Returns the comment from the node type
+ *
+ * @param array $value
+ * @return Comment
+ */
+ private static function decodeComment(array $value): Comment
+ {
+ $class_name = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
+ if (!isset($value['text']))
+ {
+ throw new RuntimeException('Comment must have text');
+ }
+
+ return new $class_name(
+ $value['text'],
+ $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
+ $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
+ );
+ }
+
+ /**
+ * Returns the reflection class from the node type
+ *
+ * @param string $node_type
+ * @return ReflectionClass
+ * @throws ReflectionException
+ */
+ private static function reflectionClassFromNodeType(string $node_type): ReflectionClass
+ {
+ return new ReflectionClass(self::classNameFromNodeType($node_type));
+ }
+
+ /**
+ * Returns the class name from the node type
+ *
+ * @param string $nodeType
+ * @return string
+ */
+ private static function classNameFromNodeType(string $nodeType): string
+ {
+ $class_name = 'ncc\\ThirdParty\\nikic\\PhpParser\\Node\\' . str_replace('_', '\\', $nodeType);
+ if (class_exists($class_name))
+ {
+ return $class_name;
+ }
+
+ $class_name .= '_';
+ if (class_exists($class_name))
+ {
+ return $class_name;
+ }
+
+ throw new RuntimeException("Unknown node type \"$nodeType\"");
+ }
+ }
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/ExecutableCompiler.php b/src/ncc/Classes/PhpExtension/ExecutableCompiler.php
new file mode 100644
index 0000000..f98f045
--- /dev/null
+++ b/src/ncc/Classes/PhpExtension/ExecutableCompiler.php
@@ -0,0 +1,170 @@
+getProjectManager()->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
+
+ if(!isset($configuration->getOptions()['ncc_configuration']))
+ {
+ throw new BuildException(sprintf("Unable to compile the binary, the build configuration '%s' does not have a ncc_configuration.", $build_configuration));
+ }
+
+ // Build the ncc package first
+ Console::outVerbose('Building ncc package.');
+ $ncc_package = parent::build($configuration->getOptions()['ncc_configuration']);
+
+ // Prepare the ncc package for compilation
+ $hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c';
+ if(is_file($hex_dump_file))
+ {
+ unlink($hex_dump_file);
+ }
+
+ Console::outVerbose(sprintf('Converting ncc package %s to hex dump', $ncc_package));
+ $this->hexDump($ncc_package, $hex_dump_file, parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName());
+
+ // Prepare the gcc command
+ $gcc_path = (new ExecutableFinder())->find('gcc');
+ $binary_path = $configuration->getOutputPath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName();
+
+ if($gcc_path === null)
+ {
+ throw new BuildException("Unable to find gcc executable, please make sure it is installed and in your PATH environment variable.");
+ }
+
+ if(!is_file(__DIR__ . DIRECTORY_SEPARATOR . 'bootstrap_main.c'))
+ {
+ throw new BuildException("Unable to find bootstrap_main.c, please make sure ncc is installed correctly.");
+ }
+
+ $gcc_options = [
+ __DIR__ . DIRECTORY_SEPARATOR . 'bootstrap_main.c',
+ realpath($hex_dump_file)
+ ];
+
+ foreach($configuration->getOptions() as $option => $value)
+ {
+ if(str_starts_with($option, 'gcc-'))
+ {
+ $gcc_options[] = sprintf('-%s%s', substr($option, 4), $value === null ? '' : '=' . $value);
+ }
+ }
+
+ $gcc_options[] = '-o';
+ $gcc_options[] = $binary_path;
+
+ switch(Main::getLogLevel())
+ {
+ case LogLevel::VERBOSE:
+ $gcc_options[] = '-v';
+ break;
+
+ case LogLevel::DEBUG:
+ $gcc_options[] = '-v';
+ $gcc_options[] = '-v';
+ break;
+ }
+
+ $process = new Process([$gcc_path, ...$gcc_options]);
+ $process->setTimeout(0);
+
+ Console::outVerbose(sprintf('Compiling executable to %s: %s', $binary_path, implode(' ', $gcc_options)));
+ $process->run(static function ($type, $buffer)
+ {
+ Console::outVerbose(rtrim($buffer, "\n"));
+ });
+
+ if(!$process->isSuccessful())
+ {
+ unlink($hex_dump_file);
+ throw new BuildException(sprintf("Unable to compile the binary, gcc exited with code %d: %s", $process->getExitCode(), $process->getErrorOutput()));
+ }
+
+ // Finally, remove the hex dump file and return the executable path
+ unlink($hex_dump_file);
+ return $binary_path;
+ }
+
+ /**
+ * Creates a hex dump of the binary data and writes it to the output file suitable for inclusion in a C source
+ * file, this is a similar utility to xxd.
+ *
+ * @param string $input_path
+ * @param string $output_path
+ * @param string $variable_name
+ * @return void
+ */
+ private function hexDump(string $input_path, string $output_path, string $variable_name): void
+ {
+ $input = fopen($input_path, 'rb');
+ $output = fopen($output_path, 'wb');
+
+ fwrite($output, sprintf("unsigned char %s[] = {\n", Functions::toSnakeCase($variable_name)));
+ $byte_count = 0;
+
+ // Convert the binary data to hex and write it to the output file
+ while (!feof($input))
+ {
+ $byte = fread($input, 1);
+ if (strlen($byte) === 1)
+ {
+ fwrite($output, sprintf(" 0x%02x,", ord($byte)));
+ $byte_count++;
+ }
+
+ // Write 12 bytes per line or when reaching the end of the file
+ if ($byte_count === 12 || feof($input))
+ {
+ fwrite($output, "\n");
+ $byte_count = 0;
+ }
+ }
+
+ // Close the output file
+ fseek($output, -2, SEEK_END);
+ fwrite($output, "\n");
+ fwrite($output, "};\n");
+
+ // Finally, close the input and output files
+ fclose($input);
+ fclose($output);
+ }
+ }
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/NccCompiler.php b/src/ncc/Classes/PhpExtension/NccCompiler.php
index 185e5c4..4c03822 100644
--- a/src/ncc/Classes/PhpExtension/NccCompiler.php
+++ b/src/ncc/Classes/PhpExtension/NccCompiler.php
@@ -23,7 +23,9 @@
namespace ncc\Classes\PhpExtension;
use Exception;
+ use ncc\Classes\PackageWriter;
use ncc\Enums\ComponentDataType;
+ use ncc\Enums\Flags\ComponentFlags;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Objects\Package\Component;
@@ -32,34 +34,44 @@
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\IO;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class NccCompiler extends \ncc\Classes\NccExtension\NccCompiler
{
/**
+ * @param PackageWriter $package_writer
* @param string $file_path
- * @return Component
+ * @return void
* @throws IOException
* @throws PathNotFoundException
+ * @noinspection UnusedFunctionResultInspection
*/
- public function buildComponent(string $file_path): Component
+ public function processComponent(PackageWriter $package_writer, string $file_path): void
{
- $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
+ $component_name = Functions::removeBasename($file_path);
try
{
- $encoded = json_encode($parser->parse(IO::fread($file_path)), JSON_THROW_ON_ERROR);
- return new Component(Functions::removeBasename($file_path), ZiProto::encode(json_decode($encoded, true, 512, JSON_THROW_ON_ERROR)), ComponentDataType::AST);
+ $stmts = (new ParserFactory())->create(ParserFactory::PREFER_PHP7)->parse(IO::fread($file_path));
+
+ $component = new Component($component_name, ZiProto::encode($stmts), ComponentDataType::AST);
+ $component->addFlag(ComponentFlags::PHP_AST);
+ $pointer = $package_writer->addComponent($component);
+
+ foreach(AstWalker::extractClasses($stmts) as $class)
+ {
+ $package_writer->mapClass($class, (int)$pointer[0], (int)$pointer[1]);
+ }
+
+ return;
}
catch(Exception $e)
{
Console::outWarning(sprintf('Failed to compile file "%s" with error "%s"', $file_path, $e->getMessage()));
}
- return new Component(
- Functions::removeBasename($file_path),
- Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED
- );
+ $component = new Component($component_name, Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED);
+ $component->addFlag(ComponentFlags::PHP_B64);
+ $package_writer->addComponent($component);
}
-
}
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/PhpInstaller.php b/src/ncc/Classes/PhpExtension/PhpInstaller.php
deleted file mode 100644
index 22017b7..0000000
--- a/src/ncc/Classes/PhpExtension/PhpInstaller.php
+++ /dev/null
@@ -1,356 +0,0 @@
-getData() === null)
- {
- return null;
- }
-
- if(!$component->validateChecksum())
- {
- throw new IntegrityException(sprintf('Checksum validation failed for component: %s', $component->getName()));
- }
-
- switch($component->getDataType())
- {
- case ComponentDataType::AST:
- try
- {
- $stmts = $this->decodeRecursive($component->getData());
- }
- catch (Exception $e)
- {
- throw new IntegrityException(sprintf('Cannot decode component: %s, %s', $component->getName(), $e->getMessage()));
- }
-
- return (new Standard())->prettyPrintFile($stmts);
-
- case ComponentDataType::BASE64_ENCODED:
- return Base64::decode($component->getData());
-
- case ComponentDataType::PLAIN:
- return $component->getData();
-
- default:
- throw new NotSupportedException(sprintf('Component data type %s is not supported.', $component->getDataType()));
- }
- }
-
- /**
- * @inheritDoc
- */
- public function preInstall(InstallationPaths $installationPaths): void
- {
- }
-
- /**
- * @inheritDoc
- */
- public function postInstall(InstallationPaths $installationPaths): void
- {
- $autoload_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php';
- $autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path);
-
- IO::fwrite($autoload_path, $autoload_src);
- }
-
- /**
- * Processes the given resource and returns the string representation of the resource
- *
- * @param Resource $resource
- * @return string|null
- * @throws IntegrityException
- */
- public function processResource(Package\Resource $resource): ?string
- {
- if(!$resource->validateChecksum())
- {
- throw new IntegrityException('Checksum validation failed for resource ' . $resource->getName() . ', the package may be corrupted.');
- }
-
- return Base64::decode($resource->getData());
- }
-
- /**
- * @param $value
- * @return array|Comment|Node
- * @throws ReflectionException
- * @noinspection PhpMissingReturnTypeInspection
- */
- private function decodeRecursive($value)
- {
- if (is_array($value))
- {
- if (isset($value['nodeType']))
- {
- if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc')
- {
- return $this->decodeComment($value);
- }
-
- return $this->decodeNode($value);
- }
-
- return $this->decodeArray($value);
- }
-
- return $value;
- }
-
- /**
- * @param array $array
- * @return array
- * @throws ReflectionException
- */
- private function decodeArray(array $array) : array
- {
- $decodedArray = [];
-
- foreach ($array as $key => $value)
- {
- $decodedArray[$key] = $this->decodeRecursive($value);
- }
-
- return $decodedArray;
- }
-
- /**
- * @param array $value
- * @return Node
- * @throws ReflectionException
- */
- private function decodeNode(array $value) : Node
- {
- $nodeType = $value['nodeType'];
- if (!is_string($nodeType))
- {
- throw new RuntimeException('Node type must be a string');
- }
-
- $reflectionClass = $this->reflectionClassFromNodeType($nodeType);
- /** @var Node $node */
- $node = $reflectionClass->newInstanceWithoutConstructor();
-
- if (isset($value['attributes'])) {
- if (!is_array($value['attributes']))
- {
- throw new RuntimeException('Attributes must be an array');
- }
-
- $node->setAttributes($this->decodeArray($value['attributes']));
- }
-
- foreach ($value as $name => $subNode) {
- if ($name === 'nodeType' || $name === 'attributes')
- {
- continue;
- }
-
- $node->$name = $this->decodeRecursive($subNode);
- }
-
- return $node;
- }
-
- /**
- * @param array $value
- * @return Comment
- */
- private function decodeComment(array $value) : Comment
- {
- $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
- if (!isset($value['text']))
- {
- throw new RuntimeException('Comment must have text');
- }
-
- return new $className(
- $value['text'],
- $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
- $value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
- );
- }
-
- /**
- * @param string $nodeType
- * @return ReflectionClass
- * @throws ReflectionException
- */
- private function reflectionClassFromNodeType(string $nodeType) : ReflectionClass
- {
- if (!isset($this->reflection_class[$nodeType]))
- {
- $className = $this->classNameFromNodeType($nodeType);
- $this->reflection_class[$nodeType] = new ReflectionClass($className);
- }
- return $this->reflection_class[$nodeType];
- }
-
- /**
- * @param string $nodeType
- * @return string
- */
- private function classNameFromNodeType(string $nodeType) : string
- {
- $className = 'ncc\\ThirdParty\\nikic\\PhpParser\\Node\\' . str_replace('_', '\\', $nodeType);
- if (class_exists($className))
- {
- return $className;
- }
-
- $className .= '_';
- if (class_exists($className))
- {
- return $className;
- }
-
- throw new RuntimeException("Unknown node type \"$nodeType\"");
- }
-
- /**
- * Processes the project and generates the autoloader source code.
- *
- * @param string $src
- * @param string $output
- * @return string
- * @throws CollectorException
- * @throws IOException
- * @throws PathNotFoundException
- */
- private function generateAutoload(string $src, string $output): string
- {
- // Construct configuration
- $configuration = new Config([$src]);
- $configuration->setFollowSymlinks(false); // Don't follow symlinks, it won't work on some systems.
- $configuration->setTrusting(true); // Paranoid
- $configuration->setOutputFile($output);
- $configuration->setStaticMode(false);
- // Official PHP file extensions that are missing from the default configuration (whatever)
- $configuration->setInclude(ComponentFileExtensions::PHP);
- $configuration->setQuietMode(true);
- $configuration->setTolerantMode(true);
-
- // Construct factory
- $factory = new Factory();
- $factory->setConfig($configuration);
-
- // Create Collector
- $result = self::runCollector($factory, $configuration);
-
- // Exception raises when there are no files in the project that can be processed by the autoloader
- $template = IO::fread($configuration->getTemplate());
- return $factory->getRenderer($result)->render($template);
- }
-
- /**
- * Iterates through the target directories through the collector and returns the collector results.
- *
- * @param Factory $factory
- * @param Config $config
- * @return CollectorResult
- * @throws CollectorException
- * @throws Exception
- */
- private static function runCollector(Factory $factory, Config $config): CollectorResult
- {
- $collector = $factory->getCollector();
- foreach($config->getDirectories() as $directory)
- {
- if(is_dir($directory))
- {
- $scanner = $factory->getScanner()->getIterator($directory);
- $collector->processDirectory($scanner);
- unset($scanner);
- }
- else
- {
- $file = new SplFileInfo($directory);
- $filter = $factory->getFilter(new ArrayIterator(array($file)));
- foreach($filter as $file)
- {
- $collector->processFile($file);
- }
- }
- }
-
- return $collector->getResult();
- }
- }
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/PhpRuntime.php b/src/ncc/Classes/PhpExtension/PhpRuntime.php
deleted file mode 100644
index 493ae3b..0000000
--- a/src/ncc/Classes/PhpExtension/PhpRuntime.php
+++ /dev/null
@@ -1,120 +0,0 @@
-getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php';
- $static_files = $versionEntry->getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin';
- $constants_path = $versionEntry->getInstallPaths()->getDataPath() . DIRECTORY_SEPARATOR . 'const';
- $assembly_path = $versionEntry->getInstallPaths()->getDataPath() . DIRECTORY_SEPARATOR . 'assembly';
-
- if(!file_exists($assembly_path))
- {
- throw new ImportException('Cannot locate assembly file \'' . $assembly_path . '\'');
- }
-
- try
- {
- $assembly_content = ZiProto::decode(IO::fread($assembly_path));
- $assembly = Assembly::fromArray($assembly_content);
- }
- catch(Exception $e)
- {
- throw new ImportException('Failed to load assembly file \'' . $assembly_path . '\': ' . $e->getMessage());
- }
-
- if(file_exists($constants_path))
- {
- try
- {
- $constants = ZiProto::decode(IO::fread($constants_path));
- }
- catch(Exception $e)
- {
- throw new ImportException('Failed to load constants file \'' . $constants_path . '\': ' . $e->getMessage());
- }
-
- foreach($constants as $name => $value)
- {
- $value = ConstantCompiler::compileRuntimeConstants($value);
-
- try
- {
- Constants::register($assembly->getPackage(), $name, $value, true);
- }
- catch (IntegrityException $e)
- {
- trigger_error('Cannot set constant \'' . $name . '\', ' . $e->getMessage(), E_USER_WARNING);
- }
- }
- }
-
- if(file_exists($autoload_path) && !in_array(RuntimeImportOptions::IMPORT_AUTOLOADER, $options, true))
- {
- require_once($autoload_path);
- }
-
- if(file_exists($static_files) && !in_array(RuntimeImportOptions::IMPORT_STATIC_FILES, $options, true))
- {
- try
- {
- $static_files = ZiProto::decode(IO::fread($static_files));
- foreach($static_files as $file)
- {
- require_once($file);
- }
- }
- catch(Exception $e)
- {
- throw new ImportException('Failed to load static files: ' . $e->getMessage(), $e);
- }
-
- }
-
- return !(!file_exists($autoload_path) && !file_exists($static_files));
- }
- }
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/TemplateFiles/main.php.tpl b/src/ncc/Classes/PhpExtension/TemplateFiles/main.php.tpl
deleted file mode 100644
index 593b299..0000000
--- a/src/ncc/Classes/PhpExtension/TemplateFiles/main.php.tpl
+++ /dev/null
@@ -1,17 +0,0 @@
-getProjectSourcePath() . DIRECTORY_SEPARATOR . 'Program.php',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
- IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Program.php.tpl')
+ IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'Program.php.tpl')
)
);
}
@@ -89,7 +89,7 @@
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'main',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
- IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'main.php.tpl')
+ IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'main.php.tpl')
)
);
}
@@ -107,7 +107,7 @@
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'Makefile',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
- IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Makefile.tpl')
+ IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'Makefile.tpl')
)
);
}
diff --git a/src/ncc/Classes/PhpExtension/PhpLibraryTemplate.php b/src/ncc/Classes/PhpExtension/Templates/LibraryTemplate.php
similarity index 96%
rename from src/ncc/Classes/PhpExtension/PhpLibraryTemplate.php
rename to src/ncc/Classes/PhpExtension/Templates/LibraryTemplate.php
index 51bb968..1aea9d3 100644
--- a/src/ncc/Classes/PhpExtension/PhpLibraryTemplate.php
+++ b/src/ncc/Classes/PhpExtension/Templates/LibraryTemplate.php
@@ -20,7 +20,7 @@
*
*/
- namespace ncc\Classes\PhpExtension;
+ namespace ncc\Classes\PhpExtension\Templates;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Exceptions\IOException;
@@ -29,7 +29,7 @@
use ncc\Managers\ProjectManager;
use ncc\Utilities\IO;
- class PhpLibraryTemplate implements TemplateInterface
+ class LibraryTemplate implements TemplateInterface
{
/**
* @inheritDoc
diff --git a/src/ncc/Classes/PhpExtension/TemplateFiles/Makefile.tpl b/src/ncc/Classes/PhpExtension/Templates/Makefile.tpl
similarity index 100%
rename from src/ncc/Classes/PhpExtension/TemplateFiles/Makefile.tpl
rename to src/ncc/Classes/PhpExtension/Templates/Makefile.tpl
diff --git a/src/ncc/Classes/PhpExtension/TemplateFiles/Program.php.tpl b/src/ncc/Classes/PhpExtension/Templates/Program.php.tpl
similarity index 58%
rename from src/ncc/Classes/PhpExtension/TemplateFiles/Program.php.tpl
rename to src/ncc/Classes/PhpExtension/Templates/Program.php.tpl
index 6538024..7ad3c7d 100644
--- a/src/ncc/Classes/PhpExtension/TemplateFiles/Program.php.tpl
+++ b/src/ncc/Classes/PhpExtension/Templates/Program.php.tpl
@@ -7,11 +7,12 @@
/**
* %ASSEMBLY.NAME% main entry point
*
- * @param string[] $args
- * @return void
+ * @param string[] $args Command-line arguments
+ * @return int Exit code
*/
- public static function main(array $args): void
+ public static function main(array $args): int
{
print("Hello World from %ASSEMBLY.PACKAGE%!" . PHP_EOL);
+ return 0;
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/PhpExtension/TemplateFiles/class.php.tpl b/src/ncc/Classes/PhpExtension/Templates/class.php.tpl
similarity index 100%
rename from src/ncc/Classes/PhpExtension/TemplateFiles/class.php.tpl
rename to src/ncc/Classes/PhpExtension/Templates/class.php.tpl
diff --git a/src/ncc/Classes/PhpExtension/Templates/main.php.tpl b/src/ncc/Classes/PhpExtension/Templates/main.php.tpl
new file mode 100644
index 0000000..f2f209e
--- /dev/null
+++ b/src/ncc/Classes/PhpExtension/Templates/main.php.tpl
@@ -0,0 +1,24 @@
+
+#include
+#include
+#include
+#include
+
+int main(int argc, char *argv[])
+{
+ // Get the program's file path
+ char programPath[PATH_MAX];
+ ssize_t pathLength = readlink("/proc/self/exe", programPath, sizeof(programPath) - 1);
+ if (pathLength == -1)
+ {
+ perror("readlink");
+ return 1;
+ }
+
+ programPath[pathLength] = '\0';
+
+ // Calculate the total length needed for the command string
+ size_t totalLength = snprintf(NULL, 0, "ncc exec --package=\"%s\" --exec-args", programPath);
+ for (int i = 1; i < argc; i++)
+ {
+ totalLength += snprintf(NULL, 0, " \"%s\"", argv[i]) + 1; // +1 for space or null terminator
+ }
+
+ // Allocate memory for the command string
+ char *command = (char *)malloc(totalLength + 1); // +1 for null terminator
+ if (command == NULL)
+ {
+ perror("malloc");
+ return 1;
+ }
+
+ // Construct the command to execute
+ snprintf(command, totalLength + 1, "ncc exec --package=\"%s\" --exec-args", programPath);
+ for (int i = 1; i < argc; i++)
+ {
+ snprintf(command + strlen(command), totalLength - strlen(command) + 1, " \"%s\"", argv[i]);
+ }
+
+ // Execute the ncc command
+ int result = system(command);
+ free(command);
+
+ if (result == -1)
+ {
+ perror("system");
+ return 1;
+ }
+
+ return WEXITSTATUS(result);
+}
diff --git a/src/ncc/Classes/PythonExtension/PythonRunner.php b/src/ncc/Classes/PythonExtension/PythonRunner.php
index f33ecbd..14ff51d 100644
--- a/src/ncc/Classes/PythonExtension/PythonRunner.php
+++ b/src/ncc/Classes/PythonExtension/PythonRunner.php
@@ -22,44 +22,47 @@
namespace ncc\Classes\PythonExtension;
+ use Exception;
+ use ncc\Classes\ExecutionUnitRunner;
use ncc\Exceptions\IOException;
- use ncc\Exceptions\PathNotFoundException;
+ use ncc\Exceptions\OperationException;
use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit;
- use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Utilities\IO;
+ use ncc\Utilities\PathFinder;
class PythonRunner implements RunnerInterface
{
-
/**
* @inheritDoc
- * @param string $path
- * @param ExecutionPolicy $policy
- * @return ExecutionUnit
* @throws IOException
- * @throws PathNotFoundException
+ * @throws OperationException
*/
- public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
+ public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
{
- $execution_unit = new ExecutionUnit();
+ $tmp = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $unit->getData()) . '.py';
+ IO::fwrite($tmp, $unit->getData(), 0777);
- if(!file_exists($path) && !is_file($path))
+ try
{
- throw new PathNotFoundException($path);
+ $process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
+ $process->run(static function($type, $buffer) use ($unit)
+ {
+ if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
+ {
+ print($buffer);
+ }
+ });
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException(sprintf('There was an error executing the python execution unit %s: %s', $unit->getExecutionPolicy()->getName(), $e->getMessage()), $e);
+ }
+ finally
+ {
+ unlink($tmp);
}
- $execution_unit->setExecutionPolicy($policy);
- $execution_unit->setData(IO::fread($path));
-
- return $execution_unit;
- }
-
- /**
- * @inheritDoc
- */
- public static function getFileExtension(): string
- {
- return '.py';
+ return $process->getExitCode();
}
}
\ No newline at end of file
diff --git a/src/ncc/Classes/Runtime.php b/src/ncc/Classes/Runtime.php
new file mode 100644
index 0000000..b22fe71
--- /dev/null
+++ b/src/ncc/Classes/Runtime.php
@@ -0,0 +1,257 @@
+getMetadata()->getMainExecutionPolicy()
+ );
+ }
+
+ if(is_string(self::$imported_packages[$package]))
+ {
+ $metadata_path = self::$imported_packages[$package] . DIRECTORY_SEPARATOR . FileDescriptor::METADATA;
+
+ if(!is_file($metadata_path))
+ {
+ throw new RuntimeException(sprintf('The package %s does not have a metadata file (is it corrupted?)', $package));
+ }
+
+ return ExecutionUnitRunner::executeFromSystem(
+ self::$imported_packages[$package],
+ Metadata::fromArray(ZiProto::decode(IO::fread($metadata_path)))->getMainExecutionPolicy()
+ );
+ }
+
+ throw new RuntimeException('Unable to execute the main execution point of the package, this is probably a bug');
+ }
+
+ /**
+ * @param string $package
+ * @param string $version
+ * @return string
+ * @throws ConfigurationException
+ * @throws IOException
+ * @throws ImportException
+ * @throws PathNotFoundException
+ */
+ public static function import(string $package, string $version=Versions::LATEST): string
+ {
+ if(self::isImported($package))
+ {
+ return $package;
+ }
+
+ if(is_file($package))
+ {
+ return self::importFromPackage(realpath($package));
+ }
+
+ if(self::getPackageManager()->getPackageLock()->entryExists($package))
+ {
+ return self::importFromSystem($package, $version);
+ }
+
+ throw new RuntimeException('Importing from a package name is not supported yet');
+ }
+
+ /**
+ * @param string $package
+ * @param string $version
+ * @return string
+ * @throws IOException
+ * @throws PathNotFoundException
+ */
+ private static function importFromSystem(string $package, string $version=Versions::LATEST): string
+ {
+ $entry = self::getPackageManager()->getPackageLock()->getEntry($package);
+
+ foreach($entry->getClassMap($version) as $class => $component_name)
+ {
+ $component_path = $entry->getPath($version) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . $component_name;
+ self::$class_map[strtolower($class)] = $component_path;
+ }
+
+ self::$imported_packages[$package] = $entry->getPath($version);
+
+ return $package;
+ }
+
+ /**
+ * Imports a package from a package file
+ *
+ * @param string $package_path
+ * @return string
+ * @throws ConfigurationException
+ * @throws ImportException
+ */
+ private static function importFromPackage(string $package_path): string
+ {
+ try
+ {
+ $package_reader = new PackageReader($package_path);
+ }
+ catch(Exception $e)
+ {
+ throw new RuntimeException(sprintf('Failed to import package from file "%s" due to an exception: %s', $package_path, $e->getMessage()), 0, $e);
+ }
+
+ // Check if the package is already imported
+ if(in_array($package_reader->getAssembly()->getPackage(), self::$imported_packages, true))
+ {
+ $package_name = $package_reader->getAssembly()->getPackage();
+ unset($package_reader);
+ return $package_name;
+ }
+
+ // Import the package
+ $package_name = $package_reader->getAssembly()->getPackage();
+ self::$imported_packages[$package_name] = $package_reader;
+
+ // Register the autoloader
+ foreach($package_reader->getClassMap() as $value)
+ {
+ self::$class_map[strtolower($value)] = static function() use ($value, $package_name)
+ {
+ return self::$imported_packages[$package_name]->getComponentByClass($value)->getData();
+ };
+ }
+
+ return $package_reader->getAssembly()->getPackage();
+ }
+
+ /**
+ * Determines if the package is already imported
+ *
+ * @param string $package
+ * @return bool
+ */
+ public static function isImported(string $package): bool
+ {
+ return isset(self::$imported_packages[$package]);
+ }
+
+ /**
+ * Returns an array of all the packages that is currently imported
+ *
+ * @return array
+ */
+ public static function getImportedPackages(): array
+ {
+ return array_keys(self::$imported_packages);
+ }
+
+ /**
+ * @param string $class
+ * @return void
+ */
+ public static function autoloadHandler(string $class): void
+ {
+ $class = strtolower($class);
+
+ if(!isset(self::$class_map[$class]))
+ {
+ return;
+ }
+
+ if(is_callable(self::$class_map[$class]))
+ {
+ eval(self::$class_map[$class]());
+ return;
+ }
+
+ if(is_string(self::$class_map[$class]) && is_file(self::$class_map[$class]))
+ {
+ require_once self::$class_map[$class];
+ return;
+ }
+ }
+
+ /**
+ * @return PackageManager
+ */
+ private static function getPackageManager(): PackageManager
+ {
+ if(self::$package_manager === null)
+ {
+ self::$package_manager = new PackageManager();
+ }
+
+ return self::$package_manager;
+ }
+ }
\ No newline at end of file
diff --git a/src/ncc/Enums/BuildOutputType.php b/src/ncc/Enums/BuildOutputType.php
index 46f5e1e..8cd636e 100644
--- a/src/ncc/Enums/BuildOutputType.php
+++ b/src/ncc/Enums/BuildOutputType.php
@@ -25,4 +25,5 @@
final class BuildOutputType
{
public const NCC_PACKAGE = 'ncc';
+ public const EXECUTABLE = 'executable';
}
\ No newline at end of file
diff --git a/src/ncc/Enums/ComponentDataType.php b/src/ncc/Enums/ComponentDataType.php
index 882681b..4507844 100644
--- a/src/ncc/Enums/ComponentDataType.php
+++ b/src/ncc/Enums/ComponentDataType.php
@@ -34,11 +34,6 @@
*/
public const PLAIN = 'plain';
- /**
- * Indicates whether the component is represented as bytecode
- */
- public const BYTECODE = 'bytecode';
-
/**
* Indicates whether the component is represented as binary or executable
*/
diff --git a/src/ncc/Enums/FileDescriptor.php b/src/ncc/Enums/FileDescriptor.php
new file mode 100644
index 0000000..b970281
--- /dev/null
+++ b/src/ncc/Enums/FileDescriptor.php
@@ -0,0 +1,34 @@
+setExecutionPolicy($policy);
- $execution_unit->setData(IO::fread($path));
-
- return $execution_unit;
- }
-
- /**
- * @inheritDoc
- */
- public static function getFileExtension(): string
- {
- return '.py';
- }
+ public const PHP_B64 = 'php_b64';
}
\ No newline at end of file
diff --git a/src/ncc/Enums/Flags/PackageFlags.php b/src/ncc/Enums/Flags/PackageFlags.php
new file mode 100644
index 0000000..69f6903
--- /dev/null
+++ b/src/ncc/Enums/Flags/PackageFlags.php
@@ -0,0 +1,34 @@
+setExecutionPolicy($policy);
- $execution_unit->setData(IO::fread($path));
+ public const DEPENDENCIES = 0x64657065;
- return $execution_unit;
- }
+ public const EXECUTION_UNITS = 0x65786563;
- /**
- * @inheritDoc
- */
- public static function getFileExtension(): string
- {
- return '.py';
- }
+ public const COMPONENTS = 0x636F6D70;
+
+ public const RESOURCES = 0x7265736F;
+
+ public const CLASS_POINTER = 0x636C6173;
}
\ No newline at end of file
diff --git a/src/ncc/Enums/Runners.php b/src/ncc/Enums/Runners.php
index ea2740f..5ca245a 100644
--- a/src/ncc/Enums/Runners.php
+++ b/src/ncc/Enums/Runners.php
@@ -30,10 +30,6 @@ namespace ncc\Enums;
public const PYTHON = 'python';
- public const PYTHON_3 = 'python3';
-
- public const PYTHON_2 = 'python2';
-
public const PERL = 'perl';
public const LUA = 'lua';
diff --git a/src/ncc/Enums/Versions.php b/src/ncc/Enums/Versions.php
index f1f0734..ab36472 100644
--- a/src/ncc/Enums/Versions.php
+++ b/src/ncc/Enums/Versions.php
@@ -1,24 +1,24 @@
isBigIntAsStr = $options->isBigIntAsStrMode();
- $this->isBigIntAsGmp = $options->isBigIntAsGmpMode();
+ $this->big_int_as_str = $options->isBigIntAsStrMode();
+ $this->big_int_as_gmp = $options->isBigIntAsGmpMode();
$this->buffer = $buffer;
}
@@ -94,7 +96,7 @@ namespace ncc\ZiProto;
* @param Extension $transformer
* @return BufferStream
*/
- public function registerTransformer(Extension $transformer) : self
+ public function registerTransformer(Extension $transformer): self
{
$this->transformers[$transformer->getType()] = $transformer;
return $this;
@@ -114,7 +116,7 @@ namespace ncc\ZiProto;
* @param string $buffer
* @return BufferStream
*/
- public function reset(string $buffer = '') : self
+ public function reset(string $buffer='') : self
{
$this->buffer = $buffer;
$this->offset = 0;
@@ -203,64 +205,61 @@ namespace ncc\ZiProto;
return $c - 0x100;
}
- switch ($c)
+ return match ($c)
{
- case 0xc0: return null;
- case 0xc2: return false;
- case 0xc3: return true;
+ 0xc0 => null,
+ 0xc2 => false,
+ 0xc3 => true,
// bin
- case 0xd9:
- case 0xc4: return $this->decodeStrData($this->decodeUint8());
- case 0xda:
- case 0xc5: return $this->decodeStrData($this->decodeUint16());
- case 0xdb:
- case 0xc6: return $this->decodeStrData($this->decodeUint32());
+ 0xd9, 0xc4 => $this->decodeStrData($this->decodeUint8()),
+ 0xda, 0xc5 => $this->decodeStrData($this->decodeUint16()),
+ 0xdb, 0xc6 => $this->decodeStrData($this->decodeUint32()),
// float
- case 0xca: return $this->decodeFloat32();
- case 0xcb: return $this->decodeFloat64();
+ 0xca => $this->decodeFloat32(),
+ 0xcb => $this->decodeFloat64(),
// uint
- case 0xcc: return $this->decodeUint8();
- case 0xcd: return $this->decodeUint16();
- case 0xce: return $this->decodeUint32();
- case 0xcf: return $this->decodeUint64();
+ 0xcc => $this->decodeUint8(),
+ 0xcd => $this->decodeUint16(),
+ 0xce => $this->decodeUint32(),
+ 0xcf => $this->decodeUint64(),
// int
- case 0xd0: return $this->decodeInt8();
- case 0xd1: return $this->decodeInt16();
- case 0xd2: return $this->decodeInt32();
- case 0xd3: return $this->decodeInt64();
+ 0xd0 => $this->decodeInt8(),
+ 0xd1 => $this->decodeInt16(),
+ 0xd2 => $this->decodeInt32(),
+ 0xd3 => $this->decodeInt64(),
// str
// array
- case 0xdc: return $this->decodeArrayData($this->decodeUint16());
- case 0xdd: return $this->decodeArrayData($this->decodeUint32());
+ 0xdc => $this->decodeArrayData($this->decodeUint16()),
+ 0xdd => $this->decodeArrayData($this->decodeUint32()),
// map
- case 0xde: return $this->decodeMapData($this->decodeUint16());
- case 0xdf: return $this->decodeMapData($this->decodeUint32());
+ 0xde => $this->decodeMapData($this->decodeUint16()),
+ 0xdf => $this->decodeMapData($this->decodeUint32()),
// ext
- case 0xd4: return $this->decodeExtData(1);
- case 0xd5: return $this->decodeExtData(2);
- case 0xd6: return $this->decodeExtData(4);
- case 0xd7: return $this->decodeExtData(8);
- case 0xd8: return $this->decodeExtData(16);
- case 0xc7: return $this->decodeExtData($this->decodeUint8());
- case 0xc8: return $this->decodeExtData($this->decodeUint16());
- case 0xc9: return $this->decodeExtData($this->decodeUint32());
- }
+ 0xd4 => $this->decodeExtData(1),
+ 0xd5 => $this->decodeExtData(2),
+ 0xd6 => $this->decodeExtData(4),
+ 0xd7 => $this->decodeExtData(8),
+ 0xd8 => $this->decodeExtData(16),
+ 0xc7 => $this->decodeExtData($this->decodeUint8()),
+ 0xc8 => $this->decodeExtData($this->decodeUint16()),
+ 0xc9 => $this->decodeExtData($this->decodeUint32()),
- throw DecodingFailedException::unknownCode($c);
+ default => throw DecodingFailedException::unknownCode($c), // Default case
+ };
}
/**
- * @return null
+ * @return void
*/
- public function decodeNil()
+ public function decodeNil(): void
{
if (!isset($this->buffer[$this->offset]))
{
@@ -270,7 +269,7 @@ namespace ncc\ZiProto;
if ("\xc0" === $this->buffer[$this->offset])
{
++$this->offset;
- return null;
+ return;
}
throw DecodingFailedException::unexpectedCode(ord($this->buffer[$this->offset++]), 'nil');
@@ -279,7 +278,7 @@ namespace ncc\ZiProto;
/**
* @return bool
*/
- public function decodeBool()
+ public function decodeBool(): bool
{
if (!isset($this->buffer[$this->offset]))
{
@@ -348,7 +347,7 @@ namespace ncc\ZiProto;
/**
* @return mixed
*/
- public function decodeFloat()
+ public function decodeFloat(): mixed
{
if (!isset($this->buffer[$this->offset]))
{
@@ -374,7 +373,7 @@ namespace ncc\ZiProto;
/**
* @return string
*/
- public function decodeStr()
+ public function decodeStr(): string
{
if (!isset($this->buffer[$this->offset]))
{
@@ -410,7 +409,7 @@ namespace ncc\ZiProto;
/**
* @return string
*/
- public function decodeBin()
+ public function decodeBin(): string
{
if (!isset($this->buffer[$this->offset]))
{
@@ -441,7 +440,7 @@ namespace ncc\ZiProto;
/**
* @return array
*/
- public function decodeArray()
+ public function decodeArray(): array
{
$size = $this->decodeArrayHeader();
$array = [];
@@ -457,7 +456,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- public function decodeArrayHeader()
+ public function decodeArrayHeader(): int
{
if (!isset($this->buffer[$this->offset]))
{
@@ -488,7 +487,7 @@ namespace ncc\ZiProto;
/**
* @return array
*/
- public function decodeMap()
+ public function decodeMap(): array
{
$size = $this->decodeMapHeader();
$map = [];
@@ -504,7 +503,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- public function decodeMapHeader()
+ public function decodeMapHeader(): int
{
if (!isset($this->buffer[$this->offset]))
{
@@ -535,7 +534,7 @@ namespace ncc\ZiProto;
/**
* @return mixed|Ext
*/
- public function decodeExt()
+ public function decodeExt(): mixed
{
if (!isset($this->buffer[$this->offset]))
{
@@ -563,7 +562,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- private function decodeUint8()
+ private function decodeUint8(): int
{
if (!isset($this->buffer[$this->offset]))
{
@@ -576,7 +575,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- private function decodeUint16()
+ private function decodeUint16(): int
{
if (!isset($this->buffer[$this->offset + 1]))
{
@@ -593,7 +592,7 @@ namespace ncc\ZiProto;
/**
* @return mixed
*/
- private function decodeUint32()
+ private function decodeUint32(): mixed
{
if (!isset($this->buffer[$this->offset + 3]))
{
@@ -625,7 +624,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- private function decodeInt8()
+ private function decodeInt8(): int
{
if (!isset($this->buffer[$this->offset]))
{
@@ -641,7 +640,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- private function decodeInt16()
+ private function decodeInt16(): int
{
if (!isset($this->buffer[$this->offset + 1]))
{
@@ -658,7 +657,7 @@ namespace ncc\ZiProto;
/**
* @return int
*/
- private function decodeInt32()
+ private function decodeInt32(): int
{
if (!isset($this->buffer[$this->offset + 3]))
{
@@ -674,7 +673,7 @@ namespace ncc\ZiProto;
/**
* @return mixed
*/
- private function decodeInt64()
+ private function decodeInt64(): mixed
{
if (!isset($this->buffer[$this->offset + 7]))
{
@@ -690,7 +689,7 @@ namespace ncc\ZiProto;
/**
* @return mixed
*/
- private function decodeFloat32()
+ private function decodeFloat32(): mixed
{
if (!isset($this->buffer[$this->offset + 3]))
{
@@ -706,7 +705,7 @@ namespace ncc\ZiProto;
/**
* @return mixed
*/
- private function decodeFloat64()
+ private function decodeFloat64(): mixed
{
if (!isset($this->buffer[$this->offset + 7]))
{
@@ -723,7 +722,7 @@ namespace ncc\ZiProto;
* @param $length
* @return string
*/
- private function decodeStrData($length)
+ private function decodeStrData($length): string
{
if (!isset($this->buffer[$this->offset + $length - 1]))
{
@@ -740,7 +739,7 @@ namespace ncc\ZiProto;
* @param $size
* @return array
*/
- private function decodeArrayData($size)
+ private function decodeArrayData($size): array
{
$array = [];
@@ -756,7 +755,7 @@ namespace ncc\ZiProto;
* @param $size
* @return array
*/
- private function decodeMapData($size)
+ private function decodeMapData($size): array
{
$map = [];
@@ -772,7 +771,7 @@ namespace ncc\ZiProto;
* @param $length
* @return mixed|Ext
*/
- private function decodeExtData($length)
+ private function decodeExtData($length): mixed
{
if (!isset($this->buffer[$this->offset + $length - 1]))
{
@@ -801,12 +800,12 @@ namespace ncc\ZiProto;
*/
private function handleIntOverflow($value)
{
- if ($this->isBigIntAsStr)
+ if ($this->big_int_as_str)
{
return sprintf('%u', $value);
}
- if ($this->isBigIntAsGmp)
+ if ($this->big_int_as_gmp)
{
return gmp_init(sprintf('%u', $value));
}
diff --git a/src/ncc/Extensions/ZiProto/DecodingOptions.php b/src/ncc/Extensions/ZiProto/DecodingOptions.php
index 347b2a1..58591a1 100644
--- a/src/ncc/Extensions/ZiProto/DecodingOptions.php
+++ b/src/ncc/Extensions/ZiProto/DecodingOptions.php
@@ -1,29 +1,32 @@
bigIntMode = Options::BIGINT_AS_STR;
+ $self->big_int_mode = Options::BIGINT_AS_STR;
return $self;
}
@@ -61,7 +64,7 @@ namespace ncc\ZiProto;
{
$self = new self();
- $self->bigIntMode = self::getSingleOption($bitmask,
+ $self->big_int_mode = self::getSingleOption($bitmask,
Options::BIGINT_AS_STR |
Options::BIGINT_AS_GMP |
Options::BIGINT_AS_EXCEPTION
@@ -75,7 +78,7 @@ namespace ncc\ZiProto;
*/
public function isBigIntAsStrMode() : bool
{
- return Options::BIGINT_AS_STR === $this->bigIntMode;
+ return Options::BIGINT_AS_STR === $this->big_int_mode;
}
/**
@@ -83,17 +86,17 @@ namespace ncc\ZiProto;
*/
public function isBigIntAsGmpMode() : bool
{
- return Options::BIGINT_AS_GMP === $this->bigIntMode;
+ return Options::BIGINT_AS_GMP === $this->big_int_mode;
}
/**
* @param int $bitmask
- * @param int $validBitmask
+ * @param int $valid_bitmask
* @return int
*/
- private static function getSingleOption(int $bitmask, int $validBitmask) : int
+ private static function getSingleOption(int $bitmask, int $valid_bitmask) : int
{
- $option = $bitmask & $validBitmask;
+ $option = $bitmask & $valid_bitmask;
if ($option === ($option & -$option))
{
return $option;
@@ -105,12 +108,14 @@ namespace ncc\ZiProto;
Options::BIGINT_AS_EXCEPTION => 'BIGINT_AS_EXCEPTION',
];
- $validOptions = [];
- for ($i = $validBitmask & -$validBitmask; $i <= $validBitmask; $i <<= 1)
+ $valid_options = [];
+
+ /** @noinspection SuspiciousLoopInspection */
+ for ($i = $valid_bitmask & -$valid_bitmask; $i <= $valid_bitmask; $i <<= 1)
{
- $validOptions[] = __CLASS__.'::'.$map[$i];
+ $valid_options[] = __CLASS__.'::'.$map[$i];
}
- throw InvalidOptionException::outOfRange('bigint', $validOptions);
+ throw InvalidOptionException::outOfRange('bigint', $valid_options);
}
}
diff --git a/src/ncc/Extensions/ZiProto/EncodingOptions.php b/src/ncc/Extensions/ZiProto/EncodingOptions.php
index c713ba4..5d42a30 100644
--- a/src/ncc/Extensions/ZiProto/EncodingOptions.php
+++ b/src/ncc/Extensions/ZiProto/EncodingOptions.php
@@ -1,29 +1,32 @@
strBinMode = Options::DETECT_STR_BIN;
- $self->arrMapMode = Options::DETECT_ARR_MAP;
- $self->floatMode = Options::FORCE_FLOAT64;
+
+ $self->str_bin_mode = Options::DETECT_STR_BIN;
+ $self->array_map_mode = Options::DETECT_ARR_MAP;
+ $self->float_mode = Options::FORCE_FLOAT64;
return $self;
}
@@ -74,7 +78,7 @@ namespace ncc\ZiProto;
if (self::getSingleOption('str/bin', $bitmask, Options::FORCE_STR | Options::FORCE_BIN | Options::DETECT_STR_BIN))
{
- $self->strBinMode = self::getSingleOption('str/bin', $bitmask,
+ $self->str_bin_mode = self::getSingleOption('str/bin', $bitmask,
Options::FORCE_STR |
Options::FORCE_BIN |
Options::DETECT_STR_BIN
@@ -82,12 +86,12 @@ namespace ncc\ZiProto;
}
else
{
- $self->strBinMode = Options::DETECT_STR_BIN;
+ $self->str_bin_mode = Options::DETECT_STR_BIN;
}
if (self::getSingleOption('arr/map', $bitmask, Options::FORCE_ARR | Options::FORCE_MAP | Options::DETECT_ARR_MAP))
{
- $self->arrMapMode = self::getSingleOption('arr/map', $bitmask,
+ $self->array_map_mode = self::getSingleOption('arr/map', $bitmask,
Options::FORCE_ARR |
Options::FORCE_MAP |
Options::DETECT_ARR_MAP
@@ -95,19 +99,19 @@ namespace ncc\ZiProto;
}
else
{
- $self->arrMapMode = Options::DETECT_ARR_MAP;
+ $self->array_map_mode = Options::DETECT_ARR_MAP;
}
if (self::getSingleOption('float', $bitmask, Options::FORCE_FLOAT32 | Options::FORCE_FLOAT64))
{
- $self->floatMode = self::getSingleOption('float', $bitmask,
+ $self->float_mode = self::getSingleOption('float', $bitmask,
Options::FORCE_FLOAT32 |
Options::FORCE_FLOAT64
);
}
else
{
- $self->floatMode = Options::FORCE_FLOAT64;
+ $self->float_mode = Options::FORCE_FLOAT64;
}
return $self;
@@ -118,7 +122,7 @@ namespace ncc\ZiProto;
*/
public function isDetectStrBinMode() : bool
{
- return Options::DETECT_STR_BIN === $this->strBinMode;
+ return Options::DETECT_STR_BIN === $this->str_bin_mode;
}
/**
@@ -126,7 +130,7 @@ namespace ncc\ZiProto;
*/
public function isForceStrMode() : bool
{
- return Options::FORCE_STR === $this->strBinMode;
+ return Options::FORCE_STR === $this->str_bin_mode;
}
/**
@@ -134,7 +138,7 @@ namespace ncc\ZiProto;
*/
public function isDetectArrMapMode() : bool
{
- return Options::DETECT_ARR_MAP === $this->arrMapMode;
+ return Options::DETECT_ARR_MAP === $this->array_map_mode;
}
/**
@@ -142,7 +146,7 @@ namespace ncc\ZiProto;
*/
public function isForceArrMode() : bool
{
- return Options::FORCE_ARR === $this->arrMapMode;
+ return Options::FORCE_ARR === $this->array_map_mode;
}
/**
@@ -150,18 +154,18 @@ namespace ncc\ZiProto;
*/
public function isForceFloat32Mode() : bool
{
- return Options::FORCE_FLOAT32 === $this->floatMode;
+ return Options::FORCE_FLOAT32 === $this->float_mode;
}
/**
* @param string $name
* @param int $bitmask
- * @param int $validBitmask
+ * @param int $valid_bitmask
* @return int
*/
- private static function getSingleOption(string $name, int $bitmask, int $validBitmask) : int
+ private static function getSingleOption(string $name, int $bitmask, int $valid_bitmask) : int
{
- $option = $bitmask & $validBitmask;
+ $option = $bitmask & $valid_bitmask;
if ($option === ($option & -$option))
{
@@ -179,13 +183,14 @@ namespace ncc\ZiProto;
Options::FORCE_FLOAT64 => 'FORCE_FLOAT64',
];
- $validOptions = [];
+ $valid_options = [];
- for ($i = $validBitmask & -$validBitmask; $i <= $validBitmask; $i <<= 1)
+ /** @noinspection SuspiciousLoopInspection */
+ for($i = $valid_bitmask & -$valid_bitmask; $i <= $valid_bitmask; $i <<= 1)
{
- $validOptions[] = __CLASS__.'::'.$map[$i];
+ $valid_options[] = __CLASS__.'::'.$map[$i];
}
- throw InvalidOptionException::outOfRange($name, $validOptions);
+ throw InvalidOptionException::outOfRange($name, $valid_options);
}
}
diff --git a/src/ncc/Extensions/ZiProto/Exception/DecodingFailedException.php b/src/ncc/Extensions/ZiProto/Exception/DecodingFailedException.php
index 79dc9ab..729ba77 100644
--- a/src/ncc/Extensions/ZiProto/Exception/DecodingFailedException.php
+++ b/src/ncc/Extensions/ZiProto/Exception/DecodingFailedException.php
@@ -1,26 +1,26 @@
value = $value;
@@ -55,7 +58,7 @@ namespace ncc\ZiProto\Exception;
/**
* @return mixed
*/
- public function getValue()
+ public function getValue(): mixed
{
return $this->value;
}
diff --git a/src/ncc/Extensions/ZiProto/Exception/InsufficientDataException.php b/src/ncc/Extensions/ZiProto/Exception/InsufficientDataException.php
index 29fc884..9d2af6c 100644
--- a/src/ncc/Extensions/ZiProto/Exception/InsufficientDataException.php
+++ b/src/ncc/Extensions/ZiProto/Exception/InsufficientDataException.php
@@ -1,26 +1,26 @@
2
- ? sprintf('one of %2$s or %1$s', array_pop($validOptions), implode(', ', $validOptions))
- : implode(' or ', $validOptions);
- return new self("Invalid option $invalidOption, use $use.");
+ $use = count($valid_options) > 2
+ ? sprintf('one of %2$s or %1$s', array_pop($valid_options), implode(', ', $valid_options))
+ : implode(' or ', $valid_options);
+ return new self("Invalid option $invalid_option, use $use.");
}
}
\ No newline at end of file
diff --git a/src/ncc/Extensions/ZiProto/Ext.php b/src/ncc/Extensions/ZiProto/Ext.php
index 76b4c9f..45ef9a0 100644
--- a/src/ncc/Extensions/ZiProto/Ext.php
+++ b/src/ncc/Extensions/ZiProto/Ext.php
@@ -1,45 +1,45 @@
type = $type;
$this->data = $data;
}
+
+ /**
+ * @return int
+ */
+ public function getType(): int
+ {
+ return $this->type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getData(): string
+ {
+ return $this->data;
+ }
}
\ No newline at end of file
diff --git a/src/ncc/Extensions/ZiProto/Packet.php b/src/ncc/Extensions/ZiProto/Packet.php
index 3db2473..4f86df7 100644
--- a/src/ncc/Extensions/ZiProto/Packet.php
+++ b/src/ncc/Extensions/ZiProto/Packet.php
@@ -1,27 +1,31 @@
isDetectStrBin = $options->isDetectStrBinMode();
- $this->isForceStr = $options->isForceStrMode();
- $this->isDetectArrMap = $options->isDetectArrMapMode();
- $this->isForceArr = $options->isForceArrMode();
- $this->isForceFloat32 = $options->isForceFloat32Mode();
+ $this->bin_mode = $options->isDetectStrBinMode();
+ $this->force_string = $options->isForceStrMode();
+ $this->detect_array_map = $options->isDetectArrMapMode();
+ $this->force_array = $options->isForceArrMode();
+ $this->force_float32 = $options->isForceFloat32Mode();
+ $this->transformers = [];
}
/**
+ * Registers a transformer.
+ *
* @param Validator $transformer
* @return Packet
*/
- public function registerTransformer(Validator $transformer) : self
+ public function registerTransformer(Validator $transformer): self
{
$this->transformers[] = $transformer;
-
return $this;
}
@@ -121,12 +129,12 @@ namespace ncc\ZiProto;
if (is_string($value))
{
- if ($this->isForceStr)
+ if ($this->force_string)
{
return $this->encodeStr($value);
}
- if ($this->isDetectStrBin)
+ if ($this->bin_mode)
{
return preg_match(Regex::UTF8_REGEX, $value)
? $this->encodeStr($value)
@@ -138,14 +146,14 @@ namespace ncc\ZiProto;
if (is_array($value))
{
- if ($this->isDetectArrMap)
+ if ($this->detect_array_map)
{
return array_values($value) === $value
? $this->encodeArray($value)
: $this->encodeMap($value);
}
- return $this->isForceArr ? $this->encodeArray($value) : $this->encodeMap($value);
+ return $this->force_array ? $this->encodeArray($value) : $this->encodeMap($value);
}
if (null === $value)
@@ -165,7 +173,12 @@ namespace ncc\ZiProto;
if ($value instanceof Ext)
{
- return $this->encodeExt($value->type, $value->data);
+ return $this->encodeExt($value->getType(), $value->getData());
+ }
+
+ if($value instanceof JsonSerializable)
+ {
+ return $this->encode($value->jsonSerialize());
}
if ($this->transformers)
@@ -259,7 +272,7 @@ namespace ncc\ZiProto;
*/
public function encodeFloat($float): string
{
- return $this->isForceFloat32
+ return $this->force_float32
? "\xca". pack('G', $float)
: "\xcb". pack('E', $float);
}
@@ -354,7 +367,7 @@ namespace ncc\ZiProto;
{
$data = $this->encodeMapHeader(count($map));
- if ($this->isForceStr)
+ if ($this->force_string)
{
foreach ($map as $key => $val)
{
@@ -365,7 +378,7 @@ namespace ncc\ZiProto;
return $data;
}
- if ($this->isDetectStrBin)
+ if ($this->bin_mode)
{
foreach ($map as $key => $val)
{
diff --git a/src/ncc/Extensions/ZiProto/Type/Binary.php b/src/ncc/Extensions/ZiProto/Type/Binary.php
index bb8b85d..e389d31 100644
--- a/src/ncc/Extensions/ZiProto/Type/Binary.php
+++ b/src/ncc/Extensions/ZiProto/Type/Binary.php
@@ -1,26 +1,29 @@
data = $data;
}
+
+ /**
+ * @return string
+ */
+ public function getData(): string
+ {
+ return $this->data;
+ }
}
\ No newline at end of file
diff --git a/src/ncc/Extensions/ZiProto/Type/Map.php b/src/ncc/Extensions/ZiProto/Type/Map.php
index 468b699..c6f731e 100644
--- a/src/ncc/Extensions/ZiProto/Type/Map.php
+++ b/src/ncc/Extensions/ZiProto/Type/Map.php
@@ -1,26 +1,29 @@
map = $map;
}
+
+ /**
+ * @return array
+ */
+ public function getMap(): array
+ {
+ return $this->map;
+ }
}
\ No newline at end of file
diff --git a/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php b/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php
index 54d2f34..2f2c28e 100644
--- a/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php
+++ b/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php
@@ -1,29 +1,29 @@
encodeBin($value->data);
+ return $packer->encodeBin($value->getData());
}
return null;
diff --git a/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php b/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php
index dffa49a..5235f1a 100644
--- a/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php
+++ b/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php
@@ -1,28 +1,28 @@
encodeMap($value->map);
+ return $packer->encodeMap($value->getMap());
}
return null;
diff --git a/src/ncc/Extensions/ZiProto/TypeTransformer/Validator.php b/src/ncc/Extensions/ZiProto/TypeTransformer/Validator.php
index a0fbc6d..e2cb9b6 100644
--- a/src/ncc/Extensions/ZiProto/TypeTransformer/Validator.php
+++ b/src/ncc/Extensions/ZiProto/TypeTransformer/Validator.php
@@ -1,28 +1,28 @@
encode($value);
+ try
+ {
+ return (new Packet($options))->encode($value);
+ }
+ catch(Exception $e)
+ {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
}
/**
+ * Decodes the given msgpack string.
+ *
* @param string $data
- * @param DecodingOptions|int|null $options
- *
- * @throws InvalidOptionException
- * @throws DecodingFailedException
- *
- * @return mixed
+ * @param int|null $options
+ * @see DecodingOptions
+ * @return array|bool|int|mixed|Ext|resource|string|null
*/
- public static function decode(string $data, $options = null)
+ public static function decode(string $data, ?int $options=null): mixed
{
- return (new BufferStream($data, $options))->decode();
+ try
+ {
+ return (new BufferStream($data, $options))->decode();
+ }
+ catch(Exception $e)
+ {
+ throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
+ }
}
}
\ No newline at end of file
diff --git a/src/ncc/Interfaces/CompilerInterface.php b/src/ncc/Interfaces/CompilerInterface.php
index 71f3dff..ea2674a 100644
--- a/src/ncc/Interfaces/CompilerInterface.php
+++ b/src/ncc/Interfaces/CompilerInterface.php
@@ -26,6 +26,7 @@
use ncc\Exceptions\BuildException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
+ use ncc\Managers\ProjectManager;
use ncc\Objects\Package;
use ncc\Objects\ProjectConfiguration;
@@ -34,60 +35,15 @@
/**
* Public constructor
*
- * @param ProjectConfiguration $project
- * @param string $path
+ * @param ProjectManager $project_manager
*/
- public function __construct(ProjectConfiguration $project, string $path);
+ public function __construct(ProjectManager $project_manager);
/**
- * Prepares the package for the build process, this method is called before build()
+ * Builds the project and returns the path to the built package
*
- * @param string $build_configuration The build configuration to use to build the project
- * @return void
+ * @param string $build_configuration
+ * @return string
*/
- public function prepare(string $build_configuration=BuildConfigurationValues::DEFAULT): void;
-
- /**
- * Executes the compiler process in the correct order and returns the finalized Package object
- *
- * @return Package|null
- * @throws BuildException
- * @throws PathNotFoundException
- * @throws IOException
- */
- public function build(): ?Package;
-
- /**
- * Compiles the components of the package
- *
- * @return void
- * @throws PathNotFoundException
- * @throws IOException
- */
- public function compileComponents(): void;
-
- /**
- * Compiles the resources of the package
- *
- * @return void
- * @throws PathNotFoundException
- * @throws IOException
- */
- public function compileResources(): void;
-
- /**
- * Compiles the execution policies of the package
- *
- * @return void
- * @throws PathNotFoundException
- * @throws IOException
- */
- public function compileExecutionPolicies(): void;
-
- /**
- * Returns the current state of the package
- *
- * @return Package|null
- */
- public function getPackage(): ?Package;
+ public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string;
}
\ No newline at end of file
diff --git a/src/ncc/Interfaces/RunnerInterface.php b/src/ncc/Interfaces/RunnerInterface.php
index c6c5511..5ae1f66 100644
--- a/src/ncc/Interfaces/RunnerInterface.php
+++ b/src/ncc/Interfaces/RunnerInterface.php
@@ -29,19 +29,12 @@
interface RunnerInterface
{
/**
- * Processes the ExecutionPolicy
+ * Executes the unit and returns the exit code of the process
*
- * @param string $path
- * @param ExecutionPolicy $policy
- * @return ExecutionUnit
- * @throws IOException
+ * @param ExecutionUnit $unit The execution unit to execute
+ * @param array $args The arguments to pass to the execution unit
+ * @param bool $local Whether to execute the execution unit locally on disk or from a memory buffer
+ * @return int The exit code of the process
*/
- public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit;
-
- /**
- * Returns the file extension to use for the target file
- *
- * @return string
- */
- public static function getFileExtension(): string;
+ public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int;
}
\ No newline at end of file
diff --git a/src/ncc/Managers/CredentialManager.php b/src/ncc/Managers/CredentialManager.php
index 6a7a9da..6c219ab 100644
--- a/src/ncc/Managers/CredentialManager.php
+++ b/src/ncc/Managers/CredentialManager.php
@@ -36,7 +36,7 @@
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class CredentialManager
{
diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php
index cb410ee..6812de7 100644
--- a/src/ncc/Managers/ExecutionPointerManager.php
+++ b/src/ncc/Managers/ExecutionPointerManager.php
@@ -51,7 +51,7 @@
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
use RuntimeException;
class ExecutionPointerManager
diff --git a/src/ncc/Managers/PackageLockManager.php b/src/ncc/Managers/PackageLockManager.php
index 80fe8ac..321d7e0 100644
--- a/src/ncc/Managers/PackageLockManager.php
+++ b/src/ncc/Managers/PackageLockManager.php
@@ -34,7 +34,7 @@
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class PackageLockManager
{
diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php
index 28f17fc..e2e725f 100644
--- a/src/ncc/Managers/PackageManager.php
+++ b/src/ncc/Managers/PackageManager.php
@@ -1,4 +1,7 @@
packages_path = PathFinder::getPackagesPath(Scopes::SYSTEM);
- $this->package_lock_manager = new PackageLockManager();
- $this->package_lock_manager->load();
+ if(file_exists(PathFinder::getPackageLock()))
+ {
+ $this->package_lock = PackageLock::fromArray(ZiProto::decode(IO::fread(PathFinder::getPackageLock())));
+ }
+ else
+ {
+ $this->package_lock = new PackageLock();
+ }
}
/**
- * Installs a local package onto the system
+ * Installs a package from an ncc package file
*
- * @param string $package_path
- * @param Entry|null $entry
- * @param array $options
- * @return string
- * @throws AuthenticationException
- * @throws IOException
- * @throws NotSupportedException
- * @throws OperationException
- * @throws PackageException
- * @throws PathNotFoundException
+ * @param string $file_path
+ * @return void
* @throws ConfigurationException
+ * @throws IOException
+ * @throws PathNotFoundException
*/
- public function install(string $package_path, ?Entry $entry=null, array $options=[]): string
+ public function installPackage(string $file_path): void
{
- if(Resolver::resolveScope() !== Scopes::SYSTEM)
+ $package_reader = new PackageReader($file_path);
+
+ if($this->package_lock->entryExists($package_reader->getAssembly()->getPackage()))
{
- throw new AuthenticationException('Insufficient permission to install packages');
- }
+ $package_entry = $this->package_lock->getEntry($package_reader->getAssembly()->getPackage());
- if(!file_exists($package_path) || !is_file($package_path) || !is_readable($package_path))
- {
- throw new PathNotFoundException($package_path);
- }
-
- $package = Package::load($package_path);
-
- if(RuntimeCache::get(sprintf('installed.%s=%s', $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion())))
- {
- Console::outDebug(sprintf('skipping installation of %s=%s, already processed', $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()));
- return $package->getAssembly()->getPackage();
- }
-
- $extension = $package->getMetadata()->getCompilerExtension()->getExtension();
- $installation_paths = new InstallationPaths($this->packages_path . DIRECTORY_SEPARATOR . $package->getAssembly()->getPackage() . '=' . $package->getAssembly()->getVersion());
-
- $installer = match ($extension)
- {
- CompilerExtensions::PHP => new PhpInstaller($package),
- default => throw new NotSupportedException(sprintf('Compiler extension %s is not supported with ncc', $extension))
- };
-
- if($this->getPackageVersion($package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()) !== null)
- {
- if(in_array(InstallPackageOptions::REINSTALL, $options, true))
+ if($package_entry->versionExists($package_reader->getAssembly()->getVersion()))
{
- if($this->getPackageLockManager()?->getPackageLock()?->packageExists($package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()))
- {
- $this->getPackageLockManager()?->getPackageLock()?->removePackageVersion(
- $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()
- );
- }
- }
- else
- {
- throw new PackageException('The package ' . $package->getAssembly()->getPackage() . '=' . $package->getAssembly()->getVersion() . ' is already installed');
+ throw new ConfigurationException(sprintf(
+ 'Package "%s" version "%s" is already installed',
+ $package_reader->getAssembly()->getPackage(),
+ $package_reader->getAssembly()->getVersion()
+ ));
}
}
- $execution_pointer_manager = new ExecutionPointerManager();
- PackageCompiler::compilePackageConstants($package, [
- ConstantReferences::INSTALL => $installation_paths
- ]);
-
- // Process all the required dependencies before installing the package
- if(count($package->getDependencies()) > 0 && !in_array(InstallPackageOptions::SKIP_DEPENDENCIES, $options, true))
- {
- foreach($package->getDependencies() as $dependency)
- {
- // Uninstall the dependency if the option Reinstall is passed on
- if(in_array(InstallPackageOptions::REINSTALL, $options, true) && $this->getPackageLockManager()?->getPackageLock()?->packageExists($dependency->getName(), $dependency->getVersion()))
- {
- if($dependency->getVersion() === 'latest')
- {
- $this->uninstallPackage($dependency->getName());
- }
- else
- {
- $this->uninstallPackageVersion($dependency->getName(), $dependency->getVersion());
- }
- }
-
- $this->processDependency($dependency, $package, $package_path, $entry, $options);
- }
- }
-
- Console::outVerbose(sprintf('Installing %s', $package_path));
-
- if(Resolver::checkLogLevel(LogLevel::DEBUG, Main::getLogLevel()))
- {
- Console::outDebug(sprintf('installer.install_path: %s', $installation_paths->getInstallationpath()));
- Console::outDebug(sprintf('installer.data_path: %s', $installation_paths->getDataPath()));
- Console::outDebug(sprintf('installer.bin_path: %s', $installation_paths->getBinPath()));
- Console::outDebug(sprintf('installer.src_path: %s', $installation_paths->getSourcePath()));
-
- foreach($package->getAssembly()->toArray() as $prop => $value)
- {
- Console::outDebug(sprintf('assembly.%s: %s', $prop, ($value ?? 'n/a')));
- }
-
- foreach($package->getMetadata()->getCompilerExtension()->toArray() as $prop => $value)
- {
- Console::outDebug(sprintf('header.compiler.%s: %s', $prop, ($value ?? 'n/a')));
- }
- }
-
- Console::out('Installing ' . $package->getAssembly()->getPackage());
-
- // Four For Directory Creation, preInstall, postInstall & initData methods
- $steps = (4 + count($package->getComponents()) + count ($package->getResources()) + count ($package->getExecutionUnits()));
-
- // Include the Execution units
- if($package->getInstaller()?->getPreInstall() !== null)
- {
- $steps += count($package->getInstaller()?->getPreInstall());
- }
-
- if($package->getInstaller()?->getPostInstall()!== null)
- {
- $steps += count($package->getInstaller()->getPostInstall());
- }
-
- $current_steps = 0;
$filesystem = new Filesystem();
+ $package_path = PathFinder::getPackagesPath() . DIRECTORY_SEPARATOR . sprintf(
+ '%s=%s', $package_reader->getAssembly()->getPackage(), $package_reader->getAssembly()->getVersion()
+ );
try
{
- $filesystem->mkdir($installation_paths->getInstallationpath(), 0755);
- $filesystem->mkdir($installation_paths->getBinPath(), 0755);
- $filesystem->mkdir($installation_paths->getDataPath(), 0755);
- $filesystem->mkdir($installation_paths->getSourcePath(), 0755);
+ if($filesystem->exists($package_path))
+ {
+ $filesystem->remove($package_path);
+ }
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
+ $this->extractPackageContents($package_reader, $package_path);
}
catch(Exception $e)
{
- throw new IOException('Error while creating directory, ' . $e->getMessage(), $e);
+ $filesystem->remove($package_path);
+ unset($package_reader);
+ throw new IOException(sprintf('Failed to extract package contents due to an exception: %s', $e->getMessage()), $e);
}
try
{
- Console::outDebug(sprintf('saving shadow package to %s', $installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg'));
-
- self::initData($package, $installation_paths);
- $package->save($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg');
- ++$current_steps;
-
- Console::inlineProgressBar($current_steps, $steps);
+ $this->package_lock->addPackage($package_reader);
}
catch(Exception $e)
{
- throw new OperationException('Cannot initialize package install, ' . $e->getMessage(), $e);
+ $filesystem->remove($package_path);
+ $this->loadLock();
+ unset($package_reader);
+ throw new IOException(sprintf('Failed to add package to package lock file due to an exception: %s', $e->getMessage()), $e);
}
- // Execute the pre-installation stage before the installation stage
- try
- {
- $installer->preInstall($installation_paths);
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
- }
- catch (Exception $e)
- {
- throw new OperationException('Pre installation stage failed, ' . $e->getMessage(), $e);
- }
-
- if($package->getInstaller()?->getPreInstall() !== null && count($package->getInstaller()->getPreInstall()) > 0)
- {
- foreach($package->getInstaller()->getPreInstall() as $unit_name)
- {
- try
- {
- $execution_pointer_manager->temporaryExecute($package, $unit_name);
- }
- catch(Exception $e)
- {
- Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage());
- }
-
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
- }
- }
-
- // Process & Install the components
- foreach($package->getComponents() as $component)
- {
- Console::outDebug(sprintf('processing component %s (%s)', $component->getName(), $component->getDataType()));
-
- try
- {
- $data = $installer->processComponent($component);
- if($data !== null)
- {
- $component_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $component->getName();
- $component_dir = dirname($component_path);
-
- if(!$filesystem->exists($component_dir))
- {
- $filesystem->mkdir($component_dir);
- }
-
- IO::fwrite($component_path, $data);
- }
- }
- catch(Exception $e)
- {
- throw new OperationException('Cannot process one or more components, ' . $e->getMessage(), $e);
- }
-
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
- }
-
- // Process & Install the resources
- foreach($package->getResources() as $resource)
- {
- Console::outDebug(sprintf('processing resource %s', $resource->getName()));
-
- try
- {
- $data = $installer->processResource($resource);
- if($data !== null)
- {
- $resource_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $resource->getName();
- $resource_dir = dirname($resource_path);
-
- if(!$filesystem->exists($resource_dir))
- {
- $filesystem->mkdir($resource_dir);
- }
-
- IO::fwrite($resource_path, $data);
- }
- }
- catch(Exception $e)
- {
- throw new OperationException('Cannot process one or more resources, ' . $e->getMessage(), $e);
- }
-
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
- }
-
- // Install execution units
- if($package->getExecutionUnits() !== null && count($package->getExecutionUnits()) > 0)
- {
- Console::outDebug('package contains execution units, processing');
-
- $execution_pointer_manager = new ExecutionPointerManager();
- $unit_paths = [];
-
- /** @var Package\ExecutionUnit $executionUnit */
- foreach($package->getExecutionUnits() as $executionUnit)
- {
- Console::outDebug(sprintf('processing execution unit %s', $executionUnit->getExecutionPolicy()->getName()));
- $execution_pointer_manager->addUnit($package->getAssembly()->getPackage(), $package->getAssembly()->getVersion(), $executionUnit);
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
- }
-
- IO::fwrite($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'exec', ZiProto::encode($unit_paths));
- }
- else
- {
- Console::outDebug('package does not contain execution units, skipping');
- }
-
- // After execution units are installed, create a symlink if needed
- if(!is_null($package->getMetadata()->getOption('create_symlink')) && $package->getMetadata()->getOption('create_symlink'))
- {
- if($package->getMainExecutionPolicy() === null)
- {
- throw new OperationException('Cannot create symlink, no main execution policy is defined');
- }
-
- Console::outDebug(sprintf('creating symlink to %s', $package->getAssembly()->getPackage()));
-
- $SymlinkManager = new SymlinkManager();
- $SymlinkManager->add($package->getAssembly()->getPackage(), $package->getMainExecutionPolicy());
- }
-
- // Execute the post-installation stage after the installation is complete
- try
- {
- Console::outDebug('executing post-installation stage');
-
- $installer->postInstall($installation_paths);
- ++$current_steps;
-
- Console::inlineProgressBar($current_steps, $steps);
- }
- catch (Exception $e)
- {
- throw new OperationException('Post installation stage failed, ' . $e->getMessage(), $e);
- }
-
- if($package->getInstaller()?->getPostInstall() !== null && count($package->getInstaller()->getPostInstall()) > 0)
- {
- Console::outDebug('executing post-installation units');
-
- foreach($package->getInstaller()->getPostInstall() as $unit_name)
- {
- try
- {
- $execution_pointer_manager->temporaryExecute($package, $unit_name);
- }
- catch(Exception $e)
- {
- Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage());
- }
- finally
- {
- ++$current_steps;
- Console::inlineProgressBar($current_steps, $steps);
- }
- }
- }
- else
- {
- Console::outDebug('no post-installation units to execute');
- }
-
- if($package->getMetadata()->getUpdateSource()?->getRepository() !== null)
- {
- $sources_manager = new RemoteSourcesManager();
- if($sources_manager->getRemoteSource($package->getMetadata()->getUpdateSource()->getRepository()->getName()) === null)
- {
- Console::outVerbose('Adding remote source ' . $package->getMetadata()->getUpdateSource()->getRepository()->getName());
-
- $defined_remote_source = new DefinedRemoteSource();
- $defined_remote_source->setName($package->getMetadata()->getUpdateSource()?->getRepository()?->getName());
- $defined_remote_source->setHost($package->getMetadata()->getUpdateSource()?->getRepository()?->getHost());
- $defined_remote_source->setType($package->getMetadata()->getUpdateSource()?->getRepository()?->getType());
- $defined_remote_source->setSsl($package->getMetadata()->getUpdateSource()?->getRepository()?->isSsl());
-
- $sources_manager->addRemoteSource($defined_remote_source);
- }
- }
-
- $this->getPackageLockManager()?->getPackageLock()?->addPackage($package, $installation_paths->getInstallationpath());
- $this->getPackageLockManager()?->save();
-
- RuntimeCache::set(sprintf('installed.%s=%s', $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()), true);
-
- return $package->getAssembly()->getPackage();
+ $this->saveLock();
}
/**
- * @param string $source
- * @param Entry|null $entry
- * @return string
- * @throws NotSupportedException
- * @throws OperationException
- * @throws PackageException
- */
- public function fetchFromSource(string $source, ?Entry $entry=null): string
- {
- $input = new RemotePackageInput($source);
-
- if($input->getSource() === null)
- {
- throw new PackageException('No source specified');
- }
-
- if($input->getVersion() === null)
- {
- $input->setVersion(Versions::LATEST);
- }
-
- Console::outVerbose('Fetching package ' . $input->getPackage() . ' from ' . $input->getSource() . ' (' . $input->getVersion() . ')');
-
- $remote_source_type = Resolver::detectRemoteSourceType($input->getSource());
- if($remote_source_type === RemoteSourceType::BUILTIN)
- {
- Console::outDebug('using builtin source ' . $input->getSource());
-
- if ($input->getSource() === 'composer')
- {
- try
- {
- return ComposerSourceBuiltin::fetch($input);
- }
- catch (Exception $e)
- {
- throw new PackageException('Cannot fetch package from composer source, ' . $e->getMessage(), $e);
- }
- }
-
- throw new NotSupportedException(sprintf('Builtin source %s is not supported', $input->getSource()));
- }
-
- if($remote_source_type === RemoteSourceType::DEFINED)
- {
- Console::outDebug('using defined source ' . $input->getSource());
- /** @noinspection CallableParameterUseCaseInTypeContextInspection */
- $source = (new RemoteSourcesManager())->getRemoteSource($input->getSource());
- if($source === null)
- {
- throw new OperationException('Remote source ' . $input->getSource() . ' is not defined');
- }
-
- $repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry);
- $exceptions = [];
-
- if($repositoryQueryResults->getFiles()->ZipballUrl !== null)
- {
- try
- {
- Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->ZipballUrl));
- $archive = Functions::downloadGitServiceFile($repositoryQueryResults->getFiles()->ZipballUrl, $entry);
- return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->getVersion());
- }
- catch(Throwable $e)
- {
- Console::outDebug('cannot fetch package from zipball url, ' . $e->getMessage());
- $exceptions[] = $e;
- }
- }
-
- if($repositoryQueryResults->getFiles()->TarballUrl !== null)
- {
- try
- {
- Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->TarballUrl));
- $archive = Functions::downloadGitServiceFile($repositoryQueryResults->getFiles()->TarballUrl, $entry);
- return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->getVersion());
- }
- catch(Exception $e)
- {
- Console::outDebug('cannot fetch package from tarball url, ' . $e->getMessage());
- $exceptions[] = $e;
- }
- }
-
- if($repositoryQueryResults->getFiles()->PackageUrl !== null)
- {
- try
- {
- Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->PackageUrl));
- return Functions::downloadGitServiceFile($repositoryQueryResults->getFiles()->PackageUrl, $entry);
- }
- catch(Exception $e)
- {
- Console::outDebug('cannot fetch package from package url, ' . $e->getMessage());
- $exceptions[] = $e;
- }
- }
-
- if($repositoryQueryResults->getFiles()->GitHttpUrl !== null || $repositoryQueryResults->getFiles()->GitSshUrl !== null)
- {
- try
- {
- Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->GitHttpUrl ?? $repositoryQueryResults->getFiles()->GitSshUrl));
- $git_repository = GitClient::cloneRepository($repositoryQueryResults->getFiles()->GitHttpUrl ?? $repositoryQueryResults->getFiles()->GitSshUrl);
-
- foreach(GitClient::getTags($git_repository) as $tag)
- {
- if(VersionComparator::compareVersion($tag, $repositoryQueryResults->getVersion()) === 0)
- {
- GitClient::checkout($git_repository, $tag);
- return PackageCompiler::tryCompile($git_repository, $repositoryQueryResults->getVersion());
- }
- }
-
- Console::outDebug('cannot fetch package from git repository, no matching tag found');
- }
- catch(Exception $e)
- {
- Console::outDebug('cannot fetch package from git repository, ' . $e->getMessage());
- $exceptions[] = $e;
- }
- }
-
- // Recursively create an exception with the previous exceptions as the previous exception
- $exception = null;
-
- if(count($exceptions) > 0)
- {
- foreach($exceptions as $e)
- {
- if($exception === null)
- {
- $exception = new PackageException($e->getMessage(), $e);
- }
- else
- {
- if($e->getMessage() === $exception->getMessage())
- {
- continue;
- }
-
- $exception = new PackageException($e->getMessage(), $exception);
- }
- }
- }
- else
- {
- $exception = new PackageException('Cannot fetch package from remote source, no assets found');
- }
-
- throw $exception;
- }
-
- throw new PackageException(sprintf('Unknown remote source type %s', $remote_source_type));
- }
-
- /**
- * Installs a package from a source syntax (vendor/package=version@source)
+ * Returns the package lock object
*
- * @param string $source
- * @param Entry|null $entry
- * @param array $options
- * @return string
- * @throws OperationException
+ * @return PackageLock
*/
- public function installFromSource(string $source, ?Entry $entry, array $options=[]): string
+ public function getPackageLock(): PackageLock
{
- try
- {
- Console::outVerbose(sprintf('Installing package from source %s', $source));
-
- $package = $this->fetchFromSource($source, $entry);
- return $this->install($package, $entry, $options);
- }
- catch(Exception $e)
- {
- throw new OperationException('Cannot install package from source, ' . $e->getMessage(), $e);
- }
+ return $this->package_lock;
}
/**
- * @param Dependency $dependency
- * @param Package $package
+ * Extracts the contents of a package to the specified path
+ *
+ * @param PackageReader $package_reader
* @param string $package_path
- * @param Entry|null $entry
- * @param array $options
* @return void
- * @throws AuthenticationException
- * @throws IOException
- * @throws NotSupportedException
- * @throws OperationException
- * @throws PackageException
- * @throws PathNotFoundException
* @throws ConfigurationException
- */
- private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null, array $options=[]): void
- {
- if(RuntimeCache::get(sprintf('dependency_installed.%s=%s', $dependency->getName(), $dependency->getVersion())))
- {
- Console::outDebug(sprintf('dependency %s=%s already processed, skipping', $dependency->getName(), $dependency->getVersion()));
- return;
- }
-
- Console::outVerbose('processing dependency ' . $dependency->getVersion() . ' (' . $dependency->getVersion() . ')');
- $dependent_package = $this->getPackage($dependency->getName());
- $dependency_met = false;
-
- if ($dependent_package !== null && $dependency->getVersion() !== null && Validate::version($dependency->getVersion()))
- {
- Console::outDebug('dependency has version constraint, checking if package is installed');
- $dependent_version = $this->getPackageVersion($dependency->getName(), $dependency->getVersion());
- if ($dependent_version !== null)
- {
- $dependency_met = true;
- }
- }
- elseif ($dependent_package !== null && $dependency->getVersion() === null)
- {
- Console::outDebug(sprintf('dependency %s has no version specified, assuming dependency is met', $dependency->getName()));
- $dependency_met = true;
- }
-
- Console::outDebug('dependency met: ' . ($dependency_met ? 'true' : 'false'));
-
- if ($dependency->getSourceType() !== null && !$dependency_met)
- {
- Console::outVerbose(sprintf('Installing dependency %s=%s for %s=%s', $dependency->getName(), $dependency->getVersion(), $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()));
- switch ($dependency->getSourceType())
- {
- case DependencySourceType::LOCAL:
- Console::outDebug('installing from local source ' . $dependency->getSource());
- $basedir = dirname($package_path);
-
- if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->getSourceType()))
- {
- throw new PathNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->getSource());
- }
-
- $this->install($basedir . DIRECTORY_SEPARATOR . $dependency->getSource(), null, $options);
- RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->getName(), $dependency->getVersion()), true);
- break;
-
- case DependencySourceType::STATIC:
- throw new PackageException('Static linking not possible, package ' . $dependency->getName() . ' is not installed');
-
- case DependencySourceType::REMOTE:
- Console::outDebug('installing from remote source ' . $dependency->getSource());
- $this->installFromSource($dependency->getSource(), $entry, $options);
- RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->getName(), $dependency->getVersion()), true);
- break;
-
- default:
- throw new NotSupportedException(sprintf('Dependency source type %s is not supported', $dependency->getSourceType()));
- }
- }
- elseif(!$dependency_met)
- {
- throw new PackageException(sprintf('Required dependency %s=%s is not installed', $dependency->getName(), $dependency->getVersion()));
- }
- }
-
- /**
- * Returns an existing package entry, returns null if no such entry exists
- *
- * @param string $package
- * @return PackageEntry|null
* @throws IOException
*/
- public function getPackage(string $package): ?PackageEntry
+ private function extractPackageContents(PackageReader $package_reader, string $package_path): void
{
- Console::outDebug('getting package ' . $package);
- return $this->getPackageLockManager()?->getPackageLock()?->getPackage($package);
- }
+ $bin_path = $package_path . DIRECTORY_SEPARATOR . 'bin';
- /**
- * Returns an existing version entry, returns null if no such entry exists
- *
- * @param string $package
- * @param string $version
- * @return VersionEntry|null
- * @throws IOException
- */
- public function getPackageVersion(string $package, string $version): ?VersionEntry
- {
- Console::outDebug('getting package version ' . $package . '=' . $version);
- return $this->getPackage($package)?->getVersion($version);
- }
-
- /**
- * Returns the latest version of the package, or null if there is no entry
- *
- * @param string $package
- * @return VersionEntry|null
- * @throws IOException
- */
- public function getLatestVersion(string $package): ?VersionEntry
- {
- Console::outDebug('getting latest version of package ' . $package);
- return $this->getPackage($package)?->getVersion($this->getPackage($package)?->getLatestVersion());
- }
-
- /**
- * Returns an array of all packages and their installed versions
- *
- * @return array
- * @throws IOException
- */
- public function getInstalledPackages(): array
- {
- return $this->getPackageLockManager()?->getPackageLock()?->getPackages() ?? [];
- }
-
- /**
- * Returns a package tree representation
- *
- * @param array $tree
- * @param string|null $package
- * @return array
- */
- public function getPackageTree(array $tree=[], ?string $package=null): array
- {
- // First build the packages to scan first
- $packages = [];
- if($package !== null)
+ foreach($package_reader->getComponents() as $component_name)
{
- // If it's coming from a selected package, query the package and process its dependencies
- $exploded = explode('=', $package);
- try
- {
- /** @noinspection CallableParameterUseCaseInTypeContextInspection */
- $package = $this->getPackage($exploded[0]);
- if($package === null)
- {
- throw new PackageException('Package ' . $exploded[0] . ' not found');
- }
-
- $version = $package->getVersion($exploded[1]);
- if($version === null)
- {
- throw new OperationException('Version ' . $exploded[1] . ' not found for package ' . $exploded[0]);
- }
-
- foreach ($version->getDependencies() as $dependency)
- {
- if(!in_array($dependency->getPackageName() . '=' . $dependency->getVersion(), $tree, true))
- {
- $packages[] = $dependency->getPackageName() . '=' . $dependency->getVersion();
- }
- }
- }
- catch(Exception $e)
- {
- unset($e);
- }
-
- }
- else
- {
- // If it's coming from nothing, start with the installed packages on the system
- try
- {
- foreach ($this->getInstalledPackages() as $installed_package => $versions)
- {
- foreach ($versions as $version)
- {
- if (!in_array($installed_package . '=' . $version, $packages, true))
- {
- $packages[] = $installed_package . '=' . $version;
- }
- }
- }
- }
- catch (IOException $e)
- {
- unset($e);
- }
+ IO::fwrite(
+ $bin_path . DIRECTORY_SEPARATOR . $component_name,
+ $package_reader->getComponent($component_name)->getData([ComponentDecodeOptions::AS_FILE]), 0755
+ );
}
- // Go through each package
- foreach($packages as $package_iter)
+ foreach($package_reader->getResources() as $resource_name)
{
- $package_e = explode('=', $package_iter);
- try
- {
- $version_entry = $this->getPackageVersion($package_e[0], $package_e[1]);
- if($version_entry === null)
- {
- Console::outWarning('Version ' . $package_e[1] . ' of package ' . $package_e[0] . ' not found');
- }
- else
- {
- $tree[$package_iter] = null;
- if(count($version_entry->getDependencies()) > 0)
- {
- $tree[$package_iter] = [];
- foreach($version_entry->getDependencies() as $dependency)
- {
- $dependency_name = sprintf('%s=%s', $dependency->getPackageName(), $dependency->getVersion());
- $tree[$package_iter] = $this->getPackageTree($tree[$package_iter], $dependency_name);
- }
- }
- }
- }
- catch(Exception $e)
- {
- unset($e);
- }
+ IO::fwrite(
+ $bin_path . DIRECTORY_SEPARATOR . $resource_name,
+ $package_reader->getResource($resource_name)->getData(), 0755
+ );
}
- return $tree;
+ foreach($package_reader->getExecutionUnits() as $unit)
+ {
+ $execution_unit = $package_reader->getExecutionUnit($unit);
+ $unit_path = $package_path . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $execution_unit->getExecutionPolicy()->getName() . '.unit';
+ IO::fwrite($unit_path, ZiProto::encode($execution_unit->toArray(true)), 0755);
+ }
+
+ $class_map = [];
+ foreach($package_reader->getClassMap() as $class)
+ {
+ $class_map[$class] = $package_reader->getComponentByClass($class)->getName();
+ }
+
+ if($package_reader->getInstaller() !== null)
+ {
+ IO::fwrite($package_path . DIRECTORY_SEPARATOR . FileDescriptor::INSTALLER, ZiProto::encode($package_reader->getInstaller()?->toArray(true)));
+ }
+
+ if(count($class_map) > 0)
+ {
+ IO::fwrite($package_path . DIRECTORY_SEPARATOR . FileDescriptor::CLASS_MAP, ZiProto::encode($class_map));
+ }
+
+ IO::fwrite($package_path . DIRECTORY_SEPARATOR . FileDescriptor::ASSEMBLY, ZiProto::encode($package_reader->getAssembly()->toArray(true)));
+ IO::fwrite($package_path . DIRECTORY_SEPARATOR . FileDescriptor::METADATA, ZiProto::encode($package_reader->getMetadata()->toArray(true)));
}
/**
- * Uninstalls a package version
+ * Reloads the package lock file from disk
*
- * @param string $package
- * @param string $version
* @return void
- * @throws AuthenticationException
+ * @throws ConfigurationException
* @throws IOException
- * @throws PackageException
* @throws PathNotFoundException
*/
- public function uninstallPackageVersion(string $package, string $version): void
+ private function loadLock(): void
{
- if(Resolver::resolveScope() !== Scopes::SYSTEM)
+ if(file_exists(PathFinder::getPackageLock()))
{
- throw new AuthenticationException('Insufficient permission to uninstall packages');
- }
-
- $version_entry = $this->getPackageVersion($package, $version);
- if($version_entry === null)
- {
- throw new PackageException(sprintf('The package %s=%s was not found', $package, $version));
- }
-
- Console::out(sprintf('Uninstalling %s=%s', $package, $version));
- Console::outVerbose(sprintf('Removing package %s=%s from PackageLock', $package, $version));
-
- if(!$this->getPackageLockManager()?->getPackageLock()?->removePackageVersion($package, $version))
- {
- Console::outDebug('warning: removing package from package lock failed');
- }
-
- $this->getPackageLockManager()?->save();
-
- Console::outVerbose('Removing package files');
- $scanner = new DirectoryScanner();
- $filesystem = new Filesystem();
-
- if($filesystem->exists($version_entry->location))
- {
- Console::outVerbose(sprintf('Removing package files from %s', $version_entry->location));
-
- /** @var SplFileInfo $item */
- /** @noinspection PhpRedundantOptionalArgumentInspection */
- foreach($scanner($version_entry->location, true) as $item)
- {
- if(is_file($item->getPath()))
- {
- Console::outDebug('removing file ' . $item->getPath());
- Console::outDebug(sprintf('deleting %s', $item->getPath()));
- $filesystem->remove($item->getPath());
- }
- }
+ $this->package_lock = PackageLock::fromArray(ZiProto::decode(IO::fread(PathFinder::getPackageLock())));
}
else
{
- Console::outWarning(sprintf('warning: package location %s does not exist', $version_entry->location));
+ $this->package_lock = new PackageLock();
}
-
- $filesystem->remove($version_entry->location);
-
- if(count($version_entry->getExecutionUnits()) > 0)
- {
- Console::outVerbose('Uninstalling execution units');
-
- $execution_pointer_manager = new ExecutionPointerManager();
- foreach($version_entry->getExecutionUnits() as $executionUnit)
- {
- if(!$execution_pointer_manager->removeUnit($package, $version, $executionUnit->getExecutionPolicy()->getName()))
- {
- Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->getExecutionPolicy()->getName()));
- }
- }
- }
-
- $symlink_manager = new SymlinkManager();
- $symlink_manager->sync();
}
/**
- * Uninstalls all versions of a package
+ * Saves the package lock file to disk
*
- * @param string $package
* @return void
- * @throws AuthenticationException
* @throws IOException
- * @throws PackageException
*/
- public function uninstallPackage(string $package): void
+ private function saveLock(): void
{
- if(Resolver::resolveScope() !== Scopes::SYSTEM)
- {
- throw new AuthenticationException('Insufficient permission to uninstall packages');
- }
-
- $package_entry = $this->getPackage($package);
- if($package_entry === null)
- {
- throw new PackageException(sprintf('The package %s was not found', $package));
- }
-
- foreach($package_entry->getVersions() as $version)
- {
- $version_entry = $package_entry->getVersion($version);
-
- if($version_entry === null)
- {
- Console::outDebug(sprintf('warning: version %s of package %s not found', $version, $package));
- continue;
- }
-
- try
- {
- $this->uninstallPackageVersion($package, $version_entry->getVersion());
- }
- catch(Exception $e)
- {
- Console::outDebug(sprintf('warning: unable to uninstall package %s=%s, %s (%s)', $package, $version_entry->getVersion(), $e->getMessage(), $e->getCode()));
- }
- }
+ IO::fwrite(PathFinder::getPackageLock(), ZiProto::encode($this->package_lock->toArray(true)));
}
-
- /**
- * @param Package $package
- * @param InstallationPaths $paths
- * @throws OperationException
- */
- private static function initData(Package $package, InstallationPaths $paths): void
- {
- Console::outVerbose(sprintf('Initializing data for %s', $package->getAssembly()->getName()));
-
- // Create data files
- $dependencies = [];
- foreach($package->getDependencies() as $dependency)
- {
- $dependencies[] = $dependency->toArray(true);
- }
-
- $data_files = [
- $paths->getDataPath() . DIRECTORY_SEPARATOR . 'assembly' => ZiProto::encode($package->getAssembly()->toArray(true)),
- $paths->getDataPath() . DIRECTORY_SEPARATOR . 'ext' => ZiProto::encode($package->getMetadata()->getCompilerExtension()->toArray()),
- $paths->getDataPath() . DIRECTORY_SEPARATOR . 'const' => ZiProto::encode($package->getMetadata()->getRuntimeConstants()),
- $paths->getDataPath() . DIRECTORY_SEPARATOR . 'dependencies' => ZiProto::encode($dependencies),
- ];
-
- foreach($data_files as $file => $data)
- {
- try
- {
- Console::outDebug(sprintf('generating data file %s', $file));
- IO::fwrite($file, $data);
- }
- catch (IOException $e)
- {
- throw new OperationException('Cannot write to file \'' . $file . '\', ' . $e->getMessage(), $e);
- }
- }
- }
-
- /**
- * @return PackageLockManager|null
- */
- private function getPackageLockManager(): ?PackageLockManager
- {
- if($this->package_lock_manager === null)
- {
- $this->package_lock_manager = new PackageLockManager();
- }
-
- return $this->package_lock_manager;
- }
-
}
\ No newline at end of file
diff --git a/src/ncc/Managers/PackageManagerOld.php b/src/ncc/Managers/PackageManagerOld.php
new file mode 100644
index 0000000..0bd33b6
--- /dev/null
+++ b/src/ncc/Managers/PackageManagerOld.php
@@ -0,0 +1,1030 @@
+packages_path = PathFinder::getPackagesPath(Scopes::SYSTEM);
+ $this->package_lock_manager = new PackageLockManager();
+ $this->package_lock_manager->load();
+ }
+
+ /**
+ * Installs a local package onto the system
+ *
+ * @param string $package_path
+ * @param Entry|null $entry
+ * @param array $options
+ * @return string
+ * @throws AuthenticationException
+ * @throws IOException
+ * @throws NotSupportedException
+ * @throws OperationException
+ * @throws PackageException
+ * @throws PathNotFoundException
+ * @throws ConfigurationException
+ */
+ public function install(string $package_path, ?Entry $entry=null, array $options=[]): string
+ {
+ if(Resolver::resolveScope() !== Scopes::SYSTEM)
+ {
+ throw new AuthenticationException('Insufficient permission to install packages');
+ }
+
+ if(!file_exists($package_path) || !is_file($package_path) || !is_readable($package_path))
+ {
+ throw new PathNotFoundException($package_path);
+ }
+
+ $package = Package::load($package_path);
+
+ if(RuntimeCache::get(sprintf('installed.%s=%s', $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion())))
+ {
+ Console::outDebug(sprintf('skipping installation of %s=%s, already processed', $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()));
+ return $package->getAssembly()->getPackage();
+ }
+
+ $extension = $package->getMetadata()->getCompilerExtension()->getExtension();
+ $installation_paths = new InstallationPaths($this->packages_path . DIRECTORY_SEPARATOR . $package->getAssembly()->getPackage() . '=' . $package->getAssembly()->getVersion());
+
+ $installer = match ($extension)
+ {
+ CompilerExtensions::PHP => new PhpInstaller($package),
+ default => throw new NotSupportedException(sprintf('Compiler extension %s is not supported with ncc', $extension))
+ };
+
+ if($this->getPackageVersion($package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()) !== null)
+ {
+ if(in_array(InstallPackageOptions::REINSTALL, $options, true))
+ {
+ if($this->getPackageLockManager()?->getPackageLock()?->packageExists($package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()))
+ {
+ $this->getPackageLockManager()?->getPackageLock()?->removePackageVersion(
+ $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()
+ );
+ }
+ }
+ else
+ {
+ throw new PackageException('The package ' . $package->getAssembly()->getPackage() . '=' . $package->getAssembly()->getVersion() . ' is already installed');
+ }
+ }
+
+ $execution_pointer_manager = new ExecutionPointerManager();
+ PackageCompiler::compilePackageConstants($package, [
+ ConstantReferences::INSTALL => $installation_paths
+ ]);
+
+ // Process all the required dependencies before installing the package
+ if(count($package->getDependencies()) > 0 && !in_array(InstallPackageOptions::SKIP_DEPENDENCIES, $options, true))
+ {
+ foreach($package->getDependencies() as $dependency)
+ {
+ // Uninstall the dependency if the option Reinstall is passed on
+ if(in_array(InstallPackageOptions::REINSTALL, $options, true) && $this->getPackageLockManager()?->getPackageLock()?->packageExists($dependency->getName(), $dependency->getVersion()))
+ {
+ if($dependency->getVersion() === 'latest')
+ {
+ $this->uninstallPackage($dependency->getName());
+ }
+ else
+ {
+ $this->uninstallPackageVersion($dependency->getName(), $dependency->getVersion());
+ }
+ }
+
+ $this->processDependency($dependency, $package, $package_path, $entry, $options);
+ }
+ }
+
+ Console::outVerbose(sprintf('Installing %s', $package_path));
+
+ if(Resolver::checkLogLevel(LogLevel::DEBUG, Main::getLogLevel()))
+ {
+ Console::outDebug(sprintf('installer.install_path: %s', $installation_paths->getInstallationpath()));
+ Console::outDebug(sprintf('installer.data_path: %s', $installation_paths->getDataPath()));
+ Console::outDebug(sprintf('installer.bin_path: %s', $installation_paths->getBinPath()));
+ Console::outDebug(sprintf('installer.src_path: %s', $installation_paths->getSourcePath()));
+
+ foreach($package->getAssembly()->toArray() as $prop => $value)
+ {
+ Console::outDebug(sprintf('assembly.%s: %s', $prop, ($value ?? 'n/a')));
+ }
+
+ foreach($package->getMetadata()->getCompilerExtension()->toArray() as $prop => $value)
+ {
+ Console::outDebug(sprintf('header.compiler.%s: %s', $prop, ($value ?? 'n/a')));
+ }
+ }
+
+ Console::out('Installing ' . $package->getAssembly()->getPackage());
+
+ // Four For Directory Creation, preInstall, postInstall & initData methods
+ $steps = (4 + count($package->getComponents()) + count ($package->getResources()) + count ($package->getExecutionUnits()));
+
+ // Include the Execution units
+ if($package->getInstaller()?->getPreInstall() !== null)
+ {
+ $steps += count($package->getInstaller()?->getPreInstall());
+ }
+
+ if($package->getInstaller()?->getPostInstall()!== null)
+ {
+ $steps += count($package->getInstaller()->getPostInstall());
+ }
+
+ $current_steps = 0;
+ $filesystem = new Filesystem();
+
+ try
+ {
+ $filesystem->mkdir($installation_paths->getInstallationpath(), 0755);
+ $filesystem->mkdir($installation_paths->getBinPath(), 0755);
+ $filesystem->mkdir($installation_paths->getDataPath(), 0755);
+ $filesystem->mkdir($installation_paths->getSourcePath(), 0755);
+
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+ catch(Exception $e)
+ {
+ throw new IOException('Error while creating directory, ' . $e->getMessage(), $e);
+ }
+
+ try
+ {
+ Console::outDebug(sprintf('saving shadow package to %s', $installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg'));
+
+ self::initData($package, $installation_paths);
+ $package->save($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg');
+ ++$current_steps;
+
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException('Cannot initialize package install, ' . $e->getMessage(), $e);
+ }
+
+ // Execute the pre-installation stage before the installation stage
+ try
+ {
+ $installer->preInstall($installation_paths);
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+ catch (Exception $e)
+ {
+ throw new OperationException('Pre installation stage failed, ' . $e->getMessage(), $e);
+ }
+
+ if($package->getInstaller()?->getPreInstall() !== null && count($package->getInstaller()->getPreInstall()) > 0)
+ {
+ foreach($package->getInstaller()->getPreInstall() as $unit_name)
+ {
+ try
+ {
+ $execution_pointer_manager->temporaryExecute($package, $unit_name);
+ }
+ catch(Exception $e)
+ {
+ Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage());
+ }
+
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+ }
+
+ // Process & Install the components
+ foreach($package->getComponents() as $component)
+ {
+ Console::outDebug(sprintf('processing component %s (%s)', $component->getName(), $component->getDataType()));
+
+ try
+ {
+ $data = $installer->processComponent($component);
+ if($data !== null)
+ {
+ $component_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $component->getName();
+ $component_dir = dirname($component_path);
+
+ if(!$filesystem->exists($component_dir))
+ {
+ $filesystem->mkdir($component_dir);
+ }
+
+ IO::fwrite($component_path, $data);
+ }
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException('Cannot process one or more components, ' . $e->getMessage(), $e);
+ }
+
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+
+ // Process & Install the resources
+ foreach($package->getResources() as $resource)
+ {
+ Console::outDebug(sprintf('processing resource %s', $resource->getName()));
+
+ try
+ {
+ $data = $installer->processResource($resource);
+ if($data !== null)
+ {
+ $resource_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $resource->getName();
+ $resource_dir = dirname($resource_path);
+
+ if(!$filesystem->exists($resource_dir))
+ {
+ $filesystem->mkdir($resource_dir);
+ }
+
+ IO::fwrite($resource_path, $data);
+ }
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException('Cannot process one or more resources, ' . $e->getMessage(), $e);
+ }
+
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+
+ // Install execution units
+ if($package->getExecutionUnits() !== null && count($package->getExecutionUnits()) > 0)
+ {
+ Console::outDebug('package contains execution units, processing');
+
+ $execution_pointer_manager = new ExecutionPointerManager();
+ $unit_paths = [];
+
+ /** @var Package\ExecutionUnit $executionUnit */
+ foreach($package->getExecutionUnits() as $executionUnit)
+ {
+ Console::outDebug(sprintf('processing execution unit %s', $executionUnit->getExecutionPolicy()->getName()));
+ $execution_pointer_manager->addUnit($package->getAssembly()->getPackage(), $package->getAssembly()->getVersion(), $executionUnit);
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+
+ IO::fwrite($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'exec', ZiProto::encode($unit_paths));
+ }
+ else
+ {
+ Console::outDebug('package does not contain execution units, skipping');
+ }
+
+ // After execution units are installed, create a symlink if needed
+ if(!is_null($package->getMetadata()->getOption('create_symlink')) && $package->getMetadata()->getOption('create_symlink'))
+ {
+ if($package->getMainExecutionPolicy() === null)
+ {
+ throw new OperationException('Cannot create symlink, no main execution policy is defined');
+ }
+
+ Console::outDebug(sprintf('creating symlink to %s', $package->getAssembly()->getPackage()));
+
+ $SymlinkManager = new SymlinkManager();
+ $SymlinkManager->add($package->getAssembly()->getPackage(), $package->getMainExecutionPolicy());
+ }
+
+ // Execute the post-installation stage after the installation is complete
+ try
+ {
+ Console::outDebug('executing post-installation stage');
+
+ $installer->postInstall($installation_paths);
+ ++$current_steps;
+
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+ catch (Exception $e)
+ {
+ throw new OperationException('Post installation stage failed, ' . $e->getMessage(), $e);
+ }
+
+ if($package->getInstaller()?->getPostInstall() !== null && count($package->getInstaller()->getPostInstall()) > 0)
+ {
+ Console::outDebug('executing post-installation units');
+
+ foreach($package->getInstaller()->getPostInstall() as $unit_name)
+ {
+ try
+ {
+ $execution_pointer_manager->temporaryExecute($package, $unit_name);
+ }
+ catch(Exception $e)
+ {
+ Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage());
+ }
+ finally
+ {
+ ++$current_steps;
+ Console::inlineProgressBar($current_steps, $steps);
+ }
+ }
+ }
+ else
+ {
+ Console::outDebug('no post-installation units to execute');
+ }
+
+ if($package->getMetadata()->getUpdateSource()?->getRepository() !== null)
+ {
+ $sources_manager = new RemoteSourcesManager();
+ if($sources_manager->getRemoteSource($package->getMetadata()->getUpdateSource()->getRepository()->getName()) === null)
+ {
+ Console::outVerbose('Adding remote source ' . $package->getMetadata()->getUpdateSource()->getRepository()->getName());
+
+ $defined_remote_source = new DefinedRemoteSource();
+ $defined_remote_source->setName($package->getMetadata()->getUpdateSource()?->getRepository()?->getName());
+ $defined_remote_source->setHost($package->getMetadata()->getUpdateSource()?->getRepository()?->getHost());
+ $defined_remote_source->setType($package->getMetadata()->getUpdateSource()?->getRepository()?->getType());
+ $defined_remote_source->setSsl($package->getMetadata()->getUpdateSource()?->getRepository()?->isSsl());
+
+ $sources_manager->addRemoteSource($defined_remote_source);
+ }
+ }
+
+ $this->getPackageLockManager()?->getPackageLock()?->addPackage($package, $installation_paths->getInstallationpath());
+ $this->getPackageLockManager()?->save();
+
+ RuntimeCache::set(sprintf('installed.%s=%s', $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()), true);
+
+ return $package->getAssembly()->getPackage();
+ }
+
+ /**
+ * @param string $source
+ * @param Entry|null $entry
+ * @return string
+ * @throws NotSupportedException
+ * @throws OperationException
+ * @throws PackageException
+ */
+ public function fetchFromSource(string $source, ?Entry $entry=null): string
+ {
+ $input = new RemotePackageInput($source);
+
+ if($input->getSource() === null)
+ {
+ throw new PackageException('No source specified');
+ }
+
+ if($input->getVersion() === null)
+ {
+ $input->setVersion(Versions::LATEST);
+ }
+
+ Console::outVerbose('Fetching package ' . $input->getPackage() . ' from ' . $input->getSource() . ' (' . $input->getVersion() . ')');
+
+ $remote_source_type = Resolver::detectRemoteSourceType($input->getSource());
+ if($remote_source_type === RemoteSourceType::BUILTIN)
+ {
+ Console::outDebug('using builtin source ' . $input->getSource());
+
+ if ($input->getSource() === 'composer')
+ {
+ try
+ {
+ return ComposerSourceBuiltin::fetch($input);
+ }
+ catch (Exception $e)
+ {
+ throw new PackageException('Cannot fetch package from composer source, ' . $e->getMessage(), $e);
+ }
+ }
+
+ throw new NotSupportedException(sprintf('Builtin source %s is not supported', $input->getSource()));
+ }
+
+ if($remote_source_type === RemoteSourceType::DEFINED)
+ {
+ Console::outDebug('using defined source ' . $input->getSource());
+ /** @noinspection CallableParameterUseCaseInTypeContextInspection */
+ $source = (new RemoteSourcesManager())->getRemoteSource($input->getSource());
+ if($source === null)
+ {
+ throw new OperationException('Remote source ' . $input->getSource() . ' is not defined');
+ }
+
+ $repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry);
+ $exceptions = [];
+
+ if($repositoryQueryResults->getFiles()->ZipballUrl !== null)
+ {
+ try
+ {
+ Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->ZipballUrl));
+ $archive = Functions::downloadGitServiceFile($repositoryQueryResults->getFiles()->ZipballUrl, $entry);
+ return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->getVersion());
+ }
+ catch(Throwable $e)
+ {
+ Console::outDebug('cannot fetch package from zipball url, ' . $e->getMessage());
+ $exceptions[] = $e;
+ }
+ }
+
+ if($repositoryQueryResults->getFiles()->TarballUrl !== null)
+ {
+ try
+ {
+ Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->TarballUrl));
+ $archive = Functions::downloadGitServiceFile($repositoryQueryResults->getFiles()->TarballUrl, $entry);
+ return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->getVersion());
+ }
+ catch(Exception $e)
+ {
+ Console::outDebug('cannot fetch package from tarball url, ' . $e->getMessage());
+ $exceptions[] = $e;
+ }
+ }
+
+ if($repositoryQueryResults->getFiles()->PackageUrl !== null)
+ {
+ try
+ {
+ Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->PackageUrl));
+ return Functions::downloadGitServiceFile($repositoryQueryResults->getFiles()->PackageUrl, $entry);
+ }
+ catch(Exception $e)
+ {
+ Console::outDebug('cannot fetch package from package url, ' . $e->getMessage());
+ $exceptions[] = $e;
+ }
+ }
+
+ if($repositoryQueryResults->getFiles()->GitHttpUrl !== null || $repositoryQueryResults->getFiles()->GitSshUrl !== null)
+ {
+ try
+ {
+ Console::outDebug(sprintf('fetching package %s from %s', $input->getPackage(), $repositoryQueryResults->getFiles()->GitHttpUrl ?? $repositoryQueryResults->getFiles()->GitSshUrl));
+ $git_repository = GitClient::cloneRepository($repositoryQueryResults->getFiles()->GitHttpUrl ?? $repositoryQueryResults->getFiles()->GitSshUrl);
+
+ foreach(GitClient::getTags($git_repository) as $tag)
+ {
+ if(VersionComparator::compareVersion($tag, $repositoryQueryResults->getVersion()) === 0)
+ {
+ GitClient::checkout($git_repository, $tag);
+ return PackageCompiler::tryCompile($git_repository, $repositoryQueryResults->getVersion());
+ }
+ }
+
+ Console::outDebug('cannot fetch package from git repository, no matching tag found');
+ }
+ catch(Exception $e)
+ {
+ Console::outDebug('cannot fetch package from git repository, ' . $e->getMessage());
+ $exceptions[] = $e;
+ }
+ }
+
+ // Recursively create an exception with the previous exceptions as the previous exception
+ $exception = null;
+
+ if(count($exceptions) > 0)
+ {
+ foreach($exceptions as $e)
+ {
+ if($exception === null)
+ {
+ $exception = new PackageException($e->getMessage(), $e);
+ }
+ else
+ {
+ if($e->getMessage() === $exception->getMessage())
+ {
+ continue;
+ }
+
+ $exception = new PackageException($e->getMessage(), $exception);
+ }
+ }
+ }
+ else
+ {
+ $exception = new PackageException('Cannot fetch package from remote source, no assets found');
+ }
+
+ throw $exception;
+ }
+
+ throw new PackageException(sprintf('Unknown remote source type %s', $remote_source_type));
+ }
+
+ /**
+ * Installs a package from a source syntax (vendor/package=version@source)
+ *
+ * @param string $source
+ * @param Entry|null $entry
+ * @param array $options
+ * @return string
+ * @throws OperationException
+ */
+ public function installFromSource(string $source, ?Entry $entry, array $options=[]): string
+ {
+ try
+ {
+ Console::outVerbose(sprintf('Installing package from source %s', $source));
+
+ $package = $this->fetchFromSource($source, $entry);
+ return $this->install($package, $entry, $options);
+ }
+ catch(Exception $e)
+ {
+ throw new OperationException('Cannot install package from source, ' . $e->getMessage(), $e);
+ }
+ }
+
+ /**
+ * @param Dependency $dependency
+ * @param Package $package
+ * @param string $package_path
+ * @param Entry|null $entry
+ * @param array $options
+ * @return void
+ * @throws AuthenticationException
+ * @throws IOException
+ * @throws NotSupportedException
+ * @throws OperationException
+ * @throws PackageException
+ * @throws PathNotFoundException
+ * @throws ConfigurationException
+ */
+ private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null, array $options=[]): void
+ {
+ if(RuntimeCache::get(sprintf('dependency_installed.%s=%s', $dependency->getName(), $dependency->getVersion())))
+ {
+ Console::outDebug(sprintf('dependency %s=%s already processed, skipping', $dependency->getName(), $dependency->getVersion()));
+ return;
+ }
+
+ Console::outVerbose('processing dependency ' . $dependency->getVersion() . ' (' . $dependency->getVersion() . ')');
+ $dependent_package = $this->getPackage($dependency->getName());
+ $dependency_met = false;
+
+ if ($dependent_package !== null && $dependency->getVersion() !== null && Validate::version($dependency->getVersion()))
+ {
+ Console::outDebug('dependency has version constraint, checking if package is installed');
+ $dependent_version = $this->getPackageVersion($dependency->getName(), $dependency->getVersion());
+ if ($dependent_version !== null)
+ {
+ $dependency_met = true;
+ }
+ }
+ elseif ($dependent_package !== null && $dependency->getVersion() === null)
+ {
+ Console::outDebug(sprintf('dependency %s has no version specified, assuming dependency is met', $dependency->getName()));
+ $dependency_met = true;
+ }
+
+ Console::outDebug('dependency met: ' . ($dependency_met ? 'true' : 'false'));
+
+ if ($dependency->getSourceType() !== null && !$dependency_met)
+ {
+ Console::outVerbose(sprintf('Installing dependency %s=%s for %s=%s', $dependency->getName(), $dependency->getVersion(), $package->getAssembly()->getPackage(), $package->getAssembly()->getVersion()));
+ switch ($dependency->getSourceType())
+ {
+ case DependencySourceType::LOCAL:
+ Console::outDebug('installing from local source ' . $dependency->getSource());
+ $basedir = dirname($package_path);
+
+ if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->getSourceType()))
+ {
+ throw new PathNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->getSource());
+ }
+
+ $this->install($basedir . DIRECTORY_SEPARATOR . $dependency->getSource(), null, $options);
+ RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->getName(), $dependency->getVersion()), true);
+ break;
+
+ case DependencySourceType::STATIC:
+ throw new PackageException('Static linking not possible, package ' . $dependency->getName() . ' is not installed');
+
+ case DependencySourceType::REMOTE:
+ Console::outDebug('installing from remote source ' . $dependency->getSource());
+ $this->installFromSource($dependency->getSource(), $entry, $options);
+ RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->getName(), $dependency->getVersion()), true);
+ break;
+
+ default:
+ throw new NotSupportedException(sprintf('Dependency source type %s is not supported', $dependency->getSourceType()));
+ }
+ }
+ elseif(!$dependency_met)
+ {
+ throw new PackageException(sprintf('Required dependency %s=%s is not installed', $dependency->getName(), $dependency->getVersion()));
+ }
+ }
+
+ /**
+ * Returns an existing package entry, returns null if no such entry exists
+ *
+ * @param string $package
+ * @return PackageEntry|null
+ * @throws IOException
+ */
+ public function getPackage(string $package): ?PackageEntry
+ {
+ Console::outDebug('getting package ' . $package);
+ return $this->getPackageLockManager()?->getPackageLock()?->getPackage($package);
+ }
+
+ /**
+ * Returns an existing version entry, returns null if no such entry exists
+ *
+ * @param string $package
+ * @param string $version
+ * @return VersionEntry|null
+ * @throws IOException
+ */
+ public function getPackageVersion(string $package, string $version): ?VersionEntry
+ {
+ Console::outDebug('getting package version ' . $package . '=' . $version);
+ return $this->getPackage($package)?->getVersion($version);
+ }
+
+ /**
+ * Returns the latest version of the package, or null if there is no entry
+ *
+ * @param string $package
+ * @return VersionEntry|null
+ * @throws IOException
+ */
+ public function getLatestVersion(string $package): ?VersionEntry
+ {
+ Console::outDebug('getting latest version of package ' . $package);
+ return $this->getPackage($package)?->getVersion($this->getPackage($package)?->getLatestVersion());
+ }
+
+ /**
+ * Returns an array of all packages and their installed versions
+ *
+ * @return array
+ * @throws IOException
+ */
+ public function getInstalledPackages(): array
+ {
+ return $this->getPackageLockManager()?->getPackageLock()?->getEntries() ?? [];
+ }
+
+ /**
+ * Returns a package tree representation
+ *
+ * @param array $tree
+ * @param string|null $package
+ * @return array
+ */
+ public function getPackageTree(array $tree=[], ?string $package=null): array
+ {
+ // First build the packages to scan first
+ $packages = [];
+ if($package !== null)
+ {
+ // If it's coming from a selected package, query the package and process its dependencies
+ $exploded = explode('=', $package);
+ try
+ {
+ /** @noinspection CallableParameterUseCaseInTypeContextInspection */
+ $package = $this->getPackage($exploded[0]);
+ if($package === null)
+ {
+ throw new PackageException('Package ' . $exploded[0] . ' not found');
+ }
+
+ $version = $package->getVersion($exploded[1]);
+ if($version === null)
+ {
+ throw new OperationException('Version ' . $exploded[1] . ' not found for package ' . $exploded[0]);
+ }
+
+ foreach ($version->getDependencies() as $dependency)
+ {
+ if(!in_array($dependency->getPackageName() . '=' . $dependency->getVersion(), $tree, true))
+ {
+ $packages[] = $dependency->getPackageName() . '=' . $dependency->getVersion();
+ }
+ }
+ }
+ catch(Exception $e)
+ {
+ unset($e);
+ }
+
+ }
+ else
+ {
+ // If it's coming from nothing, start with the installed packages on the system
+ try
+ {
+ foreach ($this->getInstalledPackages() as $installed_package => $versions)
+ {
+ foreach ($versions as $version)
+ {
+ if (!in_array($installed_package . '=' . $version, $packages, true))
+ {
+ $packages[] = $installed_package . '=' . $version;
+ }
+ }
+ }
+ }
+ catch (IOException $e)
+ {
+ unset($e);
+ }
+ }
+
+ // Go through each package
+ foreach($packages as $package_iter)
+ {
+ $package_e = explode('=', $package_iter);
+ try
+ {
+ $version_entry = $this->getPackageVersion($package_e[0], $package_e[1]);
+ if($version_entry === null)
+ {
+ Console::outWarning('Version ' . $package_e[1] . ' of package ' . $package_e[0] . ' not found');
+ }
+ else
+ {
+ $tree[$package_iter] = null;
+ if(count($version_entry->getDependencies()) > 0)
+ {
+ $tree[$package_iter] = [];
+ foreach($version_entry->getDependencies() as $dependency)
+ {
+ $dependency_name = sprintf('%s=%s', $dependency->getPackageName(), $dependency->getVersion());
+ $tree[$package_iter] = $this->getPackageTree($tree[$package_iter], $dependency_name);
+ }
+ }
+ }
+ }
+ catch(Exception $e)
+ {
+ unset($e);
+ }
+ }
+
+ return $tree;
+ }
+
+ /**
+ * Uninstalls a package version
+ *
+ * @param string $package
+ * @param string $version
+ * @return void
+ * @throws AuthenticationException
+ * @throws IOException
+ * @throws PackageException
+ * @throws PathNotFoundException
+ */
+ public function uninstallPackageVersion(string $package, string $version): void
+ {
+ if(Resolver::resolveScope() !== Scopes::SYSTEM)
+ {
+ throw new AuthenticationException('Insufficient permission to uninstall packages');
+ }
+
+ $version_entry = $this->getPackageVersion($package, $version);
+ if($version_entry === null)
+ {
+ throw new PackageException(sprintf('The package %s=%s was not found', $package, $version));
+ }
+
+ Console::out(sprintf('Uninstalling %s=%s', $package, $version));
+ Console::outVerbose(sprintf('Removing package %s=%s from PackageLock', $package, $version));
+
+ if(!$this->getPackageLockManager()?->getPackageLock()?->removePackageVersion($package, $version))
+ {
+ Console::outDebug('warning: removing package from package lock failed');
+ }
+
+ $this->getPackageLockManager()?->save();
+
+ Console::outVerbose('Removing package files');
+ $scanner = new DirectoryScanner();
+ $filesystem = new Filesystem();
+
+ if($filesystem->exists($version_entry->location))
+ {
+ Console::outVerbose(sprintf('Removing package files from %s', $version_entry->location));
+
+ /** @var SplFileInfo $item */
+ /** @noinspection PhpRedundantOptionalArgumentInspection */
+ foreach($scanner($version_entry->location, true) as $item)
+ {
+ if(is_file($item->getPath()))
+ {
+ Console::outDebug('removing file ' . $item->getPath());
+ Console::outDebug(sprintf('deleting %s', $item->getPath()));
+ $filesystem->remove($item->getPath());
+ }
+ }
+ }
+ else
+ {
+ Console::outWarning(sprintf('warning: package location %s does not exist', $version_entry->location));
+ }
+
+ $filesystem->remove($version_entry->location);
+
+ if(count($version_entry->getExecutionUnits()) > 0)
+ {
+ Console::outVerbose('Uninstalling execution units');
+
+ $execution_pointer_manager = new ExecutionPointerManager();
+ foreach($version_entry->getExecutionUnits() as $executionUnit)
+ {
+ if(!$execution_pointer_manager->removeUnit($package, $version, $executionUnit->getExecutionPolicy()->getName()))
+ {
+ Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->getExecutionPolicy()->getName()));
+ }
+ }
+ }
+
+ $symlink_manager = new SymlinkManager();
+ $symlink_manager->sync();
+ }
+
+ /**
+ * Uninstalls all versions of a package
+ *
+ * @param string $package
+ * @return void
+ * @throws AuthenticationException
+ * @throws IOException
+ * @throws PackageException
+ */
+ public function uninstallPackage(string $package): void
+ {
+ if(Resolver::resolveScope() !== Scopes::SYSTEM)
+ {
+ throw new AuthenticationException('Insufficient permission to uninstall packages');
+ }
+
+ $package_entry = $this->getPackage($package);
+ if($package_entry === null)
+ {
+ throw new PackageException(sprintf('The package %s was not found', $package));
+ }
+
+ foreach($package_entry->getVersions() as $version)
+ {
+ $version_entry = $package_entry->getVersion($version);
+
+ if($version_entry === null)
+ {
+ Console::outDebug(sprintf('warning: version %s of package %s not found', $version, $package));
+ continue;
+ }
+
+ try
+ {
+ $this->uninstallPackageVersion($package, $version_entry->getVersion());
+ }
+ catch(Exception $e)
+ {
+ Console::outDebug(sprintf('warning: unable to uninstall package %s=%s, %s (%s)', $package, $version_entry->getVersion(), $e->getMessage(), $e->getCode()));
+ }
+ }
+ }
+
+ /**
+ * @param Package $package
+ * @param InstallationPaths $paths
+ * @throws OperationException
+ */
+ private static function initData(Package $package, InstallationPaths $paths): void
+ {
+ Console::outVerbose(sprintf('Initializing data for %s', $package->getAssembly()->getName()));
+
+ // Create data files
+ $dependencies = [];
+ foreach($package->getDependencies() as $dependency)
+ {
+ $dependencies[] = $dependency->toArray(true);
+ }
+
+ $data_files = [
+ $paths->getDataPath() . DIRECTORY_SEPARATOR . 'assembly' => ZiProto::encode($package->getAssembly()->toArray(true)),
+ $paths->getDataPath() . DIRECTORY_SEPARATOR . 'ext' => ZiProto::encode($package->getMetadata()->getCompilerExtension()->toArray()),
+ $paths->getDataPath() . DIRECTORY_SEPARATOR . 'const' => ZiProto::encode($package->getMetadata()->getRuntimeConstants()),
+ $paths->getDataPath() . DIRECTORY_SEPARATOR . 'dependencies' => ZiProto::encode($dependencies),
+ ];
+
+ foreach($data_files as $file => $data)
+ {
+ try
+ {
+ Console::outDebug(sprintf('generating data file %s', $file));
+ IO::fwrite($file, $data);
+ }
+ catch (IOException $e)
+ {
+ throw new OperationException('Cannot write to file \'' . $file . '\', ' . $e->getMessage(), $e);
+ }
+ }
+ }
+
+ /**
+ * @return PackageLockManager|null
+ */
+ private function getPackageLockManager(): ?PackageLockManager
+ {
+ if($this->package_lock_manager === null)
+ {
+ $this->package_lock_manager = new PackageLockManager();
+ }
+
+ return $this->package_lock_manager;
+ }
+
+ }
\ No newline at end of file
diff --git a/src/ncc/Managers/ProjectManager.php b/src/ncc/Managers/ProjectManager.php
index 9abf604..e66772a 100644
--- a/src/ncc/Managers/ProjectManager.php
+++ b/src/ncc/Managers/ProjectManager.php
@@ -25,9 +25,10 @@
namespace ncc\Managers;
+ use ncc\Classes\PhpExtension\ExecutableCompiler;
use ncc\Classes\PhpExtension\NccCompiler;
- use ncc\Classes\PhpExtension\PhpCliTemplate;
- use ncc\Classes\PhpExtension\PhpLibraryTemplate;
+ use ncc\Classes\PhpExtension\Templates\CliTemplate;
+ use ncc\Classes\PhpExtension\Templates\LibraryTemplate;
use ncc\Enums\BuildOutputType;
use ncc\Enums\CompilerExtensions;
use ncc\Enums\ComponentFileExtensions;
@@ -155,8 +156,10 @@
return match (strtolower($this->project_configuration->getProject()->getCompiler()->getExtension()))
{
- CompilerExtensions::PHP => match (strtolower($configuration->getBuildType())) {
+ CompilerExtensions::PHP => match (strtolower($configuration->getBuildType()))
+ {
BuildOutputType::NCC_PACKAGE => (new NccCompiler($this))->build($build_configuration),
+ BuildOutputType::EXECUTABLE => (new ExecutableCompiler($this))->build($build_configuration),
default => throw new BuildException(sprintf('php cannot produce the build type \'%s\'', $configuration->getBuildType())),
},
default => throw new NotSupportedException(sprintf('The compiler extension \'%s\' is not supported', $this->project_configuration->getProject()->getCompiler()->getExtension())),
@@ -178,11 +181,11 @@
switch(strtolower($template_name))
{
case ProjectTemplates::PHP_CLI:
- PhpCliTemplate::applyTemplate($this);
+ CliTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_LIBRARY:
- PhpLibraryTemplate::applyTemplate($this);
+ LibraryTemplate::applyTemplate($this);
break;
default:
@@ -283,7 +286,6 @@
{
$configuration = $this->project_configuration->getBuild()->getBuildConfiguration($build_configuration);
- /** @noinspection ArrayMergeMissUseInspection */
return array_merge(
$configuration->getDefineConstants(),
$this->project_configuration->getBuild()->getDefineConstants()
@@ -301,7 +303,6 @@
{
$configuration = $this->project_configuration->getBuild()->getBuildConfiguration($build_configuration);
- /** @noinspection ArrayMergeMissUseInspection */
return array_merge(
$configuration->getOptions(),
$this->project_configuration->getBuild()->getOptions()
@@ -314,7 +315,7 @@
* @param string $project_path The directory for the project to be initialized in
* @param string $name The name of the project eg; ProjectLib
* @param string $package The standard package name eg; com.example.project
- * @param Compiler $compiler The compiler to use for this project
+ * @param string $compiler The compiler to use for this project
* @param array $options An array of options to use when initializing the project
* @return ProjectManager
* @throws ConfigurationException
diff --git a/src/ncc/Managers/RemoteSourcesManager.php b/src/ncc/Managers/RemoteSourcesManager.php
index 6843577..81daf0f 100644
--- a/src/ncc/Managers/RemoteSourcesManager.php
+++ b/src/ncc/Managers/RemoteSourcesManager.php
@@ -30,7 +30,7 @@
use ncc\Objects\DefinedRemoteSource;
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class RemoteSourcesManager
{
diff --git a/src/ncc/Managers/SymlinkManager.php b/src/ncc/Managers/SymlinkManager.php
index 668fed2..8fae672 100644
--- a/src/ncc/Managers/SymlinkManager.php
+++ b/src/ncc/Managers/SymlinkManager.php
@@ -34,7 +34,7 @@
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class SymlinkManager
{
diff --git a/src/ncc/Objects/Package.php b/src/ncc/Objects/Package.php
index 5ecb0b1..785b17a 100644
--- a/src/ncc/Objects/Package.php
+++ b/src/ncc/Objects/Package.php
@@ -35,7 +35,6 @@
use ncc\Objects\Package\Component;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\Package\Metadata;
- use ncc\Objects\Package\Installer;
use ncc\Objects\Package\MagicBytes;
use ncc\Objects\Package\Resource;
use ncc\Objects\ProjectConfiguration\Assembly;
@@ -43,7 +42,7 @@
use ncc\Objects\ProjectConfiguration\Dependency;
use ncc\Utilities\Functions;
use ncc\Utilities\IO;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
class Package implements BytecodeObjectInterface
{
@@ -75,13 +74,6 @@
*/
private $dependencies;
- /**
- * The installer object that is used to install the package if the package is install-able
- *
- * @var Installer|null
- */
- private $installer;
-
/**
* An array of execution units defined in the package
*
diff --git a/src/ncc/Objects/Package/Component.php b/src/ncc/Objects/Package/Component.php
index 36e5f11..6638244 100644
--- a/src/ncc/Objects/Package/Component.php
+++ b/src/ncc/Objects/Package/Component.php
@@ -24,10 +24,17 @@
namespace ncc\Objects\Package;
+ use Exception;
+ use ncc\Classes\PhpExtension\AstWalker;
use ncc\Enums\ComponentDataType;
+ use ncc\Enums\Flags\ComponentFlags;
+ use ncc\Enums\Options\ComponentDecodeOptions;
use ncc\Exceptions\ConfigurationException;
+ use ncc\Extensions\ZiProto\ZiProto;
use ncc\Interfaces\BytecodeObjectInterface;
+ use ncc\ThirdParty\nikic\PhpParser\PrettyPrinter\Standard;
use ncc\Utilities\Functions;
+ use RuntimeException;
class Component implements BytecodeObjectInterface
{
@@ -162,11 +169,63 @@
}
/**
+ * Returns the decoded data of the component, this will decode the data based on the data type and flags of the
+ * component.
+ *
+ * @param array $options
* @return string
*/
- public function getData(): string
+ public function getData(array $options=[]): string
{
- return $this->data;
+ switch($this->data_type)
+ {
+ case ComponentDataType::PLAIN:
+ case ComponentDataType::BINARY:
+ return $this->data;
+
+ case ComponentDataType::BASE64_ENCODED:
+ if(in_array(ComponentFlags::PHP_B64, $this->flags, true))
+ {
+ try
+ {
+ if(in_array(ComponentDecodeOptions::AS_FILE, $options, true))
+ {
+ return (new Standard())->prettyPrintFile(AstWalker::decodeRecursive(base64_decode($this->data)));
+ }
+
+ return (new Standard())->prettyPrint(AstWalker::decodeRecursive(base64_decode($this->data)));
+ }
+ catch(Exception $e)
+ {
+ throw new RuntimeException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_B64, $e->getMessage()), $e->getCode(), $e);
+ }
+ }
+
+ return base64_decode($this->data);
+
+ case ComponentDataType::AST:
+ if(in_array(ComponentFlags::PHP_AST, $this->flags, true))
+ {
+ try
+ {
+ if(in_array(ComponentDecodeOptions::AS_FILE, $options, true))
+ {
+ return (new Standard())->prettyPrintFile(AstWalker::decodeRecursive(ZiProto::decode($this->data)));
+ }
+
+ return (new Standard())->prettyPrint(AstWalker::decodeRecursive(ZiProto::decode($this->data)));
+ }
+ catch(Exception $e)
+ {
+ throw new RuntimeException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_AST, $e->getMessage()), $e->getCode(), $e);
+ }
+ }
+
+ throw new RuntimeException(sprintf('Cannot decode component %s with data type %s because the component does not have a flag to decode it properly', $this->name, 'AST'));
+
+ default:
+ throw new RuntimeException(sprintf('Unknown component data type "%s"', $this->data_type));
+ }
}
/**
diff --git a/src/ncc/Objects/Package/Metadata.php b/src/ncc/Objects/Package/Metadata.php
index 65ac6b6..af718f4 100644
--- a/src/ncc/Objects/Package/Metadata.php
+++ b/src/ncc/Objects/Package/Metadata.php
@@ -1,24 +1,24 @@
$this->runtime_constants,
($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->compiler_version,
($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->update_source?->toArray($bytecode)),
+ ($bytecode ? Functions::cbc('installer') : 'installer') => ($this->installer?->toArray($bytecode)),
+ ($bytecode ? Functions::cbc('main_execution_policy') : 'main_execution_policy') => $this->main_execution_policy,
($bytecode ? Functions::cbc('options') : 'options') => $this->options,
];
}
@@ -259,12 +262,20 @@
$object->compiler_version = Functions::array_bc($data, 'compiler_version');
$object->update_source = Functions::array_bc($data, 'update_source');
$object->options = Functions::array_bc($data, 'options');
+ $object->update_source = Functions::array_bc($data, 'update_source');
+ $object->main_execution_policy = Functions::array_bc($data, 'main_execution_policy');
+ $object->installer = Functions::array_bc($data, 'installer');
if($object->update_source !== null)
{
$object->update_source = UpdateSource::fromArray($object->update_source);
}
+ if($object->installer !== null)
+ {
+ $object->installer = Installer::fromArray($object->installer);
+ }
+
return $object;
}
}
\ No newline at end of file
diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php
index 4170d44..cef663e 100644
--- a/src/ncc/Objects/PackageLock.php
+++ b/src/ncc/Objects/PackageLock.php
@@ -24,9 +24,10 @@
namespace ncc\Objects;
+ use InvalidArgumentException;
+ use ncc\Classes\PackageReader;
use ncc\Enums\Versions;
use ncc\Exceptions\ConfigurationException;
- use ncc\Exceptions\IOException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Objects\PackageLock\PackageEntry;
use ncc\Utilities\Console;
@@ -53,15 +54,36 @@
*
* @var PackageEntry[]
*/
- private $packages;
+ private $entries;
/**
* Public Constructor
*/
- public function __construct()
+ public function __construct(array $entries=[], string $package_lock_version=Versions::PACKAGE_LOCK_VERSION, ?int $last_updated_timestamp=null)
{
- $this->package_lock_version = Versions::PACKAGE_LOCK_VERSION;
- $this->packages = [];
+ $this->entries = $entries;
+ $this->package_lock_version = $package_lock_version;
+ $this->last_updated_timestamp = $last_updated_timestamp ?? time();
+ }
+
+ /**
+ * Returns the package lock structure version
+ *
+ * @return string
+ */
+ public function getPackageLockVersion(): string
+ {
+ return $this->package_lock_version;
+ }
+
+ /**
+ * Returns the Unix Timestamp for when this package lock file was last updated
+ *
+ * @return int
+ */
+ public function getLastUpdatedTimestamp(): int
+ {
+ return $this->last_updated_timestamp;
}
/**
@@ -76,188 +98,141 @@
}
/**
- * @param Package $package
- * @param string $install_path
+ * Adds a new PackageEntry to the PackageLock file from a PackageReader
+ *
+ * @param PackageReader $package_reader
* @return void
* @throws ConfigurationException
*/
- public function addPackage(Package $package, string $install_path): void
+ public function addPackage(PackageReader $package_reader): void
{
- Console::outVerbose("Adding package {$package->getAssembly()->getPackage()} to package lock file");
+ Console::outVerbose("Adding package {$package_reader->getAssembly()->getPackage()} to package lock file");
- if(!isset($this->packages[$package->getAssembly()->getPackage()]))
+ if(!$this->entryExists($package_reader->getAssembly()->getPackage()))
{
- $package_entry = new PackageEntry();
- $package_entry->addVersion($package, $install_path, true);
- $package_entry->setName($package->getAssembly()->getPackage());
- $package_entry->setUpdateSource($package->getMetadata()->getUpdateSource());
- $this->packages[$package->getAssembly()->getPackage()] = $package_entry;
- $this->update();
+ $package_entry = new PackageEntry($package_reader->getAssembly()->getPackage());
+ $package_entry->addVersion($package_reader);
+ $this->addEntry($package_entry);
return;
}
- $this->packages[$package->getAssembly()->getPackage()]->setUpdateSource($package->getMetadata()->getUpdateSource());
- $this->packages[$package->getAssembly()->getPackage()]->addVersion($package, $install_path, true);
+ $package_entry = $this->getEntry($package_reader->getAssembly()->getPackage());
+ $package_entry->addVersion($package_reader);
+ $this->addEntry($package_entry);
+ }
+
+ /**
+ * Returns True if the package entry exists
+ *
+ * @param string $package_name
+ * @return bool
+ */
+ public function entryExists(string $package_name): bool
+ {
+ foreach($this->entries as $entry)
+ {
+ if($entry->getName() === $package_name)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns an existing package entry
+ *
+ * @param string $package_name
+ * @return PackageEntry
+ */
+ public function getEntry(string $package_name): PackageEntry
+ {
+ foreach($this->entries as $entry)
+ {
+ if($entry->getName() === $package_name)
+ {
+ return $entry;
+ }
+ }
+
+ throw new InvalidArgumentException(sprintf('Package entry %s does not exist', $package_name));
+ }
+
+ /**
+ * Adds a new package entry to the package lock file
+ *
+ * @param PackageEntry $entry
+ * @param bool $overwrite
+ * @return void
+ */
+ public function addEntry(PackageEntry $entry, bool $overwrite=true): void
+ {
+ if($this->entryExists($entry->getName()))
+ {
+ if(!$overwrite)
+ {
+ return;
+ }
+
+ $this->removeEntry($entry->getName());
+ }
+
$this->update();
+ $this->entries[] = $entry;
}
/**
- * Removes a package version entry, removes the entire entry if there are no installed versions
+ * Removes a package entry from the package lock file
*
- * @param string $package
- * @param string $version
- * @return bool
+ * @param string $package_name
+ * @return void
*/
- public function removePackageVersion(string $package, string $version): bool
+ public function removeEntry(string $package_name): void
{
- Console::outVerbose(sprintf('Removing package %s version %s from package lock file', $package, $version));
-
- if(isset($this->packages[$package]))
+ foreach($this->entries as $index => $entry)
{
- $r = $this->packages[$package]->removeVersion($version);
-
- // Remove the entire package entry if there's no installed versions
- if($r && $this->packages[$package]->getLatestVersion() === null)
+ if($entry->getName() === $package_name)
{
- unset($this->packages[$package]);
- }
-
- $this->update();
- return $r;
- }
-
- return false;
- }
-
- /**
- * Removes an entire package entry
- *
- * @param string $package
- * @return bool
- * @noinspection PhpUnused
- */
- public function removePackage(string $package): bool
- {
- Console::outVerbose(sprintf('Removing package %s from package lock file', $package));
- if(isset($this->packages[$package]))
- {
- unset($this->packages[$package]);
- $this->update();
- return true;
- }
-
- return false;
- }
-
- /**
- * Gets an existing package entry, returns null if no such entry exists
- *
- * @param string $package
- * @return PackageEntry|null
- */
- public function getPackage(string $package): ?PackageEntry
- {
- Console::outDebug(sprintf('getting package %s from package lock file', $package));
- return $this->packages[$package] ?? null;
- }
-
- /**
- * Determines if the requested package exists in the package lock
- *
- * @param string $package
- * @param string|null $version
- * @return bool
- */
- public function packageExists(string $package, ?string $version=null): bool
- {
- $package_entry = $this->getPackage($package);
-
- if($package_entry === null)
- {
- return false;
- }
-
- if($version !== null)
- {
- try
- {
- $version_entry = $package_entry->getVersion($version);
- }
- catch (IOException $e)
- {
- unset($e);
- return false;
- }
-
- if($version_entry === null)
- {
- return false;
+ unset($this->entries[$index]);
+ $this->update();
+ return;
}
}
-
- return true;
}
/**
- * Returns an array of all packages and their installed versions
+ * Returns an array of package entries
*
* @return array
*/
- public function getPackages(): array
+ public function getEntries(): array
{
- $results = [];
-
- foreach($this->packages as $package => $entry)
- {
- $results[$package] = $entry->getVersions();
- }
-
- return $results;
+ return array_map(static function(PackageEntry $entry) {
+ return $entry->getName();
+ }, $this->entries);
}
/**
+ * Returns the path where the package is installed
+ *
+ * @param string $package_name
+ * @param string $version
* @return string
*/
- public function getPackageLockVersion(): string
+ public function getPath(string $package_name, string $version): string
{
- return $this->package_lock_version;
+ return $this->getEntry($package_name)->getPath($version);
}
/**
- * @param string $package_lock_version
- */
- public function setPackageLockVersion(string $package_lock_version): void
- {
- $this->package_lock_version = $package_lock_version;
- }
-
- /**
- * @return int
- */
- public function getLastUpdatedTimestamp(): int
- {
- return $this->last_updated_timestamp;
- }
-
- /**
- * @param int $last_updated_timestamp
- */
- public function setLastUpdatedTimestamp(int $last_updated_timestamp): void
- {
- $this->last_updated_timestamp = $last_updated_timestamp;
- }
-
- /**
- * Returns an array representation of the object
- *
- * @param bool $bytecode
- * @return array
+ * @inheritDoc
*/
public function toArray(bool $bytecode=false): array
{
$package_entries = [];
- foreach($this->packages as $entry)
+ foreach($this->entries as $entry)
{
$package_entries[] = $entry->toArray($bytecode);
}
@@ -265,33 +240,30 @@
return [
($bytecode ? Functions::cbc('package_lock_version') : 'package_lock_version') => $this->package_lock_version,
($bytecode ? Functions::cbc('last_updated_timestamp') : 'last_updated_timestamp') => $this->last_updated_timestamp,
- ($bytecode ? Functions::cbc('packages') : 'packages') => $package_entries
+ ($bytecode ? Functions::cbc('entries') : 'entries') => $package_entries
];
}
/**
- * Constructs object from an array representation
- *
- * @param array $data
- * @return static
+ * @inheritDoc
+ * @throws ConfigurationException
*/
public static function fromArray(array $data): self
{
- $object = new self();
+ $entries_array = Functions::array_bc($data, 'entries') ?? [];
+ $entries = array_map(static function($entry) {
+ return PackageEntry::fromArray($entry);
+ }, $entries_array);
- $packages = Functions::array_bc($data, 'packages');
- if($packages !== null)
+
+ $package_lock_version = Functions::array_bc($data, 'package_lock_version') ?? Versions::PACKAGE_LOCK_VERSION;
+ $last_updated_timestamp = Functions::array_bc($data, 'last_updated_timestamp') ?? time();
+
+ if($package_lock_version === null)
{
- foreach($packages as $_datum)
- {
- $entry = PackageEntry::fromArray($_datum);
- $object->packages[$entry->getName()] = $entry;
- }
+ throw new ConfigurationException('Package lock version is missing');
}
- $object->package_lock_version = Functions::array_bc($data, 'package_lock_version');
- $object->last_updated_timestamp = Functions::array_bc($data, 'last_updated_timestamp');
-
- return $object;
+ return new self($entries, $package_lock_version, $last_updated_timestamp);
}
}
\ No newline at end of file
diff --git a/src/ncc/Objects/PackageLock/PackageEntry.php b/src/ncc/Objects/PackageLock/PackageEntry.php
index 63f2465..9ff7462 100644
--- a/src/ncc/Objects/PackageLock/PackageEntry.php
+++ b/src/ncc/Objects/PackageLock/PackageEntry.php
@@ -24,18 +24,23 @@
namespace ncc\Objects\PackageLock;
- use ncc\Enums\Scopes;
+ use InvalidArgumentException;
+ use ncc\Classes\PackageReader;
+ use ncc\Enums\FileDescriptor;
use ncc\Enums\Versions;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
+ use ncc\Exceptions\PathNotFoundException;
+ use ncc\Extensions\ZiProto\ZiProto;
use ncc\Interfaces\BytecodeObjectInterface;
- use ncc\Objects\Package;
+ use ncc\Objects\Package\Metadata;
+ use ncc\Objects\ProjectConfiguration\Assembly;
+ use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
+ use ncc\Objects\ProjectConfiguration\Installer;
use ncc\Objects\ProjectConfiguration\UpdateSource;
use ncc\ThirdParty\jelix\Version\VersionComparator;
- use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
use ncc\Utilities\Functions;
- use ncc\Utilities\PathFinder;
- use ncc\Utilities\Resolver;
+ use ncc\Utilities\IO;
class PackageEntry implements BytecodeObjectInterface
{
@@ -46,13 +51,6 @@
*/
private $name;
- /**
- * The latest version of the package entry, this is updated automatically
- *
- * @var string|null
- */
- private $latest_version;
-
/**
* An array of installed versions for this package
*
@@ -70,25 +68,114 @@
/**
* Public Constructor
*/
- public function __construct()
+ public function __construct(string $name, array $versions=[])
{
- $this->versions = [];
+ $this->name = $name;
+ $this->versions = $versions;
}
/**
- * Searches and returns a version of the package
+ * Returns the name of the package entry
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * Optional. Returns the update source of the package entry
+ *
+ * @return UpdateSource|null
+ */
+ public function getUpdateSource(): ?UpdateSource
+ {
+ return $this->update_source;
+ }
+
+ /**
+ * Returns the path to where the package is installed
*
* @param string $version
- * @param bool $throw_exception
- * @return VersionEntry|null
- * @throws IOException
+ * @return string
*/
- public function getVersion(string $version, bool $throw_exception=false): ?VersionEntry
+ public function getPath(string $version): string
{
- if($version === Versions::LATEST && $this->latest_version !== null)
+ return $this->getVersion($version)->getPath($this->name);
+ }
+
+ /**
+ * Adds a new version entry to the package, if overwrite is true then
+ * the entry will be overwritten if it exists, otherwise it will return
+ * false.
+ *
+ * @param PackageReader $package_reader
+ * @param bool $overwrite
+ * @return bool
+ * @throws ConfigurationException
+ */
+ public function addVersion(PackageReader $package_reader, bool $overwrite=false): bool
+ {
+ if($this->versionExists($package_reader->getAssembly()->getVersion()))
{
- /** @noinspection CallableParameterUseCaseInTypeContextInspection */
- $version = $this->latest_version;
+ if(!$overwrite)
+ {
+ return false;
+ }
+
+ $this->removeVersion($package_reader->getAssembly()->getVersion());
+ }
+
+ $version_entry = new VersionEntry($package_reader->getAssembly()->getVersion());
+ $version_entry->setMainExecutionPolicy($package_reader->getMetadata()->getMainExecutionPolicy());
+
+ //foreach($package_reader->getDependencies() as $dependency)
+ //{
+ // TODO: Implement this functionality
+ //}
+
+ foreach($package_reader->getExecutionUnits() as $unit)
+ {
+ $version_entry->addExecutionPolicy($package_reader->getExecutionUnit($unit)->getExecutionPolicy());
+ }
+
+ $this->versions[] = $version_entry;
+ $this->update_source =$package_reader->getMetadata()->getUpdateSource();
+
+ return true;
+ }
+
+ /**
+ * Returns True if the given version exists in the entry
+ *
+ * @param string $version
+ * @return bool
+ */
+ public function versionExists(string $version): bool
+ {
+ foreach($this->versions as $versionEntry)
+ {
+ if($versionEntry->getVersion() === $version)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a version entry by version
+ *
+ * @param string $version
+ * @return VersionEntry
+ */
+ public function getVersion(string $version): VersionEntry
+ {
+ if($version === Versions::LATEST)
+ {
+ $version = $this->getLatestVersion();
}
foreach($this->versions as $versionEntry)
@@ -99,20 +186,54 @@
}
}
- if($throw_exception)
- {
- throw new IOException(sprintf('Version %s of %s is not installed', $version, $this->name));
- }
-
- return null;
+ throw new InvalidArgumentException(sprintf('Version %s does not exist in package %s', $version, $this->name));
}
/**
- * Removes version entry from the package
+ * Updates and returns the latest version of this package entry
+ *
+ * @return string
+ */
+ private function getLatestVersion(): string
+ {
+ $latest_version = null;
+
+ foreach($this->versions as $version)
+ {
+ $version = $version->getVersion();
+
+ if($latest_version === null)
+ {
+ $latest_version = $version;
+ continue;
+ }
+
+ if(VersionComparator::compareVersion($version, $latest_version))
+ {
+ $latest_version = $version;
+ }
+ }
+
+ return $latest_version;
+ }
+
+ /**
+ * Returns an array of all versions installed
+ *
+ * @return array
+ */
+ public function getVersions(): array
+ {
+ return array_map(static function(VersionEntry $versionEntry) {
+ return $versionEntry->getVersion();
+ }, $this->versions);
+ }
+
+ /**
+ * Removes version entry from the package entry
*
* @param string $version
* @return bool
- * @noinspection PhpUnused
*/
public function removeVersion(string $version): bool
{
@@ -133,7 +254,6 @@
if($found_node)
{
unset($this->versions[$count]);
- $this->updateLatestVersion();
return true;
}
@@ -141,157 +261,121 @@
}
/**
- * Adds a new version entry to the package, if overwrite is true then
- * the entry will be overwritten if it exists, otherwise it will return
- * false.
+ * Returns the assembly of the package entry
*
- * @param Package $package
- * @param string $install_path
- * @param bool $overwrite
- * @return bool
- */
- public function addVersion(Package $package, string $install_path, bool $overwrite=false): bool
- {
- try
- {
- if ($this->getVersion($package->getAssembly()->getVersion()) !== null)
- {
- if(!$overwrite)
- {
- return false;
- }
-
- $this->removeVersion($package->getAssembly()->getVersion());
- }
- }
- catch (IOException $e)
- {
- unset($e);
- }
-
- $version = new VersionEntry();
- $version->setVersion($package->getAssembly()->getVersion());
- $version->setCompiler($package->getMetadata()->getCompilerExtension());
- $version->setExecutionUnits($package->getExecutionUnits());
- $version->main_execution_policy = $package->getMainExecutionPolicy();
- $version->location = $install_path;
-
- foreach($version->getExecutionUnits() as $unit)
- {
- $unit->setData(null);
- }
-
- foreach($package->getDependencies() as $dependency)
- {
- $version->addDependency(new DependencyEntry($dependency));
- }
-
- $this->versions[] = $version;
- $this->updateLatestVersion();
- return true;
- }
-
- /**
- * Updates and returns the latest version of this package entry
- *
- * @return void
- */
- private function updateLatestVersion(): void
- {
- $latest_version = null;
-
- foreach($this->versions as $version)
- {
- $version = $version->getVersion();
-
- if($latest_version === null)
- {
- $latest_version = $version;
- continue;
- }
-
- if(VersionComparator::compareVersion($version, $latest_version))
- {
- $latest_version = $version;
- }
- }
-
- $this->latest_version = $latest_version;
- }
-
- /**
- * @return string|null
- */
- public function getLatestVersion(): ?string
- {
- return $this->latest_version;
- }
-
- /**
- * Returns an array of all versions installed
- *
- * @return array
- */
- public function getVersions(): array
- {
- $r = [];
-
- foreach($this->versions as $version)
- {
- $r[] = $version->getVersion();
- }
-
- return $r;
-
- }
-
- /**
- * @return string
+ * @param string $version
+ * @return Assembly
* @throws ConfigurationException
+ * @throws IOException
+ * @throws PathNotFoundException
*/
- public function getDataPath(): string
+ public function getAssembly(string $version=Versions::LATEST): Assembly
{
- $path = PathFinder::getPackageDataPath($this->name);
-
- if(!file_exists($path) && Resolver::resolveScope() === Scopes::SYSTEM)
+ $assembly_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::ASSEMBLY;
+ if(!is_file($assembly_path))
{
- $filesystem = new Filesystem();
- $filesystem->mkdir($path);
+ throw new IOException(sprintf('Assembly file for package %s version %s does not exist (Expected %s)', $this->name, $version, $assembly_path));
}
- return $path;
+ return Assembly::fromArray(ZiProto::decode(IO::fread($assembly_path)));
}
/**
+ * Returns the metadata of the package entry
+ *
+ * @param string $version
+ * @return Metadata
+ * @throws ConfigurationException
+ * @throws IOException
+ * @throws PathNotFoundException
+ */
+ public function getMetadata(string $version=Versions::LATEST): Metadata
+ {
+ $metadata_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::METADATA;
+ if(!is_file($metadata_path))
+ {
+ throw new IOException(sprintf('Metadata file for package %s version %s does not exist (Expected %s)', $this->name, $version, $metadata_path));
+ }
+
+ return Metadata::fromArray(ZiProto::decode(IO::fread($metadata_path)));
+ }
+
+ /**
+ * Optional. Returns the installer details of the package entry
+ *
+ * @param string $version
+ * @return Installer|null
+ * @throws IOException
+ * @throws PathNotFoundException
+ */
+ public function getInstaller(string $version=Versions::LATEST): ?Installer
+ {
+ $installer_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::INSTALLER;
+ if(!is_file($installer_path))
+ {
+ return null;
+ }
+
+ return Installer::fromArray(ZiProto::decode(IO::fread($installer_path)));
+ }
+
+ /**
+ * Returns the class map of the package entry
+ *
+ * @param string $version
+ * @return array
+ * @throws IOException
+ * @throws PathNotFoundException
+ */
+ public function getClassMap(string $version=Versions::LATEST): array
+ {
+ $class_map_path = $this->getPath($version) . DIRECTORY_SEPARATOR . FileDescriptor::CLASS_MAP;
+ if(!is_file($class_map_path))
+ {
+ return [];
+ }
+
+ return ZiProto::decode(IO::fread($class_map_path));
+ }
+
+ /**
+ * Returns the execution policy of the package entry
+ *
+ * @param string $policy_name
+ * @param string $version
+ * @return ExecutionPolicy
+ * @throws ConfigurationException
+ * @throws IOException
+ * @throws PathNotFoundException
+ */
+ public function getExecutionPolicy(string $policy_name, string $version=Versions::LATEST): ExecutionPolicy
+ {
+ $execution_policy_path = $this->getPath($version) . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $policy_name . '.policy';
+ if(!is_file($execution_policy_path))
+ {
+ throw new IOException(sprintf('Execution policy %s for package %s version %s does not exist (Expected %s)', $policy_name, $this->name, $version, $execution_policy_path));
+ }
+
+ return ExecutionPolicy::fromArray(ZiProto::decode(IO::fread($execution_policy_path)));
+ }
+
+ /**
+ * Returns the path to the execution binary of the package entry of a given policy name
+ *
+ * @param string $policy_name
+ * @param string $version
* @return string
+ * @throws IOException
*/
- public function getName(): string
+ public function getExecutionBinaryPath(string $policy_name, string $version=Versions::LATEST): string
{
- return $this->name;
- }
+ $execution_binary_path = $this->getPath($version) . DIRECTORY_SEPARATOR . 'units' . DIRECTORY_SEPARATOR . $policy_name;
+ if(!is_file($execution_binary_path))
+ {
+ throw new IOException(sprintf('Execution binary %s for package %s version %s does not exist (Expected %s)', $policy_name, $this->name, $version, $execution_binary_path));
+ }
- /**
- * @param string $name
- */
- public function setName(string $name): void
- {
- $this->name = $name;
- }
-
- /**
- * @return UpdateSource|null
- */
- public function getUpdateSource(): ?UpdateSource
- {
- return $this->update_source;
- }
-
- /**
- * @param UpdateSource|null $update_source
- */
- public function setUpdateSource(?UpdateSource $update_source): void
- {
- $this->update_source = $update_source;
+ return $execution_binary_path;
}
/**
@@ -311,7 +395,6 @@
return [
($bytecode ? Functions::cbc('name') : 'name') => $this->name,
- ($bytecode ? Functions::cbc('latest_version') : 'latest_version') => $this->latest_version,
($bytecode ? Functions::cbc('versions') : 'versions') => $versions,
($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->update_source?->toArray($bytecode)),
];
@@ -322,28 +405,26 @@
*
* @param array $data
* @return PackageEntry
+ * @throws ConfigurationException
*/
public static function fromArray(array $data): PackageEntry
{
- $object = new self();
+ $name = Functions::array_bc($data, 'name');
+ $raw_versions = Functions::array_bc($data, 'versions') ?? [];
+ $versions = [];
- $object->name = Functions::array_bc($data, 'name');
- $object->latest_version = Functions::array_bc($data, 'latest_version');
+ if($name === null)
+ {
+ throw new ConfigurationException('PackageEntry is missing name');
+ }
+
+ foreach($raw_versions as $raw_version)
+ {
+ $versions[] = VersionEntry::fromArray($raw_version);
+ }
+
+ $object = new self($name, $versions);
$object->update_source = Functions::array_bc($data, 'update_source');
- $versions = Functions::array_bc($data, 'versions');
-
- if($object->update_source !== null)
- {
- $object->update_source = UpdateSource::fromArray($object->update_source);
- }
-
- if($versions !== null)
- {
- foreach($versions as $_datum)
- {
- $object->versions[] = VersionEntry::fromArray($_datum);
- }
- }
return $object;
}
diff --git a/src/ncc/Objects/PackageLock/VersionEntry.php b/src/ncc/Objects/PackageLock/VersionEntry.php
index 6081584..97900c5 100644
--- a/src/ncc/Objects/PackageLock/VersionEntry.php
+++ b/src/ncc/Objects/PackageLock/VersionEntry.php
@@ -24,11 +24,11 @@
namespace ncc\Objects\PackageLock;
+ use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
- use ncc\Objects\InstallationPaths;
- use ncc\Objects\Package\ExecutionUnit;
- use ncc\Objects\ProjectConfiguration\Compiler;
+ use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Utilities\Functions;
+ use ncc\Utilities\PathFinder;
class VersionEntry implements BytecodeObjectInterface
{
@@ -39,13 +39,6 @@
*/
private $version;
- /**
- * The compiler extension used for the package
- *
- * @var Compiler
- */
- private $compiler;
-
/**
* An array of packages that this package depends on
*
@@ -54,9 +47,9 @@
private $dependencies;
/**
- * @var ExecutionUnit[]
+ * @var ExecutionPolicy[]
*/
- public $execution_units;
+ public $execution_policies;
/**
* The main execution policy for this version entry if applicable
@@ -65,33 +58,20 @@
*/
public $main_execution_policy;
- /**
- * The path where the package is located
- *
- * @var string
- */
- public $location;
-
/**
* Public Constructor
*/
- public function __construct()
+ public function __construct(string $version)
{
+ $this->version = $version;
$this->dependencies = [];
- $this->execution_units = [];
+ $this->execution_policies = [];
+ $this->main_execution_policy = null;
}
/**
- * Returns installation paths
+ * Returns the version of the package that's installed
*
- * @return InstallationPaths
- */
- public function getInstallPaths(): InstallationPaths
- {
- return new InstallationPaths($this->location);
- }
-
- /**
* @return string
*/
public function getVersion(): string
@@ -100,71 +80,8 @@
}
/**
- * @param string $version
- */
- public function setVersion(string $version): void
- {
- $this->version = $version;
- }
-
- /**
- * @return Compiler
- */
- public function getCompiler(): Compiler
- {
- return $this->compiler;
- }
-
- /**
- * @param Compiler $compiler
- */
- public function setCompiler(Compiler $compiler): void
- {
- $this->compiler = $compiler;
- }
-
- /**
- * @return array|DependencyEntry[]
- */
- public function getDependencies(): array
- {
- return $this->dependencies;
- }
-
- /**
- * @param array|DependencyEntry[] $dependencies
- */
- public function setDependencies(array $dependencies): void
- {
- $this->dependencies = $dependencies;
- }
-
- /**
- * @param DependencyEntry $dependency
- * @return void
- */
- public function addDependency(DependencyEntry $dependency): void
- {
- $this->dependencies[] = $dependency;
- }
-
- /**
- * @return array|ExecutionUnit[]
- */
- public function getExecutionUnits(): array
- {
- return $this->execution_units;
- }
-
- /**
- * @param array|ExecutionUnit[] $execution_units
- */
- public function setExecutionUnits(array $execution_units): void
- {
- $this->execution_units = $execution_units;
- }
-
- /**
+ * Returns the main execution policy for this version entry if applicable
+ *
* @return string|null
*/
public function getMainExecutionPolicy(): ?string
@@ -173,27 +90,115 @@
}
/**
- * @param string|null $main_execution_policy
+ * Sets the main execution policy for this version entry if applicable
+ *
+ * @param string|null $policy
+ * @return void
*/
- public function setMainExecutionPolicy(?string $main_execution_policy): void
+ public function setMainExecutionPolicy(?string $policy): void
{
- $this->main_execution_policy = $main_execution_policy;
+ $this->main_execution_policy = $policy;
}
/**
+ * Returns an array of packages that this package depends on
+ *
+ * @return DependencyEntry[]
+ */
+ public function getDependencies(): array
+ {
+ return $this->dependencies;
+ }
+
+ /**
+ * Returns a dependency by name if it exists
+ *
+ * @param string $name
+ * @return DependencyEntry|null
+ */
+ public function getDependency(string $name): ?DependencyEntry
+ {
+ foreach($this->dependencies as $dependency)
+ {
+ if($dependency->getPackageName() === $name)
+ {
+ return $dependency;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Adds a dependency to the version entry
+ *
+ * @param DependencyEntry $dependency
+ * @return void
+ */
+ public function addDependency(DependencyEntry $dependency): void
+ {
+ if($this->getDependency($dependency->getPackageName()) !== null)
+ {
+ return;
+ }
+
+ $this->dependencies[] = $dependency;
+ }
+
+ /**
+ * Returns an array of execution policies for this version entry
+ *
+ * @return ExecutionPolicy[]
+ */
+ public function getExecutionPolicies(): array
+ {
+ return $this->execution_policies;
+ }
+
+ /**
+ * Returns the main execution policy for this version entry if it exists
+ *
+ * @param string $name
+ * @return ExecutionPolicy|null
+ */
+ public function getExecutionPolicy(string $name): ?ExecutionPolicy
+ {
+ foreach($this->execution_policies as $executionPolicy)
+ {
+ if($executionPolicy->getName() === $name)
+ {
+ return $executionPolicy;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Adds an execution policy to the version entry
+ *
+ * @param ExecutionPolicy $executionPolicy
+ * @return void
+ */
+ public function addExecutionPolicy(ExecutionPolicy $executionPolicy): void
+ {
+ if($this->getExecutionPolicy($executionPolicy->getName()) !== null)
+ {
+ return;
+ }
+
+ $this->execution_policies[] = $executionPolicy;
+ }
+
+ /**
+ * Returns the path where the package is installed
+ *
+ * @param string $package_name
* @return string
*/
- public function getLocation(): string
+ public function getPath(string $package_name): string
{
- return $this->location;
- }
-
- /**
- * @param string $location
- */
- public function setLocation(string $location): void
- {
- $this->location = $location;
+ return PathFinder::getPackagesPath() . DIRECTORY_SEPARATOR . sprintf('%s=%s', $package_name, $this->getVersion());
}
/**
@@ -210,19 +215,17 @@
$dependencies[] = $dependency->toArray($bytecode);
}
- $execution_units = [];
- foreach($this->execution_units as $executionUnit)
+ $execution_policies = [];
+ foreach($this->execution_policies as $policy)
{
- $execution_units[] = $executionUnit->toArray($bytecode);
+ $execution_policies[] = $policy->toArray($bytecode);
}
return [
($bytecode ? Functions::cbc('version') : 'version') => $this->version,
- ($bytecode ? Functions::cbc('compiler') : 'compiler') => $this->compiler->toArray(),
($bytecode ? Functions::cbc('dependencies') : 'dependencies') => $dependencies,
- ($bytecode ? Functions::cbc('execution_units') : 'execution_units') => $execution_units,
+ ($bytecode ? Functions::cbc('execution_policies') : 'execution_policies') => $execution_policies,
($bytecode ? Functions::cbc('main_execution_policy') : 'main_execution_policy') => $this->main_execution_policy,
- ($bytecode ? Functions::cbc('location') : 'location') => $this->location,
];
}
@@ -234,11 +237,15 @@
*/
public static function fromArray(array $data): VersionEntry
{
- $object = new self();
- $object->version = Functions::array_bc($data, 'version');
- $object->compiler = Compiler::fromArray(Functions::array_bc($data, 'compiler'));
+ $version = Functions::array_bc($data, 'version');
+
+ if($version === null)
+ {
+ throw new ConfigurationException('VersionEntry is missing version');
+ }
+
+ $object = new self($version);
$object->main_execution_policy = Functions::array_bc($data, 'main_execution_policy');
- $object->location = Functions::array_bc($data, 'location');
$dependencies = Functions::array_bc($data, 'dependencies');
if($dependencies !== null)
@@ -249,12 +256,12 @@
}
}
- $execution_units = Functions::array_bc($data, 'execution_units');
- if($execution_units !== null)
+ $execution_policies = Functions::array_bc($data, 'execution_policies');
+ if($execution_policies !== null)
{
- foreach($execution_units as $_datum)
+ foreach($execution_policies as $_datum)
{
- $object->execution_units[] = ExecutionUnit::fromArray($_datum);
+ $object->execution_policies[] = ExecutionPolicy::fromArray($_datum);
}
}
diff --git a/src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php b/src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php
index 9f59689..13aaaf9 100644
--- a/src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php
+++ b/src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php
@@ -436,7 +436,6 @@
public static function fromArray(array $data): BuildConfiguration
{
$name = Functions::array_bc($data, 'name');
- $build_type = Functions::array_bc($data, 'build_type');
$output_path = Functions::array_bc($data, 'output_path');
if($name === null)
@@ -451,6 +450,7 @@
$object = new BuildConfiguration($name, $output_path);
+ $object->build_type = Functions::array_bc($data, 'build_type') ?? BuildOutputType::NCC_PACKAGE;
$object->options = Functions::array_bc($data, 'options') ?? [];
$object->define_constants = Functions::array_bc($data, 'define_constants') ?? [];
$object->exclude_files = Functions::array_bc($data, 'exclude_files') ?? [];
diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php
index 80391d7..b17449f 100644
--- a/src/ncc/Objects/Vault/Entry.php
+++ b/src/ncc/Objects/Vault/Entry.php
@@ -33,7 +33,7 @@
use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword;
use ncc\Utilities\Functions;
- use ncc\ZiProto\ZiProto;
+ use ncc\Extensions\ZiProto\ZiProto;
use RuntimeException;
class Entry implements BytecodeObjectInterface
diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php
deleted file mode 100644
index 1c84a00..0000000
--- a/src/ncc/Runtime.php
+++ /dev/null
@@ -1,242 +0,0 @@
-getPackage($package)->getLatestVersion();
- }
-
- $entry = "$package=$version";
-
- return isset(self::$imported_packages[$entry]);
- }
-
- /**
- * Adds a package to the imported packages list
- *
- * @param string $package
- * @param string $version
- * @return void
- */
- private static function addImport(string $package, string $version): void
- {
- $entry = "$package=$version";
- self::$imported_packages[$entry] = true;
- }
-
-
- /**
- * @param string $package
- * @param string $version
- * @param array $options
- * @return void
- * @throws IOException
- * @throws ImportException
- */
- public static function import(string $package, string $version=Versions::LATEST, array $options=[]): void
- {
- try
- {
- $package_entry = self::getPackageManager()->getPackage($package);
- }
- catch (IOException $e)
- {
- throw new ImportException(sprintf('Failed to import package "%s" due to a package lock exception: %s', $package, $e->getMessage()), $e);
- }
-
- if($package_entry === null)
- {
- throw new ImportException(sprintf("Package '%s' not found", $package));
- }
-
- if($version === Versions::LATEST)
- {
- $version = $package_entry->getLatestVersion();
- }
-
- try
- {
- /** @var VersionEntry $version_entry */
- $version_entry = $package_entry->getVersion($version);
-
- if($version_entry === null)
- {
- throw new ImportException(sprintf('Version %s of %s is not installed', $version, $package));
- }
- }
- catch (IOException $e)
- {
- throw new ImportException(sprintf('Version %s of %s is not installed', $version, $package), $e);
- }
-
- try
- {
- if (self::isImported($package, $version))
- {
- return;
- }
- }
- catch (IOException $e)
- {
- throw new ImportException(sprintf('Failed to check if package %s is imported', $package), $e);
- }
-
- if(count($version_entry->getDependencies()) > 0)
- {
- // Import all dependencies first
- /** @var Dependency $dependency */
- foreach($version_entry->getDependencies() as $dependency)
- {
- self::import($dependency->getPackageName(), $dependency->getVersion(), $options);
- }
- }
-
- try
- {
- switch($version_entry->getCompiler()->getExtension())
- {
- case CompilerExtensions::PHP:
- PhpRuntime::import($version_entry, $options);
- break;
-
- default:
- throw new ImportException(sprintf('Compiler extension %s is not supported in this runtime', $version_entry->getCompiler()->getExtension()));
- }
- }
- catch(Exception $e)
- {
- throw new ImportException(sprintf('Failed to import package %s', $package), $e);
- }
-
- self::addImport($package, $version);
- }
-
- /**
- * Returns the data path of the package
- *
- * @param string $package
- * @return string
- * @throws ConfigurationException
- * @throws IOException
- * @throws PackageException
- */
- public static function getDataPath(string $package): string
- {
- $package = self::getPackageManager()->getPackage($package);
-
- if($package === null)
- {
- throw new PackageException('Package not found (null entry error, possible bug)');
- }
-
- return $package->getDataPath();
- }
-
- /**
- * @return PackageManager
- */
- private static function getPackageManager(): PackageManager
- {
- if(self::$package_manager === null)
- {
- self::$package_manager = new PackageManager();
- }
-
- return self::$package_manager;
- }
-
- /**
- * Returns an array of all the packages that is currently imported
- *
- * @return array
- */
- public static function getImportedPackages(): array
- {
- return array_keys(self::$imported_packages);
- }
-
- /**
- * Returns a registered constant
- *
- * @param string $package
- * @param string $name
- * @return string|null
- */
- public static function getConstant(string $package, string $name): ?string
- {
- return Constants::get($package, $name);
- }
-
- /**
- * Registers a new constant
- *
- * @param string $package
- * @param string $name
- * @param string $value
- * @return void
- * @throws IntegrityException
- */
- public static function setConstant(string $package, string $name, string $value): void
- {
- Constants::register($package, $name, $value);
- }
- }
\ No newline at end of file
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Application.php b/src/ncc/ThirdParty/theseer/Autoload/Application.php
deleted file mode 100644
index 3c1d863..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Application.php
+++ /dev/null
@@ -1,247 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- *
- */
-namespace ncc\ThirdParty\theseer\Autoload {
-
- class Application {
-
- private $logger;
- private $factory;
- private $config;
-
- public function __construct(Logger $logger, Config $config, Factory $factory) {
- $this->logger = $logger;
- $this->config = $config;
- $this->factory = $factory;
- }
-
- public function run() {
- $result = $this->runCollector();
- if (!$result->hasUnits()) {
- throw new ApplicationException('No units were found - process aborted.', ApplicationException::NoUnitsFound);
- }
- if ($result->hasDuplicates()) {
- return $this->showDuplicatesError($result->getDuplicates());
- }
-
- if ($this->config->isCacheEnabled()) {
- $this->factory->getCache()->persist($this->config->getCacheFile());
- }
-
- $template = @file_get_contents($this->config->getTemplate());
- if ($template === false) {
- throw new ApplicationException("Failed to read the template file.");
- }
-
- $builder = $this->factory->getRenderer($result);
- $code = $builder->render($template);
- if ($this->config->isLintMode()) {
- return $this->runLint($code);
- }
- return $this->runSaver($code);
- }
-
- /**
- * @return CollectorResult
- */
- private function runCollector() {
- if ($this->config->isFollowSymlinks()) {
- $this->logger->log('Following symbolic links is enabled.' . "\n\n");
- }
- $collector = $this->factory->getCollector();
- foreach ($this->config->getDirectories() as $directory) {
- if (is_dir($directory)) {
- $this->logger->log('Scanning directory ' . $directory . "\n");
- $scanner = $this->factory->getScanner()->getIterator($directory);
- $collector->processDirectory($scanner);
- // this unset is needed to "fix" a segfault on shutdown in some PHP Versions
- unset($scanner);
- } else {
- $file = new \SplFileInfo($directory);
- $filter = $this->factory->getFilter(new \ArrayIterator(array($file)));
- foreach($filter as $file) {
- $this->logger->log('Scanning file ' . $file . "\n");
- $collector->processFile($file);
- }
- }
- }
- return $collector->getResult();
- }
-
- private function runSaver($code) {
- $output = $this->config->getOutputFile();
- if (!$this->config->isPharMode()) {
- if ($output === 'STDOUT') {
- $this->logger->log("\n");
- echo $code;
- $this->logger->log("\n\n");
- return CLI::RC_OK;
- }
- // @codingStandardsIgnoreStart
- $written = @file_put_contents($output, $code);
- // @codingStandardsIgnoreEnd
- if ($written != strlen($code)) {
- $this->logger->log("Writing to file '$output' failed.", STDERR);
- return CLI::RC_EXEC_ERROR;
- }
- $this->logger->log("\nAutoload file {$output} generated.\n\n");
- return CLI::RC_OK;
- }
- if (strpos($code, '__HALT_COMPILER();') === FALSE) {
- $this->logger->log(
- "Warning: Template used in phar mode did not contain required __HALT_COMPILER() call\n" .
- "which has been added automatically. The used stub code may not work as intended.\n\n", STDERR);
- $code .= $this->config->getLinebreak() . '__HALT_COMPILER();';
- }
- $pharBuilder = $this->factory->getPharBuilder();
- if ($keyfile = $this->config->getPharKey()) {
- $pharBuilder->setSignatureKey($this->loadPharSignatureKey($keyfile));
- }
- if ($aliasName = $this->config->getPharAliasName()) {
- $pharBuilder->setAliasName($aliasName);
- }
- if ($this->config->hasPharHashAlgorithm()) {
- $pharBuilder->setSignatureType($this->config->getPharHashAlgorithm());
- }
- $pharBuilder->build($output, $code);
- $this->logger->log("\nphar archive '{$output}' generated.\n\n");
- return CLI::RC_OK;
- }
-
- private function loadPharSignatureKey($keyfile) {
- if (!extension_loaded('openssl')) {
- throw new ApplicationException('Extension for OpenSSL not loaded - cannot sign phar archive - process aborted.',
- ApplicationException::OpenSSLError);
- }
- $keydata = file_get_contents($keyfile);
- if (strpos($keydata, 'ENCRYPTED') !== FALSE) {
- $this->logger->log("Passphrase for key '$keyfile': ");
- $g = shell_exec('stty -g');
- shell_exec('stty -echo');
- $passphrase = trim(fgets(STDIN));
- $this->logger->log("\n");
- shell_exec('stty ' . $g);
- $private = openssl_pkey_get_private($keydata, $passphrase);
- } else {
- $private = openssl_pkey_get_private($keydata);
- }
- if (!$private) {
- throw new ApplicationException("Opening private key '$keyfile' failed - process aborted.\n\n", ApplicationException::OpenSSLError);
- }
- return $private;
- }
-
-
- /**
- * Execute a lint check on generated code
- *
- * @param string $code Generated code to lint
- *
- * @return boolean
- */
- protected function runLint($code) {
- $dsp = array(
- 0 => array('pipe', 'r'),
- 1 => array('pipe', 'w'),
- 2 => array('pipe', 'w')
- );
-
- $binary = $this->config->getPhp();
-
- $process = proc_open($binary . ' -l', $dsp, $pipes);
-
- if (!is_resource($process)) {
- $this->logger->log("Opening php binary for linting failed.\n", STDERR);
- return 1;
- }
-
- fwrite($pipes[0], $code);
- fclose($pipes[0]);
- fclose($pipes[1]);
-
- $stderr = stream_get_contents($pipes[2]);
- fclose($pipes[2]);
-
- $rc = proc_close($process);
-
- if ($rc == 255) {
- $this->logger->log("Syntax errors during lint:\n" .
- str_replace('in - on line', 'in generated code on line', $stderr) .
- "\n", STDERR);
- return CLI::RC_LINT_ERROR;
- }
-
- $this->logger->log("Lint check of geneated code okay\n\n");
- return CLI::RC_OK;
- }
-
- /**
- * @param array $duplicates
- *
- * @return int
- */
- private function showDuplicatesError(array $duplicates) {
- $this->logger->log(
- sprintf("\nMultiple declarations of trait(s), interface(s) or class(es). Could not generate autoload map.\n"),
- STDERR
- );
- foreach($duplicates as $unit => $files) {
- $this->logger->log(
- sprintf("\nUnit '%s' defined in:\n", $unit),
- STDERR
- );
-
- /** @var array $files */
- foreach($files as $file) {
- $this->logger->log(
- sprintf(" - %s\n", $file),
- STDERR
- );
-
- }
- }
- return CLI::RC_DUPLICATES_ERROR;
- }
-
- }
-
- class ApplicationException extends \Exception {
- const NoUnitsFound = 1;
- const OpenSSLError = 2;
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/AutoloadRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/AutoloadRenderer.php
deleted file mode 100644
index b0f4487..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/AutoloadRenderer.php
+++ /dev/null
@@ -1,297 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- */
-
-namespace ncc\ThirdParty\theseer\Autoload {
-
- /**
- * Builds spl based autoload code for inclusion into projects
- *
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- */
- class AutoloadRenderer {
-
- /**
- * Associative array of classes (key) and the files (value) they are in
- *
- * @var array
- */
- protected $classes;
-
- /**
- * An optional base dir to strip for the realpath of the filename
- *
- * @var string
- */
- protected $baseDir = '';
-
- /**
- * Indenting char(s)
- *
- * @var string
- */
- protected $indent = ' ';
-
- /**
- * Char(s) used as linebreak
- *
- * @var string
- */
- protected $linebreak = "\n";
-
- /**
- * Timestamp of production start
- *
- * @var integer
- */
- protected $timestamp;
-
- /**
- * Format string supplied to date() for use with ___CREATED___
- *
- * @var string
- */
- protected $dateformat = 'r';
-
- /**
- * Variables for templates
- *
- * @var array
- */
- protected $variables = array();
-
- /**
- * Flag to toggle PHP 5.2 compat mode
- *
- * @var boolean
- */
- protected $compat = false;
-
- /**
- * Flag to pass on to spl_autoload_register to prepend
- *
- * @var bool
- */
- private $usePrepend = false;
-
- /**
- * Flag to pass on to spl_autoload_register to optionally throw exceptions on registration error
- *
- * @var bool
- */
- private $throwExceptions = false;
-
- /**
- * Constructor of AutoloadRenderer class
- *
- * @param array $classlist Array of classes
- *
- */
- public function __construct(array $classlist) {
- $this->classes = $classlist;
- ksort($this->classes);
- }
-
- /**
- * Toggle PHP 5.2 compat mode
- *
- * @param boolean $mode Mode to set compat to
- */
- public function setCompat($mode) {
- $this->compat = $mode;
- }
-
- public function enableExceptions() {
- $this->throwExceptions = true;
- }
-
- public function prependAutoloader() {
- $this->usePrepend = true;
- }
-
- /**
- * Setter for the Basedir
- *
- * @param string $dir Path to strip from beginning of filenames
- *
- * @return void
- */
- public function setBaseDir($dir) {
- $this->baseDir = $dir;
- }
-
- /**
- * Overwrite default or previously set indenting option
- *
- * @param string $indent Char(s) to use for indenting
- *
- * @return void
- */
- public function setIndent($indent) {
- $this->indent = $indent;
- }
-
- /**
- * Overwrite default or previously set linebreak chars
- *
- * @param string $lbs Code to set linebreak
- *
- * @return void
- */
- public function setLineBreak($lbs) {
- $this->linebreak = $lbs;
- }
-
- /**
- * Accessor for current linebreak setting
- *
- * @return string
- */
- public function getLineBreak() {
- return $this->linebreak;
- }
-
- /**
- * Setter to use allow usage of fixed date/time for ___CREATED___
- *
- * @param integer $time unix timestamp
- *
- * @throws AutoloadBuilderException
- */
- public function setTimestamp($time) {
- if (!is_int($time) && null !== $time) {
- throw new AutoloadBuilderException("'$time' is not a unix timestamp", AutoloadBuilderException::InvalidTimestamp);
- }
- $this->timestamp = $time;
- }
-
- /**
- * Setter to adjust the date/time format output of ___CREATED___
- *
- * @param string $frmt Date/Time format string
- */
- public function setDateTimeFormat($frmt) {
- $this->dateformat = $frmt;
- }
-
- /**
- * Set a variable for use with template code
- *
- * @param string $name Key name (use as ___key___ in template)
- * @param string $value Value to use
- */
- public function setVariable($name, $value) {
- $this->variables['___'.$name.'___'] = $value;
- }
-
-
- /**
- * Resolve relative location of file path to basedir if one is set and fix potential
- * broken windows pathnames when run on windows.
- *
- * @param string $fname
- *
- * @return string
- */
- protected function resolvePath($fname) {
- if (empty($this->baseDir)) {
- return str_replace('\\', '/', $fname);
- }
- $basedir = explode(DIRECTORY_SEPARATOR, $this->baseDir);
- $filedir = explode(DIRECTORY_SEPARATOR, dirname(realpath($fname)));
- $pos = 0;
- $max = count($basedir);
- while (isset($filedir[$pos]) && $filedir[$pos] == $basedir[$pos]) {
- $pos++;
- if ($pos == $max) {
- break;
- }
- }
- if ($pos == 0) {
- return str_replace('\\', '/', $fname);
- }
- $rel = join('/', array_slice($filedir, $pos));
- if (!empty($rel)) {
- $rel .= '/';
- }
- if ($posclasses as $class => $file) {
- $fname = $this->resolvePath($file);
- $entries[] = "'". addslashes($class). "' => '$fname'";
- }
-
- $baseDir = '';
- if ($this->baseDir) {
- $baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . ';
- }
-
- $replace = array_merge($this->variables, array(
- '___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()),
- '___CLASSLIST___' => join( ',' . $this->linebreak . $this->indent, $entries),
- '___BASEDIR___' => $baseDir,
- '___AUTOLOAD___' => 'autoload' . md5(serialize($entries)),
- '___EXCEPTION___' => $this->throwExceptions ? 'true' : 'false',
- '___PREPEND___' => $this->usePrepend ? 'true' : 'false'
- ));
- return str_replace(array_keys($replace), array_values($replace), $template);
- }
-
- }
-
-
- class AutoloadBuilderException extends \Exception {
-
- const TemplateNotFound = 1;
- const InvalidTimestamp = 2;
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/CLI.php b/src/ncc/ThirdParty/theseer/Autoload/CLI.php
deleted file mode 100644
index b3ee9e2..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/CLI.php
+++ /dev/null
@@ -1,607 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- */
-
-namespace ncc\ThirdParty\theseer\Autoload {
-
- /**
- * CLI interface to AutoloadRenderer / StaticRenderer
- *
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- */
- class CLI {
-
- const RC_OK = 0;
- const RC_EXEC_ERROR = 1;
- const RC_PARAM_ERROR = 3;
- const RC_LINT_ERROR = 4;
- const RC_DUPLICATES_ERROR = 5;
-
- private $pharOption;
- private $staticOption;
- private $helpOption;
- private $versionOption;
- private $onceOption;
-
- /**
- * @var Factory
- */
- private $factory;
-
-
- public function __construct(Factory $factory) {
- $this->factory = $factory;
- }
-
- /**
- * Main executor method
- *
- * @return void
- */
- public function run() {
-
- try {
-
- $this->preBootstrap();
-
- $input = $this->setupInput();
- $input->process();
-
- if ($input->getOption('help')->value === TRUE) {
- $this->showVersion();
- $this->showUsage();
- exit(CLI::RC_OK);
- }
-
- if ($input->getOption('version')->value === TRUE ) {
- $this->showVersion();
- exit(CLI::RC_OK);
- }
-
- $config = $this->configure($input);
- $this->factory->setConfig($config);
- if (!$config->isQuietMode()) {
- $this->showVersion();
- }
- $rc = $this->factory->getApplication()->run();
- exit($rc);
-
- } catch (CLIEnvironmentException $e) {
- $this->showVersion();
- fwrite(STDERR, 'Sorry, but your PHP environment is currently not able to run phpab due to');
- fwrite(STDERR, "\nthe following issue(s):\n\n" . $e->getMessage() . "\n\n");
- fwrite(STDERR, "Please adjust your PHP configuration and try again.\n\n");
- exit(CLI::RC_EXEC_ERROR);
- } catch (\ezcConsoleException $e) {
- $this->showVersion();
- echo $e->getMessage() . "\n\n";
- $this->showUsage();
- exit(CLI::RC_PARAM_ERROR);
- } catch (CollectorException $e) {
- switch($e->getCode()) {
- case CollectorException::InFileRedeclarationFound:
- case CollectorException::RedeclarationFound:
- case CollectorException::ParseErrror: {
- $message = $e->getMessage();
- break;
- }
- default: {
- $message = 'Unexpected error in collector process: ' . $e->getMessage() . "\n\nPlease report this as a bug.\n\n";
- }
- }
- $this->showVersion();
- fwrite(STDERR, $message . "\n\n");
- exit(CLI::RC_EXEC_ERROR);
- } catch (\Exception $e) {
- $this->showVersion();
- fwrite(STDERR, "\nError while processing request:\n - " . $e->getMessage()."\n");
- exit(CLI::RC_EXEC_ERROR);
- }
-
- }
-
- /**
- * @param \ezcConsoleInput $input
- *
- * @return \ncc\ThirdParty\theseer\Autoload\Config
- */
- private function configure(\ezcConsoleInput $input) {
- $config = new Config($input->getArguments());
- if ($input->getOption('quiet')->value) {
- $config->setQuietMode(TRUE);
- }
- if ($input->getOption('compat')->value) {
- $config->setCompatMode(TRUE);
- }
- if ($input->getOption('tolerant')->value) {
- $config->setTolerantMode(TRUE);
- }
- if ($output = $input->getOption('output')->value) {
- $config->setOutputFile($output);
- }
- if ($input->getOption('phar')->value) {
- $compression = \Phar::NONE;
- if ($input->getOption('bzip2')->value === TRUE) {
- $compression = \Phar::BZ2;
- } else if ($input->getOption('gzip')->value === TRUE) {
- $compression = \Phar::GZ;
- }
- $config->enablePharMode(
- $compression,
- $input->getOption('all')->value,
- $input->getOption('key')->value,
- $input->getOption('alias')->value
- );
- $config->setVariable('PHAR',
- $input->getOption('alias')->value ? $input->getOption('alias')->value : basename($output)
- );
- if ($hashAlgorithm = $input->getOption('hash')->value) {
- $config->setPharHashAlgorithm($hashAlgorithm);
- }
- }
-
- if ($input->getOption('cache')->value) {
- $config->setCacheFile($input->getOption('cache')->value);
- }
-
- if ($basedir = $input->getOption('basedir')->value) {
- $config->setBaseDirectory($basedir);
- }
-
- $include = $input->getOption('include')->value;
- if (!is_array($include)) {
- $include = array($include);
- }
- $config->setInclude($include);
-
- if ($exclude = $input->getOption('exclude')->value) {
- if (!is_array($exclude)) {
- $exclude = array($exclude);
- }
- $config->setExclude($exclude);
- }
-
- $whitelist = $input->getOption('whitelist')->value;
- if (!is_array($whitelist)) {
- $whitelist = array($whitelist);
- }
- $config->setWhitelist($whitelist);
-
- if ($blacklist = $input->getOption('blacklist')->value) {
- if (!is_array($blacklist)) {
- $blacklist = array($blacklist);
- }
- $config->setBlacklist($blacklist);
- }
-
- if ($input->getOption('static')->value) {
- $config->setStaticMode(TRUE);
- }
- if ($input->getOption('once')->value) {
- $config->setOnceMode(TRUE);
- }
-
- if ($input->getOption('warm')->value) {
- $config->setWarmMode(TRUE);
- }
- if ($input->getOption('reset')->value) {
- $config->setResetMode(TRUE);
- }
-
- if ($input->getOption('follow')->value) {
- $config->setFollowSymlinks(TRUE);
- }
-
- if ($input->getOption('prepend')->value) {
- $config->enablePrepend();
- }
-
- if ($input->getOption('no-exception')->value) {
- $config->disableExceptions();
- }
-
- $indent = $input->getOption('indent')->value;
- if ($indent !== FALSE) {
- $config->setIndent($indent);
- }
- if ($template = $input->getOption('template')->value) {
- $config->setTemplate($template);
- }
- if ($linebreak = $input->getOption('linebreak')->value) {
- $config->setLinebreak($linebreak);
- }
- if ($input->getOption('nolower')->value) {
- $config->setLowercaseMode(FALSE);
- }
- if ($variables = $input->getOption('var')->value) {
- foreach($variables as $var) {
- if (strpos($var, '=')===FALSE) {
- throw new \RuntimeException("Variable defintion '$var' is invalid and cannot be processed.");
- }
- list($name, $value) = explode('=', $var, 2);
- $config->setVariable($name, $value);
- }
- }
-
- if ($input->getOption('paranoid')->value || !$input->getOption('trusting')->value) {
- $config->setTrusting(FALSE);
- }
-
- return $config;
- }
-
- /**
- * Helper to output version information
- */
- protected function showVersion() {
- static $shown = false;
- if (!$shown) {
- $shown = true;
- echo Version::getInfoString() . "\n\n";
- }
- }
-
- /**
- * Helper to output usage information
- */
- protected function showUsage() {
- print << [...]
-
- -i, --include File pattern to include (default: *.php)
- -e, --exclude File pattern to exclude
-
- --blacklist Blacklist classname or namespace (wildcards supported)
- --whitelist Whitelist classname or namespace (wildcards supported)
-
- -b, --basedir Basedir for filepaths
- -t, --template Path to code template to use
-
- -o, --output Output file for generated code (default: STDOUT)
-
- -p, --phar Create a phar archive (requires -o )
- --all Include all files in given directory when creating a phar
- --alias Specify explicit internal phar alias filename (default: output filename)
- --hash Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p, conflicts with --key)
- --bzip2 Compress phar archive using bzip2 (requires -p) (bzip2 required)
- --gzip Compress phar archive using gzip (requires -p) (gzip required)
- --key OpenSSL key file to use for signing phar archive (requires -p) (openssl required)
-
- -c, --compat Generate PHP 5.2 compatible code
- -s, --static Generate a static require file
-
- -w, --warm Generate a static opcache warming file
- --reset Add opcache reset call when generating opcache warming file
-
- -1, --prepend Register as first autoloader (prepend to stack, default: append)
- -d, --no-exception Do not throw exception on registration problem (default: throw exception)
-
- -n, --nolower Do not lowercase classnames for case insensitivity
-
- -q, --quiet Quiet mode, do not output any processing errors or information
-
- --cache Enable caching and set filename to use for cache storage
-
- --follow Enables following symbolic links (not compatible with phar mode)
- --format Dateformat string for timestamp
- --linebreak Linebreak style (CR, CRLF or LF, default: LF)
- --indent String used for indenting or number of spaces (default: 16 (compat 12) spaces)
-
- --tolerant Ignore Class Redeclarations in the same file
- --once Use require_once instead of require when creating a static require file
-
-
- --trusting Do not check mimetype of files prior to parsing (default)
- --paranoid Do check mimetype of files prior to parsing
-
- --var name=foo Assign value 'foo' to variable 'name' to be used in (custom) templates
-
- --lint Run lint on generated code and exit
- --lint-php PHP binary to use for linting (default: /usr/bin/php or c:\php\php.exe)
-
- -h, --help Prints this usage information
- -v, --version Prints the version and exits
-
-EOF;
- }
-
- /**
- * @return \ezcConsoleInput
- */
- protected function setupInput() {
- $input = new \ezcConsoleInput();
-
- $this->versionOption = $input->registerOption( new \ezcConsoleOption( 'v', 'version' ) );
- $this->versionOption->shorthelp = 'Prints the version and exits';
- $this->versionOption->isHelpOption = TRUE;
-
- $this->helpOption = $input->registerOption( new \ezcConsoleOption( 'h', 'help' ) );
- $this->helpOption->isHelpOption = TRUE;
- $this->helpOption->shorthelp = 'Prints this usage information';
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'cache', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Enable cache and set cache filename'
- ));
-
- $this->outputOption = $input->registerOption( new \ezcConsoleOption(
- 'o', 'output', \ezcConsoleInput::TYPE_STRING, 'STDOUT', FALSE,
- 'Output file for generated code (default: STDOUT)'
- ));
-
- $this->pharOption = $input->registerOption( new \ezcConsoleOption(
- 'p', 'phar', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Build a phar archive of directory contents',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'o' ) ) )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'all', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Add all files from src dir to phar',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'alias', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Provide explicit internal alias filename for phar',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
- ));
-
- $bzip2 = $input->registerOption( new \ezcConsoleOption(
- '', 'bzip2', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Compress files phar with bzip2',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
- ));
-
- $gzip = $input->registerOption( new \ezcConsoleOption(
- '', 'gzip', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Compress files phar with gzip',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ),
- array( new \ezcConsoleOptionRule( $bzip2 ) )
- ));
- $bzip2->addExclusion(new \ezcConsoleOptionRule($gzip));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'key', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Keyfile to use for signing phar archive',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) )
- ));
-
- $this->outputOption = $input->registerOption( new \ezcConsoleOption(
- '', 'hash', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Force given hash algorithm (SHA-1, SHA-256 or SHA-512) (requires -p)',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'p' ) ) ),
- array( new \ezcConsoleOptionRule( $input->getOption( 'key' ) ) )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 'i', 'include', \ezcConsoleInput::TYPE_STRING, '*.php', TRUE,
- 'File pattern to include (default: *.php)'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'blacklist', \ezcConsoleInput::TYPE_STRING, NULL, TRUE,
- 'Name pattern to exclude'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'whitelist', \ezcConsoleInput::TYPE_STRING, '*', TRUE,
- 'Name pattern to include (default: *)'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 'e', 'exclude', \ezcConsoleInput::TYPE_STRING, NULL, TRUE,
- 'File pattern to exclude'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 'b', 'basedir', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Basedir for filepaths'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 't', 'template', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Path to code template to use'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'follow', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Enables following symbolic links',
- NULL,
- array(),
- array( new \ezcConsoleOptionRule($this->pharOption) )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'format', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Dateformat string for timestamp'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'linebreak', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'Linebreak style (CR, CR/LF or LF)'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'indent', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'String used for indenting (default: 3 spaces)'
- ));
-
- $this->lintOption = $input->registerOption( new \ezcConsoleOption(
- '', 'lint', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Run lint on generated code'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'lint-php', \ezcConsoleInput::TYPE_STRING, NULL, FALSE,
- 'PHP binary path for linting (default: /usr/bin/php or c:\\php\\php.exe)',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 'lint' ) ) )
- ));
-
- $compat = $input->registerOption( new \ezcConsoleOption(
- 'c', 'compat', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Generate PHP 5.2 compliant code'
- ));
-
- $this->staticOption = $input->registerOption( new \ezcConsoleOption(
- 's', 'static', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Build a static require file'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'tolerant', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Ignore Class Redeclarations in the same file'
- ));
-
- $trusting = $input->registerOption( new \ezcConsoleOption(
- '', 'trusting', \ezcConsoleInput::TYPE_NONE, TRUE, FALSE,
- 'Do not check mimetype of files prior to parsing'
- ));
- $paranoid = $input->registerOption( new \ezcConsoleOption(
- '', 'paranoid', \ezcConsoleInput::TYPE_NONE, FALSE, FALSE,
- 'Do check mimetype of files prior to parsing',
- NULL,
- array(),
- array( new \ezcConsoleOptionRule($trusting) )
- ));
- $trusting->addExclusion(new \ezcConsoleOptionRule($paranoid));
-
- $this->onceOption = $input->registerOption( new \ezcConsoleOption(
- '', 'once', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Use require_once in static require mode',
- NULL,
- array( new \ezcConsoleOptionRule( $input->getOption( 's' ) ) )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 'n', 'nolower', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Do not lowercase classnames for case insensitivity'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 'q', 'quiet', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Run in quiet mode, no output'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '1', 'prepend', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Prepend autoloader to stack',
- NULL,
- array(),
- array( new \ezcConsoleOptionRule( $compat ) )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- 'd', 'no-exception', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'Disable exceptions on registration error'
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'var', \ezcConsoleInput::TYPE_STRING, array(), TRUE,
- 'Assign variable'
- ));
-
- $warm = $input->registerOption( new \ezcConsoleOption(
- 'w', 'warm', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'generate opcache warming file',
- NULL,
- array(),
- array(
- new \ezcConsoleOptionRule($this->pharOption),
- new \ezcConsoleOptionRule($this->staticOption)
- )
- ));
-
- $input->registerOption( new \ezcConsoleOption(
- '', 'reset', \ezcConsoleInput::TYPE_NONE, NULL, FALSE,
- 'add reset call to generated opcache warming file',
- NULL,
- array(
- new \ezcConsoleOptionRule($warm)
- )
- ));
-
- $input->argumentDefinition = new \ezcConsoleArguments();
- $input->argumentDefinition[0] = new \ezcConsoleArgument('directory');
- $input->argumentDefinition[0]->shorthelp = 'The directory to process.';
- $input->argumentDefinition[0]->multiple = TRUE;
-
- return $input;
- }
-
- private function preBootstrap() {
- $required = array('tokenizer', 'fileinfo');
- $missing = array();
- foreach($required as $test) {
- if (!extension_loaded($test)) {
- $missing[] = sprintf('ext/%s not installed/enabled', $test);
- }
- }
- if (count($missing)) {
- throw new CLIEnvironmentException(
- join("\n", $missing),
- CLIEnvironmentException::ExtensionMissing
- );
- }
-
- if (extension_loaded('xdebug')) {
- ini_set('xdebug.scream', 0);
- ini_set('xdebug.max_nesting_level', 8192);
- ini_set('xdebug.show_exception_trace', 0);
- if (function_exists('xdebug_disable')) { // Xdebug v2
- xdebug_disable();
- }
- }
-
- }
-
- }
-
- class CLIEnvironmentException extends \Exception {
- const ExtensionMissing = 1;
- }
-}
-
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Cache.php b/src/ncc/ThirdParty/theseer/Autoload/Cache.php
deleted file mode 100644
index e068f9f..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Cache.php
+++ /dev/null
@@ -1,62 +0,0 @@
-loadedEntries = $initialEntries;
- }
-
- /**
- * @param SourceFile $file
- *
- * @return bool
- */
- public function hasResult(SourceFile $file) {
- $pathname = $file->getPathname();
- if (!isset($this->loadedEntries[$pathname])) {
- return false;
- }
- return $this->loadedEntries[$pathname]->getTimestamp() === $file->getMTime();
- }
-
- public function getResult(SourceFile $file) {
- if (!$this->hasResult($file)) {
- throw new CacheException('Entry not found');
- }
- $pathname = $file->getPathname();
- $entry = $this->loadedEntries[$pathname];
- $this->usedEntries[$pathname] = $entry;
- return $entry->getResult();
- }
-
- public function addResult(SourceFile $file, ParseResult $result) {
- $this->usedEntries[$file->getPathname()] = new CacheEntry($file->getMTime(), $result);
- }
-
- public function persist($fname) {
- if (file_exists($fname)) {
- unlink($fname);
- }
- file_put_contents($fname, serialize($this->usedEntries));
- }
- }
-
-
- class CacheException extends \Exception {
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/CacheEntry.php b/src/ncc/ThirdParty/theseer/Autoload/CacheEntry.php
deleted file mode 100644
index 9bce175..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/CacheEntry.php
+++ /dev/null
@@ -1,38 +0,0 @@
-timestamp = $timestamp;
- $this->result = $result;
- }
-
- /**
- * @return ParseResult
- */
- public function getResult() {
- return $this->result;
- }
-
- /**
- * @return int
- */
- public function getTimestamp() {
- return $this->timestamp;
- }
-
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/CacheWarmingListRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/CacheWarmingListRenderer.php
deleted file mode 100644
index 5bc0f9a..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/CacheWarmingListRenderer.php
+++ /dev/null
@@ -1,41 +0,0 @@
-addReset = $addReset;
- $this->indent = $indent;
- $this->linebreak = $linebreak;
- }
-
- /**
- * @return string
- */
- public function render(array $list) {
- $line = $this->indent . 'opcache_compile_file(___BASEDIR___\'';
- $glue = '\');' . $this->linebreak . $line;
-
- $firstLine = $this->addReset ? $this->indent . 'opcache_reset();' . $this->linebreak : '';
- return $firstLine . $line . implode($glue, $list) . '\');';
-
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/CachingParser.php b/src/ncc/ThirdParty/theseer/Autoload/CachingParser.php
deleted file mode 100644
index b18b3b6..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/CachingParser.php
+++ /dev/null
@@ -1,42 +0,0 @@
-cache = $cache;
- $this->parser = $parser;
- }
-
- /**
- * Parse a given file for defintions of classes, traits and interfaces
- *
- * @param SourceFile $source file to process
- *
- * @return ParseResult
- */
- public function parse(SourceFile $source) {
- if ($this->cache->hasResult($source)) {
- return $this->cache->getResult($source);
- }
- $result = $this->parser->parse($source);
- $this->cache->addResult($source, $result);
- return $result;
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Collector.php b/src/ncc/ThirdParty/theseer/Autoload/Collector.php
deleted file mode 100644
index e7ac7c1..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Collector.php
+++ /dev/null
@@ -1,96 +0,0 @@
-parser = $parser;
- $this->tolerantMode = $tolerantMode;
- $this->trustingMode = $trustingMode;
- $this->collectorResult = new CollectorResult($whitelist, $blacklist);
- }
-
- public function getResult() {
- return $this->collectorResult;
- }
-
- public function processDirectory(\Iterator $sources) {
- $worker = $this->trustingMode ? $sources : new PHPFilterIterator($sources);
- foreach($worker as $file) {
- $this->processFile($file);
- }
- }
-
- public function processFile(\SplFileInfo $file) {
- if ($this->collectorResult->hasResultFor($file)) {
- return;
- }
- try {
- $parseResult = $this->parser->parse(new SourceFile($file->getRealPath()));
- if ($parseResult->hasRedeclarations() && !$this->tolerantMode) {
- throw new CollectorException(
- sprintf(
- "Duplicate (potentially conditional) definitions of the following unit(s) found:\n\n\tUnit(s): %s\n\tFile: %s",
- join(', ', $parseResult->getRedeclarations()),
- $file->getRealPath()
- ),
- CollectorException::InFileRedeclarationFound
- );
- }
- $this->collectorResult->addParseResult($file, $parseResult);
- } catch(ParserException $e) {
- throw new CollectorException(
- sprintf(
- "Could not process file '%s' due to parse errors: %s",
- $file->getRealPath(),
- $e->getMessage()
- ),
- CollectorException::ParseErrror,
- $e
- );
- } catch(CollectorResultException $e) {
- throw new CollectorException(
- $e->getMessage(),
- CollectorException::RedeclarationFound
- );
- }
- }
- }
-
- class CollectorException extends \Exception {
- const ParseErrror = 1;
- const RedeclarationFound = 2;
- const InFileRedeclarationFound = 3;
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/CollectorResult.php b/src/ncc/ThirdParty/theseer/Autoload/CollectorResult.php
deleted file mode 100644
index 83be9bf..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/CollectorResult.php
+++ /dev/null
@@ -1,118 +0,0 @@
-whitelist = $whitelist;
- $this->blacklist = $blacklist;
- }
-
- public function hasResultFor(\SplFileInfo $file) {
- return isset($this->seenFiles[$file->getRealPath()]);
- }
-
- public function addParseResult(\SplFileInfo $file, ParseResult $result) {
- if (!$result->hasUnits()) {
- return;
- }
- $filename = $file->getRealPath();
- $this->seenFiles[$filename] = true;
-
- foreach($result->getUnits() as $unit) {
- if (!$this->accept($unit)) {
- continue;
- }
- if (isset($this->units[$unit])) {
- if (!isset($this->duplicates[$unit])) {
- $this->duplicates[$unit] = array( $this->units[$unit] );
- }
- $this->duplicates[$unit][] = $filename;
- continue;
- }
- $this->units[$unit] = $filename;
- $this->dependencies[$unit] = $result->getDependenciesForUnit($unit);
- }
- }
-
- public function hasUnits() {
- return count($this->units) > 0;
- }
-
- public function hasDuplicates() {
- return count($this->duplicates) > 0;
- }
- /**
- * @return array
- */
- public function getDependencies() {
- return $this->dependencies;
- }
-
- /**
- * @return array
- */
- public function getUnits() {
- return $this->units;
- }
-
- /**
- * @param string $unit
- *
- * @return bool
- */
- private function accept($unit) {
- foreach($this->blacklist as $entry) {
- if (fnmatch($entry, $unit)) {
- return false;
- }
- }
- foreach($this->whitelist as $entry) {
- if (fnmatch($entry, $unit)) {
- return true;
- }
- }
- return false;
- }
-
- public function getDuplicates() {
- return $this->duplicates;
- }
-
- }
-
- class CollectorResultException extends \Exception {
- const DuplicateUnitName = 1;
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/ComposerIterator.php b/src/ncc/ThirdParty/theseer/Autoload/ComposerIterator.php
deleted file mode 100644
index 7cef0b2..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/ComposerIterator.php
+++ /dev/null
@@ -1,183 +0,0 @@
-isFile() || !$composerFile->isReadable()) {
- throw new ComposerIteratorException(
- sprintf('Composer file "%s" not found or not readable', $composerFile->getPathname()),
- ComposerIteratorException::InvalidComposerJsonFile
- );
- }
- $composerDir = dirname($composerFile->getRealPath());
- $composerData = json_decode(file_get_contents($composerFile->getRealPath()), true);
- if (isset($composerData['require'])) {
- foreach($composerData['require'] as $require => $version) {
- if ($require === 'php' || strpos($require, 'ext-') === 0) {
- continue;
- }
- $this->processRequire($composerDir, $require);
- }
- }
- if (isset($composerData['autoload'])) {
- $this->processAutoload($composerDir, $composerData['autoload']);
- }
- }
-
- private function processAutoload($baseDir, array $map) {
- if (isset($map['classmap'])) {
- foreach($map['classmap'] as $dir) {
- $this->addDirectory($baseDir . '/' . $dir);
- }
- }
- foreach(array('psr-0', 'psr-4') as $psr) {
- if (isset($map[$psr])) {
- foreach ($map[$psr] as $node => $dir) {
- if ($dir === '') {
- $this->addDirectory($baseDir);
- continue;
- }
- if (is_array($dir)) {
- foreach($dir as $d) {
- $this->addDirectory($baseDir . '/' . $d);
- }
-
- continue;
- }
- $this->addDirectory($baseDir . '/' . $dir);
- }
- }
- }
- }
-
- private function processRequire($basedir, $require) {
- if (isset($this->seen[$require])) {
- return;
- }
- $this->seen[$require] = true;
-
- $requireDir = $basedir . '/vendor/' . $require;
- $jsonFile = $this->findComposerJson($requireDir);
- if ($jsonFile === null) {
- return;
- }
- $jsonData = json_decode(file_get_contents($jsonFile), true);
-
- if (isset($jsonData['require'])) {
- foreach($jsonData['require'] as $entry => $version) {
- if ($entry === 'php' || strpos($entry, 'ext-') === 0 || strpos($entry, 'lib-') === 0) {
- continue;
- }
- $this->processRequire($basedir, $entry);
- }
- }
-
- if (isset($jsonData['autoload'])) {
- $this->processAutoload($requireDir, $jsonData['autoload']);
- return;
- }
- $this->addDirectory($requireDir);
- }
-
- private function findComposerJson($dir) {
- if (file_exists($dir . '/composer.json')) {
- return $dir . '/composer.json';
- }
- foreach(glob($dir . '/*', GLOB_ONLYDIR) as $subDir) {
- $result = $this->findComposerJson($subDir);
- if ($result !== NULL) {
- return $result;
- }
- }
- }
-
- private function addDirectory($dir) {
- $dir = rtrim($dir, '/');
- if (!in_array($dir, $this->directories)) {
- $this->directories[] = $dir;
- }
- }
-
- /**
- * (PHP 5 >= 5.0.0)
- * Return the current element
- *
- * @link http://php.net/manual/en/iterator.current.php
- * @return mixed Can return any type.
- */
- #[ReturnTypeWillChange]
- public function current() {
- return $this->directories[$this->pos];
- }
-
- /**
- * (PHP 5 >= 5.0.0)
- * Move forward to next element
- *
- * @link http://php.net/manual/en/iterator.next.php
- * @return void Any returned value is ignored.
- */
- #[ReturnTypeWillChange]
- public function next() {
- $this->pos++;
- }
-
- /**
- * (PHP 5 >= 5.0.0)
- * Return the key of the current element
- *
- * @link http://php.net/manual/en/iterator.key.php
- * @return mixed scalar on success, or null on failure.
- */
- #[ReturnTypeWillChange]
- public function key() {
- return $this->pos;
- }
-
- /**
- * (PHP 5 >= 5.0.0)
- * Checks if current position is valid
- *
- * @link http://php.net/manual/en/iterator.valid.php
- * @return boolean The return value will be casted to boolean and then evaluated.
- * Returns true on success or false on failure.
- */
- #[ReturnTypeWillChange]
- public function valid() {
- return $this->pos < count($this->directories);
- }
-
- /**
- * (PHP 5 >= 5.0.0)
- * Rewind the Iterator to the first element
- *
- * @link http://php.net/manual/en/iterator.rewind.php
- * @return void Any returned value is ignored.
- */
- #[ReturnTypeWillChange]
- public function rewind() {
- $this->pos = 0;
- }
-
- }
-
- class ComposerIteratorException extends Exception {
- const InvalidComposerJsonFile = 1;
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Config.php b/src/ncc/ThirdParty/theseer/Autoload/Config.php
deleted file mode 100644
index ecf6c9a..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Config.php
+++ /dev/null
@@ -1,435 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- *
- */
-namespace ncc\ThirdParty\theseer\Autoload {
-
- class Config {
-
- private $quietMode = FALSE;
- private $directories = array();
- private $outputFile = 'STDOUT';
- private $pharMode = FALSE;
- private $include = array('*.php');
- private $exclude = array();
- private $whitelist = array('*');
- private $blacklist = array();
- private $baseDirectory = NULL;
- private $template;
- private $linebreak = "\n";
- private $indent;
- private $lint = FALSE;
- private $php;
- private $compatMode = FALSE;
- private $staticMode = FALSE;
- private $warmMode = FALSE;
- private $tolerant = FALSE;
- private $trusting = TRUE;
- private $once = FALSE;
- private $reset = FALSE;
- private $lowercase = TRUE;
- private $dateFormat;
- private $variable = array();
- private $pharCompression = 'NONE';
- private $pharKey;
- private $pharAll = false;
- private $pharAliasName = '';
- private $pharHashAlgorithm;
- private $followSymlinks = false;
- private $cacheFilename;
- private $prepend = false;
- private $exceptions = true;
-
- public function __construct(Array $directories) {
- $this->directories = $directories;
- $this->php = (PHP_OS === 'WIN' ? 'C:\php\php.exe' : '/usr/bin/php');
- }
-
- public function setBaseDirectory($baseDirectory) {
- $this->baseDirectory = $baseDirectory;
- }
-
- public function getBaseDirectory() {
- if ($this->baseDirectory !== NULL) {
- return realpath($this->baseDirectory);
- }
- if ($this->isPharMode()) {
- $comparator = new PathComparator($this->directories);
- return $comparator->getCommonBase();
- }
- if ($this->outputFile != 'STDOUT') {
- return realpath(dirname($this->outputFile) ?: '.');
- }
- $tmp = $this->getDirectories();
- return realpath(is_dir($tmp[0]) ? $tmp[0] : (dirname($tmp[0]) ?: '.'));
- }
-
- public function setCompatMode($compatMode) {
- $this->compatMode = $compatMode;
- }
-
- public function isCompatMode() {
- return $this->compatMode === true;
- }
-
- public function setDateFormat($dateFormat) {
- $this->dateFormat = $dateFormat;
- }
-
- public function getDateFormat() {
- return $this->dateFormat;
- }
-
- public function setExclude(Array $exclude) {
- $this->exclude = $exclude;
- }
-
- public function getExclude() {
- return $this->exclude;
- }
-
- public function setInclude(Array $include) {
- $this->include = $include;
- }
-
- public function getInclude() {
- return $this->include;
- }
-
- /**
- * @return array
- */
- public function getBlacklist() {
- return $this->blacklist;
- }
-
- /**
- * @param array $blacklist
- */
- public function setBlacklist($blacklist) {
- $this->blacklist = $blacklist;
- }
-
- /**
- * @return array
- */
- public function getWhitelist() {
- return $this->whitelist;
- }
-
- /**
- * @param array $whitelist
- */
- public function setWhitelist($whitelist) {
- $this->whitelist = $whitelist;
- }
-
- public function setIndent($indent) {
- $this->indent = $indent;
- }
-
- public function getIndent() {
- if ($this->indent !== NULL) {
- if (is_numeric($this->indent) && (int)$this->indent == $this->indent) {
- return str_repeat(' ', (int)$this->indent);
- }
- return $this->indent;
- }
- if ($this->isStaticMode() || $this->isWarmMode()) {
- return '';
- }
- return str_repeat(' ', $this->isCompatMode() ? 12 : 16);
- }
-
- public function setLinebreak($linebreak) {
- $lbr = array('LF' => "\n", 'CR' => "\r", 'CRLF' => "\r\n" );
- if (isset($lbr[$linebreak])) {
- $this->linebreak = $lbr[$linebreak];
- } else {
- $this->linebreak = $linebreak;
- }
- }
-
- public function getLinebreak() {
- return $this->linebreak;
- }
-
- public function setLintMode($lint) {
- $this->lint = (boolean)$lint;
- }
-
- public function isLintMode() {
- return $this->lint;
- }
-
- public function setLowercaseMode($lowercase) {
- $this->lowercase = (boolean)$lowercase;
- }
-
- public function isLowercaseMode() {
- return $this->lowercase;
- }
-
- public function setOnceMode($once) {
- $this->once = (boolean)$once;
- }
-
- public function isOnceMode() {
- return $this->once;
- }
-
- public function setOutputFile($outputFile) {
- $this->outputFile = $outputFile;
- }
-
- public function getOutputFile() {
- return $this->outputFile;
- }
-
- public function enablePharMode($compression = 'NONE', $all = true, $key = NULL, $alias = NULL) {
- $this->pharMode = true;
- $this->pharCompression = $compression;
- $this->pharAll = (boolean)$all;
- $this->pharKey = $key;
- $this->pharAliasName = $alias;
- }
-
- public function isPharMode() {
- return $this->pharMode;
- }
-
- public function isPharAllMode() {
- return $this->pharAll;
- }
-
- public function getPharCompression() {
- return $this->pharCompression;
- }
-
- public function getPharKey() {
- return $this->pharKey;
- }
-
- public function getPharAliasName() {
- return $this->pharAliasName;
- }
-
- public function hasPharHashAlgorithm() {
- return $this->pharHashAlgorithm !== null;
- }
-
- /**
- * @return string
- */
- public function getPharHashAlgorithm() {
- return $this->pharHashAlgorithm;
- }
-
- /**
- * @param string $pharHashAlgorithm
- */
- public function setPharHashAlgorithm($pharHashAlgorithm) {
- if (!in_array($pharHashAlgorithm, array('SHA-512','SHA-256','SHA-1'))) {
- throw new \InvalidArgumentException(
- sprintf('Algorithm %s not supported', $pharHashAlgorithm)
- );
- }
- $this->pharHashAlgorithm = $pharHashAlgorithm;
- }
-
- public function setPhp($php) {
- $this->php = $php;
- }
-
- public function getPhp() {
- return $this->php;
- }
-
- public function setQuietMode($quietMode) {
- $this->quietMode = (boolean)$quietMode;
- }
-
- public function setStaticMode($staticMode) {
- $this->staticMode = (boolean)$staticMode;
- $this->warmMode = FALSE;
- }
-
- public function isStaticMode() {
- return $this->staticMode;
- }
-
- public function setWarmMode($warmMode) {
- $this->warmMode = (boolean)$warmMode;
- $this->staticMode = FALSE;
- }
-
- public function isWarmMode() {
- return $this->warmMode;
- }
-
- public function setResetMode($resetMode) {
- $this->reset = (boolean)$resetMode;
- }
-
- public function isResetMode() {
- return $this->reset;
- }
-
- public function setTemplate($template) {
- $this->template = $template;
- }
-
- public function getTemplate() {
- $tplType = $this->isLowercaseMode() ? 'ci' : 'cs';
- $template = $this->template;
- if ($template !== NULL) {
- if (!file_exists($template)) {
- $alternative = __DIR__.'/templates/'. $tplType .'/'.$template;
- if (file_exists($alternative)) {
- $template = $alternative;
- }
- $alternative .= '.php.tpl';
- if (file_exists($alternative)) {
- $template = $alternative;
- }
- }
- return $template;
- }
-
- // determine auto template to use
- $tplFile = 'default.php.tpl';
- if ($this->isCompatMode()) {
- $tplFile = 'php52.php.tpl';
- }
-
- if ($this->isPharMode()) {
- if ($this->isStaticMode()) {
- $tplFile = 'staticphar.php.tpl';
- $tplType = '.';
- } else {
- $tplFile = 'phar.php.tpl';
- }
- } elseif ($this->isStaticMode() || $this->isWarmMode()) {
- $tplFile = 'static.php.tpl';
- $tplType = '.';
- }
-
- return __DIR__.'/templates/'.$tplType.'/'.$tplFile;
-
- }
-
- public function setTolerantMode($tolerant) {
- $this->tolerant = (boolean)$tolerant;
- }
-
- public function isTolerantMode() {
- return $this->tolerant;
- }
-
- public function setTrusting($trusting) {
- $this->trusting = (boolean)$trusting;
- }
-
- public function setFollowSymlinks($followSymlinks) {
- $this->followSymlinks = (boolean)$followSymlinks;
- }
-
- public function isFollowSymlinks() {
- return $this->followSymlinks;
- }
-
- public function isTrustingMode() {
- return $this->trusting;
- }
-
- public function setVariable($name, $value) {
- $this->variable[$name] = $value;
- }
-
- public function getVariables() {
- return $this->variable;
- }
-
- public function isQuietMode() {
- return $this->quietMode;
- }
-
- public function getDirectories() {
- $list = array();
- foreach($this->directories as $dir) {
- if (is_file($dir) && basename($dir) == 'composer.json') {
- foreach(new ComposerIterator(new \SplFileInfo($dir)) as $d) {
- $list[] = $d;
- }
- } else {
- foreach(glob($dir) as $match) {
- $list[] = $match;
- }
- }
- }
- return $list;
- }
-
- public function setCacheFile($filename) {
- $this->cacheFilename = $filename;
- }
-
- public function isCacheEnabled() {
- return $this->cacheFilename !== NULL;
- }
-
- public function getCacheFile() {
- return $this->cacheFilename;
- }
-
- public function enablePrepend() {
- $this->prepend = true;
- }
-
- public function usePrepend() {
- return $this->prepend;
- }
-
- public function disableExceptions() {
- $this->exceptions = false;
- }
-
- public function useExceptions() {
- return $this->exceptions;
- }
-
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/DependencySorter.php b/src/ncc/ThirdParty/theseer/Autoload/DependencySorter.php
deleted file mode 100644
index d850c4b..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/DependencySorter.php
+++ /dev/null
@@ -1,100 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- */
-
-namespace ncc\ThirdParty\theseer\Autoload {
-
- /**
- * Sorting classes by depdendency for static requires
- *
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- */
- class ClassDependencySorter {
-
- private $classList;
- private $dependencies;
-
- private $level;
-
- private $sorted = array();
-
- public function __construct(Array $classes, Array $dependencies) {
- $this->classList = $classes;
- $this->dependencies = $dependencies;
- }
-
- public function process() {
- $this->level = 0;
- foreach($this->classList as $class => $file) {
- if (!in_array($class, $this->sorted)) {
- $this->resolve($class);
- }
- }
-
- $res = array();
- foreach($this->sorted as $class) {
- if (!isset($this->classList[$class])) {
- continue;
- }
- $res[$class] = $this->classList[$class];
- }
- return $res;
- }
-
- private function resolve($class) {
- $this->level++;
- if ($this->level == 50) {
- throw new ClassDependencySorterException("Can't resolve more than 50 levels of dependencies", ClassDependencySorterException::TooManyDependencyLevels);
- }
- if (isset($this->dependencies[$class])) {
- foreach($this->dependencies[$class] as $depclass) {
- if (!in_array($depclass, $this->sorted)) {
- $this->resolve($depclass);
- }
- }
- }
- $this->sorted[] = $class;
- $this->level--;
- }
- }
-
- class ClassDependencySorterException extends \Exception {
-
- const TooManyDependencyLevels = 1;
-
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Factory.php b/src/ncc/ThirdParty/theseer/Autoload/Factory.php
deleted file mode 100644
index c097f35..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Factory.php
+++ /dev/null
@@ -1,242 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- *
- */
-namespace ncc\ThirdParty\theseer\Autoload {
-
- use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
- use ncc\ThirdParty\theseer\DirectoryScanner\IncludeExcludeFilterIterator;
-
- class Factory {
-
- /**
- * @var Config
- */
- private $config;
-
- /**
- * @var Cache
- */
- private $cache;
-
- /**
- * @param \ncc\ThirdParty\theseer\Autoload\Config $config
- */
- public function setConfig(Config $config) {
- $this->config = $config;
- }
-
- /**
- * @return CLI
- */
- public function getCLI() {
- return new CLI($this);
- }
-
- /**
- * @return Application
- */
- public function getApplication() {
- return new Application($this->getLogger(), $this->config, $this);
- }
-
- public function getLogger() {
- return new Logger($this->config->isQuietMode());
- }
-
- /**
- * @return Parser
- */
- public function getParser() {
- $parser = new Parser(
- $this->config->isLowercaseMode()
- );
- if (!$this->config->isCacheEnabled()) {
- return $parser;
- }
- return new CachingParser(
- $this->getCache(),
- $parser
- );
- }
-
- /**
- * @return Cache
- */
- public function getCache() {
- if (!$this->cache instanceof Cache) {
- $fname = $this->config->getCacheFile();
- if (file_exists($fname)) {
- $data = unserialize(file_get_contents($fname));
- } else {
- $data = array();
- }
- $this->cache = new Cache($data);
- }
- return $this->cache;
- }
-
- public function getCollector() {
- return new Collector(
- $this->getParser(),
- $this->config->isTolerantMode(),
- $this->config->isTrustingMode(),
- $this->config->getWhitelist(),
- $this->config->getBlacklist()
- );
- }
-
- /**
- * Get instance of DirectoryScanner with filter options applied
- *
- * @param bool $filter
- * @return DirectoryScanner
- */
- public function getScanner($filter = TRUE) {
- $scanner = new DirectoryScanner;
- if ($filter) {
- $scanner->setIncludes($this->config->getInclude());
- $scanner->setExcludes($this->config->getExclude());
- }
- if ($this->config->isFollowSymlinks()) {
- $scanner->setFlag(\FilesystemIterator::FOLLOW_SYMLINKS);
- }
- return $scanner;
- }
-
- public function getFilter(\Iterator $files) {
- $filter = new IncludeExcludeFilterIterator($files);
- $filter->setInclude($this->config->getInclude());
- $filter->setExclude($this->config->getExclude());
- return $filter;
- }
-
-
- public function getPharBuilder() {
- $builder = new PharBuilder(
- $this->getScanner(!$this->config->isPharAllMode()),
- $this->config->getBaseDirectory()
- );
- $builder->setCompressionMode($this->config->getPharCompression());
- foreach($this->config->getDirectories() as $directory) {
- $builder->addDirectory($directory);
- }
-
- return $builder;
- }
-
- /**
- * Helper to get instance of AutoloadRenderer with cli options applied
- *
- * @param CollectorResult $result
- *
- * @return \ncc\ThirdParty\theseer\Autoload\AutoloadRenderer|\ncc\ThirdParty\theseer\Autoload\StaticRenderer
- * @throws \RuntimeException
- */
- public function getRenderer(CollectorResult $result) {
- $isStatic = $this->config->isStaticMode();
- $isPhar = $this->config->isPharMode();
- $isCompat = $this->config->isCompatMode();
- $isOnce = $this->config->isOnceMode();
- $isWarm = $this->config->isWarmMode();
- $isReset = $this->config->isResetMode();
-
- if ($isWarm === TRUE) {
- $renderer = new StaticRenderer(
- $result->getUnits(),
- $this->getCacheWarmingListRenderer($isReset)
- );
- $renderer->setDependencies($result->getDependencies());
- $renderer->setPharMode($isPhar);
- } else if ($isStatic === TRUE) {
- $renderer = new StaticRenderer(
- $result->getUnits(),
- $this->getStaticRequireListRenderer($isOnce)
- );
- $renderer->setDependencies($result->getDependencies());
- $renderer->setPharMode($isPhar);
- } else {
- $renderer = new AutoloadRenderer($result->getUnits());
- if ($this->config->usePrepend()) {
- $renderer->prependAutoloader();
- }
- if ($this->config->useExceptions()) {
- $renderer->enableExceptions();
- }
- }
-
- $renderer->setCompat($isCompat);
-
- $basedir = $this->config->getBaseDirectory();
- if (!$basedir || !is_dir($basedir)) {
- throw new \RuntimeException("Given basedir '{$basedir}' does not exist or is not a directory");
- }
- $renderer->setBaseDir($basedir);
-
- $format = $this->config->getDateFormat();
- if ($format) {
- $renderer->setDateTimeFormat($format);
- }
-
- $renderer->setIndent($this->config->getIndent());
- $renderer->setLineBreak($this->config->getLinebreak());
-
- foreach($this->config->getVariables() as $name => $value) {
- $renderer->setVariable($name, $value);
- }
-
- return $renderer;
- }
-
- private function getStaticRequireListRenderer($useOnce) {
- return new StaticRequireListRenderer(
- $useOnce,
- $this->config->getIndent(),
- $this->config->getLinebreak()
- );
- }
-
- private function getCacheWarmingListRenderer($addReset) {
- return new CacheWarmingListRenderer(
- $addReset,
- $this->config->getIndent(),
- $this->config->getLinebreak()
- );
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/LICENSE b/src/ncc/ThirdParty/theseer/Autoload/LICENSE
deleted file mode 100644
index 161e2dc..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/LICENSE
+++ /dev/null
@@ -1,31 +0,0 @@
-Autoload Builder
-
-Copyright (c) 2010-2016 Arne Blankerts and Contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-* Neither the name of Arne Blankerts nor the names of contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Logger.php b/src/ncc/ThirdParty/theseer/Autoload/Logger.php
deleted file mode 100644
index 49f8255..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Logger.php
+++ /dev/null
@@ -1,59 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- *
- */
-namespace ncc\ThirdParty\theseer\Autoload {
-
- class Logger {
-
- private $quiet = FALSE;
-
- /**
- * @param bool $quietMode
- */
- public function __construct($quietMode = FALSE) {
- $this->quiet = $quietMode;
- }
-
- public function log($message, $target = STDOUT) {
- if ($this->quiet) {
- return;
- }
- fwrite($target, $message);
- }
-
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/ParseResult.php b/src/ncc/ThirdParty/theseer/Autoload/ParseResult.php
deleted file mode 100644
index 25f7c51..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/ParseResult.php
+++ /dev/null
@@ -1,64 +0,0 @@
-units = $units;
- $this->dependencies = $dependencies;
- $this->redeclarations = $redeclarations;
- }
-
- public function hasUnits() {
- return count($this->units) > 0;
- }
-
- public function hasRedeclarations() {
- return count($this->redeclarations) > 0;
- }
-
- /**
- *
- * @param string $unit
- *
- * @return array
- */
- public function getDependenciesForUnit($unit) {
- if (!isset($this->dependencies[$unit])) {
- return array();
- }
- return $this->dependencies[$unit];
- }
-
- /**
- * @return \string[]
- */
- public function getRedeclarations() {
- return $this->redeclarations;
- }
-
- /**
- * @return \string[]
- */
- public function getUnits() {
- return $this->units;
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Parser.php b/src/ncc/ThirdParty/theseer/Autoload/Parser.php
deleted file mode 100644
index fac4ab7..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Parser.php
+++ /dev/null
@@ -1,598 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- */
-
-namespace ncc\ThirdParty\theseer\Autoload {
-
- // PHP 5.3 compat
- define('T_TRAIT_53', 10355);
- if (!defined('T_TRAIT')) {
- define('T_TRAIT', -1);
- }
-
- // PHP 8.0 forward compat
- if (!defined('T_NAME_FULLY_QUALIFIED')) {
- define('T_NAME_FULLY_QUALIFIED', -1);
- define('T_NAME_QUALIFIED', -1);
- }
-
- // PHP 8.1 forward compat
- if (!defined('T_ENUM')) {
- define('T_ENUM', -1);
- }
-
- /**
- * Namespace aware parser to find and extract defined classes within php source files
- *
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- */
- class Parser implements ParserInterface {
-
- private $methodMap = array(
- T_TRAIT => 'processClass',
- T_TRAIT_53 => 'processClass',
- T_CLASS => 'processClass',
- T_ENUM => 'processEnum',
- //T_CASE => 'processEnumCase',
- T_INTERFACE => 'processInterface',
- T_NAMESPACE => 'processNamespace',
- T_USE => 'processUse',
- '}' => 'processBracketClose',
- '{' => 'processBracketOpen',
- T_CURLY_OPEN => 'processBracketOpen',
- T_DOLLAR_OPEN_CURLY_BRACES => 'processBracketOpen'
- );
-
- private $typeMap = array(
- T_INTERFACE => 'interface',
- T_CLASS => 'class',
- T_ENUM => 'enum',
- T_TRAIT => 'trait',
- T_TRAIT_53 => 'trait'
- );
-
- private $caseInsensitive;
-
- private $tokenArray = array();
-
- private $inNamespace = '';
- private $inUnit = '';
-
- private $nsBracket = 0;
- private $classBracket = 0;
-
- private $bracketLevel = 0;
- private $aliases = array();
-
- private $found = array();
- private $dependencies = array();
- private $redeclarations = array();
-
- public function __construct($caseInsensitive = true) {
- $this->caseInsensitive = $caseInsensitive;
- }
-
- /**
- * Parse a given file for defintions of classes, traits and interfaces
- *
- * @param SourceFile $source file to process
- *
- * @return ParseResult
- */
- public function parse(SourceFile $source) {
- $this->found = array();
- $this->redeclarations = array();
- $this->inNamespace = '';
- $this->aliases = array();
- $this->bracketLevel = 0;
- $this->inUnit = '';
- $this->nsBracket = 0;
- $this->classBracket = 0;
- $this->tokenArray = $source->getTokens();
- $tokenCount = count($this->tokenArray);
- $tokList = array_keys($this->methodMap);
- for($t=0; $t<$tokenCount; $t++) {
- $current = (array)$this->tokenArray[$t];
-
- if ($current[0]===T_STRING && $current[1]==='trait' && T_TRAIT===-1) {
- // PHP < 5.4 compat fix
- $current[0] = T_TRAIT_53;
- $this->tokenArray[$t] = $current;
- }
- if (!in_array($current[0], $tokList)) {
- continue;
- }
-
- $t = call_user_func(array($this, $this->methodMap[$current[0]]), $t);
- }
- return new ParseResult($this->found, $this->dependencies, $this->redeclarations);
- }
-
- private function processBracketOpen($pos) {
- $this->bracketLevel++;
- return $pos + 1;
- }
-
- private function processBracketClose($pos) {
- $this->bracketLevel--;
- if ($this->nsBracket !== 0 && $this->bracketLevel < $this->nsBracket) {
- $this->inNamespace = '';
- $this->nsBracket = 0;
- $this->aliases = array();
- }
- if ($this->bracketLevel <= $this->classBracket) {
- $this->classBracket = 0;
- $this->inUnit = '';
- }
- return $pos + 1;
- }
-
- private function processClass($pos) {
- if (!$this->classTokenNeedsProcessing($pos)) {
- return $pos;
- }
- $list = array('{');
- $stack = $this->getTokensTill($pos, $list);
- $stackSize = count($stack);
- $classname = $this->inNamespace !== '' ? $this->inNamespace . '\\' : '';
- $extends = '';
- $extendsFound = false;
- $implementsFound = false;
- $implementsList = array();
- $implements = '';
- $mode = 'classname';
- foreach(array_slice($stack, 1, -1) as $tok) {
- switch ($tok[0]) {
- case T_COMMENT:
- case T_DOC_COMMENT:
- case T_WHITESPACE: {
- break;
- }
-
- case T_NAME_FULLY_QUALIFIED:
- case T_NAME_QUALIFIED:
- case T_STRING: {
- $$mode .= $tok[1];
- break;
- }
- case T_NS_SEPARATOR: {
- $$mode .= '\\';
- break;
- }
- case T_EXTENDS: {
- $extendsFound = true;
- $mode = 'extends';
- break;
- }
- case T_IMPLEMENTS: {
- $implementsFound = true;
- $mode = 'implements';
- break;
- }
-
- case ',': {
- if ($mode === 'implements') {
- $implementsList[] = $this->resolveDependencyName($implements);
- $implements = '';
- }
- break;
- }
- default: {
- throw new ParserException(sprintf(
- 'Parse error while trying to process class definition (unexpected token "%s" in name).',
- \token_name($tok[0])
- ), ParserException::ParseError
- );
- }
- }
- }
- if ($implements != '') {
- $implementsList[] = $this->resolveDependencyName($implements);
- }
- if ($implementsFound && count($implementsList)==0) {
- throw new ParserException(sprintf(
- 'Parse error while trying to process class definition (extends or implements).'
- ), ParserException::ParseError
- );
- }
- $classname = $this->registerUnit($classname, $stack[0][0]);
- $this->dependencies[$classname] = $implementsList;
- if ($extendsFound) {
- $this->dependencies[$classname][] = $this->resolveDependencyName($extends);
- }
- $this->inUnit = $classname;
- $this->classBracket = $this->bracketLevel + 1;
- return $pos + $stackSize - 1;
- }
-
- private function processEnum($pos) {
- $list = array('{');
- $stack = $this->getTokensTill($pos, $list);
- $stackSize = count($stack);
- $enumName = $this->inNamespace !== '' ? $this->inNamespace . '\\' : '';
- $implementsFound = false;
- $implementsList = array();
- $implements = '';
- $backType = '';
- $mode = 'enumName';
- foreach(array_slice($stack, 1, -1) as $tok) {
- switch ($tok[0]) {
- case T_COMMENT:
- case T_DOC_COMMENT:
- case T_WHITESPACE: {
- break;
- }
-
- case T_NAME_FULLY_QUALIFIED:
- case T_NAME_QUALIFIED:
- case T_STRING: {
- $$mode .= $tok[1];
- break;
- }
- case T_NS_SEPARATOR: {
- $$mode .= '\\';
- break;
- }
- case T_IMPLEMENTS: {
- $implementsFound = true;
- $mode = 'implements';
- break;
- }
-
- case ':': {
- $isBacked = true;
- $mode = 'backType';
- break;
- }
-
- case ',': {
- if ($mode === 'implements') {
- $implementsList[] = $this->resolveDependencyName($implements);
- $implements = '';
- }
- break;
- }
-
- default: {
- throw new ParserException(sprintf(
- 'Parse error while trying to process class definition (unexpected token "%s" in name).',
- is_int($tok[0]) ? \token_name($tok[0]) : $tok[0]
- ), ParserException::ParseError
- );
- }
- }
- }
-
- if ($implements != '') {
- $implementsList[] = $this->resolveDependencyName($implements);
- }
- if ($implementsFound && count($implementsList)==0) {
- throw new ParserException(sprintf(
- 'Parse error while trying to process enum definition (implements).'
- ), ParserException::ParseError
- );
- }
-
- $enumName = $this->registerUnit($enumName, $stack[0][0]);
- $this->dependencies[$enumName] = $implementsList;
-
- return $pos + $stackSize - 1;
- }
-
- private function processInterface($pos) {
- $list = array('{');
- $stack = $this->getTokensTill($pos, $list);
- $stackSize = count($stack);
- $next = $stack[1];
- if (is_array($next) && $next[0] === '(') {
- // sort of inline use - ignore
- return $pos + $stackSize;
- }
-
- $name = $this->inNamespace != '' ? $this->inNamespace . '\\' : '';
- $extends = '';
- $extendsList = array();
- $mode = 'name';
- foreach(array_slice($stack, 1, -1) as $tok) {
- switch ($tok[0]) {
- case T_NS_SEPARATOR:
- case T_NAME_QUALIFIED:
- case T_NAME_FULLY_QUALIFIED:
- case T_STRING: {
- $$mode .= $tok[1];
- break;
- }
- case T_EXTENDS: {
- $mode = 'extends';
- break;
- }
- case ',': {
- if ($mode == 'extends') {
- $extendsList[] = $this->resolveDependencyName($extends);
- $extends = '';
- }
- }
- }
- }
- $name = $this->registerUnit($name, T_INTERFACE);
- if ($extends != '') {
- $extendsList[] = $this->resolveDependencyName($extends);
- }
- $this->dependencies[$name] = $extendsList;
- $this->inUnit = $name;
- return $pos + $stackSize - 1;
- }
-
- private function resolveDependencyName($name) {
- if ($name == '') {
- throw new ParserException(sprintf(
- 'Parse error while trying to process class definition (extends or implements).'
- ), ParserException::ParseError
- );
- }
- if ($name[0] == '\\') {
- $name = substr($name, 1);
- } else {
- $parts = explode('\\', $name, 2);
- $search = $this->caseInsensitive ? strtolower($parts[0]) : $parts[0];
- $key = array_search($search, $this->aliases);
- if (!$key) {
- $name = ($this->inNamespace != '' ? $this->inNamespace . '\\' : ''). $name;
- } else {
- $name = $key;
- if (isset($parts[1])) {
- $name .= '\\' . $parts[1];
- }
- }
- }
- if ($this->caseInsensitive) {
- $name = strtolower($name);
- }
- return $name;
- }
-
- private function registerUnit($name, $type) {
- if ($name == '' || substr($name, -1) == '\\') {
- throw new ParserException(sprintf(
- 'Parse error while trying to process %s definition.',
- $this->typeMap[$type]
- ), ParserException::ParseError
- );
- }
- if ($this->caseInsensitive) {
- $name = strtolower($name);
- }
- if (in_array($name, $this->found)) {
- $this->redeclarations[] = $name;
- } else {
- $this->found[] = $name;
- }
- return $name;
- }
-
- private function processNamespace($pos) {
- $list = array(';', '{');
- $stack = $this->getTokensTill($pos, $list);
- $stackSize = count($stack);
- $newpos = $pos + $stackSize;
- if ($stackSize < 3) { // empty namespace defintion == root namespace
- $this->inNamespace = '';
- $this->aliases = array();
- return $newpos - 1;
- }
- $next = $stack[1];
- if (is_array($next) && ($next[0] === T_NS_SEPARATOR || $next[0] === '(')) {
- // sort of inline use - ignore
- return $newpos;
- }
-
- $this->inNamespace = '';
- foreach(array_slice($stack, 1, -1) as $tok) {
- $this->inNamespace .= $tok[1];
- }
- $this->aliases = array();
-
- return $pos + $stackSize - 1;
- }
-
- private function processUse($pos) {
- $list = array(';','(');
- $stack = $this->getTokensTill($pos, $list);
- $stackSize = count($stack);
- $ignore = array(
- '(', // closue use
- T_CONST, // use const foo\bar;
- T_FUNCTION // use function foo\bar;
- );
- if (in_array($stack[1][0], $ignore)) {
- return $pos + $stackSize - 1;
- }
-
- if ($this->classBracket > 0) {
- $this->parseUseOfTrait($stackSize, $stack);
-
- } else {
- $this->parseUseAsImport($stack);
-
- }
- return $pos + $stackSize - 1;
- }
-
- private function getTokensTill($start, $list) {
- $list = (array)$list;
- $stack = array();
- $skip = array(
- T_WHITESPACE,
- T_COMMENT,
- T_DOC_COMMENT
- );
- $limit = count($this->tokenArray);
- for ($t=$start; $t<$limit; $t++) {
- $current = (array)$this->tokenArray[$t];
- if (in_array($current[0], $skip)) {
- continue;
- }
- $stack[] = $current;
- if (in_array($current[0], $list)) {
- break;
- }
- }
- return $stack;
- }
-
- /**
- * @param $stackSize
- * @param $stack
- */
- private function parseUseOfTrait($stackSize, $stack) {
- $use = '';
- for ($t = 0; $t < $stackSize; $t++) {
- $current = (array)$stack[$t];
- switch ($current[0]) {
- case '{': {
- // find closing bracket to skip contents
- for ($x = $t + 1; $x < $stackSize; $x++) {
- $tok = $stack[$x];
- if ($tok[0] == '}') {
- $t = $x;
- break;
- }
- }
- break;
- }
- case ';':
- case ',': {
- $this->dependencies[$this->inUnit][] = $this->resolveDependencyName($use);
- $use = '';
- break;
- }
- case T_NS_SEPARATOR:
- case T_NAME_QUALIFIED:
- case T_NAME_FULLY_QUALIFIED:
- case T_STRING: {
- $use .= $current[1];
- break;
- }
- }
- }
- }
-
- /**
- * @param $stack
- */
- private function parseUseAsImport($stack) {
- $use = '';
- $alias = '';
- $mode = 'use';
- $group = '';
- $ignore = false;
- foreach ($stack as $tok) {
- $current = $tok;
- switch ($current[0]) {
- case T_CONST:
- case T_FUNCTION: {
- $ignore = true;
- break;
- }
- case '{': {
- $group = $use;
- break;
- }
- case ';':
- case ',': {
- if (!$ignore) {
- if ($alias == '') {
- $nss = strrpos($use, '\\');
- if ($nss !== FALSE) {
- $alias = substr($use, $nss + 1);
- } else {
- $alias = $use;
- }
- }
- if ($this->caseInsensitive) {
- $alias = strtolower($alias);
- }
- $this->aliases[$use] = $alias;
- }
- $alias = '';
- $use = $group;
- $mode = 'use';
- $ignore = false;
- break;
- }
- case T_NS_SEPARATOR:
- case T_NAME_QUALIFIED:
- case T_NAME_FULLY_QUALIFIED:
- case T_STRING: {
- $$mode .= $current[1];
- break;
- }
- case T_AS: {
- $mode = 'alias';
- break;
- }
- }
- }
- }
-
- private function classTokenNeedsProcessing($position) {
-
- // PHP 5.5 has classname::class, reusing T_CLASS
- if ($this->tokenArray[$position-1][0] == T_DOUBLE_COLON) {
- return false;
- }
-
- // PHP 7 has anonymous classes: $x = new class { ... }
- if ($position > 2 && $this->tokenArray[$position-2][0] === T_NEW) {
- return false;
- }
-
- if ($this->tokenArray[$position + 1] === '(' || $this->tokenArray[$position + 2] === '(') {
- return false;
- }
-
- return true;
- }
-
- }
-
- class ParserException extends \Exception {
-
- const ParseError = 1;
-
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/ParserInterface.php b/src/ncc/ThirdParty/theseer/Autoload/ParserInterface.php
deleted file mode 100644
index 23ed553..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/ParserInterface.php
+++ /dev/null
@@ -1,20 +0,0 @@
-
- * @copyright Arne Blankerts , All rights reserved.
- */
-interface ParserInterface {
-
- /**
- * Parse a given file for defintions of classes, traits and interfaces
- *
- * @param SourceFile $source file to process
- *
- * @return ParseResult
- */
- public function parse(SourceFile $source);
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/PathComparator.php b/src/ncc/ThirdParty/theseer/Autoload/PathComparator.php
deleted file mode 100644
index a325fbb..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/PathComparator.php
+++ /dev/null
@@ -1,45 +0,0 @@
-directories[] = realpath($dir).'/';
- }
- }
-
- public function getCommonBase() {
- if (count($this->directories) == 0) {
- return '/';
- }
- $result = $this->directories[0];
- foreach($this->directories as $dir) {
- $result = substr($dir, 0, $this->commonPrefix($result, $dir));
- }
- return ($result ?: '/');
- }
-
-
- private function commonPrefix( $s1, $s2 ) {
- $l1 = strlen($s1);
- $l2 = strlen($s2);
- $i=0;
- while($i < $l1 && $i < $l2 && $s1[$i] == $s2[$i]) {
- $i++;
- }
- return strrpos(substr($s1, 0, $i), '/');
- }
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/PharBuilder.php b/src/ncc/ThirdParty/theseer/Autoload/PharBuilder.php
deleted file mode 100644
index 29b84f6..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/PharBuilder.php
+++ /dev/null
@@ -1,135 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- *
- */
-namespace ncc\ThirdParty\theseer\Autoload {
-
- use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
-
- class PharBuilder {
-
- private $scanner;
- private $compression;
- private $key;
- private $basedir;
- private $aliasName;
- private $signatureType;
-
- private $directories = array();
-
- private $supportedSignatureTypes = array(
- 'SHA-512' => \Phar::SHA512,
- 'SHA-256' => \Phar::SHA256,
- 'SHA-1' => \Phar::SHA1
- );
-
- public function __construct(DirectoryScanner $scanner, $basedir) {
- $this->scanner = $scanner;
- $this->basedir = $basedir;
- }
-
- public function setCompressionMode($mode) {
- $this->compression = $mode;
- }
-
- public function setSignatureType($type) {
- if (!in_array($type, array_keys($this->supportedSignatureTypes))) {
- throw new \InvalidArgumentException(
- sprintf('Signature type "%s" not known or not supported by this PHP installation.', $type)
- );
- }
- $this->signatureType = $type;
- }
-
- public function setSignatureKey($key) {
- $this->key = $key;
- }
-
- public function addDirectory($directory) {
- $this->directories[] = $directory;
- }
-
- public function setAliasName($name) {
- $this->aliasName = $name;
- }
-
- public function build($filename, $stub) {
- if (file_exists($filename)) {
- unlink($filename);
- }
- $phar = new \Phar($filename, 0, $this->aliasName != '' ? $this->aliasName : basename($filename));
- $phar->startBuffering();
- $phar->setStub($stub);
- if ($this->key !== NULL) {
- $privateKey = '';
- openssl_pkey_export($this->key, $privateKey);
- $phar->setSignatureAlgorithm(\Phar::OPENSSL, $privateKey);
- $keyDetails = openssl_pkey_get_details($this->key);
- file_put_contents($filename . '.pubkey', $keyDetails['key']);
- } else {
- $phar->setSignatureAlgorithm($this->selectSignatureType());
- }
-
- $basedir = $this->basedir ? $this->basedir : $this->directories[0];
- foreach($this->directories as $directory) {
- $phar->buildFromIterator($this->scanner->__invoke($directory), $basedir);
- }
-
- if ($this->compression !== \Phar::NONE) {
- $phar->compressFiles($this->compression);
- }
- $phar->stopBuffering();
- }
-
- private function selectSignatureType() {
- if ($this->signatureType !== NULL) {
- return $this->supportedSignatureTypes[$this->signatureType];
- }
- $supported = \Phar::getSupportedSignatures();
- foreach($this->supportedSignatureTypes as $candidate => $type) {
- if (in_array($candidate, $supported)) {
- return $type;
- }
- }
-
- // Is there any PHP Version out there that does not support at least SHA-1?
- // But hey, fallback to md5, better than nothing
- return \Phar::MD5;
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/SourceFile.php b/src/ncc/ThirdParty/theseer/Autoload/SourceFile.php
deleted file mode 100644
index 4144f2b..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/SourceFile.php
+++ /dev/null
@@ -1,14 +0,0 @@
-getRealPath()));
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/StaticListRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/StaticListRenderer.php
deleted file mode 100644
index ecc7982..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/StaticListRenderer.php
+++ /dev/null
@@ -1,10 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- */
-
-namespace ncc\ThirdParty\theseer\Autoload {
-
- /**
- * Builds static require list for inclusion into projects
- *
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- */
- class StaticRenderer extends AutoloadRenderer {
-
- private $dependencies;
- private $phar;
- private $require = 'require';
-
- /**
- * @var StaticListRenderer
- */
- private $renderHelper;
-
- public function __construct(array $classlist, StaticListRenderer $renderHelper) {
- parent::__construct($classlist);
- $this->renderHelper = $renderHelper;
- }
-
- /**
- * Setter for Dependency Array
- * @param array $dep Dependency Array from classfinder
- */
- public function setDependencies(Array $dep) {
- $this->dependencies = $dep;
- }
-
- /**
- * Toggle phar outut mode
- *
- * @param boolean $phar
- */
- public function setPharMode($phar) {
- $this->phar = (boolean)$phar;
- }
-
- /**
- * Toggle wether or not to use require_once over require
- *
- * @param boolean $mode
- */
- public function setRequireOnce($mode) {
- }
-
-
- /**
- * @param string $template
- *
- * @return string
- */
- public function render($template) {
- $baseDir = '';
- if ($this->phar) {
- $baseDir = "'phar://". $this->variables['___PHAR___']."' . ";
- } else if ($this->baseDir) {
- $baseDir = $this->compat ? 'dirname(__FILE__) . ' : '__DIR__ . ';
- }
-
- $entries = array();
- foreach($this->sortByDependency() as $fname) {
- $entries[] = $this->resolvePath($fname);
- }
-
- $replace = array_merge(
- $this->variables,
- array(
- '___CREATED___' => date( $this->dateformat, $this->timestamp ? $this->timestamp : time()),
- '___FILELIST___' => $this->renderHelper->render($entries),
- '___BASEDIR___' => $baseDir,
- '___AUTOLOAD___' => uniqid('autoload', true)
- )
- );
-
- return str_replace(array_keys($replace), array_values($replace), $template);
- }
-
- /**
- * Helper to sort classes/interfaces and traits based on their depdendency info
- *
- * @return array
- */
- protected function sortByDependency() {
- $sorter = new ClassDependencySorter($this->classes, $this->dependencies);
- $list = $sorter->process();
-
- return array_unique($list);
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/StaticRequireListRenderer.php b/src/ncc/ThirdParty/theseer/Autoload/StaticRequireListRenderer.php
deleted file mode 100644
index 733c639..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/StaticRequireListRenderer.php
+++ /dev/null
@@ -1,34 +0,0 @@
-useOnce = $useOnce;
- $this->indent = $indent;
- $this->linebreak = $linebreak;
- }
-
- /**
- * @return string
- */
- public function render(array $list) {
- $require = (boolean)$this->useOnce ? 'require_once' : 'require';
- $require .= ' ___BASEDIR___\'';
- $glue = '\';' . $this->linebreak . $this->indent . $require;
-
- return $this->indent . $require . implode($glue, $list) . '\';';
- }
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/VERSION b/src/ncc/ThirdParty/theseer/Autoload/VERSION
deleted file mode 100644
index c5b4f6e..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.27.1
\ No newline at end of file
diff --git a/src/ncc/ThirdParty/theseer/Autoload/Version.php b/src/ncc/ThirdParty/theseer/Autoload/Version.php
deleted file mode 100644
index 50f9cb9..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/Version.php
+++ /dev/null
@@ -1,66 +0,0 @@
-
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package Autoload
- * @author Arne Blankerts
- * @copyright Arne Blankerts , All rights reserved.
- * @license BSD License
- *
- */
-namespace ncc\ThirdParty\theseer\Autoload {
-
- class Version {
-
- private static $version = NULL;
-
- public static function getVersion() {
- if (self::$version === NULL) {
- self::$version = PHPAB_VERSION;
- if (PHPAB_VERSION == '%development%') {
- $cwd = getcwd();
- chdir(__DIR__);
- $git = exec('command -p git describe --always --dirty 2>/dev/null', $foo, $rc);
- chdir($cwd);
- if ($rc === 0) {
- self::$version = $git;
- }
- }
- }
- return self::$version;
- }
-
- public static function getInfoString() {
- return 'phpab ' . self::getVersion() . ' - Copyright (C) 2009 - ' . date('Y') . ' by Arne Blankerts and Contributors';
- }
-
- }
-
-}
diff --git a/src/ncc/ThirdParty/theseer/Autoload/templates/ci/default.php.tpl b/src/ncc/ThirdParty/theseer/Autoload/templates/ci/default.php.tpl
deleted file mode 100644
index b007e0b..0000000
--- a/src/ncc/ThirdParty/theseer/Autoload/templates/ci/default.php.tpl
+++ /dev/null
@@ -1,21 +0,0 @@
-getPath()))
{
- throw new IOException(sprintf('Attempted to write data to a directory instead of a file: (%s)', $uri));
+ if(!mkdir($concurrentDirectory = $fileInfo->getPath(), 0755, true) && !is_dir($concurrentDirectory))
+ {
+ throw new IOException(sprintf('Unable to create directory: (%s)', $fileInfo->getPath()));
+ }
}
Console::outDebug(sprintf('writing %s of data to %s', Functions::b2u(strlen($data)), $uri));
diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php
index f501949..a49d6e3 100644
--- a/src/ncc/Utilities/PathFinder.php
+++ b/src/ncc/Utilities/PathFinder.php
@@ -71,91 +71,67 @@
/**
* Returns the path where all NCC installation data is stored
*
- * @param string $scope
* @return string
*/
- public static function getDataPath(string $scope=Scopes::AUTO): string
+ public static function getDataPath(): string
{
- $scope = Resolver::resolveScope($scope);
-
- if(!Validate::scope($scope, false))
- {
- throw new InvalidArgumentException(sprintf('Invalid scope "%s"', $scope));
- }
-
- switch($scope)
- {
- case Scopes::USER:
- $uid = posix_getuid();
- return posix_getpwuid($uid)['dir'] . DIRECTORY_SEPARATOR . '.ncc' . DIRECTORY_SEPARATOR . 'data';
-
- case Scopes::SYSTEM:
- return self::getRootPath() . 'var' . DIRECTORY_SEPARATOR . 'ncc';
- }
-
- throw new InvalidArgumentException(sprintf('Invalid scope "%s"', $scope));
+ return self::getRootPath() . 'var' . DIRECTORY_SEPARATOR . 'ncc';
}
/**
* Returns the path where packages are installed
*
- * @param string $scope
* @return string
*/
- public static function getPackagesPath(string $scope=Scopes::AUTO): string
+ public static function getPackagesPath(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'packages';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'packages';
}
/**
* Returns the path where cache files are stored
*
- * @param string $scope
* @return string
*/
- public static function getCachePath(string $scope=Scopes::AUTO): string
+ public static function getCachePath(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'cache';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'cache';
}
/**
* Returns the path where Runner bin files are located and installed
*
- * @param string $scope
* @return string
*/
- public static function getRunnerPath(string $scope=Scopes::AUTO): string
+ public static function getRunnerPath(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'runners';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'runners';
}
/**
* Returns the package lock file
*
- * @param string $scope
* @return string
*/
- public static function getPackageLock(string $scope=Scopes::AUTO): string
+ public static function getPackageLock(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'package.lck';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'package.lck';
}
/**
- * @param string $scope
* @return string
*/
- public static function getRemoteSources(string $scope=Scopes::AUTO): string
+ public static function getRemoteSources(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'sources';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'sources';
}
/**
- * @param string $scope
* @return string
*/
- public static function getSymlinkDictionary(string $scope=Scopes::AUTO): string
+ public static function getSymlinkDictionary(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'symlinks';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'symlinks';
}
/**
@@ -166,11 +142,11 @@
public static function getPackageLockFiles(): array
{
$results = [];
- $results[] = self::getPackageLock(Scopes::SYSTEM);
+ $results[] = self::getPackageLock();
- if(!in_array(self::getPackageLock(Scopes::USER), $results, true))
+ if(!in_array(self::getPackageLock(), $results, true))
{
- $results[] = self::getPackageLock(Scopes::USER);
+ $results[] = self::getPackageLock();
}
return $results;
@@ -190,18 +166,17 @@
throw new ConfigurationException($package);
}
- return self::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package;
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package;
}
/**
* Returns the file path where files for the given extension is stored
*
- * @param string $scope
* @return string
*/
- public static function getExtensionPath(string $scope=Scopes::AUTO): string
+ public static function getExtensionPath(): string
{
- return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'ext';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'ext';
}
/**
@@ -211,7 +186,7 @@
*/
public static function getConfigurationFile(): string
{
- return self::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'ncc.yaml';
+ return self::getDataPath() . DIRECTORY_SEPARATOR . 'ncc.yaml';
}
/**
diff --git a/src/ncc/ncc b/src/ncc/ncc
index fd7b4af..7430ad6 100644
--- a/src/ncc/ncc
+++ b/src/ncc/ncc
@@ -20,7 +20,7 @@
*
*/
-use ncc\CLI\Main;
+ use ncc\CLI\Main;
-require('autoload.php');
+ require('autoload.php');
Main::start($argv);
\ No newline at end of file
diff --git a/src/ncc/ncc.php b/src/ncc/ncc.php
index c3027f4..3b29178 100644
--- a/src/ncc/ncc.php
+++ b/src/ncc/ncc.php
@@ -25,6 +25,7 @@
namespace ncc;
+ use ncc\Classes\Runtime;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Objects\NccVersionInformation;
@@ -104,12 +105,16 @@
define('NCC_EXEC_IWD', getcwd()); // The initial working directory when ncc was first invoked
// Set version information about the current build
- $VersionInformation = self::getVersionInformation(true);
- define('NCC_VERSION_NUMBER', $VersionInformation->getVersion());
- define('NCC_VERSION_BRANCH', $VersionInformation->getBranch());
- define('NCC_VERSION_UPDATE_SOURCE', $VersionInformation->getUpdateSource());
- define('NCC_VERSION_FLAGS', $VersionInformation->getFlags());
+ $version_information = self::getVersionInformation(true);
+ define('NCC_VERSION_NUMBER', $version_information->getVersion());
+ define('NCC_VERSION_BRANCH', $version_information->getBranch());
+ define('NCC_VERSION_UPDATE_SOURCE', $version_information->getUpdateSource());
+ define('NCC_VERSION_FLAGS', $version_information->getFlags());
+ // Register the autoloader
+ spl_autoload_register([Runtime::class, 'autoloadHandler'], true, true);
+
+ // Finish initialization
define('NCC_INIT', 1);
return true;
}
diff --git a/src/ncc/version.json b/src/ncc/version.json
index 3ff9367..9eaf905 100644
--- a/src/ncc/version.json
+++ b/src/ncc/version.json
@@ -43,10 +43,6 @@
"vendor": "Symfony",
"package_name": "Yaml"
},
- {
- "vendor": "theseer",
- "package_name": "Autoload"
- },
{
"vendor": "theseer",
"package_name": "DirectoryScanner"
diff --git a/tests/functions/autoload_builder.php b/tests/functions/autoload_builder.php
new file mode 100644
index 0000000..c8a92dc
--- /dev/null
+++ b/tests/functions/autoload_builder.php
@@ -0,0 +1,14 @@
+generateAutoloaderArray($files);
+
+ var_dump($files);
+ var_dump($autoload);
\ No newline at end of file
diff --git a/tests/functions/package_reader.php b/tests/functions/package_reader.php
new file mode 100644
index 0000000..949dc2c
--- /dev/null
+++ b/tests/functions/package_reader.php
@@ -0,0 +1,7 @@
+installPackage($package_path);