- Corrected code-smell and code style issues in \ncc\Utilities > IO

- Corrected code-smell and code style issues in `\ncc > ncc`
 - Corrected code-smell and code style issues in `\ncc\CLI > Main`
 - Removed unused exception `FileNotFoundException` in `\ncc\CLI > HelpMenu`
 - Corrected code-smell and code style issues in `\ncc\Managers > ProjectManager`
 - Corrected code-smell and code style issues in `\ncc\Objects\NccVersionInformation > Component`
 - Corrected code-smell and code style issues in `\ncc\Objects\Package > Component`
 - Corrected code-smell and code style issues in `\ncc\Managers > ConfigurationManager`
 - Corrected code-smell and code style issues in `\ncc\Managers > CredentialManager`
 - Refactored `\ncc\Utilities > PathFinder` to remove all Win32 references
 - Corrected code-smell and code style issues in `\ncc\Objects > ExecutionPointers`
 - Corrected code-smell and code style issues in `\ncc\Managers > ExecutionPointerManager`
 - Corrected code-smell and code style issues in `\ncc\Utilities > Functions`
 - Corrected code-smell and code style issues in `\ncc\Managers > PackageManager`
 - Removed `FileNotFoundException` and `DirectoryNotFoundException` from `\ncc\Exceptions`
 - Removed the use of `InvalidScopeException` across the project
 - Removed references of Win32 from the project as Windows is not going supported
 - Added new exception `PathNotFoundException` and implemented it in replacement for `DirectoryNotFoundException` and
   `FileNotFoundException` in `\ncc\Exceptions`
 - Corrected code-smell and code style issues in `src/installer/hash_check.php`
 - Renamed `Abstracts` namespace to `Enums`
 - Updated class type to "final class" in `\ncc\Enums\Options > BuildConfigurationValues`
 - Updated class type to "final class" in `\ncc\Enums\Options > InitializeProjectOptions`
 - Updated class type to "final class" in `\ncc\Enums\Options > InstallPackageOptions`
 - Updated class type to "final class" in `\ncc\Enums\SpecialConstants > AssemblyConstants`
 - Updated class type to "final class" in `\ncc\Enums\SpecialConstants > BuildConstants`
 - Updated class type to "final class" in `\ncc\Enums\SpecialConstants > DateTimeConstants`
 - Updated class type to "final class" in `\ncc\Enums\SpecialConstants > InstallConstants`
 - Updated class type to "final class" in `\ncc\Enums\SpecialConstants > RuntimeConstants`
 - Updated class type to "final class" in `\ncc\Enums > AuthenticationType`
 - Updated class type to "final class" in `\ncc\Enums > CompilerExtensionDefaultVersions`
 - Updated class type to "final class" in `\ncc\Enums > CompilerExtensions`
 - Updated class type to "final class" in `\ncc\Enums > CompilerExtensionSupportedVersions`
 - Updated class type to "final class" in `\ncc\Enums > ComponentDataType`
 - Updated class type to "final class" in `\ncc\Enums > ComponentFileExtensions`
 - Updated class type to "final class" in `\ncc\Enums > ComposerPackageTypes`
 - Updated class type to "final class" in `\ncc\Enums > ComposerStabilityTypes`
 - Updated class type to "final class" in `\ncc\Enums > EncoderType`
 - Updated class type to "final class" in `\ncc\Enums > ExceptionCodes`
 - Updated class type to "final class" in `\ncc\Enums > HttpRequestType`
 - Updated class type to "final class" in `\ncc\Enums > HttpStatusCodes`
 - Updated class type to "final class" in `\ncc\Enums > LogLevel`
 - Updated class type to "final class" in `\ncc\Enums > NccBuildFlags`
 - Updated class type to "final class" in `\ncc\Enums > PackageStandardVersions`
 - Updated class type to "final class" in `\ncc\Enums > PackageStructureVersions`
 - Updated class type to "final class" in `\ncc\Enums > ProjectType`
 - Updated class type to "final class" in `\ncc\Enums > RegexPattern`
 - Updated class type to "final class" in `\ncc\Enums > RemoteSourceType`
 - Updated class type to "final class" in `\ncc\Enums > Runners`
 - Updated class type to "final class" in `\ncc\Enums > Scopes`
 - Updated class type to "final class" in `\ncc\Enums > Versions`
 - Corrected code-smell and code style issues in `\ncc\Classes > NccExtension > ConstantCompiler`
 - Corrected code-smell and code style issues in `\ncc\Classes > GitlabExtension > GitlabService`
 - Corrected code-smell and code style issues in `\ncc\Classes > GithubExtension > GithubService`
This commit is contained in:
Netkas 2023-08-17 14:40:49 -04:00
parent 983e34f58e
commit 0820cd3c32
No known key found for this signature in database
GPG key ID: 5DAF58535614062B
44 changed files with 1476 additions and 1198 deletions

View file

@ -1,6 +1,78 @@
<component name="InspectionProjectProfileManager"> <component name="InspectionProjectProfileManager">
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="133" name="PHP" />
</Languages>
</inspection_tool>
<inspection_tool class="ForgottenDebugOutputInspection" enabled="true" level="ERROR" enabled_by_default="true">
<option name="configuration">
<list>
<option value="\Codeception\Util\Debug::debug" />
<option value="\Codeception\Util\Debug::pause" />
<option value="\Doctrine\Common\Util\Debug::dump" />
<option value="\Doctrine\Common\Util\Debug::export" />
<option value="\Illuminate\Support\Debug\Dumper::dump" />
<option value="\Symfony\Component\Debug\Debug::enable" />
<option value="\Symfony\Component\Debug\DebugClassLoader::enable" />
<option value="\Symfony\Component\Debug\ErrorHandler::register" />
<option value="\Symfony\Component\Debug\ExceptionHandler::register" />
<option value="\TYPO3\CMS\Core\Utility\DebugUtility::debug" />
<option value="\Zend\Debug\Debug::dump" />
<option value="\Zend\Di\Display\Console::export" />
<option value="dd" />
<option value="debug_print_backtrace" />
<option value="debug_zval_dump" />
<option value="dpm" />
<option value="dpq" />
<option value="dsm" />
<option value="dump" />
<option value="dvm" />
<option value="error_log" />
<option value="kpr" />
<option value="phpinfo" />
<option value="print_r" />
<option value="var_dump" />
<option value="var_export" />
<option value="wp_die" />
<option value="xdebug_break" />
<option value="xdebug_call_class" />
<option value="xdebug_call_file" />
<option value="xdebug_call_function" />
<option value="xdebug_call_line" />
<option value="xdebug_code_coverage_started" />
<option value="xdebug_debug_zval" />
<option value="xdebug_debug_zval_stdout" />
<option value="xdebug_dump_superglobals" />
<option value="xdebug_enable" />
<option value="xdebug_get_code_coverage" />
<option value="xdebug_get_collected_errors" />
<option value="xdebug_get_declared_vars" />
<option value="xdebug_get_function_stack" />
<option value="xdebug_get_headers" />
<option value="xdebug_get_monitored_functions" />
<option value="xdebug_get_profiler_filename" />
<option value="xdebug_get_stack_depth" />
<option value="xdebug_get_tracefile_name" />
<option value="xdebug_is_enabled" />
<option value="xdebug_memory_usage" />
<option value="xdebug_peak_memory_usage" />
<option value="xdebug_print_function_stack" />
<option value="xdebug_start_code_coverage" />
<option value="xdebug_start_error_collection" />
<option value="xdebug_start_function_monitor" />
<option value="xdebug_start_trace" />
<option value="xdebug_stop_code_coverage" />
<option value="xdebug_stop_error_collection" />
<option value="xdebug_stop_function_monitor" />
<option value="xdebug_stop_trace" />
<option value="xdebug_time_index" />
<option value="xdebug_var_dump" />
</list>
</option>
<option name="migratedIntoUserSpace" value="true" />
</inspection_tool>
<inspection_tool class="IncorrectHttpHeaderInspection" enabled="true" level="WARNING" enabled_by_default="true"> <inspection_tool class="IncorrectHttpHeaderInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="customHeaders"> <option name="customHeaders">
<set> <set>
@ -25,5 +97,61 @@
</set> </set>
</option> </option>
</inspection_tool> </inspection_tool>
<inspection_tool class="SecurityAdvisoriesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="optionConfiguration">
<list>
<option value="barryvdh/laravel-debugbar" />
<option value="behat/behat" />
<option value="brianium/paratest" />
<option value="codeception/codeception" />
<option value="codedungeon/phpunit-result-printer" />
<option value="composer/composer" />
<option value="doctrine/coding-standard" />
<option value="filp/whoops" />
<option value="friendsofphp/php-cs-fixer" />
<option value="humbug/humbug" />
<option value="infection/infection" />
<option value="jakub-onderka/php-parallel-lint" />
<option value="johnkary/phpunit-speedtrap" />
<option value="kalessil/production-dependencies-guard" />
<option value="mikey179/vfsStream" />
<option value="mockery/mockery" />
<option value="mybuilder/phpunit-accelerator" />
<option value="orchestra/testbench" />
<option value="pdepend/pdepend" />
<option value="phan/phan" />
<option value="phing/phing" />
<option value="phpcompatibility/php-compatibility" />
<option value="phpmd/phpmd" />
<option value="phpro/grumphp" />
<option value="phpspec/phpspec" />
<option value="phpspec/prophecy" />
<option value="phpstan/phpstan" />
<option value="phpunit/phpunit" />
<option value="povils/phpmnd" />
<option value="roave/security-advisories" />
<option value="satooshi/php-coveralls" />
<option value="sebastian/phpcpd" />
<option value="slevomat/coding-standard" />
<option value="spatie/phpunit-watcher" />
<option value="squizlabs/php_codesniffer" />
<option value="sstalle/php7cc" />
<option value="symfony/debug" />
<option value="symfony/maker-bundle" />
<option value="symfony/phpunit-bridge" />
<option value="symfony/var-dumper" />
<option value="vimeo/psalm" />
<option value="wimg/php-compatibility" />
<option value="wp-coding-standards/wpcs" />
<option value="yiisoft/yii2-coding-standards" />
<option value="yiisoft/yii2-debug" />
<option value="yiisoft/yii2-gii" />
<option value="zendframework/zend-coding-standard" />
<option value="zendframework/zend-debug" />
<option value="zendframework/zend-test" />
</list>
</option>
</inspection_tool>
<inspection_tool class="UnknownInspectionInspection" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile> </profile>
</component> </component>

View file

@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Added ## Added
- `LICENSE.md` & `license.md` are now detected as license files in `\ncc\Classes\ComposerExtension > ComposerSourceBuiltin > convertProject()` - `LICENSE.md` & `license.md` are now detected as license files in `\ncc\Classes\ComposerExtension > ComposerSourceBuiltin > convertProject()`
- Added new exception `PathNotFoundException` and implemented it in replacement for `DirectoryNotFoundException` and
`FileNotFoundException` in `\ncc\Exceptions`
### Fixed ### Fixed
- Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()` - Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()`
@ -52,6 +54,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Updated class type to "final class" in `\ncc\Enums > Scopes` - Updated class type to "final class" in `\ncc\Enums > Scopes`
- Updated class type to "final class" in `\ncc\Enums > Versions` - Updated class type to "final class" in `\ncc\Enums > Versions`
- Corrected code-smell and code style issues in `src/installer/hash_check.php` - Corrected code-smell and code style issues in `src/installer/hash_check.php`
- Corrected code-smell and code style issues in `\ncc\Managers > ProjectManager`
- Corrected code-smell and code style issues in `\ncc\Objects\NccVersionInformation > Component`
- Corrected code-smell and code style issues in `\ncc\Objects\Package > Component`
- Corrected code-smell and code style issues in `\ncc\Managers > ConfigurationManager`
- Corrected code-smell and code style issues in `\ncc\Managers > CredentialManager`
- Refactored `\ncc\Utilities > PathFinder` to remove all Win32 references
- Corrected code-smell and code style issues in `\ncc\Objects > ExecutionPointers`
- Corrected code-smell and code style issues in `\ncc\Managers > ExecutionPointerManager`
- Corrected code-smell and code style issues in `\ncc\Utilities > Functions`
- Corrected code-smell and code style issues in `\ncc\Managers > PackageManager`
- Corrected code-smell and code style issues in `\ncc\Utilities > IO`
- Corrected code-smell and code style issues in `\ncc > ncc`
- Corrected code-smell and code style issues in `\ncc\CLI > Main`
## Removed
- Removed `FileNotFoundException` and `DirectoryNotFoundException` from `\ncc\Exceptions`
- Removed the use of `InvalidScopeException` across the project
- Removed references of Win32 from the project as Windows is not going supported
- Removed unused exception `FileNotFoundException` in `\ncc\CLI > HelpMenu`

View file

