diff --git a/CHANGELOG.md b/CHANGELOG.md index 179f2bc..ba946fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -329,6 +329,7 @@ features. This is the Mk II of ncc, and it is a major update, so please read the - Removed runners `Python2` & `Python3` in favor of `Python` - Removed `\ncc\Classes\NccExtension > Runner` in favor of the new Execution Unit system - Removed `\ncc\Managers > ExecutionPointerManager` in favor of the new Execution Unit system + - Removed checksum properties from Component & Resource since they are unused diff --git a/src/ncc/CLI/Commands/BuildCommand.php b/src/ncc/CLI/Commands/BuildCommand.php index 5dcfb16..f7d9384 100644 --- a/src/ncc/CLI/Commands/BuildCommand.php +++ b/src/ncc/CLI/Commands/BuildCommand.php @@ -23,6 +23,7 @@ namespace ncc\CLI\Commands; use Exception; + use ncc\Enums\Options\BuildConfigurationOptions; use ncc\Enums\Options\BuildConfigurationValues; use ncc\Managers\ProjectManager; use ncc\Objects\CliHelpSection; @@ -69,6 +70,15 @@ return 1; } + $output_path = $args['output'] ?? $args['o'] ?? null; + $options = []; + + if($output_path !== null) + { + $options[BuildConfigurationOptions::OUTPUT_FILE] = $output_path; + } + + // Load the project try { @@ -83,8 +93,8 @@ // Build the project try { - $build_configuration = $args['config'] ?? BuildConfigurationValues::DEFAULT; - $output = $project_manager->build($build_configuration); + $build_configuration = $args['config'] ?? $args['c'] ?? BuildConfigurationValues::DEFAULT; + $output = $project_manager->build($build_configuration, $options); } catch (Exception $e) { @@ -104,10 +114,11 @@ private static function displayOptions(): int { $options = [ - new CliHelpSection(['help'], 'Displays this help menu about the value command'), - new CliHelpSection(['build'], 'Builds the current project using the default build configuration'), - new CliHelpSection(['build', '--path', '-p'], 'Builds the project in the specified path that contains project.json'), - new CliHelpSection(['build', '--config'], 'Builds the current project with a specified build configuration') + new CliHelpSection(['build'], 'Builds the current project'), + new CliHelpSection(['--help'], 'Displays this help menu about the value command'), + new CliHelpSection(['--path', '-p'], 'Specifies the path to the project where project.json is located (or the file itself), default: current working directory'), + new CliHelpSection(['--config', '-c'], 'Specifies the build configuration to use, default: default build configuration'), + new CliHelpSection(['--output', '-o'], 'Specifies the output path of the build, default: build configuration specified output path'), ]; $options_padding = Functions::detectParametersPadding($options) + 4; diff --git a/src/ncc/CLI/Commands/PackageInspectorCommand.php b/src/ncc/CLI/Commands/PackageInspectorCommand.php new file mode 100644 index 0000000..c903e8b --- /dev/null +++ b/src/ncc/CLI/Commands/PackageInspectorCommand.php @@ -0,0 +1,296 @@ +getMessage()), $e, 1); + return 1; + } + } + + if(isset($args['metadata'])) + { + try + { + return self::displayMetadata($args); + } + catch(Exception $e) + { + Console::outException(sprintf('Failed to display metadata: %s', $e->getMessage()), $e, 1); + return 1; + } + } + + if(isset($args['assembly'])) + { + try + { + return self::displayAssembly($args); + } + catch(Exception $e) + { + Console::outException(sprintf('Failed to display assembly: %s', $e->getMessage()), $e, 1); + return 1; + } + } + + if(isset($args['dependencies'])) + { + try + { + return self::displayDependencies($args); + } + catch(Exception $e) + { + Console::outException(sprintf('Failed to display dependencies: %s', $e->getMessage()), $e, 1); + return 1; + } + } + + if(isset($args['execution_units'])) + { + try + { + return self::displayExecutionUnits($args); + } + catch(Exception $e) + { + Console::outException(sprintf('Failed to display execution units: %s', $e->getMessage()), $e, 1); + return 1; + } + } + + return self::displayOptions(); + } + + /** + * Displays the headers section of the package + * + * @param array $args + * @return int + * @throws IOException + */ + private static function displayHeaders(array $args): int + { + self::printArray((new PackageReader($args['path'] ?? $args['p']))->getHeaders(), + isset($args['json']), isset($args['json-pretty']) + ); + + return 0; + } + + /** + * Displays the assembly section + * + * @param array $args + * @return int + * @throws ConfigurationException + * @throws IOException + */ + private static function displayAssembly(array $args): int + { + self::printArray((new PackageReader($args['path'] ?? $args['p']))->getAssembly()->toArray(), + isset($args['json']), isset($args['json-pretty']) + ); + + return 0; + } + + /** + * Displays the metadata section + * + * @param array $args + * @return int + * @throws IOException + * @throws ConfigurationException + */ + private static function displayMetadata(array $args): int + { + self::printArray((new PackageReader($args['path'] ?? $args['p']))->getMetadata()->toArray(), + isset($args['json']), isset($args['json-pretty']) + ); + + return 0; + } + + /** + * Displays the dependencies section of the package + * + * @param array $args + * @return int + * @throws ConfigurationException + * @throws IOException + */ + private static function displayDependencies(array $args): int + { + $package_reader = new PackageReader($args['path'] ?? $args['p']); + $dependencies = array_map(static function($dependency) use ($package_reader) + { + return $package_reader->getDependency($dependency)->toArray(); + }, $package_reader->getDependencies()); + + if(count($dependencies) === 0) + { + Console::outError('No dependencies found', true, 1); + return 1; + } + + self::printArray($dependencies, isset($args['json']), isset($args['json-pretty'])); + return 0; + } + + /** + * Displays the execution units section of the package + * + * @param array $args + * @return int + * @throws ConfigurationException + * @throws IOException + */ + private static function displayExecutionUnits(array $args): int + { + $package_reader = new PackageReader($args['path'] ?? $args['p']); + $execution_units = array_map(static function($execution_unit) use ($package_reader) + { + return $package_reader->getExecutionUnit($execution_unit)->toArray(); + }, $package_reader->getExecutionUnits()); + + if(count($execution_units) === 0) + { + Console::outError('No execution units found', true, 1); + return 1; + } + + self::printArray($execution_units, isset($args['json']), isset($args['json-pretty'])); + return 0; + } + + /** + * Prints out an array in a specific format + * + * @param array $data + * @param bool $is_json + * @param bool $pretty_json + * @return void + */ + private static function printArray(array $data, bool $is_json, bool $pretty_json): void + { + if($is_json) + { + try + { + Console::out(json_encode($data, JSON_THROW_ON_ERROR)); + return; + } + catch(Exception $e) + { + Console::outException(sprintf('Failed to display headers: %s', $e->getMessage()), $e, 1); + return; + } + } + + if($pretty_json) + { + try + { + Console::out(json_encode($data, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT)); + return; + } + catch(Exception $e) + { + Console::outException(sprintf('Failed to display headers: %s', $e->getMessage()), $e, 1); + return; + } + } + + Console::out(Yaml::dump($data, 4, 2), false); + } + + /** + * Displays the main options section + * + * @return int + */ + private static function displayOptions(): int + { + $options = [ + new CliHelpSection(['help'], 'Displays this help menu about the value command'), + new CliHelpSection(['--path', '-p'], 'Required. Specifies the path to the binary package to inspect'), + new CliHelpSection(['--json'], 'Prints out the information of the package in JSON format'), + new CliHelpSection(['--pretty-json'], 'Prints out the information of the package in pretty JSON format'), + new CliHelpSection(['headers'], 'Prints out the headers of the package'), + new CliHelpSection(['metadata'], 'Prints out the metadata of the package'), + new CliHelpSection(['assembly'], 'Prints out the assembly information of the package'), + new CliHelpSection(['dependencies'], 'Prints out the dependencies of the package'), + new CliHelpSection(['execution_units'], 'Prints out the execution units of the package'), + ]; + + $options_padding = Functions::detectParametersPadding($options) + 4; + + Console::out('Usage: ncc ins [command] [options]'); + Console::out('Options:' . PHP_EOL); + foreach($options as $option) + { + Console::out(' ' . $option->toString($options_padding)); + } + + return 0; + } + } \ No newline at end of file diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index 0144814..8b58719 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -94,7 +94,7 @@ new CliHelpSection(['package', 'pkg'], 'Manages the package system'), new CliHelpSection(['cred'], 'Manages credentials'), new CliHelpSection(['config'], 'Changes ncc configuration values'), - new CliHelpSection(['repo'], 'Manages/Configure repositories'), + new CliHelpSection(['repository', 'repo'], 'Manages/Configure repositories'), ]); } @@ -108,7 +108,8 @@ Console::out('Commands:'); Console::outHelpSections([ new CliHelpSection(['build'], 'Builds the current project'), - new CliHelpSection(['exec'], 'Executes the main entrypoint of a package') + new CliHelpSection(['exec'], 'Executes the main entrypoint of a package'), + new CliHelpSection(['ins'], 'Package inspector command, various options to inspect a package'), ]); } } \ No newline at end of file diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index d45227e..3711509 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -28,6 +28,7 @@ use ncc\Classes\ShutdownHandler; use ncc\CLI\Commands\BuildCommand; use ncc\CLI\Commands\ExecCommand; + use ncc\CLI\Commands\PackageInspectorCommand; use ncc\CLI\Management\ConfigMenu; use ncc\CLI\Management\CredentialMenu; use ncc\CLI\Management\PackageManagerMenu; @@ -148,6 +149,9 @@ case 'build': return BuildCommand::start(self::$args); + case 'ins': + return PackageInspectorCommand::start(self::$args); + case 'exec': return ExecCommand::start(self::$args); @@ -162,6 +166,7 @@ return ConfigMenu::start(self::$args); case 'repo': + case 'repository': return RepositoryMenu::start(self::$args); case 'version': diff --git a/src/ncc/Classes/ArchiveExtractor.php b/src/ncc/Classes/ArchiveExtractor.php index 8144307..442c091 100644 --- a/src/ncc/Classes/ArchiveExtractor.php +++ b/src/ncc/Classes/ArchiveExtractor.php @@ -26,6 +26,7 @@ use finfo; use ncc\Exceptions\IOException; use ncc\Exceptions\NotSupportedException; + use ncc\Utilities\Console; use PharData; use RuntimeException; use ZipArchive; @@ -59,11 +60,13 @@ switch($mime) { case 'application/zip': + Console::outDebug(sprintf('Extracting zip archive "%s" to "%s"', $archive_path, $directory_path)); self::extractZip($archive_path, $directory_path); break; case 'application/x-tar': case 'application/x-gzip': + Console::outDebug(sprintf('Extracting tar archive "%s" to "%s"', $archive_path, $directory_path)); $phar = new PharData($archive_path); $phar->extractTo($directory_path); break; @@ -84,6 +87,7 @@ private static function extractZip(string $archive_path, string $directory_path): void { $zip_archive = new ZipArchive(); + Console::outDebug(sprintf('Opening zip archive "%s"', $archive_path)); if(!$zip_archive->open($archive_path)) { @@ -102,6 +106,7 @@ if(str_ends_with($entry_name, '/')) { $concurrent_directory = $directory_path . DIRECTORY_SEPARATOR . $entry_name; + Console::outDebug(sprintf('Creating directory "%s"', $concurrent_directory)); if(!is_dir($concurrent_directory) && !mkdir($concurrent_directory, 0777, true) && !is_dir($concurrent_directory)) { throw new RuntimeException(sprintf('Directory "%s" was not created', $concurrent_directory)); @@ -112,6 +117,7 @@ try { + Console::outDebug(sprintf('Extracting file "%s" from archive "%s"', $entry_name, $archive_path)); $zip_archive->extractTo($directory_path, $entry_name); } catch(Exception $e) diff --git a/src/ncc/Classes/GiteaExtension/GiteaRepository.php b/src/ncc/Classes/GiteaExtension/GiteaRepository.php index f9bbed9..ec762de 100644 --- a/src/ncc/Classes/GiteaExtension/GiteaRepository.php +++ b/src/ncc/Classes/GiteaExtension/GiteaRepository.php @@ -37,6 +37,7 @@ use ncc\Objects\RepositoryResult; use ncc\Objects\Vault\Password\AccessToken; use ncc\Objects\Vault\Password\UsernamePassword; + use ncc\Utilities\Console; use RuntimeException; class GiteaRepository implements RepositoryInterface @@ -44,7 +45,7 @@ /** * @inheritDoc */ - public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult + public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult { try { @@ -61,7 +62,7 @@ /** * @inheritDoc */ - public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult + public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult { return self::getReleasePackage($repository, $vendor, $project, $version, $authentication); } @@ -93,12 +94,15 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers + ]); $results = []; + Console::outDebug(sprintf('Fetching tags for %s/%s from %s', $group, $project, $endpoint)); foreach(self::processHttpResponse($curl, $group, $project) as $tag) { if(isset($tag['name'])) @@ -167,11 +171,14 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers + ]); + Console::outDebug(sprintf('Fetching tag archive for %s/%s/%s from %s', $group, $project, $tag, $endpoint)); $response = self::processHttpResponse($curl, $group, $project); if(isset($response['zipball_url'])) @@ -214,12 +221,15 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers + ]); $results = []; + Console::outDebug(sprintf('Fetching releases for %s/%s from %s', $group, $project, $endpoint)); foreach(self::processHttpResponse($curl, $group, $project) as $release) { if(isset($release['tag_name'])) @@ -288,11 +298,14 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers + ]); + Console::outDebug(sprintf('Fetching release package for %s/%s/%s from %s', $group, $project, $release, $endpoint)); $response = self::processHttpResponse($curl, $group, $project); if(!isset($response['assets'])) @@ -346,11 +359,14 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers + ]); + Console::outDebug(sprintf('Fetching release archive for %s/%s/%s from %s', $group, $project, $release, $endpoint)); $response = self::processHttpResponse($curl, $group, $project); if(isset($response['zipball_url'])) diff --git a/src/ncc/Classes/GithubExtension/GithubRepository.php b/src/ncc/Classes/GithubExtension/GithubRepository.php index a9b9c0e..1ee618b 100644 --- a/src/ncc/Classes/GithubExtension/GithubRepository.php +++ b/src/ncc/Classes/GithubExtension/GithubRepository.php @@ -37,6 +37,7 @@ use ncc\Objects\RepositoryResult; use ncc\Objects\Vault\Password\AccessToken; use ncc\Objects\Vault\Password\UsernamePassword; + use ncc\Utilities\Console; use RuntimeException; class GithubRepository implements RepositoryInterface @@ -44,7 +45,7 @@ /** * @inheritDoc */ - public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult + public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult { try { @@ -99,6 +100,7 @@ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); $results = []; + Console::outDebug(sprintf('Fetching tags for %s/%s from %s', $group, $project, $endpoint)); foreach(self::processHttpResponse($curl, $group, $project) as $tag) { if(isset($tag['name'])) @@ -172,6 +174,8 @@ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + Console::outDebug(sprintf('Fetching tag archive for %s/%s/%s from %s', $group, $project, $tag, $endpoint)); + $response = curl_exec($curl); if ($response === false) @@ -221,6 +225,8 @@ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + Console::outDebug(sprintf('Fetching releases for %s/%s from %s', $group, $project, $endpoint)); + $results = []; foreach(self::processHttpResponse($curl, $group, $project) as $release) { @@ -295,6 +301,7 @@ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + Console::outDebug(sprintf('Fetching release package for %s/%s/%s from %s', $group, $project, $release, $endpoint)); $response = self::processHttpResponse($curl, $group, $project); if(!isset($response['assets'])) @@ -353,6 +360,8 @@ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + Console::outDebug(sprintf('Fetching release archive for %s/%s/%s from %s', $group, $project, $release, $endpoint)); + $response = self::processHttpResponse($curl, $group, $project); if(isset($response['zipball_url'])) diff --git a/src/ncc/Classes/GitlabExtension/GitlabRepository.php b/src/ncc/Classes/GitlabExtension/GitlabRepository.php index bae83f7..303bb91 100644 --- a/src/ncc/Classes/GitlabExtension/GitlabRepository.php +++ b/src/ncc/Classes/GitlabExtension/GitlabRepository.php @@ -37,6 +37,7 @@ use ncc\Objects\RepositoryResult; use ncc\Objects\Vault\Password\AccessToken; use ncc\Objects\Vault\Password\UsernamePassword; + use ncc\Utilities\Console; use RuntimeException; class GitlabRepository implements RepositoryInterface @@ -93,10 +94,14 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers + ]); + + Console::outDebug(sprintf('Fetching tags for %s/%s from %s', $group, $project, $endpoint)); $results = []; foreach(self::processHttpResponse($curl, $group, $project) as $tag) @@ -165,13 +170,16 @@ $headers = self::injectAuthentication($authentication, $curl, $headers); } - curl_setopt($curl, CURLOPT_URL, $endpoint); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_NOBODY, true); - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET); - curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt_array($curl, [ + CURLOPT_URL => $endpoint, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_NOBODY => true, + CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, + CURLOPT_HTTPHEADER => $headers, + CURLOPT_FOLLOWLOCATION => true + ]); + Console::outDebug(sprintf('Fetching tag archive for %s/%s/%s from %s', $group, $project, $tag, $endpoint)); $response = curl_exec($curl); if ($response === false) diff --git a/src/ncc/Classes/NccExtension/ConstantCompiler.php b/src/ncc/Classes/NccExtension/ConstantCompiler.php index 775ff75..c485856 100644 --- a/src/ncc/Classes/NccExtension/ConstantCompiler.php +++ b/src/ncc/Classes/NccExtension/ConstantCompiler.php @@ -30,6 +30,7 @@ use ncc\Objects\InstallationPaths; use ncc\Objects\ProjectConfiguration; use ncc\Objects\ProjectConfiguration\Assembly; + use ncc\Utilities\Console; class ConstantCompiler { @@ -100,7 +101,7 @@ if($assembly->getTrademark() !== null) { - $input =str_replace(AssemblyConstants::ASSEMBLY_TRADEMARK, $assembly->getTrademark(), $input); + $input = str_replace(AssemblyConstants::ASSEMBLY_TRADEMARK, $assembly->getTrademark(), $input); } return $input; } @@ -258,26 +259,46 @@ { $input = str_replace(RuntimeConstants::CWD, getcwd(), $input); } + else + { + Console::outWarning('Cannot compile RuntimeConstants::CWD, getcwd() is not available'); + } if(function_exists('getmypid')) { $input = str_replace(RuntimeConstants::PID, getmypid(), $input); } + else + { + Console::outWarning('Cannot compile RuntimeConstants::PID, getmypid() is not available'); + } if(function_exists('getmyuid')) { $input = str_replace(RuntimeConstants::UID, getmyuid(), $input); } + else + { + Console::outWarning('Cannot compile RuntimeConstants::UID, getmyuid() is not available'); + } if(function_exists('getmygid')) { $input = str_replace(RuntimeConstants::GID, getmygid(), $input); } + else + { + Console::outWarning('Cannot compile RuntimeConstants::GID, getmygid() is not available'); + } if(function_exists('get_current_user')) { $input = str_replace(RuntimeConstants::USER, get_current_user(), $input); } + else + { + Console::outWarning('Cannot compile RuntimeConstants::USER, get_current_user() is not available'); + } return $input; } diff --git a/src/ncc/Classes/NccExtension/NccCompiler.php b/src/ncc/Classes/NccExtension/NccCompiler.php index d21e5ec..c408b7c 100644 --- a/src/ncc/Classes/NccExtension/NccCompiler.php +++ b/src/ncc/Classes/NccExtension/NccCompiler.php @@ -38,7 +38,9 @@ use ncc\Exceptions\PathNotFoundException; use ncc\Interfaces\CompilerInterface; use ncc\Managers\ProjectManager; - use ncc\Objects\Package; + use ncc\Objects\Package\Component; + use ncc\Objects\Package\Metadata; + use ncc\Objects\Package\Resource; use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration; use ncc\Utilities\Base64; use ncc\Utilities\Console; @@ -81,10 +83,37 @@ * @throws PathNotFoundException * @noinspection UnusedFunctionResultInspection */ - public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string + public function build(string $build_configuration=BuildConfigurationValues::DEFAULT, array $options=[]): string { $configuration = $this->project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration); - $package_path = $configuration->getOutputPath() . DIRECTORY_SEPARATOR . $this->project_manager->getProjectConfiguration()->getAssembly()->getPackage() . '.ncc'; + $configuration->setOptions(array_merge($configuration->getOptions(), $options)); + + if(count($options) > 0) + { + $configuration->setOptions(array_merge($configuration->getOptions(), $options)); + } + + if($configuration->getOutputName() !== null) + { + $package_path = + ConstantCompiler::compileConstants($this->project_manager->getProjectConfiguration(), $configuration->getOutputPath()) + . DIRECTORY_SEPARATOR . + ConstantCompiler::compileConstants($this->project_manager->getProjectConfiguration(), $configuration->getOutputName()); + } + elseif(isset($configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE])) + { + $package_path = ConstantCompiler::compileConstants( + $this->project_manager->getProjectConfiguration(), $configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE] + ); + } + else + { + $package_path = + ConstantCompiler::compileConstants($this->project_manager->getProjectConfiguration(), $configuration->getOutputPath()) + . DIRECTORY_SEPARATOR . + ConstantCompiler::compileConstants($this->project_manager->getProjectConfiguration(), $this->project_manager->getProjectConfiguration()->getAssembly()->getPackage() . '.ncc'); + } + $progress = 0; $steps = count($this->project_manager->getProjectConfiguration()->getExecutionPolicies()) + @@ -92,6 +121,7 @@ count($this->project_manager->getResources($build_configuration)); $package_writer = $this->createPackageWriter($package_path, $configuration); + Console::out(sprintf('Building project \'%s\'', $this->project_manager->getProjectConfiguration()->getAssembly()->getName())); // Debugging information @@ -227,7 +257,7 @@ */ public function processComponent(PackageWriter $package_writer, string $file_path): void { - $package_writer->addComponent(new Package\Component( + $package_writer->addComponent(new Component( Functions::removeBasename($file_path, $this->project_manager->getProjectPath()), Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED )); @@ -245,7 +275,7 @@ */ public function processResource(PackageWriter $package_writer, string $file_path): void { - $package_writer->addResource(new Package\Resource( + $package_writer->addResource(new Resource( Functions::removeBasename($file_path, $this->project_manager->getProjectPath()), IO::fread($file_path) )); } @@ -257,19 +287,17 @@ * @param string $build_configuration * @return void * @throws ConfigurationException - * @throws IOException - * @noinspection UnusedFunctionResultInspection */ public function processMetadata(PackageWriter $package_writer, string $build_configuration=BuildConfigurationValues::DEFAULT): void { - $metadata = new Package\Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler()); + $metadata = new Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler()); - $metadata->setRuntimeConstants($this->project_manager->getRuntimeConstants($build_configuration)); $metadata->setOptions($this->project_manager->getCompilerOptions($build_configuration)); $metadata->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource()); $metadata->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain()); $metadata->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller()); + /** @noinspection UnusedFunctionResultInspection */ $package_writer->setMetadata($metadata); } } \ No newline at end of file diff --git a/src/ncc/Classes/PackageReader.php b/src/ncc/Classes/PackageReader.php index 6b003a2..587023f 100644 --- a/src/ncc/Classes/PackageReader.php +++ b/src/ncc/Classes/PackageReader.php @@ -482,6 +482,11 @@ return $components; } + /** + * Returns the package's class map + * + * @return array + */ public function getClassMap(): array { $class_map = []; diff --git a/src/ncc/Classes/PhpExtension/ExecutableCompiler.php b/src/ncc/Classes/PhpExtension/ExecutableCompiler.php index 2db5b5c..619fe36 100644 --- a/src/ncc/Classes/PhpExtension/ExecutableCompiler.php +++ b/src/ncc/Classes/PhpExtension/ExecutableCompiler.php @@ -22,6 +22,7 @@ namespace ncc\Classes\PhpExtension; + use ncc\Classes\NccExtension\ConstantCompiler; use ncc\CLI\Main; use ncc\Enums\LogLevel; use ncc\Enums\Options\BuildConfigurationOptions; @@ -39,10 +40,15 @@ * @inheritDoc * @throws BuildException */ - public function build(string $build_configuration = BuildConfigurationValues::DEFAULT): string + public function build(string $build_configuration = BuildConfigurationValues::DEFAULT, array $options=[]): string { $configuration = $this->getProjectManager()->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration); + if(count($options) > 0) + { + $configuration->setOptions(array_merge($configuration->getOptions(), $options)); + } + if(!isset($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION])) { throw new BuildException(sprintf("Unable to compile the binary, the build configuration '%s' does not have a ncc_configuration.", $build_configuration)); @@ -53,18 +59,39 @@ $ncc_package = parent::build($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION]); // Prepare the ncc package for compilation - $hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c'; + $hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . $this->getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c'; if(is_file($hex_dump_file)) { unlink($hex_dump_file); } Console::outVerbose(sprintf('Converting ncc package %s to hex dump', $ncc_package)); - $this->hexDump($ncc_package, $hex_dump_file, parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName()); + $this->hexDump($ncc_package, $hex_dump_file, $this->getProjectManager()->getProjectConfiguration()->getAssembly()->getName()); // Prepare the gcc command $gcc_path = (new ExecutableFinder())->find('gcc'); - $binary_path = $configuration->getOutputPath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName(); + + if($configuration->getOutputName() !== null) + { + $binary_path = + ConstantCompiler::compileConstants($this->getProjectManager()->getProjectConfiguration(), $configuration->getOutputPath()) + . DIRECTORY_SEPARATOR . + ConstantCompiler::compileConstants($this->getProjectManager()->getProjectConfiguration(), $configuration->getOutputName()); + } + elseif(isset($configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE])) + { + $binary_path = ConstantCompiler::compileConstants( + $this->getProjectManager()->getProjectConfiguration(), + $configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE] + ); + } + else + { + $binary_path = + ConstantCompiler::compileConstants($this->getProjectManager()->getProjectConfiguration(), $configuration->getOutputPath()) + . DIRECTORY_SEPARATOR . + ConstantCompiler::compileConstants($this->getProjectManager()->getProjectConfiguration(), $this->getProjectManager()->getProjectConfiguration()->getAssembly()->getName()); + } if($gcc_path === null) { diff --git a/src/ncc/Enums/Flags/ComponentFlags.php b/src/ncc/Enums/Flags/ComponentFlags.php index e9c6d47..ab70ad8 100644 --- a/src/ncc/Enums/Flags/ComponentFlags.php +++ b/src/ncc/Enums/Flags/ComponentFlags.php @@ -33,4 +33,12 @@ * Indicates that the component is a PHP file encoded with base64. */ public const PHP_B64 = 'php_b64'; + + /** + * All the possible flags of a component + */ + public const ALL = [ + self::PHP_AST, + self::PHP_B64 + ]; } \ No newline at end of file diff --git a/src/ncc/Enums/Options/BuildConfigurationOptions.php b/src/ncc/Enums/Options/BuildConfigurationOptions.php index 8d23354..c5a2300 100644 --- a/src/ncc/Enums/Options/BuildConfigurationOptions.php +++ b/src/ncc/Enums/Options/BuildConfigurationOptions.php @@ -29,4 +29,6 @@ public const REQUIRE_FILES = 'require_files'; public const NCC_CONFIGURATION = 'ncc_configuration'; + + public const OUTPUT_FILE = 'output_file'; } \ No newline at end of file diff --git a/src/ncc/Enums/Types/ComponentDataType.php b/src/ncc/Enums/Types/ComponentDataType.php index 7d79c33..a1d64b0 100644 --- a/src/ncc/Enums/Types/ComponentDataType.php +++ b/src/ncc/Enums/Types/ComponentDataType.php @@ -43,4 +43,14 @@ * Indicates whether the component is represented as as a base64 encoded string (Raw bytes' representation) */ public const BASE64_ENCODED = 'b64enc'; + + /** + * All the possible data types of a component + */ + public const ALL = [ + self::AST, + self::PLAIN, + self::BINARY, + self::BASE64_ENCODED + ]; } \ No newline at end of file diff --git a/src/ncc/Interfaces/CompilerInterface.php b/src/ncc/Interfaces/CompilerInterface.php index e47850f..a34589a 100644 --- a/src/ncc/Interfaces/CompilerInterface.php +++ b/src/ncc/Interfaces/CompilerInterface.php @@ -37,8 +37,9 @@ /** * Builds the project and returns the path to the built package * - * @param string $build_configuration + * @param string $build_configuration The build configuration to use + * @param array $options Optional. The options to use/override for this build * @return string */ - public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string; + public function build(string $build_configuration=BuildConfigurationValues::DEFAULT, array $options=[]): string; } \ No newline at end of file diff --git a/src/ncc/Interfaces/InstallerInterface.php b/src/ncc/Interfaces/InstallerInterface.php deleted file mode 100644 index 4256991..0000000 --- a/src/ncc/Interfaces/InstallerInterface.php +++ /dev/null @@ -1,73 +0,0 @@ -getProjectFilePath()))->build(); + $package_path = (new ProjectManager($project_detection->getProjectFilePath()))->build( + BuildConfigurationValues::DEFAULT, + [BuildConfigurationOptions::OUTPUT_FILE => PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $archive) . '.ncc'] + ); - copy($package_path, PathFinder::getCachePath() . DIRECTORY_SEPARATOR . basename($package_path)); unlink($package_path); ShutdownHandler::declareTemporaryPath($source_directory); @@ -628,7 +632,10 @@ try { $project_manager = ProjectManager::initializeFromComposer(dirname($project_detection->getProjectFilePath()), $options); - $package_path = $project_manager->build(); + $package_path = $project_manager->build( + BuildConfigurationValues::DEFAULT, + [BuildConfigurationOptions::OUTPUT_FILE => PathFinder::getCachePath() . DIRECTORY_SEPARATOR . hash('sha1', $archive) . '.ncc'] + ); copy($package_path, PathFinder::getCachePath() . DIRECTORY_SEPARATOR . basename($package_path)); unlink($package_path); diff --git a/src/ncc/Managers/ProjectManager.php b/src/ncc/Managers/ProjectManager.php index e5d8355..795deaa 100644 --- a/src/ncc/Managers/ProjectManager.php +++ b/src/ncc/Managers/ProjectManager.php @@ -142,6 +142,7 @@ * Compiles the project into a package, returns the path to the build * * @param string $build_configuration + * @param array $options * @return string * @throws BuildException * @throws ConfigurationException @@ -149,7 +150,7 @@ * @throws NotSupportedException * @throws PathNotFoundException */ - public function build(string $build_configuration=BuildConfigurationValues::DEFAULT): string + public function build(string $build_configuration=BuildConfigurationValues::DEFAULT, array $options=[]): string { $configuration = $this->project_configuration->getBuild()->getBuildConfiguration($build_configuration); @@ -157,10 +158,11 @@ { CompilerExtensions::PHP => match (strtolower($configuration->getBuildType())) { - BuildOutputType::NCC_PACKAGE => (new NccCompiler($this))->build($build_configuration), - BuildOutputType::EXECUTABLE => (new ExecutableCompiler($this))->build($build_configuration), + BuildOutputType::NCC_PACKAGE => (new NccCompiler($this))->build($build_configuration, $options), + BuildOutputType::EXECUTABLE => (new ExecutableCompiler($this))->build($build_configuration, $options), default => throw new BuildException(sprintf('php cannot produce the build type \'%s\'', $configuration->getBuildType())), }, + default => throw new NotSupportedException(sprintf('The compiler extension \'%s\' is not supported', $this->project_configuration->getProject()->getCompiler()->getExtension())), }; } @@ -301,11 +303,7 @@ public function getCompilerOptions(string $build_configuration=BuildConfigurationValues::DEFAULT): array { $configuration = $this->project_configuration->getBuild()->getBuildConfiguration($build_configuration); - - return array_merge( - $configuration->getOptions(), - $this->project_configuration->getBuild()->getOptions() - ); + return array_merge($configuration->getOptions(), $this->project_configuration->getBuild()->getOptions()); } /** diff --git a/src/ncc/Objects/ComposerJson.php b/src/ncc/Objects/ComposerJson.php index 0ccd593..39e6fb1 100644 --- a/src/ncc/Objects/ComposerJson.php +++ b/src/ncc/Objects/ComposerJson.php @@ -26,91 +26,56 @@ use ncc\Enums\Types\ComposerPackageTypes; use ncc\Enums\Types\ComposerStabilityTypes; + use ncc\Interfaces\SerializableObjectInterface; use ncc\Objects\ComposerJson\Author; use ncc\Objects\ComposerJson\Autoloader; use ncc\Objects\ComposerJson\PackageLink; use ncc\Objects\ComposerJson\Suggestion; use ncc\Objects\ComposerJson\Support; - class ComposerJson + class ComposerJson implements SerializableObjectInterface { /** - * The name of the package, it consists of - * the vendor name and project name, seperated by `/` - * * @var string */ private $name; /** - * A short description of the package. Usually - * this is one line long - * * @var string|null */ private $description; /** - * The version of the package, in most cases this is not - * required and should be omitted. - * - * If the package repository can infer the version from - * somewhere. such as the VCS tag name in the VCS repository. - * In the case it is also recommended to omit it - * * @var string|null */ private $version; /** - * The type of package, it defaults to library - * * @var string */ private $type; /** - * An array of keywords that the package is related to. - * These can be used for searching and filtering - * - * Examples - * - logging - * - events - * - database - * - redis - * - templating - * * @var string[] */ private $keywords; /** - * A URL to the website of the project - * * @var string|null */ private $homepage; /** - * A relative path to the readme document - * * @var string|null */ private $readme; /** - * Release date of the version - * - * YYY-MM-DD format or YYY-MM-DD HH:MM:SS - * * @var string|null */ private $time; /** - * The license of the package. This can either be a string or - * an array of strings - * * @var string|string[]|null */ private $license; @@ -126,160 +91,97 @@ private $support; /** - * Map of packages required by this package. The package - * will not be installed unless those requirements can be met - * * @var PackageLink[]|null */ private $require; /** - * Map of packages required for developing this package, or running tests, - * etc. The dev requirements of the root package are installed by default. - * Both install or update support the --no-dev option that prevents dev - * dependencies from being installed. - * * @var PackageLink[]|null */ private $require_dev; /** - * Map of packages that conflict with this version of this package. They will - * not be allowed to be installed together with your package. - * * @var PackageLink[]|null */ private $conflict; /** - * Map of packages that are replaced by this package. This allows you to fork a - * package, publish it under a different name with its own version numbers, - * while packages requiring the original package continue to work with your fork - * because it replaces the original package. - * * @var PackageLink[]|null */ private $replace; /** - * Map of packages that are provided by this package. This is mostly useful for - * implementations of common interfaces. A package could depend on some virtual - * package e.g. psr/logger-implementation, any library that implements this logger - * interface would list it in provide. Implementors can then be found on Packagist.org. - * * @var PackageLink[]|null */ private $provide; /** - * Suggested packages that can enhance or work well with this package. These are - * informational and are displayed after the package is installed, to give your - * users a hint that they could add more packages, even though they are not strictly - * required. - * * @var Suggestion[]|null */ private $suggest; /** - * Autoload mapping for a PHP autoloader. - * * @var Autoloader|null */ private $autoload; /** - * This section allows defining autoload rules for development purposes. - * * @var Autoloader|null */ private $autoload_dev; /** - * A list of paths which should get appended to PHP's include_path. - * * @var string[]|null */ private $include_path; /** - * Defines the installation target. - * * @var string|null */ private $target_directory; /** - * This defines the default behavior for filtering packages by - * stability. This defaults to stable, so if you rely on a dev package, - * you should specify it in your file to avoid surprises. - * - * All versions of each package are checked for stability, and those that - * are less stable than the minimum-stability setting will be ignored when - * resolving your project dependencies. (Note that you can also specify - * stability requirements on a per-package basis using stability flags - * in the version constraints that you specify in a require block - * - * @var ComposerPackageTypes|null + * @var string|null + * @see ComposerStabilityTypes */ private $minimum_stability; /** - * Custom package repositories to use. - * * @var array|null */ private $repositories; /** - * A set of configuration options. It is only used for projects. - * * @var array|null */ private $configuration; /** - * Composer allows you to hook into various parts of the installation - * process through the use of scripts. - * * @var array|null */ private $scripts; /** - * Arbitrary extra data for consumption by scripts. - * * @var array|null */ private $extra; /** - * A set of files that should be treated as binaries and made available into the bin-dir (from config). - * * @var array|null */ private $bin; /** - * A set of options for creating package archives. - * * @var array|null */ private $archive; /** - * Indicates whether this package has been abandoned. - * * @var bool */ private $abandoned; /** - * A list of regex patterns of branch names that are - * non-numeric (e.g. "latest" or something), that will - * NOT be handled as feature branches. This is an array - * of strings. - * * @var array|null */ private $non_feature_branches; @@ -295,7 +197,7 @@ } /** - * Returns the name of the package, it consists of + * Returns the name of the package; it consists of * the vendor name and project name, seperated by `/` * * @return string @@ -327,6 +229,8 @@ } /** + * Returns the type of package, it defaults to library + * * @return string */ public function getType(): string @@ -335,6 +239,16 @@ } /** + * Returns an array of keywords that the package is related to. + * These can be used for searching and filtering + * + * Examples + * - logging + * - events + * - database + * - redis + * - templating + * * @return string[] */ public function getKeywords(): array @@ -343,6 +257,8 @@ } /** + * Optional. Returns a URL to the website of the project + * * @return string|null */ public function getHomepage(): ?string @@ -351,6 +267,8 @@ } /** + * Optional. Returns a relative path to the readme document + * * @return string|null */ public function getReadme(): ?string @@ -359,6 +277,9 @@ } /** + * Optional. Returns the release date of the version + * YYY-MM-DD format or YYY-MM-DD HH:MM:SS + * * @return string|null */ public function getTime(): ?string @@ -367,6 +288,9 @@ } /** + * The license of the package. This can either be a string or + * an array of strings + * * @return string|string[]|null */ public function getLicense(): array|string|null @@ -375,6 +299,8 @@ } /** + * Optional. Returns the authors of the package + * * @return Author[]|null */ public function getAuthors(): ?array @@ -383,6 +309,8 @@ } /** + * Optional. Returns the support information of the package + * * @return Support|null */ public function getSupport(): ?Support @@ -391,6 +319,8 @@ } /** + * Optional. Returns the required packages of the package + * * @return PackageLink[]|null */ public function getRequire(): ?array @@ -399,6 +329,8 @@ } /** + * Optional. Returns the required development packages of the package + * * @return PackageLink[]|null */ public function getRequireDev(): ?array @@ -407,6 +339,8 @@ } /** + * Optional. Returns the conflicting packages of the package + * * @return PackageLink[]|null */ public function getConflict(): ?array @@ -415,6 +349,8 @@ } /** + * Optional. Returns the replaced packages of the package + * * @return PackageLink[]|null */ public function getReplace(): ?array @@ -423,6 +359,8 @@ } /** + * Optional. Returns the provided packages of the package + * * @return PackageLink[]|null */ public function getProvide(): ?array @@ -431,6 +369,8 @@ } /** + * Optional. Returns the suggested packages of the package + * * @return Suggestion[]|null */ public function getSuggest(): ?array @@ -439,6 +379,8 @@ } /** + * Optional. Returns the autoload mapping for a PHP autoloader. + * * @return Autoloader|null */ public function getAutoload(): ?Autoloader @@ -447,6 +389,8 @@ } /** + * Optional. Returns the autoload mapping for a PHP autoloader. + * * @return Autoloader|null */ public function getAutoloadDev(): ?Autoloader @@ -455,6 +399,8 @@ } /** + * Optional. Returns a list of paths which should get appended to PHP's include_path. + * * @return string[]|null */ public function getIncludePath(): ?array @@ -463,6 +409,8 @@ } /** + * Optional. Returns the installation target. + * * @return string|null */ public function getTargetDirectory(): ?string @@ -471,14 +419,27 @@ } /** - * @return ComposerPackageTypes|string|null + * This defines the default behavior for filtering packages by + * stability. This defaults to stable, so if you rely on a dev package, + * you should specify it in your file to avoid surprises. + * + * All versions of each package are checked for stability, and those that + * are less stable than the minimum-stability setting will be ignored when + * resolving your project dependencies. (Note that you can also specify + * stability requirements on a per-package basis using stability flags + * in the version constraints that you specify in a require block + * + * @return string|null + * @see ComposerStabilityTypes */ - public function getMinimumStability(): ComposerPackageTypes|string|null + public function getMinimumStability(): ?string { return $this->minimum_stability; } /** + * Optional. Returns custom package repositories to use. + * * @return array|null */ public function getRepositories(): ?array @@ -487,6 +448,8 @@ } /** + * Optional. Returns a set of configuration options. It is only used for projects. + * * @return array|null */ public function getConfiguration(): ?array @@ -495,6 +458,8 @@ } /** + * Optional. Returns composer allows you to hook into various parts of the installation + * * @return array|null */ public function getScripts(): ?array @@ -503,6 +468,8 @@ } /** + * Optional. Returns arbitrary extra data for consumption by scripts. + * * @return array|null */ public function getExtra(): ?array @@ -511,6 +478,8 @@ } /** + * Optional. Returns a set of files that should be treated as binaries and made available into the bin-dir (from config). + * * @return array|null */ public function getBin(): ?array @@ -519,6 +488,8 @@ } /** + * Optional. Returns a set of options for creating package archives. + * * @return array|null */ public function getArchive(): ?array @@ -527,6 +498,8 @@ } /** + * Returns whether this package has been abandoned. + * * @return bool */ public function isAbandoned(): bool @@ -535,6 +508,8 @@ } /** + * Optional. Returns a list of regex patterns of branch names that are + * * @return array|null */ public function getNonFeatureBranches(): ?array @@ -543,9 +518,7 @@ } /** - * Returns an array representation of the object - * - * @return array + * @inheritDoc */ public function toArray(): array { @@ -653,6 +626,9 @@ ]; } + /** + * @inheritDoc + */ public static function fromArray(array $data): self { $object = new self(); diff --git a/src/ncc/Objects/ExecutionPointers.php b/src/ncc/Objects/ExecutionPointers.php deleted file mode 100644 index b2a9d15..0000000 --- a/src/ncc/Objects/ExecutionPointers.php +++ /dev/null @@ -1,214 +0,0 @@ -package = $package; - $this->version = $version; - $this->pointers = []; - } - - /** - * Adds an Execution Unit as a pointer - * - * @param ExecutionUnit $unit - * @param string $bin_file - * @param bool $overwrite - * @return bool - * @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 PathNotFoundException($bin_file); - } - - if($overwrite) - { - $this->deleteUnit($unit->getExecutionPolicy()->getName()); - } - elseif($this->getUnit($unit->getExecutionPolicy()->getName()) !== null) - { - return false; - } - - $this->pointers[] = new ExecutionPointer($unit, $bin_file); - return true; - } - - /** - * Deletes an existing unit from execution pointers - * - * @param string $name - * @return bool - */ - public function deleteUnit(string $name): bool - { - $unit = $this->getUnit($name); - - if($unit === null) - { - return false; - } - - $new_pointers = []; - foreach($this->pointers as $pointer) - { - if($pointer->getExecutionPolicy()->getName() !== $name) - { - $new_pointers[] = $pointer; - } - } - - $this->pointers = $new_pointers; - return true; - } - - /** - * Returns an existing unit from the pointers - * - * @param string $name - * @return ExecutionPointer|null - */ - public function getUnit(string $name): ?ExecutionPointer - { - /** @var ExecutionPointer $pointer */ - foreach($this->pointers as $pointer) - { - if($pointer->getExecutionPolicy()->getName() === $name) - { - return $pointer; - } - } - - return null; - } - - /** - * Returns an array of execution pointers that are currently configured - * - * @return array|ExecutionPointer[] - */ - public function getPointers(): array - { - return $this->pointers; - } - - /** - * Returns the version of the package that uses these execution policies. - * - * @return string - */ - public function getVersion(): string - { - return $this->version; - } - - /** - * Returns the name of the package that uses these execution policies - * - * @return string - */ - public function getPackage(): string - { - return $this->package; - } - - /** - * @inheritDoc - */ - public function toArray(bool $bytecode=false): array - { - $pointers = []; - 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('pointers') : 'pointers') => $pointers - ]; - } - - /** - * @inheritDoc - */ - public static function fromArray(array $data): self - { - $object = new self(); - - $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) - { - $pointers = []; - foreach($object->pointers as $pointer) - { - $pointers[] = ExecutionPointer::fromArray($pointer); - } - $object->pointers = $pointers; - } - - return $object; - } - } \ No newline at end of file diff --git a/src/ncc/Objects/NccVersionInformation/Component.php b/src/ncc/Objects/InternalComponent.php similarity index 62% rename from src/ncc/Objects/NccVersionInformation/Component.php rename to src/ncc/Objects/InternalComponent.php index 41ed694..4d8ae6b 100644 --- a/src/ncc/Objects/NccVersionInformation/Component.php +++ b/src/ncc/Objects/InternalComponent.php @@ -1,28 +1,28 @@ components[] = Component::fromArray($datum); + $object->components[] = InternalComponent::fromArray($datum); } } diff --git a/src/ncc/Objects/Package.php b/src/ncc/Objects/Package.php deleted file mode 100644 index cfd7c2c..0000000 --- a/src/ncc/Objects/Package.php +++ /dev/null @@ -1,673 +0,0 @@ -magic_bytes = new MagicBytes(); - $this->metadata = new Metadata($compiler); - $this->assembly = $assembly; - $this->execution_units = []; - $this->components = []; - $this->dependencies = []; - $this->resources = []; - } - - /** - * Adds a dependency to the package - * - * @param Dependency $dependency - * @return void - */ - public function addDependency(Dependency $dependency): void - { - foreach($this->dependencies as $dep) - { - if($dep->getName() === $dependency->getName()) - { - $this->removeDependency($dep->getName()); - break; - } - } - - $this->dependencies[] = $dependency; - } - - /** - * Removes a dependency from the build - * - * @param string $name - * @return void - */ - private function removeDependency(string $name): void - { - foreach($this->dependencies as $key => $dep) - { - if($dep->getName() === $name) - { - unset($this->dependencies[$key]); - return; - } - } - } - - /** - * @return MagicBytes - */ - public function getMagicBytes(): MagicBytes - { - return $this->magic_bytes; - } - - /** - * @param MagicBytes $magic_bytes - */ - public function setMagicBytes(MagicBytes $magic_bytes): void - { - $this->magic_bytes = $magic_bytes; - } - - /** - * @return Metadata - */ - public function getMetadata(): Metadata - { - return $this->metadata; - } - - /** - * @param Metadata $metadata - */ - public function setMetadata(Metadata $metadata): void - { - $this->metadata = $metadata; - } - - /** - * @return Assembly - */ - public function getAssembly(): Assembly - { - return $this->assembly; - } - - /** - * @param Assembly $assembly - */ - public function setAssembly(Assembly $assembly): void - { - $this->assembly = $assembly; - } - - /** - * @return array|Dependency[] - */ - public function getDependencies(): array - { - return $this->dependencies; - } - - /** - * @param array|Dependency[] $dependencies - */ - public function setDependencies(array $dependencies): void - { - $this->dependencies = $dependencies; - } - - /** - * @return string|null - */ - public function getMainExecutionPolicy(): ?string - { - return $this->main_execution_policy; - } - - /** - * @param string|null $main_execution_policy - */ - public function setMainExecutionPolicy(?string $main_execution_policy): void - { - $this->main_execution_policy = $main_execution_policy; - } - - /** - * @return Installer|null - */ - public function getInstaller(): ?Installer - { - return $this->installer; - } - - /** - * @param Installer|null $installer - */ - public function setInstaller(?Installer $installer): void - { - $this->installer = $installer; - } - - /** - * @return array|ExecutionUnit[] - */ - public function getExecutionUnits(): array - { - return $this->execution_units; - } - - /** - * @param array|ExecutionUnit[] $execution_units - */ - public function setExecutionUnits(array $execution_units): void - { - $this->execution_units = $execution_units; - } - - /** - * @param ExecutionUnit $unit - * @return void - */ - public function addExecutionUnit(ExecutionUnit $unit): void - { - foreach($this->execution_units as $exec_unit) - { - if($exec_unit->getId() === $unit->getId()) - { - $this->removeExecutionUnit($exec_unit->getId()); - break; - } - } - - $this->execution_units[] = $unit; - } - - /** - * @return array|Resource[] - */ - public function getResources(): array - { - return $this->resources; - } - - /** - * @param array|Resource[] $resources - */ - public function setResources(array $resources): void - { - $this->resources = $resources; - } - - /** - * @param Resource $resource - * @return void - */ - public function addResource(Resource $resource): void - { - foreach($this->resources as $res) - { - if($res->getName() === $resource->getName()) - { - $this->removeResource($res->getName()); - break; - } - } - - $this->resources[] = $resource; - } - - /** - * @param string $name - * @return void - */ - private function removeResource(string $name): void - { - foreach($this->resources as $key => $res) - { - if($res->getName() === $name) - { - unset($this->resources[$key]); - return; - } - } - } - - /** - * @return array|Component[] - */ - public function getComponents(): array - { - return $this->components; - } - - /** - * @param array|Component[] $components - */ - public function setComponents(array $components): void - { - $this->components = $components; - } - - /** - * @param Component $component - * @return void - */ - public function addComponent(Component $component): void - { - foreach($this->components as $comp) - { - if($comp->getName() === $component->getName()) - { - $this->removeComponent($comp->getName()); - break; - } - } - - $this->components[] = $component; - } - - /** - * @param string $name - * @return void - */ - public function removeComponent(string $name): void - { - foreach($this->components as $key => $comp) - { - if($comp->getName() === $name) - { - unset($this->components[$key]); - return; - } - } - } - - /** - * Validates the package object and returns True if the package contains the correct information - * - * Returns false if the package contains incorrect information which can cause - * an error when compiling the package. - * - * @param bool $throw_exception - * @return bool - * @throws ConfigurationException - */ - public function validate(bool $throw_exception=True): bool - { - // Validate the MagicBytes constructor - if($this->magic_bytes === null) - { - if($throw_exception) - { - throw new ConfigurationException('The MagicBytes property is required and cannot be null'); - } - - return false; - } - - // Validate the assembly object - if($this->assembly === null) - { - if($throw_exception) - { - throw new ConfigurationException('The Assembly property is required and cannot be null'); - } - - return false; - } - - if(!$this->assembly->validate($throw_exception)) - { - return false; - } - - // All checks have passed - return true; - } - - /** - * Attempts to find the execution unit with the given name - * - * @param string $name - * @return ExecutionUnit|null - */ - public function getExecutionUnit(string $name): ?ExecutionUnit - { - foreach($this->execution_units as $unit) - { - if($unit->getExecutionPolicy()->getName() === $name) - { - return $unit; - } - } - - return null; - } - - /** - * Writes the package contents to disk - * - * @param string $output_path - * @return void - * @throws IOException - */ - public function save(string $output_path): void - { - $package_contents = $this->magic_bytes->toString() . ZiProto::encode($this->toArray(true)); - IO::fwrite($output_path, $package_contents, 0777); - } - - /** - * Attempts to parse the specified package path and returns the object representation - * of the package, including with the MagicBytes representation that is in the - * file headers. - * - * @param string $path - * @return Package - * @throws PackageException - * @throws PathNotFoundException - */ - public static function load(string $path): Package - { - if(!is_file($path) || !is_readable($path)) - { - throw new PathNotFoundException($path); - } - - $handle = fopen($path, "rb"); - $header = fread($handle, 256); // Read the first 256 bytes of the file - fclose($handle); - - if(stripos($header, 'NCC_PACKAGE') === 0) - { - throw new PackageException(sprintf("The package '%s' does not appear to be a valid NCC Package (Missing Header)", $path)); - } - - // Extract the package structure version - $package_structure_version = strtoupper(substr($header, 11, 3)); - - if(!in_array($package_structure_version, PackageStructureVersions::ALL, true)) - { - throw new PackageException(sprintf("The package '%s' does not appear to be a valid NCC Package (Unsupported Package Structure Version)", $path)); - } - - // Extract the package encoding type and package type - $encoding_header = strtoupper(substr($header, 14, 5)); - $encoding_type = substr($encoding_header, 0, 3); - $package_type = substr($encoding_header, 3, 2); - - $magic_bytes = new MagicBytes(); - $magic_bytes->setPackageStructureVersion($package_structure_version); - - // Determine the encoding type - switch($encoding_type) - { - case '300': - $magic_bytes->setEncoder(EncoderType::ZI_PROTO); - $magic_bytes->setCompressed(false); - $magic_bytes->setCompressed(false); - break; - - case '301': - $magic_bytes->setEncoder(EncoderType::ZI_PROTO); - $magic_bytes->setCompressed(true); - $magic_bytes->setEncrypted(false); - break; - - case '310': - $magic_bytes->setEncoder(EncoderType::ZI_PROTO); - $magic_bytes->setCompressed(false); - $magic_bytes->setEncrypted(true); - break; - - case '311': - $magic_bytes->setEncoder(EncoderType::ZI_PROTO); - $magic_bytes->setCompressed(true); - $magic_bytes->setEncrypted(true); - break; - - default: - throw new PackageException(sprintf("The package '%s' does not appear to be a valid NCC Package (Unsupported Encoding Type)", $path)); - } - - // Determine the package type - switch($package_type) - { - case '40': - $magic_bytes->setInstallable(true); - $magic_bytes->setExecutable(false); - break; - - case '41': - $magic_bytes->setInstallable(false); - $magic_bytes->setExecutable(true); - break; - - case '42': - $magic_bytes->setInstallable(true); - $magic_bytes->setExecutable(true); - break; - - default: - throw new PackageException(sprintf("The package '%s' does not appear to be a valid NCC Package (Unsupported Package Type)", $path)); - } - - // Assuming all is good, load the entire fire into memory and parse its contents - try - { - $package = self::fromArray(ZiProto::decode(substr(IO::fread($path), strlen($magic_bytes->toString())))); - } - catch(Exception $e) - { - throw new PackageException(sprintf("The package '%s' does not appear to be a valid NCC Package (Invalid Package Contents)", $path), $e); - } - - $package->magic_bytes = $magic_bytes; - return $package; - } - - /** - * @inheritDoc - */ - public function toArray(bool $bytecode=false): array - { - $_components = []; - /** @var Component $component */ - foreach($this->components as $component) - { - $_components[] = $component->toArray($bytecode); - } - - $_dependencies = []; - /** @var Dependency $dependency */ - foreach($this->dependencies as $dependency) - { - $_dependencies[] = $dependency->toArray($bytecode); - } - - $_resources = []; - /** @var Resource $resource */ - foreach($this->resources as $resource) - { - $_resources[] = $resource->toArray($bytecode); - } - - $_execution_units = []; - foreach($this->execution_units as $unit) - { - $_execution_units[] = $unit->toArray($bytecode); - } - - return [ - ($bytecode ? Functions::cbc('header') : 'header') => $this?->metadata?->toArray($bytecode), - ($bytecode ? Functions::cbc('assembly') : 'assembly') => $this?->assembly?->toArray($bytecode), - ($bytecode ? Functions::cbc('dependencies') : 'dependencies') => $_dependencies, - ($bytecode ? Functions::cbc('main_execution_policy') : 'main_execution_policy') => $this?->main_execution_policy, - ($bytecode ? Functions::cbc('installer') : 'installer') => $this?->installer?->toArray($bytecode), - ($bytecode ? Functions::cbc('execution_units') : 'execution_units') => $_execution_units, - ($bytecode ? Functions::cbc('resources') : 'resources') => $_resources, - ($bytecode ? Functions::cbc('components') : 'components') => $_components - ]; - } - - /** - * @inheritDoc - */ - public static function fromArray(array $data): Package - { - $object = new self(); - - $object->metadata = Functions::array_bc($data, 'header'); - if($object->metadata !== null) - { - $object->metadata = Metadata::fromArray($object->metadata); - } - - $object->assembly = Functions::array_bc($data, 'assembly'); - if($object->assembly !== null) - { - $object->assembly = Assembly::fromArray($object->assembly); - } - - $object->main_execution_policy = Functions::array_bc($data, 'main_execution_policy'); - - $object->installer = Functions::array_bc($data, 'installer'); - if($object->installer !== null) - { - $object->installer = Installer::fromArray($object->installer); - } - - $_dependencies = Functions::array_bc($data, 'dependencies'); - if($_dependencies !== null) - { - foreach($_dependencies as $dependency) - { - $object->dependencies[] = Dependency::fromArray($dependency); - } - } - - $_resources = Functions::array_bc($data, 'resources'); - if($_resources !== null) - { - foreach($_resources as $resource) - { - $object->resources[] = Resource::fromArray($resource); - } - } - - $_components = Functions::array_bc($data, 'components'); - if($_components !== null) - { - foreach($_components as $component) - { - $object->components[] = Component::fromArray($component); - } - } - - $_execution_units = Functions::array_bc($data, 'execution_units'); - if($_execution_units !== null) - { - foreach($_execution_units as $unit) - { - $object->execution_units[] = ExecutionUnit::fromArray($unit); - } - } - - return $object; - } - } \ No newline at end of file diff --git a/src/ncc/Objects/Package/Component.php b/src/ncc/Objects/Package/Component.php index 68f662b..20416f2 100644 --- a/src/ncc/Objects/Package/Component.php +++ b/src/ncc/Objects/Package/Component.php @@ -25,56 +25,43 @@ namespace ncc\Objects\Package; use Exception; + use InvalidArgumentException; use ncc\Classes\PhpExtension\AstWalker; use ncc\Enums\Flags\ComponentFlags; use ncc\Enums\Options\ComponentDecodeOptions; use ncc\Enums\Types\ComponentDataType; use ncc\Exceptions\ConfigurationException; + use ncc\Exceptions\OperationException; use ncc\Extensions\ZiProto\ZiProto; use ncc\Interfaces\BytecodeObjectInterface; use ncc\ThirdParty\nikic\PhpParser\PrettyPrinter\Standard; use ncc\Utilities\Functions; - use RuntimeException; class Component implements BytecodeObjectInterface { /** - * The name of the component or the file name of the component - * * @var string */ private $name; /** - * Flags associated with the component created by the compiler extension - * * @var array */ private $flags; /** - * The data type of the component - * * @var string */ private $data_type; /** - * A sha1 hash checksum of the component, this will be compared against the data to determine - * the integrity of the component to ensure that the component is not corrupted. - * - * @var string - */ - private $checksum; - - /** - * The raw data of the component, this is to be processed by the compiler extension - * * @var string */ private $data; /** + * Component constructor. + * * @param string $name * @param string $data * @param string $data_type @@ -85,21 +72,11 @@ $this->flags = []; $this->data_type = $data_type; $this->data = $data; - $this->checksum = hash('sha1', $data, true); } /** - * Validates the checksum of the component, returns false if the checksum or data is invalid or if the checksum - * failed. + * Returns the name of the component * - * @return bool - */ - public function validateChecksum(): bool - { - return hash_equals($this->checksum, hash('sha1', $this->data, true)); - } - - /** * @return string */ public function getName(): string @@ -108,6 +85,8 @@ } /** + * Sets the name of the component + * * @param string $name */ public function setName(string $name): void @@ -116,6 +95,8 @@ } /** + * Returns an array of flags associated with the component + * * @return array */ public function getFlags(): array @@ -124,6 +105,8 @@ } /** + * Replaces the current array of flags with the new array of flags + * * @param array $flags */ public function setFlags(array $flags): void @@ -132,15 +115,24 @@ } /** + * Appends a new flag to the component if it does not exist + * * @param string $flag * @return void */ public function addFlag(string $flag): void { + if(in_array($flag, $this->flags, true)) + { + return; + } + $this->flags[] = $flag; } /** + * Removes a flag from the component if it exists + * * @param string $flag * @return void */ @@ -153,27 +145,23 @@ } /** + * Returns the data type of the component + * * @return string + * @see ComponentDataType */ public function getDataType(): string { return $this->data_type; } - /** - * @return string - */ - public function getChecksum(): string - { - return $this->checksum; - } - /** * Returns the decoded data of the component, this will decode the data based on the data type and flags of the * component. * * @param array $options * @return string + * @throws OperationException */ public function getData(array $options=[]): string { @@ -197,7 +185,7 @@ } catch(Exception $e) { - throw new RuntimeException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_B64, $e->getMessage()), $e->getCode(), $e); + throw new OperationException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_B64, $e->getMessage()), $e->getCode(), $e); } } @@ -217,26 +205,34 @@ } catch(Exception $e) { - throw new RuntimeException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_AST, $e->getMessage()), $e->getCode(), $e); + throw new OperationException(sprintf('Failed to decode component %s with data type %s because the component is corrupted: %s', $this->name, ComponentFlags::PHP_AST, $e->getMessage()), $e->getCode(), $e); } } - throw new RuntimeException(sprintf('Cannot decode component %s with data type %s because the component does not have a flag to decode it properly', $this->name, 'AST')); + throw new OperationException(sprintf('Cannot decode component %s with data type %s because the component does not have a flag to decode it properly. Got: %s', $this->name, implode(' ', $this->flags), 'AST')); default: - throw new RuntimeException(sprintf('Unknown component data type "%s"', $this->data_type)); + throw new InvalidArgumentException(sprintf('Unknown component data type "%s"', $this->data_type)); } } /** + * Sets the data of the component + * * @param mixed $data * @param string $data_type */ public function setData(mixed $data, string $data_type=ComponentDataType::PLAIN): void { + $data_type = strtolower($data_type); + + if(!in_array($data_type, ComponentDataType::ALL, true)) + { + throw new InvalidArgumentException(sprintf('Unknown component data type "%s"', $data_type)); + } + $this->data = $data; $this->data_type = $data_type; - $this->checksum = hash('sha1', $data, true); } /** @@ -251,7 +247,6 @@ ($bytecode ? Functions::cbc('name') : 'name') => $this->name, ($bytecode ? Functions::cbc('flags') : 'flags') => $this->flags, ($bytecode ? Functions::cbc('data_type') : 'data_type') => $this->data_type, - ($bytecode ? Functions::cbc('checksum') : 'checksum') => $this->checksum, ($bytecode ? Functions::cbc('data') : 'data') => $this->data, ]; } @@ -280,9 +275,7 @@ } $object = new self($name, $component_data, $data_type); - $object->flags = Functions::array_bc($data, 'flags'); - $object->checksum = Functions::array_bc($data, 'checksum'); return $object; } diff --git a/src/ncc/Objects/Package/ExecutionUnit.php b/src/ncc/Objects/Package/ExecutionUnit.php index 2d6ceeb..006457e 100644 --- a/src/ncc/Objects/Package/ExecutionUnit.php +++ b/src/ncc/Objects/Package/ExecutionUnit.php @@ -33,36 +33,37 @@ class ExecutionUnit implements BytecodeObjectInterface { /** - * @var string|null + * @var string */ private $id; /** - * The execution policy for this execution unit - * * @var ExecutionPolicy */ private $execution_policy; /** - * The data of the unit to execute - * * @var string */ private $data; /** + * ExecutionUnit constructor. + * * @param ExecutionPolicy $execution_policy * @param string $data + * @noinspection InterfacesAsConstructorDependenciesInspection */ public function __construct(ExecutionPolicy $execution_policy, string $data) { $this->execution_policy = $execution_policy; - $this->id = hash('sha1', $this->execution_policy->getName()); $this->data = $data; + $this->id = hash('sha1', $this->execution_policy->getName()); } /** + * Returns the ID of the execution unit (sha1) + * * @return string */ public function getId(): string @@ -71,6 +72,8 @@ } /** + * Returns the execution policy of the execution unit + * * @return ExecutionPolicy */ public function getExecutionPolicy(): ExecutionPolicy @@ -79,6 +82,8 @@ } /** + * Returns the executable data of the execution unit + * * @return string */ public function getData(): string diff --git a/src/ncc/Objects/Package/MagicBytes.php b/src/ncc/Objects/Package/MagicBytes.php deleted file mode 100644 index d593514..0000000 --- a/src/ncc/Objects/Package/MagicBytes.php +++ /dev/null @@ -1,273 +0,0 @@ -package_structure_version = Versions::PACKAGE_STRUCTURE_VERSION; - $this->encoder = EncoderType::ZI_PROTO; - $this->compressed = false; - $this->encrypted = false; - $this->installable = false; - $this->executable = false; - } - - /** - * @return string - */ - public function getPackageStructureVersion(): string - { - return $this->package_structure_version; - } - - /** - * @param string $package_structure_version - */ - public function setPackageStructureVersion(string $package_structure_version): void - { - $this->package_structure_version = $package_structure_version; - } - - /** - * @return EncoderType|string - */ - public function getEncoder(): EncoderType|string - { - return $this->encoder; - } - - /** - * @param EncoderType|string $encoder - */ - public function setEncoder(EncoderType|string $encoder): void - { - $this->encoder = $encoder; - } - - /** - * @return bool - */ - public function isCompressed(): bool - { - return $this->compressed; - } - - /** - * @param bool $compressed - */ - public function setCompressed(bool $compressed): void - { - $this->compressed = $compressed; - } - - /** - * @return bool - */ - public function isEncrypted(): bool - { - return $this->encrypted; - } - - /** - * @param bool $encrypted - */ - public function setEncrypted(bool $encrypted): void - { - $this->encrypted = $encrypted; - } - - /** - * @return bool - */ - public function isInstallable(): bool - { - return $this->installable; - } - - /** - * @param bool $installable - */ - public function setInstallable(bool $installable): void - { - $this->installable = $installable; - } - - /** - * @return bool - */ - public function isExecutable(): bool - { - return $this->executable; - } - - /** - * @param bool $executable - */ - public function setExecutable(bool $executable): void - { - $this->executable = $executable; - } - - /** - * @inheritDoc - */ - public function toArray(): array - { - return [ - 'package_structure_version' => $this->package_structure_version, - 'encoder' => $this->encoder, - 'is_compressed' => $this->compressed, - 'is_encrypted' => $this->encrypted, - 'is_installable' => $this->installable, - 'is_executable' => $this->executable - ]; - } - - /** - * @inheritDoc - */ - public static function fromArray(array $data): self - { - $object = new self(); - - if(isset($data['is_executable'])) - { - $object->executable = (bool)$data['is_executable']; - } - - return $object; - } - - /** - * Builds and returns the string representation of the magic bytes - * - * @return string - */ - public function toString(): string - { - // NCC_PACKAGE1.0 - $magic_bytes = 'NCC_PACKAGE' . $this->package_structure_version; - - // NCC_PACKAGE1.03 - $magic_bytes .= $this->encoder; - - if($this->encrypted) - { - // NCC_PACKAGE1.031 - $magic_bytes .= '1'; - } - else - { - // NCC_PACKAGE1.030 - $magic_bytes .= '0'; - } - - if($this->compressed) - { - // NCC_PACKAGE1.0301 - $magic_bytes .= '1'; - } - else - { - // NCC_PACKAGE1.0300 - $magic_bytes .= '0'; - } - - if($this->executable && $this->installable) - { - // NCC_PACKAGE1.030142 - $magic_bytes .= '42'; - } - elseif($this->executable) - { - // NCC_PACKAGE1.030141 - $magic_bytes .= '41'; - } - elseif($this->installable) - { - // NCC_PACKAGE1.030140 - $magic_bytes .= '40'; - } - else - { - // If no type is specified, default to installable only - // NCC_PACKAGE1.030140 - $magic_bytes .= '40'; - } - - return $magic_bytes; - } - } \ No newline at end of file diff --git a/src/ncc/Objects/Package/Metadata.php b/src/ncc/Objects/Package/Metadata.php index af718f4..3b29015 100644 --- a/src/ncc/Objects/Package/Metadata.php +++ b/src/ncc/Objects/Package/Metadata.php @@ -25,6 +25,7 @@ namespace ncc\Objects\Package; use ncc\Exceptions\ConfigurationException; + use ncc\Exceptions\NotSupportedException; use ncc\Interfaces\BytecodeObjectInterface; use ncc\Objects\ProjectConfiguration\Compiler; use ncc\Objects\ProjectConfiguration\Installer; @@ -34,36 +35,21 @@ class Metadata implements BytecodeObjectInterface { /** - * The compiler extension information that was used to build the package - * * @var Compiler */ private $compiler_extension; /** - * An array of constants that are set when the package is imported or executed during runtime. - * - * @var array - */ - private $runtime_constants; - - /** - * The version of NCC that was used to compile the package, can be used for backwards compatibility - * * @var string */ private $compiler_version; /** - * An array of options to pass on to the extension - * * @var array|null */ private $options; /** - * The optional update source to where the package can be updated from - * * @var UpdateSource|null */ private $update_source; @@ -79,17 +65,21 @@ private $installer; /** - * Public Constructor + * Metadata constructor. + * + * @param Compiler $compiler + * @noinspection InterfacesAsConstructorDependenciesInspection */ public function __construct(Compiler $compiler) { $this->compiler_extension = $compiler; $this->compiler_version = NCC_VERSION_NUMBER; - $this->runtime_constants = []; $this->options = []; } /** + * Returns the compiler extension information that was used to build the package + * * @return Compiler */ public function getCompilerExtension(): Compiler @@ -98,6 +88,8 @@ } /** + * Sets the compiler extension information that was used to build the package + * * @param Compiler $compiler_extension */ public function setCompilerExtension(Compiler $compiler_extension): void @@ -106,22 +98,8 @@ } /** - * @return array - */ - public function getRuntimeConstants(): array - { - return $this->runtime_constants; - } - - /** - * @param array $runtime_constants - */ - public function setRuntimeConstants(array $runtime_constants): void - { - $this->runtime_constants = $runtime_constants; - } - - /** + * Returns the version of ncc that was used to compile the package, can be used for backwards compatibility + * * @return string */ public function getCompilerVersion(): string @@ -130,6 +108,8 @@ } /** + * Sets the version of ncc that was used to compile the package, can be used for backwards compatibility + * * @param string $compiler_version */ public function setCompilerVersion(string $compiler_version): void @@ -138,6 +118,8 @@ } /** + * Returns an array of options associated with the package + * * @return array|null */ public function getOptions(): ?array @@ -146,6 +128,8 @@ } /** + * Sets an array of options associated with the package + * * @param array|null $options */ public function setOptions(?array $options): void @@ -154,16 +138,20 @@ } /** + * Sets an option associated with the package + * * @param string $key - * @param $value + * @param mixed $value * @return void */ - public function setOption(string $key, $value): void + public function setOption(string $key, mixed $value): void { $this->options[$key] = $value; } /** + * Removes an option associated with the package + * * @param string $key * @return void */ @@ -173,6 +161,8 @@ } /** + * Returns an option associated with the package + * * @param string $key * @return mixed|null */ @@ -182,6 +172,8 @@ } /** + * Optional. Returns the update source to where the package can be updated from + * * @return UpdateSource|null */ public function getUpdateSource(): ?UpdateSource @@ -190,6 +182,8 @@ } /** + * Sets the update source to where the package can be updated from + * * @param UpdateSource|null $update_source */ public function setUpdateSource(?UpdateSource $update_source): void @@ -198,6 +192,8 @@ } /** + * Returns the main execution policy of the package + * * @return string|null */ public function getMainExecutionPolicy(): ?string @@ -206,6 +202,8 @@ } /** + * Sets the main execution policy of the package + * * @param string|null $main_execution_policy */ public function setMainExecutionPolicy(?string $main_execution_policy): void @@ -214,6 +212,8 @@ } /** + * Returns installation policies to execute when installing/managing the package + * * @return Installer|null */ public function getInstaller(): ?Installer @@ -222,6 +222,8 @@ } /** + * Returns installation policies to execute when installing/managing the package + * * @param Installer|null $installer */ public function setInstaller(?Installer $installer): void @@ -236,7 +238,6 @@ { return [ ($bytecode ? Functions::cbc('compiler_extension') : 'compiler_extension') => $this->compiler_extension->toArray(), - ($bytecode ? Functions::cbc('runtime_constants') : 'runtime_constants') => $this->runtime_constants, ($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->compiler_version, ($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->update_source?->toArray($bytecode)), ($bytecode ? Functions::cbc('installer') : 'installer') => ($this->installer?->toArray($bytecode)), @@ -247,6 +248,10 @@ /** * @inheritDoc + * @param array $data + * @return Metadata + * @throws ConfigurationException + * @throws NotSupportedException */ public static function fromArray(array $data): Metadata { @@ -258,7 +263,6 @@ $object = new self(Compiler::fromArray($compiler_extension)); - $object->runtime_constants = Functions::array_bc($data, 'runtime_constants'); $object->compiler_version = Functions::array_bc($data, 'compiler_version'); $object->update_source = Functions::array_bc($data, 'update_source'); $object->options = Functions::array_bc($data, 'options'); diff --git a/src/ncc/Objects/Package/Resource.php b/src/ncc/Objects/Package/Resource.php index bc31eaf..20789e4 100644 --- a/src/ncc/Objects/Package/Resource.php +++ b/src/ncc/Objects/Package/Resource.php @@ -26,7 +26,6 @@ use ncc\Exceptions\ConfigurationException; use ncc\Interfaces\BytecodeObjectInterface; - use ncc\Utilities\Base64; use ncc\Utilities\Functions; class Resource implements BytecodeObjectInterface @@ -38,14 +37,6 @@ */ private $name; - /** - * A sha1 hash checksum of the resource, this will be compared against the data to determine - * the integrity of the resource to ensure that the resource is not corrupted. - * - * @var string - */ - private $checksum; - /** * The raw data of the resource * @@ -53,25 +44,21 @@ */ private $data; + /** + * Resource constructor. + * + * @param string $name + * @param mixed $data + */ public function __construct(string $name, mixed $data) { $this->name = $name; $this->data = $data; - $this->checksum = hash('sha1', $this->data, true); } /** - * Validates the checksum of the resource, returns false if the checksum or data is invalid or if the checksum - * failed. + * Returns the name of the resource * - * @return bool - */ - public function validateChecksum(): bool - { - return hash_equals($this->checksum, hash('sha1', $this->data, true)); - } - - /** * @return string */ public function getName(): string @@ -80,6 +67,8 @@ } /** + * Sets the name of the resource + * * @param string $name */ public function setName(string $name): void @@ -88,14 +77,8 @@ } /** - * @return string - */ - public function getChecksum(): string - { - return $this->checksum; - } - - /** + * Returns the resource data + * * @return string */ public function getData(): string @@ -104,12 +87,13 @@ } /** + * Sets the resource data + * * @param string $data */ public function setData(string $data): void { - $this->data = Base64::encode($data); - $this->checksum = hash('sha1', $this->data, true); + $this->data = $data; } /** @@ -119,7 +103,6 @@ { return [ ($bytecode ? Functions::cbc('name') : 'name') => $this->name, - ($bytecode ? Functions::cbc('checksum') : 'checksum') => $this->checksum, ($bytecode ? Functions::cbc('data') : 'data') => $this->data, ]; } @@ -143,9 +126,6 @@ throw new ConfigurationException('Resource data is not defined'); } - $object = new self($name, $resource_data); - $object->checksum = Functions::array_bc($data, 'checksum'); - - return $object; + return new self($name, $resource_data); } } \ No newline at end of file diff --git a/src/ncc/Objects/PackageLock/PackageEntry.php b/src/ncc/Objects/PackageLock/PackageEntry.php index 8c68e15..73ee4b5 100644 --- a/src/ncc/Objects/PackageLock/PackageEntry.php +++ b/src/ncc/Objects/PackageLock/PackageEntry.php @@ -30,6 +30,7 @@ use ncc\Enums\Versions; use ncc\Exceptions\ConfigurationException; use ncc\Exceptions\IOException; + use ncc\Exceptions\NotSupportedException; use ncc\Exceptions\PathNotFoundException; use ncc\Extensions\ZiProto\ZiProto; use ncc\Interfaces\BytecodeObjectInterface; @@ -46,22 +47,16 @@ class PackageEntry implements BytecodeObjectInterface { /** - * The name of the package that's installed - * * @var string */ private $name; /** - * An array of installed versions for this package - * * @var VersionEntry[] */ private $versions; /** - * The update source of the package entry - * * @var UpdateSource|null */ private $update_source; @@ -328,6 +323,7 @@ * @throws ConfigurationException * @throws IOException * @throws PathNotFoundException + * @throws NotSupportedException */ public function getMetadata(string $version=Versions::LATEST): Metadata { diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php index dec7227..6df8378 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php @@ -26,11 +26,12 @@ use ncc\Exceptions\ConfigurationException; use ncc\Interfaces\BytecodeObjectInterface; + use ncc\Interfaces\ValidatableObjectInterface; use ncc\Objects\ProjectConfiguration\ExecutionPolicy\Execute; use ncc\Objects\ProjectConfiguration\ExecutionPolicy\ExitHandlers; use ncc\Utilities\Functions; - class ExecutionPolicy implements BytecodeObjectInterface + class ExecutionPolicy implements BytecodeObjectInterface, ValidatableObjectInterface { /** * The unique name of the execution policy @@ -82,6 +83,8 @@ } /** + * Returns the name of the execution policy + * * @return string */ public function getName(): string @@ -90,6 +93,8 @@ } /** + * Sets the name of the execution policy + * * @param string $name */ public function setName(string $name): void @@ -106,6 +111,8 @@ } /** + * Sets the name of the runner to use + * * @param string $runner */ public function setRunner(string $runner): void @@ -114,6 +121,8 @@ } /** + * Returns the message to display when the policy is invoked + * * @return string|null */ public function getMessage(): ?string @@ -122,6 +131,8 @@ } /** + * Optional. Sets the message to display when the policy is invoked + * * @param string|null $message */ public function setMessage(?string $message): void @@ -130,6 +141,8 @@ } /** + * Returns the execution process of the policy + * * @return Execute */ public function getExecute(): Execute @@ -138,6 +151,8 @@ } /** + * Sets the execution process of the policy + * * @param Execute $execute */ public function setExecute(Execute $execute): void @@ -146,6 +161,8 @@ } /** + * Optional. Returns the exit handlers for the policy + * * @return ?ExitHandlers */ public function getExitHandlers(): ?ExitHandlers @@ -154,6 +171,8 @@ } /** + * Sets the exit handlers for the policy + * * @param ExitHandlers|null $exit_handlers */ public function setExitHandlers(?ExitHandlers $exit_handlers): void @@ -162,12 +181,45 @@ } /** - * @return bool + * @inheritDoc */ - public function validate(): bool + public function validate(): void { - // TODO: Implement validation method - return true; + if($this->name === null || $this->name === '') + { + throw new ConfigurationException('ExecutionPolicy name cannot be null or empty'); + } + + if($this->runner === null || $this->runner === '') + { + throw new ConfigurationException('ExecutionPolicy runner cannot be null or empty'); + } + + if($this->execute === null) + { + throw new ConfigurationException('ExecutionPolicy execute cannot be null'); + } + + try + { + $this->execute->validate(); + } + catch(ConfigurationException $e) + { + throw new ConfigurationException(sprintf('Invalid execution configuration for execution policy %s, %s', $this->name, $e->getMessage()), $e); + } + + if($this->exit_handlers !== null) + { + try + { + $this->exit_handlers->validate(); + } + catch(ConfigurationException $e) + { + throw new ConfigurationException(sprintf('Invalid exit handlers for execution policy %s, %s', $this->name, $e->getMessage()), $e); + } + } } /** diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php index 4cf3dd6..8ff95e2 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php @@ -27,57 +27,42 @@ use ncc\Enums\SpecialConstants\RuntimeConstants; use ncc\Exceptions\ConfigurationException; use ncc\Interfaces\BytecodeObjectInterface; + use ncc\Interfaces\ValidatableObjectInterface; use ncc\Utilities\Functions; class Execute implements BytecodeObjectInterface { /** - * The target file to execute - * * @var string */ private $target; /** - * The working directory to execute the policy in, if not specified the - * value "%CWD%" will be used as the default - * * @var string */ private $working_directory; /** - * Options to pass to the process - * * @var array */ private $options; /** - * An array of environment variables to pass on to the process - * * @var array */ private $environment_variables; /** - * Indicates if the output should be displayed or suppressed - * * @var bool */ private $silent; /** - * Indicates if the process should run in Tty mode (Overrides Silent & Pty mode) - * * @var bool */ private $tty; /** - * The number of seconds to wait before giving up on the process, will automatically execute the error handler - * if one is set. - * * @var int|null */ private $timeout; @@ -146,6 +131,8 @@ } /** + * Returns the options to pass to the process + * * @return array */ public function getOptions(): array @@ -154,6 +141,8 @@ } /** + * Sets the options to pass to the process + * * @param array $options */ public function setOptions(array $options): void @@ -162,6 +151,8 @@ } /** + * Returns an array of environment variables to pass on to the process + * * @return array */ public function getEnvironmentVariables(): array @@ -170,6 +161,8 @@ } /** + * Sets an array of environment variables to pass on to the process + * * @param array $environment_variables */ public function setEnvironmentVariables(array $environment_variables): void @@ -178,6 +171,8 @@ } /** + * Indicates if the output should be displayed or suppressed + * * @return bool */ public function isSilent(): bool @@ -186,6 +181,8 @@ } /** + * Sets if the output should be displayed or suppressed + * * @param bool $silent */ public function setSilent(bool $silent): void @@ -194,6 +191,8 @@ } /** + * Indicates if the process should run in Tty mode (Overrides Silent & Pty mode) + * * @return bool */ public function isTty(): bool @@ -202,6 +201,8 @@ } /** + * Sets if the process should run in Tty mode (Overrides Silent & Pty mode) + * * @param bool $tty */ public function setTty(bool $tty): void @@ -210,6 +211,8 @@ } /** + * Returns the number of seconds to wait before giving up on the process, will automatically execute the error + * * @return int|null */ public function getTimeout(): ?int @@ -218,6 +221,8 @@ } /** + * Sets the number of seconds to wait before giving up on the process, will automatically execute the error + * * @param int|null $timeout */ public function setTimeout(?int $timeout): void @@ -226,6 +231,8 @@ } /** + * Returns the number of seconds to wait before giving up on the process, will automatically execute the error + * * @return int|null */ public function getIdleTimeout(): ?int @@ -234,6 +241,8 @@ } /** + * Sets the number of seconds to wait before giving up on the process, will automatically execute the error + * * @param int|null $idle_timeout */ public function setIdleTimeout(?int $idle_timeout): void diff --git a/src/ncc/Objects/RepositoryQueryResults.php b/src/ncc/Objects/RepositoryQueryResults.php deleted file mode 100644 index 6bdf636..0000000 --- a/src/ncc/Objects/RepositoryQueryResults.php +++ /dev/null @@ -1,131 +0,0 @@ -files = new Files(); - } - - /** - * @return Files - */ - public function getFiles(): Files - { - return $this->files; - } - - /** - * @param Files $files - */ - public function setFiles(Files $files): void - { - $this->files = $files; - } - - /** - * @return string|null - */ - public function getVersion(): ?string - { - return $this->version; - } - - /** - * @param string|null $version - */ - public function setVersion(?string $version): void - { - $this->version = $version; - } - - /** - * @return string|null - */ - public function getReleaseName(): ?string - { - return $this->release_name; - } - - /** - * @param string|null $release_name - */ - public function setReleaseName(?string $release_name): void - { - $this->release_name = $release_name; - } - - /** - * @return string|null - */ - public function getReleaseDescription(): ?string - { - return $this->release_description; - } - - /** - * @param string|null $release_description - */ - public function setReleaseDescription(?string $release_description): void - { - $this->release_description = $release_description; - } - - } \ No newline at end of file