diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index a854623..56030f7 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -1,6 +1,78 @@ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 513c181..8a9a698 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Added - `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 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 > Versions` - 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` diff --git a/README.md b/README.md index 8f807a3..c4e3427 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # ![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. 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. diff --git a/src/installer/installer b/src/installer/installer index c738989..0ee51b6 100644 --- a/src/installer/installer +++ b/src/installer/installer @@ -291,7 +291,7 @@ foreach($VersionInformation->Components as $component) { - $full_name = $component->Vendor . '/' . $component->PackageName; + $full_name = $component->vendor . '/' . $component->package_name; try { diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index e6ce060..2efd9c8 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -1,29 +1,28 @@ 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 @@ -363,7 +363,7 @@ namespace ncc\CLI\Management; $path = $package; $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 { diff --git a/src/ncc/CLI/Management/ProjectMenu.php b/src/ncc/CLI/Management/ProjectMenu.php index b774b64..da1e21f 100644 --- a/src/ncc/CLI/Management/ProjectMenu.php +++ b/src/ncc/CLI/Management/ProjectMenu.php @@ -1,38 +1,37 @@ ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); $policy->Execute->Target = null; diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index 3f7c21c..0d230f6 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -38,8 +38,7 @@ namespace ncc\Classes\ComposerExtension; use ncc\Exceptions\ComposerDisabledException; use ncc\Exceptions\ComposerException; use ncc\Exceptions\ComposerNotAvailableException; - use ncc\Exceptions\DirectoryNotFoundException; - use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\PathNotFoundException; use ncc\Exceptions\InternalComposerNotAvailableException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; @@ -88,14 +87,13 @@ namespace ncc\Classes\ComposerExtension; * @throws ComposerDisabledException * @throws ComposerException * @throws ComposerNotAvailableException - * @throws DirectoryNotFoundException - * @throws FileNotFoundException * @throws IOException * @throws InternalComposerNotAvailableException * @throws InvalidScopeException * @throws MalformedJsonException * @throws PackageNotFoundException * @throws PackagePreparationFailedException + * @throws PathNotFoundException * @throws ProjectConfigurationNotFoundException * @throws RuntimeException * @throws UnsupportedCompilerExtensionException @@ -103,7 +101,7 @@ namespace ncc\Classes\ComposerExtension; */ 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'); $real_package_name = explode('=', $packageInput->toStandard(false))[0]; @@ -131,13 +129,12 @@ namespace ncc\Classes\ComposerExtension; * @throws ComposerDisabledException * @throws ComposerException * @throws ComposerNotAvailableException - * @throws DirectoryNotFoundException - * @throws FileNotFoundException * @throws IOException * @throws InternalComposerNotAvailableException * @throws MalformedJsonException * @throws PackageNotFoundException * @throws PackagePreparationFailedException + * @throws PathNotFoundException * @throws ProjectConfigurationNotFoundException * @throws UnsupportedCompilerExtensionException * @throws UserAbortedOperationException @@ -147,7 +144,7 @@ namespace ncc\Classes\ComposerExtension; // Check if the file composer.json exists 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 @@ -205,12 +202,11 @@ namespace ncc\Classes\ComposerExtension; * @throws AccessDeniedException * @throws BuildConfigurationNotFoundException * @throws BuildException - * @throws DirectoryNotFoundException - * @throws FileNotFoundException * @throws IOException * @throws MalformedJsonException * @throws PackageNotFoundException * @throws PackagePreparationFailedException + * @throws PathNotFoundException * @throws ProjectConfigurationNotFoundException * @throws UnsupportedCompilerExtensionException */ @@ -218,7 +214,7 @@ namespace ncc\Classes\ComposerExtension; { if (!file_exists($composer_lock_path)) { - throw new FileNotFoundException($composer_lock_path); + throw new PathNotFoundException($composer_lock_path); } $base_dir = dirname($composer_lock_path); @@ -537,7 +533,7 @@ namespace ncc\Classes\ComposerExtension; * @throws ComposerDisabledException * @throws ComposerException * @throws ComposerNotAvailableException - * @throws FileNotFoundException + * @throws PathNotFoundException * @throws IOException * @throws InternalComposerNotAvailableException * @throws InvalidScopeException @@ -564,7 +560,7 @@ namespace ncc\Classes\ComposerExtension; if (!file_exists($tpl_file)) { - throw new FileNotFoundException($tpl_file); + throw new PathNotFoundException($tpl_file); } $composer_exec = self::getComposerPath(); @@ -698,7 +694,6 @@ namespace ncc\Classes\ComposerExtension; * @param mixed $composer_package * @return ProjectConfiguration * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws MalformedJsonException * @throws PackagePreparationFailedException @@ -707,7 +702,7 @@ namespace ncc\Classes\ComposerExtension; { 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); diff --git a/src/ncc/Classes/GithubExtension/GithubService.php b/src/ncc/Classes/GithubExtension/GithubService.php index b1e24cc..a7e1bbf 100644 --- a/src/ncc/Classes/GithubExtension/GithubService.php +++ b/src/ncc/Classes/GithubExtension/GithubService.php @@ -59,9 +59,9 @@ namespace ncc\Classes\GithubExtension; { $httpRequest = new HttpRequest(); $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); - $repository = urlencode($packageInput->Package); + $repository = urlencode($packageInput->package); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository"; $response_decoded = self::getJsonResponse($httpRequest, $entry); @@ -128,9 +128,9 @@ namespace ncc\Classes\GithubExtension; { $httpRequest = new HttpRequest(); $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); - $repository = urlencode($packageInput->Package); + $repository = urlencode($packageInput->package); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases"; $response_decoded = self::getJsonResponse($httpRequest, $entry); @@ -235,7 +235,7 @@ namespace ncc\Classes\GithubExtension; throw new VersionNotFoundException('No releases found for the given repository.'); } - if ($packageInput->Version === Versions::LATEST) + if ($packageInput->version === Versions::LATEST) { $latest_version = null; foreach ($releases as $release) @@ -256,7 +256,7 @@ namespace ncc\Classes\GithubExtension; } // Query a specific version - if (!isset($releases[$packageInput->Version])) + if (!isset($releases[$packageInput->version])) { // Find the closest thing to the requested version $selected_version = null; @@ -268,7 +268,7 @@ namespace ncc\Classes\GithubExtension; continue; } - if (VersionComparator::compareVersion($version, $packageInput->Version) === 1) + if (VersionComparator::compareVersion($version, $packageInput->version) === 1) { $selected_version = $version; } @@ -281,7 +281,7 @@ namespace ncc\Classes\GithubExtension; } else { - $selected_version = $packageInput->Version; + $selected_version = $packageInput->version; } if (!isset($releases[$selected_version])) diff --git a/src/ncc/Classes/GitlabExtension/GitlabService.php b/src/ncc/Classes/GitlabExtension/GitlabService.php index b7f58fd..1550a30 100644 --- a/src/ncc/Classes/GitlabExtension/GitlabService.php +++ b/src/ncc/Classes/GitlabExtension/GitlabService.php @@ -58,9 +58,9 @@ { $httpRequest = new HttpRequest(); $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); - $project_f = str_ireplace("/", "%2F", $packageInput->Package); + $project_f = str_ireplace("/", "%2F", $packageInput->package); $project_f = str_ireplace(".", "%2F", $project_f); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$project_f"; $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); @@ -100,7 +100,7 @@ */ 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) { @@ -108,7 +108,7 @@ } // Query the latest package only - if($packageInput->Version === Versions::LATEST) + if($packageInput->version === Versions::LATEST) { $latest_version = null; foreach($releases as $release) @@ -129,7 +129,7 @@ } // Query a specific version - if(!isset($releases[$packageInput->Version])) + if(!isset($releases[$packageInput->version])) { // Find the closest thing to the requested version $selected_version = null; @@ -141,7 +141,7 @@ continue; } - if(VersionComparator::compareVersion($version, $packageInput->Version) === 1) + if(VersionComparator::compareVersion($version, $packageInput->version) === 1) { $selected_version = $version; } @@ -154,7 +154,7 @@ } else { - $selected_version = $packageInput->Version; + $selected_version = $packageInput->version; } if(!isset($releases[$selected_version])) diff --git a/src/ncc/Classes/LuaExtension/LuaRunner.php b/src/ncc/Classes/LuaExtension/LuaRunner.php index 599c5b2..0d9be05 100644 --- a/src/ncc/Classes/LuaExtension/LuaRunner.php +++ b/src/ncc/Classes/LuaExtension/LuaRunner.php @@ -37,7 +37,7 @@ namespace ncc\Classes\LuaExtension; { $execution_unit = new ExecutionUnit(); $policy->Execute->Target = null; - $execution_unit->ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); return $execution_unit; diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index d31b206..67d7d63 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -266,7 +266,7 @@ namespace ncc\Classes\NccExtension; $units = []; 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); } $package->ExecutionUnits = $units; @@ -315,46 +315,46 @@ namespace ncc\Classes\NccExtension; */ 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 = []; - 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); } - $unit->ExecutionPolicy->Execute->Options = $options; + $unit->execution_policy->Execute->Options = $options; } } diff --git a/src/ncc/Classes/NccExtension/Runner.php b/src/ncc/Classes/NccExtension/Runner.php index 0d7c631..f1c462e 100644 --- a/src/ncc/Classes/NccExtension/Runner.php +++ b/src/ncc/Classes/NccExtension/Runner.php @@ -54,7 +54,7 @@ namespace ncc\Classes\NccExtension; $ExecutionPointerManager = new ExecutionPointerManager(); $ExecutionPointerManager->addUnit($package, $version, $unit, true); - $ExecutionPointerManager->executeUnit($package, $version, $unit->ExecutionPolicy->Name); + $ExecutionPointerManager->executeUnit($package, $version, $unit->execution_policy->Name); $ExecutionPointerManager->cleanTemporaryUnits(); } } \ No newline at end of file diff --git a/src/ncc/Classes/PerlExtension/PerlRunner.php b/src/ncc/Classes/PerlExtension/PerlRunner.php index 46ee10d..37a0734 100644 --- a/src/ncc/Classes/PerlExtension/PerlRunner.php +++ b/src/ncc/Classes/PerlExtension/PerlRunner.php @@ -40,7 +40,7 @@ namespace ncc\Classes\PerlExtension; $policy->Execute->Target = null; if(!file_exists($path) && !is_file($path)) throw new FileNotFoundException($path); - $execution_unit->ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); return $execution_unit; diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index 8475673..e1007ba 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -169,10 +169,10 @@ continue; $Component = new Package\Component(); - $Component->Name = Functions::removeBasename($item->getPathname(), $this->path); + $Component->name = Functions::removeBasename($item->getPathname(), $this->path); $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) @@ -396,7 +396,7 @@ 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); try @@ -407,30 +407,30 @@ if($encoded === false) { - $component->DataType = ComponentDataType::BASE64_ENCODED; - $component->Data = Base64::encode($content); + $component->data_types = ComponentDataType::BASE64_ENCODED; + $component->data = Base64::encode($content); } else { - $component->DataType = ComponentDataType::AST; - $component->Data = json_decode($encoded, true); + $component->data_types = ComponentDataType::AST; + $component->data = json_decode($encoded, true); } } catch(Exception $e) { - $component->DataType = ComponentDataType::BASE64_ENCODED; - $component->Data = Base64::encode($content); + $component->data_types = ComponentDataType::BASE64_ENCODED; + $component->data = Base64::encode($content); unset($e); } 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(); $components[] = $component; $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 diff --git a/src/ncc/Classes/PhpExtension/PhpInstaller.php b/src/ncc/Classes/PhpExtension/PhpInstaller.php index 8b90763..e8139d8 100644 --- a/src/ncc/Classes/PhpExtension/PhpInstaller.php +++ b/src/ncc/Classes/PhpExtension/PhpInstaller.php @@ -89,35 +89,35 @@ */ public function processComponent(Package\Component $component): ?string { - if($component->Data == null) + if($component->data == null) return null; - if(!$component->validateChecksum()) - throw new ComponentChecksumException('Checksum validation failed for component ' . $component->Name . ', the package may be corrupted.'); + if(!$component->validate_checksum()) + 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: try { - $stmts = $this->decodeRecursive($component->Data); + $stmts = $this->decodeRecursive($component->data); } 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(); return $prettyPrinter->prettyPrintFile($stmts); case ComponentDataType::BASE64_ENCODED: - return Base64::decode($component->Data); + return Base64::decode($component->data); case ComponentDataType::PLAIN: - return $component->Data; + return $component->data; default: - throw new UnsupportedComponentTypeException('Unsupported component type \'' . $component->DataType . '\''); + throw new UnsupportedComponentTypeException('Unsupported component type \'' . $component->data_types . '\''); } } diff --git a/src/ncc/Classes/PhpExtension/PhpRunner.php b/src/ncc/Classes/PhpExtension/PhpRunner.php index 89f9898..a8fe874 100644 --- a/src/ncc/Classes/PhpExtension/PhpRunner.php +++ b/src/ncc/Classes/PhpExtension/PhpRunner.php @@ -46,7 +46,7 @@ namespace ncc\Classes\PhpExtension; if(!file_exists($path) && !is_file($path)) throw new FileNotFoundException($path); $policy->Execute->Target = null; - $execution_unit->ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); return $execution_unit; diff --git a/src/ncc/Classes/PythonExtension/Python2Runner.php b/src/ncc/Classes/PythonExtension/Python2Runner.php index b411a06..1e77ca6 100644 --- a/src/ncc/Classes/PythonExtension/Python2Runner.php +++ b/src/ncc/Classes/PythonExtension/Python2Runner.php @@ -40,7 +40,7 @@ namespace ncc\Classes\PythonExtension; if(!file_exists($path) && !is_file($path)) throw new FileNotFoundException($path); $policy->Execute->Target = null; - $execution_unit->ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); return $execution_unit; diff --git a/src/ncc/Classes/PythonExtension/Python3Runner.php b/src/ncc/Classes/PythonExtension/Python3Runner.php index bc6ff39..30bac9f 100644 --- a/src/ncc/Classes/PythonExtension/Python3Runner.php +++ b/src/ncc/Classes/PythonExtension/Python3Runner.php @@ -40,7 +40,7 @@ namespace ncc\Classes\PythonExtension; if(!file_exists($path) && !is_file($path)) throw new FileNotFoundException($path); $policy->Execute->Target = null; - $execution_unit->ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); return $execution_unit; diff --git a/src/ncc/Classes/PythonExtension/PythonRunner.php b/src/ncc/Classes/PythonExtension/PythonRunner.php index b3d5168..5bad4f3 100644 --- a/src/ncc/Classes/PythonExtension/PythonRunner.php +++ b/src/ncc/Classes/PythonExtension/PythonRunner.php @@ -40,7 +40,7 @@ namespace ncc\Classes\PythonExtension; if(!file_exists($path) && !is_file($path)) throw new FileNotFoundException($path); $policy->Execute->Target = null; - $execution_unit->ExecutionPolicy = $policy; + $execution_unit->execution_policy = $policy; $execution_unit->Data = IO::fread($path); return $execution_unit; diff --git a/src/ncc/Enums/ExceptionCodes.php b/src/ncc/Enums/ExceptionCodes.php index 1240f5f..2f595e7 100644 --- a/src/ncc/Enums/ExceptionCodes.php +++ b/src/ncc/Enums/ExceptionCodes.php @@ -23,6 +23,7 @@ namespace ncc\Enums; use ncc\Exceptions\InvalidDependencyConfiguration; + use ncc\Exceptions\PathNotFoundException; use ncc\Exceptions\SymlinkException; use ncc\Exceptions\UnsupportedArchiveException; @@ -37,16 +38,6 @@ namespace ncc\Enums; */ public const INVALID_PROJECT_CONFIGURATION = -1700; - /** - * @see FileNotFoundException; - */ - public const FILE_NOT_FOUND = -1701; - - /** - * @see DirectoryNotFoundException - */ - public const DIRECTORY_NOT_FOUND = -1702; - /** * @see InvalidScopeException */ @@ -367,13 +358,16 @@ namespace ncc\Enums; */ public const SYMLINK_EXCEPTION = -1768; + /** + * @see PathNotFoundException + */ + public const PATH_NOT_FOUND = -1769; + /** * All the exception codes from NCC */ public const All = [ self::INVALID_PROJECT_CONFIGURATION, - self::FILE_NOT_FOUND, - self::DIRECTORY_NOT_FOUND, self::INVALID_SCOPE, self::ACCESS_DENIED, self::MALFORMED_JSON, @@ -435,5 +429,6 @@ namespace ncc\Enums; self::INVALID_BUILD_CONFIGURATION, self::INVALID_DEPENDENCY_CONFIGURATION, self::SYMLINK_EXCEPTION, + self::PATH_NOT_FOUND ]; } \ No newline at end of file diff --git a/src/ncc/Exceptions/DirectoryNotFoundException.php b/src/ncc/Exceptions/DirectoryNotFoundException.php deleted file mode 100644 index a834296..0000000 --- a/src/ncc/Exceptions/DirectoryNotFoundException.php +++ /dev/null @@ -1,41 +0,0 @@ -Configuration = RuntimeCache::get('ncc.yaml'); - if($this->Configuration !== null) + $this->configuration = RuntimeCache::get('ncc.yaml'); + + if($this->configuration !== null) + { return; + } + $configuration_contents = IO::fread(PathFinder::getConfigurationFile()); - $this->Configuration = Yaml::parse($configuration_contents); - RuntimeCache::set('ncc.yaml', $this->Configuration); + $this->configuration = Yaml::parse($configuration_contents); + RuntimeCache::set('ncc.yaml', $this->configuration); } /** @@ -92,13 +93,17 @@ Console::outDebug(sprintf('saving configuration file to %s', PathFinder::getConfigurationFile())); if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Cannot save configuration file, insufficient permissions'); + } - if($this->Configuration == null) + if($this->configuration === null) + { return; + } - IO::fwrite(PathFinder::getConfigurationFile(), Yaml::dump($this->Configuration), 0755); - RuntimeCache::set('ncc.yaml', $this->Configuration); + IO::fwrite(PathFinder::getConfigurationFile(), Yaml::dump($this->configuration), 0755); + RuntimeCache::set('ncc.yaml', $this->configuration); RuntimeCache::set('config_cache', []); } @@ -108,20 +113,18 @@ * * @param string $property * @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($property); $current_selection = $this->getConfiguration(); - foreach(explode('.', strtolower($property)) as $property) + foreach(explode('.', strtolower($property)) as $property_value) { $value_found = false; foreach($current_selection as $key => $value) { - if($key == $property) + if($key === $property_value) { $current_selection = $value; $value_found = true; @@ -130,7 +133,9 @@ } if(!$value_found) + { return null; + } } return $current_selection; @@ -149,15 +154,18 @@ Console::outDebug(sprintf('updating property %s', $property)); $keys = explode('.', $property); - $current = &$this->Configuration; + $current = &$this->configuration; + foreach ($keys as $k) { if (!array_key_exists($k, $current)) { return false; } + $current = &$current[$k]; } + $current = Functions::stringTypeCast($value); $this->save(); @@ -169,7 +177,7 @@ */ private function getConfiguration(): mixed { - if($this->Configuration == null) + if($this->configuration === null) { try { @@ -177,11 +185,12 @@ } catch(Exception $e) { - $this->Configuration = []; + unset($e); + $this->configuration = []; } } - return $this->Configuration; + return $this->configuration; } } \ No newline at end of file diff --git a/src/ncc/Managers/CredentialManager.php b/src/ncc/Managers/CredentialManager.php index 6de26b7..9ec1d70 100644 --- a/src/ncc/Managers/CredentialManager.php +++ b/src/ncc/Managers/CredentialManager.php @@ -1,24 +1,24 @@ CredentialsPath = PathFinder::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'credentials.store'; - $this->Vault = null; + $this->store_path = PathFinder::getDataPath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . 'credentials.store'; try { @@ -69,8 +66,10 @@ unset($e); } - if($this->Vault == null) - $this->Vault = new Vault(); + if($this->vault === null) + { + $this->vault = new Vault(); + } } /** @@ -82,20 +81,24 @@ */ 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 // is to be executed to fix the damaged file. - if(file_exists($this->CredentialsPath)) + if(file_exists($this->store_path)) + { return; + } if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Cannot construct credentials store without system permissions'); + } $VaultObject = new Vault(); $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 IOException * @throws RuntimeException - * @throws FileNotFoundException */ 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) - return; - - if(!file_exists($this->CredentialsPath)) + if($this->vault !== null) { - $this->Vault = new Vault(); 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); if($VaultObject->Version !== Versions::CREDENTIALS_STORE_VERSION) + { throw new RuntimeException('Credentials store version mismatch'); + } - $this->Vault = $VaultObject; + $this->vault = $VaultObject; } /** @@ -135,26 +141,17 @@ * @return void * @throws AccessDeniedException * @throws IOException - * @noinspection PhpUnused */ 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) + { throw new AccessDeniedException('Cannot save credentials store without system permissions'); + } - IO::fwrite($this->CredentialsPath, ZiProto::encode($this->Vault->toArray()), 0744); - } - - - /** - * @return string - * @noinspection PhpUnused - */ - public function getCredentialsPath(): string - { - return $this->CredentialsPath; + IO::fwrite($this->store_path, ZiProto::encode($this->vault->toArray()), 0744); } /** @@ -162,6 +159,6 @@ */ public function getVault(): ?Vault { - return $this->Vault; + return $this->vault; } } \ No newline at end of file diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 3f7f306..b88fabc 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -1,24 +1,24 @@ RunnerPath = PathFinder::getRunnerPath(Scopes::SYSTEM); - $this->TemporaryUnits = []; + $this->runner_path = PathFinder::getRunnerPath(Scopes::SYSTEM); + $this->temporary_units = []; } /** @@ -101,14 +101,16 @@ */ public function cleanTemporaryUnits(): void { - if(count($this->TemporaryUnits) == 0) + if(count($this->temporary_units) === 0) + { return; + } Console::outVerbose('Cleaning temporary units...'); 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'])); $this->removeUnit($datum['package'], $datum['version'], $datum['name']); @@ -140,16 +142,17 @@ * @param string $version * @param string $name * @return string - * @throws FileNotFoundException */ public function getEntryPointPath(string $package, string $version, string $name): string { $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'; 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; } @@ -163,22 +166,23 @@ * @param bool $temporary * @return void * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws RunnerExecutionException - * @noinspection PhpUnused + * @throws PathNotFoundException */ public function addUnit(string $package, string $version, ExecutionUnit $unit, bool $temporary=false): void { 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_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; - $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; - $entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name) . '.entrypoint'; + $package_config_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id . '.inx'; + $package_bin_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id; + $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_config_path=%s', $package_config_path)); @@ -197,8 +201,8 @@ $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 .= match ($unit->ExecutionPolicy->Runner) + $bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->execution_policy->Name); + $bin_file .= match ($unit->execution_policy->Runner) { Runners::BASH => BashRunner::getFileExtension(), Runners::PHP => PhpRunner::getFileExtension(), @@ -206,20 +210,26 @@ Runners::PYTHON => PythonRunner::getFileExtension(), Runners::PYTHON_2 => Python2Runner::getFileExtension(), Runners::PYTHON_3 => Python3Runner::getFileExtension(), - Runners::lua => LuaRunner::getFileExtension(), - default => throw new RunnerExecutionException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), + Runners::LUA => LuaRunner::getFileExtension(), + default => throw new RunnerExecutionException('The runner \'' . $unit->execution_policy->Runner . '\' is not supported'), }; Console::outDebug(sprintf('bin_file=%s', $bin_file)); - if($filesystem->exists($bin_file) && $temporary) + if($temporary && $filesystem->exists($bin_file)) + { return; + } if(!$filesystem->exists($package_bin_path)) + { $filesystem->mkdir($package_bin_path); + } if($filesystem->exists($bin_file)) + { $filesystem->remove($bin_file); + } IO::fwrite($bin_file, $unit->Data); $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 \"$@\"", '/bin/bash', - $package, $version, $unit->ExecutionPolicy->Name + $package, $version, $unit->execution_policy->Name ); if(file_exists($entry_point_path)) + { $filesystem->remove($entry_point_path); + } + IO::fwrite($entry_point_path, $entry_point); chmod($entry_point_path, 0755); if($temporary) { - Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package)); - $this->TemporaryUnits[] = [ + Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->execution_policy->Name, $package)); + $this->temporary_units[] = [ 'package' => $package, 'version' => $version, - 'unit' => $unit->ExecutionPolicy->Name + 'unit' => $unit->execution_policy->Name ]; } } @@ -254,35 +267,44 @@ * @param string $name * @return bool * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException */ public function removeUnit(string $package, string $version, string $name): bool { if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Cannot remove ExecutionUnit \'' . $name .'\' for ' . $package . ', insufficient permissions'); + } Console::outVerbose(sprintf('Removing ExecutionUnit \'%s\' for %s', $name, $package)); $package_id = $this->getPackageId($package, $version); - $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; - $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; + $package_config_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id . '.inx'; + $package_bin_path = $this->runner_path . DIRECTORY_SEPARATOR . $package_id; Console::outDebug(sprintf('package_id=%s', $package_id)); Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); $filesystem = new Filesystem(); + if(!$filesystem->exists($package_config_path)) + { return false; + } + $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); $unit = $execution_pointers->getUnit($name); - if($unit == null) + + if($unit === null) + { return false; + } + $results = $execution_pointers->deleteUnit($name); // 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_bin_path); @@ -291,8 +313,10 @@ } // Delete the single execution pointer file - if($filesystem->exists($unit->FilePointer)) - $filesystem->remove($unit->FilePointer); + if($filesystem->exists($unit->file_pointer)) + { + $filesystem->remove($unit->file_pointer); + } return $results; } @@ -304,16 +328,14 @@ * @param string $version * @return array * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException - * @noinspection PhpUnused */ public function getUnits(string $package, string $version): array { Console::outVerbose(sprintf('getting execution units for %s', $package)); $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_config_path=%s', $package_config_path)); @@ -328,8 +350,8 @@ $results = []; foreach($execution_pointers->getPointers() as $pointer) { - Console::outDebug(sprintf('unit %s', $pointer->ExecutionPolicy->Name)); - $results[] = $pointer->ExecutionPolicy->Name; + Console::outDebug(sprintf('unit %s', $pointer->execution_policy->Name)); + $results[] = $pointer->execution_policy->Name; } return $results; @@ -344,7 +366,6 @@ * @param array $args * @return int * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException * @throws RunnerExecutionException @@ -354,45 +375,49 @@ Console::outVerbose(sprintf('executing unit %s for %s', $name, $package)); $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)) + { throw new NoAvailableUnitsException('There is no available units for \'' . $package . '=' .$version .'\''); + } $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); $unit = $execution_pointers->getUnit($name); - if($unit == null) + if($unit === null) + { throw new RunnerExecutionException('The execution unit \'' . $name . '\' was not found for \'' . $package . '=' .$version .'\''); + } - Console::outDebug(sprintf('unit=%s', $unit->ExecutionPolicy->Name)); - Console::outDebug(sprintf('runner=%s', $unit->ExecutionPolicy->Runner)); - Console::outDebug(sprintf('file=%s', $unit->FilePointer)); - Console::outDebug(sprintf('pass_thru_args=%s', json_encode($args, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE))); + Console::outDebug(sprintf('unit=%s', $unit->execution_policy->Name)); + Console::outDebug(sprintf('runner=%s', $unit->execution_policy->Runner)); + Console::outDebug(sprintf('file=%s', $unit->file_pointer)); + Console::outDebug(sprintf('pass_thru_args=%s', implode(' ', $args))); // 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); } } $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 { @@ -402,12 +427,12 @@ try { - if($unit->ExecutionPolicy->Execute->Silent) + if($unit->execution_policy->Execute->Silent) { $process->disableOutput(); $process->setTty(false); } - elseif($unit->ExecutionPolicy->Execute->Tty) + elseif($unit->execution_policy->Execute->Tty) { $process->enableOutput(); $process->setTty(true); @@ -419,6 +444,7 @@ } catch(Exception $e) { + unset($e); $process->enableOutput(); 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('timeout=%s', ($process->getTimeout() ?? 0))); - Console::outDebug(sprintf('silent=%s', ($unit->ExecutionPolicy->Execute->Silent ? 'true' : 'false'))); - Console::outDebug(sprintf('tty=%s', ($unit->ExecutionPolicy->Execute->Tty ? 'true' : 'false'))); + Console::outDebug(sprintf('timeout=%s', (int)$process->getTimeout())); + Console::outDebug(sprintf('silent=%s', ($unit->execution_policy->Execute->Silent ? 'true' : 'false'))); + Console::outDebug(sprintf('tty=%s', ($unit->execution_policy->Execute->Tty ? 'true' : 'false'))); Console::outDebug(sprintf('options=%s', implode(' ', $args))); Console::outDebug(sprintf('cmd=%s', $process->getCommandLine())); try { - if($unit->ExecutionPolicy->Message !== null) - Console::out($unit->ExecutionPolicy->Message); + if($unit->execution_policy->Message !== null) + { + Console::out($unit->execution_policy->Message); + } $process->run(function ($type, $buffer) { @@ -453,44 +481,37 @@ } 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 { 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 { - $this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Success, $process); - $this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Warning, $process); - $this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Error, $process); + $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Success, $process); + $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Warning, $process); + $this->handleExit($package, $version, $unit->execution_policy->ExitHandlers->Error, $process); } } - $exit_code = $process->getExitCode(); - - if($exit_code == null) - { - return 0; - } - - return $exit_code; + return $process->getExitCode() ?? 0; } /** @@ -500,31 +521,42 @@ * @param string $unit_name * @return void * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException + * @throws PathNotFoundException * @throws RunnerExecutionException */ 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); + 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 $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) + { $required_units[] = $required_unit; + } - $required_unit = $unit->ExecutionPolicy?->ExitHandlers?->Warning?->Run; + $required_unit = $unit->execution_policy?->ExitHandlers?->Warning?->Run; if($required_unit !== null) + { $required_units[] = $required_unit; + } - $required_unit = $unit->ExecutionPolicy?->ExitHandlers?->Error?->Run; + $required_unit = $unit->execution_policy?->ExitHandlers?->Error?->Run; if($required_unit !== null) + { $required_units = $required_unit; + } } // Install the units temporarily @@ -546,35 +578,38 @@ * * @param string $package * @param string $version - * @param ExitHandle $exitHandle + * @param ExitHandle $exit_handler * @param Process|null $process * @return bool * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException * @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) - Console::out($exitHandle->Message); - - if($process !== null && !$exitHandle->EndProcess) + if($exit_handler->Message !== null) { - if($exitHandle->ExitCode !== $process->getExitCode()) - return false; + Console::out($exit_handler->Message); } - 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())); - exit($exitHandle->ExitCode); + exit($exit_handler->ExitCode); } - if($exitHandle->Run !== null) + if($exit_handler->Run !== null) { - Console::outVerbose('Running unit \'' . $exitHandle->Run . '\''); - $this->executeUnit($package, $version, $exitHandle->Run); + Console::outVerbose('Running unit \'' . $exit_handler->Run . '\''); + $this->executeUnit($package, $version, $exit_handler->Run); } return true; diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 324e1a1..54d26d3 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -39,7 +39,6 @@ use ncc\Classes\PhpExtension\PhpInstaller; use ncc\CLI\Main; use ncc\Exceptions\AccessDeniedException; - use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\InstallationException; use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidScopeException; @@ -51,6 +50,7 @@ use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\PackageParsingException; + use ncc\Exceptions\PathNotFoundException; use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\SymlinkException; use ncc\Exceptions\UnsupportedCompilerExtensionException; @@ -82,22 +82,21 @@ /** * @var string */ - private $PackagesPath; + private $packages_path; /** * @var PackageLockManager|null */ - private $PackageLockManager; + private $package_lock_manager; /** - * @throws InvalidScopeException * @throws PackageLockException */ public function __construct() { - $this->PackagesPath = PathFinder::getPackagesPath(Scopes::SYSTEM); - $this->PackageLockManager = new PackageLockManager(); - $this->PackageLockManager->load(); + $this->packages_path = PathFinder::getPackagesPath(Scopes::SYSTEM); + $this->package_lock_manager = new PackageLockManager(); + $this->package_lock_manager->load(); } /** @@ -108,7 +107,6 @@ * @param array $options * @return string * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws InstallationException * @throws InvalidPackageNameException @@ -119,6 +117,7 @@ * @throws PackageLockException * @throws PackageNotFoundException * @throws PackageParsingException + * @throws PathNotFoundException * @throws RunnerExecutionException * @throws SymlinkException * @throws UnsupportedCompilerExtensionException @@ -127,10 +126,14 @@ public function install(string $package_path, ?Entry $entry=null, array $options=[]): string { if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Insufficient permission to install packages'); + } 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); @@ -141,7 +144,7 @@ } $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) { @@ -151,13 +154,11 @@ 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( - $package->Assembly->Package, $package->Assembly->Version - )) + if($this->getPackageLockManager()?->getPackageLock()?->packageExists($package->Assembly->Package, $package->Assembly->Version)) { - $this->getPackageLockManager()->getPackageLock()->removePackageVersion( + $this->getPackageLockManager()?->getPackageLock()?->removePackageVersion( $package->Assembly->Package, $package->Assembly->Version ); } @@ -174,23 +175,20 @@ ]); // 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) { - 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($this->getPackageLockManager()->getPackageLock()->packageExists($dependency->Name, $dependency->Version)) + if($dependency->Version === null) { - if($dependency->Version == null) - { - $this->uninstallPackage($dependency->Name); - } - else - { - $this->uninstallPackageVersion($dependency->Name, $dependency->Version); - } + $this->uninstallPackage($dependency->Name); + } + else + { + $this->uninstallPackageVersion($dependency->Name, $dependency->Version); } } @@ -208,21 +206,31 @@ Console::outDebug(sprintf('installer.src_path: %s', $installation_paths->getSourcePath())); foreach($package->Assembly->toArray() as $prop => $value) + { Console::outDebug(sprintf('assembly.%s: %s', $prop, ($value ?? 'n/a'))); + } + foreach($package->Header->CompilerExtension->toArray() as $prop => $value) + { Console::outDebug(sprintf('header.compiler.%s: %s', $prop, ($value ?? 'n/a'))); + } } 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)); // Include the Execution units if($package->Installer?->PreInstall !== null) + { $steps += count($package->Installer->PreInstall); + } + if($package->Installer?->PostInstall!== null) + { $steps += count($package->Installer->PostInstall); + } $current_steps = 0; $filesystem = new Filesystem(); @@ -233,7 +241,8 @@ $filesystem->mkdir($installation_paths->getBinPath(), 0755); $filesystem->mkdir($installation_paths->getDataPath(), 0755); $filesystem->mkdir($installation_paths->getSourcePath(), 0755); - $current_steps += 1; + + ++$current_steps; Console::inlineProgressBar($current_steps, $steps); } catch(Exception $e) @@ -243,10 +252,12 @@ try { - self::initData($package, $installation_paths); Console::outDebug(sprintf('saving shadow package to %s', $installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg')); + + self::initData($package, $installation_paths); $package->save($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'pkg'); - $current_steps += 1; + ++$current_steps; + Console::inlineProgressBar($current_steps, $steps); } catch(Exception $e) @@ -258,7 +269,7 @@ try { $installer->preInstall($installation_paths); - $current_steps += 1; + ++$current_steps; Console::inlineProgressBar($current_steps, $steps); } catch (Exception $e) @@ -279,7 +290,7 @@ Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage()); } - $current_steps += 1; + ++$current_steps; Console::inlineProgressBar($current_steps, $steps); } } @@ -287,17 +298,21 @@ // Process & Install the components 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 { $data = $installer->processComponent($component); 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); + if(!$filesystem->exists($component_dir)) + { $filesystem->mkdir($component_dir); + } + IO::fwrite($component_path, $data); } } @@ -306,7 +321,7 @@ throw new InstallationException('Cannot process one or more components, ' . $e->getMessage(), $e); } - $current_steps += 1; + ++$current_steps; Console::inlineProgressBar($current_steps, $steps); } @@ -322,8 +337,12 @@ { $resource_path = $installation_paths->getSourcePath() . DIRECTORY_SEPARATOR . $resource->Name; $resource_dir = dirname($resource_path); + if(!$filesystem->exists($resource_dir)) + { $filesystem->mkdir($resource_dir); + } + IO::fwrite($resource_path, $data); } } @@ -332,7 +351,7 @@ throw new InstallationException('Cannot process one or more resources, ' . $e->getMessage(), $e); } - $current_steps += 1; + ++$current_steps; Console::inlineProgressBar($current_steps, $steps); } @@ -347,9 +366,9 @@ /** @var Package\ExecutionUnit $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); - $current_steps += 1; + ++$current_steps; Console::inlineProgressBar($current_steps, $steps); } @@ -364,7 +383,9 @@ if(isset($package->Header->Options['create_symlink']) && $package->Header->Options['create_symlink']) { if($package->MainExecutionPolicy === null) + { throw new InstallationException('Cannot create symlink, no main execution policy is defined'); + } Console::outDebug(sprintf('creating symlink to %s', $package->Assembly->Package)); @@ -376,8 +397,10 @@ try { Console::outDebug('executing post-installation stage'); + $installer->postInstall($installation_paths); - $current_steps += 1; + ++$current_steps; + Console::inlineProgressBar($current_steps, $steps); } catch (Exception $e) @@ -399,9 +422,11 @@ { Console::outWarning('Cannot execute unit ' . $unit_name . ', ' . $e->getMessage()); } - - $current_steps += 1; - Console::inlineProgressBar($current_steps, $steps); + finally + { + ++$current_steps; + Console::inlineProgressBar($current_steps, $steps); + } } } else @@ -425,8 +450,8 @@ } } - $this->getPackageLockManager()->getPackageLock()->addPackage($package, $installation_paths->getInstallationPath()); - $this->getPackageLockManager()->save(); + $this->getPackageLockManager()?->getPackageLock()?->addPackage($package, $installation_paths->getInstallationPath()); + $this->getPackageLockManager()?->save(); RuntimeCache::set(sprintf('installed.%s=%s', $package->Assembly->Package, $package->Assembly->Version), true); @@ -445,43 +470,52 @@ { $input = new RemotePackageInput($source); - 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) + if($input->source === null) { - Console::outDebug('using builtin source ' . $input->Source); - 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'); - } + throw new PackageFetchException('No source specified'); } - if($remote_source_type == RemoteSourceType::DEFINED) + if($input->package === null) { - Console::outDebug('using defined source ' . $input->Source); - $remote_source_manager = new RemoteSourcesManager(); - $source = $remote_source_manager->getRemoteSource($input->Source); - if($source == null) - throw new InstallationException('Remote source ' . $input->Source . ' is not defined'); + 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); + + 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); $exceptions = []; @@ -490,7 +524,7 @@ { 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); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); } @@ -505,7 +539,7 @@ { 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); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); } @@ -520,7 +554,7 @@ { 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); } catch(Exception $e) @@ -534,7 +568,7 @@ { 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); foreach(GitClient::getTags($git_repository) as $tag) @@ -562,14 +596,16 @@ { foreach($exceptions as $e) { - if($exception == null) + if($exception === null) { $exception = new PackageFetchException($e->getMessage(), $e); } else { - if($e->getMessage() == $exception->getMessage()) + if($e->getMessage() === $exception->getMessage()) + { continue; + } $exception = new PackageFetchException($e->getMessage(), $exception); } @@ -600,6 +636,7 @@ try { Console::outVerbose(sprintf('Installing package from source %s', $source)); + $package = $this->fetchFromSource($source, $entry); return $this->install($package, $entry, $options); } @@ -617,7 +654,6 @@ * @param array $options * @return void * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws InstallationException * @throws InvalidPackageNameException @@ -628,10 +664,12 @@ * @throws PackageLockException * @throws PackageNotFoundException * @throws PackageParsingException + * @throws PathNotFoundException * @throws RunnerExecutionException * @throws SymlinkException * @throws UnsupportedCompilerExtensionException * @throws VersionNotFoundException + * @throws PathNotFoundException */ 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'); $dependent_version = $this->getPackageVersion($dependency->Name, $dependency->Version); if ($dependent_version !== null) + { $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)); $dependency_met = true; @@ -668,8 +708,12 @@ case DependencySourceType::LOCAL: Console::outDebug('installing from local source ' . $dependency->Source); $basedir = dirname($package_path); + 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); RuntimeCache::set(sprintf('dependency_installed.%s=%s', $dependency->Name, $dependency->Version), true); break; @@ -703,7 +747,7 @@ public function getPackage(string $package): ?PackageEntry { 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 { - return $this->getPackageLockManager()->getPackageLock()->getPackages(); + return $this->getPackageLockManager()?->getPackageLock()?->getPackages() ?? []; } /** @@ -765,18 +809,25 @@ $exploded = explode('=', $package); try { + /** @noinspection CallableParameterUseCaseInTypeContextInspection */ $package = $this->getPackage($exploded[0]); - if($package == null) + if($package === null) + { throw new PackageNotFoundException('Package ' . $exploded[0] . ' not found'); + } $version = $package->getVersion($exploded[1]); - if($version == null) + if($version === null) + { throw new VersionNotFoundException('Version ' . $exploded[1] . ' not found for package ' . $exploded[0]); + } 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; + } } } catch(Exception $e) @@ -794,8 +845,10 @@ { foreach ($versions as $version) { - if (!in_array($installed_package . '=' . $version, $packages)) + if (!in_array($installed_package . '=' . $version, $packages, true)) + { $packages[] = $installed_package . '=' . $version; + } } } } @@ -806,26 +859,26 @@ } // Go through each package - foreach($packages as $package) + foreach($packages as $package_iter) { - $package_e = explode('=', $package); + $package_e = explode('=', $package_iter); try { $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'); } else { - $tree[$package] = null; + $tree[$package_iter] = null; if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0) { - $tree[$package] = []; + $tree[$package_iter] = []; foreach($version_entry->Dependencies as $dependency) { $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 * @return void * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException * @throws PackageLockException * @throws PackageNotFoundException @@ -856,18 +908,25 @@ public function uninstallPackageVersion(string $package, string $version): void { if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Insufficient permission to uninstall packages'); + } $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)); + } Console::out(sprintf('Uninstalling %s=%s', $package, $version)); Console::outVerbose(sprintf('Removing package %s=%s from PackageLock', $package, $version)); - if(!$this->getPackageLockManager()->getPackageLock()->removePackageVersion($package, $version)) - Console::outDebug('warning: removing package from package lock failed'); - $this->getPackageLockManager()->save(); + if(!$this->getPackageLockManager()?->getPackageLock()?->removePackageVersion($package, $version)) + { + Console::outDebug('warning: removing package from package lock failed'); + } + + $this->getPackageLockManager()?->save(); Console::outVerbose('Removing package files'); $scanner = new DirectoryScanner(); @@ -903,8 +962,10 @@ $execution_pointer_manager = new ExecutionPointerManager(); foreach($version_entry->ExecutionUnits as $executionUnit) { - if(!$execution_pointer_manager->removeUnit($package, $version, $executionUnit->ExecutionPolicy->Name)) - Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->ExecutionPolicy->Name)); + if(!$execution_pointer_manager->removeUnit($package, $version, $executionUnit->execution_policy->Name)) + { + Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->execution_policy->Name)); + } } } @@ -925,16 +986,26 @@ public function uninstallPackage(string $package): void { if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Insufficient permission to uninstall packages'); + } $package_entry = $this->getPackage($package); - if($package_entry == null) + if($package_entry === null) + { throw new PackageNotFoundException(sprintf('The package %s was not found', $package)); + } foreach($package_entry->getVersions() as $version) { $version_entry = $package_entry->getVersion($version); + if($version_entry === null) + { + Console::outDebug(sprintf('warning: version %s of package %s not found', $version, $package)); + continue; + } + try { $this->uninstallPackageVersion($package, $version_entry->Version); @@ -992,12 +1063,12 @@ */ 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; } } \ No newline at end of file diff --git a/src/ncc/Managers/ProjectManager.php b/src/ncc/Managers/ProjectManager.php index 49db8d3..811901f 100644 --- a/src/ncc/Managers/ProjectManager.php +++ b/src/ncc/Managers/ProjectManager.php @@ -1,27 +1,28 @@ ProjectFilePath = null; - $this->ProjectPath = null; - // Auto-resolve the trailing slash - /** @noinspection PhpStrFunctionsInspection */ - if(substr($path, -1) !== '/') + if(!str_ends_with($path, '/')) { $path .= DIRECTORY_SEPARATOR; } @@ -94,14 +92,16 @@ // Detect if the folder exists or not 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->ProjectFilePath = $path . 'project.json'; + $this->project_path = $path; + $this->project_file_path = $path . 'project.json'; - if(file_exists($this->ProjectFilePath)) + if(file_exists($this->project_file_path)) + { $this->load(); + } } /** @@ -130,71 +130,79 @@ 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 - $this->ProjectConfiguration->Project->Compiler = $compiler; + $this->project_configuration->Project->Compiler = $compiler; // Set the assembly information - $this->ProjectConfiguration->Assembly->Name = $name; - $this->ProjectConfiguration->Assembly->Package = $package; - $this->ProjectConfiguration->Assembly->Version = '1.0.0'; - $this->ProjectConfiguration->Assembly->UUID = Uuid::v1()->toRfc4122(); + $this->project_configuration->Assembly->Name = $name; + $this->project_configuration->Assembly->Package = $package; + $this->project_configuration->Assembly->Version = '1.0.0'; + $this->project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122(); // Set the build information - $this->ProjectConfiguration->Build->SourcePath = $src; - if($this->ProjectConfiguration->Build->SourcePath == null) - $this->ProjectConfiguration->Build->SourcePath = $this->ProjectPath; - $this->ProjectConfiguration->Build->DefaultConfiguration = 'debug'; + $this->project_configuration->Build->SourcePath = $src; + + if($this->project_configuration->Build->SourcePath === null) + { + $this->project_configuration->Build->SourcePath = $this->project_path; + } + + $this->project_configuration->Build->DefaultConfiguration = 'debug'; // Assembly constants if the program wishes to check for this - $this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_NAME'] = '%ASSEMBLY.NAME%'; - $this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_PACKAGE'] = '%ASSEMBLY.PACKAGE%'; - $this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_VERSION'] = '%ASSEMBLY.VERSION%'; - $this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_UID'] = '%ASSEMBLY.UID%'; + $this->project_configuration->Build->DefineConstants['ASSEMBLY_NAME'] = '%ASSEMBLY.NAME%'; + $this->project_configuration->Build->DefineConstants['ASSEMBLY_PACKAGE'] = '%ASSEMBLY.PACKAGE%'; + $this->project_configuration->Build->DefineConstants['ASSEMBLY_VERSION'] = '%ASSEMBLY.VERSION%'; + $this->project_configuration->Build->DefineConstants['ASSEMBLY_UID'] = '%ASSEMBLY.UID%'; // Generate configurations $DebugConfiguration = new ProjectConfiguration\Build\BuildConfiguration(); $DebugConfiguration->Name = 'debug'; $DebugConfiguration->OutputPath = 'build/debug'; $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->Name = 'release'; $ReleaseConfiguration->OutputPath = 'build/release'; $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 - $this->ProjectConfiguration->toFile($this->ProjectPath . DIRECTORY_SEPARATOR . 'project.json'); + // Finally, create project.json + $this->project_configuration->toFile($this->project_path . DIRECTORY_SEPARATOR . 'project.json'); // And create the project directory for additional assets/resources $Folders = [ - $this->ProjectPath . DIRECTORY_SEPARATOR . 'ncc', - $this->ProjectPath . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'cache', - $this->ProjectPath . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'config', + $this->project_path . DIRECTORY_SEPARATOR . 'ncc', + $this->project_path . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'cache', + $this->project_path . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'config', ]; 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 foreach($options as $option) { - if ($option == InitializeProjectOptions::CREATE_SOURCE_DIRECTORY) { - if (!file_exists($this->ProjectConfiguration->Build->SourcePath)) { - mkdir($this->ProjectConfiguration->Build->SourcePath); - } + if ( + $option === InitializeProjectOptions::CREATE_SOURCE_DIRECTORY && + !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 { - if($this->ProjectConfiguration == null) - return false; - - return true; + return $this->project_configuration !== null; } /** @@ -224,10 +229,12 @@ */ public function load(): void { - if(!file_exists($this->ProjectFilePath) && !is_file($this->ProjectFilePath)) - throw new ProjectConfigurationNotFoundException('The project configuration file \'' . $this->ProjectFilePath . '\' was not found'); + if(!file_exists($this->project_file_path) && !is_file($this->project_file_path)) + { + 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 { if(!$this->projectLoaded()) + { return; - $this->ProjectConfiguration->toFile($this->ProjectFilePath); + } + + $this->project_configuration->toFile($this->project_file_path); } /** + * Returns the project's file path. + * * @return string|null */ public function getProjectFilePath(): ?string { - return $this->ProjectFilePath; + return $this->project_file_path; } /** @@ -261,17 +273,22 @@ */ public function getProjectConfiguration(): ?ProjectConfiguration { - if($this->ProjectConfiguration == null) + if($this->project_configuration === null) + { $this->load(); - return $this->ProjectConfiguration; + } + + return $this->project_configuration; } /** + * Returns the project's path. + * * @return string|null */ public function getProjectPath(): ?string { - return $this->ProjectPath; + return $this->project_path; } diff --git a/src/ncc/Managers/RemoteSourcesManager.php b/src/ncc/Managers/RemoteSourcesManager.php index 105907f..306d827 100644 --- a/src/ncc/Managers/RemoteSourcesManager.php +++ b/src/ncc/Managers/RemoteSourcesManager.php @@ -131,7 +131,9 @@ foreach($this->Sources as $source) { if($source->Name === $name) + { return $source; + } } return null; diff --git a/src/ncc/Objects/ExecutionPointers.php b/src/ncc/Objects/ExecutionPointers.php index c1f6a3b..77cff6a 100644 --- a/src/ncc/Objects/ExecutionPointers.php +++ b/src/ncc/Objects/ExecutionPointers.php @@ -1,30 +1,30 @@ Package = $package; - $this->Version = $version; - $this->Pointers = []; + $this->package = $package; + $this->version = $version; + $this->pointers = []; } /** @@ -65,26 +65,30 @@ * @param string $bin_file * @param bool $overwrite * @return bool - * @throws FileNotFoundException + * @throws PathNotFoundException */ public function addUnit(ExecutionUnit $unit, string $bin_file, bool $overwrite=true): bool { if(Validate::exceedsPathLength($bin_file)) + { return false; + } 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) { - $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; } - $this->Pointers[] = new ExecutionPointer($unit, $bin_file); + $this->pointers[] = new ExecutionPointer($unit, $bin_file); return true; } @@ -97,17 +101,22 @@ public function deleteUnit(string $name): bool { $unit = $this->getUnit($name); - if($unit == null) - return false; - $new_pointers = []; - foreach($this->Pointers as $pointer) + if($unit === null) { - if($pointer->ExecutionPolicy->Name !== $name) - $new_pointers[] = $pointer; + return false; } - $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; } @@ -120,10 +129,12 @@ public function getUnit(string $name): ?ExecutionPointer { /** @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 null; @@ -136,7 +147,7 @@ */ public function getPointers(): array { - return $this->Pointers; + return $this->pointers; } /** @@ -146,7 +157,7 @@ */ public function getVersion(): string { - return $this->Version; + return $this->version; } /** @@ -156,7 +167,7 @@ */ public function getPackage(): string { - return $this->Package; + return $this->package; } /** @@ -168,13 +179,13 @@ public function toArray(bool $bytecode=false): array { $pointers = []; - foreach($this->Pointers as $pointer) + foreach($this->pointers as $pointer) { $pointers[] = $pointer->toArray($bytecode); } return [ - ($bytecode ? Functions::cbc('package') : 'package') => $this->Package, - ($bytecode ? Functions::cbc('version') : 'version') => $this->Version, + ($bytecode ? Functions::cbc('package') : 'package') => $this->package, + ($bytecode ? Functions::cbc('version') : 'version') => $this->version, ($bytecode ? Functions::cbc('pointers') : 'pointers') => $pointers ]; } @@ -189,18 +200,18 @@ { $object = new self(); - $object->Version = Functions::array_bc($data, 'version'); - $object->Package = Functions::array_bc($data, 'package'); - $object->Pointers = Functions::array_bc($data, 'pointers'); + $object->version = Functions::array_bc($data, 'version'); + $object->package = Functions::array_bc($data, 'package'); + $object->pointers = Functions::array_bc($data, 'pointers'); - if($object->Pointers !== null) + if($object->pointers !== null) { $pointers = []; - foreach($object->Pointers as $pointer) + foreach($object->pointers as $pointer) { $pointers[] = ExecutionPointer::fromArray($pointer); } - $object->Pointers = $pointers; + $object->pointers = $pointers; } return $object; diff --git a/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php b/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php index e736eca..15adcfb 100644 --- a/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php +++ b/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php @@ -33,21 +33,21 @@ /** * @var string */ - public $ID; + public $id; /** * The execution policy for this execution unit * * @var ExecutionPolicy */ - public $ExecutionPolicy; + public $execution_policy; /** * The file pointer for where the target script should be executed * * @var string */ - public $FilePointer; + public $file_pointer; /** * Public Constructor with optional ExecutionUnit parameter to construct object from @@ -57,12 +57,14 @@ */ public function __construct(?ExecutionUnit $unit=null, ?string $bin_file=null) { - if($unit == null) + if($unit === null) + { return; + } - $this->ID = $unit->getID(); - $this->ExecutionPolicy = $unit->ExecutionPolicy; - $this->FilePointer = $bin_file; + $this->id = $unit->getId(); + $this->execution_policy = $unit->execution_policy; + $this->file_pointer = $bin_file; } /** @@ -74,14 +76,14 @@ public function toArray(bool $bytecode=false): array { return [ - ($bytecode ? Functions::cbc('id') : 'id') => $this->ID, - ($bytecode ? Functions::cbc('execution_policy') : 'execution_policy') => $this->ExecutionPolicy->toArray($bytecode), - ($bytecode ? Functions::cbc('file_pointer') : 'file_pointer') => $this->FilePointer, + ($bytecode ? Functions::cbc('id') : 'id') => $this->id, + ($bytecode ? Functions::cbc('execution_policy') : 'execution_policy') => $this->execution_policy->toArray($bytecode), + ($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 * @return ExecutionPointer @@ -90,12 +92,14 @@ { $object = new self(); - $object->ID = Functions::array_bc($data, 'id'); - $object->ExecutionPolicy = Functions::array_bc($data, 'execution_policy'); - $object->FilePointer = Functions::array_bc($data, 'file_pointer'); + $object->id = Functions::array_bc($data, 'id'); + $object->execution_policy = Functions::array_bc($data, 'execution_policy'); + $object->file_pointer = Functions::array_bc($data, 'file_pointer'); - if($object->ExecutionPolicy !== null) - $object->ExecutionPolicy = ExecutionPolicy::fromArray($object->ExecutionPolicy); + if($object->execution_policy !== null) + { + $object->execution_policy = ExecutionPolicy::fromArray($object->execution_policy); + } return $object; } diff --git a/src/ncc/Objects/NccVersionInformation/Component.php b/src/ncc/Objects/NccVersionInformation/Component.php index 5b97a43..b7c9a7e 100644 --- a/src/ncc/Objects/NccVersionInformation/Component.php +++ b/src/ncc/Objects/NccVersionInformation/Component.php @@ -1,24 +1,24 @@ 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')) + { throw new ComponentVersionNotFoundException('The file \'' . $component_path . 'VERSION' . '\' does not exist'); + } return IO::fread($component_path . 'VERSION'); } @@ -74,27 +74,31 @@ public function toArray(): array { return [ - 'vendor' => $this->Vendor, - 'package_name' => $this->PackageName + 'vendor' => $this->vendor, + 'package_name' => $this->package_name ]; } /** - * Constructs object from an array representation + * Constructs an object from an array representation * * @param array $data * @return Component */ public static function fromArray(array $data): Component { - $ComponentObject = new Component(); + $object = new self(); if(isset($data['vendor'])) - $ComponentObject->Vendor = $data['vendor']; + { + $object->vendor = $data['vendor']; + } if(isset($data['package_name'])) - $ComponentObject->PackageName = $data['package_name']; + { + $object->package_name = $data['package_name']; + } - return $ComponentObject; + return $object; } } \ No newline at end of file diff --git a/src/ncc/Objects/Package.php b/src/ncc/Objects/Package.php index 2ac235d..d636f3e 100644 --- a/src/ncc/Objects/Package.php +++ b/src/ncc/Objects/Package.php @@ -209,7 +209,7 @@ { foreach($this->ExecutionUnits as $unit) { - if($unit->ExecutionPolicy->Name == $name) + if($unit->execution_policy->Name == $name) return $unit; } diff --git a/src/ncc/Objects/Package/Component.php b/src/ncc/Objects/Package/Component.php index 8a464e0..3f18093 100644 --- a/src/ncc/Objects/Package/Component.php +++ b/src/ncc/Objects/Package/Component.php @@ -1,24 +1,24 @@ Checksum === null) + if($this->checksum === null) + { 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 + } - 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 true; } @@ -91,11 +97,11 @@ */ 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 { return [ - ($bytecode ? Functions::cbc('name') : 'name') => $this->Name, - ($bytecode ? Functions::cbc('flags') : 'flags') => $this->Flags, - ($bytecode ? Functions::cbc('data_type') : 'data_type') => $this->DataType, - ($bytecode ? Functions::cbc('checksum') : 'checksum') => $this->Checksum, - ($bytecode ? Functions::cbc('data') : 'data') => $this->Data, + ($bytecode ? Functions::cbc('name') : 'name') => $this->name, + ($bytecode ? Functions::cbc('flags') : 'flags') => $this->flags, + ($bytecode ? Functions::cbc('data_type') : 'data_type') => $this->data_types, + ($bytecode ? Functions::cbc('checksum') : 'checksum') => $this->checksum, + ($bytecode ? Functions::cbc('data') : 'data') => $this->data, ]; } @@ -126,11 +132,11 @@ { $Object = new self(); - $Object->Name = Functions::array_bc($data, 'name'); - $Object->Flags = Functions::array_bc($data, 'flags'); - $Object->DataType = Functions::array_bc($data, 'data_type'); - $Object->Checksum = Functions::array_bc($data, 'checksum'); - $Object->Data = Functions::array_bc($data, 'data'); + $Object->name = Functions::array_bc($data, 'name'); + $Object->flags = Functions::array_bc($data, 'flags'); + $Object->data_types = Functions::array_bc($data, 'data_type'); + $Object->checksum = Functions::array_bc($data, 'checksum'); + $Object->data = Functions::array_bc($data, 'data'); return $Object; } diff --git a/src/ncc/Objects/Package/ExecutionUnit.php b/src/ncc/Objects/Package/ExecutionUnit.php index 997220a..b11a3ae 100644 --- a/src/ncc/Objects/Package/ExecutionUnit.php +++ b/src/ncc/Objects/Package/ExecutionUnit.php @@ -32,14 +32,14 @@ /** * @var string|null */ - private $ID; + private $id; /** * The execution policy for this execution unit * * @var ExecutionPolicy */ - public $ExecutionPolicy; + public $execution_policy; /** * The data of the unit to execute @@ -57,7 +57,7 @@ public function toArray(bool $bytecode=false): array { 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, ]; } @@ -72,11 +72,11 @@ { $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'); - if($object->ExecutionPolicy !== null) - $object->ExecutionPolicy = ExecutionPolicy::fromArray($object->ExecutionPolicy); + if($object->execution_policy !== null) + $object->execution_policy = ExecutionPolicy::fromArray($object->execution_policy); return $object; } @@ -84,11 +84,11 @@ /** * @return string */ - public function getID(): string + public function getId(): string { - if($this->ID == null) - $this->ID = hash('sha1', $this->ExecutionPolicy->Name); - return $this->ID; + if($this->id == null) + $this->id = hash('sha1', $this->execution_policy->Name); + return $this->id; } } \ No newline at end of file diff --git a/src/ncc/Objects/RemotePackageInput.php b/src/ncc/Objects/RemotePackageInput.php index 4ab290c..3948a22 100644 --- a/src/ncc/Objects/RemotePackageInput.php +++ b/src/ncc/Objects/RemotePackageInput.php @@ -24,60 +24,59 @@ namespace ncc\Objects; + use InvalidArgumentException; use ncc\Enums\RegexPatterns; class RemotePackageInput { /** - * @var string|null + * @var string */ - public $Vendor; + public $vendor; + + /** + * @var string + */ + public $package; /** * @var string|null */ - public $Package; + public $version; /** * @var string|null */ - public $Version; + public $branch; /** - * @var string|null + * @var string */ - public $Branch; - - /** - * @var string|null - */ - public $Source; + public $source; /** * Public Constructor & String Parser * * @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']; - $this->Package = $matches['package']; - $this->Version = $matches['version']; - $this->Branch = $matches['branch']; - $this->Source = $matches['source']; + if ($matches['source'] === null || $matches['package'] === null || $matches['vendor'] === null) + { + throw new InvalidArgumentException('Package, version, and source are required.'); + } - if(strlen($this->Vendor) == 0) - $this->Vendor = null; - if(strlen($this->Package) == 0) - $this->Package = null; - if(strlen($this->Version) == 0) - $this->Version = null; - if(strlen($this->Branch) == 0) - $this->Branch = null; - if(strlen($this->Source) == 0) - $this->Source = null; + $this->vendor = $matches['vendor']; + $this->package = $matches['package']; + $this->source = $matches['source']; + $this->version = empty($matches['version']) ? null : $matches['version']; + $this->branch = empty($matches['branch']) ? null : $matches['branch']; + } + else + { + throw new InvalidArgumentException('Input does not match the expected pattern.'); } } @@ -88,19 +87,27 @@ */ public function toString(): string { - if($this->Vendor == null || $this->Package == null) + if($this->vendor === null || $this->package === null) { return ''; } - $results = $this->Vendor . '/' . $this->Package; + $results = $this->vendor . '/' . $this->package; - if($this->Version !== null) - $results .= '=' . $this->Version; - if($this->Branch !== null) - $results .= ':' . $this->Branch; - if($this->Source !== null) - $results .= '@' . $this->Source; + if($this->version !== null) + { + $results .= '=' . $this->version; + } + + if($this->branch !== null) + { + $results .= ':' . $this->branch; + } + + if($this->source !== null) + { + $results .= '@' . $this->source; + } return $results; } @@ -114,7 +121,10 @@ public function toStandard(bool $version=true): string { 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)); } } \ No newline at end of file diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 14dea3c..a99efd7 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -1,28 +1,29 @@ getMessage(), $e); } - - return $json_decoded; } /** @@ -170,39 +165,41 @@ namespace ncc\Utilities; * @param int $flags * @return string * @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) | JSON_UNESCAPED_SLASHES | ($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 - $json = json_encode($value, $flags); - if ($error = json_last_error()) + try { - 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 * - * @param $value + * @param mixed $value * @param string $path * @param int $flags * @return void * @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)); } /** + * Returns the current working directory + * * @param CliHelpSection[] $input * @return int */ @@ -235,7 +232,6 @@ namespace ncc\Utilities; * @param bool $basic_ascii * @return string * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException */ 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 = str_ireplace('%A', $banner_version, $banner); - /** @noinspection PhpUnnecessaryLocalVariableInspection */ - $banner = str_ireplace('%B', $banner_copyright, $banner); - - return $banner; + return str_ireplace('%B', $banner_copyright, $banner); } /** @@ -264,23 +257,25 @@ namespace ncc\Utilities; * current working directory, optionally accepts a different basename using the $basename parameter. * * @param string $path - * @param string|null $basename + * @param string|null $base_name * @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) - $basename = getcwd(); + if($base_name === null) + { + $base_name = getcwd(); + } // Append the trailing slash if it's not already there // "/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" - 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 * @return ExecutionUnit * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException + * @throws PathNotFoundException * @throws RunnerExecutionException */ 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::PHP => PhpRunner::processUnit($path, $policy), Runners::PERL => PerlRunner::processUnit($path, $policy), Runners::PYTHON => PythonRunner::processUnit($path, $policy), Runners::PYTHON_2 => Python2Runner::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'), }; } @@ -354,7 +350,7 @@ namespace ncc\Utilities; { $size = array('B','kB','MB','GB','TB','PB','EB','ZB','YB'); $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 * @throws AccessDeniedException - * @throws InvalidScopeException + * @noinspection PhpRedundantOptionalArgumentInspection */ public static function initializeFiles(): void { if(Resolver::resolveScope() !== Scopes::SYSTEM) + { throw new AccessDeniedException('Cannot initialize NCC files, insufficient permissions'); + } Console::outVerbose('Initializing NCC files'); @@ -381,21 +379,18 @@ namespace ncc\Utilities; if(!$filesystem->exists(PathFinder::getCachePath(Scopes::SYSTEM))) { Console::outDebug(sprintf('Initializing %s', PathFinder::getCachePath(Scopes::SYSTEM))); - /** @noinspection PhpRedundantOptionalArgumentInspection */ $filesystem->mkdir(PathFinder::getCachePath(Scopes::SYSTEM), 0777); } if(!$filesystem->exists(PathFinder::getRunnerPath(Scopes::SYSTEM))) { Console::outDebug(sprintf('Initializing %s', PathFinder::getRunnerPath(Scopes::SYSTEM))); - /** @noinspection PhpRedundantOptionalArgumentInspection */ $filesystem->mkdir(PathFinder::getRunnerPath(Scopes::SYSTEM), 0755); } if(!$filesystem->exists(PathFinder::getPackagesPath(Scopes::SYSTEM))) { Console::outDebug(sprintf('Initializing %s', PathFinder::getPackagesPath(Scopes::SYSTEM))); - /** @noinspection PhpRedundantOptionalArgumentInspection */ $filesystem->mkdir(PathFinder::getPackagesPath(Scopes::SYSTEM), 0755); } @@ -430,14 +425,21 @@ namespace ncc\Utilities; * @param string $path * @return ComposerJson * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException - * @noinspection PhpUnused + * @throws MalformedJsonException */ public static function loadComposerJson(string $path): ComposerJson { $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 { if(is_null($value)) + { return false; + } + if(is_string($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; } @@ -491,8 +487,7 @@ namespace ncc\Utilities; */ public static function getConfigurationProperty(string $property) { - $config_manager = new ConfigurationManager(); - return $config_manager->getProperty($property); + return (new ConfigurationManager())->getProperty($property); } /** @@ -504,9 +499,10 @@ namespace ncc\Utilities; */ public static function parseVersion(string $version): string { - /** @noinspection PhpStrFunctionsInspection */ - if(substr($version, 0, 1) === 'v') + if(str_starts_with(strtolower($version), 'v')) + { $version = substr($version, 1); + } return Parser::parse($version)->toString(); } @@ -517,16 +513,25 @@ namespace ncc\Utilities; * @param int $length * @return string */ - public static function randomString(int $length = 32): string + public static function randomString(int $length=32): string { $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $charactersLength = strlen($characters); - $randomString = ''; - for ($i = 0; $i < $length; $i++) + $characters_length = strlen($characters); + $random_string = ''; + + 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 $set_as_tmp * @return string - * @throws InvalidScopeException */ public static function getTmpDir(bool $create=true, bool $set_as_tmp=true): string { $path = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . self::randomString(16); + if($create) { $filesystem = new Filesystem(); /** @noinspection PhpRedundantOptionalArgumentInspection */ $filesystem->mkdir($path, 0777); } + if($set_as_tmp) + { RuntimeCache::setFileAsTemporary($path); + } + return $path; } /** * Applies the authentication to the given HTTP request. * - * @param HttpRequest $httpRequest + * @param HttpRequest $http_request * @param Entry|null $entry * @param bool $expect_json * @return HttpRequest * @throws AuthenticationException * @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->isCurrentlyDecrypted()) + if(!$entry->isCurrentlyDecrypted()) + { throw new GitlabServiceException('The given Vault entry is not decrypted.'); + } - switch ($entry->getPassword()->getAuthenticationType()) { + switch ($entry->getPassword()?->getAuthenticationType()) + { case AuthenticationType::ACCESS_TOKEN: - $httpRequest->Headers[] = "Authorization: Bearer " . $entry->getPassword(); + $http_request->Headers[] = "Authorization: Bearer " . $entry->getPassword(); break; case AuthenticationType::USERNAME_PASSWORD: @@ -580,11 +592,11 @@ namespace ncc\Utilities; if($expect_json) { - $httpRequest->Headers[] = "Accept: application/json"; - $httpRequest->Headers[] = "Content-Type: application/json"; + $http_request->Headers[] = "Accept: application/json"; + $http_request->Headers[] = "Content-Type: application/json"; } - return $httpRequest; + return $http_request; } /** @@ -595,23 +607,23 @@ namespace ncc\Utilities; * @return string * @throws AuthenticationException * @throws GitlabServiceException - * @throws InvalidScopeException * @throws HttpException */ public static function downloadGitServiceFile(string $url, ?Entry $entry=null): string { if(RuntimeCache::get('download_cache.' . $url) !== null) + { return RuntimeCache::get('download_cache.' . $url); + } - $out_path = Functions::getTmpDir() . "/" . basename($url); - - $httpRequest = new HttpRequest(); - $httpRequest->Url = $url; - $httpRequest->Type = HttpRequestType::GET; - $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); + $out_path = self::getTmpDir() . "/" . basename($url); + $http_request = new HttpRequest(); + $http_request->Url = $url; + $http_request->Type = HttpRequestType::GET; + $http_request = self::prepareGitServiceRequest($http_request, $entry, false); Console::out('Downloading file ' . $url); - HttpClient::download($httpRequest, $out_path); + HttpClient::download($http_request, $out_path); RuntimeCache::set('download_cache.' . $url, $out_path); return $out_path; @@ -632,7 +644,9 @@ namespace ncc\Utilities; $filesystem = new Filesystem(); if(!$filesystem->exists($out_path)) + { $filesystem->mkdir($out_path); + } RuntimeCache::setFileAsTemporary($out_path); @@ -651,13 +665,10 @@ namespace ncc\Utilities; '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) @@ -669,17 +680,16 @@ namespace ncc\Utilities; '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"); + } $command = match ($mimeType) { 'application/zip' => [$unzip_executable, $path, '-d', $out_path], @@ -693,12 +703,15 @@ namespace ncc\Utilities; $process = new Process($command); // display the output of the command - $process->run(function ($type, $buffer) { + $process->run(function ($type, $buffer) + { Console::outVerbose($buffer); }); - if (!$process->isSuccessful()) + if(!$process->isSuccessful()) + { throw new ArchiveException($process->getErrorOutput()); + } return $out_path; } @@ -712,15 +725,19 @@ namespace ncc\Utilities; */ public static function searchDirectory(string $path, array $files): ?string { - if (!is_dir($path)) + if(!is_dir($path)) + { return null; + } // Search files in the given directory recursively $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); foreach ($iterator as $file) { - if (in_array($file->getFilename(), $files)) + if(in_array($file->getFilename(), $files, true)) + { return $file->getPathname(); + } } return null; @@ -734,8 +751,11 @@ namespace ncc\Utilities; */ public static function convertToSemVer($version): string { - if(stripos($version, 'v') === 0) + if(stripos(strtolower($version), 'v') === 0) + { $version = substr($version, 1); + } + if(!Validate::version($version)) { $parts = explode('.', $version); @@ -744,17 +764,28 @@ namespace ncc\Utilities; $patch = (string)null; if(count($parts) >= 1) + { $major = $parts[0]; + } + if(count($parts) >= 2) + { $minor = $parts[1]; + } + if(count($parts) >= 3) + { $patch = $parts[2]; + } // Assemble the SemVer compatible string $version = "$major.$minor.$patch"; } + if(!Validate::version($version)) + { return '1.0.0'; + } return $version; } @@ -803,8 +834,11 @@ namespace ncc\Utilities; $results->ReleaseName = ($release_results->ReleaseName ?? null); $results->ReleaseDescription = ($release_results->ReleaseDescription ?? null); $results->Files = self::mergeFilesResults($release_results->Files, ($results->Files ?? null)); + if($release_results->Version !== null) + { $results->Version = $release_results->Version; + } } try @@ -819,27 +853,31 @@ namespace ncc\Utilities; if($git_results !== null) { - if($results->ReleaseName == null) + if($results->ReleaseName === null) { $results->ReleaseName = ($git_results->ReleaseName ?? null); } elseif($git_results->ReleaseName !== null) { if(strlen($git_results->ReleaseName) > strlen($results->ReleaseName)) + { $results->ReleaseName = $git_results->ReleaseName; + } } - if($results->ReleaseDescription == null) + if($results->ReleaseDescription === null) { $results->ReleaseDescription = ($git_results->ReleaseDescription ?? null); } elseif($git_results->ReleaseDescription !== null) { if(strlen($git_results->ReleaseDescription) > strlen($results->ReleaseDescription)) + { $results->ReleaseDescription = $git_results->ReleaseDescription; + } } - if($results->Version == null) + if($results->Version === null) { $results->Version = ($git_results->Version ?? null); } @@ -847,7 +885,9 @@ namespace ncc\Utilities; { // Version compare if(VersionComparator::compareVersion($git_results->Version, $results->Version) > 0) + { $results->Version = $git_results->Version; + } } $results->Files = self::mergeFilesResults($git_results->Files, ($results->Files ?? null)); @@ -865,27 +905,31 @@ namespace ncc\Utilities; if($ncc_package_results !== null) { - if($results->ReleaseName == null) + if($results->ReleaseName === null) { $results->ReleaseName = ($ncc_package_results->ReleaseName ?? null); } elseif($ncc_package_results->ReleaseName !== null) { if(strlen($ncc_package_results->ReleaseName) > strlen($results->ReleaseName)) + { $results->ReleaseName = $ncc_package_results->ReleaseName; + } } - if($results->ReleaseDescription == null) + if($results->ReleaseDescription === null) { $results->ReleaseDescription = ($ncc_package_results->ReleaseDescription ?? null); } elseif($ncc_package_results->ReleaseDescription !== null) { if(strlen($ncc_package_results->ReleaseDescription) > strlen($results->ReleaseDescription)) + { $results->ReleaseDescription = $ncc_package_results->ReleaseDescription; + } } - if($results->Version == null) + if($results->Version === null) { $results->Version = ($ncc_package_results->Version ?? null); } @@ -893,7 +937,9 @@ namespace ncc\Utilities; { // Version compare if(VersionComparator::compareVersion($ncc_package_results->Version, $results->Version) > 0) + { $results->Version = $ncc_package_results->Version; + } } $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|null $selected @@ -911,26 +957,40 @@ namespace ncc\Utilities; */ private static function mergeFilesResults(RepositoryQueryResults\Files $input, ?RepositoryQueryResults\Files $selected=null): RepositoryQueryResults\Files { - if($selected == null) + if($selected === null) + { $selected = new RepositoryQueryResults\Files(); + } if($input->GitSshUrl !== null) + { $selected->GitSshUrl = $input->GitSshUrl; + } if($input->GitHttpUrl !== null) + { $selected->GitHttpUrl = $input->GitHttpUrl; + } if($input->SourceUrl !== null) + { $selected->SourceUrl = $input->SourceUrl; + } if($input->TarballUrl !== null) + { $selected->TarballUrl = $input->TarballUrl; + } if($input->ZipballUrl !== null) + { $selected->ZipballUrl = $input->ZipballUrl; + } if($input->PackageUrl !== null) + { $selected->PackageUrl = $input->PackageUrl; + } return $selected; } @@ -946,10 +1006,14 @@ namespace ncc\Utilities; if (is_numeric($input)) { if (str_contains($input, '.')) + { return (float)$input; + } if (ctype_digit($input)) + { return (int)$input; + } } elseif (in_array(strtolower($input), ['true', 'false'])) { @@ -963,12 +1027,13 @@ namespace ncc\Utilities; * Finalizes the permissions * * @return void - * @throws InvalidScopeException */ public static function finalizePermissions(): void { if(Resolver::resolveScope() !== Scopes::SYSTEM) + { return; + } Console::outVerbose('Finalizing permissions...'); $filesystem = new Filesystem(); @@ -976,7 +1041,9 @@ namespace ncc\Utilities; try { if($filesystem->exists(PathFinder::getDataPath(Scopes::SYSTEM))) + { $filesystem->chmod(PathFinder::getDataPath(Scopes::SYSTEM), 0777, 0000, true); + } } catch(Exception $e) { @@ -986,7 +1053,9 @@ namespace ncc\Utilities; try { if($filesystem->exists(PathFinder::getCachePath(Scopes::SYSTEM))) + { $filesystem->chmod(PathFinder::getCachePath(Scopes::SYSTEM), 0777, 0000, true); + } } catch(Exception $e) { @@ -1003,10 +1072,14 @@ namespace ncc\Utilities; public static function isTtyMode(): bool { if(!is_null(RuntimeCache::get('posix_isatty'))) + { return RuntimeCache::get('posix_isatty'); + } if(function_exists('posix_isatty') === false) + { return false; + } RuntimeCache::set('posix_isatty', posix_isatty(STDOUT)); return (bool)RuntimeCache::get('posix_isatty'); diff --git a/src/ncc/Utilities/IO.php b/src/ncc/Utilities/IO.php index 13d76ea..db05339 100644 --- a/src/ncc/Utilities/IO.php +++ b/src/ncc/Utilities/IO.php @@ -1,30 +1,30 @@ flock(LOCK_EX | LOCK_NB)) { 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)); } - elseif (!$file->flock(LOCK_UN)) + + if (!$file->flock(LOCK_UN)) { 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)); } @@ -78,8 +82,8 @@ namespace ncc\Utilities; * @param int|null $length * @return string * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException + * @throws PathNotFoundException */ public static function fread(string $uri, string $mode='r', ?int $length=null): string { @@ -92,21 +96,27 @@ namespace ncc\Utilities; if(!file_exists($uri)) { - throw new FileNotFoundException(sprintf('Cannot find file %s', $uri)); + throw new PathNotFoundException($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); - if($length == null) + if($length === null) { + /** @noinspection CallableParameterUseCaseInTypeContextInspection */ $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; } diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index 8cf99b7..615f0c0 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -22,6 +22,7 @@ namespace ncc\Utilities; + use InvalidArgumentException; use ncc\Enums\Scopes; use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidScopeException; @@ -33,41 +34,21 @@ namespace ncc\Utilities; /** * Returns the root path of the system * - * @param bool $win32 * @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); } - /** - * 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 * * @param string $scope - * @param bool $win32 * @return string * @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); @@ -76,17 +57,6 @@ namespace ncc\Utilities; 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) { case Scopes::USER: @@ -104,30 +74,17 @@ namespace ncc\Utilities; * Returns the path where all NCC installation data is stored * * @param string $scope - * @param bool $win32 * @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); 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) { case Scopes::USER: @@ -138,98 +95,84 @@ namespace ncc\Utilities; 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 * * @param string $scope - * @param bool $win32 * @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 * * @param string $scope - * @param bool $win32 * @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 * * @param string $scope - * @param bool $win32 * @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 * * @param string $scope - * @param bool $win32 * @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 bool $win32 * @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 bool $win32 * @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) * - * @param bool $win32 * @return array - * @throws InvalidScopeException */ - public static function getPackageLockFiles(bool $win32=false): array + public static function getPackageLockFiles(): array { $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; @@ -241,12 +184,13 @@ namespace ncc\Utilities; * @param string $package * @return string * @throws InvalidPackageNameException - * @throws InvalidScopeException */ public static function getPackageDataPath(string $package): string { if(!Validate::packageName($package)) + { throw new InvalidPackageNameException($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 * * @param string $scope - * @param bool $win32 * @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) * * @return string - * @throws InvalidScopeException */ public static function getConfigurationFile(): string { @@ -290,15 +231,18 @@ namespace ncc\Utilities; if($config_value !== null) { if(file_exists($config_value) && is_executable($config_value)) + { return $config_value; - + } Console::outWarning(sprintf('The configured \'%s\' executable path is invalid, trying to find it automatically...', $runner)); } $exec_path = $executable_finder->find($runner); if($exec_path !== null) + { return $exec_path; + } throw new RunnerExecutionException(sprintf('Unable to find \'%s\' executable', $runner)); } diff --git a/src/ncc/ncc.php b/src/ncc/ncc.php index 72e609f..e34f78f 100644 --- a/src/ncc/ncc.php +++ b/src/ncc/ncc.php @@ -1,31 +1,34 @@ 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 * @throws AccessDeniedException - * @throws FileNotFoundException * @throws IOException - * @throws RuntimeException + * @throws PathNotFoundException */ public static function initialize(): bool { if(defined('NCC_INIT')) + { return false; - + } + // Set debugging/troubleshooting constants 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 @@ -130,27 +127,20 @@ namespace ncc; */ public static function cliMode(): bool { - // TODO: Optimize this function to reduce redundant calls - - if(defined('NCC_CLI_MODE') && NCC_CLI_MODE == 1) - { - return true; - } - - return false; + return defined('NCC_CLI_MODE') && NCC_CLI_MODE === 1; } /** * Returns the constants set by NCC * * @return array - * @throws RuntimeException */ public static function getConstants(): array { 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 [