@ -1,5 +1,7 @@
# ![NCC](assets/icon/ncc@32px.png "NCC") NCC # ![NCC](assets/icon/ncc@32px.png "NCC") NCC
[![wakatime](https://wakatime.com/badge/user/bc15cc8e-c9b9-4c11-bad9-3e3cfacf01e4/project/273bc06f-12e7-43d7-824d-40a78b02aada.svg)](https://wakatime.com/badge/user/bc15cc8e-c9b9-4c11-bad9-3e3cfacf01e4/project/273bc06f-12e7-43d7-824d-40a78b02aada)
Nosial Code Compiler is a program written in PHP designed to be a multi-purpose compiler, package manager and toolkit. Nosial Code Compiler is a program written in PHP designed to be a multi-purpose compiler, package manager and toolkit.
This program is a complete re-write of the now defunct [PHP Package Manager (PPM)](https://git.n64.cc/intellivoid/ppm) This program is a complete re-write of the now defunct [PHP Package Manager (PPM)](https://git.n64.cc/intellivoid/ppm)
toolkit offering more features, security and proper code licensing and copyrighting for the components used for the project. toolkit offering more features, security and proper code licensing and copyrighting for the components used for the project.

View file

@ -291,7 +291,7 @@
foreach($VersionInformation->Components as $component) foreach($VersionInformation->Components as $component)
{ {
$full_name = $component->Vendor . '/' . $component->PackageName; $full_name = $component->vendor . '/' . $component->package_name;
try try
{ {

View file

@ -1,29 +1,28 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
namespace ncc\CLI; namespace ncc\CLI;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Objects\CliHelpSection; use ncc\Objects\CliHelpSection;
use ncc\Utilities\Console; use ncc\Utilities\Console;
@ -37,7 +36,6 @@ namespace ncc\CLI;
* @param $args * @param $args
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
*/ */
public static function start($args): void public static function start($args): void

View file

@ -1,24 +1,24 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
@ -34,10 +34,7 @@
use ncc\CLI\Management\PackageManagerMenu; use ncc\CLI\Management\PackageManagerMenu;
use ncc\CLI\Management\ProjectMenu; use ncc\CLI\Management\ProjectMenu;
use ncc\CLI\Management\SourcesMenu; use ncc\CLI\Management\SourcesMenu;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\RuntimeException;
use ncc\ncc; use ncc\ncc;
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\Functions; use ncc\Utilities\Functions;
@ -61,9 +58,6 @@
* *
* @param $argv * @param $argv
* @return void * @return void
* @throws RuntimeException
* @throws AccessDeniedException
* @throws IOException
*/ */
public static function start($argv): void public static function start($argv): void
{ {
@ -76,13 +70,13 @@
{ {
ncc::initialize(); ncc::initialize();
} }
catch (FileNotFoundException $e) catch (PathNotFoundException $e)
{ {
Console::outException('Cannot initialize NCC, one or more files were not found.', $e, 1); Console::outException('Cannot initialize NCC, one or more files were not found.', $e, 1);
} }
catch (RuntimeException $e) catch (Exception $e)
{ {
Console::outException('Cannot initialize NCC due to a runtime error.', $e, 1); Console::outException('Cannot initialize NCC due to an unexpected error.', $e, 1);
} }
define('NCC_CLI_MODE', 1); define('NCC_CLI_MODE', 1);
@ -116,11 +110,13 @@
if(Resolver::checkLogLevel(self::$log_level, LogLevel::DEBUG)) if(Resolver::checkLogLevel(self::$log_level, LogLevel::DEBUG))
{ {
Console::outDebug('Debug logging enabled'); Console::outDebug('Debug logging enabled');
/** @noinspection JsonEncodingApiUsageInspection */
Console::outDebug(sprintf('const: %s', json_encode(ncc::getConstants(), JSON_UNESCAPED_SLASHES))); Console::outDebug(sprintf('const: %s', json_encode(ncc::getConstants(), JSON_UNESCAPED_SLASHES)));
/** @noinspection JsonEncodingApiUsageInspection */
Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES))); Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES)));
} }
if(in_array(NccBuildFlags::UNSTABLE, NCC_VERSION_FLAGS)) if(in_array(NccBuildFlags::UNSTABLE, NCC_VERSION_FLAGS, true))
{ {
Console::outWarning('This is an unstable build of NCC, expect some features to not work as expected'); Console::outWarning('This is an unstable build of NCC, expect some features to not work as expected');
} }
@ -187,18 +183,26 @@
} }
} }
private static function displayVersion() /**
* Displays the current version of NCC
*
* @return void
*/
private static function displayVersion(): void
{ {
Console::out(sprintf('NCC version %s (%s)', NCC_VERSION_NUMBER, NCC_VERSION_BRANCH)); Console::out(sprintf('NCC version %s (%s)', NCC_VERSION_NUMBER, NCC_VERSION_BRANCH));
} }
/** /**
* Returns the arguments passed to NCC
*
* @return array * @return array
*/ */
public static function getArgs(): array public static function getArgs(): array
{ {
if (self::$args == null) if (self::$args === null)
{ {
/** @noinspection IssetArgumentExistenceInspection */
if(isset($argv)) if(isset($argv))
{ {
self::$args = Resolver::parseArguments(implode(' ', $argv)); self::$args = Resolver::parseArguments(implode(' ', $argv));
@ -217,8 +221,11 @@
*/ */
public static function getLogLevel(): string public static function getLogLevel(): string
{ {
if(self::$log_level == null) if(self::$log_level === null)
{
self::$log_level = LogLevel::INFO; self::$log_level = LogLevel::INFO;
}
return self::$log_level; return self::$log_level;
} }

View file

@ -225,7 +225,7 @@ namespace ncc\CLI\Management;
Console::out('components:'); Console::out('components:');
foreach($package->Components as $component) foreach($package->Components as $component)
{ {
Console::out(' - ' . sprintf('#%s %s - %s', $component->DataType, $component->Name, json_encode(($component->Flags ?? []), JSON_UNESCAPED_SLASHES))); Console::out(' - ' . sprintf('#%s %s - %s', $component->data_types, $component->name, json_encode(($component->flags ?? []), JSON_UNESCAPED_SLASHES)));
} }
} }
else else
@ -363,7 +363,7 @@ namespace ncc\CLI\Management;
$path = $package; $path = $package;
$parsed_source = new RemotePackageInput($path); $parsed_source = new RemotePackageInput($path);
if($parsed_source->Vendor !== null && $parsed_source->Package !== null && $parsed_source->Source !== null) if($parsed_source->vendor !== null && $parsed_source->package !== null && $parsed_source->source !== null)
{ {
try try
{ {

View file

@ -1,38 +1,37 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
namespace ncc\CLI\Management; namespace ncc\CLI\Management;
use Exception; use Exception;
use ncc\Enums\CompilerExtensionDefaultVersions; use ncc\Enums\CompilerExtensionDefaultVersions;
use ncc\Enums\CompilerExtensions; use ncc\Enums\CompilerExtensions;
use ncc\Enums\CompilerExtensionSupportedVersions; use ncc\Enums\CompilerExtensionSupportedVersions;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\DirectoryNotFoundException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidPackageNameException;
use ncc\Exceptions\InvalidProjectNameException; use ncc\Exceptions\InvalidProjectNameException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\MalformedJsonException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\ProjectAlreadyExistsException; use ncc\Exceptions\ProjectAlreadyExistsException;
use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\ProjectConfigurationNotFoundException;
use ncc\Managers\ProjectManager; use ncc\Managers\ProjectManager;
@ -49,10 +48,9 @@ namespace ncc\CLI\Management;
* @param $args * @param $args
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws PathNotFoundException
* @throws ProjectConfigurationNotFoundException * @throws ProjectConfigurationNotFoundException
*/ */
public static function start($args): void public static function start($args): void
@ -69,11 +67,10 @@ namespace ncc\CLI\Management;
* @param $args * @param $args
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws ProjectConfigurationNotFoundException * @throws ProjectConfigurationNotFoundException
* @throws PathNotFoundException
*/ */
public static function createProject($args): void public static function createProject($args): void
{ {

View file

@ -22,7 +22,7 @@
namespace ncc\Classes\BashExtension; namespace ncc\Classes\BashExtension;
use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\RunnerInterface; use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy; use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
@ -33,16 +33,17 @@ namespace ncc\Classes\BashExtension;
/** /**
* @inheritDoc * @inheritDoc
* @throws PathNotFoundException
*/ */
public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit
{ {
if(!file_exists($path) && !is_file($path)) if(!file_exists($path) && !is_file($path))
{ {
throw new FileNotFoundException($path); throw new PathNotFoundException($path);
} }
$execution_unit = new ExecutionUnit(); $execution_unit = new ExecutionUnit();
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
$policy->Execute->Target = null; $policy->Execute->Target = null;

View file

@ -38,8 +38,7 @@ namespace ncc\Classes\ComposerExtension;
use ncc\Exceptions\ComposerDisabledException; use ncc\Exceptions\ComposerDisabledException;
use ncc\Exceptions\ComposerException; use ncc\Exceptions\ComposerException;
use ncc\Exceptions\ComposerNotAvailableException; use ncc\Exceptions\ComposerNotAvailableException;
use ncc\Exceptions\DirectoryNotFoundException; use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InternalComposerNotAvailableException; use ncc\Exceptions\InternalComposerNotAvailableException;
use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\InvalidScopeException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
@ -88,14 +87,13 @@ namespace ncc\Classes\ComposerExtension;
* @throws ComposerDisabledException * @throws ComposerDisabledException
* @throws ComposerException * @throws ComposerException
* @throws ComposerNotAvailableException * @throws ComposerNotAvailableException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws InternalComposerNotAvailableException * @throws InternalComposerNotAvailableException
* @throws InvalidScopeException * @throws InvalidScopeException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws PackageNotFoundException * @throws PackageNotFoundException
* @throws PackagePreparationFailedException * @throws PackagePreparationFailedException
* @throws PathNotFoundException
* @throws ProjectConfigurationNotFoundException * @throws ProjectConfigurationNotFoundException
* @throws RuntimeException * @throws RuntimeException
* @throws UnsupportedCompilerExtensionException * @throws UnsupportedCompilerExtensionException
@ -103,7 +101,7 @@ namespace ncc\Classes\ComposerExtension;
*/ */
public static function fetch(RemotePackageInput $packageInput): string public static function fetch(RemotePackageInput $packageInput): string
{ {
$package_path = self::require($packageInput->Vendor, $packageInput->Package, $packageInput->Version); $package_path = self::require($packageInput->vendor, $packageInput->package, $packageInput->version);
$packages = self::compilePackages($package_path . DIRECTORY_SEPARATOR . 'composer.lock'); $packages = self::compilePackages($package_path . DIRECTORY_SEPARATOR . 'composer.lock');
$real_package_name = explode('=', $packageInput->toStandard(false))[0]; $real_package_name = explode('=', $packageInput->toStandard(false))[0];
@ -131,13 +129,12 @@ namespace ncc\Classes\ComposerExtension;
* @throws ComposerDisabledException * @throws ComposerDisabledException
* @throws ComposerException * @throws ComposerException
* @throws ComposerNotAvailableException * @throws ComposerNotAvailableException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws InternalComposerNotAvailableException * @throws InternalComposerNotAvailableException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws PackageNotFoundException * @throws PackageNotFoundException
* @throws PackagePreparationFailedException * @throws PackagePreparationFailedException
* @throws PathNotFoundException
* @throws ProjectConfigurationNotFoundException * @throws ProjectConfigurationNotFoundException
* @throws UnsupportedCompilerExtensionException * @throws UnsupportedCompilerExtensionException
* @throws UserAbortedOperationException * @throws UserAbortedOperationException
@ -147,7 +144,7 @@ namespace ncc\Classes\ComposerExtension;
// Check if the file composer.json exists // Check if the file composer.json exists
if (!file_exists($path . DIRECTORY_SEPARATOR . 'composer.json')) if (!file_exists($path . DIRECTORY_SEPARATOR . 'composer.json'))
{ {
throw new FileNotFoundException(sprintf('File "%s" not found', $path . DIRECTORY_SEPARATOR . 'composer.json')); throw new PathNotFoundException(sprintf('File "%s" not found', $path . DIRECTORY_SEPARATOR . 'composer.json'));
} }
// Execute composer with options // Execute composer with options
@ -205,12 +202,11 @@ namespace ncc\Classes\ComposerExtension;
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws BuildConfigurationNotFoundException * @throws BuildConfigurationNotFoundException
* @throws BuildException * @throws BuildException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws PackageNotFoundException * @throws PackageNotFoundException
* @throws PackagePreparationFailedException * @throws PackagePreparationFailedException
* @throws PathNotFoundException
* @throws ProjectConfigurationNotFoundException * @throws ProjectConfigurationNotFoundException
* @throws UnsupportedCompilerExtensionException * @throws UnsupportedCompilerExtensionException
*/ */
@ -218,7 +214,7 @@ namespace ncc\Classes\ComposerExtension;
{ {
if (!file_exists($composer_lock_path)) if (!file_exists($composer_lock_path))
{ {
throw new FileNotFoundException($composer_lock_path); throw new PathNotFoundException($composer_lock_path);
} }
$base_dir = dirname($composer_lock_path); $base_dir = dirname($composer_lock_path);
@ -537,7 +533,7 @@ namespace ncc\Classes\ComposerExtension;
* @throws ComposerDisabledException * @throws ComposerDisabledException
* @throws ComposerException * @throws ComposerException
* @throws ComposerNotAvailableException * @throws ComposerNotAvailableException
* @throws FileNotFoundException * @throws PathNotFoundException
* @throws IOException * @throws IOException
* @throws InternalComposerNotAvailableException * @throws InternalComposerNotAvailableException
* @throws InvalidScopeException * @throws InvalidScopeException
@ -564,7 +560,7 @@ namespace ncc\Classes\ComposerExtension;
if (!file_exists($tpl_file)) if (!file_exists($tpl_file))
{ {
throw new FileNotFoundException($tpl_file); throw new PathNotFoundException($tpl_file);
} }
$composer_exec = self::getComposerPath(); $composer_exec = self::getComposerPath();
@ -698,7 +694,6 @@ namespace ncc\Classes\ComposerExtension;
* @param mixed $composer_package * @param mixed $composer_package
* @return ProjectConfiguration * @return ProjectConfiguration
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws PackagePreparationFailedException * @throws PackagePreparationFailedException
@ -707,7 +702,7 @@ namespace ncc\Classes\ComposerExtension;
{ {
if($composer_package === null) if($composer_package === null)
{ {
$composer_package = ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json', Functions::FORCE_ARRAY)); $composer_package = Functions::loadComposerJson($package_path . DIRECTORY_SEPARATOR . 'composer.json');
} }
$project_configuration = self::generateProjectConfiguration($composer_package, $version_map); $project_configuration = self::generateProjectConfiguration($composer_package, $version_map);

View file

@ -59,9 +59,9 @@ namespace ncc\Classes\GithubExtension;
{ {
$httpRequest = new HttpRequest(); $httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->SSL ? "https" : "http"); $protocol = ($definedRemoteSource->SSL ? "https" : "http");
$owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); $owner_f = str_ireplace("/", "%2F", $packageInput->vendor);
$owner_f = str_ireplace(".", "%2F", $owner_f); $owner_f = str_ireplace(".", "%2F", $owner_f);
$repository = urlencode($packageInput->Package); $repository = urlencode($packageInput->package);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository"; $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository";
$response_decoded = self::getJsonResponse($httpRequest, $entry); $response_decoded = self::getJsonResponse($httpRequest, $entry);
@ -128,9 +128,9 @@ namespace ncc\Classes\GithubExtension;
{ {
$httpRequest = new HttpRequest(); $httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->SSL ? "https" : "http"); $protocol = ($definedRemoteSource->SSL ? "https" : "http");
$owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); $owner_f = str_ireplace("/", "%2F", $packageInput->vendor);
$owner_f = str_ireplace(".", "%2F", $owner_f); $owner_f = str_ireplace(".", "%2F", $owner_f);
$repository = urlencode($packageInput->Package); $repository = urlencode($packageInput->package);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases"; $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases";
$response_decoded = self::getJsonResponse($httpRequest, $entry); $response_decoded = self::getJsonResponse($httpRequest, $entry);
@ -235,7 +235,7 @@ namespace ncc\Classes\GithubExtension;
throw new VersionNotFoundException('No releases found for the given repository.'); throw new VersionNotFoundException('No releases found for the given repository.');
} }
if ($packageInput->Version === Versions::LATEST) if ($packageInput->version === Versions::LATEST)
{ {
$latest_version = null; $latest_version = null;
foreach ($releases as $release) foreach ($releases as $release)
@ -256,7 +256,7 @@ namespace ncc\Classes\GithubExtension;
} }
// Query a specific version // Query a specific version
if (!isset($releases[$packageInput->Version])) if (!isset($releases[$packageInput->version]))
{ {
// Find the closest thing to the requested version // Find the closest thing to the requested version
$selected_version = null; $selected_version = null;
@ -268,7 +268,7 @@ namespace ncc\Classes\GithubExtension;
continue; continue;
} }
if (VersionComparator::compareVersion($version, $packageInput->Version) === 1) if (VersionComparator::compareVersion($version, $packageInput->version) === 1)
{ {
$selected_version = $version; $selected_version = $version;
} }
@ -281,7 +281,7 @@ namespace ncc\Classes\GithubExtension;
} }
else else
{ {
$selected_version = $packageInput->Version; $selected_version = $packageInput->version;
} }
if (!isset($releases[$selected_version])) if (!isset($releases[$selected_version]))

View file

@ -58,9 +58,9 @@
{ {
$httpRequest = new HttpRequest(); $httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->SSL ? "https" : "http"); $protocol = ($definedRemoteSource->SSL ? "https" : "http");
$owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); $owner_f = str_ireplace("/", "%2F", $packageInput->vendor);
$owner_f = str_ireplace(".", "%2F", $owner_f); $owner_f = str_ireplace(".", "%2F", $owner_f);
$project_f = str_ireplace("/", "%2F", $packageInput->Package); $project_f = str_ireplace("/", "%2F", $packageInput->package);
$project_f = str_ireplace(".", "%2F", $project_f); $project_f = str_ireplace(".", "%2F", $project_f);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$project_f"; $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$project_f";
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
@ -100,7 +100,7 @@
*/ */
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
{ {
$releases = self::getReleases($packageInput->Vendor, $packageInput->Package, $definedRemoteSource, $entry); $releases = self::getReleases($packageInput->vendor, $packageInput->package, $definedRemoteSource, $entry);
if(count($releases) === 0) if(count($releases) === 0)
{ {
@ -108,7 +108,7 @@
} }
// Query the latest package only // Query the latest package only
if($packageInput->Version === Versions::LATEST) if($packageInput->version === Versions::LATEST)
{ {
$latest_version = null; $latest_version = null;
foreach($releases as $release) foreach($releases as $release)
@ -129,7 +129,7 @@
} }
// Query a specific version // Query a specific version
if(!isset($releases[$packageInput->Version])) if(!isset($releases[$packageInput->version]))
{ {
// Find the closest thing to the requested version // Find the closest thing to the requested version
$selected_version = null; $selected_version = null;
@ -141,7 +141,7 @@
continue; continue;
} }
if(VersionComparator::compareVersion($version, $packageInput->Version) === 1) if(VersionComparator::compareVersion($version, $packageInput->version) === 1)
{ {
$selected_version = $version; $selected_version = $version;
} }
@ -154,7 +154,7 @@
} }
else else
{ {
$selected_version = $packageInput->Version; $selected_version = $packageInput->version;
} }
if(!isset($releases[$selected_version])) if(!isset($releases[$selected_version]))

View file

@ -37,7 +37,7 @@ namespace ncc\Classes\LuaExtension;
{ {
$execution_unit = new ExecutionUnit(); $execution_unit = new ExecutionUnit();
$policy->Execute->Target = null; $policy->Execute->Target = null;
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
return $execution_unit; return $execution_unit;

View file

@ -266,7 +266,7 @@ namespace ncc\Classes\NccExtension;
$units = []; $units = [];
foreach($package->ExecutionUnits as $executionUnit) foreach($package->ExecutionUnits as $executionUnit)
{ {
Console::outDebug(sprintf('compiling execution unit consts %s (%s)', $executionUnit->ExecutionPolicy->Name, implode(', ', array_keys($refs)))); Console::outDebug(sprintf('compiling execution unit consts %s (%s)', $executionUnit->execution_policy->Name, implode(', ', array_keys($refs))));
$units[] = self::compileExecutionUnitConstants($executionUnit, $refs); $units[] = self::compileExecutionUnitConstants($executionUnit, $refs);
} }
$package->ExecutionUnits = $units; $package->ExecutionUnits = $units;
@ -315,46 +315,46 @@ namespace ncc\Classes\NccExtension;
*/ */
public static function compileExecutionUnitConstants(Package\ExecutionUnit $unit, array $refs): Package\ExecutionUnit public static function compileExecutionUnitConstants(Package\ExecutionUnit $unit, array $refs): Package\ExecutionUnit
{ {
$unit->ExecutionPolicy->Message = self::compileConstants($unit->ExecutionPolicy->Message, $refs); $unit->execution_policy->Message = self::compileConstants($unit->execution_policy->Message, $refs);
if($unit->ExecutionPolicy->ExitHandlers !== null) if($unit->execution_policy->ExitHandlers !== null)
{ {
if($unit->ExecutionPolicy->ExitHandlers->Success !== null) if($unit->execution_policy->ExitHandlers->Success !== null)
{ {
$unit->ExecutionPolicy->ExitHandlers->Success->Message = self::compileConstants($unit->ExecutionPolicy->ExitHandlers->Success->Message, $refs); $unit->execution_policy->ExitHandlers->Success->Message = self::compileConstants($unit->execution_policy->ExitHandlers->Success->Message, $refs);
} }
if($unit->ExecutionPolicy->ExitHandlers->Error !== null) if($unit->execution_policy->ExitHandlers->Error !== null)
{ {
$unit->ExecutionPolicy->ExitHandlers->Error->Message = self::compileConstants($unit->ExecutionPolicy->ExitHandlers->Error->Message, $refs); $unit->execution_policy->ExitHandlers->Error->Message = self::compileConstants($unit->execution_policy->ExitHandlers->Error->Message, $refs);
} }
if($unit->ExecutionPolicy->ExitHandlers->Warning !== null) if($unit->execution_policy->ExitHandlers->Warning !== null)
{ {
$unit->ExecutionPolicy->ExitHandlers->Warning->Message = self::compileConstants($unit->ExecutionPolicy->ExitHandlers->Warning->Message, $refs); $unit->execution_policy->ExitHandlers->Warning->Message = self::compileConstants($unit->execution_policy->ExitHandlers->Warning->Message, $refs);
} }
} }
if($unit->ExecutionPolicy->Execute !== null) if($unit->execution_policy->Execute !== null)
{ {
if($unit->ExecutionPolicy->Execute->Target !== null) if($unit->execution_policy->Execute->Target !== null)
{ {
$unit->ExecutionPolicy->Execute->Target = self::compileConstants($unit->ExecutionPolicy->Execute->Target, $refs); $unit->execution_policy->Execute->Target = self::compileConstants($unit->execution_policy->Execute->Target, $refs);
} }
if($unit->ExecutionPolicy->Execute->WorkingDirectory !== null) if($unit->execution_policy->Execute->WorkingDirectory !== null)
{ {
$unit->ExecutionPolicy->Execute->WorkingDirectory = self::compileConstants($unit->ExecutionPolicy->Execute->WorkingDirectory, $refs); $unit->execution_policy->Execute->WorkingDirectory = self::compileConstants($unit->execution_policy->Execute->WorkingDirectory, $refs);
} }
if($unit->ExecutionPolicy->Execute->Options !== null && count($unit->ExecutionPolicy->Execute->Options) > 0) if($unit->execution_policy->Execute->Options !== null && count($unit->execution_policy->Execute->Options) > 0)
{ {
$options = []; $options = [];
foreach($unit->ExecutionPolicy->Execute->Options as $key=>$value) foreach($unit->execution_policy->Execute->Options as $key=> $value)
{ {
$options[self::compileConstants($key, $refs)] = self::compileConstants($value, $refs); $options[self::compileConstants($key, $refs)] = self::compileConstants($value, $refs);
} }
$unit->ExecutionPolicy->Execute->Options = $options; $unit->execution_policy->Execute->Options = $options;
} }
} }

View file

@ -54,7 +54,7 @@ namespace ncc\Classes\NccExtension;
$ExecutionPointerManager = new ExecutionPointerManager(); $ExecutionPointerManager = new ExecutionPointerManager();
$ExecutionPointerManager->addUnit($package, $version, $unit, true); $ExecutionPointerManager->addUnit($package, $version, $unit, true);
$ExecutionPointerManager->executeUnit($package, $version, $unit->ExecutionPolicy->Name); $ExecutionPointerManager->executeUnit($package, $version, $unit->execution_policy->Name);
$ExecutionPointerManager->cleanTemporaryUnits(); $ExecutionPointerManager->cleanTemporaryUnits();
} }
} }

View file

@ -40,7 +40,7 @@ namespace ncc\Classes\PerlExtension;
$policy->Execute->Target = null; $policy->Execute->Target = null;
if(!file_exists($path) && !is_file($path)) if(!file_exists($path) && !is_file($path))
throw new FileNotFoundException($path); throw new FileNotFoundException($path);
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
return $execution_unit; return $execution_unit;

View file

@ -169,10 +169,10 @@
continue; continue;
$Component = new Package\Component(); $Component = new Package\Component();
$Component->Name = Functions::removeBasename($item->getPathname(), $this->path); $Component->name = Functions::removeBasename($item->getPathname(), $this->path);
$this->package->Components[] = $Component; $this->package->Components[] = $Component;
Console::outVerbose(sprintf('Found component %s', $Component->Name)); Console::outVerbose(sprintf('Found component %s', $Component->name));
} }
if(count($this->package->Components) > 0) if(count($this->package->Components) > 0)
@ -396,7 +396,7 @@
Console::inlineProgressBar($processed_items, $total_items); Console::inlineProgressBar($processed_items, $total_items);
} }
$content = IO::fread(Functions::correctDirectorySeparator($this->path . $component->Name)); $content = IO::fread(Functions::correctDirectorySeparator($this->path . $component->name));
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7); $parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
try try
@ -407,30 +407,30 @@
if($encoded === false) if($encoded === false)
{ {
$component->DataType = ComponentDataType::BASE64_ENCODED; $component->data_types = ComponentDataType::BASE64_ENCODED;
$component->Data = Base64::encode($content); $component->data = Base64::encode($content);
} }
else else
{ {
$component->DataType = ComponentDataType::AST; $component->data_types = ComponentDataType::AST;
$component->Data = json_decode($encoded, true); $component->data = json_decode($encoded, true);
} }
} }
catch(Exception $e) catch(Exception $e)
{ {
$component->DataType = ComponentDataType::BASE64_ENCODED; $component->data_types = ComponentDataType::BASE64_ENCODED;
$component->Data = Base64::encode($content); $component->data = Base64::encode($content);
unset($e); unset($e);
} }
unset($parser); unset($parser);
$component->Name = str_replace($this->project->Build->SourcePath, (string)null, $component->Name); $component->name = str_replace($this->project->Build->SourcePath, (string)null, $component->name);
$component->updateChecksum(); $component->updateChecksum();
$components[] = $component; $components[] = $component;
$processed_items += 1; $processed_items += 1;
Console::outDebug(sprintf('processed component %s (%s)', $component->Name, $component->DataType)); Console::outDebug(sprintf('processed component %s (%s)', $component->name, $component->data_types));
} }
// Update the components // Update the components

View file

@ -89,35 +89,35 @@
*/ */
public function processComponent(Package\Component $component): ?string public function processComponent(Package\Component $component): ?string
{ {
if($component->Data == null) if($component->data == null)
return null; return null;
if(!$component->validateChecksum()) if(!$component->validate_checksum())
throw new ComponentChecksumException('Checksum validation failed for component ' . $component->Name . ', the package may be corrupted.'); throw new ComponentChecksumException('Checksum validation failed for component ' . $component->name . ', the package may be corrupted.');
switch($component->DataType) switch($component->data_types)
{ {
case ComponentDataType::AST: case ComponentDataType::AST:
try try
{ {
$stmts = $this->decodeRecursive($component->Data); $stmts = $this->decodeRecursive($component->data);
} }
catch (Exception $e) catch (Exception $e)
{ {
throw new ComponentDecodeException('Cannot decode component: ' . $component->Name . ', ' . $e->getMessage(), $e); throw new ComponentDecodeException('Cannot decode component: ' . $component->name . ', ' . $e->getMessage(), $e);
} }
$prettyPrinter = new Standard(); $prettyPrinter = new Standard();
return $prettyPrinter->prettyPrintFile($stmts); return $prettyPrinter->prettyPrintFile($stmts);
case ComponentDataType::BASE64_ENCODED: case ComponentDataType::BASE64_ENCODED:
return Base64::decode($component->Data); return Base64::decode($component->data);
case ComponentDataType::PLAIN: case ComponentDataType::PLAIN:
return $component->Data; return $component->data;
default: default:
throw new UnsupportedComponentTypeException('Unsupported component type \'' . $component->DataType . '\''); throw new UnsupportedComponentTypeException('Unsupported component type \'' . $component->data_types . '\'');
} }
} }

View file

@ -46,7 +46,7 @@ namespace ncc\Classes\PhpExtension;
if(!file_exists($path) && !is_file($path)) if(!file_exists($path) && !is_file($path))
throw new FileNotFoundException($path); throw new FileNotFoundException($path);
$policy->Execute->Target = null; $policy->Execute->Target = null;
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
return $execution_unit; return $execution_unit;

View file

@ -40,7 +40,7 @@ namespace ncc\Classes\PythonExtension;
if(!file_exists($path) && !is_file($path)) if(!file_exists($path) && !is_file($path))
throw new FileNotFoundException($path); throw new FileNotFoundException($path);
$policy->Execute->Target = null; $policy->Execute->Target = null;
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
return $execution_unit; return $execution_unit;

View file

@ -40,7 +40,7 @@ namespace ncc\Classes\PythonExtension;
if(!file_exists($path) && !is_file($path)) if(!file_exists($path) && !is_file($path))
throw new FileNotFoundException($path); throw new FileNotFoundException($path);
$policy->Execute->Target = null; $policy->Execute->Target = null;
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
return $execution_unit; return $execution_unit;

View file

@ -40,7 +40,7 @@ namespace ncc\Classes\PythonExtension;
if(!file_exists($path) && !is_file($path)) if(!file_exists($path) && !is_file($path))
throw new FileNotFoundException($path); throw new FileNotFoundException($path);
$policy->Execute->Target = null; $policy->Execute->Target = null;
$execution_unit->ExecutionPolicy = $policy; $execution_unit->execution_policy = $policy;
$execution_unit->Data = IO::fread($path); $execution_unit->Data = IO::fread($path);
return $execution_unit; return $execution_unit;

View file

@ -23,6 +23,7 @@
namespace ncc\Enums; namespace ncc\Enums;
use ncc\Exceptions\InvalidDependencyConfiguration; use ncc\Exceptions\InvalidDependencyConfiguration;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\SymlinkException; use ncc\Exceptions\SymlinkException;
use ncc\Exceptions\UnsupportedArchiveException; use ncc\Exceptions\UnsupportedArchiveException;
@ -37,16 +38,6 @@ namespace ncc\Enums;
*/ */
public const INVALID_PROJECT_CONFIGURATION = -1700; public const INVALID_PROJECT_CONFIGURATION = -1700;
/**
* @see FileNotFoundException;
*/
public const FILE_NOT_FOUND = -1701;
/**
* @see DirectoryNotFoundException
*/
public const DIRECTORY_NOT_FOUND = -1702;
/** /**
* @see InvalidScopeException * @see InvalidScopeException
*/ */
@ -367,13 +358,16 @@ namespace ncc\Enums;
*/ */
public const SYMLINK_EXCEPTION = -1768; public const SYMLINK_EXCEPTION = -1768;
/**
* @see PathNotFoundException
*/
public const PATH_NOT_FOUND = -1769;
/** /**
* All the exception codes from NCC * All the exception codes from NCC
*/ */
public const All = [ public const All = [
self::INVALID_PROJECT_CONFIGURATION, self::INVALID_PROJECT_CONFIGURATION,
self::FILE_NOT_FOUND,
self::DIRECTORY_NOT_FOUND,
self::INVALID_SCOPE, self::INVALID_SCOPE,
self::ACCESS_DENIED, self::ACCESS_DENIED,
self::MALFORMED_JSON, self::MALFORMED_JSON,
@ -435,5 +429,6 @@ namespace ncc\Enums;
self::INVALID_BUILD_CONFIGURATION, self::INVALID_BUILD_CONFIGURATION,
self::INVALID_DEPENDENCY_CONFIGURATION, self::INVALID_DEPENDENCY_CONFIGURATION,
self::SYMLINK_EXCEPTION, self::SYMLINK_EXCEPTION,
self::PATH_NOT_FOUND
]; ];
} }

View file

@ -1,41 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Exceptions;
use Exception;
use ncc\Enums\ExceptionCodes;
use Throwable;
class DirectoryNotFoundException extends Exception
{
/**
* Public Constructor
*
* @param string $path
* @param Throwable|null $previous
*/
public function __construct(string $path = "", ?Throwable $previous = null)
{
parent::__construct('The file \'' . realpath($path) . '\' was not found', ExceptionCodes::DIRECTORY_NOT_FOUND, $previous);
}
}

View file

@ -1,43 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Exceptions;
use Exception;
use ncc\Enums\ExceptionCodes;
use Throwable;
/**
* @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2022. Nosial - All Rights Reserved.
*/
class FileNotFoundException extends Exception
{
/**
* @param string $path
* @param Throwable|null $previous
*/
public function __construct(string $path = "", ?Throwable $previous = null)
{
parent::__construct('The file \'' . realpath($path) . '\' was not found', ExceptionCodes::FILE_NOT_FOUND, $previous);
}
}

View file

@ -0,0 +1,35 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Exceptions;
use Exception;
use ncc\Enums\ExceptionCodes;
use Throwable;
class PathNotFoundException extends Exception
{
public function __construct(string $path, ?Throwable $previous = null)
{
parent::__construct(sprintf('Path "%s" not found', $path), ExceptionCodes::PATH_NOT_FOUND, $previous);
}
}

View file

@ -1,32 +1,32 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
namespace ncc\Interfaces; namespace ncc\Interfaces;
use ncc\Enums\Options\BuildConfigurationValues; use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\BuildException; use ncc\Exceptions\BuildException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Objects\Package; use ncc\Objects\Package;
use ncc\Objects\ProjectConfiguration; use ncc\Objects\ProjectConfiguration;
@ -49,12 +49,12 @@ namespace ncc\Interfaces;
public function prepare(string $build_configuration=BuildConfigurationValues::DEFAULT): void; public function prepare(string $build_configuration=BuildConfigurationValues::DEFAULT): void;
/** /**
* Executes the compile process in the correct order and returns the finalized Package object * Executes the compiler process in the correct order and returns the finalized Package object
* *
* @return Package|null * @return Package|null
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws BuildException * @throws BuildException
* @throws FileNotFoundException * @throws PathNotFoundException
* @throws IOException * @throws IOException
*/ */
public function build(): ?Package; public function build(): ?Package;
@ -64,7 +64,7 @@ namespace ncc\Interfaces;
* *
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException * @throws PathNotFoundException
* @throws IOException * @throws IOException
*/ */
public function compileComponents(): void; public function compileComponents(): void;
@ -74,7 +74,7 @@ namespace ncc\Interfaces;
* *
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException * @throws PathNotFoundException
* @throws IOException * @throws IOException
*/ */
public function compileResources(): void; public function compileResources(): void;
@ -84,7 +84,7 @@ namespace ncc\Interfaces;
* *
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException * @throws PathNotFoundException
* @throws IOException * @throws IOException
*/ */
public function compileExecutionPolicies(): void; public function compileExecutionPolicies(): void;

View file

@ -1,24 +1,24 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
@ -27,7 +27,6 @@
use Exception; use Exception;
use ncc\Enums\Scopes; use ncc\Enums\Scopes;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\InvalidScopeException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\ThirdParty\Symfony\Yaml\Yaml; use ncc\ThirdParty\Symfony\Yaml\Yaml;
@ -45,11 +44,10 @@
* *
* @var mixed * @var mixed
*/ */
private $Configuration; private $configuration;
/** /**
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws InvalidScopeException * @throws InvalidScopeException
*/ */
@ -63,7 +61,6 @@
* *
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws InvalidScopeException * @throws InvalidScopeException
*/ */
@ -71,12 +68,16 @@
{ {
Console::outDebug(sprintf('loading configuration file from %s', PathFinder::getConfigurationFile())); Console::outDebug(sprintf('loading configuration file from %s', PathFinder::getConfigurationFile()));
$this->Configuration = RuntimeCache::get('ncc.yaml'); $this->configuration = RuntimeCache::get('ncc.yaml');
if($this->Configuration !== null)
if($this->configuration !== null)
{
return; return;
}
$configuration_contents = IO::fread(PathFinder::getConfigurationFile()); $configuration_contents = IO::fread(PathFinder::getConfigurationFile());
$this->Configuration = Yaml::parse($configuration_contents); $this->configuration = Yaml::parse($configuration_contents);
RuntimeCache::set('ncc.yaml', $this->Configuration); RuntimeCache::set('ncc.yaml', $this->configuration);
} }
/** /**
@ -92,13 +93,17 @@
Console::outDebug(sprintf('saving configuration file to %s', PathFinder::getConfigurationFile())); Console::outDebug(sprintf('saving configuration file to %s', PathFinder::getConfigurationFile()));
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Cannot save configuration file, insufficient permissions'); throw new AccessDeniedException('Cannot save configuration file, insufficient permissions');
}
if($this->Configuration == null) if($this->configuration === null)
{
return; return;
}
IO::fwrite(PathFinder::getConfigurationFile(), Yaml::dump($this->Configuration), 0755); IO::fwrite(PathFinder::getConfigurationFile(), Yaml::dump($this->configuration), 0755);
RuntimeCache::set('ncc.yaml', $this->Configuration); RuntimeCache::set('ncc.yaml', $this->configuration);
RuntimeCache::set('config_cache', []); RuntimeCache::set('config_cache', []);
} }
@ -108,20 +113,18 @@
* *
* @param string $property * @param string $property
* @return mixed|null * @return mixed|null
* @noinspection PhpMissingReturnTypeInspection
*/ */
public function getProperty(string $property) public function getProperty(string $property): mixed
{ {
Console::outDebug(sprintf('getting property %s', $property)); Console::outDebug(sprintf('getting property %s', $property));
Console::outDebug($property);
$current_selection = $this->getConfiguration(); $current_selection = $this->getConfiguration();
foreach(explode('.', strtolower($property)) as $property) foreach(explode('.', strtolower($property)) as $property_value)
{ {
$value_found = false; $value_found = false;
foreach($current_selection as $key => $value) foreach($current_selection as $key => $value)
{ {
if($key == $property) if($key === $property_value)
{ {
$current_selection = $value; $current_selection = $value;
$value_found = true; $value_found = true;
@ -130,7 +133,9 @@
} }
if(!$value_found) if(!$value_found)
{
return null; return null;
}
} }
return $current_selection; return $current_selection;
@ -149,15 +154,18 @@
Console::outDebug(sprintf('updating property %s', $property)); Console::outDebug(sprintf('updating property %s', $property));
$keys = explode('.', $property); $keys = explode('.', $property);
$current = &$this->Configuration; $current = &$this->configuration;
foreach ($keys as $k) foreach ($keys as $k)
{ {
if (!array_key_exists($k, $current)) if (!array_key_exists($k, $current))
{ {
return false; return false;
} }
$current = &$current[$k]; $current = &$current[$k];
} }
$current = Functions::stringTypeCast($value); $current = Functions::stringTypeCast($value);
$this->save(); $this->save();
@ -169,7 +177,7 @@
*/ */
private function getConfiguration(): mixed private function getConfiguration(): mixed
{ {
if($this->Configuration == null) if($this->configuration === null)
{ {
try try
{ {
@ -177,11 +185,12 @@
} }
catch(Exception $e) catch(Exception $e)
{ {
$this->Configuration = []; unset($e);
$this->configuration = [];
} }
} }
return $this->Configuration; return $this->configuration;
} }
} }

View file

@ -1,24 +1,24 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
@ -28,7 +28,6 @@
use ncc\Enums\Scopes; use ncc\Enums\Scopes;
use ncc\Enums\Versions; use ncc\Enums\Versions;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\RuntimeException; use ncc\Exceptions\RuntimeException;
use ncc\Objects\Vault; use ncc\Objects\Vault;
@ -43,22 +42,20 @@
/** /**
* @var string * @var string
*/ */
private $CredentialsPath; private $store_path;
/** /**
* @var Vault * @var Vault
*/ */
private $Vault; private $vault;
/** /**
* Public Constructor * Public Constructor
*/ */
public function __construct() public function __construct()
{ {
/** @noinspection PhpUnhandledExceptionInspection */ $this->store_path = PathFinder::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'credentials.store';
$this->CredentialsPath = PathFinder::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'credentials.store';
$this->Vault = null;
try try
{ {
@ -69,8 +66,10 @@
unset($e); unset($e);
} }
if($this->Vault == null) if($this->vault === null)
$this->Vault = new Vault(); {
$this->vault = new Vault();
}
} }
/** /**
@ -82,20 +81,24 @@
*/ */
public function constructStore(): void public function constructStore(): void
{ {
Console::outDebug(sprintf('constructing credentials store at %s', $this->CredentialsPath)); Console::outDebug(sprintf('constructing credentials store at %s', $this->store_path));
// Do not continue the function if the file already exists, if the file is damaged a separate function // Do not continue the function if the file already exists, if the file is damaged a separate function
// is to be executed to fix the damaged file. // is to be executed to fix the damaged file.
if(file_exists($this->CredentialsPath)) if(file_exists($this->store_path))
{
return; return;
}
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Cannot construct credentials store without system permissions'); throw new AccessDeniedException('Cannot construct credentials store without system permissions');
}
$VaultObject = new Vault(); $VaultObject = new Vault();
$VaultObject->Version = Versions::CREDENTIALS_STORE_VERSION; $VaultObject->Version = Versions::CREDENTIALS_STORE_VERSION;
IO::fwrite($this->CredentialsPath, ZiProto::encode($VaultObject->toArray()), 0744); IO::fwrite($this->store_path, ZiProto::encode($VaultObject->toArray()), 0744);
} }
/** /**
@ -105,28 +108,31 @@
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws IOException * @throws IOException
* @throws RuntimeException * @throws RuntimeException
* @throws FileNotFoundException
*/ */
private function loadVault(): void private function loadVault(): void
{ {
Console::outDebug(sprintf('loading credentials store from %s', $this->CredentialsPath)); Console::outDebug(sprintf('loading credentials store from %s', $this->store_path));
if($this->Vault !== null) if($this->vault !== null)
return;
if(!file_exists($this->CredentialsPath))
{ {
$this->Vault = new Vault();
return; return;
} }
$VaultArray = ZiProto::decode(IO::fread($this->CredentialsPath)); if(!file_exists($this->store_path))
{
$this->vault = new Vault();
return;
}
$VaultArray = ZiProto::decode(IO::fread($this->store_path));
$VaultObject = Vault::fromArray($VaultArray); $VaultObject = Vault::fromArray($VaultArray);
if($VaultObject->Version !== Versions::CREDENTIALS_STORE_VERSION) if($VaultObject->Version !== Versions::CREDENTIALS_STORE_VERSION)
{
throw new RuntimeException('Credentials store version mismatch'); throw new RuntimeException('Credentials store version mismatch');
}
$this->Vault = $VaultObject; $this->vault = $VaultObject;
} }
/** /**
@ -135,26 +141,17 @@
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws IOException * @throws IOException
* @noinspection PhpUnused
*/ */
public function saveVault(): void public function saveVault(): void
{ {
Console::outDebug(sprintf('saving credentials store to %s', $this->CredentialsPath)); Console::outDebug(sprintf('saving credentials store to %s', $this->store_path));
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Cannot save credentials store without system permissions'); throw new AccessDeniedException('Cannot save credentials store without system permissions');
}
IO::fwrite($this->CredentialsPath, ZiProto::encode($this->Vault->toArray()), 0744); IO::fwrite($this->store_path, ZiProto::encode($this->vault->toArray()), 0744);
}
/**
* @return string
* @noinspection PhpUnused
*/
public function getCredentialsPath(): string
{
return $this->CredentialsPath;
} }
/** /**
@ -162,6 +159,6 @@
*/ */
public function getVault(): ?Vault public function getVault(): ?Vault
{ {
return $this->Vault; return $this->vault;
} }
} }

View file

@ -1,24 +1,24 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
@ -36,10 +36,9 @@
use ncc\Classes\PythonExtension\Python3Runner; use ncc\Classes\PythonExtension\Python3Runner;
use ncc\Classes\PythonExtension\PythonRunner; use ncc\Classes\PythonExtension\PythonRunner;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InvalidScopeException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\NoAvailableUnitsException; use ncc\Exceptions\NoAvailableUnitsException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\RunnerExecutionException;
use ncc\Objects\ExecutionPointers; use ncc\Objects\ExecutionPointers;
use ncc\Objects\Package; use ncc\Objects\Package;
@ -53,6 +52,7 @@
use ncc\Utilities\PathFinder; use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver; use ncc\Utilities\Resolver;
use ncc\ZiProto\ZiProto; use ncc\ZiProto\ZiProto;
use RuntimeException;
class ExecutionPointerManager class ExecutionPointerManager
{ {
@ -61,14 +61,14 @@
* *
* @var string * @var string
*/ */
private $RunnerPath; private $runner_path;
/** /**
* An array of temporary unit names to destroy once the object is destroyed * An array of temporary unit names to destroy once the object is destroyed
* *
* @var string[] * @var string[]
*/ */
private $TemporaryUnits; private $temporary_units;
/** /**
* Deletes all the temporary files on destruct * Deletes all the temporary files on destruct
@ -86,12 +86,12 @@
} }
/** /**
* @throws InvalidScopeException * ExecutionPointerManager constructor.
*/ */
public function __construct() public function __construct()
{ {
$this->RunnerPath = PathFinder::getRunnerPath(Scopes::SYSTEM); $this->runner_path = PathFinder::getRunnerPath(Scopes::SYSTEM);
$this->TemporaryUnits = []; $this->temporary_units = [];
} }
/** /**
@ -101,14 +101,16 @@
*/ */
public function cleanTemporaryUnits(): void public function cleanTemporaryUnits(): void
{ {
if(count($this->TemporaryUnits) == 0) if(count($this->temporary_units) === 0)
{
return; return;
}
Console::outVerbose('Cleaning temporary units...'); Console::outVerbose('Cleaning temporary units...');
try try
{ {
foreach($this->TemporaryUnits as $datum) foreach($this->temporary_units as $datum)
{ {
Console::outDebug(sprintf('deleting unit %s=%s.%s', $datum['package'], $datum['version'], $datum['name'])); Console::outDebug(sprintf('deleting unit %s=%s.%s', $datum['package'], $datum['version'], $datum['name']));
$this->removeUnit($datum['package'], $datum['version'], $datum['name']); $this->removeUnit($datum['package'], $datum['version'], $datum['name']);
@ -140,16 +142,17 @@
* @param string $version * @param string $version
* @param string $name * @param string $name
* @return string * @return string
* @throws FileNotFoundException
*/ */
public function getEntryPointPath(string $package, string $version, string $name): string public function getEntryPointPath(string $package, string $version, string $name): string
{ {
$package_id = $this->getPackageId($package, $version); $package_id = $this->getPackageId($package, $version);
$package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; $package_bin_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id;
$entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $name) . '.entrypoint'; $entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $name) . '.entrypoint';
if(!file_exists($entry_point_path)) if(!file_exists($entry_point_path))
throw new FileNotFoundException('Cannot find entry point for ' . $package . '=' . $version . '.' . $name); {
throw new RuntimeException('Cannot find entry point for ' . $package . '=' . $version . '.' . $name);
}
return $entry_point_path; return $entry_point_path;
} }
@ -163,22 +166,23 @@
* @param bool $temporary * @param bool $temporary
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws RunnerExecutionException * @throws RunnerExecutionException
* @noinspection PhpUnused * @throws PathNotFoundException
*/ */
public function addUnit(string $package, string $version, ExecutionUnit $unit, bool $temporary=false): void public function addUnit(string $package, string $version, ExecutionUnit $unit, bool $temporary=false): void
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
throw new AccessDeniedException('Cannot add new ExecutionUnit \'' . $unit->ExecutionPolicy->Name .'\' for ' . $package . ', insufficient permissions'); {
throw new AccessDeniedException('Cannot add new ExecutionUnit \'' . $unit->execution_policy->Name .'\' for ' . $package . ', insufficient permissions');
}
Console::outVerbose(sprintf('Adding new ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package)); Console::outVerbose(sprintf('Adding new ExecutionUnit \'%s\' for %s', $unit->execution_policy->Name, $package));
$package_id = $this->getPackageId($package, $version); $package_id = $this->getPackageId($package, $version);
$package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_config_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id . '.inx';
$package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; $package_bin_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id;
$entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name) . '.entrypoint'; $entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->execution_policy->Name) . '.entrypoint';
Console::outDebug(sprintf('package_id=%s', $package_id)); Console::outDebug(sprintf('package_id=%s', $package_id));
Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); Console::outDebug(sprintf('package_config_path=%s', $package_config_path));
@ -197,8 +201,8 @@
$execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path)));
} }
$bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name); $bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->execution_policy->Name);
$bin_file .= match ($unit->ExecutionPolicy->Runner) $bin_file .= match ($unit->execution_policy->Runner)
{ {
Runners::BASH => BashRunner::getFileExtension(), Runners::BASH => BashRunner::getFileExtension(),
Runners::PHP => PhpRunner::getFileExtension(), Runners::PHP => PhpRunner::getFileExtension(),
@ -206,20 +210,26 @@
Runners::PYTHON => PythonRunner::getFileExtension(), Runners::PYTHON => PythonRunner::getFileExtension(),
Runners::PYTHON_2 => Python2Runner::getFileExtension(), Runners::PYTHON_2 => Python2Runner::getFileExtension(),
Runners::PYTHON_3 => Python3Runner::getFileExtension(), Runners::PYTHON_3 => Python3Runner::getFileExtension(),
Runners::lua => LuaRunner::getFileExtension(), Runners::LUA => LuaRunner::getFileExtension(),
default => throw new RunnerExecutionException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), default => throw new RunnerExecutionException('The runner \'' . $unit->execution_policy->Runner . '\' is not supported'),
}; };
Console::outDebug(sprintf('bin_file=%s', $bin_file)); Console::outDebug(sprintf('bin_file=%s', $bin_file));
if($filesystem->exists($bin_file) && $temporary) if($temporary && $filesystem->exists($bin_file))
{
return; return;
}
if(!$filesystem->exists($package_bin_path)) if(!$filesystem->exists($package_bin_path))
{
$filesystem->mkdir($package_bin_path); $filesystem->mkdir($package_bin_path);
}
if($filesystem->exists($bin_file)) if($filesystem->exists($bin_file))
{
$filesystem->remove($bin_file); $filesystem->remove($bin_file);
}
IO::fwrite($bin_file, $unit->Data); IO::fwrite($bin_file, $unit->Data);
$execution_pointers->addUnit($unit, $bin_file); $execution_pointers->addUnit($unit, $bin_file);
@ -227,21 +237,24 @@
$entry_point = sprintf("#!%s\nncc exec --package=\"%s\" --exec-version=\"%s\" --exec-unit=\"%s\" --exec-args \"$@\"", $entry_point = sprintf("#!%s\nncc exec --package=\"%s\" --exec-version=\"%s\" --exec-unit=\"%s\" --exec-args \"$@\"",
'/bin/bash', '/bin/bash',
$package, $version, $unit->ExecutionPolicy->Name $package, $version, $unit->execution_policy->Name
); );
if(file_exists($entry_point_path)) if(file_exists($entry_point_path))
{
$filesystem->remove($entry_point_path); $filesystem->remove($entry_point_path);
}
IO::fwrite($entry_point_path, $entry_point); IO::fwrite($entry_point_path, $entry_point);
chmod($entry_point_path, 0755); chmod($entry_point_path, 0755);
if($temporary) if($temporary)
{ {
Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package)); Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->execution_policy->Name, $package));
$this->TemporaryUnits[] = [ $this->temporary_units[] = [
'package' => $package, 'package' => $package,
'version' => $version, 'version' => $version,
'unit' => $unit->ExecutionPolicy->Name 'unit' => $unit->execution_policy->Name
]; ];
} }
} }
@ -254,35 +267,44 @@
* @param string $name * @param string $name
* @return bool * @return bool
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
*/ */
public function removeUnit(string $package, string $version, string $name): bool public function removeUnit(string $package, string $version, string $name): bool
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Cannot remove ExecutionUnit \'' . $name .'\' for ' . $package . ', insufficient permissions'); throw new AccessDeniedException('Cannot remove ExecutionUnit \'' . $name .'\' for ' . $package . ', insufficient permissions');
}
Console::outVerbose(sprintf('Removing ExecutionUnit \'%s\' for %s', $name, $package)); Console::outVerbose(sprintf('Removing ExecutionUnit \'%s\' for %s', $name, $package));
$package_id = $this->getPackageId($package, $version); $package_id = $this->getPackageId($package, $version);
$package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_config_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id . '.inx';
$package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; $package_bin_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id;
Console::outDebug(sprintf('package_id=%s', $package_id)); Console::outDebug(sprintf('package_id=%s', $package_id));
Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); Console::outDebug(sprintf('package_config_path=%s', $package_config_path));
Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path));
$filesystem = new Filesystem(); $filesystem = new Filesystem();
if(!$filesystem->exists($package_config_path)) if(!$filesystem->exists($package_config_path))
{
return false; return false;
}
$execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path)));
$unit = $execution_pointers->getUnit($name); $unit = $execution_pointers->getUnit($name);
if($unit == null)
if($unit === null)
{
return false; return false;
}
$results = $execution_pointers->deleteUnit($name); $results = $execution_pointers->deleteUnit($name);
// Delete everything if there are no execution pointers configured // Delete everything if there are no execution pointers configured
if(count($execution_pointers->getPointers()) == 0) if(count($execution_pointers->getPointers()) === 0)
{ {
$filesystem->remove($package_config_path); $filesystem->remove($package_config_path);
$filesystem->remove($package_bin_path); $filesystem->remove($package_bin_path);
@ -291,8 +313,10 @@
} }
// Delete the single execution pointer file // Delete the single execution pointer file
if($filesystem->exists($unit->FilePointer)) if($filesystem->exists($unit->file_pointer))
$filesystem->remove($unit->FilePointer); {
$filesystem->remove($unit->file_pointer);
}
return $results; return $results;
} }
@ -304,16 +328,14 @@
* @param string $version * @param string $version
* @return array * @return array
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @noinspection PhpUnused
*/ */
public function getUnits(string $package, string $version): array public function getUnits(string $package, string $version): array
{ {
Console::outVerbose(sprintf('getting execution units for %s', $package)); Console::outVerbose(sprintf('getting execution units for %s', $package));
$package_id = $this->getPackageId($package, $version); $package_id = $this->getPackageId($package, $version);
$package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_config_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id . '.inx';
Console::outDebug(sprintf('package_id=%s', $package_id)); Console::outDebug(sprintf('package_id=%s', $package_id));
Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); Console::outDebug(sprintf('package_config_path=%s', $package_config_path));
@ -328,8 +350,8 @@
$results = []; $results = [];
foreach($execution_pointers->getPointers() as $pointer) foreach($execution_pointers->getPointers() as $pointer)
{ {
Console::outDebug(sprintf('unit %s', $pointer->ExecutionPolicy->Name)); Console::outDebug(sprintf('unit %s', $pointer->execution_policy->Name));
$results[] = $pointer->ExecutionPolicy->Name; $results[] = $pointer->execution_policy->Name;
} }
return $results; return $results;
@ -344,7 +366,6 @@
* @param array $args * @param array $args
* @return int * @return int
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws NoAvailableUnitsException * @throws NoAvailableUnitsException
* @throws RunnerExecutionException * @throws RunnerExecutionException
@ -354,45 +375,49 @@
Console::outVerbose(sprintf('executing unit %s for %s', $name, $package)); Console::outVerbose(sprintf('executing unit %s for %s', $name, $package));
$package_id = $this->getPackageId($package, $version); $package_id = $this->getPackageId($package, $version);
$package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_config_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id . '.inx';
if(!file_exists($package_config_path)) if(!file_exists($package_config_path))
{
throw new NoAvailableUnitsException('There is no available units for \'' . $package . '=' .$version .'\''); throw new NoAvailableUnitsException('There is no available units for \'' . $package . '=' .$version .'\'');
}
$execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path)));
$unit = $execution_pointers->getUnit($name); $unit = $execution_pointers->getUnit($name);
if($unit == null) if($unit === null)
{
throw new RunnerExecutionException('The execution unit \'' . $name . '\' was not found for \'' . $package . '=' .$version .'\''); throw new RunnerExecutionException('The execution unit \'' . $name . '\' was not found for \'' . $package . '=' .$version .'\'');
}
Console::outDebug(sprintf('unit=%s', $unit->ExecutionPolicy->Name)); Console::outDebug(sprintf('unit=%s', $unit->execution_policy->Name));
Console::outDebug(sprintf('runner=%s', $unit->ExecutionPolicy->Runner)); Console::outDebug(sprintf('runner=%s', $unit->execution_policy->Runner));
Console::outDebug(sprintf('file=%s', $unit->FilePointer)); Console::outDebug(sprintf('file=%s', $unit->file_pointer));
Console::outDebug(sprintf('pass_thru_args=%s', json_encode($args, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE))); Console::outDebug(sprintf('pass_thru_args=%s', implode(' ', $args)));
// Handle the arguments // Handle the arguments
if($unit->ExecutionPolicy->Execute->Options !== null && count($unit->ExecutionPolicy->Execute->Options) > 0) if($unit->execution_policy->Execute->Options !== null && count($unit->execution_policy->Execute->Options) > 0)
{ {
$args = array_merge($args, $unit->ExecutionPolicy->Execute->Options); $args = array_merge($args, $unit->execution_policy->Execute->Options);
foreach($unit->ExecutionPolicy->Execute->Options as $option) foreach($unit->execution_policy->Execute->Options as $option)
{ {
$args[] = ConstantCompiler::compileRuntimeConstants($option); $args[] = ConstantCompiler::compileRuntimeConstants($option);
} }
} }
$process = new Process(array_merge( $process = new Process(array_merge(
[PathFinder::findRunner(strtolower($unit->ExecutionPolicy->Runner)), $unit->FilePointer], $args) [PathFinder::findRunner(strtolower($unit->execution_policy->Runner)), $unit->file_pointer], $args)
); );
if($unit->ExecutionPolicy->Execute->WorkingDirectory !== null) if($unit->execution_policy->Execute->WorkingDirectory !== null)
{ {
$process->setWorkingDirectory(ConstantCompiler::compileRuntimeConstants($unit->ExecutionPolicy->Execute->WorkingDirectory)); $process->setWorkingDirectory(ConstantCompiler::compileRuntimeConstants($unit->execution_policy->Execute->WorkingDirectory));
} }
if($unit->ExecutionPolicy->Execute->Timeout !== null) if($unit->execution_policy->Execute->Timeout !== null)
{ {
$process->setTimeout((float)$unit->ExecutionPolicy->Execute->Timeout); $process->setTimeout((float)$unit->execution_policy->Execute->Timeout);
} }
else else
{ {
@ -402,12 +427,12 @@
try try
{ {
if($unit->ExecutionPolicy->Execute->Silent) if($unit->execution_policy->Execute->Silent)
{ {
$process->disableOutput(); $process->disableOutput();
$process->setTty(false); $process->setTty(false);
} }
elseif($unit->ExecutionPolicy->Execute->Tty) elseif($unit->execution_policy->Execute->Tty)
{ {
$process->enableOutput(); $process->enableOutput();
$process->setTty(true); $process->setTty(true);
@ -419,6 +444,7 @@
} }
catch(Exception $e) catch(Exception $e)
{ {
unset($e);
$process->enableOutput(); $process->enableOutput();
Console::outWarning('The process is configured to use a TTY, but the current environment does not support it'); Console::outWarning('The process is configured to use a TTY, but the current environment does not support it');
} }
@ -433,16 +459,18 @@
Console::outDebug(sprintf('working_directory=%s', $process->getWorkingDirectory())); Console::outDebug(sprintf('working_directory=%s', $process->getWorkingDirectory()));
Console::outDebug(sprintf('timeout=%s', ($process->getTimeout() ?? 0))); Console::outDebug(sprintf('timeout=%s', (int)$process->getTimeout()));
Console::outDebug(sprintf('silent=%s', ($unit->ExecutionPolicy->Execute->Silent ? 'true' : 'false'))); Console::outDebug(sprintf('silent=%s', ($unit->execution_policy->Execute->Silent ? 'true' : 'false')));
Console::outDebug(sprintf('tty=%s', ($unit->ExecutionPolicy->Execute->Tty ? 'true' : 'false'))); Console::outDebug(sprintf('tty=%s', ($unit->execution_policy->Execute->Tty ? 'true' : 'false')));
Console::outDebug(sprintf('options=%s', implode(' ', $args))); Console::outDebug(sprintf('options=%s', implode(' ', $args)));
Console::outDebug(sprintf('cmd=%s', $process->getCommandLine())); Console::outDebug(sprintf('cmd=%s', $process->getCommandLine()));
try try
{ {
if($unit->ExecutionPolicy->Message !== null) if($unit->execution_policy->Message !== null)
Console::out($unit->ExecutionPolicy->Message); {
Console::out($unit->execution_policy->Message);
}
$process->run(function ($type, $buffer) $process->run(function ($type, $buffer)
{ {
@ -453,44 +481,37 @@
} }
catch(Exception $e) catch(Exception $e)
{ {
if($unit->ExecutionPolicy->ExitHandlers !== null && $unit->ExecutionPolicy->ExitHandlers->Error !== null) if($unit->execution_policy->ExitHandlers !== null && $unit->execution_policy->ExitHandlers->Error !== null)
{ {
$this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Error); $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Error);
} }
Console::outException(sprintf('An error occurred while executing the unit \'%s\' for \'%s\' (exit code %s)', $unit->ExecutionPolicy->Name, $package, $process->getExitCode()), $e); Console::outException(sprintf('An error occurred while executing the unit \'%s\' for \'%s\' (exit code %s)', $unit->execution_policy->Name, $package, $process->getExitCode()), $e);
} }
finally finally
{ {
Console::outDebug(sprintf('exit_code=%s', $process->getExitCode())); Console::outDebug(sprintf('exit_code=%s', $process->getExitCode()));
} }
if($unit->ExecutionPolicy->ExitHandlers !== null) if($unit->execution_policy->ExitHandlers !== null)
{ {
if($process->isSuccessful() && $unit->ExecutionPolicy->ExitHandlers->Success !== null) if($unit->execution_policy->ExitHandlers->Success !== null && $process->isSuccessful())
{ {
$this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Success); $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Success);
} }
elseif($process->isSuccessful() && $unit->ExecutionPolicy->ExitHandlers->Error !== null) elseif($unit->execution_policy->ExitHandlers->Error !== null && $process->isSuccessful())
{ {
$this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Error); $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Error);
} }
else else
{ {
$this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Success, $process); $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Success, $process);
$this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Warning, $process); $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Warning, $process);
$this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Error, $process); $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Error, $process);
} }
} }
$exit_code = $process->getExitCode(); return $process->getExitCode() ?? 0;
if($exit_code == null)
{
return 0;
}
return $exit_code;
} }
/** /**
@ -500,31 +521,42 @@
* @param string $unit_name * @param string $unit_name
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws NoAvailableUnitsException * @throws NoAvailableUnitsException
* @throws PathNotFoundException
* @throws RunnerExecutionException * @throws RunnerExecutionException
*/ */
public function temporaryExecute(Package $package, string $unit_name): void public function temporaryExecute(Package $package, string $unit_name): void
{ {
// First get the execution unit from the package. // First, get the execution unit from the package.
$unit = $package->getExecutionUnit($unit_name); $unit = $package->getExecutionUnit($unit_name);
if($unit === null)
{
throw new NoAvailableUnitsException(sprintf('No execution unit named \'%s\' is available for package \'%s\'', $unit_name, $package->Assembly->Package));
}
// Get the required units // Get the required units
$required_units = []; $required_units = [];
if($unit->ExecutionPolicy->ExitHandlers !== null) if($unit->execution_policy->ExitHandlers !== null)
{ {
$required_unit = $unit->ExecutionPolicy?->ExitHandlers?->Success?->Run; $required_unit = $unit->execution_policy?->ExitHandlers?->Success?->Run;
if($required_unit !== null) if($required_unit !== null)
{
$required_units[] = $required_unit; $required_units[] = $required_unit;
}
$required_unit = $unit->ExecutionPolicy?->ExitHandlers?->Warning?->Run; $required_unit = $unit->execution_policy?->ExitHandlers?->Warning?->Run;
if($required_unit !== null) if($required_unit !== null)
{
$required_units[] = $required_unit; $required_units[] = $required_unit;
}
$required_unit = $unit->ExecutionPolicy?->ExitHandlers?->Error?->Run; $required_unit = $unit->execution_policy?->ExitHandlers?->Error?->Run;
if($required_unit !== null) if($required_unit !== null)
{
$required_units = $required_unit; $required_units = $required_unit;
}
} }
// Install the units temporarily // Install the units temporarily
@ -546,35 +578,38 @@
* *
* @param string $package * @param string $package
* @param string $version * @param string $version
* @param ExitHandle $exitHandle * @param ExitHandle $exit_handler
* @param Process|null $process * @param Process|null $process
* @return bool * @return bool
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws NoAvailableUnitsException * @throws NoAvailableUnitsException
* @throws RunnerExecutionException * @throws RunnerExecutionException
*/ */
public function handleExit(string $package, string $version, ExitHandle $exitHandle, ?Process $process=null): bool public function handleExit(string $package, string $version, ExitHandle $exit_handler, ?Process $process=null): bool
{ {
if($exitHandle->Message !== null) if($exit_handler->Message !== null)
Console::out($exitHandle->Message);
if($process !== null && !$exitHandle->EndProcess)
{ {
if($exitHandle->ExitCode !== $process->getExitCode()) Console::out($exit_handler->Message);
return false;
} }
elseif($exitHandle->EndProcess)
if($process !== null && !$exit_handler->EndProcess)
{
if($exit_handler->ExitCode !== $process->getExitCode())
{
return false;
}
}
elseif($exit_handler->EndProcess)
{ {
Console::outDebug(sprintf('exit_code=%s', $process->getExitCode())); Console::outDebug(sprintf('exit_code=%s', $process->getExitCode()));
exit($exitHandle->ExitCode); exit($exit_handler->ExitCode);
} }
if($exitHandle->Run !== null) if($exit_handler->Run !== null)
{ {
Console::outVerbose('Running unit \'' . $exitHandle->Run . '\''); Console::outVerbose('Running unit \'' . $exit_handler->Run . '\'');
$this->executeUnit($package, $version, $exitHandle->Run); $this->executeUnit($package, $version, $exit_handler->Run);
} }
return true; return true;

View file

@ -39,7 +39,6 @@
use ncc\Classes\PhpExtension\PhpInstaller; use ncc\Classes\PhpExtension\PhpInstaller;
use ncc\CLI\Main; use ncc\CLI\Main;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InstallationException; use ncc\Exceptions\InstallationException;
use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidPackageNameException;
use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\InvalidScopeException;
@ -51,6 +50,7 @@
use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageLockException;
use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\PackageNotFoundException;
use ncc\Exceptions\PackageParsingException; use ncc\Exceptions\PackageParsingException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\RunnerExecutionException;
use ncc\Exceptions\SymlinkException; use ncc\Exceptions\SymlinkException;
use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedCompilerExtensionException;
@ -82,22 +82,21 @@
/** /**
* @var string * @var string
*/ */
private $PackagesPath; private $packages_path;
/** /**
* @var PackageLockManager|null * @var PackageLockManager|null
*/ */
private $PackageLockManager; private $package_lock_manager;
/** /**
* @throws InvalidScopeException
* @throws PackageLockException * @throws PackageLockException
*/ */
public function __construct() public function __construct()
{ {
$this->PackagesPath = PathFinder::getPackagesPath(Scopes::SYSTEM); $this->packages_path = PathFinder::getPackagesPath(Scopes::SYSTEM);
$this->PackageLockManager = new PackageLockManager(); $this->package_lock_manager = new PackageLockManager();
$this->PackageLockManager->load(); $this->package_lock_manager->load();
} }
/** /**
@ -108,7 +107,6 @@
* @param array $options * @param array $options
* @return string * @return string
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws InstallationException * @throws InstallationException
* @throws InvalidPackageNameException * @throws InvalidPackageNameException
@ -119,6 +117,7 @@
* @throws PackageLockException * @throws PackageLockException
* @throws PackageNotFoundException * @throws PackageNotFoundException
* @throws PackageParsingException * @throws PackageParsingException
* @throws PathNotFoundException
* @throws RunnerExecutionException * @throws RunnerExecutionException
* @throws SymlinkException * @throws SymlinkException
* @throws UnsupportedCompilerExtensionException * @throws UnsupportedCompilerExtensionException
@ -127,10 +126,14 @@
public function install(string $package_path, ?Entry $entry=null, array $options=[]): string public function install(string $package_path, ?Entry $entry=null, array $options=[]): string
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Insufficient permission to install packages'); throw new AccessDeniedException('Insufficient permission to install packages');
}
if(!file_exists($package_path) || !is_file($package_path) || !is_readable($package_path)) if(!file_exists($package_path) || !is_file($package_path) || !is_readable($package_path))
throw new FileNotFoundException('The specified file \'' . $package_path .' \' does not exist or is not readable.'); {
throw new PathNotFoundException($package_path);
}
$package = Package::load($package_path); $package = Package::load($package_path);
@ -141,7 +144,7 @@
} }
$extension = $package->Header->CompilerExtension->Extension; $extension = $package->Header->CompilerExtension->Extension;
$installation_paths = new InstallationPaths($this->PackagesPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '=' . $package->Assembly->Version); $installation_paths = new InstallationPaths($this->packages_path . DIRECTORY_SEPARATOR . $package->Assembly->Package . '=' . $package->Assembly->Version);
$installer = match ($extension) $installer = match ($extension)
{ {
@ -151,13 +154,11 @@
if($this->getPackageVersion($package->Assembly->Package, $package->Assembly->Version) !== null) if($this->getPackageVersion($package->Assembly->Package, $package->Assembly->Version) !== null)
{ {
if(in_array(InstallPackageOptions::REINSTALL, $options)) if(in_array(InstallPackageOptions::REINSTALL, $options, true))
{ {
if($this->getPackageLockManager()->getPackageLock()->packageExists( if($this->getPackageLockManager()?->getPackageLock()?->packageExists($package->Assembly->Package, $package->Assembly->Version))
$package->Assembly->Package, $package->Assembly->Version
))
{ {
$this->getPackageLockManager()->getPackageLock()->removePackageVersion( $this->getPackageLockManager()?->getPackageLock()?->removePackageVersion(
$package->Assembly->Package, $package->Assembly->Version $package->Assembly->Package, $package->Assembly->Version
); );
} }
@ -174,23 +175,20 @@
]); ]);
// Process all the required dependencies before installing the package // Process all the required dependencies before installing the package
if($package->Dependencies !== null && count($package->Dependencies) > 0 && !in_array(InstallPackageOptions::SKIP_DEPENDENCIES, $options)) if($package->Dependencies !== null && count($package->Dependencies) > 0 && !in_array(InstallPackageOptions::SKIP_DEPENDENCIES, $options, true))
{ {
foreach($package->Dependencies as $dependency) foreach($package->Dependencies as $dependency)
{ {
if(in_array(InstallPackageOptions::REINSTALL, $options)) // Uninstall the dependency if the option Reinstall is passed on
if(in_array(InstallPackageOptions::REINSTALL, $options, true) && $this->getPackageLockManager()?->getPackageLock()?->packageExists($dependency->Name, $dependency->Version))
{ {
// Uninstall the dependency if the option Reinstall is passed on if($dependency->Version === null)
if($this->getPackageLockManager()->getPackageLock()->packageExists($dependency->Name, $dependency->Version))
{ {
if($dependency->Version == null) $this->uninstallPackage($dependency->Name);
{ }
$this->uninstallPackage($dependency->Name); else
} {
else $this->uninstallPackageVersion($dependency->Name, $dependency->Version);
{
$this->uninstallPackageVersion($dependency->Name, $dependency->Version);
}
} }
} }
@ -208,21 +206,31 @@
Console::outDebug(sprintf('installer.src_path: %s', $installation_paths->getSourcePath())); Console::outDebug(sprintf('installer.src_path: %s', $installation_paths->getSourcePath()));
foreach($package->Assembly->toArray() as $prop => $value) foreach($package->Assembly->toArray() as $prop => $value)
{
Console::outDebug(sprintf('assembly.%s: %s', $prop, ($value ?? 'n/a'))); Console::outDebug(sprintf('assembly.%s: %s', $prop, ($value ?? 'n/a')));
}
foreach($package->Header->CompilerExtension->toArray() as $prop => $value) foreach($package->Header->CompilerExtension->toArray() as $prop => $value)
{
Console::outDebug(sprintf('header.compiler.%s: %s', $prop, ($value ?? 'n/a'))); Console::outDebug(sprintf('header.compiler.%s: %s', $prop, ($value ?? 'n/a')));
}
} }
Console::out('Installing ' . $package->Assembly->Package); Console::out('Installing ' . $package->Assembly->Package);
// 4 For Directory Creation, preInstall, postInstall & initData methods // Four For Directory Creation, preInstall, postInstall & initData methods
$steps = (4 + count($package->Components) + count ($package->Resources) + count ($package->ExecutionUnits)); $steps = (4 + count($package->Components) + count ($package->Resources) + count ($package->ExecutionUnits));
// Include the Execution units // Include the Execution units
if($package->Installer?->PreInstall !== null) if($package->Installer?->PreInstall !== null)
{
$steps += count($package->Installer->PreInstall); $steps += count($package->Installer->PreInstall);
}
if($package->Installer?->PostInstall!== null) if($package->Installer?->PostInstall!== null)
{
$steps += count($package->Installer->PostInstall); $steps += count($package->Installer->PostInstall);
}
$current_steps = 0; $current_steps = 0;
$filesystem = new Filesystem(); $filesystem = new Filesystem();
@ -233,7 +241,8 @@
$filesystem->mkdir($installation_paths->getBinPath(), 0755); $filesystem->mkdir($installation_paths->getBinPath(), 0755);
$filesystem->mkdir($installation_paths->getDataPath(), 0755); $filesystem->mkdir($installation_paths->getDataPath(), 0755);
$filesystem->mkdir($installation_paths->getSourcePath(), 0755); $filesystem->mkdir($installation_paths->getSourcePath(), 0755);
$current_steps += 1;
++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
catch(Exception $e) catch(Exception $e)
@ -243,10 +252,12 @@
try try
{ {
self::initData($package, $installation_paths);
Console::outDebug(sprintf('saving shadow package to %s', $installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg')); 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'); $package->save($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg');
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
catch(Exception $e) catch(Exception $e)
@ -258,7 +269,7 @@
try try
{ {
$installer->preInstall($installation_paths); $installer->preInstall($installation_paths);
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
catch (Exception $e) catch (Exception $e)
@ -279,7 +290,7 @@
Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage()); Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage());
} }
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
} }
@ -287,17 +298,21 @@
// Process & Install the components // Process & Install the components
foreach($package->Components as $component) foreach($package->Components as $component)
{ {
Console::outDebug(sprintf('processing component %s (%s)', $component->Name, $component->DataType)); Console::outDebug(sprintf('processing component %s (%s)', $component->name, $component->data_types));
try try
{ {
$data = $installer->processComponent($component); $data = $installer->processComponent($component);
if($data !== null) if($data !== null)
{ {
$component_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $component->Name; $component_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $component->name;
$component_dir = dirname($component_path); $component_dir = dirname($component_path);
if(!$filesystem->exists($component_dir)) if(!$filesystem->exists($component_dir))
{
$filesystem->mkdir($component_dir); $filesystem->mkdir($component_dir);
}
IO::fwrite($component_path, $data); IO::fwrite($component_path, $data);
} }
} }
@ -306,7 +321,7 @@
throw new InstallationException('Cannot process one or more components, ' . $e->getMessage(), $e); throw new InstallationException('Cannot process one or more components, ' . $e->getMessage(), $e);
} }
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
@ -322,8 +337,12 @@
{ {
$resource_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $resource->Name; $resource_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $resource->Name;
$resource_dir = dirname($resource_path); $resource_dir = dirname($resource_path);
if(!$filesystem->exists($resource_dir)) if(!$filesystem->exists($resource_dir))
{
$filesystem->mkdir($resource_dir); $filesystem->mkdir($resource_dir);
}
IO::fwrite($resource_path, $data); IO::fwrite($resource_path, $data);
} }
} }
@ -332,7 +351,7 @@
throw new InstallationException('Cannot process one or more resources, ' . $e->getMessage(), $e); throw new InstallationException('Cannot process one or more resources, ' . $e->getMessage(), $e);
} }
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
@ -347,9 +366,9 @@
/** @var Package\ExecutionUnit $executionUnit */ /** @var Package\ExecutionUnit $executionUnit */
foreach($package->ExecutionUnits as $executionUnit) foreach($package->ExecutionUnits as $executionUnit)
{ {
Console::outDebug(sprintf('processing execution unit %s', $executionUnit->ExecutionPolicy->Name)); Console::outDebug(sprintf('processing execution unit %s', $executionUnit->execution_policy->Name));
$execution_pointer_manager->addUnit($package->Assembly->Package, $package->Assembly->Version, $executionUnit); $execution_pointer_manager->addUnit($package->Assembly->Package, $package->Assembly->Version, $executionUnit);
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
@ -364,7 +383,9 @@
if(isset($package->Header->Options['create_symlink']) && $package->Header->Options['create_symlink']) if(isset($package->Header->Options['create_symlink']) && $package->Header->Options['create_symlink'])
{ {
if($package->MainExecutionPolicy === null) if($package->MainExecutionPolicy === null)
{
throw new InstallationException('Cannot create symlink, no main execution policy is defined'); throw new InstallationException('Cannot create symlink, no main execution policy is defined');
}
Console::outDebug(sprintf('creating symlink to %s', $package->Assembly->Package)); Console::outDebug(sprintf('creating symlink to %s', $package->Assembly->Package));
@ -376,8 +397,10 @@
try try
{ {
Console::outDebug('executing post-installation stage'); Console::outDebug('executing post-installation stage');
$installer->postInstall($installation_paths); $installer->postInstall($installation_paths);
$current_steps += 1; ++$current_steps;
Console::inlineProgressBar($current_steps, $steps); Console::inlineProgressBar($current_steps, $steps);
} }
catch (Exception $e) catch (Exception $e)
@ -399,9 +422,11 @@
{ {
Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage()); Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage());
} }
finally
$current_steps += 1; {
Console::inlineProgressBar($current_steps, $steps); ++$current_steps;
Console::inlineProgressBar($current_steps, $steps);
}
} }
} }
else else
@ -425,8 +450,8 @@
} }
} }
$this->getPackageLockManager()->getPackageLock()->addPackage($package, $installation_paths->getInstallationPath()); $this->getPackageLockManager()?->getPackageLock()?->addPackage($package, $installation_paths->getInstallationPath());
$this->getPackageLockManager()->save(); $this->getPackageLockManager()?->save();
RuntimeCache::set(sprintf('installed.%s=%s', $package->Assembly->Package, $package->Assembly->Version), true); RuntimeCache::set(sprintf('installed.%s=%s', $package->Assembly->Package, $package->Assembly->Version), true);
@ -445,43 +470,52 @@
{ {
$input = new RemotePackageInput($source); $input = new RemotePackageInput($source);
if($input->Source == null) if($input->source === null)
throw new PackageFetchException('No source specified');
if($input->Package == null)
throw new PackageFetchException('No package specified');
if($input->Version == null)
$input->Version = Versions::LATEST;
Console::outVerbose('Fetching package ' . $input->Package . ' from ' . $input->Source . ' (' . $input->Version . ')');
$remote_source_type = Resolver::detectRemoteSourceType($input->Source);
if($remote_source_type == RemoteSourceType::BUILTIN)
{ {
Console::outDebug('using builtin source ' . $input->Source); throw new PackageFetchException('No source specified');
switch($input->Source)
{
case 'composer':
try
{
return ComposerSourceBuiltin::fetch($input);
}
catch(Exception $e)
{
throw new PackageFetchException('Cannot fetch package from composer source, ' . $e->getMessage(), $e);
}
default:
throw new NotImplementedException('Builtin source type ' . $input->Source . ' is not implemented');
}
} }
if($remote_source_type == RemoteSourceType::DEFINED) if($input->package === null)
{ {
Console::outDebug('using defined source ' . $input->Source); throw new PackageFetchException('No package specified');
$remote_source_manager = new RemoteSourcesManager(); }
$source = $remote_source_manager->getRemoteSource($input->Source);
if($source == null) if($input->version === null)
throw new InstallationException('Remote source ' . $input->Source . ' is not defined'); {
$input->version = Versions::LATEST;
}
Console::outVerbose('Fetching package ' . $input->package . ' from ' . $input->source . ' (' . $input->version . ')');
$remote_source_type = Resolver::detectRemoteSourceType($input->source);
if($remote_source_type === RemoteSourceType::BUILTIN)
{
Console::outDebug('using builtin source ' . $input->source);
if ($input->source === 'composer')
{
try
{
return ComposerSourceBuiltin::fetch($input);
}
catch (Exception $e)
{
throw new PackageFetchException('Cannot fetch package from composer source, ' . $e->getMessage(), $e);
}
}
throw new NotImplementedException('Builtin source type ' . $input->source . ' is not implemented');
}
if($remote_source_type === RemoteSourceType::DEFINED)
{
Console::outDebug('using defined source ' . $input->source);
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
$source = (new RemoteSourcesManager())->getRemoteSource($input->source);
if($source === null)
{
throw new InstallationException('Remote source ' . $input->source . ' is not defined');
}
$repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry); $repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry);
$exceptions = []; $exceptions = [];
@ -490,7 +524,7 @@
{ {
try try
{ {
Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->ZipballUrl)); Console::outDebug(sprintf('fetching package %s from %s', $input->package, $repositoryQueryResults->Files->ZipballUrl));
$archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->ZipballUrl, $entry); $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->ZipballUrl, $entry);
return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version);
} }
@ -505,7 +539,7 @@
{ {
try try
{ {
Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->TarballUrl)); Console::outDebug(sprintf('fetching package %s from %s', $input->package, $repositoryQueryResults->Files->TarballUrl));
$archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->TarballUrl, $entry); $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->TarballUrl, $entry);
return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version);
} }
@ -520,7 +554,7 @@
{ {
try try
{ {
Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->PackageUrl)); Console::outDebug(sprintf('fetching package %s from %s', $input->package, $repositoryQueryResults->Files->PackageUrl));
return Functions::downloadGitServiceFile($repositoryQueryResults->Files->PackageUrl, $entry); return Functions::downloadGitServiceFile($repositoryQueryResults->Files->PackageUrl, $entry);
} }
catch(Exception $e) catch(Exception $e)
@ -534,7 +568,7 @@
{ {
try try
{ {
Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl)); Console::outDebug(sprintf('fetching package %s from %s', $input->package, $repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl));
$git_repository = GitClient::cloneRepository($repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl); $git_repository = GitClient::cloneRepository($repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl);
foreach(GitClient::getTags($git_repository) as $tag) foreach(GitClient::getTags($git_repository) as $tag)
@ -562,14 +596,16 @@
{ {
foreach($exceptions as $e) foreach($exceptions as $e)
{ {
if($exception == null) if($exception === null)
{ {
$exception = new PackageFetchException($e->getMessage(), $e); $exception = new PackageFetchException($e->getMessage(), $e);
} }
else else
{ {
if($e->getMessage() == $exception->getMessage()) if($e->getMessage() === $exception->getMessage())
{
continue; continue;
}
$exception = new PackageFetchException($e->getMessage(), $exception); $exception = new PackageFetchException($e->getMessage(), $exception);
} }
@ -600,6 +636,7 @@
try try
{ {
Console::outVerbose(sprintf('Installing package from source %s', $source)); Console::outVerbose(sprintf('Installing package from source %s', $source));
$package = $this->fetchFromSource($source, $entry); $package = $this->fetchFromSource($source, $entry);
return $this->install($package, $entry, $options); return $this->install($package, $entry, $options);
} }
@ -617,7 +654,6 @@
* @param array $options * @param array $options
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws InstallationException * @throws InstallationException
* @throws InvalidPackageNameException * @throws InvalidPackageNameException
@ -628,10 +664,12 @@
* @throws PackageLockException * @throws PackageLockException
* @throws PackageNotFoundException * @throws PackageNotFoundException
* @throws PackageParsingException * @throws PackageParsingException
* @throws PathNotFoundException
* @throws RunnerExecutionException * @throws RunnerExecutionException
* @throws SymlinkException * @throws SymlinkException
* @throws UnsupportedCompilerExtensionException * @throws UnsupportedCompilerExtensionException
* @throws VersionNotFoundException * @throws VersionNotFoundException
* @throws PathNotFoundException
*/ */
private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null, array $options=[]): void private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null, array $options=[]): void
{ {
@ -650,9 +688,11 @@
Console::outDebug('dependency has version constraint, checking if package is installed'); Console::outDebug('dependency has version constraint, checking if package is installed');
$dependent_version = $this->getPackageVersion($dependency->Name, $dependency->Version); $dependent_version = $this->getPackageVersion($dependency->Name, $dependency->Version);
if ($dependent_version !== null) if ($dependent_version !== null)
{
$dependency_met = true; $dependency_met = true;
}
} }
elseif ($dependent_package !== null && $dependency->Version == null) elseif ($dependent_package !== null && $dependency->Version === null)
{ {
Console::outDebug(sprintf('dependency %s has no version specified, assuming dependency is met', $dependency->Name)); Console::outDebug(sprintf('dependency %s has no version specified, assuming dependency is met', $dependency->Name));
$dependency_met = true; $dependency_met = true;
@ -668,8 +708,12 @@
case DependencySourceType::LOCAL: case DependencySourceType::LOCAL:
Console::outDebug('installing from local source ' . $dependency->Source); Console::outDebug('installing from local source ' . $dependency->Source);
$basedir = dirname($package_path); $basedir = dirname($package_path);
if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->Source)) if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->Source))
throw new FileNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->Source); {
throw new PathNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->Source);
}
$this->install($basedir . DIRECTORY_SEPARATOR . $dependency->Source, null, $options); $this->install($basedir . DIRECTORY_SEPARATOR . $dependency->Source, null, $options);
RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->Name, $dependency->Version), true); RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->Name, $dependency->Version), true);
break; break;
@ -703,7 +747,7 @@
public function getPackage(string $package): ?PackageEntry public function getPackage(string $package): ?PackageEntry
{ {
Console::outDebug('getting package ' . $package); Console::outDebug('getting package ' . $package);
return $this->getPackageLockManager()->getPackageLock()->getPackage($package); return $this->getPackageLockManager()?->getPackageLock()?->getPackage($package);
} }
/** /**
@ -745,7 +789,7 @@
*/ */
public function getInstalledPackages(): array public function getInstalledPackages(): array
{ {
return $this->getPackageLockManager()->getPackageLock()->getPackages(); return $this->getPackageLockManager()?->getPackageLock()?->getPackages() ?? [];
} }
/** /**
@ -765,18 +809,25 @@
$exploded = explode('=', $package); $exploded = explode('=', $package);
try try
{ {
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
$package = $this->getPackage($exploded[0]); $package = $this->getPackage($exploded[0]);
if($package == null) if($package === null)
{
throw new PackageNotFoundException('Package ' . $exploded[0] . ' not found'); throw new PackageNotFoundException('Package ' . $exploded[0] . ' not found');
}
$version = $package->getVersion($exploded[1]); $version = $package->getVersion($exploded[1]);
if($version == null) if($version === null)
{
throw new VersionNotFoundException('Version ' . $exploded[1] . ' not found for package ' . $exploded[0]); throw new VersionNotFoundException('Version ' . $exploded[1] . ' not found for package ' . $exploded[0]);
}
foreach ($version->Dependencies as $dependency) foreach ($version->Dependencies as $dependency)
{ {
if(!in_array($dependency->PackageName . '=' . $dependency->Version, $tree)) if(!in_array($dependency->PackageName . '=' . $dependency->Version, $tree, true))
{
$packages[] = $dependency->PackageName . '=' . $dependency->Version; $packages[] = $dependency->PackageName . '=' . $dependency->Version;
}
} }
} }
catch(Exception $e) catch(Exception $e)
@ -794,8 +845,10 @@
{ {
foreach ($versions as $version) foreach ($versions as $version)
{ {
if (!in_array($installed_package . '=' . $version, $packages)) if (!in_array($installed_package . '=' . $version, $packages, true))
{
$packages[] = $installed_package . '=' . $version; $packages[] = $installed_package . '=' . $version;
}
} }
} }
} }
@ -806,26 +859,26 @@
} }
// Go through each package // Go through each package
foreach($packages as $package) foreach($packages as $package_iter)
{ {
$package_e = explode('=', $package); $package_e = explode('=', $package_iter);
try try
{ {
$version_entry = $this->getPackageVersion($package_e[0], $package_e[1]); $version_entry = $this->getPackageVersion($package_e[0], $package_e[1]);
if($version_entry == null) if($version_entry === null)
{ {
Console::outWarning('Version ' . $package_e[1] . ' of package ' . $package_e[0] . ' not found'); Console::outWarning('Version ' . $package_e[1] . ' of package ' . $package_e[0] . ' not found');
} }
else else
{ {
$tree[$package] = null; $tree[$package_iter] = null;
if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0) if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0)
{ {
$tree[$package] = []; $tree[$package_iter] = [];
foreach($version_entry->Dependencies as $dependency) foreach($version_entry->Dependencies as $dependency)
{ {
$dependency_name = sprintf('%s=%s', $dependency->PackageName, $dependency->Version); $dependency_name = sprintf('%s=%s', $dependency->PackageName, $dependency->Version);
$tree[$package] = $this->getPackageTree($tree[$package], $dependency_name); $tree[$package_iter] = $this->getPackageTree($tree[$package_iter], $dependency_name);
} }
} }
} }
@ -846,7 +899,6 @@
* @param string $version * @param string $version
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws PackageLockException * @throws PackageLockException
* @throws PackageNotFoundException * @throws PackageNotFoundException
@ -856,18 +908,25 @@
public function uninstallPackageVersion(string $package, string $version): void public function uninstallPackageVersion(string $package, string $version): void
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Insufficient permission to uninstall packages'); throw new AccessDeniedException('Insufficient permission to uninstall packages');
}
$version_entry = $this->getPackageVersion($package, $version); $version_entry = $this->getPackageVersion($package, $version);
if($version_entry == null) if($version_entry === null)
{
throw new PackageNotFoundException(sprintf('The package %s=%s was not found', $package, $version)); throw new PackageNotFoundException(sprintf('The package %s=%s was not found', $package, $version));
}
Console::out(sprintf('Uninstalling %s=%s', $package, $version)); Console::out(sprintf('Uninstalling %s=%s', $package, $version));
Console::outVerbose(sprintf('Removing package %s=%s from PackageLock', $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(); if(!$this->getPackageLockManager()?->getPackageLock()?->removePackageVersion($package, $version))
{
Console::outDebug('warning: removing package from package lock failed');
}
$this->getPackageLockManager()?->save();
Console::outVerbose('Removing package files'); Console::outVerbose('Removing package files');
$scanner = new DirectoryScanner(); $scanner = new DirectoryScanner();
@ -903,8 +962,10 @@
$execution_pointer_manager = new ExecutionPointerManager(); $execution_pointer_manager = new ExecutionPointerManager();
foreach($version_entry->ExecutionUnits as $executionUnit) foreach($version_entry->ExecutionUnits as $executionUnit)
{ {
if(!$execution_pointer_manager->removeUnit($package, $version, $executionUnit->ExecutionPolicy->Name)) if(!$execution_pointer_manager->removeUnit($package, $version, $executionUnit->execution_policy->Name))
Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->ExecutionPolicy->Name)); {
Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->execution_policy->Name));
}
} }
} }
@ -925,16 +986,26 @@
public function uninstallPackage(string $package): void public function uninstallPackage(string $package): void
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Insufficient permission to uninstall packages'); throw new AccessDeniedException('Insufficient permission to uninstall packages');
}
$package_entry = $this->getPackage($package); $package_entry = $this->getPackage($package);
if($package_entry == null) if($package_entry === null)
{
throw new PackageNotFoundException(sprintf('The package %s was not found', $package)); throw new PackageNotFoundException(sprintf('The package %s was not found', $package));
}
foreach($package_entry->getVersions() as $version) foreach($package_entry->getVersions() as $version)
{ {
$version_entry = $package_entry->getVersion($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 try
{ {
$this->uninstallPackageVersion($package, $version_entry->Version); $this->uninstallPackageVersion($package, $version_entry->Version);
@ -992,12 +1063,12 @@
*/ */
private function getPackageLockManager(): ?PackageLockManager private function getPackageLockManager(): ?PackageLockManager
{ {
if($this->PackageLockManager == null) if($this->package_lock_manager === null)
{ {
$this->PackageLockManager = new PackageLockManager(); $this->package_lock_manager = new PackageLockManager();
} }
return $this->PackageLockManager; return $this->package_lock_manager;
} }
} }

View file

@ -1,27 +1,28 @@
<?php <?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Managers; namespace ncc\Managers;
use ncc\Enums\Options\BuildConfigurationValues; use ncc\Enums\Options\BuildConfigurationValues;
@ -30,13 +31,13 @@
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\BuildConfigurationNotFoundException; use ncc\Exceptions\BuildConfigurationNotFoundException;
use ncc\Exceptions\BuildException; use ncc\Exceptions\BuildException;
use ncc\Exceptions\DirectoryNotFoundException;
use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidPackageNameException;
use ncc\Exceptions\InvalidProjectNameException; use ncc\Exceptions\InvalidProjectNameException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\MalformedJsonException;
use ncc\Exceptions\PackagePreparationFailedException; use ncc\Exceptions\PackagePreparationFailedException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\ProjectAlreadyExistsException; use ncc\Exceptions\ProjectAlreadyExistsException;
use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\ProjectConfigurationNotFoundException;
use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedCompilerExtensionException;
@ -44,6 +45,7 @@
use ncc\Objects\ProjectConfiguration\Compiler; use ncc\Objects\ProjectConfiguration\Compiler;
use ncc\ThirdParty\Symfony\Uid\Uuid; use ncc\ThirdParty\Symfony\Uid\Uuid;
use ncc\Utilities\Validate; use ncc\Utilities\Validate;
use RuntimeException;
class ProjectManager class ProjectManager
{ {
@ -52,41 +54,37 @@
* *
* @var string * @var string
*/ */
private $ProjectFilePath; private $project_file_path;
/** /**
* The path that points the project's main directory * The path that points the project's main directory
* *
* @var string * @var string
*/ */
private $ProjectPath; private $project_path;
/** /**
* The loaded project configuration, null if no project file is loaded * The loaded project configuration, null if no project file is loaded
* *
* @var ProjectConfiguration|null * @var ProjectConfiguration|null
*/ */
private $ProjectConfiguration; private $project_configuration;
/** /**
* Public Constructor * Public Constructor
* *
* @param string $path * @param string $path
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws DirectoryNotFoundException
* @throws FileNotFoundException * @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws MalformedJsonException * @throws MalformedJsonException
* @throws PathNotFoundException
* @throws ProjectConfigurationNotFoundException * @throws ProjectConfigurationNotFoundException
*/ */
public function __construct(string $path) public function __construct(string $path)
{ {
$this->ProjectFilePath = null;
$this->ProjectPath = null;
// Auto-resolve the trailing slash // Auto-resolve the trailing slash
/** @noinspection PhpStrFunctionsInspection */ if(!str_ends_with($path, '/'))
if(substr($path, -1) !== '/')
{ {
$path .= DIRECTORY_SEPARATOR; $path .= DIRECTORY_SEPARATOR;
} }
@ -94,14 +92,16 @@
// Detect if the folder exists or not // Detect if the folder exists or not
if(!file_exists($path) || !is_dir($path)) if(!file_exists($path) || !is_dir($path))
{ {
throw new DirectoryNotFoundException('The given directory \'' . $path .'\' does not exist'); throw new PathNotFoundException($path);
} }
$this->ProjectPath = $path; $this->project_path = $path;
$this->ProjectFilePath = $path . 'project.json'; $this->project_file_path = $path . 'project.json';
if(file_exists($this->ProjectFilePath)) if(file_exists($this->project_file_path))
{
$this->load(); $this->load();
}
} }
/** /**
@ -130,71 +130,79 @@
throw new InvalidProjectNameException('The given project name \'' . $name . '\' is not valid'); throw new InvalidProjectNameException('The given project name \'' . $name . '\' is not valid');
} }
if(file_exists($this->ProjectPath . DIRECTORY_SEPARATOR . 'project.json')) if(file_exists($this->project_path . DIRECTORY_SEPARATOR . 'project.json'))
{ {
throw new ProjectAlreadyExistsException('A project has already been initialized in \'' . $this->ProjectPath . DIRECTORY_SEPARATOR . 'project.json' . '\''); throw new ProjectAlreadyExistsException('A project has already been initialized in \'' . $this->project_path . DIRECTORY_SEPARATOR . 'project.json' . '\'');
} }
$this->ProjectConfiguration = new ProjectConfiguration(); $this->project_configuration = new ProjectConfiguration();
// Set the compiler information // Set the compiler information
$this->ProjectConfiguration->Project->Compiler = $compiler; $this->project_configuration->Project->Compiler = $compiler;
// Set the assembly information // Set the assembly information
$this->ProjectConfiguration->Assembly->Name = $name; $this->project_configuration->Assembly->Name = $name;
$this->ProjectConfiguration->Assembly->Package = $package; $this->project_configuration->Assembly->Package = $package;
$this->ProjectConfiguration->Assembly->Version = '1.0.0'; $this->project_configuration->Assembly->Version = '1.0.0';
$this->ProjectConfiguration->Assembly->UUID = Uuid::v1()->toRfc4122(); $this->project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122();
// Set the build information // Set the build information
$this->ProjectConfiguration->Build->SourcePath = $src; $this->project_configuration->Build->SourcePath = $src;
if($this->ProjectConfiguration->Build->SourcePath == null)
$this->ProjectConfiguration->Build->SourcePath = $this->ProjectPath; if($this->project_configuration->Build->SourcePath === null)
$this->ProjectConfiguration->Build->DefaultConfiguration = 'debug'; {
$this->project_configuration->Build->SourcePath = $this->project_path;
}
$this->project_configuration->Build->DefaultConfiguration = 'debug';
// Assembly constants if the program wishes to check for this // Assembly constants if the program wishes to check for this
$this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_NAME'] = '%ASSEMBLY.NAME%'; $this->project_configuration->Build->DefineConstants['ASSEMBLY_NAME'] = '%ASSEMBLY.NAME%';
$this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_PACKAGE'] = '%ASSEMBLY.PACKAGE%'; $this->project_configuration->Build->DefineConstants['ASSEMBLY_PACKAGE'] = '%ASSEMBLY.PACKAGE%';
$this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_VERSION'] = '%ASSEMBLY.VERSION%'; $this->project_configuration->Build->DefineConstants['ASSEMBLY_VERSION'] = '%ASSEMBLY.VERSION%';
$this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_UID'] = '%ASSEMBLY.UID%'; $this->project_configuration->Build->DefineConstants['ASSEMBLY_UID'] = '%ASSEMBLY.UID%';
// Generate configurations // Generate configurations
$DebugConfiguration = new ProjectConfiguration\Build\BuildConfiguration(); $DebugConfiguration = new ProjectConfiguration\Build\BuildConfiguration();
$DebugConfiguration->Name = 'debug'; $DebugConfiguration->Name = 'debug';
$DebugConfiguration->OutputPath = 'build/debug'; $DebugConfiguration->OutputPath = 'build/debug';
$DebugConfiguration->DefineConstants["DEBUG"] = '1'; // Debugging constant if the program wishes to check for this $DebugConfiguration->DefineConstants["DEBUG"] = '1'; // Debugging constant if the program wishes to check for this
$this->ProjectConfiguration->Build->Configurations[] = $DebugConfiguration; $this->project_configuration->Build->Configurations[] = $DebugConfiguration;
$ReleaseConfiguration = new ProjectConfiguration\Build\BuildConfiguration(); $ReleaseConfiguration = new ProjectConfiguration\Build\BuildConfiguration();
$ReleaseConfiguration->Name = 'release'; $ReleaseConfiguration->Name = 'release';
$ReleaseConfiguration->OutputPath = 'build/release'; $ReleaseConfiguration->OutputPath = 'build/release';
$ReleaseConfiguration->DefineConstants["DEBUG"] = '0'; // Debugging constant if the program wishes to check for this $ReleaseConfiguration->DefineConstants["DEBUG"] = '0'; // Debugging constant if the program wishes to check for this
$this->ProjectConfiguration->Build->Configurations[] = $ReleaseConfiguration; $this->project_configuration->Build->Configurations[] = $ReleaseConfiguration;
// Finally create project.json // Finally, create project.json
$this->ProjectConfiguration->toFile($this->ProjectPath . DIRECTORY_SEPARATOR . 'project.json'); $this->project_configuration->toFile($this->project_path . DIRECTORY_SEPARATOR . 'project.json');
// And create the project directory for additional assets/resources // And create the project directory for additional assets/resources
$Folders = [ $Folders = [
$this->ProjectPath . DIRECTORY_SEPARATOR . 'ncc', $this->project_path . DIRECTORY_SEPARATOR . 'ncc',
$this->ProjectPath . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'cache', $this->project_path . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'cache',
$this->ProjectPath . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'config', $this->project_path . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'config',
]; ];
foreach($Folders as $folder) foreach($Folders as $folder)
{ {
if(!file_exists($folder)) if(!file_exists($folder) && !mkdir($folder) && !is_dir($folder))
{ {
mkdir($folder); throw new RuntimeException(sprintf('Directory "%s" was not created', $folder));
} }
} }
// Process options // Process options
foreach($options as $option) foreach($options as $option)
{ {
if ($option == InitializeProjectOptions::CREATE_SOURCE_DIRECTORY) { if (
if (!file_exists($this->ProjectConfiguration->Build->SourcePath)) { $option === InitializeProjectOptions::CREATE_SOURCE_DIRECTORY &&
mkdir($this->ProjectConfiguration->Build->SourcePath); !file_exists($this->project_configuration->Build->SourcePath) &&
} !mkdir($concurrentDirectory = $this->project_configuration->Build->SourcePath) &&
!is_dir($concurrentDirectory)
)
{
throw new RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
} }
} }
} }
@ -206,10 +214,7 @@
*/ */
public function projectLoaded(): bool public function projectLoaded(): bool
{ {
if($this->ProjectConfiguration == null) return $this->project_configuration !== null;
return false;
return true;
} }
/** /**
@ -224,10 +229,12 @@
*/ */
public function load(): void public function load(): void
{ {
if(!file_exists($this->ProjectFilePath) && !is_file($this->ProjectFilePath)) if(!file_exists($this->project_file_path) && !is_file($this->project_file_path))
throw new ProjectConfigurationNotFoundException('The project configuration file \'' . $this->ProjectFilePath . '\' was not found'); {
throw new ProjectConfigurationNotFoundException('The project configuration file \'' . $this->project_file_path . '\' was not found');
}
$this->ProjectConfiguration = ProjectConfiguration::fromFile($this->ProjectFilePath); $this->project_configuration = ProjectConfiguration::fromFile($this->project_file_path);
} }
/** /**
@ -239,16 +246,21 @@
public function save(): void public function save(): void
{ {
if(!$this->projectLoaded()) if(!$this->projectLoaded())
{
return; return;
$this->ProjectConfiguration->toFile($this->ProjectFilePath); }
$this->project_configuration->toFile($this->project_file_path);
} }
/** /**
* Returns the project's file path.
*
* @return string|null * @return string|null
*/ */
public function getProjectFilePath(): ?string public function getProjectFilePath(): ?string
{ {
return $this->ProjectFilePath; return $this->project_file_path;
} }
/** /**
@ -261,17 +273,22 @@
*/ */
public function getProjectConfiguration(): ?ProjectConfiguration public function getProjectConfiguration(): ?ProjectConfiguration
{ {
if($this->ProjectConfiguration == null) if($this->project_configuration === null)
{
$this->load(); $this->load();
return $this->ProjectConfiguration; }
return $this->project_configuration;
} }
/** /**
* Returns the project's path.
*
* @return string|null * @return string|null
*/ */
public function getProjectPath(): ?string public function getProjectPath(): ?string
{ {
return $this->ProjectPath; return $this->project_path;
} }

View file

@ -131,7 +131,9 @@
foreach($this->Sources as $source) foreach($this->Sources as $source)
{ {
if($source->Name === $name) if($source->Name === $name)
{
return $source; return $source;
}
} }
return null; return null;

View file

@ -1,30 +1,30 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
namespace ncc\Objects; namespace ncc\Objects;
use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\PathNotFoundException;
use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\ExecutionPointers\ExecutionPointer;
use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\Package\ExecutionUnit;
use ncc\Utilities\Functions; use ncc\Utilities\Functions;
@ -35,17 +35,17 @@
/** /**
* @var string * @var string
*/ */
private $Package; private $package;
/** /**
* @var string * @var string
*/ */
private $Version; private $version;
/** /**
* @var ExecutionPointer[] * @var ExecutionPointer[]
*/ */
private $Pointers; private $pointers;
/** /**
* @param string|null $package * @param string|null $package
@ -53,9 +53,9 @@
*/ */
public function __construct(?string $package=null, ?string $version=null) public function __construct(?string $package=null, ?string $version=null)
{ {
$this->Package = $package; $this->package = $package;
$this->Version = $version; $this->version = $version;
$this->Pointers = []; $this->pointers = [];
} }
/** /**
@ -65,26 +65,30 @@
* @param string $bin_file * @param string $bin_file
* @param bool $overwrite * @param bool $overwrite
* @return bool * @return bool
* @throws FileNotFoundException * @throws PathNotFoundException
*/ */
public function addUnit(ExecutionUnit $unit, string $bin_file, bool $overwrite=true): bool public function addUnit(ExecutionUnit $unit, string $bin_file, bool $overwrite=true): bool
{ {
if(Validate::exceedsPathLength($bin_file)) if(Validate::exceedsPathLength($bin_file))
{
return false; return false;
}
if(!file_exists($bin_file)) if(!file_exists($bin_file))
throw new FileNotFoundException('The file ' . $unit->Data . ' does not exist, cannot add unit \'' . $unit->ExecutionPolicy->Name . '\''); {
throw new PathNotFoundException($bin_file);
}
if($overwrite) if($overwrite)
{ {
$this->deleteUnit($unit->ExecutionPolicy->Name); $this->deleteUnit($unit->execution_policy->Name);
} }
elseif($this->getUnit($unit->ExecutionPolicy->Name) !== null) elseif($this->getUnit($unit->execution_policy->Name) !== null)
{ {
return false; return false;
} }
$this->Pointers[] = new ExecutionPointer($unit, $bin_file); $this->pointers[] = new ExecutionPointer($unit, $bin_file);
return true; return true;
} }
@ -97,17 +101,22 @@
public function deleteUnit(string $name): bool public function deleteUnit(string $name): bool
{ {
$unit = $this->getUnit($name); $unit = $this->getUnit($name);
if($unit == null)
return false;
$new_pointers = []; if($unit === null)
foreach($this->Pointers as $pointer)
{ {
if($pointer->ExecutionPolicy->Name !== $name) return false;
$new_pointers[] = $pointer;
} }
$this->Pointers = $new_pointers; $new_pointers = [];
foreach($this->pointers as $pointer)
{
if($pointer->execution_policy->Name !== $name)
{
$new_pointers[] = $pointer;
}
}
$this->pointers = $new_pointers;
return true; return true;
} }
@ -120,10 +129,12 @@
public function getUnit(string $name): ?ExecutionPointer public function getUnit(string $name): ?ExecutionPointer
{ {
/** @var ExecutionPointer $pointer */ /** @var ExecutionPointer $pointer */
foreach($this->Pointers as $pointer) foreach($this->pointers as $pointer)
{ {
if($pointer->ExecutionPolicy->Name == $name) if($pointer->execution_policy->Name === $name)
{
return $pointer; return $pointer;
}
} }
return null; return null;
@ -136,7 +147,7 @@
*/ */
public function getPointers(): array public function getPointers(): array
{ {
return $this->Pointers; return $this->pointers;
} }
/** /**
@ -146,7 +157,7 @@
*/ */
public function getVersion(): string public function getVersion(): string
{ {
return $this->Version; return $this->version;
} }
/** /**
@ -156,7 +167,7 @@
*/ */
public function getPackage(): string public function getPackage(): string
{ {
return $this->Package; return $this->package;
} }
/** /**
@ -168,13 +179,13 @@
public function toArray(bool $bytecode=false): array public function toArray(bool $bytecode=false): array
{ {
$pointers = []; $pointers = [];
foreach($this->Pointers as $pointer) foreach($this->pointers as $pointer)
{ {
$pointers[] = $pointer->toArray($bytecode); $pointers[] = $pointer->toArray($bytecode);
} }
return [ return [
($bytecode ? Functions::cbc('package') : 'package') => $this->Package, ($bytecode ? Functions::cbc('package') : 'package') => $this->package,
($bytecode ? Functions::cbc('version') : 'version') => $this->Version, ($bytecode ? Functions::cbc('version') : 'version') => $this->version,
($bytecode ? Functions::cbc('pointers') : 'pointers') => $pointers ($bytecode ? Functions::cbc('pointers') : 'pointers') => $pointers
]; ];
} }
@ -189,18 +200,18 @@
{ {
$object = new self(); $object = new self();
$object->Version = Functions::array_bc($data, 'version'); $object->version = Functions::array_bc($data, 'version');
$object->Package = Functions::array_bc($data, 'package'); $object->package = Functions::array_bc($data, 'package');
$object->Pointers = Functions::array_bc($data, 'pointers'); $object->pointers = Functions::array_bc($data, 'pointers');
if($object->Pointers !== null) if($object->pointers !== null)
{ {
$pointers = []; $pointers = [];
foreach($object->Pointers as $pointer) foreach($object->pointers as $pointer)
{ {
$pointers[] = ExecutionPointer::fromArray($pointer); $pointers[] = ExecutionPointer::fromArray($pointer);
} }
$object->Pointers = $pointers; $object->pointers = $pointers;
} }
return $object; return $object;

View file

@ -33,21 +33,21 @@
/** /**
* @var string * @var string
*/ */
public $ID; public $id;
/** /**
* The execution policy for this execution unit * The execution policy for this execution unit
* *
* @var ExecutionPolicy * @var ExecutionPolicy
*/ */
public $ExecutionPolicy; public $execution_policy;
/** /**
* The file pointer for where the target script should be executed * The file pointer for where the target script should be executed
* *
* @var string * @var string
*/ */
public $FilePointer; public $file_pointer;
/** /**
* Public Constructor with optional ExecutionUnit parameter to construct object from * Public Constructor with optional ExecutionUnit parameter to construct object from
@ -57,12 +57,14 @@
*/ */
public function __construct(?ExecutionUnit $unit=null, ?string $bin_file=null) public function __construct(?ExecutionUnit $unit=null, ?string $bin_file=null)
{ {
if($unit == null) if($unit === null)
{
return; return;
}
$this->ID = $unit->getID(); $this->id = $unit->getId();
$this->ExecutionPolicy = $unit->ExecutionPolicy; $this->execution_policy = $unit->execution_policy;
$this->FilePointer = $bin_file; $this->file_pointer = $bin_file;
} }
/** /**
@ -74,14 +76,14 @@
public function toArray(bool $bytecode=false): array public function toArray(bool $bytecode=false): array
{ {
return [ return [
($bytecode ? Functions::cbc('id') : 'id') => $this->ID, ($bytecode ? Functions::cbc('id') : 'id') => $this->id,
($bytecode ? Functions::cbc('execution_policy') : 'execution_policy') => $this->ExecutionPolicy->toArray($bytecode), ($bytecode ? Functions::cbc('execution_policy') : 'execution_policy') => $this->execution_policy->toArray($bytecode),
($bytecode ? Functions::cbc('file_pointer') : 'file_pointer') => $this->FilePointer, ($bytecode ? Functions::cbc('file_pointer') : 'file_pointer') => $this->file_pointer,
]; ];
} }
/** /**
* Constructs object from an array representation * Constructs an object from an array representation
* *
* @param array $data * @param array $data
* @return ExecutionPointer * @return ExecutionPointer
@ -90,12 +92,14 @@
{ {
$object = new self(); $object = new self();
$object->ID = Functions::array_bc($data, 'id'); $object->id = Functions::array_bc($data, 'id');
$object->ExecutionPolicy = Functions::array_bc($data, 'execution_policy'); $object->execution_policy = Functions::array_bc($data, 'execution_policy');
$object->FilePointer = Functions::array_bc($data, 'file_pointer'); $object->file_pointer = Functions::array_bc($data, 'file_pointer');
if($object->ExecutionPolicy !== null) if($object->execution_policy !== null)
$object->ExecutionPolicy = ExecutionPolicy::fromArray($object->ExecutionPolicy); {
$object->execution_policy = ExecutionPolicy::fromArray($object->execution_policy);
}
return $object; return $object;
} }

View file

@ -1,24 +1,24 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
@ -26,7 +26,6 @@
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\ComponentVersionNotFoundException; use ncc\Exceptions\ComponentVersionNotFoundException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Utilities\IO; use ncc\Utilities\IO;
@ -37,14 +36,14 @@
* *
* @var string * @var string
*/ */
public $Vendor; public $vendor;
/** /**
* The name of the package * The name of the package
* *
* @var string * @var string
*/ */
public $PackageName; public $package_name;
/** /**
* Attempts to resolve the component's build version * Attempts to resolve the component's build version
@ -52,16 +51,17 @@
* @return string * @return string
* @throws ComponentVersionNotFoundException * @throws ComponentVersionNotFoundException
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
*/ */
public function getVersion(): string public function getVersion(): string
{ {
$third_party_path = NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR; $third_party_path = NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR;
$component_path = $third_party_path . $this->Vendor . DIRECTORY_SEPARATOR . $this->PackageName . DIRECTORY_SEPARATOR; $component_path = $third_party_path . $this->vendor . DIRECTORY_SEPARATOR . $this->package_name . DIRECTORY_SEPARATOR;
if(!file_exists($component_path . 'VERSION')) if(!file_exists($component_path . 'VERSION'))
{
throw new ComponentVersionNotFoundException('The file \'' . $component_path . 'VERSION' . '\' does not exist'); throw new ComponentVersionNotFoundException('The file \'' . $component_path . 'VERSION' . '\' does not exist');
}
return IO::fread($component_path . 'VERSION'); return IO::fread($component_path . 'VERSION');
} }
@ -74,27 +74,31 @@
public function toArray(): array public function toArray(): array
{ {
return [ return [
'vendor' => $this->Vendor, 'vendor' => $this->vendor,
'package_name' => $this->PackageName 'package_name' => $this->package_name
]; ];
} }
/** /**
* Constructs object from an array representation * Constructs an object from an array representation
* *
* @param array $data * @param array $data
* @return Component * @return Component
*/ */
public static function fromArray(array $data): Component public static function fromArray(array $data): Component
{ {
$ComponentObject = new Component(); $object = new self();
if(isset($data['vendor'])) if(isset($data['vendor']))
$ComponentObject->Vendor = $data['vendor']; {
$object->vendor = $data['vendor'];
}
if(isset($data['package_name'])) if(isset($data['package_name']))
$ComponentObject->PackageName = $data['package_name']; {
$object->package_name = $data['package_name'];
}
return $ComponentObject; return $object;
} }
} }

View file

@ -209,7 +209,7 @@
{ {
foreach($this->ExecutionUnits as $unit) foreach($this->ExecutionUnits as $unit)
{ {
if($unit->ExecutionPolicy->Name == $name) if($unit->execution_policy->Name == $name)
return $unit; return $unit;
} }

View file

@ -1,24 +1,24 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
/** @noinspection PhpMissingFieldTypeInspection */ /** @noinspection PhpMissingFieldTypeInspection */
@ -33,21 +33,21 @@
* *
* @var string * @var string
*/ */
public $Name; public $name;
/** /**
* Flags associated with the component created by the compiler extension * Flags associated with the component created by the compiler extension
* *
* @var array * @var array
*/ */
public $Flags; public $flags;
/** /**
* The data type of the component * The data type of the component
* *
* @var string * @var string
*/ */
public $DataType; public $data_types;
/** /**
* A sha1 hash checksum of the component, this will be compared against the data to determine * A sha1 hash checksum of the component, this will be compared against the data to determine
@ -55,14 +55,14 @@
* *
* @var string * @var string
*/ */
private $Checksum; private $checksum;
/** /**
* The raw data of the component, this is to be processed by the compiler extension * The raw data of the component, this is to be processed by the compiler extension
* *
* @var mixed * @var mixed
*/ */
public $Data; public $data;
/** /**
* Validates the checksum of the component, returns false if the checksum or data is invalid or if the checksum * Validates the checksum of the component, returns false if the checksum or data is invalid or if the checksum
@ -70,16 +70,22 @@
* *
* @return bool * @return bool
*/ */
public function validateChecksum(): bool public function validate_checksum(): bool
{ {
if($this->Checksum === null) if($this->checksum === null)
{
return true; // Return true if the checksum is empty return true; // Return true if the checksum is empty
}
if($this->Data === null) if($this->data === null)
{
return true; // Return true if the data is null return true; // Return true if the data is null
}
if(hash('sha1', $this->Data, true) !== $this->Checksum) if(hash('sha1', $this->data, true) !== $this->checksum)
{
return false; // Return false if the checksum failed return false; // Return false if the checksum failed
}
return true; return true;
} }
@ -91,11 +97,11 @@
*/ */
public function updateChecksum(): void public function updateChecksum(): void
{ {
$this->Checksum = null; $this->checksum = null;
if(gettype($this->Data) == 'string') if(is_string($this->data))
{ {
$this->Checksum = hash('sha1', $this->Data, true); $this->checksum = hash('sha1', $this->data, true);
} }
} }
@ -108,11 +114,11 @@
public function toArray(bool $bytecode=false): array public function toArray(bool $bytecode=false): array
{ {
return [ return [
($bytecode ? Functions::cbc('name') : 'name') => $this->Name, ($bytecode ? Functions::cbc('name') : 'name') => $this->name,
($bytecode ? Functions::cbc('flags') : 'flags') => $this->Flags, ($bytecode ? Functions::cbc('flags') : 'flags') => $this->flags,
($bytecode ? Functions::cbc('data_type') : 'data_type') => $this->DataType, ($bytecode ? Functions::cbc('data_type') : 'data_type') => $this->data_types,
($bytecode ? Functions::cbc('checksum') : 'checksum') => $this->Checksum, ($bytecode ? Functions::cbc('checksum') : 'checksum') => $this->checksum,
($bytecode ? Functions::cbc('data') : 'data') => $this->Data, ($bytecode ? Functions::cbc('data') : 'data') => $this->data,
]; ];
} }
@ -126,11 +132,11 @@
{ {
$Object = new self(); $Object = new self();
$Object->Name = Functions::array_bc($data, 'name'); $Object->name = Functions::array_bc($data, 'name');
$Object->Flags = Functions::array_bc($data, 'flags'); $Object->flags = Functions::array_bc($data, 'flags');
$Object->DataType = Functions::array_bc($data, 'data_type'); $Object->data_types = Functions::array_bc($data, 'data_type');
$Object->Checksum = Functions::array_bc($data, 'checksum'); $Object->checksum = Functions::array_bc($data, 'checksum');
$Object->Data = Functions::array_bc($data, 'data'); $Object->data = Functions::array_bc($data, 'data');
return $Object; return $Object;
} }

View file

@ -32,14 +32,14 @@
/** /**
* @var string|null * @var string|null
*/ */
private $ID; private $id;
/** /**
* The execution policy for this execution unit * The execution policy for this execution unit
* *
* @var ExecutionPolicy * @var ExecutionPolicy
*/ */
public $ExecutionPolicy; public $execution_policy;
/** /**
* The data of the unit to execute * The data of the unit to execute
@ -57,7 +57,7 @@
public function toArray(bool $bytecode=false): array public function toArray(bool $bytecode=false): array
{ {
return [ return [
($bytecode ? Functions::cbc('execution_policy') : 'execution_policy') => $this->ExecutionPolicy->toArray($bytecode), ($bytecode ? Functions::cbc('execution_policy') : 'execution_policy') => $this->execution_policy->toArray($bytecode),
($bytecode ? Functions::cbc('data') : 'data') => $this->Data, ($bytecode ? Functions::cbc('data') : 'data') => $this->Data,
]; ];
} }
@ -72,11 +72,11 @@
{ {
$object = new self(); $object = new self();
$object->ExecutionPolicy = Functions::array_bc($data, 'execution_policy'); $object->execution_policy = Functions::array_bc($data, 'execution_policy');
$object->Data = Functions::array_bc($data, 'data'); $object->Data = Functions::array_bc($data, 'data');
if($object->ExecutionPolicy !== null) if($object->execution_policy !== null)
$object->ExecutionPolicy = ExecutionPolicy::fromArray($object->ExecutionPolicy); $object->execution_policy = ExecutionPolicy::fromArray($object->execution_policy);
return $object; return $object;
} }
@ -84,11 +84,11 @@
/** /**
* @return string * @return string
*/ */
public function getID(): string public function getId(): string
{ {
if($this->ID == null) if($this->id == null)
$this->ID = hash('sha1', $this->ExecutionPolicy->Name); $this->id = hash('sha1', $this->execution_policy->Name);
return $this->ID; return $this->id;
} }
} }

View file

@ -24,60 +24,59 @@
namespace ncc\Objects; namespace ncc\Objects;
use InvalidArgumentException;
use ncc\Enums\RegexPatterns; use ncc\Enums\RegexPatterns;
class RemotePackageInput class RemotePackageInput
{ {
/** /**
* @var string|null * @var string
*/ */
public $Vendor; public $vendor;
/**
* @var string
*/
public $package;
/** /**
* @var string|null * @var string|null
*/ */
public $Package; public $version;
/** /**
* @var string|null * @var string|null
*/ */
public $Version; public $branch;
/** /**
* @var string|null * @var string
*/ */
public $Branch; public $source;
/**
* @var string|null
*/
public $Source;
/** /**
* Public Constructor & String Parser * Public Constructor & String Parser
* *
* @param string|null $input * @param string|null $input
*/ */
public function __construct(?string $input=null) public function __construct(?string $input = null)
{ {
if($input !== null && preg_match(RegexPatterns::REMOTE_PACKAGE, $input, $matches)) if ($input !== null && preg_match(RegexPatterns::REMOTE_PACKAGE, $input, $matches))
{ {
$this->Vendor = $matches['vendor']; if ($matches['source'] === null || $matches['package'] === null || $matches['vendor'] === null)
$this->Package = $matches['package']; {
$this->Version = $matches['version']; throw new InvalidArgumentException('Package, version, and source are required.');
$this->Branch = $matches['branch']; }
$this->Source = $matches['source'];
if(strlen($this->Vendor) == 0) $this->vendor = $matches['vendor'];
$this->Vendor = null; $this->package = $matches['package'];
if(strlen($this->Package) == 0) $this->source = $matches['source'];
$this->Package = null; $this->version = empty($matches['version']) ? null : $matches['version'];
if(strlen($this->Version) == 0) $this->branch = empty($matches['branch']) ? null : $matches['branch'];
$this->Version = null; }
if(strlen($this->Branch) == 0) else
$this->Branch = null; {
if(strlen($this->Source) == 0) throw new InvalidArgumentException('Input does not match the expected pattern.');
$this->Source = null;
} }
} }
@ -88,19 +87,27 @@
*/ */
public function toString(): string public function toString(): string
{ {
if($this->Vendor == null || $this->Package == null) if($this->vendor === null || $this->package === null)
{ {
return ''; return '';
} }
$results = $this->Vendor . '/' . $this->Package; $results = $this->vendor . '/' . $this->package;
if($this->Version !== null) if($this->version !== null)
$results .= '=' . $this->Version; {
if($this->Branch !== null) $results .= '=' . $this->version;
$results .= ':' . $this->Branch; }
if($this->Source !== null)
$results .= '@' . $this->Source; if($this->branch !== null)
{
$results .= ':' . $this->branch;
}
if($this->source !== null)
{
$results .= '@' . $this->source;
}
return $results; return $results;
} }
@ -114,7 +121,10 @@
public function toStandard(bool $version=true): string public function toStandard(bool $version=true): string
{ {
if($version) if($version)
return str_replace('-', '_', sprintf('com.%s.%s=%s', $this->Vendor, $this->Package, $this->Version)); {
return str_replace('-', '_', sprintf('com.%s.%s', $this->Vendor, $this->Package)); return str_replace('-', '_', sprintf('com.%s.%s=%s', $this->vendor, $this->package, $this->version));
}
return str_replace('-', '_', sprintf('com.%s.%s', $this->vendor, $this->package));
} }
} }

View file

@ -1,28 +1,29 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
namespace ncc\Utilities; namespace ncc\Utilities;
use Exception; use Exception;
use JsonException;
use ncc\Enums\AuthenticationType; use ncc\Enums\AuthenticationType;
use ncc\Enums\DefinedRemoteSourceType; use ncc\Enums\DefinedRemoteSourceType;
use ncc\Enums\HttpRequestType; use ncc\Enums\HttpRequestType;
@ -41,12 +42,11 @@ namespace ncc\Utilities;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\ArchiveException; use ncc\Exceptions\ArchiveException;
use ncc\Exceptions\AuthenticationException; use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\GitlabServiceException; use ncc\Exceptions\GitlabServiceException;
use ncc\Exceptions\HttpException; use ncc\Exceptions\HttpException;
use ncc\Exceptions\InvalidScopeException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\MalformedJsonException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\RunnerExecutionException;
use ncc\Exceptions\UnsupportedArchiveException; use ncc\Exceptions\UnsupportedArchiveException;
use ncc\Managers\ConfigurationManager; use ncc\Managers\ConfigurationManager;
@ -62,7 +62,6 @@ namespace ncc\Utilities;
use ncc\Objects\RepositoryQueryResults; use ncc\Objects\RepositoryQueryResults;
use ncc\Objects\RepositoryQueryResults\Files; use ncc\Objects\RepositoryQueryResults\Files;
use ncc\Objects\Vault\Entry; use ncc\Objects\Vault\Entry;
use ncc\Runtime;
use ncc\ThirdParty\jelix\Version\Parser; use ncc\ThirdParty\jelix\Version\Parser;
use ncc\ThirdParty\jelix\Version\VersionComparator; use ncc\ThirdParty\jelix\Version\VersionComparator;
use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
@ -70,6 +69,7 @@ namespace ncc\Utilities;
use ncc\ThirdParty\Symfony\Process\Process; use ncc\ThirdParty\Symfony\Process\Process;
use RecursiveDirectoryIterator; use RecursiveDirectoryIterator;
use RecursiveIteratorIterator; use RecursiveIteratorIterator;
use RuntimeException;
use Throwable; use Throwable;
/** /**
@ -78,10 +78,19 @@ namespace ncc\Utilities;
*/ */
class Functions class Functions
{ {
/**
* Forces the output to be an array
*/
public const FORCE_ARRAY = 0b0001; public const FORCE_ARRAY = 0b0001;
/**
* Forces the output to be pretty
*/
public const PRETTY = 0b0010; public const PRETTY = 0b0010;
/**
* Escapes unicode characters
*/
public const ESCAPE_UNICODE = 0b0100; public const ESCAPE_UNICODE = 0b0100;
/** /**
@ -92,11 +101,7 @@ namespace ncc\Utilities;
*/ */
public static function cbc(string $input): string public static function cbc(string $input): string
{ {
$cache = RuntimeCache::get("cbc_$input"); return RuntimeCache::get("cbc_$input") ?? RuntimeCache::set("cbc_$input", hash('crc32', $input, true));
if($cache !== null)
return $cache;
return RuntimeCache::set("cbc_$input", hash('crc32', $input, true));
} }
/** /**
@ -106,17 +111,10 @@ namespace ncc\Utilities;
* @param array $data * @param array $data
* @param string $select * @param string $select
* @return mixed|null * @return mixed|null
* @noinspection PhpMissingReturnTypeInspection
*/ */
public static function array_bc(array $data, string $select) public static function array_bc(array $data, string $select): mixed
{ {
if(isset($data[$select])) return $data[$select] ?? $data[self::cbc($select)] ?? null;
return $data[$select];
if(isset($data[self::cbc($select)]))
return $data[self::cbc($select)];
return null;
} }
/** /**
@ -126,16 +124,15 @@ namespace ncc\Utilities;
* @param int $flags * @param int $flags
* @return mixed * @return mixed
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws MalformedJsonException * @throws MalformedJsonException
* @noinspection PhpMissingReturnTypeInspection * @throws PathNotFoundException
*/ */
public static function loadJsonFile(string $path, int $flags=0) public static function loadJsonFile(string $path, int $flags=0): mixed
{ {
if(!file_exists($path)) if(!file_exists($path))
{ {
throw new FileNotFoundException($path); throw new PathNotFoundException($path);
} }
return self::loadJson(IO::fread($path), $flags); return self::loadJson(IO::fread($path), $flags);
@ -148,19 +145,17 @@ namespace ncc\Utilities;
* @param int $flags * @param int $flags
* @return mixed * @return mixed
* @throws MalformedJsonException * @throws MalformedJsonException
* @noinspection PhpMissingReturnTypeInspection
*/ */
public static function loadJson(string $json, int $flags=0) public static function loadJson(string $json, int $flags=0): mixed
{ {
$forceArray = (bool) ($flags & self::FORCE_ARRAY); try
$json_decoded = json_decode($json, $forceArray, 512, JSON_BIGINT_AS_STRING);
if($json_decoded == null && json_last_error() !== JSON_ERROR_NONE)
{ {
throw new MalformedJsonException(json_last_error_msg() . ' (' . json_last_error() . ')'); return json_decode($json, ($flags & self::FORCE_ARRAY), 512, JSON_THROW_ON_ERROR | JSON_BIGINT_AS_STRING);
}
catch(Throwable $e)
{
throw new MalformedJsonException($e->getMessage(), $e);
} }
return $json_decoded;
} }
/** /**
@ -170,39 +165,41 @@ namespace ncc\Utilities;
* @param int $flags * @param int $flags
* @return string * @return string
* @throws MalformedJsonException * @throws MalformedJsonException
* @noinspection PhpMissingParamTypeInspection
* @noinspection PhpUnusedLocalVariableInspection
*/ */
public static function encodeJson($value, int $flags=0): string public static function encodeJson(mixed $value, int $flags=0): string
{ {
$flags = ($flags & self::ESCAPE_UNICODE ? 0 : JSON_UNESCAPED_UNICODE) $flags = ($flags & self::ESCAPE_UNICODE ? 0 : JSON_UNESCAPED_UNICODE)
| JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_SLASHES
| ($flags & self::PRETTY ? JSON_PRETTY_PRINT : 0) | ($flags & self::PRETTY ? JSON_PRETTY_PRINT : 0)
| (defined('JSON_PRESERVE_ZERO_FRACTION') ? JSON_PRESERVE_ZERO_FRACTION : 0); // since PHP 5.6.6 & PECL JSON-C 1.3.7 | (defined('JSON_PRESERVE_ZERO_FRACTION') ? JSON_PRESERVE_ZERO_FRACTION : 0); // since PHP 5.6.6 & PECL JSON-C 1.3.7
$json = json_encode($value, $flags); try
if ($error = json_last_error())
{ {
throw new MalformedJsonException(json_last_error_msg() . ' (' . json_last_error() . ')'); return json_encode($value, JSON_THROW_ON_ERROR | $flags);
}
catch (JsonException $e)
{
throw new MalformedJsonException($e->getMessage(), $e);
} }
return $json;
} }
/** /**
* Writes a json file to disk * Writes a json file to disk
* *
* @param $value * @param mixed $value
* @param string $path * @param string $path
* @param int $flags * @param int $flags
* @return void * @return void
* @throws MalformedJsonException * @throws MalformedJsonException
*/ */
public static function encodeJsonFile($value, string $path, int $flags=0): void public static function encodeJsonFile(mixed $value, string $path, int $flags=0): void
{ {
file_put_contents($path, self::encodeJson($value, $flags)); file_put_contents($path, self::encodeJson($value, $flags));
} }
/** /**
* Returns the current working directory
*
* @param CliHelpSection[] $input * @param CliHelpSection[] $input
* @return int * @return int
*/ */
@ -235,7 +232,6 @@ namespace ncc\Utilities;
* @param bool $basic_ascii * @param bool $basic_ascii
* @return string * @return string
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
*/ */
public static function getBanner(string $version, string $copyright, bool $basic_ascii=false): string public static function getBanner(string $version, string $copyright, bool $basic_ascii=false): string
@ -253,10 +249,7 @@ namespace ncc\Utilities;
$banner_copyright = str_pad($copyright, 30); $banner_copyright = str_pad($copyright, 30);
$banner = str_ireplace('%A', $banner_version, $banner); $banner = str_ireplace('%A', $banner_version, $banner);
/** @noinspection PhpUnnecessaryLocalVariableInspection */ return str_ireplace('%B', $banner_copyright, $banner);
$banner = str_ireplace('%B', $banner_copyright, $banner);
return $banner;
} }
/** /**
@ -264,23 +257,25 @@ namespace ncc\Utilities;
* current working directory, optionally accepts a different basename using the $basename parameter. * current working directory, optionally accepts a different basename using the $basename parameter.
* *
* @param string $path * @param string $path
* @param string|null $basename * @param string|null $base_name
* @return string * @return string
*/ */
public static function removeBasename(string $path, ?string $basename=null): string public static function removeBasename(string $path, ?string $base_name=null): string
{ {
if($basename == null) if($base_name === null)
$basename = getcwd(); {
$base_name = getcwd();
}
// Append the trailing slash if it's not already there // Append the trailing slash if it's not already there
// "/etc/foo" becomes "/etc/foo/" // "/etc/foo" becomes "/etc/foo/"
if(substr($basename, -1) !== DIRECTORY_SEPARATOR) if(substr($base_name, -1) !== DIRECTORY_SEPARATOR)
{ {
$basename .= DIRECTORY_SEPARATOR; $base_name .= DIRECTORY_SEPARATOR;
} }
// If the path is "/etc/foo/text.txt" and the basename is "/etc" then the returned path will be "foo/test.txt" // If the path is "/etc/foo/text.txt" and the basename is "/etc" then the returned path will be "foo/test.txt"
return str_replace($basename, (string)null, $path); return str_replace($base_name, (string)null, $path);
} }
/** /**
@ -300,20 +295,21 @@ namespace ncc\Utilities;
* @param ExecutionPolicy $policy * @param ExecutionPolicy $policy
* @return ExecutionUnit * @return ExecutionUnit
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws PathNotFoundException
* @throws RunnerExecutionException * @throws RunnerExecutionException
*/ */
public static function compileRunner(string $path, ExecutionPolicy $policy): ExecutionUnit public static function compileRunner(string $path, ExecutionPolicy $policy): ExecutionUnit
{ {
return match (strtolower($policy->Runner)) { return match (strtolower($policy->Runner))
{
Runners::BASH => BashRunner::processUnit($path, $policy), Runners::BASH => BashRunner::processUnit($path, $policy),
Runners::PHP => PhpRunner::processUnit($path, $policy), Runners::PHP => PhpRunner::processUnit($path, $policy),
Runners::PERL => PerlRunner::processUnit($path, $policy), Runners::PERL => PerlRunner::processUnit($path, $policy),
Runners::PYTHON => PythonRunner::processUnit($path, $policy), Runners::PYTHON => PythonRunner::processUnit($path, $policy),
Runners::PYTHON_2 => Python2Runner::processUnit($path, $policy), Runners::PYTHON_2 => Python2Runner::processUnit($path, $policy),
Runners::PYTHON_3 => Python3Runner::processUnit($path, $policy), Runners::PYTHON_3 => Python3Runner::processUnit($path, $policy),
Runners::lua => LuaRunner::processUnit($path, $policy), Runners::LUA => LuaRunner::processUnit($path, $policy),
default => throw new RunnerExecutionException('The runner \'' . $policy->Runner . '\' is not supported'), default => throw new RunnerExecutionException('The runner \'' . $policy->Runner . '\' is not supported'),
}; };
} }
@ -354,7 +350,7 @@ namespace ncc\Utilities;
{ {
$size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB');
$factor = floor((strlen($bytes) - 1) / 3); $factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor]; return sprintf("%.{$decimals}f", $bytes / (1024 ** $factor)) . @$size[$factor];
} }
/** /**
@ -362,12 +358,14 @@ namespace ncc\Utilities;
* *
* @return void * @return void
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws InvalidScopeException * @noinspection PhpRedundantOptionalArgumentInspection
*/ */
public static function initializeFiles(): void public static function initializeFiles(): void
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AccessDeniedException('Cannot initialize NCC files, insufficient permissions'); throw new AccessDeniedException('Cannot initialize NCC files, insufficient permissions');
}
Console::outVerbose('Initializing NCC files'); Console::outVerbose('Initializing NCC files');
@ -381,21 +379,18 @@ namespace ncc\Utilities;
if(!$filesystem->exists(PathFinder::getCachePath(Scopes::SYSTEM))) if(!$filesystem->exists(PathFinder::getCachePath(Scopes::SYSTEM)))
{ {
Console::outDebug(sprintf('Initializing %s', PathFinder::getCachePath(Scopes::SYSTEM))); Console::outDebug(sprintf('Initializing %s', PathFinder::getCachePath(Scopes::SYSTEM)));
/** @noinspection PhpRedundantOptionalArgumentInspection */
$filesystem->mkdir(PathFinder::getCachePath(Scopes::SYSTEM), 0777); $filesystem->mkdir(PathFinder::getCachePath(Scopes::SYSTEM), 0777);
} }
if(!$filesystem->exists(PathFinder::getRunnerPath(Scopes::SYSTEM))) if(!$filesystem->exists(PathFinder::getRunnerPath(Scopes::SYSTEM)))
{ {
Console::outDebug(sprintf('Initializing %s', PathFinder::getRunnerPath(Scopes::SYSTEM))); Console::outDebug(sprintf('Initializing %s', PathFinder::getRunnerPath(Scopes::SYSTEM)));
/** @noinspection PhpRedundantOptionalArgumentInspection */
$filesystem->mkdir(PathFinder::getRunnerPath(Scopes::SYSTEM), 0755); $filesystem->mkdir(PathFinder::getRunnerPath(Scopes::SYSTEM), 0755);
} }
if(!$filesystem->exists(PathFinder::getPackagesPath(Scopes::SYSTEM))) if(!$filesystem->exists(PathFinder::getPackagesPath(Scopes::SYSTEM)))
{ {
Console::outDebug(sprintf('Initializing %s', PathFinder::getPackagesPath(Scopes::SYSTEM))); Console::outDebug(sprintf('Initializing %s', PathFinder::getPackagesPath(Scopes::SYSTEM)));
/** @noinspection PhpRedundantOptionalArgumentInspection */
$filesystem->mkdir(PathFinder::getPackagesPath(Scopes::SYSTEM), 0755); $filesystem->mkdir(PathFinder::getPackagesPath(Scopes::SYSTEM), 0755);
} }
@ -430,14 +425,21 @@ namespace ncc\Utilities;
* @param string $path * @param string $path
* @return ComposerJson * @return ComposerJson
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @noinspection PhpUnused * @throws MalformedJsonException
*/ */
public static function loadComposerJson(string $path): ComposerJson public static function loadComposerJson(string $path): ComposerJson
{ {
$json_contents = IO::fread($path); $json_contents = IO::fread($path);
return ComposerJson::fromArray(json_decode($json_contents, true));
try
{
return ComposerJson::fromArray(json_decode($json_contents, true, 512, JSON_THROW_ON_ERROR));
}
catch(JsonException $e)
{
throw new MalformedJsonException('Cannot parse composer.json, ' . $e->getMessage(), $e);
}
} }
/** /**
@ -449,7 +451,10 @@ namespace ncc\Utilities;
public static function cbool($value): bool public static function cbool($value): bool
{ {
if(is_null($value)) if(is_null($value))
{
return false; return false;
}
if(is_string($value)) if(is_string($value))
{ {
switch(strtolower($value)) switch(strtolower($value))
@ -470,15 +475,6 @@ namespace ncc\Utilities;
} }
} }
if(is_int($value))
{
if ($value == 0)
return false;
if ($value == 1)
return true;
return false;
}
return (bool)$value; return (bool)$value;
} }
@ -491,8 +487,7 @@ namespace ncc\Utilities;
*/ */
public static function getConfigurationProperty(string $property) public static function getConfigurationProperty(string $property)
{ {
$config_manager = new ConfigurationManager(); return (new ConfigurationManager())->getProperty($property);
return $config_manager->getProperty($property);
} }
/** /**
@ -504,9 +499,10 @@ namespace ncc\Utilities;
*/ */
public static function parseVersion(string $version): string public static function parseVersion(string $version): string
{ {
/** @noinspection PhpStrFunctionsInspection */ if(str_starts_with(strtolower($version), 'v'))
if(substr($version, 0, 1) === 'v') {
$version = substr($version, 1); $version = substr($version, 1);
}
return Parser::parse($version)->toString(); return Parser::parse($version)->toString();
} }
@ -517,16 +513,25 @@ namespace ncc\Utilities;
* @param int $length * @param int $length
* @return string * @return string
*/ */
public static function randomString(int $length = 32): string public static function randomString(int $length=32): string
{ {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters); $characters_length = strlen($characters);
$randomString = ''; $random_string = '';
for ($i = 0; $i < $length; $i++)
for($i = 0; $i < $length; $i++)
{ {
$randomString .= $characters[rand(0, $charactersLength - 1)]; try
{
$random_string .= $characters[random_int(0, $characters_length - 1)];
}
catch (Exception $e)
{
throw new RuntimeException('Cannot generate random string, ' . $e->getMessage(), $e->getCode(), $e);
}
} }
return $randomString;
return $random_string;
} }
/** /**
@ -535,42 +540,49 @@ namespace ncc\Utilities;
* @param bool $create * @param bool $create
* @param bool $set_as_tmp * @param bool $set_as_tmp
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getTmpDir(bool $create=true, bool $set_as_tmp=true): string public static function getTmpDir(bool $create=true, bool $set_as_tmp=true): string
{ {
$path = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . self::randomString(16); $path = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . self::randomString(16);
if($create) if($create)
{ {
$filesystem = new Filesystem(); $filesystem = new Filesystem();
/** @noinspection PhpRedundantOptionalArgumentInspection */ /** @noinspection PhpRedundantOptionalArgumentInspection */
$filesystem->mkdir($path, 0777); $filesystem->mkdir($path, 0777);
} }
if($set_as_tmp) if($set_as_tmp)
{
RuntimeCache::setFileAsTemporary($path); RuntimeCache::setFileAsTemporary($path);
}
return $path; return $path;
} }
/** /**
* Applies the authentication to the given HTTP request. * Applies the authentication to the given HTTP request.
* *
* @param HttpRequest $httpRequest * @param HttpRequest $http_request
* @param Entry|null $entry * @param Entry|null $entry
* @param bool $expect_json * @param bool $expect_json
* @return HttpRequest * @return HttpRequest
* @throws AuthenticationException * @throws AuthenticationException
* @throws GitlabServiceException * @throws GitlabServiceException
*/ */
public static function prepareGitServiceRequest(HttpRequest $httpRequest, ?Entry $entry=null, bool $expect_json=true): HttpRequest public static function prepareGitServiceRequest(HttpRequest $http_request, ?Entry $entry=null, bool $expect_json=true): HttpRequest
{ {
if($entry !== null) if($entry !== null)
{ {
if (!$entry->isCurrentlyDecrypted()) if(!$entry->isCurrentlyDecrypted())
{
throw new GitlabServiceException('The given Vault entry is not decrypted.'); throw new GitlabServiceException('The given Vault entry is not decrypted.');
}
switch ($entry->getPassword()->getAuthenticationType()) { switch ($entry->getPassword()?->getAuthenticationType())
{
case AuthenticationType::ACCESS_TOKEN: case AuthenticationType::ACCESS_TOKEN:
$httpRequest->Headers[] = "Authorization: Bearer " . $entry->getPassword(); $http_request->Headers[] = "Authorization: Bearer " . $entry->getPassword();
break; break;
case AuthenticationType::USERNAME_PASSWORD: case AuthenticationType::USERNAME_PASSWORD:
@ -580,11 +592,11 @@ namespace ncc\Utilities;
if($expect_json) if($expect_json)
{ {
$httpRequest->Headers[] = "Accept: application/json"; $http_request->Headers[] = "Accept: application/json";
$httpRequest->Headers[] = "Content-Type: application/json"; $http_request->Headers[] = "Content-Type: application/json";
} }
return $httpRequest; return $http_request;
} }
/** /**
@ -595,23 +607,23 @@ namespace ncc\Utilities;
* @return string * @return string
* @throws AuthenticationException * @throws AuthenticationException
* @throws GitlabServiceException * @throws GitlabServiceException
* @throws InvalidScopeException
* @throws HttpException * @throws HttpException
*/ */
public static function downloadGitServiceFile(string $url, ?Entry $entry=null): string public static function downloadGitServiceFile(string $url, ?Entry $entry=null): string
{ {
if(RuntimeCache::get('download_cache.' . $url) !== null) if(RuntimeCache::get('download_cache.' . $url) !== null)
{
return RuntimeCache::get('download_cache.' . $url); return RuntimeCache::get('download_cache.' . $url);
}
$out_path = Functions::getTmpDir() . "/" . basename($url); $out_path = self::getTmpDir() . "/" . basename($url);
$http_request = new HttpRequest();
$httpRequest = new HttpRequest(); $http_request->Url = $url;
$httpRequest->Url = $url; $http_request->Type = HttpRequestType::GET;
$httpRequest->Type = HttpRequestType::GET; $http_request = self::prepareGitServiceRequest($http_request, $entry, false);
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false);
Console::out('Downloading file ' . $url); Console::out('Downloading file ' . $url);
HttpClient::download($httpRequest, $out_path); HttpClient::download($http_request, $out_path);
RuntimeCache::set('download_cache.' . $url, $out_path); RuntimeCache::set('download_cache.' . $url, $out_path);
return $out_path; return $out_path;
@ -632,7 +644,9 @@ namespace ncc\Utilities;
$filesystem = new Filesystem(); $filesystem = new Filesystem();
if(!$filesystem->exists($out_path)) if(!$filesystem->exists($out_path))
{
$filesystem->mkdir($out_path); $filesystem->mkdir($out_path);
}
RuntimeCache::setFileAsTemporary($out_path); RuntimeCache::setFileAsTemporary($out_path);
@ -651,13 +665,10 @@ namespace ncc\Utilities;
'multipart/x-zip' 'multipart/x-zip'
]); ]);
} }
else elseif(RuntimeCache::get('warning_zip_shown') !== true)
{ {
if(RuntimeCache::get('warning_zip_shown') !== true) Console::out('unzip executable not found. ZIP archives will not be supported.');
{ RuntimeCache::set('warning_zip_shown', true);
Console::out('unzip executable not found. ZIP archives will not be supported.');
RuntimeCache::set('warning_zip_shown', true);
}
} }
if($tar_executable !== null) if($tar_executable !== null)
@ -669,17 +680,16 @@ namespace ncc\Utilities;
'application/x-xz' 'application/x-xz'
]); ]);
} }
else elseif(RuntimeCache::get('warning_tar_shown') !== true)
{ {
if(RuntimeCache::get('warning_tar_shown') !== true) Console::outWarning('tar executable not found. TAR archives will not be supported.');
{ RuntimeCache::set('warning_tar_shown', true);
Console::outWarning('tar executable not found. TAR archives will not be supported.');
RuntimeCache::set('warning_tar_shown', true);
}
} }
if (!in_array($mimeType, $supportedTypes)) if(!in_array($mimeType, $supportedTypes, true))
{
throw new UnsupportedArchiveException("Unsupported archive type: $mimeType"); throw new UnsupportedArchiveException("Unsupported archive type: $mimeType");
}
$command = match ($mimeType) { $command = match ($mimeType) {
'application/zip' => [$unzip_executable, $path, '-d', $out_path], 'application/zip' => [$unzip_executable, $path, '-d', $out_path],
@ -693,12 +703,15 @@ namespace ncc\Utilities;
$process = new Process($command); $process = new Process($command);
// display the output of the command // display the output of the command
$process->run(function ($type, $buffer) { $process->run(function ($type, $buffer)
{
Console::outVerbose($buffer); Console::outVerbose($buffer);
}); });
if (!$process->isSuccessful()) if(!$process->isSuccessful())
{
throw new ArchiveException($process->getErrorOutput()); throw new ArchiveException($process->getErrorOutput());
}
return $out_path; return $out_path;
} }
@ -712,15 +725,19 @@ namespace ncc\Utilities;
*/ */
public static function searchDirectory(string $path, array $files): ?string public static function searchDirectory(string $path, array $files): ?string
{ {
if (!is_dir($path)) if(!is_dir($path))
{
return null; return null;
}
// Search files in the given directory recursively // Search files in the given directory recursively
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
foreach ($iterator as $file) foreach ($iterator as $file)
{ {
if (in_array($file->getFilename(), $files)) if(in_array($file->getFilename(), $files, true))
{
return $file->getPathname(); return $file->getPathname();
}
} }
return null; return null;
@ -734,8 +751,11 @@ namespace ncc\Utilities;
*/ */
public static function convertToSemVer($version): string public static function convertToSemVer($version): string
{ {
if(stripos($version, 'v') === 0) if(stripos(strtolower($version), 'v') === 0)
{
$version = substr($version, 1); $version = substr($version, 1);
}
if(!Validate::version($version)) if(!Validate::version($version))
{ {
$parts = explode('.', $version); $parts = explode('.', $version);
@ -744,17 +764,28 @@ namespace ncc\Utilities;
$patch = (string)null; $patch = (string)null;
if(count($parts) >= 1) if(count($parts) >= 1)
{
$major = $parts[0]; $major = $parts[0];
}
if(count($parts) >= 2) if(count($parts) >= 2)
{
$minor = $parts[1]; $minor = $parts[1];
}
if(count($parts) >= 3) if(count($parts) >= 3)
{
$patch = $parts[2]; $patch = $parts[2];
}
// Assemble the SemVer compatible string // Assemble the SemVer compatible string
$version = "$major.$minor.$patch"; $version = "$major.$minor.$patch";
} }
if(!Validate::version($version)) if(!Validate::version($version))
{
return '1.0.0'; return '1.0.0';
}
return $version; return $version;
} }
@ -803,8 +834,11 @@ namespace ncc\Utilities;
$results->ReleaseName = ($release_results->ReleaseName ?? null); $results->ReleaseName = ($release_results->ReleaseName ?? null);
$results->ReleaseDescription = ($release_results->ReleaseDescription ?? null); $results->ReleaseDescription = ($release_results->ReleaseDescription ?? null);
$results->Files = self::mergeFilesResults($release_results->Files, ($results->Files ?? null)); $results->Files = self::mergeFilesResults($release_results->Files, ($results->Files ?? null));
if($release_results->Version !== null) if($release_results->Version !== null)
{
$results->Version = $release_results->Version; $results->Version = $release_results->Version;
}
} }
try try
@ -819,27 +853,31 @@ namespace ncc\Utilities;
if($git_results !== null) if($git_results !== null)
{ {
if($results->ReleaseName == null) if($results->ReleaseName === null)
{ {
$results->ReleaseName = ($git_results->ReleaseName ?? null); $results->ReleaseName = ($git_results->ReleaseName ?? null);
} }
elseif($git_results->ReleaseName !== null) elseif($git_results->ReleaseName !== null)
{ {
if(strlen($git_results->ReleaseName) > strlen($results->ReleaseName)) if(strlen($git_results->ReleaseName) > strlen($results->ReleaseName))
{
$results->ReleaseName = $git_results->ReleaseName; $results->ReleaseName = $git_results->ReleaseName;
}
} }
if($results->ReleaseDescription == null) if($results->ReleaseDescription === null)
{ {
$results->ReleaseDescription = ($git_results->ReleaseDescription ?? null); $results->ReleaseDescription = ($git_results->ReleaseDescription ?? null);
} }
elseif($git_results->ReleaseDescription !== null) elseif($git_results->ReleaseDescription !== null)
{ {
if(strlen($git_results->ReleaseDescription) > strlen($results->ReleaseDescription)) if(strlen($git_results->ReleaseDescription) > strlen($results->ReleaseDescription))
{
$results->ReleaseDescription = $git_results->ReleaseDescription; $results->ReleaseDescription = $git_results->ReleaseDescription;
}
} }
if($results->Version == null) if($results->Version === null)
{ {
$results->Version = ($git_results->Version ?? null); $results->Version = ($git_results->Version ?? null);
} }
@ -847,7 +885,9 @@ namespace ncc\Utilities;
{ {
// Version compare // Version compare
if(VersionComparator::compareVersion($git_results->Version, $results->Version) > 0) if(VersionComparator::compareVersion($git_results->Version, $results->Version) > 0)
{
$results->Version = $git_results->Version; $results->Version = $git_results->Version;
}
} }
$results->Files = self::mergeFilesResults($git_results->Files, ($results->Files ?? null)); $results->Files = self::mergeFilesResults($git_results->Files, ($results->Files ?? null));
@ -865,27 +905,31 @@ namespace ncc\Utilities;
if($ncc_package_results !== null) if($ncc_package_results !== null)
{ {
if($results->ReleaseName == null) if($results->ReleaseName === null)
{ {
$results->ReleaseName = ($ncc_package_results->ReleaseName ?? null); $results->ReleaseName = ($ncc_package_results->ReleaseName ?? null);
} }
elseif($ncc_package_results->ReleaseName !== null) elseif($ncc_package_results->ReleaseName !== null)
{ {
if(strlen($ncc_package_results->ReleaseName) > strlen($results->ReleaseName)) if(strlen($ncc_package_results->ReleaseName) > strlen($results->ReleaseName))
{
$results->ReleaseName = $ncc_package_results->ReleaseName; $results->ReleaseName = $ncc_package_results->ReleaseName;
}
} }
if($results->ReleaseDescription == null) if($results->ReleaseDescription === null)
{ {
$results->ReleaseDescription = ($ncc_package_results->ReleaseDescription ?? null); $results->ReleaseDescription = ($ncc_package_results->ReleaseDescription ?? null);
} }
elseif($ncc_package_results->ReleaseDescription !== null) elseif($ncc_package_results->ReleaseDescription !== null)
{ {
if(strlen($ncc_package_results->ReleaseDescription) > strlen($results->ReleaseDescription)) if(strlen($ncc_package_results->ReleaseDescription) > strlen($results->ReleaseDescription))
{
$results->ReleaseDescription = $ncc_package_results->ReleaseDescription; $results->ReleaseDescription = $ncc_package_results->ReleaseDescription;
}
} }
if($results->Version == null) if($results->Version === null)
{ {
$results->Version = ($ncc_package_results->Version ?? null); $results->Version = ($ncc_package_results->Version ?? null);
} }
@ -893,7 +937,9 @@ namespace ncc\Utilities;
{ {
// Version compare // Version compare
if(VersionComparator::compareVersion($ncc_package_results->Version, $results->Version) > 0) if(VersionComparator::compareVersion($ncc_package_results->Version, $results->Version) > 0)
{
$results->Version = $ncc_package_results->Version; $results->Version = $ncc_package_results->Version;
}
} }
$results->Files = self::mergeFilesResults($ncc_package_results->Files, ($results->Files ?? null)); $results->Files = self::mergeFilesResults($ncc_package_results->Files, ($results->Files ?? null));
@ -903,7 +949,7 @@ namespace ncc\Utilities;
} }
/** /**
* Merges the given Files object with another Files object * Merges the given Files an object with another Files object
* *
* @param Files $input * @param Files $input
* @param Files|null $selected * @param Files|null $selected
@ -911,26 +957,40 @@ namespace ncc\Utilities;
*/ */
private static function mergeFilesResults(RepositoryQueryResults\Files $input, ?RepositoryQueryResults\Files $selected=null): RepositoryQueryResults\Files private static function mergeFilesResults(RepositoryQueryResults\Files $input, ?RepositoryQueryResults\Files $selected=null): RepositoryQueryResults\Files
{ {
if($selected == null) if($selected === null)
{
$selected = new RepositoryQueryResults\Files(); $selected = new RepositoryQueryResults\Files();
}
if($input->GitSshUrl !== null) if($input->GitSshUrl !== null)
{
$selected->GitSshUrl = $input->GitSshUrl; $selected->GitSshUrl = $input->GitSshUrl;
}
if($input->GitHttpUrl !== null) if($input->GitHttpUrl !== null)
{
$selected->GitHttpUrl = $input->GitHttpUrl; $selected->GitHttpUrl = $input->GitHttpUrl;
}
if($input->SourceUrl !== null) if($input->SourceUrl !== null)
{
$selected->SourceUrl = $input->SourceUrl; $selected->SourceUrl = $input->SourceUrl;
}
if($input->TarballUrl !== null) if($input->TarballUrl !== null)
{
$selected->TarballUrl = $input->TarballUrl; $selected->TarballUrl = $input->TarballUrl;
}
if($input->ZipballUrl !== null) if($input->ZipballUrl !== null)
{
$selected->ZipballUrl = $input->ZipballUrl; $selected->ZipballUrl = $input->ZipballUrl;
}
if($input->PackageUrl !== null) if($input->PackageUrl !== null)
{
$selected->PackageUrl = $input->PackageUrl; $selected->PackageUrl = $input->PackageUrl;
}
return $selected; return $selected;
} }
@ -946,10 +1006,14 @@ namespace ncc\Utilities;
if (is_numeric($input)) if (is_numeric($input))
{ {
if (str_contains($input, '.')) if (str_contains($input, '.'))
{
return (float)$input; return (float)$input;
}
if (ctype_digit($input)) if (ctype_digit($input))
{
return (int)$input; return (int)$input;
}
} }
elseif (in_array(strtolower($input), ['true', 'false'])) elseif (in_array(strtolower($input), ['true', 'false']))
{ {
@ -963,12 +1027,13 @@ namespace ncc\Utilities;
* Finalizes the permissions * Finalizes the permissions
* *
* @return void * @return void
* @throws InvalidScopeException
*/ */
public static function finalizePermissions(): void public static function finalizePermissions(): void
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
return; return;
}
Console::outVerbose('Finalizing permissions...'); Console::outVerbose('Finalizing permissions...');
$filesystem = new Filesystem(); $filesystem = new Filesystem();
@ -976,7 +1041,9 @@ namespace ncc\Utilities;
try try
{ {
if($filesystem->exists(PathFinder::getDataPath(Scopes::SYSTEM))) if($filesystem->exists(PathFinder::getDataPath(Scopes::SYSTEM)))
{
$filesystem->chmod(PathFinder::getDataPath(Scopes::SYSTEM), 0777, 0000, true); $filesystem->chmod(PathFinder::getDataPath(Scopes::SYSTEM), 0777, 0000, true);
}
} }
catch(Exception $e) catch(Exception $e)
{ {
@ -986,7 +1053,9 @@ namespace ncc\Utilities;
try try
{ {
if($filesystem->exists(PathFinder::getCachePath(Scopes::SYSTEM))) if($filesystem->exists(PathFinder::getCachePath(Scopes::SYSTEM)))
{
$filesystem->chmod(PathFinder::getCachePath(Scopes::SYSTEM), 0777, 0000, true); $filesystem->chmod(PathFinder::getCachePath(Scopes::SYSTEM), 0777, 0000, true);
}
} }
catch(Exception $e) catch(Exception $e)
{ {
@ -1003,10 +1072,14 @@ namespace ncc\Utilities;
public static function isTtyMode(): bool public static function isTtyMode(): bool
{ {
if(!is_null(RuntimeCache::get('posix_isatty'))) if(!is_null(RuntimeCache::get('posix_isatty')))
{
return RuntimeCache::get('posix_isatty'); return RuntimeCache::get('posix_isatty');
}
if(function_exists('posix_isatty') === false) if(function_exists('posix_isatty') === false)
{
return false; return false;
}
RuntimeCache::set('posix_isatty', posix_isatty(STDOUT)); RuntimeCache::set('posix_isatty', posix_isatty(STDOUT));
return (bool)RuntimeCache::get('posix_isatty'); return (bool)RuntimeCache::get('posix_isatty');

View file

@ -1,30 +1,30 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following * Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions: * conditions:
* *
* The above copyright notice and this permission notice shall be included in all copies or substantial portions * The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software. * of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
*/ */
namespace ncc\Utilities; namespace ncc\Utilities;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use SplFileInfo; use SplFileInfo;
use SplFileObject; use SplFileObject;
@ -50,21 +50,25 @@ namespace ncc\Utilities;
} }
Console::outDebug(sprintf('writing %s of data to %s', Functions::b2u(strlen($data)), $uri)); Console::outDebug(sprintf('writing %s of data to %s', Functions::b2u(strlen($data)), $uri));
$file = new SplFileObject($uri, $mode); $file = new SplFileObject($uri, $mode);
if (!$file->flock(LOCK_EX | LOCK_NB)) if (!$file->flock(LOCK_EX | LOCK_NB))
{ {
throw new IOException(sprintf('Unable to obtain lock on file: (%s)', $uri)); throw new IOException(sprintf('Unable to obtain lock on file: (%s)', $uri));
} }
elseif (!$file->fwrite($data))
if (!$file->fwrite($data))
{ {
throw new IOException(sprintf('Unable to write content to file: (%s)... to (%s)', substr($data,0,25), $uri)); throw new IOException(sprintf('Unable to write content to file: (%s)... to (%s)', substr($data,0,25), $uri));
} }
elseif (!$file->flock(LOCK_UN))
if (!$file->flock(LOCK_UN))
{ {
throw new IOException(sprintf('Unable to remove lock on file: (%s)', $uri)); throw new IOException(sprintf('Unable to remove lock on file: (%s)', $uri));
} }
elseif (!@chmod($uri, $perms))
if (!@chmod($uri, $perms))
{ {
throw new IOException(sprintf('Unable to chmod: (%s) to (%s)', $uri, $perms)); throw new IOException(sprintf('Unable to chmod: (%s) to (%s)', $uri, $perms));
} }
@ -78,8 +82,8 @@ namespace ncc\Utilities;
* @param int|null $length * @param int|null $length
* @return string * @return string
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws PathNotFoundException
*/ */
public static function fread(string $uri, string $mode='r', ?int $length=null): string public static function fread(string $uri, string $mode='r', ?int $length=null): string
{ {
@ -92,21 +96,27 @@ namespace ncc\Utilities;
if(!file_exists($uri)) if(!file_exists($uri))
{ {
throw new FileNotFoundException(sprintf('Cannot find file %s', $uri)); throw new PathNotFoundException($uri);
} }
if(!is_readable($uri)) if(!is_readable($uri))
{ {
throw new AccessDeniedException(sprintf('Insufficient permissions to read %s', $uri)); throw new AccessDeniedException(sprintf('Unable to read file: (%s)', $uri));
} }
$file = new SplFileObject($uri, $mode); $file = new SplFileObject($uri, $mode);
if($length == null) if($length === null)
{ {
/** @noinspection CallableParameterUseCaseInTypeContextInspection */
$length = $file->getSize(); $length = $file->getSize();
if($length === false)
{
throw new IOException(sprintf('Unable to get size of file: (%s)', $uri));
}
} }
if($length == 0) if($length === 0)
{ {
return (string)null; return (string)null;
} }

View file

@ -22,6 +22,7 @@
namespace ncc\Utilities; namespace ncc\Utilities;
use InvalidArgumentException;
use ncc\Enums\Scopes; use ncc\Enums\Scopes;
use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidPackageNameException;
use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\InvalidScopeException;
@ -33,41 +34,21 @@ namespace ncc\Utilities;
/** /**
* Returns the root path of the system * Returns the root path of the system
* *
* @param bool $win32
* @return string * @return string
*/ */
public static function getRootPath(bool $win32=false): string public static function getRootPath(): string
{ {
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' && $win32)
return "C:/"; // Emulation for unix only
return realpath(DIRECTORY_SEPARATOR); return realpath(DIRECTORY_SEPARATOR);
} }
/**
* Returns the path for where NCC is installed
*
* @return string
*/
public static function getInstallationPath(): string
{
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
{
return realpath(self::getRootPath() . DIRECTORY_SEPARATOR . 'ncc');
}
return realpath(self::getRootPath() . DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'ncc');
}
/** /**
* Returns the home directory of the user * Returns the home directory of the user
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException * @throws InvalidScopeException
*/ */
public static function getHomePath(string $scope=Scopes::AUTO, bool $win32=false): string public static function getHomePath(string $scope=Scopes::AUTO): string
{ {
$scope = Resolver::resolveScope($scope); $scope = Resolver::resolveScope($scope);
@ -76,17 +57,6 @@ namespace ncc\Utilities;
throw new InvalidScopeException($scope); throw new InvalidScopeException($scope);
} }
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || $win32)
{
switch($scope)
{
case Scopes::USER:
return self::getRootPath($win32) . 'ncc' . DIRECTORY_SEPARATOR . 'user_home';
case Scopes::SYSTEM:
return self::getRootPath($win32) . 'ncc' . DIRECTORY_SEPARATOR . 'system_home';
}
}
switch($scope) switch($scope)
{ {
case Scopes::USER: case Scopes::USER:
@ -104,30 +74,17 @@ namespace ncc\Utilities;
* Returns the path where all NCC installation data is stored * Returns the path where all NCC installation data is stored
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getDataPath(string $scope=Scopes::AUTO, bool $win32=false): string public static function getDataPath(string $scope=Scopes::AUTO): string
{ {
$scope = Resolver::resolveScope($scope); $scope = Resolver::resolveScope($scope);
if(!Validate::scope($scope, false)) if(!Validate::scope($scope, false))
{ {
throw new InvalidScopeException($scope); throw new InvalidArgumentException(sprintf('Invalid scope "%s"', $scope));
} }
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || $win32)
{
switch($scope)
{
case Scopes::USER:
return self::getRootPath($win32) . 'ncc' . DIRECTORY_SEPARATOR . 'user';
case Scopes::SYSTEM:
return self::getRootPath($win32) . 'ncc' . DIRECTORY_SEPARATOR . 'system';
}
}
switch($scope) switch($scope)
{ {
case Scopes::USER: case Scopes::USER:
@ -138,98 +95,84 @@ namespace ncc\Utilities;
return self::getRootPath() . 'var' . DIRECTORY_SEPARATOR . 'ncc'; return self::getRootPath() . 'var' . DIRECTORY_SEPARATOR . 'ncc';
} }
throw new InvalidScopeException($scope); throw new InvalidArgumentException(sprintf('Invalid scope "%s"', $scope));
} }
/** /**
* Returns the path where packages are installed * Returns the path where packages are installed
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getPackagesPath(string $scope=Scopes::AUTO, bool $win32=false): string public static function getPackagesPath(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'packages'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'packages';
} }
/** /**
* Returns the path where cache files are stored * Returns the path where cache files are stored
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getCachePath(string $scope=Scopes::AUTO, bool $win32=false): string public static function getCachePath(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'cache'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'cache';
} }
/** /**
* Returns the path where Runner bin files are located and installed * Returns the path where Runner bin files are located and installed
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getRunnerPath(string $scope=Scopes::AUTO, bool $win32=false): string public static function getRunnerPath(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'runners'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'runners';
} }
/** /**
* Returns the package lock file * Returns the package lock file
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getPackageLock(string $scope=Scopes::AUTO, bool $win32=false): string public static function getPackageLock(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'package.lck'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'package.lck';
} }
/** /**
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getRemoteSources(string $scope=Scopes::AUTO, bool $win32=false): string public static function getRemoteSources(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'sources'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'sources';
} }
/** /**
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getSymlinkDictionary(string $scope=Scopes::AUTO, bool $win32=false): string public static function getSymlinkDictionary(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'symlinks'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'symlinks';
} }
/** /**
* Returns an array of all the package lock files the current user can access (For global-cross referencing) * Returns an array of all the package lock files the current user can access (For global-cross referencing)
* *
* @param bool $win32
* @return array * @return array
* @throws InvalidScopeException
*/ */
public static function getPackageLockFiles(bool $win32=false): array public static function getPackageLockFiles(): array
{ {
$results = []; $results = [];
$results[] = self::getPackageLock(Scopes::SYSTEM, $win32); $results[] = self::getPackageLock(Scopes::SYSTEM);
if(!in_array(self::getPackageLock(Scopes::USER, $win32), $results)) if(!in_array(self::getPackageLock(Scopes::USER), $results, true))
{ {
$results[] = self::getPackageLock(Scopes::USER, $win32); $results[] = self::getPackageLock(Scopes::USER);
} }
return $results; return $results;
@ -241,12 +184,13 @@ namespace ncc\Utilities;
* @param string $package * @param string $package
* @return string * @return string
* @throws InvalidPackageNameException * @throws InvalidPackageNameException
* @throws InvalidScopeException
*/ */
public static function getPackageDataPath(string $package): string public static function getPackageDataPath(string $package): string
{ {
if(!Validate::packageName($package)) if(!Validate::packageName($package))
{
throw new InvalidPackageNameException($package); throw new InvalidPackageNameException($package);
}
return self::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package; return self::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package;
} }
@ -255,20 +199,17 @@ namespace ncc\Utilities;
* Returns the file path where files for the given extension is stored * Returns the file path where files for the given extension is stored
* *
* @param string $scope * @param string $scope
* @param bool $win32
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getExtensionPath(string $scope=Scopes::AUTO, bool $win32=false): string public static function getExtensionPath(string $scope=Scopes::AUTO): string
{ {
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'ext'; return self::getDataPath($scope) . DIRECTORY_SEPARATOR . 'ext';
} }
/** /**
* Returns the configuration file path (ncc.yaml) * Returns the configuration file path (ncc.yaml)
* *
* @return string * @return string
* @throws InvalidScopeException
*/ */
public static function getConfigurationFile(): string public static function getConfigurationFile(): string
{ {
@ -290,15 +231,18 @@ namespace ncc\Utilities;
if($config_value !== null) if($config_value !== null)
{ {
if(file_exists($config_value) && is_executable($config_value)) if(file_exists($config_value) && is_executable($config_value))
{
return $config_value; return $config_value;
}
Console::outWarning(sprintf('The configured \'%s\' executable path is invalid, trying to find it automatically...', $runner)); Console::outWarning(sprintf('The configured \'%s\' executable path is invalid, trying to find it automatically...', $runner));
} }
$exec_path = $executable_finder->find($runner); $exec_path = $executable_finder->find($runner);
if($exec_path !== null) if($exec_path !== null)
{
return $exec_path; return $exec_path;
}
throw new RunnerExecutionException(sprintf('Unable to find \'%s\' executable', $runner)); throw new RunnerExecutionException(sprintf('Unable to find \'%s\' executable', $runner));
} }

View file

@ -1,31 +1,34 @@
<?php <?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc; /** @noinspection PhpMissingFieldTypeInspection */
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc;
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\MalformedJsonException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\RuntimeException; use ncc\Exceptions\RuntimeException;
use ncc\Objects\NccVersionInformation; use ncc\Objects\NccVersionInformation;
use ncc\Utilities\Functions; use ncc\Utilities\Functions;
@ -42,15 +45,7 @@ namespace ncc;
* *
* @var NccVersionInformation|null * @var NccVersionInformation|null
*/ */
private static $VersionInformation; private static $version_information;
/**
* NCC Public Constructor
*/
public function __construct()
{
}
/** /**
* Returns the version information object about the current build of NCC * Returns the version information object about the current build of NCC
@ -58,40 +53,41 @@ namespace ncc;
* @param boolean $reload Indicates if the cached version is to be ignored and the version file to be reloaded and validated * @param boolean $reload Indicates if the cached version is to be ignored and the version file to be reloaded and validated
* @return NccVersionInformation * @return NccVersionInformation
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws RuntimeException * @throws PathNotFoundException
*/ */
public static function getVersionInformation(bool $reload=False): NccVersionInformation public static function getVersionInformation(bool $reload=False): NccVersionInformation
{ {
if(self::$VersionInformation !== null && !$reload) if(self::$version_information !== null && !$reload)
return self::$VersionInformation; {
return self::$version_information;
}
if(!file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'version.json')) if(!file_exists(__DIR__ . DIRECTORY_SEPARATOR . 'version.json'))
{ {
throw new RuntimeException('The file \'version.json\' was not found in \'' . __DIR__ . '\''); throw new \RuntimeException('The file \'version.json\' was not found in \'' . __DIR__ . '\'');
} }
try try
{ {
self::$VersionInformation = NccVersionInformation::fromArray(Functions::loadJsonFile(__DIR__ . DIRECTORY_SEPARATOR . 'version.json', Functions::FORCE_ARRAY)); self::$version_information = NccVersionInformation::fromArray(Functions::loadJsonFile(__DIR__ . DIRECTORY_SEPARATOR . 'version.json', Functions::FORCE_ARRAY));
} }
catch(MalformedJsonException $e) catch(MalformedJsonException $e)
{ {
throw new RuntimeException('Unable to parse JSON contents of \'version.json\' in \'' . __DIR__ . '\'', $e); throw new \RuntimeException('Unable to parse JSON contents of \'version.json\' in \'' . __DIR__ . '\'', $e);
} }
if(self::$VersionInformation->Version == null) if(self::$version_information->Version === null)
{ {
throw new RuntimeException('The version number is not specified in the version information file'); throw new \RuntimeException('The version number is not specified in the version information file');
} }
if(self::$VersionInformation->Branch == null) if(self::$version_information->Branch === null)
{ {
throw new RuntimeException('The version branch is not specified in the version information file'); throw new \RuntimeException('The version branch is not specified in the version information file');
} }
return self::$VersionInformation; return self::$version_information;
} }
/** /**
@ -99,15 +95,16 @@ namespace ncc;
* *
* @return bool * @return bool
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException
* @throws IOException * @throws IOException
* @throws RuntimeException * @throws PathNotFoundException
*/ */
public static function initialize(): bool public static function initialize(): bool
{ {
if(defined('NCC_INIT')) if(defined('NCC_INIT'))
{
return false; return false;
}
// Set debugging/troubleshooting constants // Set debugging/troubleshooting constants
define('NCC_EXEC_LOCATION', __DIR__); // The directory of where ncc.php is located define('NCC_EXEC_LOCATION', __DIR__); // The directory of where ncc.php is located
define('NCC_EXEC_IWD', getcwd()); // The initial working directory when NCC was first invoked define('NCC_EXEC_IWD', getcwd()); // The initial working directory when NCC was first invoked
@ -130,27 +127,20 @@ namespace ncc;
*/ */
public static function cliMode(): bool public static function cliMode(): bool
{ {
// TODO: Optimize this function to reduce redundant calls return defined('NCC_CLI_MODE') && NCC_CLI_MODE === 1;
if(defined('NCC_CLI_MODE') && NCC_CLI_MODE == 1)
{
return true;
}
return false;
} }
/** /**
* Returns the constants set by NCC * Returns the constants set by NCC
* *
* @return array * @return array
* @throws RuntimeException
*/ */
public static function getConstants(): array public static function getConstants(): array
{ {
if(!defined('NCC_INIT')) if(!defined('NCC_INIT'))
{ {
throw new RuntimeException('NCC Must be initialized before executing ' . get_called_class() . '::getConstants()'); /** @noinspection ClassConstantCanBeUsedInspection */
throw new \RuntimeException('NCC Must be initialized before executing ' . get_called_class() . '::getConstants()');
} }
return [ return [