From e4e0c7b9b5a2f34ceeb830efc51eae0fd648a58a Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 5 Dec 2022 04:21:12 -0500 Subject: [PATCH 001/212] Added v1.0.0_alpha.md --- changelog/v1.0.0_alpha.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 changelog/v1.0.0_alpha.md diff --git a/changelog/v1.0.0_alpha.md b/changelog/v1.0.0_alpha.md new file mode 100644 index 0000000..1ccc539 --- /dev/null +++ b/changelog/v1.0.0_alpha.md @@ -0,0 +1,14 @@ +# v1.0.0 Alpha + +First release of NCC (Nosial Code Compiler) in alpha stage. + +## Note + +NCC is in it's alpha stage, meaning that it's not fully +functional and may not work on your system. If you find +any bugs or issues please report them to the +[Issue Tracker](https://git.n64.cc/intellivoid/ncc/issues). + +At the moment NCC is currently being used while developing +other software, this serves as a test run to improve on +changes for the next version. \ No newline at end of file -- 2.45.3 From 6371f260467a15f6760f98457af2400a28424e6d Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 6 Dec 2022 01:23:51 -0500 Subject: [PATCH 002/212] Added method array_replace_recursive() & recurse() to the installer which corrects issue #30 see https://git.n64.cc/nosial/ncc/-/issues/30 Updated some default values for ncc.yaml for better security. --- src/config/ncc.yaml | 7 ++-- src/installer/installer | 73 +++++++++++++++++++++++++++++++---------- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/config/ncc.yaml b/src/config/ncc.yaml index 0b713ba..f552647 100644 --- a/src/config/ncc.yaml +++ b/src/config/ncc.yaml @@ -23,9 +23,6 @@ php: # Whether to initialize NCC when running `require('ncc');` initialize_on_require: true - # if NCC should handle fatal exceptions during execution - handle_exceptions: true - git: # if git is enabled or not enabled: true @@ -55,10 +52,10 @@ composer: quiet: false # Disable ANSI output - no_ansi: false + no_ansi: true # Do not ask any interactive question - no_interaction: false + no_interaction: true # Display timing and memory usage information profile: false diff --git a/src/installer/installer b/src/installer/installer index 1cc4a21..6cfb6e5 100644 --- a/src/installer/installer +++ b/src/installer/installer @@ -712,7 +712,6 @@ $config_obj['composer']['enable_internal_composer'] = false; if($config_obj['composer']['executable_path'] == null) { - // TODO: Implement Configuration Tools Console::outWarning('Cannot locate the executable path for \'composer\', run \'ncc config --composer.executable_path="composer.phar"\' as root to update the path'); } } @@ -724,7 +723,7 @@ { if ($NCC_FILESYSTEM->exists(PathFinder::getConfigurationFile())) { - $config_backup = IO::fread(PathFinder::getConfigurationFile()); + $config_backup = Yaml::parseFile(PathFinder::getConfigurationFile()); } } catch (Exception $e) @@ -736,33 +735,73 @@ // Create/Update configuration file $config_obj = Yaml::parseFile(__DIR__ . DIRECTORY_SEPARATOR . 'default_config.yaml'); - // Update the old configuration - if($config_backup !== null) + if(!function_exists('array_replace_recursive')) { - $old_config_obj = Yaml::parse($config_backup); - foreach($old_config_obj as $section => $value) + /** + * @param $array + * @param $array1 + * @return array|mixed + * @author + * @noinspection PhpMissingReturnTypeInspection + */ + function array_replace_recursive($array, $array1) { - if(isset($config_obj[$section])) + // handle the arguments, merge one by one + $args = func_get_args(); + $array = $args[0]; + if (!is_array($array)) { - foreach($value as $section_item => $section_value) + return $array; + } + for ($i = 1; $i < count($args); $i++) + { + if (is_array($args[$i])) { - if(!isset($config_obj[$section][$section_item])) - { - $config_obj[$section][$section_item] = $section_value; - } + $array = recurse($array, $args[$i]); } } - else - { - $config_obj[$section] = $value; - } + return $array; } } + if(!function_exists('recurse')) + { + /** + * @param $array + * @param $array1 + * @return mixed + * @author + * @noinspection PhpMissingReturnTypeInspection + */ + function recurse($array, $array1) + { + foreach ($array1 as $key => $value) + { + // create new key in $array, if it is empty or not an array + /** @noinspection PhpConditionAlreadyCheckedInspection */ + if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key]))) + { + $array[$key] = array(); + } + + // overwrite the value in the base array + if (is_array($value)) + { + $value = recurse($array[$key], $value); + } + $array[$key] = $value; + } + return $array; + } + } + + + if($config_backup !== null) + $config_obj = array_replace_recursive($config_obj, $config_backup); + if($config_backup == null) { Console::out('Generating ncc.yaml'); - } else { -- 2.45.3 From f08ecb7947ec72f910f6b2047e11ffc0b7e7aa2a Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 6 Dec 2022 01:32:16 -0500 Subject: [PATCH 003/212] Added shutdown handler (for cli only) to clear cache ref #38 https://git.n64.cc/nosial/ncc/-/issues/38 --- src/ncc/CLI/Main.php | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index 793a8fc..af2f0cf 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -12,6 +12,7 @@ use ncc\ncc; use ncc\Utilities\Console; use ncc\Utilities\Resolver; + use ncc\Utilities\RuntimeCache; class Main { @@ -24,7 +25,7 @@ * @var string|null */ private static $log_level; - + /** * Executes the main CLI process * @@ -51,8 +52,8 @@ Console::outException('Cannot initialize NCC due to a runtime error.', $e, 1); } - // Define CLI stuff define('NCC_CLI_MODE', 1); + register_shutdown_function('ncc\CLI\Main::shutdown'); if(isset(self::$args['l']) || isset(self::$args['log-level'])) { @@ -82,13 +83,14 @@ if(Resolver::checkLogLevel(self::$log_level, LogLevel::Debug)) { Console::outDebug('Debug logging enabled'); - Console::outDebug(sprintf('consts: %s', json_encode(ncc::getConstants(), JSON_UNESCAPED_SLASHES))); + /** @noinspection PhpUnhandledExceptionInspection */ + Console::outDebug(sprintf('const: %s', json_encode(ncc::getConstants(), JSON_UNESCAPED_SLASHES))); Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES))); } if(in_array(NccBuildFlags::Unstable, NCC_VERSION_FLAGS)) { - //Console::outWarning('This is an unstable build of NCC, expect some features to not work as expected'); + Console::outWarning('This is an unstable build of NCC, expect some features to not work as expected'); } try @@ -152,4 +154,13 @@ return self::$log_level; } + /** + * @return void + */ + public static function shutdown() + { + Console::outDebug('clearing cache'); + RuntimeCache::clearCache(); + } + } \ No newline at end of file -- 2.45.3 From 9cef8e4394777614bf45a15f4bee06b30e8086e4 Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 6 Dec 2022 01:35:38 -0500 Subject: [PATCH 004/212] RuntimeCache.php code cleanup --- src/ncc/Utilities/RuntimeCache.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/ncc/Utilities/RuntimeCache.php b/src/ncc/Utilities/RuntimeCache.php index 9aad37e..fb12903 100644 --- a/src/ncc/Utilities/RuntimeCache.php +++ b/src/ncc/Utilities/RuntimeCache.php @@ -1,7 +1,10 @@ remove($file); + } + catch (Exception $e) + { + // Ignore + unset($e); + } } } } -- 2.45.3 From 9507cd6e43ae6335bd2daadf395ff76a0582afc6 Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 6 Dec 2022 01:40:14 -0500 Subject: [PATCH 005/212] Added more logging calls ref #29 https://git.n64.cc/nosial/ncc/-/issues/29 --- src/ncc/Utilities/RuntimeCache.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ncc/Utilities/RuntimeCache.php b/src/ncc/Utilities/RuntimeCache.php index fb12903..815cc2c 100644 --- a/src/ncc/Utilities/RuntimeCache.php +++ b/src/ncc/Utilities/RuntimeCache.php @@ -32,6 +32,7 @@ */ public static function set($key, $value): mixed { + Console::outDebug(sprintf('setting cache entry \'%s\'', $key)); self::$cache[$key] = $value; return $value; } @@ -44,6 +45,7 @@ */ public static function get($key): mixed { + Console::outDebug(sprintf('getting cache entry \'%s\'', $key)); if(isset(self::$cache[$key])) return self::$cache[$key]; @@ -58,6 +60,7 @@ */ public static function setFileAsTemporary(string $path): void { + Console::outDebug(sprintf('setting file \'%s\' as temporary', $path)); if(!in_array($path, self::$temporary_files)) self::$temporary_files[] = $path; } @@ -71,6 +74,7 @@ */ public static function removeFileAsTemporary(string $path): void { + Console::outDebug(sprintf('removing file \'%s\' from temporary files list', $path)); if(in_array($path, self::$temporary_files)) unset(self::$temporary_files[array_search($path, self::$temporary_files)]); } @@ -84,21 +88,24 @@ { if($clear_memory) { + Console::outDebug('clearing memory cache'); self::$cache = []; } if($clear_files) { + Console::outDebug('clearing temporary files'); $filesystem = new Filesystem(); foreach(self::$temporary_files as $file) { try { $filesystem->remove($file); + Console::outDebug(sprintf('deleted temporary file \'%s\'', $file)); } catch (Exception $e) { - // Ignore + Console::outDebug(sprintf('failed to delete temporary file \'%s\', %s', $file, $e->getMessage())); unset($e); } } -- 2.45.3 From 274f33a5c97ad35ebcd6ddb30013bd18705737f5 Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 6 Dec 2022 01:48:06 -0500 Subject: [PATCH 006/212] More efficient logging --- src/ncc/Utilities/RuntimeCache.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ncc/Utilities/RuntimeCache.php b/src/ncc/Utilities/RuntimeCache.php index 815cc2c..48708c8 100644 --- a/src/ncc/Utilities/RuntimeCache.php +++ b/src/ncc/Utilities/RuntimeCache.php @@ -32,7 +32,7 @@ */ public static function set($key, $value): mixed { - Console::outDebug(sprintf('setting cache entry \'%s\'', $key)); + Console::outDebug($key); self::$cache[$key] = $value; return $value; } @@ -45,7 +45,7 @@ */ public static function get($key): mixed { - Console::outDebug(sprintf('getting cache entry \'%s\'', $key)); + Console::outDebug($key); if(isset(self::$cache[$key])) return self::$cache[$key]; @@ -60,7 +60,7 @@ */ public static function setFileAsTemporary(string $path): void { - Console::outDebug(sprintf('setting file \'%s\' as temporary', $path)); + Console::outDebug($path); if(!in_array($path, self::$temporary_files)) self::$temporary_files[] = $path; } @@ -74,7 +74,7 @@ */ public static function removeFileAsTemporary(string $path): void { - Console::outDebug(sprintf('removing file \'%s\' from temporary files list', $path)); + Console::outDebug($path); if(in_array($path, self::$temporary_files)) unset(self::$temporary_files[array_search($path, self::$temporary_files)]); } @@ -88,7 +88,7 @@ { if($clear_memory) { - Console::outDebug('clearing memory cache'); + Console::outDebug(sprintf('clearing memory cache (%d entries)', count(self::$cache))); self::$cache = []; } -- 2.45.3 From 273d4b66129434cc2ca6f22e69a6e3ba2dbe2213 Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 6 Dec 2022 04:26:43 -0500 Subject: [PATCH 007/212] Refactored CredentialManager & Vault https://git.n64.cc/nosial/ncc/-/issues/27 --- ...icationType.php => AuthenticationType.php} | 6 +- src/ncc/Interfaces/PasswordInterface.php | 30 ++ src/ncc/Managers/CredentialManager.php | 119 +++--- src/ncc/Objects/Vault.php | 180 +++++++-- src/ncc/Objects/Vault/DefaultEntry.php | 60 --- src/ncc/Objects/Vault/Entry.php | 359 ++++++++++++++---- .../Objects/Vault/Password/AccessToken.php | 74 ++++ .../Vault/Password/UsernamePassword.php | 93 +++++ 8 files changed, 677 insertions(+), 244 deletions(-) rename src/ncc/Abstracts/{RemoteAuthenticationType.php => AuthenticationType.php} (60%) create mode 100644 src/ncc/Interfaces/PasswordInterface.php delete mode 100644 src/ncc/Objects/Vault/DefaultEntry.php create mode 100644 src/ncc/Objects/Vault/Password/AccessToken.php create mode 100644 src/ncc/Objects/Vault/Password/UsernamePassword.php diff --git a/src/ncc/Abstracts/RemoteAuthenticationType.php b/src/ncc/Abstracts/AuthenticationType.php similarity index 60% rename from src/ncc/Abstracts/RemoteAuthenticationType.php rename to src/ncc/Abstracts/AuthenticationType.php index 64233b3..044a977 100644 --- a/src/ncc/Abstracts/RemoteAuthenticationType.php +++ b/src/ncc/Abstracts/AuthenticationType.php @@ -2,15 +2,15 @@ namespace ncc\Abstracts; - abstract class RemoteAuthenticationType + abstract class AuthenticationType { /** * A combination of a username and password is used for authentication */ - const UsernamePassword = 'USERNAME_PASSWORD'; + const UsernamePassword = 1; /** * A single private access token is used for authentication */ - const PrivateAccessToken = 'PRIVATE_ACCESS_TOKEN'; + const AccessToken = 2; } \ No newline at end of file diff --git a/src/ncc/Interfaces/PasswordInterface.php b/src/ncc/Interfaces/PasswordInterface.php new file mode 100644 index 0000000..488c7dd --- /dev/null +++ b/src/ncc/Interfaces/PasswordInterface.php @@ -0,0 +1,30 @@ +CredentialsPath = PathFinder::getDataPath(Scopes::System) . DIRECTORY_SEPARATOR . 'credentials.store'; - } + $this->Vault = null; - /** - * Determines if CredentialManager has correct access to manage credentials on the system - * - * @return bool - */ - public function checkAccess(): bool - { - $ResolvedScope = Resolver::resolveScope(); - - if($ResolvedScope !== Scopes::System) + try { - return False; + $this->loadVault(); + } + catch(Exception $e) + { + unset($e); } - - return True; } /** @@ -64,95 +63,67 @@ if(file_exists($this->CredentialsPath)) return; - if(!$this->checkAccess()) - { + if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Cannot construct credentials store without system permissions'); - } $VaultObject = new Vault(); $VaultObject->Version = Versions::CredentialsStoreVersion; - IO::fwrite($this->CredentialsPath, ZiProto::encode($VaultObject->toArray()), 0600); + IO::fwrite($this->CredentialsPath, ZiProto::encode($VaultObject->toArray()), 0744); } /** - * Returns the vault object from the credentials store file. + * Loads the vault from the disk * - * @return Vault - * @throws AccessDeniedException - * @throws IOException - * @throws RuntimeException - */ - public function getVault(): Vault - { - $this->constructStore(); - - if(!$this->checkAccess()) - { - throw new AccessDeniedException('Cannot read credentials store without system permissions'); - } - - try - { - $Vault = ZiProto::decode(IO::fread($this->CredentialsPath)); - } - catch(Exception $e) - { - // TODO: Implement error-correction for corrupted credentials store. - throw new RuntimeException($e->getMessage(), $e); - } - - return Vault::fromArray($Vault); - } - - /** - * Saves the vault object to the credentials store - * - * @param Vault $vault * @return void * @throws AccessDeniedException * @throws IOException + * @throws RuntimeException + * @throws FileNotFoundException */ - public function saveVault(Vault $vault): void + public function loadVault(): void { - if(!$this->checkAccess()) + if($this->Vault !== null) + return; + + if(!file_exists($this->CredentialsPath)) { - throw new AccessDeniedException('Cannot write to credentials store without system permissions'); + $this->Vault = new Vault(); + return; } - IO::fwrite($this->CredentialsPath, ZiProto::encode($vault->toArray()), 0600); + $VaultArray = ZiProto::decode(IO::fread($this->CredentialsPath)); + $VaultObject = new Vault(); + $VaultObject->fromArray($VaultArray); + + if($VaultObject->Version !== Versions::CredentialsStoreVersion) + throw new RuntimeException('Credentials store version mismatch'); + + $this->Vault = $VaultObject; } /** - * Registers an entry to the credentials store file + * Saves the vault to the disk * - * @param Vault\Entry $entry * @return void * @throws AccessDeniedException - * @throws InvalidCredentialsEntryException - * @throws RuntimeException * @throws IOException + * @noinspection PhpUnused */ - public function registerEntry(Vault\Entry $entry): void + public function saveVault(): void { - if(!preg_match('/^[\w-]+$/', $entry->Alias)) - { - throw new InvalidCredentialsEntryException('The property \'Alias\' must be alphanumeric (Regex error)'); - } + if(Resolver::resolveScope() !== Scopes::System) + throw new AccessDeniedException('Cannot save credentials store without system permissions'); - // TODO: Implement more validation checks for the rest of the entry properties. - // TODO: Implement encryption for entries that require encryption (For securing passwords and data) - - $Vault = $this->getVault(); - $Vault->Entries[] = $entry; - - $this->saveVault($Vault); + IO::fwrite($this->CredentialsPath, ZiProto::encode($this->Vault->toArray()), 0744); } + /** - * @return null + * @return string + * @noinspection PhpUnused */ - public function getCredentialsPath(): ?string + public function getCredentialsPath(): string { return $this->CredentialsPath; } diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index 8a60105..c8440e3 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -1,9 +1,16 @@ Entries as $entry) { - $Entries[] = $entry->toArray(); + if($entry->getName() === $name) + return false; + } + + // Create the new entry + $entry = new Entry(); + $entry->setName($name); + $entry->setEncrypted($encrypt); + $entry->setAuthentication($password); + + // Add the entry to the vault + $this->Entries[] = $entry; + return true; + } + + /** + * Deletes an entry from the vault + * + * @param string $name + * @return bool + * @noinspection PhpUnused + */ + public function deleteEntry(string $name): bool + { + foreach($this->Entries as $entry) + { + if($entry->getName() === $name) + { + $this->Entries = array_diff($this->Entries, [$entry]); + return true; + } + } + + return false; + } + + /** + * Returns all the entries in the vault + * + * @return array|Entry[] + * @noinspection PhpUnused + */ + public function getEntries(): array + { + return $this->Entries; + } + + /** + * Returns an existing entry from the vault + * + * @param string $name + * @return Entry|null + */ + public function getEntry(string $name): ?Entry + { + foreach($this->Entries as $entry) + { + if($entry->getName() === $name) + return $entry; + } + + return null; + } + + /** + * Authenticates an entry in the vault + * + * @param string $name + * @param string $password + * @return bool + * @throws RuntimeException + * @noinspection PhpUnused + */ + public function authenticate(string $name, string $password): bool + { + $entry = $this->getEntry($name); + if($entry === null) + return false; + + if($entry->getPassword() === null) + { + if($entry->isEncrypted() && !$entry->isIsCurrentlyDecrypted()) + { + return $entry->unlock($password); + } + } + + $input = []; + switch($entry->getPassword()->getAuthenticationType()) + { + case AuthenticationType::UsernamePassword: + $input = ['password' => $password]; + break; + case AuthenticationType::AccessToken: + $input = ['token' => $password]; + break; + } + + return $entry->authenticate($input); + } + + /** + * Returns an array representation of the object + * + * @param bool $bytecode + * @return array + */ + public function toArray(bool $bytecode=false): array + { + $entries = []; + foreach($this->Entries as $entry) + { + $entry_array = $entry->toArray($bytecode); + + if($entry->getPassword() !== null && $entry->isEncrypted()) + { + $entry_array['password'] = Crypto::encryptWithPassword( + ZiProto::encode($entry_array['password']), $entry->getPassword()->__toString(), $bytecode + ); + } + + $entries[] = $entry_array; } return [ - 'version' => $this->Version, - 'entries' => $Entries + ($bytecode ? Functions::cbc('version') : 'version') => $this->Version, + ($bytecode ? Functions::cbc('entries') : 'entries') => $entries, ]; } /** - * Constructs an object from an array representation + * Constructs a new object from an array * - * @param array $data + * @param array $array * @return Vault */ - public static function fromArray(array $data): Vault + public static function fromArray(array $array): Vault { - $VaultObject = new Vault(); + $vault = new Vault(); + $vault->Version = Functions::array_bc($array, 'version'); + $entries = Functions::array_bc($array, 'entries'); - if(isset($data['version'])) - $VaultObject->Version = $data['version']; - - if(isset($data['entries'])) + foreach($entries as $entry) { - foreach($data['entries'] as $entry) - { - $VaultObject->Entries[] = Entry::fromArray($entry); - } + $entry = Entry::fromArray($entry); + $vault->Entries[] = $entry; } - return $VaultObject; + return $vault; } + } \ No newline at end of file diff --git a/src/ncc/Objects/Vault/DefaultEntry.php b/src/ncc/Objects/Vault/DefaultEntry.php deleted file mode 100644 index c834f0d..0000000 --- a/src/ncc/Objects/Vault/DefaultEntry.php +++ /dev/null @@ -1,60 +0,0 @@ - $this->Alias, - 'source' => $this->Source - ]; - } - - /** - * Constructs the object from an array representation - * - * @param array $data - * @return DefaultEntry - */ - public static function fromArray(array $data): DefaultEntry - { - $DefaultEntryObject = new DefaultEntry(); - - if(isset($data['alias'])) - { - $DefaultEntryObject->Alias = $data['alias']; - } - - if(isset($data['source'])) - { - $DefaultEntryObject->Source = $data['source']; - } - - return $DefaultEntryObject; - } - - } \ No newline at end of file diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php index 27c778f..e85df14 100644 --- a/src/ncc/Objects/Vault/Entry.php +++ b/src/ncc/Objects/Vault/Entry.php @@ -4,124 +4,327 @@ namespace ncc\Objects\Vault; - use ncc\Abstracts\RemoteAuthenticationType; - use ncc\Abstracts\RemoteSource; + use ncc\Abstracts\AuthenticationType; + use ncc\Defuse\Crypto\Crypto; + use ncc\Defuse\Crypto\Exception\EnvironmentIsBrokenException; + use ncc\Defuse\Crypto\Exception\WrongKeyOrModifiedCiphertextException; + use ncc\Exceptions\RuntimeException; + use ncc\Interfaces\PasswordInterface; + use ncc\Objects\Vault\Password\AccessToken; + use ncc\Objects\Vault\Password\UsernamePassword; + use ncc\Utilities\Functions; + use ncc\ZiProto\ZiProto; class Entry { /** - * The unique alias of the source entry, can also be used for remote resource fetching for dependencies with the - * following example schemes; - * - * - alias@github.com/org/package - * - alias@git.example.org/org/package - * - alias@gitlab.com/org/package + * The entry's unique identifier * * @var string */ - public $Alias; + private $Name; /** - * The remote source of the entry, currently only supported sources are allowed. - * - * @var string|RemoteSource - */ - public $Source; - - /** - * The host of the remote source, eg; github.com or git.example.org, will be used for remote resource fetching - * for dependencies with the following example schemes; - * - * - github.com/org/package - * - git.example.org/org/package - * - gitlab.com/org/package - * - * @var string - */ - public $SourceHost; - - /** - * @var string|RemoteAuthenticationType - */ - public $AuthenticationType; - - /** - * Indicates if the authentication details are encrypted or not, if encrypted a passphrase is required - * by the user + * Whether the entry's password is encrypted * * @var bool */ - public $Encrypted; + private $Encrypted; /** - * The authentication details. + * The entry's password * - * If the remote authentication type is private access token, the first index (0) would be the key itself - * If the remote authentication type is a username and password, first index would be Username and second - * would be the password. - * - * @var array + * @var PasswordInterface|string|null */ - public $Authentication; + private $Password; + + /** + * Whether the entry's password is currently decrypted in memory + * (Not serialized) + * + * @var bool + */ + private $IsCurrentlyDecrypted; /** * Returns an array representation of the object * - * @return array - * @noinspection PhpArrayShapeAttributeCanBeAddedInspection */ - public function toArray(): array + public function __construct() { + $this->Encrypted = true; + $this->IsCurrentlyDecrypted = true; + } + + /** + * Test Authenticates the entry + * + * For UsernamePassword the $input parameter expects an array with the keys 'username' and 'password' + * For AccessToken the $input parameter expects an array with the key 'token' + * + * @param array $input + * @return bool + * @noinspection PhpUnused + */ + public function authenticate(array $input): bool + { + if(!$this->IsCurrentlyDecrypted) + return false; + + if($this->Password == null) + return false; + + switch($this->Password->getAuthenticationType()) + { + case AuthenticationType::UsernamePassword: + if(!($this->Password instanceof UsernamePassword)) + return false; + + $username = $input['username'] ?? null; + $password = $input['password'] ?? null; + + if($username === null && $password === null) + return false; + + if($username == null) + return $password == $this->Password->Password; + + if($password == null) + return $username == $this->Password->Username; + + return $username == $this->Password->Username && $password == $this->Password->Password; + + case AuthenticationType::AccessToken: + if(!($this->Password instanceof AccessToken)) + return false; + + $token = $input['token'] ?? null; + + if($token === null) + return false; + + return $token == $this->Password->AccessToken; + + default: + return false; + + } + } + + /** + * @param PasswordInterface $password + * @return void + */ + public function setAuthentication(PasswordInterface $password): void + { + $this->Password = $password; + } + + /** + * @return bool + * @noinspection PhpUnused + */ + public function isIsCurrentlyDecrypted(): bool + { + return $this->IsCurrentlyDecrypted; + } + + /** + * Locks the entry by encrypting the password + * + * @return bool + */ + public function lock(): bool + { + if($this->Password == null) + return false; + + if($this->Encrypted) + return false; + + if(!$this->IsCurrentlyDecrypted) + return false; + + if(!($this->Password instanceof PasswordInterface)) + return false; + + $this->Password = $this->encrypt(); + return true; + } + + /** + * Unlocks the entry by decrypting the password + * + * @param string $password + * @return bool + * @throws RuntimeException + * @noinspection PhpUnused + */ + public function unlock(string $password): bool + { + if($this->Password == null) + return false; + + if(!$this->Encrypted) + return false; + + if($this->IsCurrentlyDecrypted) + return false; + + if(!is_string($this->Password)) + return false; + + try + { + $password = Crypto::decryptWithPassword($this->Password, $password, true); + } + catch (EnvironmentIsBrokenException $e) + { + throw new RuntimeException('Cannot decrypt password', $e); + } + catch (WrongKeyOrModifiedCiphertextException $e) + { + unset($e); + return false; + } + + $this->Password = ZiProto::decode($password); + $this->IsCurrentlyDecrypted = true; + + return true; + } + + /** + * Returns the password object as an encrypted binary string + * + * @return string|null + */ + private function encrypt(): ?string + { + if(!$this->IsCurrentlyDecrypted) + return false; + + if($this->Password == null) + return false; + + if(!($this->Password instanceof PasswordInterface)) + return null; + + $password = ZiProto::encode($this->Password->toArray(true)); + return Crypto::encryptWithPassword($password, $password, true); + } + + /** + * Returns an array representation of the object + * + * @param bool $bytecode + * @return array + */ + public function toArray(bool $bytecode=false): array + { + if(!$this->Password) + { + if($this->Encrypted && $this->IsCurrentlyDecrypted) + { + $password = $this->encrypt(); + } + else + { + $password = $this->Password->toArray(true); + } + } + else + { + $password = $this->Password; + } + return [ - 'alias' => $this->Alias, - 'source' => $this->Source, - 'source_host' => $this->SourceHost, - 'authentication_type' => $this->AuthenticationType, - 'encrypted' => $this->Encrypted, - 'authentication' => $this->Authentication + ($bytecode ? Functions::cbc('name') : 'name') => $this->Name, + ($bytecode ? Functions::cbc('encrypted') : 'encrypted') => $this->Encrypted, + ($bytecode ? Functions::cbc('password') : 'password') => $password, ]; } /** - * Returns an array representation of the object + * Constructs an object from an array representation * * @param array $data * @return Entry */ - public static function fromArray(array $data): Entry + public static function fromArray(array $data): self { - $EntryObject = new Entry(); + $self = new self(); - if(isset($data['alias'])) + $self->Name = Functions::array_bc($data, 'name'); + $self->Encrypted = Functions::array_bc($data, 'encrypted'); + + $password = Functions::array_bc($data, 'password'); + if($password !== null) { - $EntryObject->Alias = $data['alias']; + if($self->Encrypted) + { + $self->Password = $password; + $self->IsCurrentlyDecrypted = false; + } + elseif(gettype($password) == 'array') + { + $self->Password = match (Functions::array_bc($data, 'authentication_type')) { + AuthenticationType::UsernamePassword => UsernamePassword::fromArray($password), + AuthenticationType::AccessToken => AccessToken::fromArray($password) + }; + } } - if(isset($data['source'])) - { - $EntryObject->Source = $data['source']; - } + return $self; + } - if(isset($data['source_host'])) - { - $EntryObject->SourceHost = $data['source_host']; - } + /** + * @return bool + */ + public function isEncrypted(): bool + { + return $this->Encrypted; + } - if(isset($data['authentication_type'])) - { - $EntryObject->AuthenticationType = $data['authentication_type']; - } + /** + * Returns false if the entry needs to be decrypted first + * + * @param bool $Encrypted + * @return bool + */ + public function setEncrypted(bool $Encrypted): bool + { + if(!$this->IsCurrentlyDecrypted) + return false; - if(isset($data['encrypted'])) - { - $EntryObject->Encrypted = $data['encrypted']; - } + $this->Encrypted = $Encrypted; + return true; + } - if(isset($data['authentication'])) - { - $EntryObject->Authentication = $data['authentication']; - } + /** + * @return string + */ + public function getName(): string + { + return $this->Name; + } - return $EntryObject; + /** + * @param string $Name + */ + public function setName(string $Name): void + { + $this->Name = $Name; + } + + /** + * @return PasswordInterface|null + */ + public function getPassword(): ?PasswordInterface + { + if(!$this->IsCurrentlyDecrypted) + return null; + + return $this->Password; } } \ No newline at end of file diff --git a/src/ncc/Objects/Vault/Password/AccessToken.php b/src/ncc/Objects/Vault/Password/AccessToken.php new file mode 100644 index 0000000..ec00407 --- /dev/null +++ b/src/ncc/Objects/Vault/Password/AccessToken.php @@ -0,0 +1,74 @@ + AuthenticationType::AccessToken, + ($bytecode ? Functions::cbc('access_token') : 'access_token') => $this->AccessToken, + ]; + } + + /** + * Constructs an object from an array representation + * + * @param array $data + * @return static + */ + public static function fromArray(array $data): self + { + $object = new self(); + + $object->AccessToken = Functions::array_bc($data, 'access_token'); + + return $object; + } + + /** + * @return string + */ + public function getAccessToken(): string + { + return $this->AccessToken; + } + + /** + * @inheritDoc + */ + public function getAuthenticationType(): string + { + return AuthenticationType::AccessToken; + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function __toString(): string + { + return $this->AccessToken; + } + } \ No newline at end of file diff --git a/src/ncc/Objects/Vault/Password/UsernamePassword.php b/src/ncc/Objects/Vault/Password/UsernamePassword.php new file mode 100644 index 0000000..25097a6 --- /dev/null +++ b/src/ncc/Objects/Vault/Password/UsernamePassword.php @@ -0,0 +1,93 @@ + AuthenticationType::UsernamePassword, + ($bytecode ? Functions::cbc('username') : 'username') => $this->Username, + ($bytecode ? Functions::cbc('password') : 'password') => $this->Password, + ]; + } + + /** + * Constructs an object from an array representation + * + * @param array $data + * @return static + */ + public static function fromArray(array $data): self + { + $instance = new self(); + + $instance->Username = Functions::array_bc($data, 'username'); + $instance->Password = Functions::array_bc($data, 'password'); + + return $instance; + } + + /** + * @return string + * @noinspection PhpUnused + */ + public function getUsername(): string + { + return $this->Username; + } + + /** + * @return string + * @noinspection PhpUnused + */ + public function getPassword(): string + { + return $this->Password; + } + + /** + * @inheritDoc + */ + public function getAuthenticationType(): string + { + return AuthenticationType::UsernamePassword; + } + + /** + * Returns a string representation of the object + * + * @return string + */ + public function __toString(): string + { + return $this->Password; + } + } \ No newline at end of file -- 2.45.3 From e53bc97e4a95a1e1f930555096540b302d49a074 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 01:25:21 -0500 Subject: [PATCH 008/212] Refactored Vault & CredentialManager to support encryption and indexing. https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/Managers/CredentialManager.php | 13 +++++++++++- src/ncc/Objects/Vault.php | 13 ++---------- src/ncc/Objects/Vault/Entry.php | 17 ++++++++++------ .../Objects/Vault/Password/AccessToken.php | 8 ++++++++ .../Vault/Password/UsernamePassword.php | 20 +++++++++++++++++-- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/ncc/Managers/CredentialManager.php b/src/ncc/Managers/CredentialManager.php index cfe6c3d..606b8c5 100644 --- a/src/ncc/Managers/CredentialManager.php +++ b/src/ncc/Managers/CredentialManager.php @@ -47,6 +47,9 @@ { unset($e); } + + if($this->Vault == null) + $this->Vault = new Vault(); } /** @@ -81,7 +84,7 @@ * @throws RuntimeException * @throws FileNotFoundException */ - public function loadVault(): void + private function loadVault(): void { if($this->Vault !== null) return; @@ -127,4 +130,12 @@ { return $this->CredentialsPath; } + + /** + * @return Vault|null + */ + public function getVault(): ?Vault + { + return $this->Vault; + } } \ No newline at end of file diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index c8440e3..9f95e41 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -131,7 +131,7 @@ if($entry->getPassword() === null) { - if($entry->isEncrypted() && !$entry->isIsCurrentlyDecrypted()) + if($entry->isEncrypted() && !$entry->isCurrentlyDecrypted()) { return $entry->unlock($password); } @@ -162,16 +162,7 @@ $entries = []; foreach($this->Entries as $entry) { - $entry_array = $entry->toArray($bytecode); - - if($entry->getPassword() !== null && $entry->isEncrypted()) - { - $entry_array['password'] = Crypto::encryptWithPassword( - ZiProto::encode($entry_array['password']), $entry->getPassword()->__toString(), $bytecode - ); - } - - $entries[] = $entry_array; + $entries[] = $entry->toArray($bytecode);; } return [ diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php index e85df14..0925c41 100644 --- a/src/ncc/Objects/Vault/Entry.php +++ b/src/ncc/Objects/Vault/Entry.php @@ -87,12 +87,12 @@ return false; if($username == null) - return $password == $this->Password->Password; + return $password == $this->Password->getPassword(); if($password == null) - return $username == $this->Password->Username; + return $username == $this->Password->getUsername(); - return $username == $this->Password->Username && $password == $this->Password->Password; + return $username == $this->Password->getUsername() && $password == $this->Password->getPassword(); case AuthenticationType::AccessToken: if(!($this->Password instanceof AccessToken)) @@ -124,7 +124,7 @@ * @return bool * @noinspection PhpUnused */ - public function isIsCurrentlyDecrypted(): bool + public function isCurrentlyDecrypted(): bool { return $this->IsCurrentlyDecrypted; } @@ -222,12 +222,16 @@ */ public function toArray(bool $bytecode=false): array { - if(!$this->Password) + if($this->Password !== null) { if($this->Encrypted && $this->IsCurrentlyDecrypted) { $password = $this->encrypt(); } + elseif($this->Encrypted) + { + $password = $this->Password; + } else { $password = $this->Password->toArray(true); @@ -268,7 +272,8 @@ } elseif(gettype($password) == 'array') { - $self->Password = match (Functions::array_bc($data, 'authentication_type')) { + $self->Password = match (Functions::array_bc($data, 'authentication_type')) + { AuthenticationType::UsernamePassword => UsernamePassword::fromArray($password), AuthenticationType::AccessToken => AccessToken::fromArray($password) }; diff --git a/src/ncc/Objects/Vault/Password/AccessToken.php b/src/ncc/Objects/Vault/Password/AccessToken.php index ec00407..84420b6 100644 --- a/src/ncc/Objects/Vault/Password/AccessToken.php +++ b/src/ncc/Objects/Vault/Password/AccessToken.php @@ -71,4 +71,12 @@ { return $this->AccessToken; } + + /** + * @param string $AccessToken + */ + public function setAccessToken(string $AccessToken): void + { + $this->AccessToken = $AccessToken; + } } \ No newline at end of file diff --git a/src/ncc/Objects/Vault/Password/UsernamePassword.php b/src/ncc/Objects/Vault/Password/UsernamePassword.php index 25097a6..ca9c883 100644 --- a/src/ncc/Objects/Vault/Password/UsernamePassword.php +++ b/src/ncc/Objects/Vault/Password/UsernamePassword.php @@ -15,14 +15,14 @@ * * @var string */ - public $Username; + private $Username; /** * The entry's password * * @var string */ - public $Password; + private $Password; /** * Returns an array representation of the object @@ -90,4 +90,20 @@ { return $this->Password; } + + /** + * @param string $Username + */ + public function setUsername(string $Username): void + { + $this->Username = $Username; + } + + /** + * @param string $Password + */ + public function setPassword(string $Password): void + { + $this->Password = $Password; + } } \ No newline at end of file -- 2.45.3 From fb645aacc4feefe1f52c51bc09837ce8e722574e Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 01:25:47 -0500 Subject: [PATCH 009/212] Minor code corrections --- src/ncc/Objects/Vault.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index 9f95e41..f3ab09c 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -5,12 +5,10 @@ namespace ncc\Objects; use ncc\Abstracts\AuthenticationType; - use ncc\Defuse\Crypto\Crypto; use ncc\Exceptions\RuntimeException; use ncc\Interfaces\PasswordInterface; use ncc\Objects\Vault\Entry; use ncc\Utilities\Functions; - use ncc\ZiProto\ZiProto; class Vault { @@ -162,7 +160,7 @@ $entries = []; foreach($this->Entries as $entry) { - $entries[] = $entry->toArray($bytecode);; + $entries[] = $entry->toArray($bytecode); } return [ -- 2.45.3 From 8bda6da2dc2581cac482b3f8b5dfe3adeeaece30 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 01:28:08 -0500 Subject: [PATCH 010/212] Added `add` command to CredentialMenu & Detailed documentation in the help menu https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/CLI/CredentialMenu.php | 164 ++++++++++++++++++++++++++++---- src/ncc/Utilities/Console.php | 50 +++++++++- src/ncc/Utilities/Functions.php | 20 ++++ 3 files changed, 215 insertions(+), 19 deletions(-) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index a82336f..4013525 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -2,9 +2,14 @@ namespace ncc\CLI; + use Exception; use ncc\Abstracts\Scopes; - use ncc\Exceptions\AccessDeniedException; + use ncc\Managers\CredentialManager; use ncc\Objects\CliHelpSection; + use ncc\Objects\Vault\Password\AccessToken; + use ncc\Objects\Vault\Password\UsernamePassword; + use ncc\Utilities\Console; + use ncc\Utilities\Functions; use ncc\Utilities\Resolver; class CredentialMenu @@ -14,7 +19,7 @@ * * @param $args * @return void - * @throws AccessDeniedException + * @noinspection PhpNoReturnAttributeCanBeAddedInspection */ public static function start($args): void { @@ -31,18 +36,120 @@ /** * @param $args * @return void - * @throws AccessDeniedException */ public static function addCredential($args): void { $ResolvedScope = Resolver::resolveScope(); if($ResolvedScope !== Scopes::System) + Console::outError('Insufficient permissions to add credentials'); + + // Really dumb-proofing this + $name = $args['alias'] ?? $args['name'] ?? null; + $auth_type = $args['auth-type'] ?? $args['auth'] ?? null; + $username = $args['username'] ?? $args['usr'] ?? null; + $password = $args['password'] ?? $args['pwd'] ?? null; + $token = $args['token'] ?? $args['pat'] ?? $args['private-token'] ?? null; + $encrypt = $args['encrypt'] ?? $args['encrypted'] ?? null; + + if($name === null) + $name = Console::getInput('Enter a name for the entry: '); + + if($auth_type === null) + $auth_type = Console::getInput('Enter the authentication type (login or pat): '); + + if($auth_type === 'login') { - throw new AccessDeniedException('Root permissions are required to manage the vault'); + if($username === null) + $username = Console::getInput('Username: '); + + if($password === null) + $password = Console::passwordInput('Password: '); + } + elseif($auth_type === 'pat') + { + if($token === null) + $token = Console::passwordInput('Token: '); + } + else + { + Console::outError('Invalid authentication type'); } - print('end' . PHP_EOL); + if($encrypt === null) + $encrypt = Console::getBooleanInput('Encrypt entry with your password?'); + + if($name === null) + { + Console::outError('You must specify a name for the entry (alias, name)', true, 1); + return; + } + + if($auth_type === null) + { + Console::outError('You must specify an authentication type for the entry (auth-type, auth)', true, 1); + return; + } + + $encrypt = Functions::cbool($encrypt); + + switch($auth_type) + { + case 'login': + + if($username === null) + { + Console::outError('You must specify a username for the entry (username, usr)', true, 1); + return; + } + if($password === null) + { + Console::outError('You must specify a password for the entry (password, pwd)', true, 1); + return; + } + + $pass_object = new UsernamePassword(); + $pass_object->setUsername($username); + $pass_object->setPassword($password); + + break; + + case 'pat': + + if($token === null) + { + Console::outError('You must specify a token for the entry (token, pat, private-token)', true, 1); + return; + } + + $pass_object = new AccessToken(); + $pass_object->setAccessToken($token); + + break; + + default: + Console::outError('Invalid authentication type specified', true, 1); + return; + } + + $credential_manager = new CredentialManager(); + if(!$credential_manager->getVault()->addEntry($name, $pass_object, $encrypt)) + { + Console::outError('Failed to add entry, entry already exists.', true, 1); + return; + } + + try + { + $credential_manager->saveVault(); + } + catch(Exception $e) + { + Console::outException('Failed to save vault', $e, 1); + return; + } + + Console::out('Successfully added entry', true, 0); exit(0); } @@ -53,20 +160,43 @@ */ private static function displayOptions(): void { - $options = [ + Console::out('Usage: ncc vault {command} [options]'); + Console::out('Options:'); + Console::outHelpSections([ new CliHelpSection(['help'], 'Displays this help menu about the value command'), - new CliHelpSection(['add'], 'Adds a new credential to the vault'), - new CliHelpSection(['remove'], 'Adds a new credential to the vault'), - ]; + new CliHelpSection(['add'], 'Adds a new entry to the vault (See below)'), + new CliHelpSection(['remove', '--name'], 'Removes'), + ]); + Console::out((string)null); - $options_padding = \ncc\Utilities\Functions::detectParametersPadding($options) + 4; + Console::out('If you are adding a new entry, you can run the add command in interactive mode'); + Console::out('or you can specify the options below' . PHP_EOL); - print('Usage: ncc vault {command} [options]' . PHP_EOL); - print('Options:' . PHP_EOL); - foreach($options as $option) - { - print(' ' . $option->toString($options_padding) . PHP_EOL); - } - print(PHP_EOL); + Console::out('Add Options:'); + Console::outHelpSections([ + new CliHelpSection(['--name'], 'The name of the entry'), + new CliHelpSection(['--auth-type', '--auth'], 'The type of authentication (login, pat)'), + new CliHelpSection(['--encrypted', '--encrypt'], 'Whether or not to encrypt the entry', true), + ]); + + Console::out(' login authentication type options:'); + Console::outHelpSections([ + new CliHelpSection(['--username', '--usr'], 'The username for the entry'), + new CliHelpSection(['--password', '--pwd'], 'The password for the entry'), + ]); + + Console::out(' pat authentication type options:'); + Console::outHelpSections([ + new CliHelpSection(['--token', '--pat',], 'The private access token for the entry', true), + ]); + + Console::out('Authentication Types:'); + Console::out(' login'); + Console::out(' pat' . PHP_EOL); + + Console::out('Examples:'); + Console::out(' ncc vault add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" --encrypt'); + Console::out(' ncc vault add --alias "My Alias" --auth-type pat --token "mytoken"'); + Console::out(' ncc vault remove --alias "My Alias"'); } } \ No newline at end of file diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index 5b8437b..6ae82eb 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -1,12 +1,14 @@ -find('bash'); + + if($bash_path == null) + { + self::outWarning('Unable to find bash executable, cannot hide password input'); + return self::getInput($prompt); + } + + $prompt = escapeshellarg($prompt); + $random = Functions::randomString(10); + $command = "$bash_path -c 'read -s -p $prompt $random && echo \$" . $random . "'"; + $password = rtrim(shell_exec($command)); + self::out((string)null); + return $password; + } + + /** + * @param array $sections + * @return void + */ + public static function outHelpSections(array $sections): void + { + if(!ncc::cliMode()) + return; + + $padding = Functions::detectParametersPadding($sections); + + foreach($sections as $section) + Console::out(' ' . $section->toString($padding)); + } + } \ No newline at end of file diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index fa4096c..8bf97b4 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -376,6 +376,7 @@ * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException + * @noinspection PhpUnused */ public static function loadComposerJson(string $path): ComposerJson { @@ -430,6 +431,7 @@ * * @param string $property * @return mixed|null + * @noinspection PhpMissingReturnTypeInspection */ public static function getConfigurationProperty(string $property) { @@ -452,4 +454,22 @@ return Parser::parse($version)->toString(); } + + /** + * Returns a random string + * + * @param int $length + * @return string + */ + public static function randomString(int $length = 32): string + { + $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + $charactersLength = strlen($characters); + $randomString = ''; + for ($i = 0; $i < $length; $i++) + { + $randomString .= $characters[rand(0, $charactersLength - 1)]; + } + return $randomString; + } } \ No newline at end of file -- 2.45.3 From c99b58892f0ef50602c5e977ba4f5794cae25403 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 14:46:59 -0500 Subject: [PATCH 011/212] Shortened 'credential' in CLI to 'cred' --- src/ncc/CLI/CredentialMenu.php | 1 - src/ncc/CLI/HelpMenu.php | 2 +- src/ncc/CLI/Main.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index 4013525..f1e6fd9 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -30,7 +30,6 @@ self::displayOptions(); exit(0); - } /** diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index 140bae4..1351154 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -71,7 +71,7 @@ new CliHelpSection(['project'], 'Manages the current project'), new CliHelpSection(['package'], 'Manages the package system'), new CliHelpSection(['cache'], 'Manages the system cache'), - new CliHelpSection(['credential'], 'Manages credentials'), + new CliHelpSection(['cred'], 'Manages credentials'), new CliHelpSection(['config'], 'Changes NCC configuration values'), ]; $commands_padding = \ncc\Utilities\Functions::detectParametersPadding($commands) + 2; diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index af2f0cf..b5de035 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -109,7 +109,7 @@ BuildMenu::start(self::$args); exit(0); - case 'credential': + case 'cred': CredentialMenu::start(self::$args); exit(0); -- 2.45.3 From b9a356fe409347e473f7a2e59b5f836fd0825531 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 17:04:57 -0500 Subject: [PATCH 012/212] Added 'remove' command to CredentialMenu.php https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/CLI/CredentialMenu.php | 70 +++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index f1e6fd9..cb3ebc7 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -19,29 +19,50 @@ * * @param $args * @return void - * @noinspection PhpNoReturnAttributeCanBeAddedInspection */ public static function start($args): void { if(isset($args['add'])) { - self::addCredential($args); + try + { + self::addEntry($args); + } + catch(Exception $e) + { + Console::outException('Error while adding entry.', $e, 1); + } + + return; + } + + if(isset($args['remove'])) + { + try + { + self::removeEntry($args); + } + catch(Exception $e) + { + Console::outException('Cannot remove credential.', $e, 1); + } + + return; } self::displayOptions(); - exit(0); } /** * @param $args * @return void */ - public static function addCredential($args): void + public static function addEntry($args): void { $ResolvedScope = Resolver::resolveScope(); if($ResolvedScope !== Scopes::System) - Console::outError('Insufficient permissions to add credentials'); + Console::outError('Insufficient permissions to add entries'); // Really dumb-proofing this $name = $args['alias'] ?? $args['name'] ?? null; @@ -149,7 +170,44 @@ } Console::out('Successfully added entry', true, 0); - exit(0); + } + + /** + * Removes an existing entry from the vault. + * + * @param $args + * @return void + */ + private static function removeEntry($args): void + { + $ResolvedScope = Resolver::resolveScope(); + + if($ResolvedScope !== Scopes::System) + Console::outError('Insufficient permissions to remove entries'); + + $name = $args['alias'] ?? $args['name'] ?? null; + + if($name === null) + $name = Console::getInput('Enter the name of the entry to remove: '); + + $credential_manager = new CredentialManager(); + if(!$credential_manager->getVault()->deleteEntry($name)) + { + Console::outError('Failed to remove entry, entry does not exist.', true, 1); + return; + } + + try + { + $credential_manager->saveVault(); + } + catch(Exception $e) + { + Console::outException('Failed to save vault', $e, 1); + return; + } + + Console::out('Successfully removed entry', true, 0); } /** -- 2.45.3 From b465bcefa554ec9401635ca72ba90cf16da4e4ea Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 18:04:47 -0500 Subject: [PATCH 013/212] \ncc\CLI > Main > getArgs() will try to fetch $argv if available https://git.n64.cc/nosial/ncc/-/issues/23 --- src/ncc/CLI/Main.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index b5de035..1c571f6 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -31,6 +31,7 @@ * * @param $argv * @return void + * @throws RuntimeException */ public static function start($argv): void { @@ -137,10 +138,22 @@ } /** - * @return mixed + * @return array */ - public static function getArgs() + public static function getArgs(): array { + if (self::$args == null) + { + if(isset($argv)) + { + self::$args = Resolver::parseArguments(implode(' ', $argv)); + } + else + { + self::$args = []; + } + } + return self::$args; } @@ -157,7 +170,7 @@ /** * @return void */ - public static function shutdown() + public static function shutdown(): void { Console::outDebug('clearing cache'); RuntimeCache::clearCache(); -- 2.45.3 From f1e7aeccfaf801709c72dc2744e21264c540a3b7 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 18:06:42 -0500 Subject: [PATCH 014/212] Improved help menu https://git.n64.cc/nosial/ncc/-/issues/23 --- src/ncc/CLI/HelpMenu.php | 59 ++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 38 deletions(-) diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index 1351154..47c4b3c 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -2,8 +2,12 @@ namespace ncc\CLI; + use ncc\Exceptions\AccessDeniedException; + use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\IOException; use ncc\Objects\CliHelpSection; use ncc\Utilities\Console; + use ncc\Utilities\Functions; class HelpMenu { @@ -12,8 +16,11 @@ * * @param $args * @return void + * @throws AccessDeniedException + * @throws FileNotFoundException + * @throws IOException */ - public static function start($args) + public static function start($args): void { $basic_ascii = false; @@ -23,7 +30,7 @@ } // TODO: Make copyright not hard-coded. - print(\ncc\Utilities\Functions::getBanner(NCC_VERSION_BRANCH . ' ' . NCC_VERSION_NUMBER, 'Copyright (c) 2022-2022 Nosial', $basic_ascii) . PHP_EOL); + print(Functions::getBanner(NCC_VERSION_BRANCH . ' ' . NCC_VERSION_NUMBER, 'Copyright (c) 2022-2022 Nosial', $basic_ascii) . PHP_EOL); Console::out('Usage: ncc COMMAND [options]'); Console::out('Alternative Usage: ncc.php --ncc-cli=COMMAND [options]' . PHP_EOL); @@ -42,7 +49,8 @@ */ private static function displayMainOptions(): void { - $options = [ + Console::out('Options:'); + Console::outHelpSections([ new CliHelpSection(['{command} --help'], 'Displays help information about a specific command'), new CliHelpSection(['-v', '--version'], 'Display NCC version information'), new CliHelpSection(['-D', '--debug'], 'Enables debug mode'), @@ -50,14 +58,7 @@ new CliHelpSection(['--basic-ascii'], 'Uses basic ascii characters'), new CliHelpSection(['--no-color'], 'Omits the use of colors'), new CliHelpSection(['--no-banner'], 'Omits displaying the NCC ascii banner') - ]; - $options_padding = \ncc\Utilities\Functions::detectParametersPadding($options) + 4; - - Console::out('Options:'); - foreach($options as $option) - { - Console::out(' ' . $option->toString($options_padding)); - } + ]); } /** @@ -67,20 +68,14 @@ */ private static function displayManagementCommands(): void { - $commands = [ + Console::out('Management Commands:'); + Console::outHelpSections([ new CliHelpSection(['project'], 'Manages the current project'), new CliHelpSection(['package'], 'Manages the package system'), new CliHelpSection(['cache'], 'Manages the system cache'), new CliHelpSection(['cred'], 'Manages credentials'), new CliHelpSection(['config'], 'Changes NCC configuration values'), - ]; - $commands_padding = \ncc\Utilities\Functions::detectParametersPadding($commands) + 2; - - Console::out('Management Commands:'); - foreach($commands as $command) - { - Console::out(' ' . $command->toString($commands_padding)); - } + ]); } /** @@ -90,17 +85,11 @@ */ private static function displayMainCommands(): void { - $commands = [ + Console::out('Commands:'); + Console::outHelpSections([ new CliHelpSection(['build'], 'Builds the current project'), new CliHelpSection(['main'], 'Executes the main entrypoint of a package') - ]; - $commands_padding = \ncc\Utilities\Functions::detectParametersPadding($commands) + 2; - - Console::out('Commands:'); - foreach($commands as $command) - { - Console::out(' ' . $command->toString($commands_padding)); - } + ]); } /** @@ -110,15 +99,9 @@ */ private static function displayExtensions(): void { - $extensions = [ - new CliHelpSection(['exphp'], 'The PHP compiler extension') - ]; - $extensions_padding = \ncc\Utilities\Functions::detectParametersPadding($extensions) + 2; - Console::out('Extensions:'); - foreach($extensions as $command) - { - Console::out(' ' . $command->toString($extensions_padding)); - } + Console::outHelpSections([ + new CliHelpSection(['exphp'], 'The PHP compiler extension') + ]); } } \ No newline at end of file -- 2.45.3 From 5a83a7f6fe1f9bec9bc48bdc29c15dd72eebd851 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 18:08:15 -0500 Subject: [PATCH 015/212] Minor bug fixes when parsing Vault https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/Managers/CredentialManager.php | 3 +-- src/ncc/Objects/Vault.php | 8 ++++---- src/ncc/Objects/Vault/Entry.php | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/ncc/Managers/CredentialManager.php b/src/ncc/Managers/CredentialManager.php index 606b8c5..d90bcc1 100644 --- a/src/ncc/Managers/CredentialManager.php +++ b/src/ncc/Managers/CredentialManager.php @@ -96,8 +96,7 @@ } $VaultArray = ZiProto::decode(IO::fread($this->CredentialsPath)); - $VaultObject = new Vault(); - $VaultObject->fromArray($VaultArray); + $VaultObject = Vault::fromArray($VaultArray); if($VaultObject->Version !== Versions::CredentialsStoreVersion) throw new RuntimeException('Credentials store version mismatch'); diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index f3ab09c..65e1698 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -5,6 +5,7 @@ namespace ncc\Objects; use ncc\Abstracts\AuthenticationType; + use ncc\Abstracts\Versions; use ncc\Exceptions\RuntimeException; use ncc\Interfaces\PasswordInterface; use ncc\Objects\Vault\Entry; @@ -31,6 +32,7 @@ */ public function __construct() { + $this->Version = Versions::CredentialsStoreVersion; $this->Entries = []; } @@ -180,12 +182,10 @@ $vault = new Vault(); $vault->Version = Functions::array_bc($array, 'version'); $entries = Functions::array_bc($array, 'entries'); + $vault->Entries = []; foreach($entries as $entry) - { - $entry = Entry::fromArray($entry); - $vault->Entries[] = $entry; - } + $vault->Entries[] = Entry::fromArray($entry); return $vault; } diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php index 0925c41..f0d4b1e 100644 --- a/src/ncc/Objects/Vault/Entry.php +++ b/src/ncc/Objects/Vault/Entry.php @@ -261,8 +261,8 @@ $self->Name = Functions::array_bc($data, 'name'); $self->Encrypted = Functions::array_bc($data, 'encrypted'); - $password = Functions::array_bc($data, 'password'); + if($password !== null) { if($self->Encrypted) @@ -272,7 +272,7 @@ } elseif(gettype($password) == 'array') { - $self->Password = match (Functions::array_bc($data, 'authentication_type')) + $self->Password = match (Functions::array_bc($password, 'authentication_type')) { AuthenticationType::UsernamePassword => UsernamePassword::fromArray($password), AuthenticationType::AccessToken => AccessToken::fromArray($password) -- 2.45.3 From c6b67016f22e2906c36c251341dbe1c68ebc962e Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 18:08:38 -0500 Subject: [PATCH 016/212] Added 'list' command to CredentialMenu.php --- src/ncc/CLI/CredentialMenu.php | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index cb3ebc7..faf2fce 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -50,9 +50,47 @@ return; } + if(isset($args['list'])) + { + try + { + self::listEntries(); + } + catch(Exception $e) + { + Console::outException('Cannot list credentials.', $e, 1); + } + + return; + } + self::displayOptions(); } + /** + * Prints the list of entries in the vault + * + * @return void + */ + public static function listEntries(): void + { + $credential_manager = new CredentialManager(); + $entries = $credential_manager->getVault()->getEntries(); + + if(count($entries) === 0) + { + Console::out('No credentials found.'); + return; + } + + foreach($entries as $entry) + { + Console::out(sprintf('%s%s', $entry->getName(), ($entry->isEncrypted() ? ' (encrypted)' : ''))); + } + + Console::out('Total: ' . count($entries)); + } + /** * @param $args * @return void -- 2.45.3 From e38a4df2eea93a9734998df91d29a15c7bf666d8 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 18:08:38 -0500 Subject: [PATCH 017/212] Added 'list' command to CredentialMenu.php https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/CLI/CredentialMenu.php | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index cb3ebc7..faf2fce 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -50,9 +50,47 @@ return; } + if(isset($args['list'])) + { + try + { + self::listEntries(); + } + catch(Exception $e) + { + Console::outException('Cannot list credentials.', $e, 1); + } + + return; + } + self::displayOptions(); } + /** + * Prints the list of entries in the vault + * + * @return void + */ + public static function listEntries(): void + { + $credential_manager = new CredentialManager(); + $entries = $credential_manager->getVault()->getEntries(); + + if(count($entries) === 0) + { + Console::out('No credentials found.'); + return; + } + + foreach($entries as $entry) + { + Console::out(sprintf('%s%s', $entry->getName(), ($entry->isEncrypted() ? ' (encrypted)' : ''))); + } + + Console::out('Total: ' . count($entries)); + } + /** * @param $args * @return void -- 2.45.3 From 9716ad8e61d6924f26de16726ca928b96e280adf Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 18:24:48 -0500 Subject: [PATCH 018/212] Updated CredentialMenu.php help menu https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/CLI/CredentialMenu.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index faf2fce..85e1ff0 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -260,7 +260,8 @@ Console::outHelpSections([ new CliHelpSection(['help'], 'Displays this help menu about the value command'), new CliHelpSection(['add'], 'Adds a new entry to the vault (See below)'), - new CliHelpSection(['remove', '--name'], 'Removes'), + new CliHelpSection(['remove', '--name'], 'Removes an entry from the vault'), + new CliHelpSection(['list'], 'Lists all entries in the vault'), ]); Console::out((string)null); -- 2.45.3 From 33e373c798b2f821d7896d67be1fef293fff806b Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 19:47:44 -0500 Subject: [PATCH 019/212] Bug fix in \ncc\Objects > Vault > deleteEntry() https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/Objects/Vault.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index 65e1698..87338b5 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -74,15 +74,18 @@ */ public function deleteEntry(string $name): bool { - foreach($this->Entries as $entry) + // Find the entry + foreach($this->Entries as $index => $entry) { if($entry->getName() === $name) { - $this->Entries = array_diff($this->Entries, [$entry]); + // Remove the entry + unset($this->Entries[$index]); return true; } } + // Entry not found return false; } -- 2.45.3 From 3fc50e04e599e24c037d29319cee3e66b9d7eb29 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 19:48:12 -0500 Subject: [PATCH 020/212] Disabled password prompt due to instability https://git.n64.cc/nosial/ncc/-/issues/23 --- src/ncc/Utilities/Console.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index 6ae82eb..4323bd0 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -1,6 +1,8 @@ -find('bash'); @@ -454,6 +460,7 @@ namespace ncc\Utilities; $password = rtrim(shell_exec($command)); self::out((string)null); return $password; + **/ } /** -- 2.45.3 From ec1aaf1d0ffc94a5aebcdf0c2b097b2692f754fd Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 19:53:10 -0500 Subject: [PATCH 021/212] Minor bug fix in \ncc\Objects\Vault > Entry > unlock() https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/Objects/Vault/Entry.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php index f0d4b1e..6f52b6b 100644 --- a/src/ncc/Objects/Vault/Entry.php +++ b/src/ncc/Objects/Vault/Entry.php @@ -149,6 +149,7 @@ return false; $this->Password = $this->encrypt(); + var_dump($this->Password); return true; } @@ -210,8 +211,8 @@ if(!($this->Password instanceof PasswordInterface)) return null; - $password = ZiProto::encode($this->Password->toArray(true)); - return Crypto::encryptWithPassword($password, $password, true); + $data = ZiProto::encode($this->Password->toArray(true)); + return Crypto::encryptWithPassword($data, (string)$this->Password, true); } /** -- 2.45.3 From f2bc94292a2b8b8055f6c8829b088ed1eb62a536 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 19:55:11 -0500 Subject: [PATCH 022/212] Added command 'test' to test an entry https://git.n64.cc/nosial/ncc/-/issues/27 --- src/ncc/CLI/CredentialMenu.php | 86 ++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index 85e1ff0..436e8ab 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -4,6 +4,7 @@ use Exception; use ncc\Abstracts\Scopes; + use ncc\Exceptions\RuntimeException; use ncc\Managers\CredentialManager; use ncc\Objects\CliHelpSection; use ncc\Objects\Vault\Password\AccessToken; @@ -44,7 +45,7 @@ } catch(Exception $e) { - Console::outException('Cannot remove credential.', $e, 1); + Console::outException('Cannot remove entry.', $e, 1); } return; @@ -58,7 +59,21 @@ } catch(Exception $e) { - Console::outException('Cannot list credentials.', $e, 1); + Console::outException('Cannot list entries.', $e, 1); + } + + return; + } + + if(isset($args['test'])) + { + try + { + self::testEntry($args); + } + catch(Exception $e) + { + Console::outException('Cannot test entry.', $e, 1); } return; @@ -67,6 +82,71 @@ self::displayOptions(); } + /** + * Tests an entry authentication + * + * @param $args + * @return void + */ + public static function testEntry($args): void + { + $name = $args['name'] ?? $args['alias'] ?? null; + + if($name === null) + { + Console::outError('Please specify a name or alias for the entry.', true, 1); + return; + } + + $credential_manager = new CredentialManager(); + $entry = $credential_manager->getVault()->getEntry($name); + + if($entry === null) + { + Console::out('Entry not found.', true, 1); + return; + } + + if($entry->isEncrypted()) + { + $tries = 0; + + while(true) + { + try + { + $password = Console::passwordInput('Password/Secret: '); + if (!$entry->unlock($password)) + { + $tries++; + if ($tries >= 3) + { + Console::outError('Too many failed attempts.', true, 1); + return; + } + + Console::outError('Invalid password.', true, 1); + } + else + { + Console::out('Authentication successful.'); + return; + } + } + catch (RuntimeException $e) + { + Console::outException('Cannot unlock entry.', $e, 1); + return; + } + } + } + + else + { + Console::out('Authentication always successful, entry is not encrypted.'); + } + } + /** * Prints the list of entries in the vault * @@ -79,7 +159,7 @@ if(count($entries) === 0) { - Console::out('No credentials found.'); + Console::out('No entries found.'); return; } -- 2.45.3 From f8a7e22f5996fd94eae5aab96944b6489a6ce089 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 20:33:42 -0500 Subject: [PATCH 023/212] Updated ComposerSource to display license information and authors. https://git.n64.cc/nosial/ncc/-/issues/40 --- .../ComposerExtension/ComposerSource.php | 58 +++++++++++++++++-- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/src/ncc/Classes/ComposerExtension/ComposerSource.php b/src/ncc/Classes/ComposerExtension/ComposerSource.php index d732939..31f3d9b 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSource.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSource.php @@ -148,8 +148,6 @@ $source_directories = []; $static_files = []; - // TODO: Implement static files handling - // Extract all the source directories if ($package->Autoload->Psr4 !== null && count($package->Autoload->Psr4) > 0) { @@ -221,18 +219,68 @@ if (count($static_files) > 0) { $project_configuration->Project->Options['static_files'] = $static_files; - $parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName()); - if (!$filesystem->exists($source_directory . DIRECTORY_SEPARATOR . $parsed_path)) + + foreach ($static_files as $file) { + $parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $file); Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name)); - $filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path); + $filesystem->copy($file, $source_directory . DIRECTORY_SEPARATOR . $parsed_path); } + unset($file); } $project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json'); } // Load the project + $license_files = [ + 'LICENSE', + 'license', + 'LICENSE.txt', + 'license.txt' + ]; + + foreach($license_files as $license_file) + { + if($filesystem->exists($package_path . DIRECTORY_SEPARATOR . $license_file)) + { + // Check configuration if composer.extension.display_licenses is set + if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_licenses'))) + { + Console::out(sprintf('License for package %s:', $package->Name)); + Console::out(IO::fread($package_path . DIRECTORY_SEPARATOR . $license_file)); + } + } + } + + if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_authors'))) + { + if($package->Authors !== null && count($package->Authors) > 0) + { + Console::out(sprintf('Authors for package %s:', $package->Name)); + foreach($package->Authors as $author) + { + Console::out(sprintf(' - %s', $author->Name)); + + if($author->Email !== null) + { + Console::out(sprintf(' %s', $author->Email)); + } + + if($author->Homepage !== null) + { + Console::out(sprintf(' %s', $author->Homepage)); + } + + if($author->Role !== null) + { + Console::out(sprintf(' %s', $author->Role)); + } + + } + } + } + $project_manager = new ProjectManager($package_path); $project_manager->load(); $built_package = $project_manager->build(); -- 2.45.3 From 2a7b92ca94bb5accae0cf3664ae9b23f4b81847d Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 20:40:57 -0500 Subject: [PATCH 024/212] Minor Correction --- src/ncc/Utilities/Console.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index 4323bd0..c492611 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -441,7 +441,7 @@ if(!ncc::cliMode()) return null; - Console::outWarning('passwordInput() is not properly implemented yet, defaulting to prompt'); + // passwordInput() is not properly implemented yet, defaulting to prompt return self::getInput($prompt); /** -- 2.45.3 From a60981380f802683137e94680c88abd2c2d26da8 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 20:58:00 -0500 Subject: [PATCH 025/212] Added method \ncc\Utilities > PathFinder > findRunner() to simplify the process of finding a runner executable via the config or locally https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Utilities/PathFinder.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index a67b640..340eb6f 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -2,8 +2,11 @@ namespace ncc\Utilities; + use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Exceptions\InvalidScopeException; + use ncc\Exceptions\RunnerExecutionException; + use ncc\ThirdParty\Symfony\Process\ExecutableFinder; class PathFinder { @@ -213,4 +216,32 @@ { return self::getDataPath(Scopes::System) . DIRECTORY_SEPARATOR . 'ncc.yaml'; } + + /** + * Attempts to locate the executable path of the given program name + * + * @param string $runner + * @return string + * @throws RunnerExecutionException + */ + public static function findRunner(string $runner): string + { + $executable_finder = new ExecutableFinder(); + + $config_value = Functions::getConfigurationProperty(sprintf('runners.%s', $runner)); + if($config_value !== null) + { + if(file_exists($config_value) && is_executable($config_value)) + return $config_value; + + Console::outWarning(sprintf('The configured \'%s\' executable path is invalid, trying to find it automatically...', $runner)); + } + + $exec_path = $executable_finder->find($runner); + + if($exec_path !== null) + return $exec_path; + + throw new RunnerExecutionException(sprintf('Unable to find \'%s\' executable', $runner)); + } } \ No newline at end of file -- 2.45.3 From 2842e63637800a7d19bc224c07821d209bee8d9e Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 20:59:06 -0500 Subject: [PATCH 026/212] Improved PhpRunner.php https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Classes/PhpExtension/PhpRunner.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/ncc/Classes/PhpExtension/PhpRunner.php b/src/ncc/Classes/PhpExtension/PhpRunner.php index 100a807..6792057 100644 --- a/src/ncc/Classes/PhpExtension/PhpRunner.php +++ b/src/ncc/Classes/PhpExtension/PhpRunner.php @@ -2,6 +2,7 @@ namespace ncc\Classes\PhpExtension; + use ncc\Abstracts\Runners; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; @@ -10,10 +11,10 @@ use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\ExecutableFinder; use ncc\ThirdParty\Symfony\Process\Process; use ncc\Utilities\Base64; use ncc\Utilities\IO; + use ncc\Utilities\PathFinder; class PhpRunner implements RunnerInterface { @@ -28,12 +29,11 @@ public static function processUnit(string $path, ExecutionPolicy $policy): ExecutionUnit { $execution_unit = new ExecutionUnit(); - $target_file = $path; - if(!file_exists($target_file) && !is_file($target_file)) - throw new FileNotFoundException($target_file); + if(!file_exists($path) && !is_file($path)) + throw new FileNotFoundException($path); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($target_file)); + $execution_unit->Data = Base64::encode(IO::fread($path)); return $execution_unit; } @@ -55,10 +55,7 @@ */ public static function prepareProcess(ExecutionPointer $pointer): Process { - $php_bin = new ExecutableFinder(); - $php_bin = $php_bin->find('php'); - if($php_bin == null) - throw new RunnerExecutionException('Cannot locate PHP executable'); + $php_bin = PathFinder::findRunner(Runners::php); if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) return new Process(array_merge([$php_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); -- 2.45.3 From f4abc020ec409c86e55d61918a3d2f9f07d3884e Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 20:59:34 -0500 Subject: [PATCH 027/212] Added more Runners to \ncc\Abstracts > Runners https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Abstracts/Runners.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/ncc/Abstracts/Runners.php b/src/ncc/Abstracts/Runners.php index 5a0e052..85dc5fe 100644 --- a/src/ncc/Abstracts/Runners.php +++ b/src/ncc/Abstracts/Runners.php @@ -5,4 +5,30 @@ abstract class Runners { const php = 'php'; + + const bash = 'bash'; + + const sh = 'sh'; + + const python = 'python'; + + const python3 = 'python3'; + + const python2 = 'python2'; + + const perl = 'perl'; + + const lua = 'lua'; + + + const All = [ + self::php, + self::bash, + self::sh, + self::python, + self::python3, + self::python2, + self::perl, + self::lua + ]; } \ No newline at end of file -- 2.45.3 From daa954bd7623bcc430fede79560b56ebb3d4ccef Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 20:59:55 -0500 Subject: [PATCH 028/212] Updated build flag --- src/ncc/Abstracts/NccBuildFlags.php | 2 +- src/ncc/version.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ncc/Abstracts/NccBuildFlags.php b/src/ncc/Abstracts/NccBuildFlags.php index 7d27a69..c156b08 100644 --- a/src/ncc/Abstracts/NccBuildFlags.php +++ b/src/ncc/Abstracts/NccBuildFlags.php @@ -8,5 +8,5 @@ * Indicates if the build is currently unstable and some features may not work correctly * and can cause errors */ - const Unstable = 'UNSTABLE'; + const Unstable = 'unstable'; } \ No newline at end of file diff --git a/src/ncc/version.json b/src/ncc/version.json index aab248b..0f0ae15 100644 --- a/src/ncc/version.json +++ b/src/ncc/version.json @@ -1,7 +1,7 @@ { "version": "1.0.0", - "branch": "master", - "flags": ["UNSTABLE"], + "branch": "v1.0.0_alpha", + "flags": [], "components": [ { "vendor": "defuse", -- 2.45.3 From 388d856503be5c14aef47c63b71c46ed893d6108 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 21:17:25 -0500 Subject: [PATCH 029/212] Added example ExecutionPolicy files --- tests/example_project/scripts/unit.bash | 3 +++ tests/example_project/scripts/unit.lua | 4 ++++ tests/example_project/scripts/unit.php | 5 +++++ tests/example_project/scripts/unit.pl | 6 ++++++ tests/example_project/scripts/unit.py2 | 3 +++ tests/example_project/scripts/unit.py3 | 3 +++ 6 files changed, 24 insertions(+) create mode 100644 tests/example_project/scripts/unit.bash create mode 100644 tests/example_project/scripts/unit.lua create mode 100644 tests/example_project/scripts/unit.php create mode 100644 tests/example_project/scripts/unit.pl create mode 100644 tests/example_project/scripts/unit.py2 create mode 100644 tests/example_project/scripts/unit.py3 diff --git a/tests/example_project/scripts/unit.bash b/tests/example_project/scripts/unit.bash new file mode 100644 index 0000000..cf03e95 --- /dev/null +++ b/tests/example_project/scripts/unit.bash @@ -0,0 +1,3 @@ +echo "Hello World!" +read -p "What is your name? " name +echo "Hello $name" \ No newline at end of file diff --git a/tests/example_project/scripts/unit.lua b/tests/example_project/scripts/unit.lua new file mode 100644 index 0000000..866d929 --- /dev/null +++ b/tests/example_project/scripts/unit.lua @@ -0,0 +1,4 @@ +print("Hello World!") +print("What is your name?") +name = io.read() +print("Hello " .. name) diff --git a/tests/example_project/scripts/unit.php b/tests/example_project/scripts/unit.php new file mode 100644 index 0000000..b318314 --- /dev/null +++ b/tests/example_project/scripts/unit.php @@ -0,0 +1,5 @@ +; +chomp($name); +print("Hello, $name\n"); \ No newline at end of file diff --git a/tests/example_project/scripts/unit.py2 b/tests/example_project/scripts/unit.py2 new file mode 100644 index 0000000..af4b858 --- /dev/null +++ b/tests/example_project/scripts/unit.py2 @@ -0,0 +1,3 @@ +print('Hello World!') +name = input('What is your name? ') +print('Hello', name) \ No newline at end of file diff --git a/tests/example_project/scripts/unit.py3 b/tests/example_project/scripts/unit.py3 new file mode 100644 index 0000000..af4b858 --- /dev/null +++ b/tests/example_project/scripts/unit.py3 @@ -0,0 +1,3 @@ +print('Hello World!') +name = input('What is your name? ') +print('Hello', name) \ No newline at end of file -- 2.45.3 From 6679da80220b3d2b35d485641185c0d87eaa7675 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 21:48:52 -0500 Subject: [PATCH 030/212] Updated execution_policy.md https://git.n64.cc/nosial/ncc/-/issues/35 --- .../project_configuration/execution_policy.md | 140 +++++++++++++++++- 1 file changed, 134 insertions(+), 6 deletions(-) diff --git a/docs/project_configuration/execution_policy.md b/docs/project_configuration/execution_policy.md index f5b851b..db304c2 100644 --- a/docs/project_configuration/execution_policy.md +++ b/docs/project_configuration/execution_policy.md @@ -1,6 +1,6 @@ # Execution Policies -**Updated on Sunday, November 20, 2022** +**Updated on Wednesday, December 07, 2022** An execution policy is a policy defined in the Project configuration file (`project.json`) that can be used @@ -24,13 +24,20 @@ handled by NCC's compiler extensions. * [JSON Example](#json-example) * [ExecutionPolicy Object](#executionpolicy-object) * [Object Properties](#object-properties) - * [JSON Example](#json-example) + * [JSON Example](#json-example-1) * [ExecutionConfiguration Object](#executionconfiguration-object) - * [Object Properties](#object-properties) - * [JSON Example](#json-example) + * [Object Properties](#object-properties-1) + * [JSON Example](#json-example-2) * [ExitHandler Object](#exithandler-object) - * [Object Properties](#object-properties) - * [JSON Example](#json-example) + * [Object Properties](#object-properties-2) + * [JSON Example](#json-example-3) + * [More Examples](#more-examples) + * [bash](#bash) + * [lua](#lua) + * [php](#php) + * [perl](#perl) + * [python (or python2/python3)](#python--or-python2python3-) + * [shell](#shell) @@ -148,4 +155,125 @@ an exit handler is specified it will be executed. "run": null, "exit_code": 1 } +``` + + +## More Examples + +Just like the `project.json` file, you can have multiple +execution policies in your project, here are some examples +of how you can use them: + +### bash + +```json +{ + "execution_policies": [ + { + "name": "main", + "runner": "bash", + "message": "Running main %ASSEMBLY.PACKAGE%", + "exec": { + "target": "scripts/main.bash", + "working_directory": "%INSTALL_PATH.SRC%", + "silent": false + } + } + ] +} +``` + +### lua + +```json +{ + "execution_policies": [ + { + "name": "main", + "runner": "lua", + "message": "Running main %ASSEMBLY.PACKAGE%", + "exec": { + "target": "scripts/main.lua", + "working_directory": "%INSTALL_PATH.SRC%", + "silent": false + } + } + ] +} +``` + +### php + +```json +{ + "execution_policies": [ + { + "name": "main", + "runner": "php", + "message": "Running main %ASSEMBLY.PACKAGE%", + "exec": { + "target": "scripts/main.php", + "working_directory": "%INSTALL_PATH.SRC%", + "silent": false + } + } + ] +} +``` + +### perl + +```json +{ + "execution_policies": [ + { + "name": "main", + "runner": "perl", + "message": "Running main %ASSEMBLY.PACKAGE%", + "exec": { + "target": "scripts/main.pl", + "working_directory": "%INSTALL_PATH.SRC%", + "silent": false + } + } + ] +} +``` + +### python (or python2/python3) + +```json +{ + "execution_policies": [ + { + "name": "main", + "runner": "python", + "message": "Running main %ASSEMBLY.PACKAGE%", + "exec": { + "target": "scripts/main.py", + "working_directory": "%INSTALL_PATH.SRC%", + "silent": false + } + } + ] +} +``` + +### shell + +```json +{ + "execution_policies": [ + { + "name": "main", + "runner": "shell", + "message": "Running main %ASSEMBLY.PACKAGE%", + "exec": { + "target": "scripts/main.sh", + "working_directory": "%INSTALL_PATH.SRC%", + "silent": false + } + } + ] +} ``` \ No newline at end of file -- 2.45.3 From 852be3087bc48199643b1e5c80b8116a9b1f8014 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 21:56:02 -0500 Subject: [PATCH 031/212] Implemented Bash runner https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Classes/BashExtension/BashRunner.php | 53 ++++++++++++++++++++ src/ncc/Managers/ExecutionPointerManager.php | 3 ++ src/ncc/Utilities/Functions.php | 2 + 3 files changed, 58 insertions(+) create mode 100644 src/ncc/Classes/BashExtension/BashRunner.php diff --git a/src/ncc/Classes/BashExtension/BashRunner.php b/src/ncc/Classes/BashExtension/BashRunner.php new file mode 100644 index 0000000..6a8e953 --- /dev/null +++ b/src/ncc/Classes/BashExtension/BashRunner.php @@ -0,0 +1,53 @@ +Execute->Target = null; + $execution_unit->ExecutionPolicy = $policy; + $execution_unit->Data = Base64::encode(IO::fread($path)); + + return $execution_unit; + } + + /** + * @inheritDoc + */ + public static function getFileExtension(): string + { + return '.bash'; + } + + /** + * @inheritDoc + */ + public static function prepareProcess(ExecutionPointer $pointer): Process + { + $bash_bin = PathFinder::findRunner(Runners::bash); + + if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) + return new Process(array_merge([$bash_bin, '-c', $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); + return new Process([$bash_bin, '-c', $pointer->FilePointer]); + } + } \ No newline at end of file diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index c2f2dbb..775b439 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -7,6 +7,7 @@ use Exception; use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; + use ncc\Classes\BashExtension\BashRunner; use ncc\Classes\PhpExtension\PhpRunner; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\ExecutionUnitNotFoundException; @@ -140,6 +141,7 @@ $bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name); $bin_file .= match ($unit->ExecutionPolicy->Runner) { + Runners::bash => BashRunner::getFileExtension(), Runners::php => PhpRunner::getFileExtension(), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; @@ -272,6 +274,7 @@ $process = match (strtolower($unit->ExecutionPolicy->Runner)) { + Runners::bash => BashRunner::prepareProcess($unit), Runners::php => PhpRunner::prepareProcess($unit), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 8bf97b4..5e196c8 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -5,6 +5,7 @@ use Exception; use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; + use ncc\Classes\BashExtension\BashRunner; use ncc\Classes\PhpExtension\PhpRunner; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; @@ -257,6 +258,7 @@ public static function compileRunner(string $path, ExecutionPolicy $policy): ExecutionUnit { return match (strtolower($policy->Runner)) { + Runners::bash => BashRunner::processUnit($path, $policy), Runners::php => PhpRunner::processUnit($path, $policy), default => throw new UnsupportedRunnerException('The runner \'' . $policy->Runner . '\' is not supported'), }; -- 2.45.3 From 71cda91c42fa9d8564d47806714e056dff732b30 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 22:53:18 -0500 Subject: [PATCH 032/212] Added PerlRunner https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Classes/PerlExtension/PerlRunner.php | 53 ++++++++++++++++++++ src/ncc/Managers/ExecutionPointerManager.php | 3 ++ src/ncc/Utilities/Functions.php | 2 + 3 files changed, 58 insertions(+) create mode 100644 src/ncc/Classes/PerlExtension/PerlRunner.php diff --git a/src/ncc/Classes/PerlExtension/PerlRunner.php b/src/ncc/Classes/PerlExtension/PerlRunner.php new file mode 100644 index 0000000..0be4cdb --- /dev/null +++ b/src/ncc/Classes/PerlExtension/PerlRunner.php @@ -0,0 +1,53 @@ +Execute->Target = null; + if(!file_exists($path) && !is_file($path)) + throw new FileNotFoundException($path); + $execution_unit->ExecutionPolicy = $policy; + $execution_unit->Data = Base64::encode(IO::fread($path)); + + return $execution_unit; + } + + /** + * @inheritDoc + */ + public static function getFileExtension(): string + { + return '.pl'; + } + + /** + * @inheritDoc + */ + public static function prepareProcess(ExecutionPointer $pointer): Process + { + $perl_bin = PathFinder::findRunner(Runners::perl); + + if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) + return new Process(array_merge([$perl_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); + return new Process([$perl_bin, $pointer->FilePointer]); + } + } \ No newline at end of file diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 775b439..34192e6 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -8,6 +8,7 @@ use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; + use ncc\Classes\PerlExtension\PerlRunner; use ncc\Classes\PhpExtension\PhpRunner; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\ExecutionUnitNotFoundException; @@ -143,6 +144,7 @@ $bin_file .= match ($unit->ExecutionPolicy->Runner) { Runners::bash => BashRunner::getFileExtension(), Runners::php => PhpRunner::getFileExtension(), + Runners::perl => PerlRunner::getFileExtension(), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; @@ -276,6 +278,7 @@ { Runners::bash => BashRunner::prepareProcess($unit), Runners::php => PhpRunner::prepareProcess($unit), + Runners::perl => PerlRunner::prepareProcess($unit), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 5e196c8..294ac7a 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -6,6 +6,7 @@ use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; + use ncc\Classes\PerlExtension\PerlRunner; use ncc\Classes\PhpExtension\PhpRunner; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; @@ -260,6 +261,7 @@ return match (strtolower($policy->Runner)) { Runners::bash => BashRunner::processUnit($path, $policy), Runners::php => PhpRunner::processUnit($path, $policy), + Runners::perl => PerlRunner::processUnit($path, $policy), default => throw new UnsupportedRunnerException('The runner \'' . $policy->Runner . '\' is not supported'), }; } -- 2.45.3 From d2acf224f382c8f6ff299a1a52944c6eb31dade1 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 22:57:42 -0500 Subject: [PATCH 033/212] Added PythonRunner https://git.n64.cc/nosial/ncc/-/issues/32 --- .../Classes/PythonExtension/PythonRunner.php | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/ncc/Classes/PythonExtension/PythonRunner.php diff --git a/src/ncc/Classes/PythonExtension/PythonRunner.php b/src/ncc/Classes/PythonExtension/PythonRunner.php new file mode 100644 index 0000000..d3b2baa --- /dev/null +++ b/src/ncc/Classes/PythonExtension/PythonRunner.php @@ -0,0 +1,53 @@ +Execute->Target = null; + $execution_unit->ExecutionPolicy = $policy; + $execution_unit->Data = Base64::encode(IO::fread($path)); + + return $execution_unit; + } + + /** + * @inheritDoc + */ + public static function getFileExtension(): string + { + return '.py'; + } + + /** + * @inheritDoc + */ + public static function prepareProcess(ExecutionPointer $pointer): Process + { + $python_bin = PathFinder::findRunner(Runners::python); + + if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) + return new Process(array_merge([$python_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); + return new Process([$python_bin, $pointer->FilePointer]); + } +} \ No newline at end of file -- 2.45.3 From e7e2cca62abfcffdb7d322731a5c5f71f630a4ae Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 22:59:15 -0500 Subject: [PATCH 034/212] Added Python3Runner https://git.n64.cc/nosial/ncc/-/issues/32 --- .../Classes/PythonExtension/Python3Runner.php | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/ncc/Classes/PythonExtension/Python3Runner.php diff --git a/src/ncc/Classes/PythonExtension/Python3Runner.php b/src/ncc/Classes/PythonExtension/Python3Runner.php new file mode 100644 index 0000000..94b5447 --- /dev/null +++ b/src/ncc/Classes/PythonExtension/Python3Runner.php @@ -0,0 +1,53 @@ +Execute->Target = null; + $execution_unit->ExecutionPolicy = $policy; + $execution_unit->Data = Base64::encode(IO::fread($path)); + + return $execution_unit; + } + + /** + * @inheritDoc + */ + public static function getFileExtension(): string + { + return '.py'; + } + + /** + * @inheritDoc + */ + public static function prepareProcess(ExecutionPointer $pointer): Process + { + $python_bin = PathFinder::findRunner(Runners::python3); + + if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) + return new Process(array_merge([$python_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); + return new Process([$python_bin, $pointer->FilePointer]); + } + } \ No newline at end of file -- 2.45.3 From afb69cd9ea1df518d2113c917ed16c878444e68e Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 23:03:13 -0500 Subject: [PATCH 035/212] Added Python2Runner https://git.n64.cc/nosial/ncc/-/issues/32 --- .../Classes/PythonExtension/Python2Runner.php | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/ncc/Classes/PythonExtension/Python2Runner.php diff --git a/src/ncc/Classes/PythonExtension/Python2Runner.php b/src/ncc/Classes/PythonExtension/Python2Runner.php new file mode 100644 index 0000000..0f8ca05 --- /dev/null +++ b/src/ncc/Classes/PythonExtension/Python2Runner.php @@ -0,0 +1,53 @@ +Execute->Target = null; + $execution_unit->ExecutionPolicy = $policy; + $execution_unit->Data = Base64::encode(IO::fread($path)); + + return $execution_unit; + } + + /** + * @inheritDoc + */ + public static function getFileExtension(): string + { + return '.py'; + } + + /** + * @inheritDoc + */ + public static function prepareProcess(ExecutionPointer $pointer): Process + { + $python_bin = PathFinder::findRunner(Runners::python2); + + if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) + return new Process(array_merge([$python_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); + return new Process([$python_bin, $pointer->FilePointer]); + } + } \ No newline at end of file -- 2.45.3 From ef43b1ccbc8331c4e53312f3a5544b09699a4ea5 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 23:05:27 -0500 Subject: [PATCH 036/212] Added LuaRunner https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Classes/LuaExtension/LuaRunner.php | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/ncc/Classes/LuaExtension/LuaRunner.php diff --git a/src/ncc/Classes/LuaExtension/LuaRunner.php b/src/ncc/Classes/LuaExtension/LuaRunner.php new file mode 100644 index 0000000..fba88c4 --- /dev/null +++ b/src/ncc/Classes/LuaExtension/LuaRunner.php @@ -0,0 +1,50 @@ +Execute->Target = null; + $execution_unit->ExecutionPolicy = $policy; + $execution_unit->Data = Base64::encode(IO::fread($path)); + + return $execution_unit; + } + + /** + * @inheritDoc + */ + public static function getFileExtension(): string + { + return '.lua'; + } + + /** + * @inheritDoc + */ + public static function prepareProcess(ExecutionPointer $pointer): Process + { + $lua_bin = PathFinder::findRunner(Runners::lua); + + if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) + return new Process(array_merge([$lua_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); + return new Process([$lua_bin, $pointer->FilePointer]); + } + } \ No newline at end of file -- 2.45.3 From 87e67564fae10b86cfa92d5dfb06d0e9d722bf72 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 23:11:27 -0500 Subject: [PATCH 037/212] Fully implemented all the runners https://git.n64.cc/nosial/ncc/-/issues/32 --- src/ncc/Abstracts/Runners.php | 3 --- src/ncc/Managers/ExecutionPointerManager.php | 12 ++++++++++++ src/ncc/Utilities/Functions.php | 8 ++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/ncc/Abstracts/Runners.php b/src/ncc/Abstracts/Runners.php index 85dc5fe..f6576c5 100644 --- a/src/ncc/Abstracts/Runners.php +++ b/src/ncc/Abstracts/Runners.php @@ -8,8 +8,6 @@ const bash = 'bash'; - const sh = 'sh'; - const python = 'python'; const python3 = 'python3'; @@ -24,7 +22,6 @@ const All = [ self::php, self::bash, - self::sh, self::python, self::python3, self::python2, diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 34192e6..765b5dc 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -8,8 +8,12 @@ use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; + use ncc\Classes\LuaExtension\LuaRunner; use ncc\Classes\PerlExtension\PerlRunner; use ncc\Classes\PhpExtension\PhpRunner; + use ncc\Classes\PythonExtension\Python2Runner; + use ncc\Classes\PythonExtension\Python3Runner; + use ncc\Classes\PythonExtension\PythonRunner; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\ExecutionUnitNotFoundException; use ncc\Exceptions\FileNotFoundException; @@ -145,6 +149,10 @@ Runners::bash => BashRunner::getFileExtension(), Runners::php => PhpRunner::getFileExtension(), Runners::perl => PerlRunner::getFileExtension(), + Runners::python => PythonRunner::getFileExtension(), + Runners::python2 => Python2Runner::getFileExtension(), + Runners::python3 => Python3Runner::getFileExtension(), + Runners::lua => LuaRunner::getFileExtension(), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; @@ -279,6 +287,10 @@ Runners::bash => BashRunner::prepareProcess($unit), Runners::php => PhpRunner::prepareProcess($unit), Runners::perl => PerlRunner::prepareProcess($unit), + Runners::python => PythonRunner::prepareProcess($unit), + Runners::python2 => Python2Runner::prepareProcess($unit), + Runners::python3 => Python3Runner::prepareProcess($unt), + Runners::lua => LuaRunner::prepareProcess($unit), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 294ac7a..13e6413 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -6,8 +6,12 @@ use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; + use ncc\Classes\LuaExtension\LuaRunner; use ncc\Classes\PerlExtension\PerlRunner; use ncc\Classes\PhpExtension\PhpRunner; + use ncc\Classes\PythonExtension\Python2Runner; + use ncc\Classes\PythonExtension\Python3Runner; + use ncc\Classes\PythonExtension\PythonRunner; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\InvalidScopeException; @@ -262,6 +266,10 @@ Runners::bash => BashRunner::processUnit($path, $policy), Runners::php => PhpRunner::processUnit($path, $policy), Runners::perl => PerlRunner::processUnit($path, $policy), + Runners::python => PythonRunner::processUnit($path, $policy), + Runners::python2 => Python2Runner::processUnit($path, $policy), + Runners::python3 => Python3Runner::processUnit($path, $policy), + Runners::lua => LuaRunner::processUnit($path, $policy), default => throw new UnsupportedRunnerException('The runner \'' . $policy->Runner . '\' is not supported'), }; } -- 2.45.3 From a5811839721a0139197d97a913c8b90350d20781 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 23:20:38 -0500 Subject: [PATCH 038/212] Added logging call to \ncc\Managers > ConfigurationManager > updateProperty() https://git.n64.cc/nosial/ncc/-/issues/29 --- src/ncc/Managers/ConfigurationManager.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ncc/Managers/ConfigurationManager.php b/src/ncc/Managers/ConfigurationManager.php index e605c74..8ec173c 100644 --- a/src/ncc/Managers/ConfigurationManager.php +++ b/src/ncc/Managers/ConfigurationManager.php @@ -12,6 +12,7 @@ use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; use ncc\ThirdParty\Symfony\Yaml\Yaml; + use ncc\Utilities\Console; use ncc\Utilities\Functions; use ncc\Utilities\IO; use ncc\Utilities\PathFinder; @@ -88,6 +89,7 @@ */ public function getProperty(string $property) { + Console::outDebug($property); $current_selection = $this->getConfiguration(); foreach(explode('.', strtolower($property)) as $property) { -- 2.45.3 From 4a252c030202e24a134d6d7342c8b16539070ad4 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 7 Dec 2022 23:21:22 -0500 Subject: [PATCH 039/212] Corrected Help Menu in CredentialMenu.php --- src/ncc/CLI/CredentialMenu.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ncc/CLI/CredentialMenu.php b/src/ncc/CLI/CredentialMenu.php index 436e8ab..0e31b5c 100644 --- a/src/ncc/CLI/CredentialMenu.php +++ b/src/ncc/CLI/CredentialMenu.php @@ -335,7 +335,7 @@ */ private static function displayOptions(): void { - Console::out('Usage: ncc vault {command} [options]'); + Console::out('Usage: ncc cred {command} [options]'); Console::out('Options:'); Console::outHelpSections([ new CliHelpSection(['help'], 'Displays this help menu about the value command'), @@ -371,8 +371,8 @@ Console::out(' pat' . PHP_EOL); Console::out('Examples:'); - Console::out(' ncc vault add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" --encrypt'); - Console::out(' ncc vault add --alias "My Alias" --auth-type pat --token "mytoken"'); - Console::out(' ncc vault remove --alias "My Alias"'); + Console::out(' ncc cred add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" --encrypt'); + Console::out(' ncc cred add --alias "My Alias" --auth-type pat --token "mytoken"'); + Console::out(' ncc cred remove --alias "My Alias"'); } } \ No newline at end of file -- 2.45.3 From dbf010970065952e7adf7c325e830a3897e94322 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 8 Dec 2022 16:23:02 -0500 Subject: [PATCH 040/212] Updated license, added MIT License for NCC --- LICENSE | 363 ++---------------------------------------------------- LICENSES | 346 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 22 ++-- 3 files changed, 367 insertions(+), 364 deletions(-) create mode 100644 LICENSES diff --git a/LICENSE b/LICENSE index 3fad6f1..db24663 100644 --- a/LICENSE +++ b/LICENSE @@ -1,355 +1,14 @@ ------------------------- -Nosial - NCC +Copyright 2022 Nosial - All Rights Reserved. -Copyright (C) 2022-2022. Nosial - All Rights Reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following conditions: -Unauthorized copying of this file, via any medium is strictly prohibited -Proprietary and confidential, written by Zi Xing Narrakas +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the +Software. ------------------------- -Symfony - Process - -Copyright (c) 2004-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------------------- -defuse - php-encryption - -The MIT License (MIT) - -Copyright (c) 2016 Taylor Hornby -Copyright (c) 2016 Paragon Initiative Enterprises . - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------------------------- -Symfony - uid - -Copyright (c) 2020-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - polyfill-mbstring - -Copyright (c) 2015-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - polyfill-ctype - -Copyright (c) 2018-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - polyfill-uuid - -Copyright (c) 2018-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - - ------------------------- -dealnews.com, Inc. - Inline ProgressBar CLI - -Copyright (c) 2010, dealnews.com, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of dealnews.com, Inc. nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -Symfony - Filesystem - -Copyright (c) 2004-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - Yaml - -Copyright (c) 2004-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------------------- -theseer - Autoload - -Autoload Builder - -Copyright (c) 2010-2016 Arne Blankerts and Contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Arne Blankerts nor the names of contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -theseer - DirectoryScanner - -DirectoryScanner - -Copyright (c) 2009-2014 Arne Blankerts -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Arne Blankerts nor the names of contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -nikic - PhpParser - -BSD 3-Clause License - -Copyright (c) 2011, Nikita Popov -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -jelix - version - -Copyright (C) 2009-2016 Laurent Jouanneau - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/LICENSES b/LICENSES new file mode 100644 index 0000000..6a475e7 --- /dev/null +++ b/LICENSES @@ -0,0 +1,346 @@ +Symfony - Process + +Copyright (c) 2004-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +------------------------ +defuse - php-encryption + +The MIT License (MIT) + +Copyright (c) 2016 Taylor Hornby +Copyright (c) 2016 Paragon Initiative Enterprises . + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +------------------------ +Symfony - uid + +Copyright (c) 2020-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +------------------------ +Symfony - polyfill-mbstring + +Copyright (c) 2015-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +------------------------ +Symfony - polyfill-ctype + +Copyright (c) 2018-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +------------------------ +Symfony - polyfill-uuid + +Copyright (c) 2018-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + +------------------------ +dealnews.com, Inc. - Inline ProgressBar CLI + +Copyright (c) 2010, dealnews.com, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of dealnews.com, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +------------------------ +Symfony - Filesystem + +Copyright (c) 2004-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +------------------------ +Symfony - Yaml + +Copyright (c) 2004-2022 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +------------------------ +theseer - Autoload + +Autoload Builder + +Copyright (c) 2010-2016 Arne Blankerts and Contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of Arne Blankerts nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +------------------------ +theseer - DirectoryScanner + +DirectoryScanner + +Copyright (c) 2009-2014 Arne Blankerts +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of Arne Blankerts nor the names of contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +------------------------ +nikic - PhpParser + +BSD 3-Clause License + +Copyright (c) 2011, Nikita Popov +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +------------------------ +jelix - version + +Copyright (C) 2009-2016 Laurent Jouanneau + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 9db1970..4d02c30 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,15 @@ Nosial Code Compiler is a program written in PHP designed to be a multi-purpose This program is a complete re-write of the now defunct [PHP Package Manager (PPM)](https://git.n64.cc/intellivoid/ppm) toolkit offering more features, security and proper code licensing and copyrighting for the components used for the project. -NCC Cannot compile, read or use PPM packages (.ppm) files or work with project sources designed to be built with PPM, however -a PPM extension may be built in the future to allow for backwards compatibility. +### Alpha Stage +NCC is currently in alpha stage, meaning that it's not fully functional and may not work on your system. If you find any bugs +or issues please report them to the [GitHub Issue Tracker](https://git.n64.cc/intellivoid/ncc/issues). -## Notes +At the moment NCC is currently being used while developing other software, this serves as a test run to +improve on changes for the next version. - > While NCC has windows compatibility in mind, not all compiler extensions or features will work correctly. NCC is - > designed to be used in production in a Unix environment and Windows should only be used for development purposes. +### Notes > Compiler extensions requires their own set of dependencies to be met, for example Java compilers will require JDK @@ -29,13 +30,10 @@ a PPM extension may be built in the future to allow for backwards compatibility. ## Copyright - Copyright (c) 2022-2022, Nosial - All Rights Reserved -- Copyright (c) 2004-2022, Fabien Potencier -- Copyright (c) 2010, dealnews.com, Inc. All rights reserved. -- Copyright (c) 2013 Austin Hyde -- Copyright (C) 2009-2016 Laurent Jouanneau -- Copyright (c) 2011, Nikita Popov -- Copyright (c) 2010-2016 Arne Blankerts and Contributors # Licenses -Multiple licenses can be found at [LICENSE](LICENSE) \ No newline at end of file +NCC is licensed under the MIT License, see [LICENSE](LICENSE) for more information. + +Multiple licenses for the open source components used in this +project can be found at [LICENSE](LICENSES) \ No newline at end of file -- 2.45.3 From 4f9f78e21d17c654e08f7d2565a8f2dba7952089 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 9 Dec 2022 00:25:41 -0500 Subject: [PATCH 041/212] Added HttpClient --- src/ncc/Abstracts/ExceptionCodes.php | 8 +- src/ncc/Abstracts/HttpRequestType.php | 11 +++ src/ncc/Abstracts/HttpStatusCodes.php | 104 ++++++++++++++++++++++++ src/ncc/Exceptions/HttpException.php | 20 +++++ src/ncc/Objects/HttpRequest.php | 87 ++++++++++++++++++++ src/ncc/Objects/HttpResponse.php | 50 ++++++++++++ src/ncc/Utilities/HttpClient.php | 111 ++++++++++++++++++++++++++ 7 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 src/ncc/Abstracts/HttpRequestType.php create mode 100644 src/ncc/Abstracts/HttpStatusCodes.php create mode 100644 src/ncc/Exceptions/HttpException.php create mode 100644 src/ncc/Objects/HttpRequest.php create mode 100644 src/ncc/Objects/HttpResponse.php create mode 100644 src/ncc/Utilities/HttpClient.php diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 06b2192..995041b 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -268,6 +268,11 @@ */ const MissingDependencyException = -1751; + /** + * @see HttpException + */ + const HttpException = -1752; + /** * All the exception codes from NCC */ @@ -322,6 +327,7 @@ self::ComposerNotAvailableException, self::ComposerException, self::UserAbortedOperationException, - self::MissingDependencyException + self::MissingDependencyException, + self::HttpException ]; } \ No newline at end of file diff --git a/src/ncc/Abstracts/HttpRequestType.php b/src/ncc/Abstracts/HttpRequestType.php new file mode 100644 index 0000000..75ba864 --- /dev/null +++ b/src/ncc/Abstracts/HttpRequestType.php @@ -0,0 +1,11 @@ +message = $message; + } + } \ No newline at end of file diff --git a/src/ncc/Objects/HttpRequest.php b/src/ncc/Objects/HttpRequest.php new file mode 100644 index 0000000..fc3760f --- /dev/null +++ b/src/ncc/Objects/HttpRequest.php @@ -0,0 +1,87 @@ +Type = HttpRequestType::GET; + $this->Body = null; + $this->Headers = [ + 'User-Agent: ncc/1.0' + ]; + } + + /** + * Returns an array representation of the object. + * + * @return array + */ + public function toArray(): array + { + return [ + 'type' => $this->Type, + 'url' => $this->Url, + 'headers' => $this->Headers, + 'body' => $this->Body, + 'authentication' => $this->Authentication + ]; + } + + /** + * Constructs a new HttpRequest object from an array representation. + * + * @param array $data + * @return static + */ + public static function fromArray(array $data): self + { + $request = new self(); + $request->Type = $data['type']; + $request->Url = $data['url']; + $request->Headers = $data['headers']; + $request->Body = $data['body']; + $request->Authentication = $data['authentication']; + return $request; + } + } \ No newline at end of file diff --git a/src/ncc/Objects/HttpResponse.php b/src/ncc/Objects/HttpResponse.php new file mode 100644 index 0000000..fe9f9dd --- /dev/null +++ b/src/ncc/Objects/HttpResponse.php @@ -0,0 +1,50 @@ +StatusCode = 0; + $this->Headers = []; + $this->Body = ''; + } + + /** + * Returns an array representation of the object. + * + * @return array + */ + public function toArray(): array + { + return [ + 'status_code' => $this->StatusCode, + 'headers' => $this->Headers, + 'body' => $this->Body + ]; + } + } \ No newline at end of file diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Utilities/HttpClient.php new file mode 100644 index 0000000..3bf119d --- /dev/null +++ b/src/ncc/Utilities/HttpClient.php @@ -0,0 +1,111 @@ +Url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_MAXREDIRS, 10); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + + switch($httpRequest->Type) + { + case HttpRequestType::GET: + curl_setopt($curl, CURLOPT_HTTPGET, true); + break; + + case HttpRequestType::POST: + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $httpRequest->Body); + break; + + case HttpRequestType::PUT: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + curl_setopt($curl, CURLOPT_POSTFIELDS, $httpRequest->Body); + break; + + case HttpRequestType::DELETE: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + break; + + default: + throw new HttpException(sprintf('Invalid HTTP request type: %s', $httpRequest->Type)); + } + + if (is_array($httpRequest->Authentication)) + { + curl_setopt($curl, CURLOPT_USERPWD, $httpRequest->Authentication[0] . ':' . $httpRequest->Authentication[1]); + } + else if (is_string($httpRequest->Authentication)) + { + curl_setopt($curl, CURLOPT_USERPWD, $httpRequest->Authentication); + } + + if (count($httpRequest->Headers) > 0) + curl_setopt($curl, CURLOPT_HTTPHEADER, $httpRequest->Headers); + + $response = curl_exec($curl); + + if ($response === false) + { + $error = curl_error($curl); + curl_close($curl); + throw new HttpException($error); + } + + $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); + $headers = substr($response, 0, $headerSize); + $body = substr($response, $headerSize); + + $httpResponse = new HttpResponse(); + $httpResponse->StatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); + $httpResponse->Headers = self::parseHeaders($headers); + $httpResponse->Body = $body; + + curl_close($curl); + + return $httpResponse; + } + + /** + * Takes the return headers of a cURL request and parses them into an array. + * + * @param string $headers + * @return array + */ + private static function parseHeaders(string $headers): array + { + $headers = explode("\r", $headers); + $headers = array_filter($headers, function ($header) + { + return !empty($header); + }); + $headers = array_map(function ($header) { + return explode(':', $header, 2); + }, $headers); + + return array_combine(array_map(function ($header) { return strtolower($header[0]); }, $headers), + array_map(function ($header) { return trim($header[1]); }, $headers) + ); + } + } \ No newline at end of file -- 2.45.3 From f521c3291df9ee07762e11e4e8c7bb2762500042 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 10 Dec 2022 04:25:30 -0500 Subject: [PATCH 042/212] Added more logging calls to \ncc\Utilities > HttpClient https://git.n64.cc/nosial/ncc/-/issues/29 --- src/ncc/Utilities/HttpClient.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Utilities/HttpClient.php index 3bf119d..5abb381 100644 --- a/src/ncc/Utilities/HttpClient.php +++ b/src/ncc/Utilities/HttpClient.php @@ -64,6 +64,12 @@ if (count($httpRequest->Headers) > 0) curl_setopt($curl, CURLOPT_HTTPHEADER, $httpRequest->Headers); + Console::outDebug(sprintf(' => %s request %s', $httpRequest->Type, $httpRequest->Url)); + if($httpRequest->Headers !== null && count($httpRequest->Headers) > 0) + Console::outDebug(sprintf(' => headers: %s', implode(', ', $httpRequest->Headers))); + if($httpRequest->Body !== null) + Console::outDebug(sprintf(' => body: %s', $httpRequest->Body)); + $response = curl_exec($curl); if ($response === false) @@ -82,6 +88,13 @@ $httpResponse->Headers = self::parseHeaders($headers); $httpResponse->Body = $body; + Console::outDebug(sprintf(' <= %s response', $httpResponse->StatusCode));/** @noinspection PhpConditionAlreadyCheckedInspection */ + if($httpResponse->Headers !== null && count($httpResponse->Headers) > 0) + Console::outDebug(sprintf(' <= headers: %s', implode(', ', $httpResponse->Headers))); + /** @noinspection PhpConditionAlreadyCheckedInspection */ + if($httpResponse->Body !== null) + Console::outDebug(sprintf(' <= body: %s', $httpResponse->Body)); + curl_close($curl); return $httpResponse; -- 2.45.3 From d664cf7bf0a8a21a0340f26a3892ae43253e2a08 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 10 Dec 2022 04:27:26 -0500 Subject: [PATCH 043/212] Added HttpException to ExceptionCodes.php --- src/ncc/Abstracts/ExceptionCodes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 995041b..e07d556 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -328,6 +328,6 @@ self::ComposerException, self::UserAbortedOperationException, self::MissingDependencyException, - self::HttpException + self::HttpException, ]; } \ No newline at end of file -- 2.45.3 From 1f4ef9aba1cace86d06a31d399dc8da14b33e59b Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 10 Dec 2022 04:29:03 -0500 Subject: [PATCH 044/212] Added UnsupportedRemoteSourceTypeException.php https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Abstracts/ExceptionCodes.php | 6 ++++++ .../UnsupportedRemoteSourceTypeException.php | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index e07d556..74dd103 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -273,6 +273,11 @@ */ const HttpException = -1752; + /** + * @see UnsupportedRemoteSourceTypeException + */ + const UnsupportedRemoteSourceTypeException = -1753; + /** * All the exception codes from NCC */ @@ -329,5 +334,6 @@ self::UserAbortedOperationException, self::MissingDependencyException, self::HttpException, + self::UnsupportedRemoteSourceTypeException ]; } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php b/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php new file mode 100644 index 0000000..6548f35 --- /dev/null +++ b/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From b3c877931396146e42cdee2ba6c77f85ec0a85ac Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 10 Dec 2022 04:29:17 -0500 Subject: [PATCH 045/212] Added DefinedRemoteSourceType.php https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Abstracts/DefinedRemoteSourceType.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/ncc/Abstracts/DefinedRemoteSourceType.php diff --git a/src/ncc/Abstracts/DefinedRemoteSourceType.php b/src/ncc/Abstracts/DefinedRemoteSourceType.php new file mode 100644 index 0000000..345e4c9 --- /dev/null +++ b/src/ncc/Abstracts/DefinedRemoteSourceType.php @@ -0,0 +1,12 @@ + Date: Wed, 14 Dec 2022 20:02:57 -0500 Subject: [PATCH 046/212] Added 'Latest' to \ncc\Abstracts > Versions Added SourcesMenu.php Updated \ncc\Utilities > PathFinder Added 'source' menu to \ncc\CLI Added method \ncc\Utilities\Functions > getTmpDir() Updated \ncc\CLI > HelpMenu Updated \ncc\Utilities > HttpClient Updated \ncc\Objects > HttpRequest Updated php.xml for .idea Added \ncc\Exception > GitlabServiceException Added \ncc\Exceptions > GitCloneException Added \ncc\Exceptions > GitCheckoutException Updated \ncc\Abstracts > ExceptionCodes Updated \ncc\Abstracts > DefinedRemoteSourceType Added \ncc\Objects > DefinedRemoteSource Renamed ComposerSource to \ncc\Classes\ComposerExtension > ComposerSourceBuiltin Renamed RemoteSource to \ncc\Abstracts > BuiltinRemoteSourceType --- .idea/php.xml | 17 +- src/ncc/Abstracts/BuiltinRemoteSourceType.php | 17 ++ src/ncc/Abstracts/DefinedRemoteSourceType.php | 36 +++ src/ncc/Abstracts/ExceptionCodes.php | 23 +- src/ncc/Abstracts/RemoteSource.php | 16 -- src/ncc/Abstracts/Versions.php | 5 + src/ncc/CLI/HelpMenu.php | 1 + src/ncc/CLI/Main.php | 4 + src/ncc/CLI/SourcesMenu.php | 220 ++++++++++++++++++ ...erSource.php => ComposerSourceBuiltin.php} | 6 +- src/ncc/Exceptions/GitCheckoutException.php | 19 ++ src/ncc/Exceptions/GitCloneException.php | 20 ++ src/ncc/Exceptions/GitlabServiceException.php | 20 ++ src/ncc/Objects/DefinedRemoteSource.php | 75 ++++++ src/ncc/Objects/HttpRequest.php | 12 +- src/ncc/Utilities/Functions.php | 22 ++ src/ncc/Utilities/HttpClient.php | 3 + src/ncc/Utilities/PathFinder.php | 11 + 18 files changed, 505 insertions(+), 22 deletions(-) create mode 100644 src/ncc/Abstracts/BuiltinRemoteSourceType.php delete mode 100644 src/ncc/Abstracts/RemoteSource.php create mode 100644 src/ncc/CLI/SourcesMenu.php rename src/ncc/Classes/ComposerExtension/{ComposerSource.php => ComposerSourceBuiltin.php} (99%) create mode 100644 src/ncc/Exceptions/GitCheckoutException.php create mode 100644 src/ncc/Exceptions/GitCloneException.php create mode 100644 src/ncc/Exceptions/GitlabServiceException.php create mode 100644 src/ncc/Objects/DefinedRemoteSource.php diff --git a/.idea/php.xml b/.idea/php.xml index a87bd36..dec4919 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -1,11 +1,26 @@ + + + + + + - + + + + + \ No newline at end of file diff --git a/src/ncc/Abstracts/BuiltinRemoteSourceType.php b/src/ncc/Abstracts/BuiltinRemoteSourceType.php new file mode 100644 index 0000000..4f3eeb3 --- /dev/null +++ b/src/ncc/Abstracts/BuiltinRemoteSourceType.php @@ -0,0 +1,17 @@ +getSources(); + + if(count($sources) == 0) + { + Console::out('No remote sources defined.', 1); + return; + } + + Console::out('Remote sources:', 1); + foreach($sources as $source) + { + Console::out(' - ' . $source->Name . ' (' . $source->Host . ')', 1); + } + + Console::out('Total: ' . count($sources), 1); + } + + /** + * @param $args + * @return void + */ + public static function addEntry($args): void + { + if(Resolver::resolveScope() !== Scopes::System) + { + Console::outError('Insufficient permissions to add entry.', true, 1); + return; + } + + $name = $args['name'] ?? null; + $type = $args['type'] ?? null; + $host = $args['host'] ?? null; + $ssl = $args['ssl'] ?? null; + + if($name == null) + { + Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1); + return; + } + + if($type == null) + { + Console::outError(sprintf('Missing required argument \'%s\'.', 'type'), true, 1); + return; + } + + if($host == null) + { + Console::outError(sprintf('Missing required argument \'%s\'.', 'host'), true, 1); + return; + } + + if($ssl !== null) + { + $ssl = Functions::cbool($ssl); + } + + $source_manager = new RemoteSourcesManager(); + $source = new DefinedRemoteSource(); + $source->Name = $name; + $source->Type = $type; + $source->Host = $host; + $source->SSL = $ssl; + + if(!$source_manager->addRemoteSource($source)) + { + Console::outError(sprintf('Cannot add entry \'%s\', it already exists', $name), true, 1); + return; + } + + try + { + $source_manager->save(); + } + catch (IOException $e) + { + Console::outException('Cannot save remote sources file.', $e, 1); + return; + } + + Console::out(sprintf('Entry \'%s\' added successfully.', $name)); + } + + /** + * Removes an existing entry from the vault. + * + * @param $args + * @return void + */ + private static function removeEntry($args): void + { + $ResolvedScope = Resolver::resolveScope(); + + if($ResolvedScope !== Scopes::System) + Console::outError('Insufficient permissions to remove entries'); + + $name = $args['name'] ?? null; + + if($name == null) + { + Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1); + return; + } + + $source_manager = new RemoteSourcesManager(); + + if(!$source_manager->deleteRemoteSource($name)) + { + Console::outError(sprintf('Cannot remove entry \'%s\', it does not exist', $name), true, 1); + return; + } + + try + { + $source_manager->save(); + } + catch (IOException $e) + { + Console::outException('Cannot save remote sources file.', $e, 1); + return; + + } + Console::out(sprintf('Entry \'%s\' removed successfully.', $name)); + } + + /** + * Displays the main options section + * + * @return void + */ + private static function displayOptions(): void + { + Console::out('Usage: ncc sources {command} [options]'); + Console::out('Options:'); + Console::outHelpSections([ + new CliHelpSection(['help'], 'Displays this help menu about the sources command'), + new CliHelpSection(['add'], 'Adds a new entry to the list of remote sources (See below)'), + new CliHelpSection(['remove', '--name'], 'Removes an entry from the list'), + new CliHelpSection(['list'], 'Lists all entries defined as remote sources'), + ]); + Console::out((string)null); + + } + } \ No newline at end of file diff --git a/src/ncc/Classes/ComposerExtension/ComposerSource.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php similarity index 99% rename from src/ncc/Classes/ComposerExtension/ComposerSource.php rename to src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index 31f3d9b..8fbd154 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSource.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -30,7 +30,7 @@ use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Exceptions\UserAbortedOperationException; - use ncc\Interfaces\RemoteSourceInterface; + use ncc\Interfaces\ServiceSourceInterface; use ncc\Managers\ProjectManager; use ncc\Objects\ComposerLock; use ncc\Objects\ProjectConfiguration; @@ -47,7 +47,7 @@ use ncc\Utilities\RuntimeCache; use SplFileInfo; - class ComposerSource implements RemoteSourceInterface + class ComposerSourceBuiltin implements ServiceSourceInterface { /** * Attempts to acquire the package from the composer repository and @@ -134,7 +134,7 @@ { $package_path = $base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->Name; // Generate the package configuration - $project_configuration = ComposerSource::generateProjectConfiguration($package->Name, $composer_lock); + $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($package->Name, $composer_lock); // Process the source files if ($package->Autoload !== null) diff --git a/src/ncc/Exceptions/GitCheckoutException.php b/src/ncc/Exceptions/GitCheckoutException.php new file mode 100644 index 0000000..cd84341 --- /dev/null +++ b/src/ncc/Exceptions/GitCheckoutException.php @@ -0,0 +1,19 @@ +message = $message; + } + } diff --git a/src/ncc/Exceptions/GitCloneException.php b/src/ncc/Exceptions/GitCloneException.php new file mode 100644 index 0000000..a9cc009 --- /dev/null +++ b/src/ncc/Exceptions/GitCloneException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file diff --git a/src/ncc/Exceptions/GitlabServiceException.php b/src/ncc/Exceptions/GitlabServiceException.php new file mode 100644 index 0000000..202ee1e --- /dev/null +++ b/src/ncc/Exceptions/GitlabServiceException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file diff --git a/src/ncc/Objects/DefinedRemoteSource.php b/src/ncc/Objects/DefinedRemoteSource.php new file mode 100644 index 0000000..7177e3c --- /dev/null +++ b/src/ncc/Objects/DefinedRemoteSource.php @@ -0,0 +1,75 @@ + $this->Name, + ($bytecode ? Functions::cbc('type') : 'type') => $this->Type, + ($bytecode ? Functions::cbc('host') : 'host') => $this->Host, + ($bytecode ? Functions::cbc('ssl') : 'ssl') => $this->SSL + ]; + } + + /** + * Constructs object from an array representation. + * + * @param array $data + * @return static + */ + public static function fromArray(array $data): self + { + $definedRemoteSource = new self(); + + $definedRemoteSource->Name = Functions::array_bc($data, 'name'); + $definedRemoteSource->Type = Functions::array_bc($data, 'type'); + $definedRemoteSource->Host = Functions::array_bc($data, 'host'); + $definedRemoteSource->SSL = Functions::array_bc($data, 'ssl'); + + return $definedRemoteSource; + } + } \ No newline at end of file diff --git a/src/ncc/Objects/HttpRequest.php b/src/ncc/Objects/HttpRequest.php index fc3760f..9b28347 100644 --- a/src/ncc/Objects/HttpRequest.php +++ b/src/ncc/Objects/HttpRequest.php @@ -43,6 +43,13 @@ */ public $Authentication; + /** + * An array of curl options to set + * + * @var array + */ + public $Options; + public function __construct() { $this->Type = HttpRequestType::GET; @@ -50,6 +57,7 @@ $this->Headers = [ 'User-Agent: ncc/1.0' ]; + $this->Options = []; } /** @@ -64,7 +72,8 @@ 'url' => $this->Url, 'headers' => $this->Headers, 'body' => $this->Body, - 'authentication' => $this->Authentication + 'authentication' => $this->Authentication, + 'options' => $this->Options ]; } @@ -82,6 +91,7 @@ $request->Headers = $data['headers']; $request->Body = $data['body']; $request->Authentication = $data['authentication']; + $request->Options = $data['options']; return $request; } } \ No newline at end of file diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 13e6413..7087fd7 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -484,4 +484,26 @@ } return $randomString; } + + /** + * Returns a path to a temporary directory + * + * @param bool $create + * @param bool $set_as_tmp + * @return string + * @throws InvalidScopeException + */ + public static function getTmpDir(bool $create=true, bool $set_as_tmp=true): string + { + $path = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . self::randomString(16); + if($create) + { + $filesystem = new Filesystem(); + /** @noinspection PhpRedundantOptionalArgumentInspection */ + $filesystem->mkdir($path, 0777); + } + if($set_as_tmp) + RuntimeCache::setFileAsTemporary($path); + return $path; + } } \ No newline at end of file diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Utilities/HttpClient.php index 5abb381..ebded8e 100644 --- a/src/ncc/Utilities/HttpClient.php +++ b/src/ncc/Utilities/HttpClient.php @@ -28,6 +28,9 @@ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + foreach($httpRequest->Options as $option => $value) + curl_setopt($curl, $option, $value); + switch($httpRequest->Type) { case HttpRequestType::GET: diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index 340eb6f..8872291 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -173,6 +173,17 @@ return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'package.lck'; } + /** + * @param string $scope + * @param bool $win32 + * @return string + * @throws InvalidScopeException + */ + public static function getRemouteSources(string $scope=Scopes::Auto, bool $win32=false): string + { + return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'sources'; + } + /** * Returns an array of all the package lock files the current user can access (For global-cross referencing) * -- 2.45.3 From 553bf5ede0301807085bd2344d6a8b4c5a539a7d Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 14 Dec 2022 22:31:52 -0500 Subject: [PATCH 047/212] Added ImportException --- src/ncc/Abstracts/ExceptionCodes.php | 5 +++++ src/ncc/Exceptions/ImportException.php | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/ncc/Exceptions/ImportException.php diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 8eb6e24..4f49a69 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -295,6 +295,11 @@ */ const GitlabServiceException = -1756; + /** + * @see ImportException + */ + const ImportException = -1757; + /** * All the exception codes from NCC diff --git a/src/ncc/Exceptions/ImportException.php b/src/ncc/Exceptions/ImportException.php new file mode 100644 index 0000000..37defdf --- /dev/null +++ b/src/ncc/Exceptions/ImportException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From 0fbb374507c12878ae05b70484e45a530c586792 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 00:54:38 -0500 Subject: [PATCH 048/212] Added method \ncc\Runtime > Constants > get() https://git.n64.cc/nosial/ncc/-/issues/33 --- src/ncc/Runtime/Constants.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/ncc/Runtime/Constants.php b/src/ncc/Runtime/Constants.php index 312b443..62e3eeb 100644 --- a/src/ncc/Runtime/Constants.php +++ b/src/ncc/Runtime/Constants.php @@ -68,4 +68,24 @@ unset(self::$Constants[$constant_hash]); } + + /** + * Gets the constant + * + * @param string $scope + * @param string $name + * @return string|null + */ + public static function get(string $scope, string $name): ?string + { + if(!Validate::constantName($name)) + return null; + + $constant_hash = Resolver::resolveConstantHash($scope, $name); + + if(isset(self::$Constants[$constant_hash])) + return self::$Constants[$constant_hash]->getValue(); + + return null; + } } \ No newline at end of file -- 2.45.3 From 7a7ceb319b567119c9ff166b96c361a51571a99c Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 00:57:53 -0500 Subject: [PATCH 049/212] Implemented php runtime functions into extension https://git.n64.cc/nosial/ncc/-/issues/33 --- src/installer/extension | 106 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) diff --git a/src/installer/extension b/src/installer/extension index aaff950..a8ae695 100644 --- a/src/installer/extension +++ b/src/installer/extension @@ -1,8 +1,15 @@ Date: Thu, 15 Dec 2022 00:58:22 -0500 Subject: [PATCH 050/212] Implemented \ncc\Runtime https://git.n64.cc/nosial/ncc/-/issues/33 --- src/ncc/Runtime.php | 157 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 src/ncc/Runtime.php diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php new file mode 100644 index 0000000..8acb2a5 --- /dev/null +++ b/src/ncc/Runtime.php @@ -0,0 +1,157 @@ +getPackage($package)->getLatestVersion(); + + $entry = "$package=$version"; + + return isset(self::$imported_packages[$entry]); + } + + /** + * Adds a package to the imported packages list + * + * @param string $package + * @param string $version + * @return void + */ + private static function addImport(string $package, string $version): void + { + $entry = "$package=$version"; + self::$imported_packages[$entry] = true; + } + + + /** + * @param string $package + * @param string $version + * @param array $options + * @return void + * @throws ImportException + */ + public static function import(string $package, string $version=Versions::Latest, array $options=[]): void + { + try + { + $package_entry = self::getPackageManager()->getPackage($package); + } + catch (PackageLockException $e) + { + throw new ImportException(sprintf('Failed to import package "%s" due to a package lock exception: %s', $package, $e->getMessage()), $e); + } + if($package_entry == null) + { + throw new ImportException(sprintf("Package '%s' not found", $package)); + } + + if($version == Versions::Latest) + $version = $package_entry->getLatestVersion(); + + try + { + /** @var VersionEntry $version_entry */ + $version_entry = $package_entry->getVersion($version); + + if($version_entry == null) + throw new VersionNotFoundException(); + } + catch (VersionNotFoundException $e) + { + throw new ImportException(sprintf('Version %s of %s is not installed', $version, $package), $e); + } + + + try + { + if (self::isImported($package, $version)) + return; + } + catch (PackageLockException $e) + { + throw new ImportException(sprintf('Failed to check if package %s is imported', $package), $e); + } + + if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0) + { + // Import all dependencies first + foreach($version_entry->Dependencies as $dependency) + self::import($dependency->Package, $dependency->Version, $options); + } + + try + { + switch($version_entry->Compiler->Extension) + { + case CompilerExtensions::PHP: + PhpRuntime::import($version_entry, $options); + break; + + default: + throw new ImportException(sprintf('Compiler extension %s is not supported in this runtime', $version_entry->Compiler->Extension)); + } + } + catch(Exception $e) + { + throw new ImportException(sprintf('Failed to import package %s', $package), $e); + } + + + self::addImport($package, $version); + } + + /** + * @return PackageManager + */ + private static function getPackageManager(): PackageManager + { + if(self::$package_manager == null) + self::$package_manager = new PackageManager(); + return self::$package_manager; + } + + /** + * Returns an array of all the packages that is currently imported + * + * @return array + */ + public static function getImportedPackages(): array + { + return array_keys(self::$imported_packages); + } + } \ No newline at end of file -- 2.45.3 From 13e3834fc7c7feebb7ef8d8941f388308aecd2af Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:02:54 -0500 Subject: [PATCH 051/212] Implemented the ability to install from a remote source in \ncc\Managers > PackageManager https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Managers/PackageManager.php | 83 ++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index f22fafd..d13e5e8 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -5,11 +5,15 @@ namespace ncc\Managers; use Exception; + use ncc\Abstracts\BuiltinRemoteSourceType; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\ConstantReferences; use ncc\Abstracts\DependencySourceType; use ncc\Abstracts\LogLevel; + use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; + use ncc\Abstracts\Versions; + use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; use ncc\Classes\NccExtension\PackageCompiler; use ncc\Classes\PhpExtension\PhpInstaller; use ncc\CLI\Main; @@ -32,6 +36,7 @@ use ncc\Objects\PackageLock\PackageEntry; use ncc\Objects\PackageLock\VersionEntry; use ncc\Objects\ProjectConfiguration\Dependency; + use ncc\Objects\RemotePackageInput; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner; use ncc\Utilities\Console; @@ -308,6 +313,83 @@ return $package->Assembly->Package; } + /** + * @param string $source + * @return string + * @throws InstallationException + */ + public function fetchFromSource(string $source): string + { + $parsed_source = new RemotePackageInput($source); + + if($parsed_source->Source == null) + throw new InstallationException('No source specified'); + + if($parsed_source->Package == null) + throw new InstallationException('No package specified'); + + if($parsed_source->Version == null) + $parsed_source->Version = Versions::Latest; + + $remote_source_type = Resolver::detectRemoteSourceType($parsed_source->Source); + + if($remote_source_type == RemoteSourceType::Builtin) + { + switch($parsed_source->Source) + { + case BuiltinRemoteSourceType::Composer: + try + { + return ComposerSourceBuiltin::fetch($parsed_source); + } + catch(Exception $e) + { + throw new InstallationException('Cannot fetch package from composer source, ' . $e->getMessage(), $e); + } + + default: + throw new InstallationException('Builtin source type ' . $parsed_source->Source . ' is not implemented'); + } + } + + if($remote_source_type == RemoteSourceType::Defined) + { + $remote_source_manager = new RemoteSourcesManager(); + $remote_source = $remote_source_manager->getRemoteSource($parsed_source->Source); + if($remote_source == null) + throw new InstallationException('Remote source ' . $parsed_source->Source . ' is not defined'); + + // TODO: Implement defined remote sources + } + + throw new InstallationException(sprintf('Unknown remote source type %s', $remote_source_type)); + } + + /** + * Installs a package from a source syntax (vendor/package=version@source) + * + * @param string $source + * @return string + * @throws AccessDeniedException + * @throws FileNotFoundException + * @throws IOException + * @throws InstallationException + * @throws MissingDependencyException + * @throws NotImplementedException + * @throws PackageAlreadyInstalledException + * @throws PackageLockException + * @throws PackageNotFoundException + * @throws PackageParsingException + * @throws UnsupportedCompilerExtensionException + * @throws UnsupportedRunnerException + * @throws VersionNotFoundException + */ + public function installFromSource(string $source): string + { + $package_path = $this->fetchFromSource($source); + return $this->install($package_path); + } + /** * @param Dependency $dependency * @param Package $package @@ -379,7 +461,6 @@ * @param string $package * @return PackageEntry|null * @throws PackageLockException - * @throws PackageLockException */ public function getPackage(string $package): ?PackageEntry { -- 2.45.3 From 47f58aa50e39e4613179a673502e76f4d69c2f63 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:03:12 -0500 Subject: [PATCH 052/212] Added RemoteResourcesManager to \ncc\Managers https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Managers/RemoteSourcesManager.php | 152 ++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 src/ncc/Managers/RemoteSourcesManager.php diff --git a/src/ncc/Managers/RemoteSourcesManager.php b/src/ncc/Managers/RemoteSourcesManager.php new file mode 100644 index 0000000..95f156b --- /dev/null +++ b/src/ncc/Managers/RemoteSourcesManager.php @@ -0,0 +1,152 @@ +DefinedSourcesPath = PathFinder::getRemouteSources(Scopes::System); + + $this->load(); + } + + /** + * Loads an existing remote sources file, or creates a new one if it doesn't exist + * + * @return void + */ + public function load(): void + { + $this->Sources = []; + + try + { + + if(file_exists($this->DefinedSourcesPath)) + { + $sources = ZiProto::decode(IO::fread($this->DefinedSourcesPath)); + $this->Sources = []; + foreach($sources as $source) + $this->Sources[] = DefinedRemoteSource::fromArray($source); + } + } + catch(Exception $e) + { + unset($e); + } + } + + /** + * Saves the remote sources file to disk + * + * @return void + * @throws IOException + */ + public function save(): void + { + $sources = []; + foreach($this->Sources as $source) + $sources[] = $source->toArray(true); + + IO::fwrite($this->DefinedSourcesPath, ZiProto::encode($sources)); + } + + /** + * Adds a new remote source to the list + * + * @param DefinedRemoteSource $source + * @return bool + */ + public function addRemoteSource(DefinedRemoteSource $source): bool + { + foreach($this->Sources as $existingSource) + { + if($existingSource->Name === $source->Name) + return false; + } + + $this->Sources[] = $source; + return true; + } + + /** + * Gets a remote source by its name + * + * @param string $name + * @return DefinedRemoteSource|null + */ + public function getRemoteSource(string $name): ?DefinedRemoteSource + { + foreach($this->Sources as $source) + { + if($source->Name === $name) + return $source; + } + + return null; + } + + /** + * Deletes an existing remote source + * + * @param string $name + * @return bool + */ + public function deleteRemoteSource(string $name): bool + { + foreach($this->Sources as $index => $source) + { + if($source->Name === $name) + { + unset($this->Sources[$index]); + return true; + } + } + + return false; + } + + /** + * Returns an array of all the defined remote sources + * + * @return DefinedRemoteSource[] + */ + public function getSources(): array + { + if($this->Sources == null) + $this->load(); + return $this->Sources; + } + } \ No newline at end of file -- 2.45.3 From 31ae2fcdddb7355ff6f8029fdbe02aa7fdf1c668 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:04:26 -0500 Subject: [PATCH 053/212] Added RepositorySourceInterface.php https://git.n64.cc/nosial/ncc/-/issues/28 --- .../Interfaces/RepositorySourceInterface.php | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/ncc/Interfaces/RepositorySourceInterface.php diff --git a/src/ncc/Interfaces/RepositorySourceInterface.php b/src/ncc/Interfaces/RepositorySourceInterface.php new file mode 100644 index 0000000..1021bec --- /dev/null +++ b/src/ncc/Interfaces/RepositorySourceInterface.php @@ -0,0 +1,21 @@ + Date: Thu, 15 Dec 2022 01:04:52 -0500 Subject: [PATCH 054/212] Renamed RemoteSourceInterface.php to ServiceSourceInterface.php https://git.n64.cc/nosial/ncc/-/issues/28 --- .../{RemoteSourceInterface.php => ServiceSourceInterface.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/ncc/Interfaces/{RemoteSourceInterface.php => ServiceSourceInterface.php} (93%) diff --git a/src/ncc/Interfaces/RemoteSourceInterface.php b/src/ncc/Interfaces/ServiceSourceInterface.php similarity index 93% rename from src/ncc/Interfaces/RemoteSourceInterface.php rename to src/ncc/Interfaces/ServiceSourceInterface.php index e745c24..5eb9c1c 100644 --- a/src/ncc/Interfaces/RemoteSourceInterface.php +++ b/src/ncc/Interfaces/ServiceSourceInterface.php @@ -4,7 +4,7 @@ use ncc\Objects\RemotePackageInput; - interface RemoteSourceInterface + interface ServiceSourceInterface { /** * Fetches a package and all it's dependencies from the given remote source -- 2.45.3 From 223ae9189b9779c1159bb95ae3407208a2a30d10 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:05:11 -0500 Subject: [PATCH 055/212] Added \ncc\Abstracts > RemoteSourceType https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Abstracts/RemoteSourceType.php | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/ncc/Abstracts/RemoteSourceType.php diff --git a/src/ncc/Abstracts/RemoteSourceType.php b/src/ncc/Abstracts/RemoteSourceType.php new file mode 100644 index 0000000..6bfeca6 --- /dev/null +++ b/src/ncc/Abstracts/RemoteSourceType.php @@ -0,0 +1,30 @@ + Date: Thu, 15 Dec 2022 01:05:53 -0500 Subject: [PATCH 056/212] Added \ncc\Abstracts > RuntimeImportOptions https://git.n64.cc/nosial/ncc/-/issues/33 --- src/ncc/Abstracts/RuntimeImportOptions.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/ncc/Abstracts/RuntimeImportOptions.php diff --git a/src/ncc/Abstracts/RuntimeImportOptions.php b/src/ncc/Abstracts/RuntimeImportOptions.php new file mode 100644 index 0000000..230e98a --- /dev/null +++ b/src/ncc/Abstracts/RuntimeImportOptions.php @@ -0,0 +1,18 @@ + Date: Thu, 15 Dec 2022 01:06:23 -0500 Subject: [PATCH 057/212] Added \ncc\Classes\PhpExtension > PhpRuntime to import PHP packages https://git.n64.cc/nosial/ncc/-/issues/33 --- src/ncc/Classes/PhpExtension/PhpRuntime.php | 49 +++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/ncc/Classes/PhpExtension/PhpRuntime.php diff --git a/src/ncc/Classes/PhpExtension/PhpRuntime.php b/src/ncc/Classes/PhpExtension/PhpRuntime.php new file mode 100644 index 0000000..20aeb4f --- /dev/null +++ b/src/ncc/Classes/PhpExtension/PhpRuntime.php @@ -0,0 +1,49 @@ +getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php'; + $static_files = $versionEntry->getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin'; + + if(file_exists($autoload_path) && !in_array(RuntimeImportOptions::ImportAutoloader, $options)) + { + require_once($autoload_path); + } + + if(file_exists($static_files) && !in_array(RuntimeImportOptions::ImportStaticFiles, $options)) + { + $static_files = ZiProto::decode(IO::fread($static_files)); + foreach($static_files as $file) + require_once($file); + } + + if(!file_exists($autoload_path) && !file_exists($static_files)) + return false; + + return true; + } + } \ No newline at end of file -- 2.45.3 From b9252a0fda9a64d9fc957543d5f3165bb9fdb966 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:06:43 -0500 Subject: [PATCH 058/212] Added \ncc\Interfaces > RuntimeInterface https://git.n64.cc/nosial/ncc/-/issues/33 --- src/ncc/Interfaces/RuntimeInterface.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/ncc/Interfaces/RuntimeInterface.php diff --git a/src/ncc/Interfaces/RuntimeInterface.php b/src/ncc/Interfaces/RuntimeInterface.php new file mode 100644 index 0000000..7b70e51 --- /dev/null +++ b/src/ncc/Interfaces/RuntimeInterface.php @@ -0,0 +1,24 @@ + Date: Thu, 15 Dec 2022 01:07:23 -0500 Subject: [PATCH 059/212] Added method \ncc\Utilities > Resolver > detectRemoteSourceType() https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Utilities/Resolver.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ncc/Utilities/Resolver.php b/src/ncc/Utilities/Resolver.php index 4d172a0..cc3cb29 100644 --- a/src/ncc/Utilities/Resolver.php +++ b/src/ncc/Utilities/Resolver.php @@ -4,8 +4,12 @@ namespace ncc\Utilities; + use ncc\Abstracts\BuiltinRemoteSourceType; + use ncc\Abstracts\DefinedRemoteSourceType; use ncc\Abstracts\LogLevel; + use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; + use ncc\Managers\RemoteSourcesManager; class Resolver { @@ -86,7 +90,7 @@ } $configs = array(); - $regex = "/(?(?=-)-(?(?=-)-(?'bigflag'[^\\s=]+)|(?'smallflag'\\S))(?:\\s*=\\s*|\\s+)(?(?!-)(?(?=[\\\"\\'])((? $match) @@ -241,4 +245,25 @@ return false; } } + + /** + * Detects the remote source type, can also accept defined remote + * sources as the input, the function will look for the source + * type and return it + * + * @param string $input + * @return string + */ + public static function detectRemoteSourceType(string $input): string + { + if(in_array($input, BuiltinRemoteSourceType::All)) + return RemoteSourceType::Builtin; + + $source_manager = new RemoteSourcesManager(); + $defined_source = $source_manager->getRemoteSource($input); + if($defined_source == null) + return RemoteSourceType::Unknown; + + return $defined_source->Type; + } } \ No newline at end of file -- 2.45.3 From 3757c970a5ffe2653718a6e745d98d2c52b722ce Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:27:28 -0500 Subject: [PATCH 060/212] Updated \ncc\Objects\ProjectConfiguration > Project https://git.n64.cc/nosial/ncc/-/issues/34 --- src/ncc/Objects/ProjectConfiguration/Project.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ncc/Objects/ProjectConfiguration/Project.php b/src/ncc/Objects/ProjectConfiguration/Project.php index 8a22e2e..83f7e2e 100644 --- a/src/ncc/Objects/ProjectConfiguration/Project.php +++ b/src/ncc/Objects/ProjectConfiguration/Project.php @@ -26,6 +26,11 @@ */ public $Options; + /** + * @var UpdateSource|null + */ + public $UpdateSource; + /** * Public Constructor */ @@ -65,6 +70,7 @@ $ReturnResults[($bytecode ? Functions::cbc('compiler') : 'compiler')] = $this->Compiler->toArray($bytecode); $ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options; + $ReturnResults[($bytecode ? Functions::cbc('update_source') : 'update_source')] = $this->UpdateSource->toArray($bytecode); return $ReturnResults; } @@ -89,6 +95,11 @@ $ProjectObject->Options = Functions::array_bc($data, 'options'); } + if(Functions::array_bc($data, 'update_source') !== null) + { + $ProjectObject->UpdateSource = UpdateSource::fromArray(Functions::array_bc($data, 'update_source')); + } + return $ProjectObject; } } \ No newline at end of file -- 2.45.3 From b4acfaa0cb866a726595bed8639e2ff8077067f4 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:27:58 -0500 Subject: [PATCH 061/212] Implemented \ncc\Objects\ProjectConfiguration > updateSource https://git.n64.cc/nosial/ncc/-/issues/34 --- .../ProjectConfiguration/UpdateSource.php | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/ncc/Objects/ProjectConfiguration/UpdateSource.php b/src/ncc/Objects/ProjectConfiguration/UpdateSource.php index b9344e7..98a24ae 100644 --- a/src/ncc/Objects/ProjectConfiguration/UpdateSource.php +++ b/src/ncc/Objects/ProjectConfiguration/UpdateSource.php @@ -1,8 +1,58 @@ $this->Source, + ($bytecode ? Functions::cbc('repository') : 'repository') => ($this->Repository?->toArray($bytecode)) + ]; + } + + + /** + * Constructs object from an array representation + * + * @param array $data + * @return UpdateSource + */ + public static function fromArray(array $data): UpdateSource + { + $obj = new UpdateSource(); + $obj->Source = Functions::array_bc($data, 'source'); + $obj->Repository = Functions::array_bc($data, 'repository'); + + if($obj->Repository !== null) + $obj->Repository = Repository::fromArray($obj->Repository); + + return $obj; + } } \ No newline at end of file -- 2.45.3 From 57cf2dbca378bdaf6e9de2eee4f7815a0fba12ec Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 01:31:34 -0500 Subject: [PATCH 062/212] Updated Makefile --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6931230..bd0b8dd 100644 --- a/Makefile +++ b/Makefile @@ -80,7 +80,8 @@ $(SRC_PATH)/ncc/autoload_spl.php: $(SRC_PATH)/ncc/Objects \ $(SRC_PATH)/ncc/Runtime \ $(SRC_PATH)/ncc/Utilities \ - $(SRC_PATH)/ncc/ncc.php + $(SRC_PATH)/ncc/ncc.php \ + $(SRC_PATH)/ncc/Runtime.php redist: autoload rm -rf $(BUILD_PATH)/src -- 2.45.3 From 8e8c1dca58ac58d792df30a1c1f7039c14ea307d Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 15:23:06 -0500 Subject: [PATCH 063/212] Added optional UpdateSource to \ncc\Objects\Package > Header https://git.n64.cc/nosial/ncc/-/issues/34 --- src/ncc/Objects/Package/Header.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ncc/Objects/Package/Header.php b/src/ncc/Objects/Package/Header.php index 34804de..1cc5f3d 100644 --- a/src/ncc/Objects/Package/Header.php +++ b/src/ncc/Objects/Package/Header.php @@ -5,6 +5,7 @@ namespace ncc\Objects\Package; use ncc\Objects\ProjectConfiguration\Compiler; + use ncc\Objects\ProjectConfiguration\UpdateSource; use ncc\Utilities\Functions; class Header @@ -37,6 +38,13 @@ */ public $Options; + /** + * The optional update source to where the package can be updated from + * + * @var $UpdateSource|null + */ + public $UpdateSource; + /** * Public Constructor */ @@ -59,6 +67,7 @@ ($bytecode ? Functions::cbc('compiler_extension') : 'compiler_extension') => $this->CompilerExtension->toArray($bytecode), ($bytecode ? Functions::cbc('runtime_constants') : 'runtime_constants') => $this->RuntimeConstants, ($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->CompilerVersion, + ($bytecode ? Functions::cbc('update_source') : 'update_source') => $this->UpdateSource->toArray($bytecode), ($bytecode ? Functions::cbc('options') : 'options') => $this->Options, ]; } @@ -76,10 +85,13 @@ $object->CompilerExtension = Functions::array_bc($data, 'compiler_extension'); $object->RuntimeConstants = Functions::array_bc($data, 'runtime_constants'); $object->CompilerVersion = Functions::array_bc($data, 'compiler_version'); + $object->UpdateSource = Functions::array_bc($data, 'update_source'); $object->Options = Functions::array_bc($data, 'options'); if($object->CompilerExtension !== null) $object->CompilerExtension = Compiler::fromArray($object->CompilerExtension); + if($object->UpdateSource !== null) + $object->UpdateSource = UpdateSource::fromArray($object->UpdateSource); return $object; } -- 2.45.3 From 54b733caf791b75d8f28c9fcc82f81aebf2dcacb Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 15:24:13 -0500 Subject: [PATCH 064/212] Added \ncc\Objects\UpdateSource > Repository https://git.n64.cc/nosial/ncc/-/issues/34 --- .../UpdateSource/Repository.php | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/ncc/Objects/ProjectConfiguration/UpdateSource/Repository.php diff --git a/src/ncc/Objects/ProjectConfiguration/UpdateSource/Repository.php b/src/ncc/Objects/ProjectConfiguration/UpdateSource/Repository.php new file mode 100644 index 0000000..69cb7b4 --- /dev/null +++ b/src/ncc/Objects/ProjectConfiguration/UpdateSource/Repository.php @@ -0,0 +1,70 @@ + $this->Name, + ($bytecode ? Functions::cbc('type') : 'type') => $this->Type, + ($bytecode ? Functions::cbc('host') : 'host') => $this->Host, + ($bytecode ? Functions::cbc('ssl') : 'ssl') => $this->SSL + ]; + } + + /** + * Constructs object from an array representation + * + * @param array $data + * @return Repository + */ + public static function fromArray(array $data): self + { + $obj = new self(); + $obj->Name = Functions::array_bc($data, 'name'); + $obj->Type = Functions::array_bc($data, 'type'); + $obj->Host = Functions::array_bc($data, 'host'); + $obj->SSL = Functions::array_bc($data, 'ssl'); + return $obj; + } + } \ No newline at end of file -- 2.45.3 From 6d35e42106bf8660b88bd0a1d6a3c4d8484e58be Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 17:48:03 -0500 Subject: [PATCH 065/212] Added \ncc\Objects > HttpResponseCache --- src/ncc/Objects/HttpResponseCache.php | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/ncc/Objects/HttpResponseCache.php diff --git a/src/ncc/Objects/HttpResponseCache.php b/src/ncc/Objects/HttpResponseCache.php new file mode 100644 index 0000000..dde55ce --- /dev/null +++ b/src/ncc/Objects/HttpResponseCache.php @@ -0,0 +1,56 @@ +httpResponse = $httpResponse; + $this->ttl = $ttl; + } + + /** + * Returns the cached response + * + * @return HttpResponse + */ + public function getHttpResponse(): HttpResponse + { + return $this->httpResponse; + } + + /** + * Returns the Unix Timestamp of when the cache becomes invalid + * + * @return int + */ + public function getTtl(): int + { + return $this->ttl; + } + } \ No newline at end of file -- 2.45.3 From fa8301710fa44455ac763cf902971abb40817a72 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 17:48:20 -0500 Subject: [PATCH 066/212] Added method \ncc\Objects > HttpRequest > requestHash() --- src/ncc/Objects/HttpRequest.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/ncc/Objects/HttpRequest.php b/src/ncc/Objects/HttpRequest.php index 9b28347..09e2972 100644 --- a/src/ncc/Objects/HttpRequest.php +++ b/src/ncc/Objects/HttpRequest.php @@ -77,6 +77,17 @@ ]; } + /** + * Returns the hash of the object. + * (This is used for caching) + * + * @return string + */ + public function requestHash(): string + { + return hash('sha1', json_encode($this->toArray())); + } + /** * Constructs a new HttpRequest object from an array representation. * -- 2.45.3 From 259620079ef46b380cf11c5c10bfc445342e8337 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 17:49:09 -0500 Subject: [PATCH 067/212] Implemented HttpResponse cache to reduce hitting rate-limits for redundant requests (plus it makes requests faster) --- src/ncc/Utilities/HttpClient.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Utilities/HttpClient.php index ebded8e..464101f 100644 --- a/src/ncc/Utilities/HttpClient.php +++ b/src/ncc/Utilities/HttpClient.php @@ -6,6 +6,7 @@ use ncc\Exceptions\HttpException; use ncc\Objects\HttpRequest; use ncc\Objects\HttpResponse; + use ncc\Objects\HttpResponseCache; class HttpClient { @@ -13,11 +14,22 @@ * Creates a new HTTP request and returns the response. * * @param HttpRequest $httpRequest + * @param bool $cache * @return HttpResponse * @throws HttpException */ - public static function request(HttpRequest $httpRequest): HttpResponse + public static function request(HttpRequest $httpRequest, bool $cache=false): HttpResponse { + if($cache) + { + /** @var HttpResponseCache $cache */ + $cache = RuntimeCache::get(sprintf('http_cache_%s', $httpRequest->requestHash())); + if($cache !== null && $cache->getTtl() > time()) + { + return $cache->getHttpResponse(); + } + } + $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $httpRequest->Url); @@ -100,6 +112,12 @@ curl_close($curl); + if($cache) + { + $httpCacheObject = new HttpResponseCache($httpResponse, 60); + RuntimeCache::set(sprintf('http_cache_%s', $httpRequest->requestHash()), $httpCacheObject); + } + return $httpResponse; } -- 2.45.3 From bfbd7b4828d41f85c5c0fb1ceaa3acb7e0dd571e Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 17:59:55 -0500 Subject: [PATCH 068/212] Updated interface \ncc\Interfaces > RepositorySourceInterface https://git.n64.cc/nosial/ncc/-/issues/34 --- .../Interfaces/RepositorySourceInterface.php | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/ncc/Interfaces/RepositorySourceInterface.php b/src/ncc/Interfaces/RepositorySourceInterface.php index 1021bec..25d7ee4 100644 --- a/src/ncc/Interfaces/RepositorySourceInterface.php +++ b/src/ncc/Interfaces/RepositorySourceInterface.php @@ -4,18 +4,37 @@ use ncc\Objects\DefinedRemoteSource; use ncc\Objects\RemotePackageInput; + use ncc\Objects\Vault\Entry; interface RepositorySourceInterface { /** - * Fetches a package and all it's dependencies from the given remote source - * and optionally converts and compiles it to a local package, returns the - * fetched package as a path to the ncc package file. This function uses - * a defined remote source to fetch the package or build the package from. + * Returns the git repository url of the repository, versions cannot be specified. * * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry * @return string */ - public static function fetch(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource): string; + public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): string; + + /** + * Returns the release url of the repository, versions can be specified. + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + */ + public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string; + + /** + * Returns the download URL of the pre-compiled .ncc package if available + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + */ + public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string; } \ No newline at end of file -- 2.45.3 From 03b02774b6b7649877d6297511b225d143423cdb Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 18:16:44 -0500 Subject: [PATCH 069/212] Refactored HttpClient to support the ability to download files to disk. --- src/ncc/Utilities/HttpClient.php | 157 +++++++++++++++++++++---------- 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Utilities/HttpClient.php index 464101f..180cab3 100644 --- a/src/ncc/Utilities/HttpClient.php +++ b/src/ncc/Utilities/HttpClient.php @@ -2,6 +2,7 @@ namespace ncc\Utilities; + use CurlHandle; use ncc\Abstracts\HttpRequestType; use ncc\Exceptions\HttpException; use ncc\Objects\HttpRequest; @@ -10,6 +11,64 @@ class HttpClient { + /** + * Prepares the curl request + * + * @param HttpRequest $request + * @return CurlHandle + */ + private static function prepareCurl(HttpRequest $request): CurlHandle + { + $curl = curl_init($request->Url); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl, CURLOPT_MAXREDIRS, 5); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); + curl_setopt($curl, CURLOPT_HTTPHEADER, $request->Headers); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->Type); + + switch($request->Type) + { + case HttpRequestType::GET: + curl_setopt($curl, CURLOPT_HTTPGET, true); + break; + + case HttpRequestType::POST: + curl_setopt($curl, CURLOPT_POST, true); + if($request->Body !== null) + curl_setopt($curl, CURLOPT_POSTFIELDS, $request->Body); + break; + + case HttpRequestType::PUT: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); + if($request->Body !== null) + curl_setopt($curl, CURLOPT_POSTFIELDS, $request->Body); + break; + + case HttpRequestType::DELETE: + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); + break; + } + + if (is_array($request->Authentication)) + { + curl_setopt($curl, CURLOPT_USERPWD, $request->Authentication[0] . ':' . $request->Authentication[1]); + } + else if (is_string($request->Authentication)) + { + curl_setopt($curl, CURLOPT_USERPWD, $request->Authentication); + } + + foreach ($request->Options as $option => $value) + curl_setopt($curl, $option, $value); + + return $curl; + } + /** * Creates a new HTTP request and returns the response. * @@ -26,58 +85,12 @@ $cache = RuntimeCache::get(sprintf('http_cache_%s', $httpRequest->requestHash())); if($cache !== null && $cache->getTtl() > time()) { + Console::outDebug(sprintf('using cached response for %s', $httpRequest->requestHash())); return $cache->getHttpResponse(); } } - $curl = curl_init(); - - curl_setopt($curl, CURLOPT_URL, $httpRequest->Url); - curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); - curl_setopt($curl, CURLOPT_HEADER, true); - curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($curl, CURLOPT_MAXREDIRS, 10); - curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); - curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); - - foreach($httpRequest->Options as $option => $value) - curl_setopt($curl, $option, $value); - - switch($httpRequest->Type) - { - case HttpRequestType::GET: - curl_setopt($curl, CURLOPT_HTTPGET, true); - break; - - case HttpRequestType::POST: - curl_setopt($curl, CURLOPT_POST, true); - curl_setopt($curl, CURLOPT_POSTFIELDS, $httpRequest->Body); - break; - - case HttpRequestType::PUT: - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); - curl_setopt($curl, CURLOPT_POSTFIELDS, $httpRequest->Body); - break; - - case HttpRequestType::DELETE: - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE'); - break; - - default: - throw new HttpException(sprintf('Invalid HTTP request type: %s', $httpRequest->Type)); - } - - if (is_array($httpRequest->Authentication)) - { - curl_setopt($curl, CURLOPT_USERPWD, $httpRequest->Authentication[0] . ':' . $httpRequest->Authentication[1]); - } - else if (is_string($httpRequest->Authentication)) - { - curl_setopt($curl, CURLOPT_USERPWD, $httpRequest->Authentication); - } - - if (count($httpRequest->Headers) > 0) - curl_setopt($curl, CURLOPT_HTTPHEADER, $httpRequest->Headers); + $curl = self::prepareCurl($httpRequest); Console::outDebug(sprintf(' => %s request %s', $httpRequest->Type, $httpRequest->Url)); if($httpRequest->Headers !== null && count($httpRequest->Headers) > 0) @@ -114,13 +127,59 @@ if($cache) { - $httpCacheObject = new HttpResponseCache($httpResponse, 60); + $httpCacheObject = new HttpResponseCache($httpResponse, time() + 60); RuntimeCache::set(sprintf('http_cache_%s', $httpRequest->requestHash()), $httpCacheObject); + + Console::outDebug(sprintf('cached response for %s', $httpRequest->requestHash())); } return $httpResponse; } + /** + * Downloads a file from the given url and saves it to the given path. + * + * @param HttpRequest $httpRequest + * @param string $path + * @return void + * @throws HttpException + */ + public static function download(HttpRequest $httpRequest, string $path): void + { + $curl = self::prepareCurl($httpRequest); + + $fp = fopen($path, 'w'); + curl_setopt($curl, CURLOPT_FILE, $fp); + curl_setopt($curl, CURLOPT_HEADER, 0); + $response = curl_exec($curl); + + if ($response === false) + { + $error = curl_error($curl); + curl_close($curl); + throw new HttpException($error); + } + + curl_close($curl); + fclose($fp); + } + + /** + * Displays the download progress in the console + * + * @param $resource + * @param $downloadSize + * @param $downloaded + * @param $uploadSize + * @param $uploaded + * @return void + */ + public static function displayProgress($resource, $downloadSize, $downloaded, $uploadSize, $uploaded): void + { + if ($downloadSize > 0) + Console::inlineProgressBar($downloaded, $downloadSize); + } + /** * Takes the return headers of a cURL request and parses them into an array. * -- 2.45.3 From 698adff3b5ff05a339795298a12cd57266bbc081 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 18:32:18 -0500 Subject: [PATCH 070/212] Added method \ncc\Utilities > Functions > prepareGitServiceRequest() https://git.n64.cc/nosial/ncc/-/issues/34 --- src/ncc/Utilities/Functions.php | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 7087fd7..7a37f96 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -3,6 +3,7 @@ namespace ncc\Utilities; use Exception; + use ncc\Abstracts\AuthenticationType; use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; @@ -13,7 +14,9 @@ use ncc\Classes\PythonExtension\Python3Runner; use ncc\Classes\PythonExtension\PythonRunner; use ncc\Exceptions\AccessDeniedException; + use ncc\Exceptions\AuthenticationException; use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\GitlabServiceException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; use ncc\Exceptions\MalformedJsonException; @@ -23,8 +26,10 @@ use ncc\Managers\PackageLockManager; use ncc\Objects\CliHelpSection; use ncc\Objects\ComposerJson; + use ncc\Objects\HttpRequest; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; + use ncc\Objects\Vault\Entry; use ncc\ThirdParty\jelix\Version\Parser; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; @@ -506,4 +511,36 @@ RuntimeCache::setFileAsTemporary($path); return $path; } + + /** + * Applies the authentication to the given HTTP request. + * + * @param HttpRequest $httpRequest + * @param Entry|null $entry + * @return HttpRequest + * @throws AuthenticationException + * @throws GitlabServiceException + */ + public static function prepareGitServiceRequest(HttpRequest $httpRequest, ?Entry $entry=null): HttpRequest + { + if($entry !== null) + { + if (!$entry->isCurrentlyDecrypted()) + throw new GitlabServiceException('The given Vault entry is not decrypted.'); + + switch ($entry->getPassword()->getAuthenticationType()) { + case AuthenticationType::AccessToken: + $httpRequest->Headers[] = "Authorization: Bearer " . $entry->getPassword(); + break; + + case AuthenticationType::UsernamePassword: + throw new AuthenticationException('Username/Password authentication is not supported'); + } + } + + $httpRequest->Headers[] = "Accept: application/json"; + $httpRequest->Headers[] = "Content-Type: application/json"; + + return $httpRequest; + } } \ No newline at end of file -- 2.45.3 From 3e43df48ac4069033f97158ac64710736caeb671 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 20:47:23 -0500 Subject: [PATCH 071/212] Added UpdateSource to \ncc\Objects\PackageLock > PackageEntry --- src/ncc/Objects/PackageLock/PackageEntry.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ncc/Objects/PackageLock/PackageEntry.php b/src/ncc/Objects/PackageLock/PackageEntry.php index 43cf7a9..c2f95f0 100644 --- a/src/ncc/Objects/PackageLock/PackageEntry.php +++ b/src/ncc/Objects/PackageLock/PackageEntry.php @@ -6,6 +6,7 @@ use ncc\Exceptions\VersionNotFoundException; use ncc\Objects\Package; + use ncc\Objects\ProjectConfiguration\UpdateSource; use ncc\ThirdParty\jelix\Version\VersionComparator; use ncc\Utilities\Functions; @@ -32,6 +33,13 @@ */ public $Versions; + /** + * The update source of the package entry + * + * @var UpdateSource|null + */ + public $UpdateSource; + /** * Public Constructor */ @@ -204,6 +212,7 @@ ($bytecode ? Functions::cbc('name') : 'name') => $this->Name, ($bytecode ? Functions::cbc('latest_version') : 'latest_version') => $this->LatestVersion, ($bytecode ? Functions::cbc('versions') : 'versions') => $versions, + ($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->UpdateSource?->toArray($bytecode) ?? null), ]; } @@ -220,6 +229,10 @@ $object->Name = Functions::array_bc($data, 'name'); $object->LatestVersion = Functions::array_bc($data, 'latest_version'); $versions = Functions::array_bc($data, 'versions'); + $object->UpdateSource = Functions::array_bc($data, 'update_source'); + + if($object->UpdateSource !== null) + $object->UpdateSource = UpdateSource::fromArray($object->UpdateSource); if($versions !== null) { -- 2.45.3 From eca1a3a66676ed2a4775168992072e10f114ea09 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 20:51:08 -0500 Subject: [PATCH 072/212] Added auto-update for UpdateSource --- src/ncc/Objects/PackageLock.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php index 3e4d055..7f84302 100644 --- a/src/ncc/Objects/PackageLock.php +++ b/src/ncc/Objects/PackageLock.php @@ -63,12 +63,14 @@ $package_entry = new PackageEntry(); $package_entry->addVersion($package, $install_path, true); $package_entry->Name = $package->Assembly->Package; + $package_entry->UpdateSource = $package->Header->UpdateSource; $this->Packages[$package->Assembly->Package] = $package_entry; $this->update(); return; } + $this->Packages[$package->Assembly->Package]->UpdateSource = $package->Header->UpdateSource; $this->Packages[$package->Assembly->Package]->addVersion($package, true); $this->update(); } -- 2.45.3 From 35fd1691233cc91512411408c74a8d41c02f313d Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:08:51 -0500 Subject: [PATCH 073/212] Updated \ncc\Managers > PackageManager to allow installations from sources to be possible and added the ability to add new remote sources from packages. https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Managers/PackageManager.php | 41 +++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index d13e5e8..b3a883e 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -8,12 +8,15 @@ use ncc\Abstracts\BuiltinRemoteSourceType; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\ConstantReferences; + use ncc\Abstracts\DefinedRemoteSourceType; use ncc\Abstracts\DependencySourceType; use ncc\Abstracts\LogLevel; use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; use ncc\Abstracts\Versions; use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; + use ncc\Classes\GithubExtension\GithubService; + use ncc\Classes\GitlabExtension\GitlabService; use ncc\Classes\NccExtension\PackageCompiler; use ncc\Classes\PhpExtension\PhpInstaller; use ncc\CLI\Main; @@ -31,12 +34,15 @@ use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Exceptions\VersionNotFoundException; + use ncc\Interfaces\RepositorySourceInterface; + use ncc\Objects\DefinedRemoteSource; use ncc\Objects\InstallationPaths; use ncc\Objects\Package; use ncc\Objects\PackageLock\PackageEntry; use ncc\Objects\PackageLock\VersionEntry; use ncc\Objects\ProjectConfiguration\Dependency; use ncc\Objects\RemotePackageInput; + use ncc\Objects\Vault\Entry; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner; use ncc\Utilities\Console; @@ -307,6 +313,22 @@ } } + if($package->Header->UpdateSource !== null && $package->Header->UpdateSource->Repository !== null) + { + $sources_manager = new RemoteSourcesManager(); + if($sources_manager->getRemoteSource($package->Header->UpdateSource->Repository->Name) === null) + { + Console::outVerbose('Adding remote source ' . $package->Header->UpdateSource->Repository->Name); + $defined_remote_source = new DefinedRemoteSource(); + $defined_remote_source->Name = $package->Header->UpdateSource->Repository->Name; + $defined_remote_source->Host = $package->Header->UpdateSource->Repository->Host; + $defined_remote_source->Type = $package->Header->UpdateSource->Repository->Type; + $defined_remote_source->SSL = $package->Header->UpdateSource->Repository->SSL; + + $sources_manager->addRemoteSource($defined_remote_source); + } + } + $this->getPackageLockManager()->getPackageLock()->addPackage($package, $installation_paths->getInstallationPath()); $this->getPackageLockManager()->save(); @@ -315,10 +337,11 @@ /** * @param string $source + * @param Entry|null $auth_entry * @return string * @throws InstallationException */ - public function fetchFromSource(string $source): string + public function fetchFromSource(string $source, ?Entry $auth_entry=null): string { $parsed_source = new RemotePackageInput($source); @@ -359,7 +382,21 @@ if($remote_source == null) throw new InstallationException('Remote source ' . $parsed_source->Source . ' is not defined'); - // TODO: Implement defined remote sources + /** @var RepositorySourceInterface $remote_service_client */ + $remote_service_client = match ($remote_source->Type) { + DefinedRemoteSourceType::Gitlab => GitlabService::class, + DefinedRemoteSourceType::Github => GithubService::class, + default => throw new InstallationException('Remote source type ' . $remote_source->Type . ' is not implemented'), + }; + + try + { + return $remote_service_client::fetch($parsed_source, $remote_source, $auth_entry); + } + catch(Exception $e) + { + throw new InstallationException('Cannot fetch package from remote source, ' . $e->getMessage(), $e); + } } throw new InstallationException(sprintf('Unknown remote source type %s', $remote_source_type)); -- 2.45.3 From 3a6d008a17cceb611983b80f53c42dace6c70415 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:15:12 -0500 Subject: [PATCH 074/212] Added support for 8.2 --- src/ncc/Abstracts/CompilerExtensionSupportedVersions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Abstracts/CompilerExtensionSupportedVersions.php b/src/ncc/Abstracts/CompilerExtensionSupportedVersions.php index 5e04bc4..822df63 100644 --- a/src/ncc/Abstracts/CompilerExtensionSupportedVersions.php +++ b/src/ncc/Abstracts/CompilerExtensionSupportedVersions.php @@ -4,5 +4,5 @@ abstract class CompilerExtensionSupportedVersions { - const PHP = ['8.0', '8.1']; + const PHP = ['8.0', '8.1', '8.2']; } \ No newline at end of file -- 2.45.3 From eab6c2765f07d2f64525a73c7720933ee704e264 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:17:07 -0500 Subject: [PATCH 075/212] Minor correction --- src/ncc/Objects/Package/Header.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ncc/Objects/Package/Header.php b/src/ncc/Objects/Package/Header.php index 1cc5f3d..2c18c5c 100644 --- a/src/ncc/Objects/Package/Header.php +++ b/src/ncc/Objects/Package/Header.php @@ -41,7 +41,7 @@ /** * The optional update source to where the package can be updated from * - * @var $UpdateSource|null + * @var UpdateSource|null */ public $UpdateSource; @@ -67,7 +67,7 @@ ($bytecode ? Functions::cbc('compiler_extension') : 'compiler_extension') => $this->CompilerExtension->toArray($bytecode), ($bytecode ? Functions::cbc('runtime_constants') : 'runtime_constants') => $this->RuntimeConstants, ($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->CompilerVersion, - ($bytecode ? Functions::cbc('update_source') : 'update_source') => $this->UpdateSource->toArray($bytecode), + ($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->UpdateSource?->toArray($bytecode) ?? null), ($bytecode ? Functions::cbc('options') : 'options') => $this->Options, ]; } -- 2.45.3 From d154aa02ca1bc45b5b9071a8e14c1961a58cfeae Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:19:33 -0500 Subject: [PATCH 076/212] Updated \ncc\Abstracts > DefinedRemoteSourceType https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Abstracts/DefinedRemoteSourceType.php | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/ncc/Abstracts/DefinedRemoteSourceType.php b/src/ncc/Abstracts/DefinedRemoteSourceType.php index 5f19f99..34581d8 100644 --- a/src/ncc/Abstracts/DefinedRemoteSourceType.php +++ b/src/ncc/Abstracts/DefinedRemoteSourceType.php @@ -4,20 +4,6 @@ abstract class DefinedRemoteSourceType { - /** - * The remote source is from a generic remote git server - * (Will search for packages with /group/package) - * - * For example if the host is git.example.com and the package is - * group/package, the package will be fetched from - * https://git.example.com/group/package.git - * - * The git client will be used to fetch the package - * but NCC will not be able to easily check for updates - * without having to pull the entire repository - */ - const Git = 'git'; - /** * THe remote source is from gitlab or a custom gitlab instance * @@ -41,7 +27,6 @@ const Github = 'github'; const All = [ - self::Git, self::Gitlab, self::Github ]; -- 2.45.3 From 23b5ddfa1f1b825b107189bb7e2449e37e3c8710 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:20:00 -0500 Subject: [PATCH 077/212] Added exception \ncc\Exceptions > NotSupportedException --- src/ncc/Exceptions/NotSupportedException.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/NotSupportedException.php diff --git a/src/ncc/Exceptions/NotSupportedException.php b/src/ncc/Exceptions/NotSupportedException.php new file mode 100644 index 0000000..9ea4f25 --- /dev/null +++ b/src/ncc/Exceptions/NotSupportedException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From 623155d96eef3c7eb16cbb2f5654bc8ef999f7d3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:20:33 -0500 Subject: [PATCH 078/212] Added exception \ncc\Exceptions > GitTagsException https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Exceptions/GitTagsException.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/GitTagsException.php diff --git a/src/ncc/Exceptions/GitTagsException.php b/src/ncc/Exceptions/GitTagsException.php new file mode 100644 index 0000000..385de18 --- /dev/null +++ b/src/ncc/Exceptions/GitTagsException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From 7b031af53df4a0cd751e46c4ce6eac3157c2fec1 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:20:49 -0500 Subject: [PATCH 079/212] Added exception \ncc\Exceptions > GithubServiceException https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Exceptions/GithubServiceException.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/GithubServiceException.php diff --git a/src/ncc/Exceptions/GithubServiceException.php b/src/ncc/Exceptions/GithubServiceException.php new file mode 100644 index 0000000..5d62b3b --- /dev/null +++ b/src/ncc/Exceptions/GithubServiceException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From a86140d8a9689ce64e81c4f240439fcb67fb311c Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:21:01 -0500 Subject: [PATCH 080/212] Added exception \ncc\Exceptions > AuthenticationException https://git.n64.cc/nosial/ncc/-/issues/28 --- .../Exceptions/AuthenticationException.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/AuthenticationException.php diff --git a/src/ncc/Exceptions/AuthenticationException.php b/src/ncc/Exceptions/AuthenticationException.php new file mode 100644 index 0000000..29a927c --- /dev/null +++ b/src/ncc/Exceptions/AuthenticationException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From cadfd398367c6f51267d331b8e34dafb9f8253e1 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 21:21:16 -0500 Subject: [PATCH 081/212] Updated \ncc\Abstracts > ExceptionCodes --- src/ncc/Abstracts/ExceptionCodes.php | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 4f49a69..f2bd962 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -300,6 +300,25 @@ */ const ImportException = -1757; + /** + * @see GitTagsException + */ + const GitTagsException = -1758; + + /** + * @see GithubServiceException + */ + const GithubServiceException = -1759; + + /** + * @see AuthenticationException + */ + const AuthenticationException = -1760; + + /** + * @see NotSupportedException + */ + const NotSupportedException = -1761; /** * All the exception codes from NCC @@ -360,6 +379,9 @@ self::UnsupportedRemoteSourceTypeException, self::GitCloneException, self::GitCheckoutException, - self::GitlabServiceException + self::GitlabServiceException, + self::GitTagsException, + self::AuthenticationException, + self::NotSupportedException ]; } \ No newline at end of file -- 2.45.3 From 815637cf3e39eee3953e497b97cb4f5f9dfbd2de Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 22:16:33 -0500 Subject: [PATCH 082/212] Updated Makefile --- Makefile | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index bd0b8dd..f5eaa17 100644 --- a/Makefile +++ b/Makefile @@ -87,16 +87,18 @@ redist: autoload rm -rf $(BUILD_PATH)/src mkdir -p $(BUILD_PATH)/src cp -rf $(SRC_PATH)/ncc/* $(BUILD_PATH)/src - cp $(SRC_PATH)/installer/installer $(BUILD_PATH)/$(SRC_PATH)/INSTALL - cp $(SRC_PATH)/installer/ncc.sh $(BUILD_PATH)/$(SRC_PATH)/ncc.sh - cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/$(SRC_PATH)/default_config.yaml; - cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/$(SRC_PATH)/CLI/template_config.yaml; - cp $(SRC_PATH)/installer/extension $(BUILD_PATH)/$(SRC_PATH)/extension - chmod +x $(BUILD_PATH)/$(SRC_PATH)/INSTALL - cp LICENSE $(BUILD_PATH)/$(SRC_PATH)/LICENSE - cp README.md $(BUILD_PATH)/$(SRC_PATH)/README.md - cp $(SRC_PATH)/installer/hash_check.php $(BUILD_PATH)/$(SRC_PATH)/hash_check.php; $(PHPCC) $(BUILD_PATH)/$(SRC_PATH)/hash_check.php; rm $(BUILD_PATH)/$(SRC_PATH)/hash_check.php - cp $(SRC_PATH)/installer/generate_build_files.php $(BUILD_PATH)/$(SRC_PATH)/generate_build_files.php; $(PHPCC) $(BUILD_PATH)/$(SRC_PATH)/generate_build_files.php; rm $(BUILD_PATH)/$(SRC_PATH)/generate_build_files.php + cp $(SRC_PATH)/installer/installer $(BUILD_PATH)/src/INSTALL + cp $(SRC_PATH)/installer/ncc.sh $(BUILD_PATH)/src/ncc.sh + cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/src/default_config.yaml; + cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/src/CLI/template_config.yaml; + cp $(SRC_PATH)/installer/extension $(BUILD_PATH)/src/extension + chmod +x $(BUILD_PATH)/src/INSTALL + cp LICENSE $(BUILD_PATH)/src/LICENSE + cp README.md $(BUILD_PATH)/src/README.md + cp $(SRC_PATH)/installer/hash_check.php $(BUILD_PATH)/src/hash_check.php; $(PHPCC) $(BUILD_PATH)/src/hash_check.php; rm $(BUILD_PATH)/src/hash_check.php + cp $(SRC_PATH)/installer/generate_build_files.php $(BUILD_PATH)/src/generate_build_files.php; $(PHPCC) $(BUILD_PATH)/src/generate_build_files.php; rm $(BUILD_PATH)/src/generate_build_files.php + mkdir -p $(BUILD_PATH)/src/repositories + cp -rf $(SRC_PATH)/default_repositories/*.json $(BUILD_PATH)/src/repositories tar: redist cd $(BUILD_PATH)/src; tar -czvf ../ncc.tar.gz * -- 2.45.3 From 134c26452a8535c4125dfd671bb283e98724c8a8 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 22:24:12 -0500 Subject: [PATCH 083/212] Updated installer to automatically install pre-defined remote repositories --- src/installer/installer | 57 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/src/installer/installer b/src/installer/installer index 6cfb6e5..a064276 100644 --- a/src/installer/installer +++ b/src/installer/installer @@ -14,9 +14,11 @@ use ncc\Abstracts\ConsoleColors; use ncc\Exceptions\FileNotFoundException; - use ncc\ncc; +use ncc\Managers\RemoteSourcesManager; +use ncc\ncc; use ncc\Objects\CliHelpSection; - use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException; +use ncc\Objects\DefinedRemoteSource; +use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\ThirdParty\Symfony\Process\Exception\ProcessFailedException; use ncc\ThirdParty\Symfony\Process\ExecutableFinder; @@ -818,6 +820,57 @@ return; } + if($NCC_FILESYSTEM->exists(__DIR__ . DIRECTORY_SEPARATOR . 'repositories')) + { + if(!$NCC_FILESYSTEM->exists(__DIR__ . DIRECTORY_SEPARATOR . 'repositories' . DIRECTORY_SEPARATOR . 'custom_repositories.json')) + return; + + try + { + $custom_repositories = Functions::loadJsonFile(__DIR__ . DIRECTORY_SEPARATOR . 'repositories' . DIRECTORY_SEPARATOR . 'custom_repositories.json', Functions::FORCE_ARRAY); + } + catch(Exception $e) + { + $custom_repositories = null; + Console::outWarning(sprintf('Failed to load custom repositories: %s', $e->getMessage())); + } + + if($custom_repositories !== null) + { + $source_manager = new RemoteSourcesManager(); + foreach($custom_repositories as $repository) + { + $repo_path = __DIR__ . DIRECTORY_SEPARATOR . 'repositories' . DIRECTORY_SEPARATOR . $repository; + if($NCC_FILESYSTEM->exists($repo_path)) + { + try + { + $definedEntry = DefinedRemoteSource::fromArray(Functions::loadJsonFile($repo_path, Functions::FORCE_ARRAY)); + if(!$source_manager->getRemoteSource($definedEntry->Name)) + $source_manager->addRemoteSource($definedEntry); + } + catch(Exception $e) + { + Console::outWarning(sprintf('Failed to load custom repository %s: %s', $repository, $e->getMessage())); + } + } + else + { + Console::outWarning(sprintf('Failed to load custom repository %s, file does not exist', $repository)); + } + } + + try + { + $source_manager->save(); + } + catch (\ncc\Exceptions\IOException $e) + { + Console::outWarning(sprintf('Failed to save sources: %s', $e->getMessage())); + } + } + } + Console::out('NCC version: ' . NCC_VERSION_NUMBER . ' has been successfully installed'); Console::out('For licensing information see \'' . $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'LICENSE\' or run \'ncc help --license\''); -- 2.45.3 From d1367ad05d9903cb112ca0750bca30470c20da7f Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 15 Dec 2022 22:28:28 -0500 Subject: [PATCH 084/212] Added Default Repositories --- src/default_repositories/custom_repositories.json | 6 ++++++ src/default_repositories/github.json | 6 ++++++ src/default_repositories/gitlab.json | 6 ++++++ src/default_repositories/n64.json | 6 ++++++ src/default_repositories/nocturn9x.json | 6 ++++++ 5 files changed, 30 insertions(+) create mode 100644 src/default_repositories/custom_repositories.json create mode 100644 src/default_repositories/github.json create mode 100644 src/default_repositories/gitlab.json create mode 100644 src/default_repositories/n64.json create mode 100644 src/default_repositories/nocturn9x.json diff --git a/src/default_repositories/custom_repositories.json b/src/default_repositories/custom_repositories.json new file mode 100644 index 0000000..d2cded0 --- /dev/null +++ b/src/default_repositories/custom_repositories.json @@ -0,0 +1,6 @@ +[ + "github.json", + "gitlab.json", + "n64.json", + "nocturn9x.json" +] \ No newline at end of file diff --git a/src/default_repositories/github.json b/src/default_repositories/github.json new file mode 100644 index 0000000..f095339 --- /dev/null +++ b/src/default_repositories/github.json @@ -0,0 +1,6 @@ +{ + "name": "github", + "type": "github", + "host": "github.com", + "ssl": true +} \ No newline at end of file diff --git a/src/default_repositories/gitlab.json b/src/default_repositories/gitlab.json new file mode 100644 index 0000000..2694fbd --- /dev/null +++ b/src/default_repositories/gitlab.json @@ -0,0 +1,6 @@ +{ + "name": "gitlab", + "type": "gitlab", + "host": "gitlab.com", + "ssl": true +} \ No newline at end of file diff --git a/src/default_repositories/n64.json b/src/default_repositories/n64.json new file mode 100644 index 0000000..ac57ee8 --- /dev/null +++ b/src/default_repositories/n64.json @@ -0,0 +1,6 @@ +{ + "name": "n64", + "type": "gitlab", + "host": "git.n64.cc", + "ssl": true +} \ No newline at end of file diff --git a/src/default_repositories/nocturn9x.json b/src/default_repositories/nocturn9x.json new file mode 100644 index 0000000..121df9b --- /dev/null +++ b/src/default_repositories/nocturn9x.json @@ -0,0 +1,6 @@ +{ + "name": "nocturn9x", + "type": "gitea", + "host": "git.nocturn9x.space", + "ssl": true +} \ No newline at end of file -- 2.45.3 From 7099b02514a2262ebd023e83073529d008431a85 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:03:57 -0500 Subject: [PATCH 085/212] Removed nocturn9x.json for now, gitea support intended in the future. --- src/default_repositories/nocturn9x.json | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/default_repositories/nocturn9x.json diff --git a/src/default_repositories/nocturn9x.json b/src/default_repositories/nocturn9x.json deleted file mode 100644 index 121df9b..0000000 --- a/src/default_repositories/nocturn9x.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "nocturn9x", - "type": "gitea", - "host": "git.nocturn9x.space", - "ssl": true -} \ No newline at end of file -- 2.45.3 From 344454e8c4295746d4bb1979992766b6fb434199 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:21:26 -0500 Subject: [PATCH 086/212] Updated method \ncc\Utilities > HttpClient > displayProgress() --- src/ncc/Utilities/HttpClient.php | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Utilities/HttpClient.php index 180cab3..d87ad98 100644 --- a/src/ncc/Utilities/HttpClient.php +++ b/src/ncc/Utilities/HttpClient.php @@ -4,6 +4,8 @@ use CurlHandle; use ncc\Abstracts\HttpRequestType; + use ncc\Abstracts\LogLevel; + use ncc\CLI\Main; use ncc\Exceptions\HttpException; use ncc\Objects\HttpRequest; use ncc\Objects\HttpResponse; @@ -176,8 +178,24 @@ */ public static function displayProgress($resource, $downloadSize, $downloaded, $uploadSize, $uploaded): void { - if ($downloadSize > 0) - Console::inlineProgressBar($downloaded, $downloadSize); + if(Main::getLogLevel() !== null) + { + switch(Main::getLogLevel()) + { + case LogLevel::Verbose: + case LogLevel::Debug: + case LogLevel::Silent: + Console::outVerbose(sprintf(' <= %s of %s bytes downloaded', $downloaded, $downloadSize)); + break; + + default: + if ($downloadSize > 0) + Console::inlineProgressBar($downloaded, $downloadSize); + break; + } + } + + } /** -- 2.45.3 From 9003222d510a4c235c5ffc2ba9fa278857f72a58 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:36:48 -0500 Subject: [PATCH 087/212] Added class \ncc\Classes\GithubExtension > GithubService https://git.n64.cc/nosial/ncc/-/issues/28 --- .../Classes/GithubExtension/GithubService.php | 334 ++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 src/ncc/Classes/GithubExtension/GithubService.php diff --git a/src/ncc/Classes/GithubExtension/GithubService.php b/src/ncc/Classes/GithubExtension/GithubService.php new file mode 100644 index 0000000..c5823a1 --- /dev/null +++ b/src/ncc/Classes/GithubExtension/GithubService.php @@ -0,0 +1,334 @@ +Host)); + $ncc_package = self::getNccPackage($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $ncc_package = null; + unset($e); + } + + if($ncc_package !== null) + { + try + { + return Functions::downloadGitServiceFile($ncc_package, $entry); + } + catch(Exception $e) + { + throw new GithubServiceException(sprintf('Failed to download pre-compiled package from %s', $definedRemoteSource->Host), $e); + } + } + + // Check if the specified version is a release + try + { + Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host)); + $release_url = self::getRelease($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $release_url = null; + unset($e); + } + + // If the specified version is a release, download the source code + if($release_url !== null) + { + try + { + $release_file = Functions::downloadGitServiceFile($release_url, $entry); + $project_path = Functions::extractArchive($release_file); + return PackageCompiler::tryCompile($project_path); + } + catch(Exception $e) + { + throw new GithubServiceException(sprintf('Failed to download release from %s', $definedRemoteSource->Host), $e); + } + } + + try + { + Console::outVerbose(sprintf('Attempting to fetch git repository from %s', $definedRemoteSource->Host)); + $git_url = self::fetchGitUri($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $git_url = null; + unset($e); + } + + if($git_url !== null) + { + try + { + $project_path = GitClient::cloneRepository($git_url); + + foreach(GitClient::getTags($project_path) as $tag) + { + $tag = str_replace('v', '', $tag); + if(VersionComparator::compareVersion($tag, $packageInput->Version) === 0) + { + GitClient::checkout($project_path, $tag); + return PackageCompiler::tryCompile($project_path); + } + } + } + catch(Exception $e) + { + throw new GithubServiceException(sprintf('Failed to clone git repository from %s', $definedRemoteSource->Host), $e); + } + } + + throw new GithubServiceException('Unable to fetch package from remote source'); + } + + + /** + * Returns the git repository url of the repository, versions cannot be specified. + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + * @throws GithubServiceException + * @throws GitlabServiceException + * @throws AuthenticationException + * @throws HttpException + * @throws MalformedJsonException + */ + public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + { + $httpRequest = new HttpRequest(); + $protocol = ($definedRemoteSource->SSL ? "https" : "http"); + $owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); + $owner_f = str_ireplace(".", "%2F", $owner_f); + $repository = urlencode($packageInput->Package); + $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository"; + $httpRequest->Type = HttpRequestType::POST; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); + + $response = HttpClient::request($httpRequest); + + if($response->StatusCode != 200) + throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); + + $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); + + return + $response_decoded['git_url'] ?? + $response_decoded['clone_url'] ?? + $response_decoded['ssh_url'] ?? + throw new GithubServiceException('Failed to fetch the repository URL.'); + } + + /** + * Returns the download URL of the requested version of the package. + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + * @throws AuthenticationException + * @throws GithubServiceException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + * @throws VersionNotFoundException + */ + public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + { + $releases = self::getReleases($packageInput, $definedRemoteSource, $entry); + + if(count($releases) === 0) + throw new VersionNotFoundException('No releases found for the given repository.'); + + if($packageInput->Version == Versions::Latest) + { + $latest_version = null; + foreach($releases as $version => $url) + { + if($latest_version == null) + { + $latest_version = $version; + continue; + } + + if(VersionComparator::compareVersion($version, $latest_version) == 1) + $latest_version = $version; + } + + return $releases[$latest_version]['url']; + } + + if(!isset($releases[$packageInput->Version])) + throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); + + return $releases[$packageInput->Version]['url']; + } + + /** + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + * @throws AuthenticationException + * @throws GithubServiceException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + * @throws VersionNotFoundException + */ + public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + { + $releases = self::getReleases($packageInput, $definedRemoteSource, $entry); + + if(count($releases) === 0) + throw new VersionNotFoundException('No releases found for the given repository.'); + + if($packageInput->Version == Versions::Latest) + { + $latest_version = null; + foreach($releases as $version => $url) + { + if($latest_version == null) + { + $latest_version = $version; + continue; + } + + if(VersionComparator::compareVersion($version, $latest_version) == 1) + $latest_version = $version; + } + + return $releases[$latest_version]['package']; + } + + if(!isset($releases[$packageInput->Version])) + throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); + + return $releases[$packageInput->Version]['package']; + } + + /** + * Returns a list of all releases of the given repository with their download URL. + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return array + * @throws AuthenticationException + * @throws GithubServiceException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + */ + private static function getReleases(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): array + { + $httpRequest = new HttpRequest(); + $protocol = ($definedRemoteSource->SSL ? "https" : "http"); + $owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); + $owner_f = str_ireplace(".", "%2F", $owner_f); + $repository = urlencode($packageInput->Package); + $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases"; + $httpRequest->Type = HttpRequestType::POST; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); + + $response = HttpClient::request($httpRequest); + + if($response->StatusCode != 200) + throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); + + $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); + + if(count($response_decoded) == 0) + return []; + + $return = []; + foreach($response_decoded as $release) + { + // Make the tag_name version friendly + $release_version = str_replace('v', '', $release['tag_name']); + $return[$release_version] = [ + 'url' => ($release['tarball_url'] ?? $release['zipball_url'] ?? null) + ]; + + if(isset($release['assets'])) + { + foreach($release['assets'] as $asset) + { + if(self::parseAsset($asset) !== null) + $return[$release_version]['package'] = $asset['browser_download_url']; + } + } + } + + return $return; + } + + /** + * Returns the asset download URL if it points to a .ncc package. + * + * @param array $asset + * @return string|null' + */ + private static function parseAsset(array $asset): ?string + { + if(isset($asset['browser_download_url'])) + { + $file_extension = pathinfo($asset['browser_download_url'], PATHINFO_EXTENSION); + if($file_extension == 'ncc') + return $asset['browser_download_url']; + } + + return null; + } + } \ No newline at end of file -- 2.45.3 From 6a37c8216d4e789b94d76d9051648e87cfef33c3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:37:06 -0500 Subject: [PATCH 088/212] Added ProjectType to \ncc\Abstracts --- src/ncc/Abstracts/ProjectType.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/ncc/Abstracts/ProjectType.php diff --git a/src/ncc/Abstracts/ProjectType.php b/src/ncc/Abstracts/ProjectType.php new file mode 100644 index 0000000..004d76f --- /dev/null +++ b/src/ncc/Abstracts/ProjectType.php @@ -0,0 +1,12 @@ + Date: Fri, 16 Dec 2022 00:37:43 -0500 Subject: [PATCH 089/212] Added \ncc\Exceptions > UnsupportedProjectTypeException https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Abstracts/ExceptionCodes.php | 10 ++++++--- .../UnsupportedProjectTypeException.php | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/ncc/Exceptions/UnsupportedProjectTypeException.php diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index f2bd962..60d7412 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -2,8 +2,6 @@ namespace ncc\Abstracts; - use ncc\Exceptions\GitlabServiceException; - /** * @author Zi Xing Narrakas * @copyright Copyright (C) 2022-2022. Nosial - All Rights Reserved. @@ -320,6 +318,11 @@ */ const NotSupportedException = -1761; + /** + * @see UnsupportedProjectTypeException + */ + const UnsupportedProjectTypeException = -1762; + /** * All the exception codes from NCC */ @@ -382,6 +385,7 @@ self::GitlabServiceException, self::GitTagsException, self::AuthenticationException, - self::NotSupportedException + self::NotSupportedException, + self::UnsupportedProjectTypeException ]; } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedProjectTypeException.php b/src/ncc/Exceptions/UnsupportedProjectTypeException.php new file mode 100644 index 0000000..384a2b2 --- /dev/null +++ b/src/ncc/Exceptions/UnsupportedProjectTypeException.php @@ -0,0 +1,21 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From ff04349ae4a386f5e9c25f0c21657e9934479f04 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:38:04 -0500 Subject: [PATCH 090/212] Added method \ncc\Classes\NccExtension > PackageCompiler > tryCompile() --- .../Classes/NccExtension/PackageCompiler.php | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index fc66a12..f27f2ac 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -7,6 +7,8 @@ use ncc\Abstracts\ConstantReferences; use ncc\Abstracts\LogLevel; use ncc\Abstracts\Options\BuildConfigurationValues; + use ncc\Abstracts\ProjectType; + use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; use ncc\Classes\PhpExtension\PhpCompiler; use ncc\CLI\Main; use ncc\Exceptions\AccessDeniedException; @@ -18,6 +20,7 @@ use ncc\Exceptions\PackagePreparationFailedException; use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\UnsupportedCompilerExtensionException; + use ncc\Exceptions\UnsupportedProjectTypeException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Interfaces\CompilerInterface; use ncc\Managers\ProjectManager; @@ -84,6 +87,39 @@ ); } + /** + * Attempts to detect the project type and convert it accordingly before compiling + * Returns the compiled package path + * + * @param string $path + * @return string + * @throws BuildException + * @throws UnsupportedProjectTypeException + */ + public static function tryCompile(string $path): string + { + $project_type = Resolver::detectProjectType($path); + + try + { + if($project_type->ProjectType == ProjectType::Composer) + return ComposerSourceBuiltin::fromLocal($project_type->ProjectPath); + + if($project_type->ProjectType == ProjectType::Ncc) + { + $project_manager = new ProjectManager($project_type->ProjectPath); + return $project_manager->build(); + } + } + catch(Exception $e) + { + throw new BuildException('Failed to build project', $e); + } + + + throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported'); + } + /** * Compiles the execution policies of the package * -- 2.45.3 From c904a172254b3efdaba70d7e905a290d4196da9d Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:38:19 -0500 Subject: [PATCH 091/212] Moved HttpClient to \ncc\Classes --- src/ncc/{Utilities => Classes}/HttpClient.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename src/ncc/{Utilities => Classes}/HttpClient.php (98%) diff --git a/src/ncc/Utilities/HttpClient.php b/src/ncc/Classes/HttpClient.php similarity index 98% rename from src/ncc/Utilities/HttpClient.php rename to src/ncc/Classes/HttpClient.php index d87ad98..409ade0 100644 --- a/src/ncc/Utilities/HttpClient.php +++ b/src/ncc/Classes/HttpClient.php @@ -1,6 +1,6 @@ Date: Fri, 16 Dec 2022 00:38:46 -0500 Subject: [PATCH 092/212] Added GitClient to \ncc\Classes https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Classes/GitClient.php | 118 ++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/ncc/Classes/GitClient.php diff --git a/src/ncc/Classes/GitClient.php b/src/ncc/Classes/GitClient.php new file mode 100644 index 0000000..ec94a30 --- /dev/null +++ b/src/ncc/Classes/GitClient.php @@ -0,0 +1,118 @@ +setTimeout(3600); // 1 hour + $process->run(function ($type, $buffer) + { + if (Process::ERR === $type) + { + Console::outWarning($buffer); + } + else + { + Console::outVerbose($buffer); + } + }); + + if (!$process->isSuccessful()) + throw new GitCloneException($process->getErrorOutput()); + + Console::outVerbose('Repository cloned to ' . $path); + return $path; + } + + /** + * Checks out a specific branch or tag. + * + * @param string $path + * @param string $branch + * @throws GitCheckoutException + */ + public static function checkout(string $path, string $branch) + { + $process = new Process(["git", "checkout", $branch], $path); + $process->setTimeout(3600); // 1 hour + $process->run(function ($type, $buffer) + { + if (Process::ERR === $type) + { + Console::outWarning($buffer); + } + else + { + Console::outVerbose($buffer); + } + }); + + if (!$process->isSuccessful()) + throw new GitCheckoutException($process->getErrorOutput()); + + Console::outVerbose('Checked out branch ' . $branch); + } + + /** + * Returns an array of tags that are available in the repository. + * + * @param string $path + * @return array + * @throws GitTagsException + */ + public static function getTags(string $path): array + { + $process = new Process(["git", "fetch", '--all', '--tags'] , $path); + $process->setTimeout(3600); // 1 hour + $process->run(function ($type, $buffer) + { + if (Process::ERR === $type) + { + Console::outWarning($buffer); + } + else + { + Console::outVerbose($buffer); + } + }); + + if (!$process->isSuccessful()) + throw new GitTagsException($process->getErrorOutput()); + + $process = new Process(['git', '--no-pager', 'tag', '-l'] , $path); + + $process->run(function ($type, $buffer) + { + if (Process::ERR === $type) + Console::outWarning($buffer); + + }); + + if (!$process->isSuccessful()) + throw new GitTagsException($process->getErrorOutput()); + + $tags = explode(PHP_EOL, $process->getOutput()); + return array_filter($tags); + } + + } \ No newline at end of file -- 2.45.3 From 2b78bdd9595ff63c66b1e83b78fa1dc23b15c398 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:39:05 -0500 Subject: [PATCH 093/212] Added \ncc\Objects > ProjectDetectionResults https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Objects/ProjectDetectionResults.php | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/ncc/Objects/ProjectDetectionResults.php diff --git a/src/ncc/Objects/ProjectDetectionResults.php b/src/ncc/Objects/ProjectDetectionResults.php new file mode 100644 index 0000000..0729a91 --- /dev/null +++ b/src/ncc/Objects/ProjectDetectionResults.php @@ -0,0 +1,23 @@ + Date: Fri, 16 Dec 2022 00:40:13 -0500 Subject: [PATCH 094/212] Added method \ncc\Utilities > Functions > downloadGitServiceFile() Added method \ncc\Utilities > Functions > prepareGitServiceRequest() https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Utilities/Functions.php | 79 +++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 7a37f96..381e8d6 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -4,9 +4,11 @@ use Exception; use ncc\Abstracts\AuthenticationType; + use ncc\Abstracts\HttpRequestType; use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; + use ncc\Classes\HttpClient; use ncc\Classes\LuaExtension\LuaRunner; use ncc\Classes\PerlExtension\PerlRunner; use ncc\Classes\PhpExtension\PhpRunner; @@ -17,6 +19,7 @@ use ncc\Exceptions\AuthenticationException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\GitlabServiceException; + use ncc\Exceptions\HttpException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; use ncc\Exceptions\MalformedJsonException; @@ -32,6 +35,8 @@ use ncc\Objects\Vault\Entry; use ncc\ThirdParty\jelix\Version\Parser; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; + use PharData; + use ZipArchive; /** * @author Zi Xing Narrakas @@ -517,11 +522,12 @@ * * @param HttpRequest $httpRequest * @param Entry|null $entry + * @param bool $expect_json * @return HttpRequest * @throws AuthenticationException * @throws GitlabServiceException */ - public static function prepareGitServiceRequest(HttpRequest $httpRequest, ?Entry $entry=null): HttpRequest + public static function prepareGitServiceRequest(HttpRequest $httpRequest, ?Entry $entry=null, bool $expect_json=true): HttpRequest { if($entry !== null) { @@ -538,9 +544,76 @@ } } - $httpRequest->Headers[] = "Accept: application/json"; - $httpRequest->Headers[] = "Content-Type: application/json"; + if($expect_json) + { + $httpRequest->Headers[] = "Accept: application/json"; + $httpRequest->Headers[] = "Content-Type: application/json"; + } return $httpRequest; } + + /** + * Downloads a file from the given URL and saves it to the given path + * + * @param string $url + * @param Entry|null $entry + * @return string + * @throws AuthenticationException + * @throws GitlabServiceException + * @throws InvalidScopeException + * @throws HttpException + */ + public static function downloadGitServiceFile(string $url, ?Entry $entry=null): string + { + $out_path = Functions::getTmpDir() . "/" . basename($url); + + $httpRequest = new HttpRequest(); + $httpRequest->Url = $url; + $httpRequest->Type = HttpRequestType::GET; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); + + Console::out('Downloading file ' . $url); + HttpClient::download($httpRequest, $out_path); + + return $out_path; + } + + /** + * @param string $path + * @return string + * @throws Exception + */ + public static function extractArchive(string $path): string + { + $filesystem = new Filesystem(); + if(!$filesystem->exists(dirname($path))) + $filesystem->mkdir(dirname($path)); + + switch(pathinfo($path, PATHINFO_EXTENSION)) + { + case 'zip': + $zip = new ZipArchive(); + $zip->open($path); + $zip->extractTo(dirname($path)); + $zip->close(); + break; + + case 'tar': + $phar = new PharData($path); + $phar->extractTo(dirname($path)); + break; + + case 'gz': + $phar = new PharData($path); + $phar->decompress(); + break; + + default: + throw new Exception('Unsupported archive type'); + } + + return dirname($path); + } + } \ No newline at end of file -- 2.45.3 From 75aacc62fa9d5d2d63cda78af81a82194d498908 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:40:35 -0500 Subject: [PATCH 095/212] Added method \ncc\Resolvers > detectProjectType() https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Utilities/Resolver.php | 45 ++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/ncc/Utilities/Resolver.php b/src/ncc/Utilities/Resolver.php index cc3cb29..bd14ef2 100644 --- a/src/ncc/Utilities/Resolver.php +++ b/src/ncc/Utilities/Resolver.php @@ -7,9 +7,12 @@ use ncc\Abstracts\BuiltinRemoteSourceType; use ncc\Abstracts\DefinedRemoteSourceType; use ncc\Abstracts\LogLevel; + use ncc\Abstracts\ProjectType; use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; use ncc\Managers\RemoteSourcesManager; + use ncc\Objects\ProjectDetectionResults; + use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner; class Resolver { @@ -266,4 +269,46 @@ return $defined_source->Type; } + + /** + * Detects the project type from the specified path + * + * @param string $path + * @param array $exlucde + * @return ProjectDetectionResults + */ + public static function detectProjectType(string $path, array $exlucde=[]): ProjectDetectionResults + { + $Scanner = new DirectoryScanner(); + $Scanner->setExcludes($exlucde); + $project_files = [ + 'composer.json', + 'package.json', + ]; + + $project_detection_results = new ProjectDetectionResults(); + $project_detection_results->ProjectType = ProjectType::Unknown; + + /** @var \SplFileInfo $item */ + foreach($Scanner($path, true) as $item) + { + if(in_array($item->getFilename(), $project_files)) + { + switch($item->getFilename()) + { + case 'composer.json': + $project_detection_results->ProjectType = ProjectType::Composer; + $project_detection_results->ProjectPath = dirname($item->getPathname()); + break; + + case 'project.json': + $project_detection_results->ProjectType = ProjectType::Ncc; + $project_detection_results->ProjectPath = dirname($item->getPathname()); + break; + } + } + } + + return $project_detection_results; + } } \ No newline at end of file -- 2.45.3 From fecc7e046505dd35a69b8364f41b18656cbbd0b5 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 00:41:09 -0500 Subject: [PATCH 096/212] Updated \ncc\Objects > DefinedRemoteSource https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/Objects/DefinedRemoteSource.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Objects/DefinedRemoteSource.php b/src/ncc/Objects/DefinedRemoteSource.php index 7177e3c..f636463 100644 --- a/src/ncc/Objects/DefinedRemoteSource.php +++ b/src/ncc/Objects/DefinedRemoteSource.php @@ -19,7 +19,7 @@ public $Name; /** - * The type of service NCC should use with this source (git, gitlab, github, etc...). + * The type of service NCC should use with this source (gitlab, github, etc...). * * @var string|DefinedRemoteSourceType */ -- 2.45.3 From 150ff9dee3345f001d55f9e9c16bc2a7846d6492 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 01:15:12 -0500 Subject: [PATCH 097/212] Refactored \ncc\Classes\ComposerExtension > ComposerSourceBuiltin to allow for building from local packages --- .../ComposerSourceBuiltin.php | 465 +++++++++++------- 1 file changed, 288 insertions(+), 177 deletions(-) diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index 8fbd154..85f94f5 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -32,6 +32,8 @@ use ncc\Exceptions\UserAbortedOperationException; use ncc\Interfaces\ServiceSourceInterface; use ncc\Managers\ProjectManager; + use ncc\ncc; + use ncc\Objects\ComposerJson; use ncc\Objects\ComposerLock; use ncc\Objects\ProjectConfiguration; use ncc\Objects\RemotePackageInput; @@ -95,6 +97,68 @@ throw new RuntimeException(sprintf('Could not find package %s in the compiled packages', $packageInput->toStandard())); } + /** + * Works with a local composer.json file and attempts to compile the required packages + * and their dependencies, returns the path to the compiled package. + * + * @param string $path + * @return string + * @throws AccessDeniedException + * @throws BuildConfigurationNotFoundException + * @throws BuildException + * @throws ComposerDisabledException + * @throws ComposerException + * @throws ComposerNotAvailableException + * @throws DirectoryNotFoundException + * @throws FileNotFoundException + * @throws IOException + * @throws InternalComposerNotAvailableException + * @throws MalformedJsonException + * @throws PackageNotFoundException + * @throws PackagePreparationFailedException + * @throws ProjectConfigurationNotFoundException + * @throws UnsupportedCompilerExtensionException + * @throws UnsupportedRunnerException + * @throws UserAbortedOperationException + */ + public static function fromLocal(string $path): string + { + // Check if the file composer.json exists + if (!file_exists($path . DIRECTORY_SEPARATOR . 'composer.json')) + throw new FileNotFoundException(sprintf('File "%s" not found', $path . DIRECTORY_SEPARATOR . 'composer.json')); + + // Execute composer with options + $options = self::getOptions(); + $composer_exec = self::getComposerPath(); + $process = new Process([$composer_exec, 'install']); + self::prepareProcess($process, $path, $options); + + Console::outDebug(sprintf('executing %s', $process->getCommandLine())); + $process->run(function ($type, $buffer) { + Console::out($buffer, false); + }); + + if (!$process->isSuccessful()) + throw new ComposerException($process->getErrorOutput()); + + $filesystem = new Filesystem(); + if($filesystem->exists($path . DIRECTORY_SEPARATOR . 'build')) + $filesystem->remove($path . DIRECTORY_SEPARATOR . 'build'); + $filesystem->mkdir($path . DIRECTORY_SEPARATOR . 'build'); + + // Compile dependencies + self::compilePackages($path . DIRECTORY_SEPARATOR . 'composer.lock'); + + // Finally convert the main package's composer.json to package.json and compile it + ComposerSourceBuiltin::convertProject($path); + $project_manager = new ProjectManager($path); + $project_manager->load(); + $built_package = $project_manager->build(); + + RuntimeCache::setFileAsTemporary($built_package); + return $built_package; + } + /** * @param string $composer_lock_path * @return array @@ -133,154 +197,16 @@ foreach ($composer_lock->Packages as $package) { $package_path = $base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->Name; - // Generate the package configuration - $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($package->Name, $composer_lock); - // Process the source files - if ($package->Autoload !== null) - { - $source_directory = $package_path . DIRECTORY_SEPARATOR . '.src'; - if ($filesystem->exists($source_directory)) - { - $filesystem->remove($source_directory); - } - $filesystem->mkdir($source_directory); - $source_directories = []; - $static_files = []; + // Load the composer lock file + $composer_package = $composer_lock->getPackage($package->Name); + if ($composer_package == null) + throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package->Name)); - // Extract all the source directories - if ($package->Autoload->Psr4 !== null && count($package->Autoload->Psr4) > 0) - { - Console::outVerbose('Extracting PSR-4 source directories'); - foreach ($package->Autoload->Psr4 as $namespace_pointer) - { - if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories)) - { - $source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path; - } - } - } - - if ($package->Autoload->Psr0 !== null && count($package->Autoload->Psr0) > 0) - { - Console::outVerbose('Extracting PSR-0 source directories'); - foreach ($package->Autoload->Psr0 as $namespace_pointer) - { - if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories)) - { - $source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path; - } - } - } - - if ($package->Autoload->Files !== null && count($package->Autoload->Files) > 0) - { - Console::outVerbose('Extracting static files'); - foreach ($package->Autoload->Files as $file) - { - $static_files[] = $package_path . DIRECTORY_SEPARATOR . $file; - } - } - - Console::outDebug(sprintf('source directories: %s', implode(', ', $source_directories))); - - // First scan the project files and create a file struct. - $DirectoryScanner = new DirectoryScanner(); - - // TODO: Implement exclude-class handling - try - { - $DirectoryScanner->unsetFlag(FilesystemIterator::FOLLOW_SYMLINKS); - } - catch (Exception $e) - { - throw new PackagePreparationFailedException('Cannot unset flag \'FOLLOW_SYMLINKS\' in DirectoryScanner, ' . $e->getMessage(), $e); - } - - // Include file components that can be compiled - $DirectoryScanner->setIncludes(ComponentFileExtensions::Php); - - foreach ($source_directories as $directory) - { - /** @var SplFileInfo $item */ - /** @noinspection PhpRedundantOptionalArgumentInspection */ - foreach ($DirectoryScanner($directory, True) as $item) - { - if (is_dir($item->getPathName())) - continue; - - $parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName()); - - Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name)); - $filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path); - } - } - - if (count($static_files) > 0) - { - $project_configuration->Project->Options['static_files'] = $static_files; - - foreach ($static_files as $file) - { - $parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $file); - Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name)); - $filesystem->copy($file, $source_directory . DIRECTORY_SEPARATOR . $parsed_path); - } - unset($file); - } - - $project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json'); - } + // Convert it to a NCC project configuration + $project_configuration = self::convertProject($package_path, $composer_package); // Load the project - $license_files = [ - 'LICENSE', - 'license', - 'LICENSE.txt', - 'license.txt' - ]; - - foreach($license_files as $license_file) - { - if($filesystem->exists($package_path . DIRECTORY_SEPARATOR . $license_file)) - { - // Check configuration if composer.extension.display_licenses is set - if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_licenses'))) - { - Console::out(sprintf('License for package %s:', $package->Name)); - Console::out(IO::fread($package_path . DIRECTORY_SEPARATOR . $license_file)); - } - } - } - - if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_authors'))) - { - if($package->Authors !== null && count($package->Authors) > 0) - { - Console::out(sprintf('Authors for package %s:', $package->Name)); - foreach($package->Authors as $author) - { - Console::out(sprintf(' - %s', $author->Name)); - - if($author->Email !== null) - { - Console::out(sprintf(' %s', $author->Email)); - } - - if($author->Homepage !== null) - { - Console::out(sprintf(' %s', $author->Homepage)); - } - - if($author->Role !== null) - { - Console::out(sprintf(' %s', $author->Role)); - } - - } - } - } - $project_manager = new ProjectManager($package_path); $project_manager->load(); $built_package = $project_manager->build(); @@ -288,6 +214,7 @@ // Copy the project to the build directory $out_path = $base_dir . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . sprintf('%s=%s.ncc', $project_configuration->Assembly->Package, $project_configuration->Assembly->Version); $filesystem->copy($built_package, $out_path); + $filesystem->remove($built_package); $built_packages[$project_configuration->Assembly->Package] = $out_path; } @@ -323,18 +250,12 @@ * Generates a project configuration from a package selection * from the composer.lock file * - * @param string $package_name - * @param ComposerLock $composer_lock + * @param ComposerJson $composer_package * @return ProjectConfiguration - * @throws PackageNotFoundException + * @throws Exception */ - private static function generateProjectConfiguration(string $package_name, ComposerLock $composer_lock): ProjectConfiguration + private static function generateProjectConfiguration(ComposerJson $composer_package): ProjectConfiguration { - // Load the composer lock file - $composer_package = $composer_lock->getPackage($package_name); - if ($composer_package == null) - throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package_name)); - // Generate a new project configuration object $project_configuration = new ProjectConfiguration(); @@ -345,14 +266,22 @@ if (isset($composer_package->Version)) $project_configuration->Assembly->Version = Functions::parseVersion($composer_package->Version); + if($project_configuration->Assembly->Version == null || $project_configuration->Assembly->Version == '') + $project_configuration->Assembly->Version = '1.0.0'; + $project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122(); - $project_configuration->Assembly->Package = self::toPackageName($package_name); + $project_configuration->Assembly->Package = self::toPackageName($composer_package->Name); + + // Add the update source + $project_configuration->Project->UpdateSource = new ProjectConfiguration\UpdateSource(); + $project_configuration->Project->UpdateSource->Source = sprintf('%s=%s@composer', str_ireplace('\\', '/', $composer_package->Name), $composer_package->Version); + $project_configuration->Project->UpdateSource->Repository = null; // Process the dependencies foreach ($composer_package->Require as $item) { $package_name = self::toPackageName($item->PackageName); - $package_version = $composer_lock->getPackage($item->PackageName)?->Version; + $package_version = $composer_package->Version; if ($package_version == null) { $package_version = '1.0.0'; @@ -485,7 +414,6 @@ * @param string $vendor * @param string $package * @param string|null $version - * @param array $options * @return string * @throws AccessDeniedException * @throws ComposerDisabledException @@ -497,7 +425,7 @@ * @throws InvalidScopeException * @throws UserAbortedOperationException */ - private static function require(string $vendor, string $package, ?string $version = null, array $options = []): string + private static function require(string $vendor, string $package, ?string $version = null): string { if (Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Insufficient permissions to require'); @@ -530,26 +458,7 @@ // Execute composer with options $options = self::getOptions(); $process = new Process(array_merge([$composer_exec, 'require'], $options)); - $process->setWorkingDirectory($tmp_dir); - - // Check if scripts are enabled while running as root - if (!in_array('--no-scripts', $options) && Resolver::resolveScope() == Scopes::System) - { - Console::outWarning('composer scripts are enabled while running as root, this can allow malicious scripts to run as root'); - if (!isset($options['--no-interaction'])) - { - if (!Console::getBooleanInput('Do you want to continue?')) - throw new UserAbortedOperationException('The operation was aborted by the user'); - - // The user understands the risks and wants to continue - $process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]); - } - } - else - { - // Composer is running "safely". We can disable the superuser check - $process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]); - } + self::prepareProcess($process, $tmp_dir, $options); Console::outDebug(sprintf('executing %s', $process->getCommandLine())); $process->run(function ($type, $buffer) { @@ -606,4 +515,206 @@ throw new ComposerNotAvailableException('No composer executable path is configured'); } + + /** + * @param Process $process + * @param string $path + * @param array $options + * @return void + * @throws UserAbortedOperationException + */ + private static function prepareProcess(Process $process, string $path, array $options): void + { + $process->setWorkingDirectory($path); + + // Check if scripts are enabled while running as root + if (!in_array('--no-scripts', $options) && Resolver::resolveScope() == Scopes::System) + { + Console::outWarning('composer scripts are enabled while running as root, this can allow malicious scripts to run as root'); + if (!isset($options['--no-interaction'])) + { + if (!Console::getBooleanInput('Do you want to continue?')) + throw new UserAbortedOperationException('The operation was aborted by the user'); + + // The user understands the risks and wants to continue + $process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]); + } + } + else + { + // Composer is running "safely". We can disable the superuser check + $process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]); + } + } + + /** + * Converts a composer project to a NCC project + * + * @param mixed $composer_package + * @param string $package_path + * @return ProjectConfiguration + * @throws AccessDeniedException + * @throws FileNotFoundException + * @throws IOException + * @throws MalformedJsonException + * @throws PackagePreparationFailedException + * @throws Exception + */ + private static function convertProject(string $package_path, ?ComposerJson $composer_package=null): ProjectConfiguration + { + if($composer_package == null) + ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json')); + + $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package); + $filesystem = new Filesystem(); + + // Process the source files + if ($composer_package->Autoload !== null) + { + $source_directory = $package_path . DIRECTORY_SEPARATOR . '.src'; + if ($filesystem->exists($source_directory)) + $filesystem->remove($source_directory); + $filesystem->mkdir($source_directory); + $source_directories = []; + $static_files = []; + + // Extract all the source directories + if ($composer_package->Autoload->Psr4 !== null && count($composer_package->Autoload->Psr4) > 0) + { + Console::outVerbose('Extracting PSR-4 source directories'); + foreach ($composer_package->Autoload->Psr4 as $namespace_pointer) + { + if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories)) + { + $source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path; + } + } + } + + if ($composer_package->Autoload->Psr0 !== null && count($composer_package->Autoload->Psr0) > 0) + { + Console::outVerbose('Extracting PSR-0 source directories'); + foreach ($composer_package->Autoload->Psr0 as $namespace_pointer) + { + if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories)) + { + $source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path; + } + } + } + + if ($composer_package->Autoload->Files !== null && count($composer_package->Autoload->Files) > 0) + { + Console::outVerbose('Extracting static files'); + foreach ($composer_package->Autoload->Files as $file) + { + $static_files[] = $package_path . DIRECTORY_SEPARATOR . $file; + } + } + + Console::outDebug(sprintf('source directories: %s', implode(', ', $source_directories))); + + // First scan the project files and create a file struct. + $DirectoryScanner = new DirectoryScanner(); + + // TODO: Implement exclude-class handling + try + { + $DirectoryScanner->unsetFlag(FilesystemIterator::FOLLOW_SYMLINKS); + } + catch (Exception $e) + { + throw new PackagePreparationFailedException('Cannot unset flag \'FOLLOW_SYMLINKS\' in DirectoryScanner, ' . $e->getMessage(), $e); + } + + // Include file components that can be compiled + $DirectoryScanner->setIncludes(ComponentFileExtensions::Php); + + foreach ($source_directories as $directory) + { + /** @var SplFileInfo $item */ + /** @noinspection PhpRedundantOptionalArgumentInspection */ + foreach ($DirectoryScanner($directory, True) as $item) + { + if (is_dir($item->getPathName())) + continue; + + $parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName()); + + Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $composer_package->Name)); + $filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path); + } + } + + if (count($static_files) > 0) + { + $project_configuration->Project->Options['static_files'] = $static_files; + + foreach ($static_files as $file) + { + $parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $file); + Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $composer_package->Name)); + $filesystem->copy($file, $source_directory . DIRECTORY_SEPARATOR . $parsed_path); + } + unset($file); + } + + $project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json'); + } + + // This part simply displays the package information to the command-line interface + if(ncc::cliMode()) + { + $license_files = [ + 'LICENSE', + 'license', + 'LICENSE.txt', + 'license.txt' + ]; + + foreach($license_files as $license_file) + { + if($filesystem->exists($package_path . DIRECTORY_SEPARATOR . $license_file)) + { + // Check configuration if composer.extension.display_licenses is set + if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_licenses'))) + { + Console::out(sprintf('License for package %s:', $composer_package->Name)); + Console::out(IO::fread($package_path . DIRECTORY_SEPARATOR . $license_file)); + break; + } + } + } + + if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_authors'))) + { + if($composer_package->Authors !== null && count($composer_package->Authors) > 0) + { + Console::out(sprintf('Authors for package %s:', $composer_package->Name)); + foreach($composer_package->Authors as $author) + { + Console::out(sprintf(' - %s', $author->Name)); + + if($author->Email !== null) + { + Console::out(sprintf(' %s', $author->Email)); + } + + if($author->Homepage !== null) + { + Console::out(sprintf(' %s', $author->Homepage)); + } + + if($author->Role !== null) + { + Console::out(sprintf(' %s', $author->Role)); + } + + } + } + } + } + + return $project_configuration; + } } \ No newline at end of file -- 2.45.3 From e1bb4cf92e7a49afb0caa0907e3d406c938153a0 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 01:16:09 -0500 Subject: [PATCH 098/212] Added \ncc\Classes\GitlabExtension > GitlabService https://git.n64.cc/nosial/ncc/-/issues/24 --- .../Classes/GitlabExtension/GitlabService.php | 252 ++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 src/ncc/Classes/GitlabExtension/GitlabService.php diff --git a/src/ncc/Classes/GitlabExtension/GitlabService.php b/src/ncc/Classes/GitlabExtension/GitlabService.php new file mode 100644 index 0000000..74ee85f --- /dev/null +++ b/src/ncc/Classes/GitlabExtension/GitlabService.php @@ -0,0 +1,252 @@ +Host)); + $release_url = self::getRelease($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $release_url = null; + unset($e); + } + + // If the specified version is a release, download the source code + if($release_url !== null) + { + try + { + $release_file = Functions::downloadGitServiceFile($release_url, $entry); + $project_path = Functions::extractArchive($release_file); + return PackageCompiler::tryCompile($project_path); + } + catch(Exception $e) + { + throw new GitlabServiceException(sprintf('Failed to download release from %s', $definedRemoteSource->Host), $e); + } + } + + try + { + Console::outVerbose(sprintf('Attempting to fetch git repository from %s', $definedRemoteSource->Host)); + $git_url = self::fetchGitUri($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $git_url = null; + unset($e); + } + + if($git_url !== null) + { + try + { + $project_path = GitClient::cloneRepository($git_url); + + foreach(GitClient::getTags($project_path) as $tag) + { + $tag = str_replace('v', '', $tag); + if(VersionComparator::compareVersion($tag, $packageInput->Version) === 0) + { + GitClient::checkout($project_path, $tag); + return PackageCompiler::tryCompile($project_path); + } + } + } + catch(Exception $e) + { + throw new GitlabServiceException(sprintf('Failed to clone git repository from %s', $definedRemoteSource->Host), $e); + } + } + + throw new GitlabServiceException('Unable to fetch package from remote source'); + } + + /** + * Attempts to return the gitRepositoryUrl of a release, cannot specify a version. + * This needs to be done using git + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + * @throws AuthenticationException + */ + public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): string + { + $httpRequest = new HttpRequest(); + $protocol = ($definedRemoteSource->SSL ? "https" : "http"); + $owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); + $owner_f = str_ireplace(".", "%2F", $owner_f); + $repository = urlencode($packageInput->Package); + $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository"; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); + + $response = HttpClient::request($httpRequest); + + if($response->StatusCode != 200) + throw new GitlabServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); + + $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); + + return + $response_decoded['http_url_to_repo'] ?? + $response_decoded['ssh_url_to_repo'] ?? + throw new GitlabServiceException('Failed to fetch the repository URL.'); + } + + /** + * Returns the download URL of the requested version of the package. + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + * @throws AuthenticationException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + * @throws VersionNotFoundException + */ + public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + { + $releases = self::getReleases($packageInput->Vendor, $packageInput->Package, $definedRemoteSource, $entry); + + if(count($releases) === 0) + throw new VersionNotFoundException('No releases found for the given repository.'); + + if($packageInput->Version == Versions::Latest) + { + $latest_version = null; + foreach($releases as $version => $url) + { + if($latest_version == null) + { + $latest_version = $version; + continue; + } + + if(VersionComparator::compareVersion($version, $latest_version) == 1) + $latest_version = $version; + } + + return $releases[$latest_version]; + } + + if(!isset($releases[$packageInput->Version])) + throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); + + return $releases[$packageInput->Version]; + } + + /** + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return string + * @throws NotSupportedException + */ + public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + { + throw new NotSupportedException(sprintf('The given repository source "%s" does not support ncc packages.', $definedRemoteSource->Host)); + } + + /** + * Returns an array of all the tags for the given owner and repository name. + * + * @param string $owner + * @param string $repository + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return array + * @throws AuthenticationException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + */ + private static function getReleases(string $owner, string $repository, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): array + { + $httpRequest = new HttpRequest(); + $protocol = ($definedRemoteSource->SSL ? "https" : "http"); + $owner_f = str_ireplace("/", "%2F", $owner); + $owner_f = str_ireplace(".", "%2F", $owner_f); + $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository/releases"; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); + + $response = HttpClient::request($httpRequest); + + if($response->StatusCode != 200) + throw new GitlabServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); + + $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); + + if(count($response_decoded) == 0) + return []; + + $return = []; + foreach($response_decoded as $release) + { + // Make the tag_name version friendly + $release_version = str_replace('v', '', $release['tag_name']); + + if(isset($release['assets']) && isset($release['assets']['sources'])) + { + if(count($release['assets']['sources']) > 0) + { + // Use the first source as the download url, if a tar.gz file is available, use that instead. + $return[$release_version] = $release['assets']['sources'][0]['url']; + foreach($release['assets']['sources'] as $source) + { + if($source['format'] == 'tar.gz') + { + $return[$release_version] = $source['url']; + break; + } + } + } + } + } + + return $return; + } + } \ No newline at end of file -- 2.45.3 From b0d6654e95dbaf42f667f73f0e8dd165877a3e55 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 01:44:53 -0500 Subject: [PATCH 099/212] Implemented remote source resolving and install handling https://git.n64.cc/nosial/ncc/-/issues/28 --- src/ncc/CLI/PackageManagerMenu.php | 80 +++++++++++++------ src/ncc/Managers/PackageManager.php | 33 ++++---- .../ProjectConfiguration/Dependency.php | 2 +- 3 files changed, 76 insertions(+), 39 deletions(-) diff --git a/src/ncc/CLI/PackageManagerMenu.php b/src/ncc/CLI/PackageManagerMenu.php index a66d117..612d733 100644 --- a/src/ncc/CLI/PackageManagerMenu.php +++ b/src/ncc/CLI/PackageManagerMenu.php @@ -4,13 +4,21 @@ use Exception; use ncc\Abstracts\ConsoleColors; - use ncc\Abstracts\RemoteSource; + use ncc\Abstracts\BuiltinRemoteSourceType; + use ncc\Abstracts\DefinedRemoteSourceType; + use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; - use ncc\Classes\ComposerExtension\ComposerSource; + use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; + use ncc\Classes\GithubExtension\GithubService; + use ncc\Classes\GitlabExtension\GitlabService; use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\InstallationException; use ncc\Exceptions\PackageLockException; + use ncc\Exceptions\RuntimeException; use ncc\Exceptions\VersionNotFoundException; + use ncc\Managers\CredentialManager; use ncc\Managers\PackageManager; + use ncc\Managers\RemoteSourcesManager; use ncc\Objects\CliHelpSection; use ncc\Objects\Package; use ncc\Objects\RemotePackageInput; @@ -32,6 +40,7 @@ { try { + Console::outException('Example Error', new Exception('test'), 1); self::installPackage($args); return; } @@ -191,33 +200,58 @@ return; } - $path = $package; - $parsed_source = new RemotePackageInput($path); - if($parsed_source->Vendor !== null && $parsed_source->Package !== null) + // check if authentication is provided + $entry_arg = ($args['auth'] ?? null); + $credential_manager = new CredentialManager(); + $credential = $credential_manager->getVault()->getEntry($entry_arg); + + if($credential == null) { - if($parsed_source->Source == null) + Console::outError(sprintf('Unknown credential entry \'%s\'', $entry_arg), true, 1); + return; + } + + if(!$credential->isCurrentlyDecrypted()) + { + // Try 3 times + for($i = 0; $i < 3; $i++) { - Console::outError('No source specified', true, 1); - return; + try + { + $credential->unlock(Console::passwordInput(sprintf('Enter Password for %s: ', $credential->getName()))); + } + catch (RuntimeException $e) + { + Console::outException(sprintf('Failed to unlock credential %s', $credential->getName()), $e, 1); + return; + } + + if($credential->isCurrentlyDecrypted()) + break; + + Console::outWarning(sprintf('Invalid password, %d attempts remaining', 2 - $i)); } - switch($parsed_source->Source) + if(!$credential->isCurrentlyDecrypted()) { - case RemoteSource::Composer: - try - { - $path = ComposerSource::fetch($parsed_source); - break; - } - catch(Exception $e) - { - Console::outException(sprintf('Failed to fetch package %s', $package), $e, 1); - return; - } + Console::outError('Failed to unlock credential', true, 1); + return; + } + } - default: - Console::outError('Cannot install package from source: ' . $parsed_source->Source, true, 1); - return; + $path = $package; + $parsed_source = new RemotePackageInput($path); + + if($parsed_source->Vendor !== null && $parsed_source->Package !== null) + { + try + { + $path = $package_manager->fetchFromSource($parsed_source->toString()); + } + catch (Exception $e) + { + Console::outException('Failed to fetch package from source', $e, 1); + return; } } diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index b3a883e..143c036 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -110,10 +110,13 @@ $extension = $package->Header->CompilerExtension->Extension; $installation_paths = new InstallationPaths($this->PackagesPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '=' . $package->Assembly->Version); - $installer = match ($extension) { + + $installer = match ($extension) + { CompilerExtensions::PHP => new PhpInstaller($package), default => throw new UnsupportedCompilerExtensionException('The compiler extension \'' . $extension . '\' is not supported'), }; + $execution_pointer_manager = new ExecutionPointerManager(); PackageCompiler::compilePackageConstants($package, [ ConstantReferences::Install => $installation_paths @@ -407,24 +410,19 @@ * * @param string $source * @return string - * @throws AccessDeniedException - * @throws FileNotFoundException - * @throws IOException * @throws InstallationException - * @throws MissingDependencyException - * @throws NotImplementedException - * @throws PackageAlreadyInstalledException - * @throws PackageLockException - * @throws PackageNotFoundException - * @throws PackageParsingException - * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException - * @throws VersionNotFoundException */ public function installFromSource(string $source): string { - $package_path = $this->fetchFromSource($source); - return $this->install($package_path); + try + { + $package = $this->fetchFromSource($source); + return $this->install($package); + } + catch(Exception $e) + { + throw new InstallationException('Cannot install package from source, ' . $e->getMessage(), $e); + } } /** @@ -481,6 +479,11 @@ case DependencySourceType::StaticLinking: throw new PackageNotFoundException('Static linking not possible, package ' . $dependency->Name . ' is not installed'); + case DependencySourceType::RemoteSource: + Console::outDebug('installing from remote source ' . $dependency->Source); + $this->installFromSource($dependency->Source); + break; + default: throw new NotImplementedException('Dependency source type ' . $dependency->SourceType . ' is not implemented'); } diff --git a/src/ncc/Objects/ProjectConfiguration/Dependency.php b/src/ncc/Objects/ProjectConfiguration/Dependency.php index 3fa3116..6978740 100644 --- a/src/ncc/Objects/ProjectConfiguration/Dependency.php +++ b/src/ncc/Objects/ProjectConfiguration/Dependency.php @@ -30,7 +30,7 @@ /** * Optional. The actual source where NCC can fetch the dependency from * - * @var DependencySourceType|string|null + * @var string|null */ public $Source; -- 2.45.3 From a59c7c4a8d13b35bb9b103c6caf7c428f139e88b Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 01:48:16 -0500 Subject: [PATCH 100/212] Added Credential passthrough --- src/ncc/CLI/PackageManagerMenu.php | 4 ++-- src/ncc/Managers/PackageManager.php | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ncc/CLI/PackageManagerMenu.php b/src/ncc/CLI/PackageManagerMenu.php index 612d733..e6aa13d 100644 --- a/src/ncc/CLI/PackageManagerMenu.php +++ b/src/ncc/CLI/PackageManagerMenu.php @@ -246,7 +246,7 @@ { try { - $path = $package_manager->fetchFromSource($parsed_source->toString()); + $path = $package_manager->fetchFromSource($parsed_source->toString(), $credential); } catch (Exception $e) { @@ -364,7 +364,7 @@ { try { - $package_manager->install($path); + $package_manager->install($path, $credential); Console::out(sprintf('Package %s installed successfully', $package->Assembly->Package)); } catch(Exception $e) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 143c036..a62d311 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -95,7 +95,7 @@ * @throws UnsupportedRunnerException * @throws VersionNotFoundException */ - public function install(string $package_path): string + public function install(string $package_path, ?Entry $entry=null): string { if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Insufficient permission to install packages'); @@ -127,7 +127,7 @@ { foreach($package->Dependencies as $dependency) { - $this->processDependency($dependency, $package, $package_path); + $this->processDependency($dependency, $package, $package_path, $entry); } } @@ -412,12 +412,12 @@ * @return string * @throws InstallationException */ - public function installFromSource(string $source): string + public function installFromSource(string $source, ?Entry $entry): string { try { - $package = $this->fetchFromSource($source); - return $this->install($package); + $package = $this->fetchFromSource($source, $entry); + return $this->install($package, $entry); } catch(Exception $e) { @@ -444,7 +444,7 @@ * @throws UnsupportedRunnerException * @throws VersionNotFoundException */ - private function processDependency(Dependency $dependency, Package $package, string $package_path): void + private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null): void { Console::outVerbose('processing dependency ' . $dependency->Name . ' (' . $dependency->Version . ')'); $dependent_package = $this->getPackage($dependency->Name); @@ -481,7 +481,7 @@ case DependencySourceType::RemoteSource: Console::outDebug('installing from remote source ' . $dependency->Source); - $this->installFromSource($dependency->Source); + $this->installFromSource($dependency->Source, $entry); break; default: -- 2.45.3 From aec5dea17c62a9129d1b05fcf80d17820a9d32ce Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 01:48:59 -0500 Subject: [PATCH 101/212] Cleanup --- src/ncc/CLI/PackageManagerMenu.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/ncc/CLI/PackageManagerMenu.php b/src/ncc/CLI/PackageManagerMenu.php index e6aa13d..8695104 100644 --- a/src/ncc/CLI/PackageManagerMenu.php +++ b/src/ncc/CLI/PackageManagerMenu.php @@ -4,21 +4,13 @@ use Exception; use ncc\Abstracts\ConsoleColors; - use ncc\Abstracts\BuiltinRemoteSourceType; - use ncc\Abstracts\DefinedRemoteSourceType; - use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; - use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; - use ncc\Classes\GithubExtension\GithubService; - use ncc\Classes\GitlabExtension\GitlabService; use ncc\Exceptions\FileNotFoundException; - use ncc\Exceptions\InstallationException; use ncc\Exceptions\PackageLockException; use ncc\Exceptions\RuntimeException; use ncc\Exceptions\VersionNotFoundException; use ncc\Managers\CredentialManager; use ncc\Managers\PackageManager; - use ncc\Managers\RemoteSourcesManager; use ncc\Objects\CliHelpSection; use ncc\Objects\Package; use ncc\Objects\RemotePackageInput; -- 2.45.3 From 4bd8a0f017fa2f9138dd263e1b68ac49b3f794fe Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 01:49:33 -0500 Subject: [PATCH 102/212] Minor change --- src/ncc/CLI/PackageManagerMenu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/CLI/PackageManagerMenu.php b/src/ncc/CLI/PackageManagerMenu.php index 8695104..e873c57 100644 --- a/src/ncc/CLI/PackageManagerMenu.php +++ b/src/ncc/CLI/PackageManagerMenu.php @@ -234,7 +234,7 @@ $path = $package; $parsed_source = new RemotePackageInput($path); - if($parsed_source->Vendor !== null && $parsed_source->Package !== null) + if($parsed_source->Vendor !== null && $parsed_source->Package !== null && $parsed_source->Source !== null) { try { -- 2.45.3 From f41a3a63514f735ff7093af9dda275c022c8c681 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 03:08:04 -0500 Subject: [PATCH 103/212] Improved exception display --- src/ncc/Utilities/Console.php | 20 +++++++++++++++++--- src/ncc/Utilities/Functions.php | 5 +++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index c492611..27710eb 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -11,6 +11,7 @@ use ncc\ncc; use ncc\Objects\CliHelpSection; use ncc\ThirdParty\Symfony\Process\ExecutableFinder; + use Throwable; class Console { @@ -317,16 +318,20 @@ * Prints out a detailed exception display (unfinished) * * @param Exception $e + * @param bool $sub * @return void */ - private static function outExceptionDetails(Exception $e): void + private static function outExceptionDetails(Throwable $e, bool $sub=false): void { if(!ncc::cliMode()) return; + // Exception name without namespace + $trace_header = self::formatColor($e->getFile() . ':' . $e->getLine(), ConsoleColors::Magenta); - $trace_error = self::formatColor('error: ', ConsoleColors::Red); + $trace_error = self::formatColor( 'Error: ', ConsoleColors::Red); self::out($trace_header . ' ' . $trace_error . $e->getMessage()); + self::out(sprintf('Exception: %s', get_class($e))); self::out(sprintf('Error code: %s', $e->getCode())); $trace = $e->getTrace(); if(count($trace) > 1) @@ -338,7 +343,16 @@ } } - if(Main::getArgs() !== null) + if($e->getPrevious() !== null) + { + // Check if previous is the same as the current + if($e->getPrevious()->getMessage() !== $e->getMessage()) + { + self::outExceptionDetails($e->getPrevious(), true); + } + } + + if(Main::getArgs() !== null && !$sub) { if(isset(Main::getArgs()['dbg-ex'])) { diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 381e8d6..928114c 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -36,6 +36,7 @@ use ncc\ThirdParty\jelix\Version\Parser; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use PharData; + use Throwable; use ZipArchive; /** @@ -290,7 +291,7 @@ * @param Exception $e * @return array */ - public static function exceptionToArray(Exception $e): array + public static function exceptionToArray(Throwable $e): array { $exception = [ 'message' => $e->getMessage(), @@ -303,7 +304,7 @@ if($e->getPrevious() !== null) { - $exception['trace'] = self::exceptionToArray($e); + $exception['previous'] = self::exceptionToArray($e->getPrevious()); } return $exception; -- 2.45.3 From 06e876bc03e8191c743cc6cd09d77feab28eab3a Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 16 Dec 2022 12:20:45 -0500 Subject: [PATCH 104/212] Bug Fixes Part 1 --- src/default_repositories/github.json | 2 +- src/ncc/CLI/PackageManagerMenu.php | 19 ++- .../ComposerSourceBuiltin.php | 62 ++++++---- src/ncc/Classes/GitClient.php | 22 +--- .../Classes/GithubExtension/GithubService.php | 30 +++-- .../Classes/GitlabExtension/GitlabService.php | 16 ++- src/ncc/Classes/HttpClient.php | 24 ++-- .../Classes/NccExtension/PackageCompiler.php | 17 +-- src/ncc/Classes/PhpExtension/PhpCompiler.php | 116 ++++++++++-------- src/ncc/Objects/Vault/Entry.php | 1 - src/ncc/Utilities/Console.php | 2 +- src/ncc/Utilities/Functions.php | 94 ++++++++++---- src/ncc/Utilities/Resolver.php | 50 ++++---- 13 files changed, 260 insertions(+), 195 deletions(-) diff --git a/src/default_repositories/github.json b/src/default_repositories/github.json index f095339..f05cc8c 100644 --- a/src/default_repositories/github.json +++ b/src/default_repositories/github.json @@ -1,6 +1,6 @@ { "name": "github", "type": "github", - "host": "github.com", + "host": "api.github.com", "ssl": true } \ No newline at end of file diff --git a/src/ncc/CLI/PackageManagerMenu.php b/src/ncc/CLI/PackageManagerMenu.php index e873c57..5c7945d 100644 --- a/src/ncc/CLI/PackageManagerMenu.php +++ b/src/ncc/CLI/PackageManagerMenu.php @@ -32,7 +32,6 @@ { try { - Console::outException('Example Error', new Exception('test'), 1); self::installPackage($args); return; } @@ -195,15 +194,23 @@ // check if authentication is provided $entry_arg = ($args['auth'] ?? null); $credential_manager = new CredentialManager(); - $credential = $credential_manager->getVault()->getEntry($entry_arg); - if($credential == null) + if($entry_arg !== null) { - Console::outError(sprintf('Unknown credential entry \'%s\'', $entry_arg), true, 1); - return; + $credential = $credential_manager->getVault()->getEntry($entry_arg); + + if($credential == null) + { + Console::outError(sprintf('Unknown credential entry \'%s\'', $entry_arg), true, 1); + return; + } + } + else + { + $credential = null; } - if(!$credential->isCurrentlyDecrypted()) + if($credential !== null && !$credential->isCurrentlyDecrypted()) { // Try 3 times for($i = 0; $i < 3; $i++) diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index 85f94f5..e97d4b4 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -35,6 +35,7 @@ use ncc\ncc; use ncc\Objects\ComposerJson; use ncc\Objects\ComposerLock; + use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; use ncc\Objects\RemotePackageInput; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; @@ -47,6 +48,7 @@ use ncc\Utilities\PathFinder; use ncc\Utilities\Resolver; use ncc\Utilities\RuntimeCache; + use ncc\Utilities\Validate; use SplFileInfo; class ComposerSourceBuiltin implements ServiceSourceInterface @@ -212,11 +214,10 @@ $built_package = $project_manager->build(); // Copy the project to the build directory - $out_path = $base_dir . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . sprintf('%s=%s.ncc', $project_configuration->Assembly->Package, $project_configuration->Assembly->Version); + $out_path = $base_dir . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . sprintf('%s.ncc', $project_configuration->Assembly->Package); $filesystem->copy($built_package, $out_path); $filesystem->remove($built_package); $built_packages[$project_configuration->Assembly->Package] = $out_path; - } return $built_packages; @@ -269,35 +270,50 @@ if($project_configuration->Assembly->Version == null || $project_configuration->Assembly->Version == '') $project_configuration->Assembly->Version = '1.0.0'; + if(!Validate::version($project_configuration->Assembly->Version)) + $project_configuration->Assembly->Version = Functions::convertToSemVer($project_configuration->Assembly->Version); + + if(!Validate::version($project_configuration->Assembly->Version)) + { + Console::outWarning(sprintf('Invalid version "%s" for package "%s", using "1.0.0" instead', $project_configuration->Assembly->Version, $project_configuration->Assembly->Name)); + $project_configuration->Assembly->Version = '1.0.0'; + } + + RuntimeCache::set(sprintf('composer_version_%s', $project_configuration->Assembly->Package), $project_configuration->Assembly->Version); + + $project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122(); $project_configuration->Assembly->Package = self::toPackageName($composer_package->Name); // Add the update source $project_configuration->Project->UpdateSource = new ProjectConfiguration\UpdateSource(); - $project_configuration->Project->UpdateSource->Source = sprintf('%s=%s@composer', str_ireplace('\\', '/', $composer_package->Name), $composer_package->Version); + $project_configuration->Project->UpdateSource->Source = sprintf('%s@composer', str_ireplace('\\', '/', $composer_package->Name)); $project_configuration->Project->UpdateSource->Repository = null; // Process the dependencies - foreach ($composer_package->Require as $item) + if($composer_package->Require !== null && count($composer_package->Require) > 0) { - $package_name = self::toPackageName($item->PackageName); - $package_version = $composer_package->Version; - if ($package_version == null) + foreach ($composer_package->Require as $item) { - $package_version = '1.0.0'; + $package_name = self::toPackageName($item->PackageName); + $package_version = $composer_package->Version; + if ($package_version == null) + { + $package_version = '1.0.0'; + } + else + { + $package_version = Functions::parseVersion($package_version); + } + if ($package_name == null) + continue; + $dependency = new ProjectConfiguration\Dependency(); + $dependency->Name = $package_name; + $dependency->SourceType = DependencySourceType::Local; + $dependency->Version = $package_version; + $dependency->Source = $package_name . '.ncc'; + $project_configuration->Build->Dependencies[] = $dependency; } - else - { - $package_version = Functions::parseVersion($package_version); - } - if ($package_name == null) - continue; - $dependency = new ProjectConfiguration\Dependency(); - $dependency->Name = $package_name; - $dependency->SourceType = DependencySourceType::Local; - $dependency->Version = $package_version; - $dependency->Source = $package_name . '=' . $dependency->Version . '.ncc'; - $project_configuration->Build->Dependencies[] = $dependency; } // Create a build configuration @@ -563,7 +579,7 @@ private static function convertProject(string $package_path, ?ComposerJson $composer_package=null): ProjectConfiguration { if($composer_package == null) - ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json')); + $composer_package = ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json', Functions::FORCE_ARRAY)); $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package); $filesystem = new Filesystem(); @@ -658,10 +674,10 @@ } unset($file); } - - $project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json'); } + $project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json'); + // This part simply displays the package information to the command-line interface if(ncc::cliMode()) { diff --git a/src/ncc/Classes/GitClient.php b/src/ncc/Classes/GitClient.php index ec94a30..c7daca4 100644 --- a/src/ncc/Classes/GitClient.php +++ b/src/ncc/Classes/GitClient.php @@ -27,14 +27,7 @@ $process->setTimeout(3600); // 1 hour $process->run(function ($type, $buffer) { - if (Process::ERR === $type) - { - Console::outWarning($buffer); - } - else - { - Console::outVerbose($buffer); - } + Console::outVerbose($buffer); }); if (!$process->isSuccessful()) @@ -86,14 +79,7 @@ $process->setTimeout(3600); // 1 hour $process->run(function ($type, $buffer) { - if (Process::ERR === $type) - { - Console::outWarning($buffer); - } - else - { - Console::outVerbose($buffer); - } + Console::outVerbose($buffer); }); if (!$process->isSuccessful()) @@ -103,9 +89,7 @@ $process->run(function ($type, $buffer) { - if (Process::ERR === $type) - Console::outWarning($buffer); - + Console::outVerbose($buffer); }); if (!$process->isSuccessful()) diff --git a/src/ncc/Classes/GithubExtension/GithubService.php b/src/ncc/Classes/GithubExtension/GithubService.php index c5823a1..745eed2 100644 --- a/src/ncc/Classes/GithubExtension/GithubService.php +++ b/src/ncc/Classes/GithubExtension/GithubService.php @@ -153,10 +153,12 @@ $owner_f = str_ireplace(".", "%2F", $owner_f); $repository = urlencode($packageInput->Package); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository"; - $httpRequest->Type = HttpRequestType::POST; - $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); + $httpRequest->Type = HttpRequestType::GET; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); + $httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28'; + $httpRequest->Headers[] = 'Accept: application/vnd.github+json'; - $response = HttpClient::request($httpRequest); + $response = HttpClient::request($httpRequest, true); if($response->StatusCode != 200) throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); @@ -249,13 +251,21 @@ $latest_version = $version; } - return $releases[$latest_version]['package']; + $return = $releases[$latest_version]['package'] ?? null; + if($return === null) + throw new VersionNotFoundException('No releases found for the given repository.'); + + return $return; } if(!isset($releases[$packageInput->Version])) throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); - return $releases[$packageInput->Version]['package']; + $return = $releases[$packageInput->Version]['package'] ?? null; + if($return === null) + throw new VersionNotFoundException('No releases found for the given repository.'); + + return $return; } /** @@ -279,10 +289,12 @@ $owner_f = str_ireplace(".", "%2F", $owner_f); $repository = urlencode($packageInput->Package); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases"; - $httpRequest->Type = HttpRequestType::POST; - $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); + $httpRequest->Type = HttpRequestType::GET; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); + $httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28'; + $httpRequest->Headers[] = 'Accept: application/vnd.github+json'; - $response = HttpClient::request($httpRequest); + $response = HttpClient::request($httpRequest, true); if($response->StatusCode != 200) throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); @@ -298,7 +310,7 @@ // Make the tag_name version friendly $release_version = str_replace('v', '', $release['tag_name']); $return[$release_version] = [ - 'url' => ($release['tarball_url'] ?? $release['zipball_url'] ?? null) + 'url' => ($release['zipball_url'] ?? $release['tarball_url'] ?? null) ]; if(isset($release['assets'])) diff --git a/src/ncc/Classes/GitlabExtension/GitlabService.php b/src/ncc/Classes/GitlabExtension/GitlabService.php index 74ee85f..b398d5d 100644 --- a/src/ncc/Classes/GitlabExtension/GitlabService.php +++ b/src/ncc/Classes/GitlabExtension/GitlabService.php @@ -118,11 +118,12 @@ $protocol = ($definedRemoteSource->SSL ? "https" : "http"); $owner_f = str_ireplace("/", "%2F", $packageInput->Vendor); $owner_f = str_ireplace(".", "%2F", $owner_f); - $repository = urlencode($packageInput->Package); - $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository"; + $project_f = str_ireplace("/", "%2F", $packageInput->Package); + $project_f = str_ireplace(".", "%2F", $project_f); + $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$project_f"; $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); - $response = HttpClient::request($httpRequest); + $response = HttpClient::request($httpRequest, true); if($response->StatusCode != 200) throw new GitlabServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); @@ -210,10 +211,13 @@ $protocol = ($definedRemoteSource->SSL ? "https" : "http"); $owner_f = str_ireplace("/", "%2F", $owner); $owner_f = str_ireplace(".", "%2F", $owner_f); - $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository/releases"; + $repository_f = str_ireplace("/", "%2F", $repository); + $repository_f = str_ireplace(".", "%2F", $repository_f); + + $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository_f/releases"; $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry); - $response = HttpClient::request($httpRequest); + $response = HttpClient::request($httpRequest, true); if($response->StatusCode != 200) throw new GitlabServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); @@ -237,7 +241,7 @@ $return[$release_version] = $release['assets']['sources'][0]['url']; foreach($release['assets']['sources'] as $source) { - if($source['format'] == 'tar.gz') + if($source['format'] == 'zip') { $return[$release_version] = $source['url']; break; diff --git a/src/ncc/Classes/HttpClient.php b/src/ncc/Classes/HttpClient.php index 409ade0..73da79a 100644 --- a/src/ncc/Classes/HttpClient.php +++ b/src/ncc/Classes/HttpClient.php @@ -206,19 +206,19 @@ * @param string $headers * @return array */ - private static function parseHeaders(string $headers): array + private static function parseHeaders(string $input): array { - $headers = explode("\r", $headers); - $headers = array_filter($headers, function ($header) - { - return !empty($header); - }); - $headers = array_map(function ($header) { - return explode(':', $header, 2); - }, $headers); + $headers = array(); + $lines = explode("\n", $input); + $headers['HTTP'] = array_shift($lines); - return array_combine(array_map(function ($header) { return strtolower($header[0]); }, $headers), - array_map(function ($header) { return trim($header[1]); }, $headers) - ); + foreach ($lines as $line) { + $header = explode(':', $line, 2); + if (count($header) == 2) { + $headers[trim($header[0])] = trim($header[1]); + } + } + + return $headers; } } \ No newline at end of file diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index f27f2ac..08c96bb 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -116,7 +116,6 @@ throw new BuildException('Failed to build project', $e); } - throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported'); } @@ -168,7 +167,6 @@ * @param string $build_configuration * @return string * @throws BuildConfigurationNotFoundException - * @throws BuildException * @throws IOException */ public static function writePackage(string $path, Package $package, ProjectConfiguration $configuration, string $build_configuration=BuildConfigurationValues::DefaultConfiguration): string @@ -176,21 +174,14 @@ // Write the package to disk $FileSystem = new Filesystem(); $BuildConfiguration = $configuration->Build->getBuildConfiguration($build_configuration); - if($FileSystem->exists($path . $BuildConfiguration->OutputPath)) - { - try - { - $FileSystem->remove($path . $BuildConfiguration->OutputPath); - } - catch(\ncc\ThirdParty\Symfony\Filesystem\Exception\IOException $e) - { - throw new BuildException('Cannot delete directory \'' . $path . $BuildConfiguration->OutputPath . '\', ' . $e->getMessage(), $e); - } - } + if(!$FileSystem->exists($path . $BuildConfiguration->OutputPath)) + $FileSystem->mkdir($path . $BuildConfiguration->OutputPath); // Finally write the package to the disk $FileSystem->mkdir($path . $BuildConfiguration->OutputPath); $output_file = $path . $BuildConfiguration->OutputPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '.ncc'; + if($FileSystem->exists($output_file)) + $FileSystem->remove($output_file); $FileSystem->touch($output_file); try diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index bb29ce9..f105d12 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -128,67 +128,75 @@ // TODO: Re-implement the scanning process outside the compiler, as this is will be redundant // Scan for components first. - Console::outVerbose('Scanning for components... '); - /** @var SplFileInfo $item */ - /** @noinspection PhpRedundantOptionalArgumentInspection */ - foreach($DirectoryScanner($source_path, True) as $item) + + if(file_exists($source_path)) { - // Ignore directories, they're not important. :-) - if(is_dir($item->getPathName())) - continue; + Console::outVerbose('Scanning for components... '); + /** @var SplFileInfo $item */ + /** @noinspection PhpRedundantOptionalArgumentInspection */ + foreach($DirectoryScanner($source_path, True) as $item) + { + // Ignore directories, they're not important. :-) + if(is_dir($item->getPathName())) + continue; - $Component = new Package\Component(); - $Component->Name = Functions::removeBasename($item->getPathname(), $this->path); - $this->package->Components[] = $Component; + $Component = new Package\Component(); + $Component->Name = Functions::removeBasename($item->getPathname(), $this->path); + $this->package->Components[] = $Component; - Console::outVerbose(sprintf('Found component %s', $Component->Name)); - } + Console::outVerbose(sprintf('Found component %s', $Component->Name)); + } - if(count($this->package->Components) > 0) - { - Console::outVerbose(count($this->package->Components) . ' component(s) found'); + if(count($this->package->Components) > 0) + { + Console::outVerbose(count($this->package->Components) . ' component(s) found'); + } + else + { + Console::outVerbose('No components found'); + } + + // Clear previous excludes and includes + $DirectoryScanner->setExcludes([]); + $DirectoryScanner->setIncludes([]); + + // Ignore component files + if($selected_build_configuration->ExcludeFiles !== null && count($selected_build_configuration->ExcludeFiles) > 0) + { + $DirectoryScanner->setExcludes(array_merge($selected_build_configuration->ExcludeFiles, ComponentFileExtensions::Php)); + } + else + { + $DirectoryScanner->setExcludes(ComponentFileExtensions::Php); + } + + Console::outVerbose('Scanning for resources... '); + /** @var SplFileInfo $item */ + foreach($DirectoryScanner($source_path) as $item) + { + // Ignore directories, they're not important. :-) + if(is_dir($item->getPathName())) + continue; + + $Resource = new Package\Resource(); + $Resource->Name = Functions::removeBasename($item->getPathname(), $this->path); + $this->package->Resources[] = $Resource; + + Console::outVerbose(sprintf('found resource %s', $Resource->Name)); + } + + if(count($this->package->Resources) > 0) + { + Console::outVerbose(count($this->package->Resources) . ' resources(s) found'); + } + else + { + Console::outVerbose('No resources found'); + } } else { - Console::outVerbose('No components found'); - } - - // Clear previous excludes and includes - $DirectoryScanner->setExcludes([]); - $DirectoryScanner->setIncludes([]); - - // Ignore component files - if($selected_build_configuration->ExcludeFiles !== null && count($selected_build_configuration->ExcludeFiles) > 0) - { - $DirectoryScanner->setExcludes(array_merge($selected_build_configuration->ExcludeFiles, ComponentFileExtensions::Php)); - } - else - { - $DirectoryScanner->setExcludes(ComponentFileExtensions::Php); - } - - Console::outVerbose('Scanning for resources... '); - /** @var SplFileInfo $item */ - foreach($DirectoryScanner($source_path) as $item) - { - // Ignore directories, they're not important. :-) - if(is_dir($item->getPathName())) - continue; - - $Resource = new Package\Resource(); - $Resource->Name = Functions::removeBasename($item->getPathname(), $this->path); - $this->package->Resources[] = $Resource; - - Console::outVerbose(sprintf('found resource %s', $Resource->Name)); - } - - if(count($this->package->Resources) > 0) - { - Console::outVerbose(count($this->package->Resources) . ' resources(s) found'); - } - else - { - Console::outVerbose('No resources found'); + Console::outWarning('Source path does not exist, skipping resource and component scanning'); } $selected_dependencies = []; diff --git a/src/ncc/Objects/Vault/Entry.php b/src/ncc/Objects/Vault/Entry.php index 6f52b6b..c1e45b0 100644 --- a/src/ncc/Objects/Vault/Entry.php +++ b/src/ncc/Objects/Vault/Entry.php @@ -149,7 +149,6 @@ return false; $this->Password = $this->encrypt(); - var_dump($this->Password); return true; } diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index 27710eb..642d3fb 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -126,7 +126,7 @@ /** @noinspection PhpRedundantOptionalArgumentInspection */ $tick_time = str_pad($tick_time, (strlen($tick_time) + (self::$largestTickLength - strlen($tick_time))), ' ', STR_PAD_RIGHT); - return '[' . $tick_time . ' - ' . date('TH:i:sP') . '] ' . $input; + return '[' . $tick_time . '] ' . $input; } /** diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 928114c..1c7a41f 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -36,6 +36,8 @@ use ncc\ThirdParty\jelix\Version\Parser; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use PharData; + use RecursiveDirectoryIterator; + use RecursiveIteratorIterator; use Throwable; use ZipArchive; @@ -585,36 +587,82 @@ * @return string * @throws Exception */ - public static function extractArchive(string $path): string + public static function extractArchive(string $path): ?string { - $filesystem = new Filesystem(); - if(!$filesystem->exists(dirname($path))) - $filesystem->mkdir(dirname($path)); + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($finfo, $path); + finfo_close($finfo); - switch(pathinfo($path, PATHINFO_EXTENSION)) + if ($mimeType == 'application/zip') { - case 'zip': - $zip = new ZipArchive(); - $zip->open($path); + $zip = new ZipArchive; + $res = $zip->open($path); + if ($res === TRUE) + { $zip->extractTo(dirname($path)); $zip->close(); - break; - - case 'tar': - $phar = new PharData($path); - $phar->extractTo(dirname($path)); - break; - - case 'gz': - $phar = new PharData($path); - $phar->decompress(); - break; - - default: - throw new Exception('Unsupported archive type'); + return dirname($path); + } + } + if ($mimeType == 'application/x-tar' || $mimeType == 'application/tar') + { + $phar = new PharData($path); + $phar->extractTo(dirname($path), null, true); + return dirname($path); + } + elseif ($mimeType == 'application/x-gzip' || $mimeType == 'application/gzip') + { + $phar = new PharData($path); + $phar->decompress(); + return dirname($path); } - return dirname($path); + return null; } + /** + * Scans the given directory for files and returns the found file + * + * @param string $path + * @param array $files + * @return string|null + */ + public static function searchDirectory(string $path, array $files): ?string + { + if (!is_dir($path)) + return null; + + // Search files in the given directory recursively + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); + foreach ($iterator as $file) + { + if (in_array($file->getFilename(), $files)) + return $file->getPathname(); + } + + return null; + } + + /** + * Attempts to convert a weird version number to a standard version number + * + * @param $version + * @return string + */ + public static function convertToSemVer($version) + { + $parts = explode('.', $version); + $major = $parts[0]; + $minor = $parts[1]; + $patch = $parts[2]; + $buildmetadata = $parts[3]; + + // Assemble the SemVer compatible string + $semver = "$major.$minor.$patch+$buildmetadata"; + + return $semver; + } + + + } \ No newline at end of file diff --git a/src/ncc/Utilities/Resolver.php b/src/ncc/Utilities/Resolver.php index bd14ef2..a9905e9 100644 --- a/src/ncc/Utilities/Resolver.php +++ b/src/ncc/Utilities/Resolver.php @@ -1,18 +1,16 @@ Type; + return RemoteSourceType::Defined; } /** @@ -277,38 +275,36 @@ * @param array $exlucde * @return ProjectDetectionResults */ - public static function detectProjectType(string $path, array $exlucde=[]): ProjectDetectionResults + public static function detectProjectType(string $path): ProjectDetectionResults { - $Scanner = new DirectoryScanner(); - $Scanner->setExcludes($exlucde); $project_files = [ - 'composer.json', - 'package.json', + 'project.json', + 'composer.json' ]; + $project_file = Functions::searchDirectory($path, $project_files); + $project_detection_results = new ProjectDetectionResults(); $project_detection_results->ProjectType = ProjectType::Unknown; - /** @var \SplFileInfo $item */ - foreach($Scanner($path, true) as $item) + if($project_file == null) { - if(in_array($item->getFilename(), $project_files)) - { - switch($item->getFilename()) - { - case 'composer.json': - $project_detection_results->ProjectType = ProjectType::Composer; - $project_detection_results->ProjectPath = dirname($item->getPathname()); - break; - - case 'project.json': - $project_detection_results->ProjectType = ProjectType::Ncc; - $project_detection_results->ProjectPath = dirname($item->getPathname()); - break; - } - } + return $project_detection_results; } + // Get filename of the project file + switch(basename($project_file)) + { + case 'project.json': + $project_detection_results->ProjectType = ProjectType::Ncc; + break; + + case 'composer.json': + $project_detection_results->ProjectType = ProjectType::Composer; + break; + } + + $project_detection_results->ProjectPath = dirname($project_file); return $project_detection_results; } } \ No newline at end of file -- 2.45.3 From 722c99879e2d01f4870b243b1ef481388a529363 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 00:57:07 -0500 Subject: [PATCH 105/212] Bug Fixes Part 2 --- .../ComposerSourceBuiltin.php | 93 ++++++++++++------- src/ncc/Classes/PhpExtension/PhpInstaller.php | 20 +--- .../Objects/ProjectConfiguration/Build.php | 38 ++++++++ 3 files changed, 100 insertions(+), 51 deletions(-) diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index e97d4b4..eee3abe 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -35,7 +35,6 @@ use ncc\ncc; use ncc\Objects\ComposerJson; use ncc\Objects\ComposerLock; - use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; use ncc\Objects\RemotePackageInput; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; @@ -151,8 +150,11 @@ // Compile dependencies self::compilePackages($path . DIRECTORY_SEPARATOR . 'composer.lock'); + $composer_lock = Functions::loadJson(IO::fread($path . DIRECTORY_SEPARATOR . 'composer.lock'), Functions::FORCE_ARRAY); + $version_map = self::getVersionMap(ComposerLock::fromArray($composer_lock)); + // Finally convert the main package's composer.json to package.json and compile it - ComposerSourceBuiltin::convertProject($path); + ComposerSourceBuiltin::convertProject($path, $version_map); $project_manager = new ProjectManager($path); $project_manager->load(); $built_package = $project_manager->build(); @@ -195,6 +197,7 @@ } $filesystem->mkdir($base_dir . DIRECTORY_SEPARATOR . 'build'); + $version_map = self::getVersionMap($composer_lock); foreach ($composer_lock->Packages as $package) { @@ -206,7 +209,7 @@ throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package->Name)); // Convert it to a NCC project configuration - $project_configuration = self::convertProject($package_path, $composer_package); + $project_configuration = self::convertProject($package_path, $version_map, $composer_package); // Load the project $project_manager = new ProjectManager($package_path); @@ -223,6 +226,22 @@ return $built_packages; } + /** + * Returns array of versions from the ComposerLock file + * + * @param ComposerLock $composerLock + * @return array + */ + private static function getVersionMap(ComposerLock $composerLock): array + { + $version_map = []; + foreach($composerLock->Packages as $package) + { + $version_map[$package->Name] = $package->Version; + } + return $version_map; + } + /** * Converts a composer package name to a valid package name * @@ -247,15 +266,40 @@ return null; } + /** + * Returns a valid version from a version map + * + * @param string $package_name + * @param array $version_map + * @return string + */ + private static function versionMap(string $package_name, array $version_map): string + { + if (array_key_exists($package_name, $version_map)) + { + $version = $version_map[$package_name]; + if(stripos($version, 'v') === 0) + $version = substr($version, 1); + if(!Validate::version($version)) + $version = Functions::convertToSemVer($version); + if(!Validate::version($version)) + return '1.0.0'; + + return $version; + } + + return '1.0.0'; + } + /** * Generates a project configuration from a package selection * from the composer.lock file * * @param ComposerJson $composer_package + * @param array $version_map * @return ProjectConfiguration - * @throws Exception */ - private static function generateProjectConfiguration(ComposerJson $composer_package): ProjectConfiguration + private static function generateProjectConfiguration(ComposerJson $composer_package, array $version_map): ProjectConfiguration { // Generate a new project configuration object $project_configuration = new ProjectConfiguration(); @@ -264,23 +308,12 @@ $project_configuration->Assembly->Name = $composer_package->Name; if (isset($composer_package->Description)) $project_configuration->Assembly->Description = $composer_package->Description; - if (isset($composer_package->Version)) - $project_configuration->Assembly->Version = Functions::parseVersion($composer_package->Version); + if(isset($version_map[$composer_package->Name])) + $project_configuration->Assembly->Version = self::versionMap($composer_package->Name, $version_map); if($project_configuration->Assembly->Version == null || $project_configuration->Assembly->Version == '') $project_configuration->Assembly->Version = '1.0.0'; - if(!Validate::version($project_configuration->Assembly->Version)) - $project_configuration->Assembly->Version = Functions::convertToSemVer($project_configuration->Assembly->Version); - - if(!Validate::version($project_configuration->Assembly->Version)) - { - Console::outWarning(sprintf('Invalid version "%s" for package "%s", using "1.0.0" instead', $project_configuration->Assembly->Version, $project_configuration->Assembly->Name)); - $project_configuration->Assembly->Version = '1.0.0'; - } - - RuntimeCache::set(sprintf('composer_version_%s', $project_configuration->Assembly->Package), $project_configuration->Assembly->Version); - $project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122(); $project_configuration->Assembly->Package = self::toPackageName($composer_package->Name); @@ -295,24 +328,16 @@ { foreach ($composer_package->Require as $item) { + // Check if the dependency is already in the project configuration $package_name = self::toPackageName($item->PackageName); - $package_version = $composer_package->Version; - if ($package_version == null) - { - $package_version = '1.0.0'; - } - else - { - $package_version = Functions::parseVersion($package_version); - } if ($package_name == null) continue; $dependency = new ProjectConfiguration\Dependency(); $dependency->Name = $package_name; $dependency->SourceType = DependencySourceType::Local; - $dependency->Version = $package_version; + $dependency->Version = self::versionMap($item->PackageName, $version_map);; $dependency->Source = $package_name . '.ncc'; - $project_configuration->Build->Dependencies[] = $dependency; + $project_configuration->Build->addDependency($dependency); } } @@ -448,6 +473,8 @@ if ($version == null) $version = '*'; + if($version == 'latest') + $version = '*'; $tpl_file = __DIR__ . DIRECTORY_SEPARATOR . 'composer.jtpl'; if (!file_exists($tpl_file)) @@ -566,22 +593,22 @@ /** * Converts a composer project to a NCC project * - * @param mixed $composer_package * @param string $package_path + * @param array $version_map + * @param mixed $composer_package * @return ProjectConfiguration * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException * @throws MalformedJsonException * @throws PackagePreparationFailedException - * @throws Exception */ - private static function convertProject(string $package_path, ?ComposerJson $composer_package=null): ProjectConfiguration + private static function convertProject(string $package_path, array $version_map, ?ComposerJson $composer_package=null): ProjectConfiguration { if($composer_package == null) $composer_package = ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json', Functions::FORCE_ARRAY)); - $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package); + $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package, $version_map); $filesystem = new Filesystem(); // Process the source files diff --git a/src/ncc/Classes/PhpExtension/PhpInstaller.php b/src/ncc/Classes/PhpExtension/PhpInstaller.php index 611f21e..490d739 100644 --- a/src/ncc/Classes/PhpExtension/PhpInstaller.php +++ b/src/ncc/Classes/PhpExtension/PhpInstaller.php @@ -115,24 +115,8 @@ */ public function postInstall(InstallationPaths $installationPaths): void { - $static_files_exists = false; - if($this->package->Header->Options !== null && isset($this->package->Header->Options['static_files'])) - { - $static_files = $this->package->Header->Options['static_files']; - $static_files_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin'; - - foreach($static_files as $file) - { - if(!file_exists($file)) - throw new InstallationException(sprintf('Static file %s does not exist', $file)); - } - - $static_files_exists = true; - IO::fwrite($static_files_path, ZiProto::encode($static_files)); - } - $autoload_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php'; - $autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path, $static_files_exists); + $autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path); IO::fwrite($autoload_path, $autoload_src); } @@ -294,7 +278,7 @@ * @throws IOException * @throws NoUnitsFoundException */ - private function generateAutoload(string $src, string $output, bool $ignore_units=false): string + private function generateAutoload(string $src, string $output, bool $ignore_units=true): string { // Construct configuration $configuration = new Config([$src]); diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index 938288e..75cb315 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -106,6 +106,44 @@ $this->Configurations = []; } + /** + * Adds a new dependency to the build, if it doesn't already exist + * + * @param Dependency $dependency + * @return void + */ + public function addDependency(Dependency $dependency) + { + foreach($this->Dependencies as $dep) + { + if($dep->Name == $dependency->Name) + { + $this->removeDependency($dep); + break; + } + } + + $this->Dependencies[] = $dependency; + } + + /** + * Removes a dependency from the build + * + * @param string $name + * @return void + */ + private function removeDependency(string $name) + { + foreach($this->Dependencies as $key => $dep) + { + if($dep->Name == $name) + { + unset($this->Dependencies[$key]); + return; + } + } + } + /** * Validates the build configuration object * -- 2.45.3 From 61146d1b1d2e23a4e6a2eb020dbcd32d23cb360d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 06:58:35 -0500 Subject: [PATCH 106/212] Bug Fixes Part 3 Also included refactoring of the current Remote repository system to make the codebase easier to maintain --- src/ncc/Abstracts/ExceptionCodes.php | 20 +- .../ComposerSourceBuiltin.php | 29 +- .../Classes/GithubExtension/GithubService.php | 337 +++++++----------- .../Classes/GitlabExtension/GitlabService.php | 168 ++++----- .../Classes/NccExtension/PackageCompiler.php | 18 +- src/ncc/Exceptions/ArchiveException.php | 15 + src/ncc/Exceptions/PackageFetchException.php | 14 + .../UnsupportedArchiveException.php | 20 ++ .../Interfaces/RepositorySourceInterface.php | 13 +- src/ncc/Managers/PackageManager.php | 120 +++++-- src/ncc/Objects/RepositoryQueryResults.php | 46 +++ .../Objects/RepositoryQueryResults/Files.php | 50 +++ src/ncc/Utilities/Functions.php | 317 ++++++++++++++-- 13 files changed, 752 insertions(+), 415 deletions(-) create mode 100644 src/ncc/Exceptions/ArchiveException.php create mode 100644 src/ncc/Exceptions/PackageFetchException.php create mode 100644 src/ncc/Exceptions/UnsupportedArchiveException.php create mode 100644 src/ncc/Objects/RepositoryQueryResults.php create mode 100644 src/ncc/Objects/RepositoryQueryResults/Files.php diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 60d7412..38b32da 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -323,6 +323,21 @@ */ const UnsupportedProjectTypeException = -1762; + /** + * @see UnsupportedArchiveException + */ + const UnsupportedArchiveException = -1763; + + /** + * @see ArchiveException + */ + const ArchiveException = -1764; + + /** + * @see PackageFetchException + */ + const PackageFetchException = -1765; + /** * All the exception codes from NCC */ @@ -386,6 +401,9 @@ self::GitTagsException, self::AuthenticationException, self::NotSupportedException, - self::UnsupportedProjectTypeException + self::UnsupportedProjectTypeException, + self::UnsupportedArchiveException, + self::ArchiveException, + self::PackageFetchException ]; } \ No newline at end of file diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index eee3abe..a210837 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -47,7 +47,6 @@ use ncc\Utilities\PathFinder; use ncc\Utilities\Resolver; use ncc\Utilities\RuntimeCache; - use ncc\Utilities\Validate; use SplFileInfo; class ComposerSourceBuiltin implements ServiceSourceInterface @@ -277,15 +276,7 @@ { if (array_key_exists($package_name, $version_map)) { - $version = $version_map[$package_name]; - if(stripos($version, 'v') === 0) - $version = substr($version, 1); - if(!Validate::version($version)) - $version = Functions::convertToSemVer($version); - if(!Validate::version($version)) - return '1.0.0'; - - return $version; + return Functions::convertToSemVer($version_map[$package_name]); } return '1.0.0'; @@ -335,7 +326,7 @@ $dependency = new ProjectConfiguration\Dependency(); $dependency->Name = $package_name; $dependency->SourceType = DependencySourceType::Local; - $dependency->Version = self::versionMap($item->PackageName, $version_map);; + $dependency->Version = self::versionMap($item->PackageName, $version_map); $dependency->Source = $package_name . '.ncc'; $project_configuration->Build->addDependency($dependency); } @@ -359,22 +350,6 @@ return $project_configuration; } - /** - * Extracts a version if available from the input - * - * @param string $input - * @return string|null - */ - private static function extractVersion(string $input): ?string - { - if (stripos($input, ':')) - { - return explode(':', $input)[1]; - } - - return null; - } - /** * Gets the applicable options configured for composer * diff --git a/src/ncc/Classes/GithubExtension/GithubService.php b/src/ncc/Classes/GithubExtension/GithubService.php index 745eed2..440f4c9 100644 --- a/src/ncc/Classes/GithubExtension/GithubService.php +++ b/src/ncc/Classes/GithubExtension/GithubService.php @@ -2,12 +2,9 @@ namespace ncc\Classes\GithubExtension; - use Exception; use ncc\Abstracts\HttpRequestType; use ncc\Abstracts\Versions; - use ncc\Classes\GitClient; use ncc\Classes\HttpClient; - use ncc\Classes\NccExtension\PackageCompiler; use ncc\Exceptions\AuthenticationException; use ncc\Exceptions\GithubServiceException; use ncc\Exceptions\GitlabServiceException; @@ -18,134 +15,28 @@ use ncc\Objects\DefinedRemoteSource; use ncc\Objects\HttpRequest; use ncc\Objects\RemotePackageInput; + use ncc\Objects\RepositoryQueryResults; use ncc\Objects\Vault\Entry; use ncc\ThirdParty\jelix\Version\VersionComparator; - use ncc\Utilities\Console; use ncc\Utilities\Functions; + use ncc\Utilities\Validate; class GithubService implements RepositorySourceInterface { - - /** - * Attempts to fetch the .ncc package from a remote source, optionally attempts to compile - * the package if it cannot find a pre-compiled version. - * - * Priority of fetching: - * - Pre-compiled version - * - Source code of specified release - * - Git repository (checkout specified release) - * - Git repository master branch (If version is not specified or set to latest) - * - * @param RemotePackageInput $packageInput - * @param DefinedRemoteSource $definedRemoteSource - * @param Entry|null $entry - * @return string - * @throws GithubServiceException - */ - public static function fetch(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): string - { - // Check if there is a pre-compiled version of the package available - try - { - Console::outVerbose(sprintf('Attempting to fetch pre-compiled package from %s', $definedRemoteSource->Host)); - $ncc_package = self::getNccPackage($packageInput, $definedRemoteSource, $entry); - } - catch(Exception $e) - { - $ncc_package = null; - unset($e); - } - - if($ncc_package !== null) - { - try - { - return Functions::downloadGitServiceFile($ncc_package, $entry); - } - catch(Exception $e) - { - throw new GithubServiceException(sprintf('Failed to download pre-compiled package from %s', $definedRemoteSource->Host), $e); - } - } - - // Check if the specified version is a release - try - { - Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host)); - $release_url = self::getRelease($packageInput, $definedRemoteSource, $entry); - } - catch(Exception $e) - { - $release_url = null; - unset($e); - } - - // If the specified version is a release, download the source code - if($release_url !== null) - { - try - { - $release_file = Functions::downloadGitServiceFile($release_url, $entry); - $project_path = Functions::extractArchive($release_file); - return PackageCompiler::tryCompile($project_path); - } - catch(Exception $e) - { - throw new GithubServiceException(sprintf('Failed to download release from %s', $definedRemoteSource->Host), $e); - } - } - - try - { - Console::outVerbose(sprintf('Attempting to fetch git repository from %s', $definedRemoteSource->Host)); - $git_url = self::fetchGitUri($packageInput, $definedRemoteSource, $entry); - } - catch(Exception $e) - { - $git_url = null; - unset($e); - } - - if($git_url !== null) - { - try - { - $project_path = GitClient::cloneRepository($git_url); - - foreach(GitClient::getTags($project_path) as $tag) - { - $tag = str_replace('v', '', $tag); - if(VersionComparator::compareVersion($tag, $packageInput->Version) === 0) - { - GitClient::checkout($project_path, $tag); - return PackageCompiler::tryCompile($project_path); - } - } - } - catch(Exception $e) - { - throw new GithubServiceException(sprintf('Failed to clone git repository from %s', $definedRemoteSource->Host), $e); - } - } - - throw new GithubServiceException('Unable to fetch package from remote source'); - } - - /** * Returns the git repository url of the repository, versions cannot be specified. * * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults + * @throws AuthenticationException * @throws GithubServiceException * @throws GitlabServiceException - * @throws AuthenticationException * @throws HttpException * @throws MalformedJsonException */ - public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults { $httpRequest = new HttpRequest(); $protocol = ($definedRemoteSource->SSL ? "https" : "http"); @@ -153,23 +44,17 @@ $owner_f = str_ireplace(".", "%2F", $owner_f); $repository = urlencode($packageInput->Package); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository"; - $httpRequest->Type = HttpRequestType::GET; - $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); - $httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28'; - $httpRequest->Headers[] = 'Accept: application/vnd.github+json'; + $response_decoded = self::getJsonResponse($httpRequest, $entry); - $response = HttpClient::request($httpRequest, true); + $query = new RepositoryQueryResults(); + $query->Files->GitSshUrl = ($response_decoded['ssh_url'] ?? null); + $query->Files->GitHttpUrl = ($response_decoded['clone_url'] ?? null); + $query->Version = Functions::convertToSemVer($response_decoded['default_branch'] ?? null); + $query->ReleaseDescription = ($response_decoded['description'] ?? null); + $query->ReleaseName = ($response_decoded['name'] ?? null); - if($response->StatusCode != 200) - throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); - $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); - - return - $response_decoded['git_url'] ?? - $response_decoded['clone_url'] ?? - $response_decoded['ssh_url'] ?? - throw new GithubServiceException('Failed to fetch the repository URL.'); + return $query; } /** @@ -178,7 +63,7 @@ * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults * @throws AuthenticationException * @throws GithubServiceException * @throws GitlabServiceException @@ -186,42 +71,16 @@ * @throws MalformedJsonException * @throws VersionNotFoundException */ - public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults { - $releases = self::getReleases($packageInput, $definedRemoteSource, $entry); - - if(count($releases) === 0) - throw new VersionNotFoundException('No releases found for the given repository.'); - - if($packageInput->Version == Versions::Latest) - { - $latest_version = null; - foreach($releases as $version => $url) - { - if($latest_version == null) - { - $latest_version = $version; - continue; - } - - if(VersionComparator::compareVersion($version, $latest_version) == 1) - $latest_version = $version; - } - - return $releases[$latest_version]['url']; - } - - if(!isset($releases[$packageInput->Version])) - throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); - - return $releases[$packageInput->Version]['url']; + return self::processReleases($packageInput, $definedRemoteSource, $entry); } /** * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults * @throws AuthenticationException * @throws GithubServiceException * @throws GitlabServiceException @@ -229,43 +88,9 @@ * @throws MalformedJsonException * @throws VersionNotFoundException */ - public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults { - $releases = self::getReleases($packageInput, $definedRemoteSource, $entry); - - if(count($releases) === 0) - throw new VersionNotFoundException('No releases found for the given repository.'); - - if($packageInput->Version == Versions::Latest) - { - $latest_version = null; - foreach($releases as $version => $url) - { - if($latest_version == null) - { - $latest_version = $version; - continue; - } - - if(VersionComparator::compareVersion($version, $latest_version) == 1) - $latest_version = $version; - } - - $return = $releases[$latest_version]['package'] ?? null; - if($return === null) - throw new VersionNotFoundException('No releases found for the given repository.'); - - return $return; - } - - if(!isset($releases[$packageInput->Version])) - throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); - - $return = $releases[$packageInput->Version]['package'] ?? null; - if($return === null) - throw new VersionNotFoundException('No releases found for the given repository.'); - - return $return; + return self::processReleases($packageInput, $definedRemoteSource, $entry); } /** @@ -289,17 +114,7 @@ $owner_f = str_ireplace(".", "%2F", $owner_f); $repository = urlencode($packageInput->Package); $httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases"; - $httpRequest->Type = HttpRequestType::GET; - $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); - $httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28'; - $httpRequest->Headers[] = 'Accept: application/vnd.github+json'; - - $response = HttpClient::request($httpRequest, true); - - if($response->StatusCode != 200) - throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); - - $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); + $response_decoded = self::getJsonResponse($httpRequest, $entry); if(count($response_decoded) == 0) return []; @@ -307,20 +122,24 @@ $return = []; foreach($response_decoded as $release) { - // Make the tag_name version friendly - $release_version = str_replace('v', '', $release['tag_name']); - $return[$release_version] = [ - 'url' => ($release['zipball_url'] ?? $release['tarball_url'] ?? null) - ]; + $query_results = new RepositoryQueryResults(); + $query_results->Version = Functions::convertToSemVer($release['tag_name']); + $query_results->ReleaseName = $release['name']; + $query_results->ReleaseDescription = $release['body']; + $query_results->Files->ZipballUrl = ($release['zipball_url'] ?? null); + $query_results->Files->TarballUrl = ($release['tarball_url'] ?? null); if(isset($release['assets'])) { foreach($release['assets'] as $asset) { - if(self::parseAsset($asset) !== null) - $return[$release_version]['package'] = $asset['browser_download_url']; + $parsed_asset = self::parseAsset($asset); + if($parsed_asset !== null) + $query_results->Files->PackageUrl = $parsed_asset; } } + + $return[$query_results->Version] = $query_results; } return $return; @@ -343,4 +162,98 @@ return null; } + + /** + * @param HttpRequest $httpRequest + * @param Entry|null $entry + * @return array + * @throws AuthenticationException + * @throws GithubServiceException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + */ + private static function getJsonResponse(HttpRequest $httpRequest, ?Entry $entry): array + { + $httpRequest->Type = HttpRequestType::GET; + $httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false); + $httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28'; + $httpRequest->Headers[] = 'Accept: application/vnd.github+json'; + + $response = HttpClient::request($httpRequest, true); + + if ($response->StatusCode != 200) + throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); + + $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); + return $response_decoded; + } + + /** + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return mixed + * @throws AuthenticationException + * @throws GithubServiceException + * @throws GitlabServiceException + * @throws HttpException + * @throws MalformedJsonException + * @throws VersionNotFoundException + */ + private static function processReleases(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): mixed + { + $releases = self::getReleases($packageInput, $definedRemoteSource, $entry); + + if (count($releases) === 0) + throw new VersionNotFoundException('No releases found for the given repository.'); + + if ($packageInput->Version == Versions::Latest) + { + $latest_version = null; + foreach ($releases as $release) + { + if ($latest_version == null) + { + $latest_version = $release->Version; + continue; + } + + if (VersionComparator::compareVersion($release->Version, $latest_version) == 1) + $latest_version = $release->Version; + } + + return $releases[$latest_version]; + } + + // Query a specific version + if (!isset($releases[$packageInput->Version])) + { + // Find the closest thing to the requested version + $selected_version = null; + foreach ($releases as $version => $url) + { + if ($selected_version == null) + { + $selected_version = $version; + continue; + } + + if (VersionComparator::compareVersion($version, $packageInput->Version) == 1) + $selected_version = $version; + } + + if ($selected_version == null) + throw new VersionNotFoundException('No releases found for the given repository.'); + } + else + { + $selected_version = $packageInput->Version; + } + + if (!isset($releases[$selected_version])) + throw new VersionNotFoundException(sprintf('No releases found for the given repository. (Selected version: %s)', $selected_version)); + + return $releases[$selected_version]; + } } \ No newline at end of file diff --git a/src/ncc/Classes/GitlabExtension/GitlabService.php b/src/ncc/Classes/GitlabExtension/GitlabService.php index b398d5d..feda673 100644 --- a/src/ncc/Classes/GitlabExtension/GitlabService.php +++ b/src/ncc/Classes/GitlabExtension/GitlabService.php @@ -2,11 +2,8 @@ namespace ncc\Classes\GitlabExtension; - use Exception; use ncc\Abstracts\Versions; - use ncc\Classes\GitClient; use ncc\Classes\HttpClient; - use ncc\Classes\NccExtension\PackageCompiler; use ncc\Exceptions\AuthenticationException; use ncc\Exceptions\GitlabServiceException; use ncc\Exceptions\HttpException; @@ -17,88 +14,13 @@ use ncc\Objects\DefinedRemoteSource; use ncc\Objects\HttpRequest; use ncc\Objects\RemotePackageInput; + use ncc\Objects\RepositoryQueryResults; use ncc\Objects\Vault\Entry; use ncc\ThirdParty\jelix\Version\VersionComparator; - use ncc\Utilities\Console; use ncc\Utilities\Functions; class GitlabService implements RepositorySourceInterface { - - /** - * Attempts to fetch the requested package from the Gitlab repository, and returns the pre-compiled package - * - * @param RemotePackageInput $packageInput - * @param DefinedRemoteSource $definedRemoteSource - * @param Entry|null $entry - * @return string - * @throws GitlabServiceException - */ - public static function fetch(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): string - { - // Check if the specified version is a release - try - { - Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host)); - $release_url = self::getRelease($packageInput, $definedRemoteSource, $entry); - } - catch(Exception $e) - { - $release_url = null; - unset($e); - } - - // If the specified version is a release, download the source code - if($release_url !== null) - { - try - { - $release_file = Functions::downloadGitServiceFile($release_url, $entry); - $project_path = Functions::extractArchive($release_file); - return PackageCompiler::tryCompile($project_path); - } - catch(Exception $e) - { - throw new GitlabServiceException(sprintf('Failed to download release from %s', $definedRemoteSource->Host), $e); - } - } - - try - { - Console::outVerbose(sprintf('Attempting to fetch git repository from %s', $definedRemoteSource->Host)); - $git_url = self::fetchGitUri($packageInput, $definedRemoteSource, $entry); - } - catch(Exception $e) - { - $git_url = null; - unset($e); - } - - if($git_url !== null) - { - try - { - $project_path = GitClient::cloneRepository($git_url); - - foreach(GitClient::getTags($project_path) as $tag) - { - $tag = str_replace('v', '', $tag); - if(VersionComparator::compareVersion($tag, $packageInput->Version) === 0) - { - GitClient::checkout($project_path, $tag); - return PackageCompiler::tryCompile($project_path); - } - } - } - catch(Exception $e) - { - throw new GitlabServiceException(sprintf('Failed to clone git repository from %s', $definedRemoteSource->Host), $e); - } - } - - throw new GitlabServiceException('Unable to fetch package from remote source'); - } - /** * Attempts to return the gitRepositoryUrl of a release, cannot specify a version. * This needs to be done using git @@ -106,13 +28,13 @@ * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults + * @throws AuthenticationException * @throws GitlabServiceException * @throws HttpException * @throws MalformedJsonException - * @throws AuthenticationException */ - public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): string + public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): RepositoryQueryResults { $httpRequest = new HttpRequest(); $protocol = ($definedRemoteSource->SSL ? "https" : "http"); @@ -130,10 +52,14 @@ $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); - return - $response_decoded['http_url_to_repo'] ?? - $response_decoded['ssh_url_to_repo'] ?? - throw new GitlabServiceException('Failed to fetch the repository URL.'); + $query = new RepositoryQueryResults(); + $query->Files->GitSshUrl = ($response_decoded['ssh_url_to_repo'] ?? null); + $query->Files->GitHttpUrl = ($response_decoded['http_url_to_repo'] ?? null); + $query->Version = Functions::convertToSemVer($response_decoded['default_branch']) ?? null; + $query->ReleaseDescription = ($response_decoded['description'] ?? null); + $query->ReleaseName = ($response_decoded['name'] ?? null); + + return $query; } /** @@ -142,52 +68,78 @@ * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults * @throws AuthenticationException * @throws GitlabServiceException * @throws HttpException * @throws MalformedJsonException * @throws VersionNotFoundException */ - public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults { $releases = self::getReleases($packageInput->Vendor, $packageInput->Package, $definedRemoteSource, $entry); if(count($releases) === 0) throw new VersionNotFoundException('No releases found for the given repository.'); + // Query the latest package only if($packageInput->Version == Versions::Latest) { $latest_version = null; - foreach($releases as $version => $url) + foreach($releases as $release) { if($latest_version == null) { - $latest_version = $version; + $latest_version = $release->Version; continue; } - if(VersionComparator::compareVersion($version, $latest_version) == 1) - $latest_version = $version; + if(VersionComparator::compareVersion($release->Version, $latest_version) == 1) + $latest_version = $release->Version; } return $releases[$latest_version]; } + // Query a specific version if(!isset($releases[$packageInput->Version])) - throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version)); + { + // Find the closest thing to the requested version + $selected_version = null; + foreach($releases as $version => $url) + { + if($selected_version == null) + { + $selected_version = $version; + continue; + } - return $releases[$packageInput->Version]; + if(VersionComparator::compareVersion($version, $packageInput->Version) == 1) + $selected_version = $version; + } + + if($selected_version == null) + throw new VersionNotFoundException('No releases found for the given repository.'); + } + else + { + $selected_version = $packageInput->Version; + } + + if(!isset($releases[$selected_version])) + throw new VersionNotFoundException(sprintf('No releases found for the given repository. (Selected version: %s)', $selected_version)); + + return $releases[$selected_version]; } /** * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults * @throws NotSupportedException */ - public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string + public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults { throw new NotSupportedException(sprintf('The given repository source "%s" does not support ncc packages.', $definedRemoteSource->Host)); } @@ -230,25 +182,39 @@ $return = []; foreach($response_decoded as $release) { - // Make the tag_name version friendly - $release_version = str_replace('v', '', $release['tag_name']); + $query_results = new RepositoryQueryResults(); + $query_results->ReleaseName = ($release['name'] ?? null); + $query_results->ReleaseDescription = ($release['description'] ?? null); + $query_results->Version = Functions::convertToSemVer($release['tag_name']); if(isset($release['assets']) && isset($release['assets']['sources'])) { if(count($release['assets']['sources']) > 0) { - // Use the first source as the download url, if a tar.gz file is available, use that instead. - $return[$release_version] = $release['assets']['sources'][0]['url']; foreach($release['assets']['sources'] as $source) { if($source['format'] == 'zip') { - $return[$release_version] = $source['url']; + $query_results->Files->ZipballUrl = $source['url']; + break; + } + + if($source['format'] == 'tar.gz') + { + $query_results->Files->ZipballUrl = $source['url']; + break; + } + + if($source['format'] == 'ncc') + { + $query_results->Files->PackageUrl = $source['url']; break; } } } } + + $return[$query_results->Version] = $query_results; } return $return; diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index 08c96bb..5e643bb 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -5,10 +5,14 @@ use Exception; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\ConstantReferences; + use ncc\Abstracts\DefinedRemoteSourceType; use ncc\Abstracts\LogLevel; use ncc\Abstracts\Options\BuildConfigurationValues; use ncc\Abstracts\ProjectType; use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; + use ncc\Classes\GitClient; + use ncc\Classes\GithubExtension\GithubService; + use ncc\Classes\GitlabExtension\GitlabService; use ncc\Classes\PhpExtension\PhpCompiler; use ncc\CLI\Main; use ncc\Exceptions\AccessDeniedException; @@ -17,17 +21,24 @@ use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; use ncc\Exceptions\MalformedJsonException; + use ncc\Exceptions\PackageFetchException; use ncc\Exceptions\PackagePreparationFailedException; use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedProjectTypeException; + use ncc\Exceptions\UnsupportedRemoteSourceTypeException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Interfaces\CompilerInterface; + use ncc\Interfaces\RepositorySourceInterface; use ncc\Managers\ProjectManager; use ncc\ncc; + use ncc\Objects\DefinedRemoteSource; use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; use ncc\Objects\ProjectConfiguration\Assembly; + use ncc\Objects\RemotePackageInput; + use ncc\Objects\Vault\Entry; + use ncc\ThirdParty\jelix\Version\VersionComparator; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\Utilities\Console; use ncc\Utilities\Functions; @@ -96,10 +107,13 @@ * @throws BuildException * @throws UnsupportedProjectTypeException */ - public static function tryCompile(string $path): string + public static function tryCompile(string $path, ?string $version=null): string { $project_type = Resolver::detectProjectType($path); + if($version !== null) + $version = Functions::convertToSemVer($version); + try { if($project_type->ProjectType == ProjectType::Composer) @@ -108,6 +122,7 @@ if($project_type->ProjectType == ProjectType::Ncc) { $project_manager = new ProjectManager($project_type->ProjectPath); + $project_manager->getProjectConfiguration()->Assembly->Version = $version; return $project_manager->build(); } } @@ -119,6 +134,7 @@ throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported'); } + /** * Compiles the execution policies of the package * diff --git a/src/ncc/Exceptions/ArchiveException.php b/src/ncc/Exceptions/ArchiveException.php new file mode 100644 index 0000000..a7e7a22 --- /dev/null +++ b/src/ncc/Exceptions/ArchiveException.php @@ -0,0 +1,15 @@ +message = $message; + } + } \ No newline at end of file diff --git a/src/ncc/Interfaces/RepositorySourceInterface.php b/src/ncc/Interfaces/RepositorySourceInterface.php index 25d7ee4..09cc39c 100644 --- a/src/ncc/Interfaces/RepositorySourceInterface.php +++ b/src/ncc/Interfaces/RepositorySourceInterface.php @@ -4,6 +4,7 @@ use ncc\Objects\DefinedRemoteSource; use ncc\Objects\RemotePackageInput; + use ncc\Objects\RepositoryQueryResults; use ncc\Objects\Vault\Entry; interface RepositorySourceInterface @@ -14,9 +15,9 @@ * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults */ - public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): string; + public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): RepositoryQueryResults; /** * Returns the release url of the repository, versions can be specified. @@ -24,9 +25,9 @@ * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults */ - public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string; + public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults; /** * Returns the download URL of the pre-compiled .ncc package if available @@ -34,7 +35,7 @@ * @param RemotePackageInput $packageInput * @param DefinedRemoteSource $definedRemoteSource * @param Entry|null $entry - * @return string + * @return RepositoryQueryResults */ - public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string; + public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults; } \ No newline at end of file diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index a62d311..b2a5e71 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -8,15 +8,13 @@ use ncc\Abstracts\BuiltinRemoteSourceType; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\ConstantReferences; - use ncc\Abstracts\DefinedRemoteSourceType; use ncc\Abstracts\DependencySourceType; use ncc\Abstracts\LogLevel; use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; use ncc\Abstracts\Versions; use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; - use ncc\Classes\GithubExtension\GithubService; - use ncc\Classes\GitlabExtension\GitlabService; + use ncc\Classes\GitClient; use ncc\Classes\NccExtension\PackageCompiler; use ncc\Classes\PhpExtension\PhpInstaller; use ncc\CLI\Main; @@ -28,13 +26,14 @@ use ncc\Exceptions\MissingDependencyException; use ncc\Exceptions\NotImplementedException; use ncc\Exceptions\PackageAlreadyInstalledException; + use ncc\Exceptions\PackageFetchException; use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\PackageParsingException; use ncc\Exceptions\UnsupportedCompilerExtensionException; + use ncc\Exceptions\UnsupportedRemoteSourceTypeException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Exceptions\VersionNotFoundException; - use ncc\Interfaces\RepositorySourceInterface; use ncc\Objects\DefinedRemoteSource; use ncc\Objects\InstallationPaths; use ncc\Objects\Package; @@ -43,9 +42,11 @@ use ncc\Objects\ProjectConfiguration\Dependency; use ncc\Objects\RemotePackageInput; use ncc\Objects\Vault\Entry; + use ncc\ThirdParty\jelix\Version\VersionComparator; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner; use ncc\Utilities\Console; + use ncc\Utilities\Functions; use ncc\Utilities\IO; use ncc\Utilities\PathFinder; use ncc\Utilities\Resolver; @@ -80,6 +81,7 @@ * Installs a local package onto the system * * @param string $package_path + * @param Entry|null $entry * @return string * @throws AccessDeniedException * @throws FileNotFoundException @@ -340,75 +342,122 @@ /** * @param string $source - * @param Entry|null $auth_entry + * @param Entry|null $entry * @return string * @throws InstallationException + * @throws NotImplementedException + * @throws PackageFetchException */ - public function fetchFromSource(string $source, ?Entry $auth_entry=null): string + public function fetchFromSource(string $source, ?Entry $entry=null): string { - $parsed_source = new RemotePackageInput($source); + $input = new RemotePackageInput($source); - if($parsed_source->Source == null) - throw new InstallationException('No source specified'); - - if($parsed_source->Package == null) - throw new InstallationException('No package specified'); - - if($parsed_source->Version == null) - $parsed_source->Version = Versions::Latest; - - $remote_source_type = Resolver::detectRemoteSourceType($parsed_source->Source); + if($input->Source == null) + throw new PackageFetchException('No source specified'); + if($input->Package == null) + throw new PackageFetchException('No package specified'); + if($input->Version == null) + $input->Version = Versions::Latest; + $remote_source_type = Resolver::detectRemoteSourceType($input->Source); if($remote_source_type == RemoteSourceType::Builtin) { - switch($parsed_source->Source) + switch($input->Source) { case BuiltinRemoteSourceType::Composer: try { - return ComposerSourceBuiltin::fetch($parsed_source); + return ComposerSourceBuiltin::fetch($input); } catch(Exception $e) { - throw new InstallationException('Cannot fetch package from composer source, ' . $e->getMessage(), $e); + throw new PackageFetchException('Cannot fetch package from composer source, ' . $e->getMessage(), $e); } default: - throw new InstallationException('Builtin source type ' . $parsed_source->Source . ' is not implemented'); + throw new NotImplementedException('Builtin source type ' . $input->Source . ' is not implemented'); } } if($remote_source_type == RemoteSourceType::Defined) { $remote_source_manager = new RemoteSourcesManager(); - $remote_source = $remote_source_manager->getRemoteSource($parsed_source->Source); - if($remote_source == null) - throw new InstallationException('Remote source ' . $parsed_source->Source . ' is not defined'); + $source = $remote_source_manager->getRemoteSource($input->Source); + if($source == null) + throw new InstallationException('Remote source ' . $input->Source . ' is not defined'); - /** @var RepositorySourceInterface $remote_service_client */ - $remote_service_client = match ($remote_source->Type) { - DefinedRemoteSourceType::Gitlab => GitlabService::class, - DefinedRemoteSourceType::Github => GithubService::class, - default => throw new InstallationException('Remote source type ' . $remote_source->Type . ' is not implemented'), - }; + $repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry); - try + if($repositoryQueryResults->Files->ZipballUrl !== null) { - return $remote_service_client::fetch($parsed_source, $remote_source, $auth_entry); + try + { + $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->ZipballUrl, $entry); + return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); + } + catch(Exception $e) + { + unset($e); + } } - catch(Exception $e) + + if($repositoryQueryResults->Files->TarballUrl !== null) { - throw new InstallationException('Cannot fetch package from remote source, ' . $e->getMessage(), $e); + try + { + $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->TarballUrl, $entry); + return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); + } + catch(Exception $e) + { + unset($e); + } } + + if($repositoryQueryResults->Files->PackageUrl !== null) + { + try + { + return Functions::downloadGitServiceFile($repositoryQueryResults->Files->PackageUrl, $entry); + } + catch(Exception $e) + { + unset($e); + } + } + + if($repositoryQueryResults->Files->GitHttpUrl !== null || $repositoryQueryResults->Files->GitSshUrl !== null) + { + try + { + $git_repository = GitClient::cloneRepository($repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl); + + foreach(GitClient::getTags($git_repository) as $tag) + { + if(VersionComparator::compareVersion($tag, $repositoryQueryResults->Version) === 0) + { + GitClient::checkout($git_repository, $tag); + return PackageCompiler::tryCompile($git_repository, $repositoryQueryResults->Version); + } + } + } + catch(Exception $e) + { + unset($e); + } + } + + throw new PackageFetchException(sprintf('Failed to fetch package \'%s\'', $input->Package)); } - throw new InstallationException(sprintf('Unknown remote source type %s', $remote_source_type)); + throw new PackageFetchException(sprintf('Unknown remote source type %s', $remote_source_type)); } /** * Installs a package from a source syntax (vendor/package=version@source) * * @param string $source + * @param Entry|null $entry * @return string * @throws InstallationException */ @@ -429,6 +478,7 @@ * @param Dependency $dependency * @param Package $package * @param string $package_path + * @param Entry|null $entry * @return void * @throws AccessDeniedException * @throws FileNotFoundException diff --git a/src/ncc/Objects/RepositoryQueryResults.php b/src/ncc/Objects/RepositoryQueryResults.php new file mode 100644 index 0000000..a55ab9b --- /dev/null +++ b/src/ncc/Objects/RepositoryQueryResults.php @@ -0,0 +1,46 @@ +Files = new Files(); + } + } \ No newline at end of file diff --git a/src/ncc/Objects/RepositoryQueryResults/Files.php b/src/ncc/Objects/RepositoryQueryResults/Files.php new file mode 100644 index 0000000..2cda2d2 --- /dev/null +++ b/src/ncc/Objects/RepositoryQueryResults/Files.php @@ -0,0 +1,50 @@ +find('unzip'); + $tar_executable = $executable_finder->find('tar'); + $out_path = dirname($path); + $filesystem = new Filesystem(); - if ($mimeType == 'application/zip') + if(!$filesystem->exists($out_path)) + $filesystem->mkdir($out_path); + + RuntimeCache::setFileAsTemporary($out_path); + + $mimeType = mime_content_type($path); + $supportedTypes = []; + + if($unzip_executable !== null) { - $zip = new ZipArchive; - $res = $zip->open($path); - if ($res === TRUE) + $supportedTypes = array_merge($supportedTypes, [ + 'application/zip', + 'application/x-zip', + 'application/x-zip-compressed', + 'application/octet-stream', + 'application/x-compress', + 'application/x-compressed', + 'multipart/x-zip' + ]); + } + else + { + if(RuntimeCache::get('warning_zip_shown') !== true) { - $zip->extractTo(dirname($path)); - $zip->close(); - return dirname($path); + Console::out('unzip executable not found. ZIP archives will not be supported.'); + RuntimeCache::set('warning_zip_shown', true); } } - if ($mimeType == 'application/x-tar' || $mimeType == 'application/tar') + + if($tar_executable !== null) { - $phar = new PharData($path); - $phar->extractTo(dirname($path), null, true); - return dirname($path); + $supportedTypes = array_merge($supportedTypes, [ + 'application/x-tar', + 'application/x-gzip', + 'application/x-bzip2', + 'application/x-xz' + ]); } - elseif ($mimeType == 'application/x-gzip' || $mimeType == 'application/gzip') + else { - $phar = new PharData($path); - $phar->decompress(); - return dirname($path); + if(RuntimeCache::get('warning_tar_shown') !== true) + { + Console::outWarning('tar executable not found. TAR archives will not be supported.'); + RuntimeCache::set('warning_tar_shown', true); + } } - return null; + if (!in_array($mimeType, $supportedTypes)) + throw new UnsupportedArchiveException("Unsupported archive type: $mimeType"); + + switch($mimeType) + { + case 'application/zip': + $command = [$unzip_executable, $path, '-d', $out_path]; + break; + case 'application/x-tar': + $command = [$tar_executable, '--verbose', '-xf', $path, '-C', $out_path]; + break; + case 'application/x-gzip': + $command = [$tar_executable, '--verbose', '-xzf', $path, '-C', $out_path]; + break; + case 'application/x-bzip2': + $command = [$tar_executable, '--verbose', '-xjf', $path, '-C', $out_path]; + break; + } + + Console::out("Extracting archive $path"); + $process = new Process($command); + + // display the output of the command + $process->run(function ($type, $buffer) { + Console::outVerbose($buffer); + }); + + if (!$process->isSuccessful()) + throw new ArchiveException($process->getErrorOutput()); + + return $out_path; } /** @@ -649,20 +715,207 @@ * @param $version * @return string */ - public static function convertToSemVer($version) + public static function convertToSemVer($version): string { - $parts = explode('.', $version); - $major = $parts[0]; - $minor = $parts[1]; - $patch = $parts[2]; - $buildmetadata = $parts[3]; + if(stripos($version, 'v') === 0) + $version = substr($version, 1); + if(!Validate::version($version)) + { + $parts = explode('.', $version); + $major = (string)null; + $minor = (string)null; + $patch = (string)null; - // Assemble the SemVer compatible string - $semver = "$major.$minor.$patch+$buildmetadata"; + $buildmetadata = (string)null; + if(count($parts) >= 1) + $major = $parts[0]; + if(count($parts) >= 2) + $minor = $parts[1]; + if(count($parts) >= 3) + $patch = $parts[2]; - return $semver; + // Assemble the SemVer compatible string + $version = "$major.$minor.$patch"; + } + if(!Validate::version($version)) + return '1.0.0'; + + return $version; } + /** + * Returns a complete RepositoryQueryResults object + * + * @param RemotePackageInput $packageInput + * @param DefinedRemoteSource $definedRemoteSource + * @param Entry|null $entry + * @return RepositoryQueryResults + */ + public static function getRepositoryQueryResults(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): RepositoryQueryResults + { + $results = new RepositoryQueryResults(); + switch($definedRemoteSource->Type) + { + case DefinedRemoteSourceType::Github: + $source = GithubService::class; + break; + case DefinedRemoteSourceType::Gitlab: + $source = GitlabService::class; + break; + + default: + return $results; + } + + // Check if the specified version is a release + try + { + Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host)); + $release_results = $source::getRelease($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $release_results = null; + unset($e); + } + + // If the specified version is a release, download the source code + if($release_results !== null) + { + $results->ReleaseName = ($release_results->ReleaseName ?? null); + $results->ReleaseDescription = ($release_results->ReleaseDescription ?? null); + $results->Files = self::mergeFilesResults($release_results->Files, ($results->Files ?? null)); + if($release_results->Version !== null) + $results->Version = $release_results->Version; + } + + try + { + $git_results = $source::getGitRepository($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + $git_results = null; + unset($e); + } + + if($git_results !== null) + { + if($results->ReleaseName == null) + { + $results->ReleaseName = ($git_results->ReleaseName ?? null); + } + elseif($git_results->ReleaseName !== null) + { + if(strlen($git_results->ReleaseName) > strlen($results->ReleaseName)) + $results->ReleaseName = $git_results->ReleaseName; + } + + if($results->ReleaseDescription == null) + { + $results->ReleaseDescription = ($git_results->ReleaseDescription ?? null); + } + elseif($git_results->ReleaseDescription !== null) + { + if(strlen($git_results->ReleaseDescription) > strlen($results->ReleaseDescription)) + $results->ReleaseDescription = $git_results->ReleaseDescription; + } + + if($results->Version == null) + { + $results->Version = ($git_results->Version ?? null); + } + elseif($git_results->Version !== null) + { + // Version compare + if(VersionComparator::compareVersion($git_results->Version, $results->Version) > 0) + $results->Version = $git_results->Version; + } + + $results->Files = self::mergeFilesResults($git_results->Files, ($results->Files ?? null)); + } + + try + { + $ncc_package_results = $source::getNccPackage($packageInput, $definedRemoteSource, $entry); + } + catch(Exception $e) + { + unset($e); + $ncc_package_results = null; + } + + if($ncc_package_results !== null) + { + if($results->ReleaseName == null) + { + $results->ReleaseName = ($ncc_package_results->ReleaseName ?? null); + } + elseif($ncc_package_results->ReleaseName !== null) + { + if(strlen($ncc_package_results->ReleaseName) > strlen($results->ReleaseName)) + $results->ReleaseName = $ncc_package_results->ReleaseName; + } + + if($results->ReleaseDescription == null) + { + $results->ReleaseDescription = ($ncc_package_results->ReleaseDescription ?? null); + } + elseif($ncc_package_results->ReleaseDescription !== null) + { + if(strlen($ncc_package_results->ReleaseDescription) > strlen($results->ReleaseDescription)) + $results->ReleaseDescription = $ncc_package_results->ReleaseDescription; + } + + if($results->Version == null) + { + $results->Version = ($ncc_package_results->Version ?? null); + } + elseif($ncc_package_results->Version !== null) + { + // Version compare + if(VersionComparator::compareVersion($ncc_package_results->Version, $results->Version) > 0) + $results->Version = $ncc_package_results->Version; + } + + $results->Files = self::mergeFilesResults($ncc_package_results->Files, ($results->Files ?? null)); + } + + return $results; + } + + /** + * Merges the given Files object with another Files object + * + * @param Files $input + * @param Files|null $selected + * @return Files + */ + private static function mergeFilesResults(RepositoryQueryResults\Files $input, ?RepositoryQueryResults\Files $selected=null): RepositoryQueryResults\Files + { + if($selected == null) + $selected = new RepositoryQueryResults\Files(); + + if($input->GitSshUrl !== null) + $selected->GitSshUrl = $input->GitSshUrl; + + if($input->GitHttpUrl !== null) + $selected->GitHttpUrl = $input->GitHttpUrl; + + if($input->SourceUrl !== null) + $selected->SourceUrl = $input->SourceUrl; + + if($input->TarballUrl !== null) + $selected->TarballUrl = $input->TarballUrl; + + if($input->ZipballUrl !== null) + $selected->ZipballUrl = $input->ZipballUrl; + + if($input->PackageUrl !== null) + $selected->PackageUrl = $input->PackageUrl; + + return $selected; + } } \ No newline at end of file -- 2.45.3 From 570b21ca3d4b48c3bed84a34c809781f461f801d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 08:21:56 -0500 Subject: [PATCH 107/212] Updated method \ncc\Classes\NccExtension > PackageCompiler > tryCompile() to apply the correct version to the target package if a version is specified. --- .../Classes/NccExtension/PackageCompiler.php | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index 5e643bb..459afc4 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -5,14 +5,10 @@ use Exception; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\ConstantReferences; - use ncc\Abstracts\DefinedRemoteSourceType; use ncc\Abstracts\LogLevel; use ncc\Abstracts\Options\BuildConfigurationValues; use ncc\Abstracts\ProjectType; use ncc\Classes\ComposerExtension\ComposerSourceBuiltin; - use ncc\Classes\GitClient; - use ncc\Classes\GithubExtension\GithubService; - use ncc\Classes\GitlabExtension\GitlabService; use ncc\Classes\PhpExtension\PhpCompiler; use ncc\CLI\Main; use ncc\Exceptions\AccessDeniedException; @@ -21,24 +17,17 @@ use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; use ncc\Exceptions\MalformedJsonException; - use ncc\Exceptions\PackageFetchException; use ncc\Exceptions\PackagePreparationFailedException; use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedProjectTypeException; - use ncc\Exceptions\UnsupportedRemoteSourceTypeException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Interfaces\CompilerInterface; - use ncc\Interfaces\RepositorySourceInterface; use ncc\Managers\ProjectManager; use ncc\ncc; - use ncc\Objects\DefinedRemoteSource; use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; use ncc\Objects\ProjectConfiguration\Assembly; - use ncc\Objects\RemotePackageInput; - use ncc\Objects\Vault\Entry; - use ncc\ThirdParty\jelix\Version\VersionComparator; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\Utilities\Console; use ncc\Utilities\Functions; @@ -103,35 +92,44 @@ * Returns the compiled package path * * @param string $path + * @param string|null $version * @return string * @throws BuildException - * @throws UnsupportedProjectTypeException */ public static function tryCompile(string $path, ?string $version=null): string { $project_type = Resolver::detectProjectType($path); - if($version !== null) - $version = Functions::convertToSemVer($version); - try { if($project_type->ProjectType == ProjectType::Composer) - return ComposerSourceBuiltin::fromLocal($project_type->ProjectPath); - - if($project_type->ProjectType == ProjectType::Ncc) + { + $project_path = ComposerSourceBuiltin::fromLocal($project_type->ProjectPath); + } + elseif($project_type->ProjectType == ProjectType::Ncc) { $project_manager = new ProjectManager($project_type->ProjectPath); $project_manager->getProjectConfiguration()->Assembly->Version = $version; - return $project_manager->build(); + $project_path = $project_manager->build(); } + else + { + throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported'); + } + + if($version !== null) + { + $package = Package::load($project_path); + $package->Assembly->Version = Functions::convertToSemVer($version); + $package->save($project_path); + } + + return $project_path; } catch(Exception $e) { throw new BuildException('Failed to build project', $e); } - - throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported'); } -- 2.45.3 From 24077691bbc071de6d9c8f12624dd111bec661fb Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 08:29:41 -0500 Subject: [PATCH 108/212] Bug fix: Duplicate dependencies --- src/ncc/Classes/PhpExtension/PhpCompiler.php | 2 +- src/ncc/Objects/Package.php | 38 +++++++++++++++++++ .../Objects/ProjectConfiguration/Build.php | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index f105d12..5450b5c 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -250,7 +250,7 @@ break; } - $this->package->Dependencies[] = $dependency; + $this->package->addDependency($dependency); } if(count($this->package->Dependencies) > 0) diff --git a/src/ncc/Objects/Package.php b/src/ncc/Objects/Package.php index c4d5f5b..f5e7b32 100644 --- a/src/ncc/Objects/Package.php +++ b/src/ncc/Objects/Package.php @@ -103,6 +103,44 @@ $this->Resources = []; } + /** + * Adds a dependency to the package + * + * @param Dependency $dependency + * @return void + */ + public function addDependency(Dependency $dependency) + { + foreach($this->Dependencies as $dep) + { + if($dep->Name == $dependency->Name) + { + $this->removeDependency($dep->Name); + break; + } + } + + $this->Dependencies[] = $dependency; + } + + /** + * Removes a dependency from the build + * + * @param string $name + * @return void + */ + private function removeDependency(string $name) + { + foreach($this->Dependencies as $key => $dep) + { + if($dep->Name == $name) + { + unset($this->Dependencies[$key]); + return; + } + } + } + /** * Validates the package object and returns True if the package contains the correct information * diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index 75cb315..0a1eff1 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -118,7 +118,7 @@ { if($dep->Name == $dependency->Name) { - $this->removeDependency($dep); + $this->removeDependency($dep->Name); break; } } -- 2.45.3 From cc01051e73be7cfe1c1c95f713f87b4e2ce74535 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 08:32:35 -0500 Subject: [PATCH 109/212] Updated string --- src/ncc/CLI/PackageManagerMenu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/CLI/PackageManagerMenu.php b/src/ncc/CLI/PackageManagerMenu.php index 5c7945d..6f39285 100644 --- a/src/ncc/CLI/PackageManagerMenu.php +++ b/src/ncc/CLI/PackageManagerMenu.php @@ -338,7 +338,7 @@ } } - Console::out('The following dependencies will be installed:'); + Console::out('The package requires the following dependencies:'); Console::out(sprintf('%s', implode(PHP_EOL, $dependencies))); } -- 2.45.3 From 46f6cbba702d713d902b8b40d19d420a5f89390a Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 09:26:33 -0500 Subject: [PATCH 110/212] Minor correction in Runtime.php --- src/ncc/Runtime.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php index 8acb2a5..1e00e53 100644 --- a/src/ncc/Runtime.php +++ b/src/ncc/Runtime.php @@ -13,6 +13,7 @@ use ncc\Exceptions\VersionNotFoundException; use ncc\Managers\PackageManager; use ncc\Objects\PackageLock\VersionEntry; + use ncc\Objects\ProjectConfiguration\Dependency; class Runtime { @@ -110,8 +111,9 @@ if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0) { // Import all dependencies first + /** @var Dependency $dependency */ foreach($version_entry->Dependencies as $dependency) - self::import($dependency->Package, $dependency->Version, $options); + self::import($dependency->PackageName, $dependency->Version, $options); } try -- 2.45.3 From a3c3322f28a81e1c822c25913fb96f6ed31adb0c Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 09:38:54 -0500 Subject: [PATCH 111/212] Added method \ncc\Utilities > Validate > nameFriendly() https://git.n64.cc/nosial/ncc/-/issues/4 --- src/ncc/Utilities/Validate.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ncc/Utilities/Validate.php b/src/ncc/Utilities/Validate.php index 368f6ac..46297a0 100644 --- a/src/ncc/Utilities/Validate.php +++ b/src/ncc/Utilities/Validate.php @@ -258,4 +258,21 @@ return false; } + + /** + * Determines if the input is considered "name friendly" and does not + * contain any special characters, spaces or weird prefixes + * + * @param string $input + * @return bool + */ + public static function nameFriendly(string $input): bool + { + if (!preg_match('/^[a-zA-Z0-9_]+$/', $input)) + return false; + if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $input)) + return false; + + return true; + } } \ No newline at end of file -- 2.45.3 From 405f53673ac15e19b35f5387827ff4725fad33cb Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 09:50:34 -0500 Subject: [PATCH 112/212] Added method \ncc\Objects\ProjectConfiguration > Dependency > validate() https://git.n64.cc/nosial/ncc/-/issues/4 --- .../ProjectConfiguration/Dependency.php | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/ncc/Objects/ProjectConfiguration/Dependency.php b/src/ncc/Objects/ProjectConfiguration/Dependency.php index 6978740..067f785 100644 --- a/src/ncc/Objects/ProjectConfiguration/Dependency.php +++ b/src/ncc/Objects/ProjectConfiguration/Dependency.php @@ -5,7 +5,9 @@ namespace ncc\Objects\ProjectConfiguration; use ncc\Abstracts\DependencySourceType; + use ncc\Exceptions\InvalidDependencyConfiguration; use ncc\Utilities\Functions; + use ncc\Utilities\Validate; /** * @author Zi Xing Narrakas @@ -84,4 +86,32 @@ return $DependencyObject; } + + /** + * Validates the dependency configuration + * + * @param bool $throw_exception + * @return bool + * @throws InvalidDependencyConfiguration + */ + public function validate(bool $throw_exception): bool + { + if(!Validate::packageName($this->Name)) + { + if($throw_exception) + throw new InvalidDependencyConfiguration(sprintf('Invalid dependency name "%s"', $this->Name)); + + return false; + } + + if($this->Version !== null && !Validate::version($this->Version)) + { + if($throw_exception) + throw new InvalidDependencyConfiguration(sprintf('Invalid dependency version "%s"', $this->Version)); + + return false; + } + + return true; + } } \ No newline at end of file -- 2.45.3 From f75625633cdf226b5200e03324ae528afc06cd8e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 17 Dec 2022 09:52:33 -0500 Subject: [PATCH 113/212] Added method \ncc\Objects\ProjectConfiguration > BuildConfiguration > validate() https://git.n64.cc/nosial/ncc/-/issues/4 --- .../BuildConfiguration.php | 88 ++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php b/src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php index 8991c63..3d228db 100644 --- a/src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php +++ b/src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php @@ -4,7 +4,10 @@ namespace ncc\Objects\ProjectConfiguration; + use ncc\Exceptions\InvalidBuildConfigurationException; + use ncc\Exceptions\InvalidDependencyConfiguration; use ncc\Utilities\Functions; + use ncc\Utilities\Validate; /** * @author Zi Xing Narrakas @@ -83,7 +86,90 @@ $this->Dependencies = []; } - // TODO: Add a function to validate the object data + /** + * Validates the BuildConfiguration object + * + * @param bool $throw_exception + * @return bool + * @throws InvalidBuildConfigurationException + */ + public function validate(bool $throw_exception=True): bool + { + if(!Validate::nameFriendly($this->Name)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('Invalid build configuration name "%s"', $this->Name)); + + return False; + } + + if(!Validate::pathName($this->OutputPath)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('\'output_path\' contains an invalid path name in %s', $this->Name)); + + return False; + } + + if($this->DefineConstants !== null && !is_array($this->DefineConstants)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('\'define_constants\' must be an array in %s', $this->Name)); + + return False; + } + + if($this->ExcludeFiles !== null && !is_array($this->ExcludeFiles)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('\'exclude_files\' must be an array in %s', $this->Name)); + + return False; + } + + if($this->PreBuild !== null && !is_array($this->PreBuild)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('\'pre_build\' must be an array in %s', $this->Name)); + + return False; + } + + if($this->PostBuild !== null && !is_array($this->PostBuild)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('\'post_build\' must be an array in %s', $this->Name)); + + return False; + } + + if($this->Dependencies !== null && !is_array($this->Dependencies)) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('\'dependencies\' must be an array in %s', $this->Name)); + + return False; + } + + /** @var Dependency $dependency */ + foreach($this->Dependencies as $dependency) + { + try + { + if (!$dependency->validate($throw_exception)) + return False; + } + catch (InvalidDependencyConfiguration $e) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('Invalid dependency configuration in %s: %s', $this->Name, $e->getMessage())); + + return False; + } + } + + return True; + } /** * Returns an array representation of the object -- 2.45.3 From 4f30d343e5997de9f826ac85306c1b6be0868f3f Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 00:12:45 -0500 Subject: [PATCH 114/212] Added method \ncc\Utilities > Validate > pathName() https://git.n64.cc/nosial/ncc/-/issues/4 --- src/ncc/Utilities/Validate.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/ncc/Utilities/Validate.php b/src/ncc/Utilities/Validate.php index 46297a0..838555c 100644 --- a/src/ncc/Utilities/Validate.php +++ b/src/ncc/Utilities/Validate.php @@ -268,6 +268,8 @@ */ public static function nameFriendly(string $input): bool { + if(strlen($input) == 0) + return false; if (!preg_match('/^[a-zA-Z0-9_]+$/', $input)) return false; if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $input)) @@ -275,4 +277,22 @@ return true; } + + /** + * Validates if the given input is a valid path name + * + * @param string $input + * @return bool + */ + public static function pathName(string $input): bool + { + if(strlen($input) == 0) + return false; + if (!preg_match('/^[a-zA-Z0-9_\-\/]+$/', $input)) + return false; + if (!preg_match('/^[a-zA-Z_\-\/][a-zA-Z0-9_\-\/]*$/', $input)) + return false; + + return true; + } } \ No newline at end of file -- 2.45.3 From 10237159f2f1d036205abbc030feb25771a7ee9e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 00:22:45 -0500 Subject: [PATCH 115/212] Updated method \ncc\Objects\ProjectConfiguration > Build > validate() https://git.n64.cc/nosial/ncc/-/issues/4 --- .../Objects/ProjectConfiguration/Build.php | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index 0a1eff1..aea3594 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -6,6 +6,7 @@ use ncc\Abstracts\Options\BuildConfigurationValues; use ncc\Exceptions\BuildConfigurationNotFoundException; + use ncc\Exceptions\InvalidBuildConfigurationException; use ncc\Exceptions\InvalidConstantNameException; use ncc\Exceptions\InvalidProjectBuildConfiguration; use ncc\Utilities\Functions; @@ -112,7 +113,7 @@ * @param Dependency $dependency * @return void */ - public function addDependency(Dependency $dependency) + public function addDependency(Dependency $dependency): void { foreach($this->Dependencies as $dep) { @@ -132,7 +133,7 @@ * @param string $name * @return void */ - private function removeDependency(string $name) + private function removeDependency(string $name): void { foreach($this->Dependencies as $key => $dep) { @@ -149,13 +150,13 @@ * * @param bool $throw_exception * @return bool + * @throws BuildConfigurationNotFoundException + * @throws InvalidBuildConfigurationException * @throws InvalidConstantNameException * @throws InvalidProjectBuildConfiguration */ public function validate(bool $throw_exception=True): bool { - // TODO: Implement validation for Configurations, Dependencies and ExcludedFiles - // Check the defined constants foreach($this->DefineConstants as $name => $value) { @@ -178,6 +179,37 @@ } } + foreach($this->Configurations as $configuration) + { + try + { + if (!$configuration->validate($throw_exception)) + return false; + } + catch (InvalidBuildConfigurationException $e) + { + throw new InvalidBuildConfigurationException(sprintf('Error in build configuration \'%s\'', $configuration->Name), $e); + } + } + + if($this->DefaultConfiguration == null) + { + if($throw_exception) + throw new InvalidProjectBuildConfiguration('The default build configuration is not set'); + + return false; + } + + if(!Validate::nameFriendly($this->DefaultConfiguration)) + { + if($throw_exception) + throw new InvalidProjectBuildConfiguration('The default build configuration name \'' . $this->DefaultConfiguration . '\' is not valid'); + + return false; + } + + $this->getBuildConfiguration($this->DefaultConfiguration); + return true; } -- 2.45.3 From 67391c0bde816b7d4547fa54675d176b366fcec0 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 00:24:12 -0500 Subject: [PATCH 116/212] Added \ncc\Exceptions > InvalidDependencyConfiguration https://git.n64.cc/nosial/ncc/-/issues/4 --- .../InvalidDependencyConfiguration.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/InvalidDependencyConfiguration.php diff --git a/src/ncc/Exceptions/InvalidDependencyConfiguration.php b/src/ncc/Exceptions/InvalidDependencyConfiguration.php new file mode 100644 index 0000000..8745d53 --- /dev/null +++ b/src/ncc/Exceptions/InvalidDependencyConfiguration.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From 79cec40f2392ca32cfbfe3b31ec25224ce673b5c Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 00:24:28 -0500 Subject: [PATCH 117/212] Added \ncc\Exceptions > InvalidBuildConfigurationException https://git.n64.cc/nosial/ncc/-/issues/4 --- .../InvalidBuildConfigurationException.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/InvalidBuildConfigurationException.php diff --git a/src/ncc/Exceptions/InvalidBuildConfigurationException.php b/src/ncc/Exceptions/InvalidBuildConfigurationException.php new file mode 100644 index 0000000..cc2ea91 --- /dev/null +++ b/src/ncc/Exceptions/InvalidBuildConfigurationException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From dd8d40989eaabc932c40ce6573f4eb07d938b7f3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 00:24:48 -0500 Subject: [PATCH 118/212] Updated \ncc\Abstracts > ExceptionCodes https://git.n64.cc/nosial/ncc/-/issues/4 --- src/ncc/Abstracts/ExceptionCodes.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index 38b32da..dee6915 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -338,6 +338,16 @@ */ const PackageFetchException = -1765; + /** + * @see InvalidBuildConfigurationException + */ + const InvalidBuildConfigurationException = -1766; + + /** + * @see InvalidBuildConfigurationNameException + */ + const InvalidDependencyConfiguration = -1767; + /** * All the exception codes from NCC */ @@ -404,6 +414,8 @@ self::UnsupportedProjectTypeException, self::UnsupportedArchiveException, self::ArchiveException, - self::PackageFetchException + self::PackageFetchException, + self::InvalidBuildConfigurationException, + self::InvalidDependencyConfiguration, ]; } \ No newline at end of file -- 2.45.3 From a1014eb2a5ccfe9b90e9dc00dc2d12a435a529af Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 02:11:01 -0500 Subject: [PATCH 119/212] Improved exception handling in \ncc\Managers > PackageManager > FetchFromSource() --- src/ncc/Managers/PackageManager.php | 39 ++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index b2a5e71..7bbe8b5 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -53,6 +53,7 @@ use ncc\Utilities\Validate; use ncc\ZiProto\ZiProto; use SplFileInfo; + use Throwable; class PackageManager { @@ -387,6 +388,7 @@ throw new InstallationException('Remote source ' . $input->Source . ' is not defined'); $repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry); + $exceptions = []; if($repositoryQueryResults->Files->ZipballUrl !== null) { @@ -395,9 +397,9 @@ $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->ZipballUrl, $entry); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); } - catch(Exception $e) + catch(Throwable $e) { - unset($e); + $exceptions[] = $e; } } @@ -410,7 +412,7 @@ } catch(Exception $e) { - unset($e); + $exceptions[] = $e; } } @@ -422,7 +424,7 @@ } catch(Exception $e) { - unset($e); + $exceptions[] = $e; } } @@ -443,11 +445,36 @@ } catch(Exception $e) { - unset($e); + $exceptions[] = $e; } } - throw new PackageFetchException(sprintf('Failed to fetch package \'%s\'', $input->Package)); + // Recursively create an exception with the previous exceptions as the previous exception + $exception = null; + + if(count($exceptions) > 0) + { + foreach($exceptions as $e) + { + if($exception == null) + { + $exception = new PackageFetchException($e->getMessage(), $e); + } + else + { + if($e->getMessage() == $exception->getMessage()) + continue; + + $exception = new PackageFetchException($e->getMessage(), $exception); + } + } + } + else + { + $exception = new PackageFetchException('Cannot fetch package from remote source, no assets found'); + } + + throw $exception; } throw new PackageFetchException(sprintf('Unknown remote source type %s', $remote_source_type)); -- 2.45.3 From 0099a8616845d93acb16ca3bfb2875d5b30497ef Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 02:29:56 -0500 Subject: [PATCH 120/212] Refactored \ncc\CLI --- src/ncc/CLI/{ => Commands}/BuildMenu.php | 2 +- src/ncc/CLI/Main.php | 6 ++ src/ncc/CLI/{ => Management}/ConfigMenu.php | 2 +- .../CLI/{ => Management}/CredentialMenu.php | 2 +- .../{ => Management}/PackageManagerMenu.php | 2 +- src/ncc/CLI/{ => Management}/ProjectMenu.php | 2 +- src/ncc/CLI/{ => Management}/SourcesMenu.php | 2 +- src/ncc/CLI/PhpMenu.php | 59 ------------------- 8 files changed, 12 insertions(+), 65 deletions(-) rename src/ncc/CLI/{ => Commands}/BuildMenu.php (99%) rename src/ncc/CLI/{ => Management}/ConfigMenu.php (99%) rename src/ncc/CLI/{ => Management}/CredentialMenu.php (99%) rename src/ncc/CLI/{ => Management}/PackageManagerMenu.php (99%) rename src/ncc/CLI/{ => Management}/ProjectMenu.php (99%) rename src/ncc/CLI/{ => Management}/SourcesMenu.php (99%) delete mode 100644 src/ncc/CLI/PhpMenu.php diff --git a/src/ncc/CLI/BuildMenu.php b/src/ncc/CLI/Commands/BuildMenu.php similarity index 99% rename from src/ncc/CLI/BuildMenu.php rename to src/ncc/CLI/Commands/BuildMenu.php index e88d85a..15d3411 100644 --- a/src/ncc/CLI/BuildMenu.php +++ b/src/ncc/CLI/Commands/BuildMenu.php @@ -1,6 +1,6 @@ toString($options_padding)); - } - } - } \ No newline at end of file -- 2.45.3 From cada094371e32ae917ee2f94590a6e30d3b50569 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 03:01:07 -0500 Subject: [PATCH 121/212] Updated custom_repositories.json --- src/default_repositories/custom_repositories.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/default_repositories/custom_repositories.json b/src/default_repositories/custom_repositories.json index d2cded0..b7cc656 100644 --- a/src/default_repositories/custom_repositories.json +++ b/src/default_repositories/custom_repositories.json @@ -1,6 +1,5 @@ [ "github.json", "gitlab.json", - "n64.json", - "nocturn9x.json" + "n64.json" ] \ No newline at end of file -- 2.45.3 From a25f1e0c2aafbead86b39349156fad3579ec4f8e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 03:05:13 -0500 Subject: [PATCH 122/212] Added custom repository gitgud.io --- src/default_repositories/custom_repositories.json | 1 + src/default_repositories/gitgud.json | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 src/default_repositories/gitgud.json diff --git a/src/default_repositories/custom_repositories.json b/src/default_repositories/custom_repositories.json index b7cc656..aa1a562 100644 --- a/src/default_repositories/custom_repositories.json +++ b/src/default_repositories/custom_repositories.json @@ -1,4 +1,5 @@ [ + "gitgud.json", "github.json", "gitlab.json", "n64.json" diff --git a/src/default_repositories/gitgud.json b/src/default_repositories/gitgud.json new file mode 100644 index 0000000..83f904e --- /dev/null +++ b/src/default_repositories/gitgud.json @@ -0,0 +1,6 @@ +{ + "name": "gitgud", + "type": "gitlab", + "host": "gitgud.io", + "ssl": true +} \ No newline at end of file -- 2.45.3 From 856db39f9a88ac911ddc0a02bd1239566e15d2c1 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 18 Dec 2022 17:01:29 -0500 Subject: [PATCH 123/212] Updated method in \ncc\Objects\Project > Project > fromArray() to invoke toArray() on UpdateSource if it's not null. --- src/ncc/Objects/ProjectConfiguration/Project.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ncc/Objects/ProjectConfiguration/Project.php b/src/ncc/Objects/ProjectConfiguration/Project.php index 83f7e2e..cda1034 100644 --- a/src/ncc/Objects/ProjectConfiguration/Project.php +++ b/src/ncc/Objects/ProjectConfiguration/Project.php @@ -70,7 +70,9 @@ $ReturnResults[($bytecode ? Functions::cbc('compiler') : 'compiler')] = $this->Compiler->toArray($bytecode); $ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options; - $ReturnResults[($bytecode ? Functions::cbc('update_source') : 'update_source')] = $this->UpdateSource->toArray($bytecode); + + if($this->UpdateSource !== null) + $ReturnResults[($bytecode ? Functions::cbc('update_source') : 'update_source')] = $this->UpdateSource->toArray($bytecode); return $ReturnResults; } -- 2.45.3 From 50042a244d206415a0ac065372a14ef36b030fd4 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 19 Dec 2022 00:57:31 -0500 Subject: [PATCH 124/212] Added check in \ncc\Managers > PackageManager > uninstallPackageVersion() --- src/ncc/Managers/PackageManager.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 7bbe8b5..f0b0257 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -732,16 +732,23 @@ $scanner = new DirectoryScanner(); $filesystem = new Filesystem(); - /** @var SplFileInfo $item */ - /** @noinspection PhpRedundantOptionalArgumentInspection */ - foreach($scanner($version_entry->Location, true) as $item) + if($filesystem->exists($version_entry->Location)) { - if(is_file($item->getPath())) + /** @var SplFileInfo $item */ + /** @noinspection PhpRedundantOptionalArgumentInspection */ + foreach($scanner($version_entry->Location, true) as $item) { - Console::outDebug(sprintf('deleting %s', $item->getPath())); - $filesystem->remove($item->getPath()); + if(is_file($item->getPath())) + { + Console::outDebug(sprintf('deleting %s', $item->getPath())); + $filesystem->remove($item->getPath()); + } } } + else + { + Console::outWarning(sprintf('warning: package location %s does not exist', $version_entry->Location)); + } $filesystem->remove($version_entry->Location); -- 2.45.3 From dc4ad1d08db7b475588bbffc0904b0cadf4b2dad Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 19 Dec 2022 16:20:59 -0500 Subject: [PATCH 125/212] Moved RuntimeImportOptions to \ncc\Abstracts > Options --- src/ncc/Abstracts/{ => Options}/RuntimeImportOptions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/ncc/Abstracts/{ => Options}/RuntimeImportOptions.php (92%) diff --git a/src/ncc/Abstracts/RuntimeImportOptions.php b/src/ncc/Abstracts/Options/RuntimeImportOptions.php similarity index 92% rename from src/ncc/Abstracts/RuntimeImportOptions.php rename to src/ncc/Abstracts/Options/RuntimeImportOptions.php index 230e98a..dff2798 100644 --- a/src/ncc/Abstracts/RuntimeImportOptions.php +++ b/src/ncc/Abstracts/Options/RuntimeImportOptions.php @@ -1,6 +1,6 @@ Date: Mon, 19 Dec 2022 16:42:48 -0500 Subject: [PATCH 126/212] Some bug fixes, added options `--reinstall` & `--skip-dependencies` for the `ncc package install` command. --- .../Options/InstallPackageOptions.php | 20 ++++++ src/ncc/CLI/Management/PackageManagerMenu.php | 63 +++++++++++++------ src/ncc/Classes/PhpExtension/PhpRuntime.php | 2 +- src/ncc/Managers/PackageManager.php | 44 +++++++++++-- src/ncc/Objects/PackageLock.php | 35 +++++++++++ 5 files changed, 138 insertions(+), 26 deletions(-) create mode 100644 src/ncc/Abstracts/Options/InstallPackageOptions.php diff --git a/src/ncc/Abstracts/Options/InstallPackageOptions.php b/src/ncc/Abstracts/Options/InstallPackageOptions.php new file mode 100644 index 0000000..dd5207c --- /dev/null +++ b/src/ncc/Abstracts/Options/InstallPackageOptions.php @@ -0,0 +1,20 @@ +Assembly->Trademark, ConsoleColors::LightGreen)); Console::out((string)null); - if(count($package->Dependencies) > 0) + if(count($package->Dependencies) > 0 && !in_array(InstallPackageOptions::Reinstall, $installer_options)) { $dependencies = []; foreach($package->Dependencies as $dependency) { - $require_dependency = true; - - try + if(in_array(InstallPackageOptions::Reinstall, $installer_options)) { - $dependency_package = $package_manager->getPackage($dependency->Name); + $require_dependency = true; } - catch (PackageLockException $e) - { - unset($e); - $dependency_package = null; - } - - if($dependency_package !== null) + else { try { - $dependency_version = $dependency_package->getVersion($dependency->Version); + $dependency_package = $package_manager->getPackage($dependency->Name); } - catch (VersionNotFoundException $e) + catch (PackageLockException $e) { unset($e); - $dependency_version = null; + $dependency_package = null; } - if($dependency_version !== null) + if($dependency_package !== null) { - $require_dependency = false; + try + { + $dependency_version = $dependency_package->getVersion($dependency->Version); + } + catch (VersionNotFoundException $e) + { + unset($e); + $dependency_version = null; + } + + if($dependency_version !== null) + { + $require_dependency = false; + } } } @@ -338,8 +356,11 @@ } } - Console::out('The package requires the following dependencies:'); - Console::out(sprintf('%s', implode(PHP_EOL, $dependencies))); + if($dependencies !== null && count($dependencies) > 0) + { + Console::out('The package requires the following dependencies:'); + Console::out(sprintf('%s', implode(PHP_EOL, $dependencies))); + } } Console::out(sprintf('Extension: %s', @@ -359,11 +380,13 @@ if(!$user_confirmation) $user_confirmation = Console::getBooleanInput(sprintf('Do you want to install %s', $package->Assembly->Package)); + + if($user_confirmation) { try { - $package_manager->install($path, $credential); + $package_manager->install($path, $credential, $installer_options); Console::out(sprintf('Package %s installed successfully', $package->Assembly->Package)); } catch(Exception $e) diff --git a/src/ncc/Classes/PhpExtension/PhpRuntime.php b/src/ncc/Classes/PhpExtension/PhpRuntime.php index 20aeb4f..1e5cf22 100644 --- a/src/ncc/Classes/PhpExtension/PhpRuntime.php +++ b/src/ncc/Classes/PhpExtension/PhpRuntime.php @@ -2,7 +2,7 @@ namespace ncc\Classes\PhpExtension; - use ncc\Abstracts\RuntimeImportOptions; + use ncc\Abstracts\Options\RuntimeImportOptions; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index f0b0257..c3e846f 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -10,6 +10,7 @@ use ncc\Abstracts\ConstantReferences; use ncc\Abstracts\DependencySourceType; use ncc\Abstracts\LogLevel; + use ncc\Abstracts\Options\InstallPackageOptions; use ncc\Abstracts\RemoteSourceType; use ncc\Abstracts\Scopes; use ncc\Abstracts\Versions; @@ -83,6 +84,7 @@ * * @param string $package_path * @param Entry|null $entry + * @param array $options * @return string * @throws AccessDeniedException * @throws FileNotFoundException @@ -98,7 +100,7 @@ * @throws UnsupportedRunnerException * @throws VersionNotFoundException */ - public function install(string $package_path, ?Entry $entry=null): string + public function install(string $package_path, ?Entry $entry=null, array $options=[]): string { if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Insufficient permission to install packages'); @@ -108,9 +110,6 @@ $package = Package::load($package_path); - if($this->getPackageVersion($package->Assembly->Package, $package->Assembly->Version) !== null) - throw new PackageAlreadyInstalledException('The package ' . $package->Assembly->Package . '=' . $package->Assembly->Version . ' is already installed'); - $extension = $package->Header->CompilerExtension->Extension; $installation_paths = new InstallationPaths($this->PackagesPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '=' . $package->Assembly->Version); @@ -120,16 +119,51 @@ default => throw new UnsupportedCompilerExtensionException('The compiler extension \'' . $extension . '\' is not supported'), }; + if($this->getPackageVersion($package->Assembly->Package, $package->Assembly->Version) !== null) + { + if(in_array(InstallPackageOptions::Reinstall, $options)) + { + if($this->getPackageLockManager()->getPackageLock()->packageExists( + $package->Assembly->Package, $package->Assembly->Version + )) + { + $this->getPackageLockManager()->getPackageLock()->removePackageVersion( + $package->Assembly->Package, $package->Assembly->Version + ); + } + } + else + { + throw new PackageAlreadyInstalledException('The package ' . $package->Assembly->Package . '=' . $package->Assembly->Version . ' is already installed'); + } + } + $execution_pointer_manager = new ExecutionPointerManager(); PackageCompiler::compilePackageConstants($package, [ ConstantReferences::Install => $installation_paths ]); // Process all the required dependencies before installing the package - if($package->Dependencies !== null && count($package->Dependencies) > 0) + if($package->Dependencies !== null && count($package->Dependencies) > 0 && !in_array(InstallPackageOptions::SkipDependencies, $options)) { foreach($package->Dependencies as $dependency) { + if(in_array(InstallPackageOptions::Reinstall, $options)) + { + // Uninstall the dependency if the option Reinstall is passed on + if($this->getPackageLockManager()->getPackageLock()->packageExists($dependency->Name, $dependency->Version)) + { + if($dependency->Version == null) + { + $this->uninstallPackage($dependency->Name); + } + else + { + $this->uninstallPackageVersion($dependency->Name, $dependency->Version); + } + } + } + $this->processDependency($dependency, $package, $package_path, $entry); } } diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php index 7f84302..5415d8e 100644 --- a/src/ncc/Objects/PackageLock.php +++ b/src/ncc/Objects/PackageLock.php @@ -5,6 +5,7 @@ namespace ncc\Objects; use ncc\Abstracts\Versions; + use ncc\Exceptions\VersionNotFoundException; use ncc\Objects\PackageLock\PackageEntry; use ncc\Utilities\Functions; @@ -134,6 +135,40 @@ return null; } + /** + * Determines if the requested package exists in the package lock + * + * @param string $package + * @param string|null $version + * @return bool + */ + public function packageExists(string $package, ?string $version=null): bool + { + $package_entry = $this->getPackage($package); + if($package_entry == null) + return false; + + if($version !== null) + { + try + { + $version_entry = $package_entry->getVersion($version); + } + catch (VersionNotFoundException $e) + { + unset($e); + return false; + } + + if($version_entry == null) + { + return false; + } + } + + return true; + } + /** * Returns an array of all packages and their installed versions * -- 2.45.3 From 558c0a3212ea1248ec0874f9e43470b9d1304219 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 19 Dec 2022 16:51:08 -0500 Subject: [PATCH 127/212] Updated method \ncc\CLI\Management > PackageManagerMenu > displayOptions() --- src/ncc/CLI/Management/PackageManagerMenu.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ncc/CLI/Management/PackageManagerMenu.php b/src/ncc/CLI/Management/PackageManagerMenu.php index fc41d94..fa64d7d 100644 --- a/src/ncc/CLI/Management/PackageManagerMenu.php +++ b/src/ncc/CLI/Management/PackageManagerMenu.php @@ -546,6 +546,8 @@ new CliHelpSection(['list'], 'Lists all installed packages on the system'), new CliHelpSection(['install', '--package', '-p'], 'Installs a specified NCC package'), new CliHelpSection(['install', '--package', '-p', '--version', '-v'], 'Installs a specified NCC package version'), + new CliHelpSection(['install', '-p', '--skip-dependencies'], 'Installs a specified NCC package but skips the installation of dependencies'), + new CliHelpSection(['install', '-p', '--reinstall'], 'Installs a specified NCC package, reinstall if already installed'), new CliHelpSection(['uninstall', '--package', '-p'], 'Uninstalls a specified NCC package'), new CliHelpSection(['uninstall', '--package', '-p', '--version', '-v'], 'Uninstalls a specified NCC package version'), new CliHelpSection(['uninstall-all'], 'Uninstalls all packages'), -- 2.45.3 From 7ffbdf72c100449f32581265d01af0708631f7cd Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 19 Dec 2022 18:41:10 -0500 Subject: [PATCH 128/212] Added Data path for packages --- src/installer/extension | 24 +++++++++++++++++++- src/ncc/Objects/PackageLock.php | 2 ++ src/ncc/Objects/PackageLock/PackageEntry.php | 24 ++++++++++++++++++++ src/ncc/Runtime.php | 21 +++++++++++++++++ src/ncc/Utilities/PathFinder.php | 17 ++++++++++++++ 5 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/installer/extension b/src/installer/extension index a8ae695..bbdcffa 100644 --- a/src/installer/extension +++ b/src/installer/extension @@ -4,7 +4,11 @@ use ncc\Exceptions\ConstantReadonlyException; use ncc\Exceptions\ImportException; use ncc\Exceptions\InvalidConstantNameException; - use ncc\ncc; +use ncc\Exceptions\InvalidPackageNameException; +use ncc\Exceptions\InvalidScopeException; +use ncc\Exceptions\PackageLockException; +use ncc\Exceptions\PackageNotFoundException; +use ncc\ncc; use ncc\Runtime; if(!defined('NCC_INIT')) @@ -112,4 +116,22 @@ Runtime\Constants::delete($package, $name); } } + + if(!function_exists('get_data_path')) + { + /** + * Returns the data path of the package + * + * @param string $package + * @return string + * @throws InvalidPackageNameException + * @throws InvalidScopeException + * @throws PackageLockException + * @throws PackageNotFoundException + */ + function get_data_path(string $package): string + { + return Runtime::getDataPath($package); + } + } } \ No newline at end of file diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php index 5415d8e..989164c 100644 --- a/src/ncc/Objects/PackageLock.php +++ b/src/ncc/Objects/PackageLock.php @@ -65,6 +65,7 @@ $package_entry->addVersion($package, $install_path, true); $package_entry->Name = $package->Assembly->Package; $package_entry->UpdateSource = $package->Header->UpdateSource; + $package_entry->getDataPath(); $this->Packages[$package->Assembly->Package] = $package_entry; $this->update(); @@ -73,6 +74,7 @@ $this->Packages[$package->Assembly->Package]->UpdateSource = $package->Header->UpdateSource; $this->Packages[$package->Assembly->Package]->addVersion($package, true); + $this->Packages[$package->Assembly->Package]->getDataPath(); $this->update(); } diff --git a/src/ncc/Objects/PackageLock/PackageEntry.php b/src/ncc/Objects/PackageLock/PackageEntry.php index c2f95f0..2c58990 100644 --- a/src/ncc/Objects/PackageLock/PackageEntry.php +++ b/src/ncc/Objects/PackageLock/PackageEntry.php @@ -4,11 +4,17 @@ namespace ncc\Objects\PackageLock; + use ncc\Abstracts\Scopes; + use ncc\Exceptions\InvalidPackageNameException; + use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\VersionNotFoundException; use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration\UpdateSource; use ncc\ThirdParty\jelix\Version\VersionComparator; + use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\Utilities\Functions; + use ncc\Utilities\PathFinder; + use ncc\Utilities\Resolver; class PackageEntry { @@ -194,6 +200,24 @@ return $r; } + /** + * @return string + * @throws InvalidPackageNameException + * @throws InvalidScopeException + */ + public function getDataPath(): string + { + $path = PathFinder::getPackageDataPath($this->Name); + + if(!file_exists($path) && Resolver::resolveScope() == Scopes::System) + { + $filesystem = new Filesystem(); + $filesystem->mkdir($path, 0777); + } + + return $path; + } + /** * Returns an array representation of the object * diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php index 1e00e53..6bb63ba 100644 --- a/src/ncc/Runtime.php +++ b/src/ncc/Runtime.php @@ -10,6 +10,7 @@ use ncc\Classes\PhpExtension\PhpRuntime; use ncc\Exceptions\ImportException; use ncc\Exceptions\PackageLockException; + use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\VersionNotFoundException; use ncc\Managers\PackageManager; use ncc\Objects\PackageLock\VersionEntry; @@ -137,6 +138,26 @@ self::addImport($package, $version); } + /** + * Returns the data path of the package + * + * @param string $package + * @return string + * @throws Exceptions\InvalidPackageNameException + * @throws Exceptions\InvalidScopeException + * @throws PackageLockException + * @throws PackageNotFoundException + */ + public static function getDataPath(string $package): string + { + $package = self::getPackageManager()->getPackage($package); + + if($package == null) + throw new PackageNotFoundException(sprintf('Package %s not found', $package)); + + return $package->getDataPath(); + } + /** * @return PackageManager */ diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index 8872291..df457fc 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -4,6 +4,7 @@ use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; + use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\RunnerExecutionException; use ncc\ThirdParty\Symfony\Process\ExecutableFinder; @@ -204,6 +205,22 @@ return $results; } + /** + * Returns the path where package data is located + * + * @param string $package + * @return string + * @throws InvalidPackageNameException + * @throws InvalidScopeException + */ + public static function getPackageDataPath(string $package): string + { + if(!Validate::packageName($package)) + throw new InvalidPackageNameException($package); + + return self::getDataPath() . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package; + } + /** * Returns the file path where files for the given extension is stored * -- 2.45.3 From 8ff91590d27c2f8f98eef96da3ff553e18d530a7 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 19 Dec 2022 18:59:02 -0500 Subject: [PATCH 129/212] Updated configuration manager to not use hard-coded configuration values (there's no way I'm hard-coding every single configuration value and checking their correct type.) --- src/ncc/Managers/ConfigurationManager.php | 204 ++-------------------- src/ncc/Utilities/Functions.php | 24 +++ 2 files changed, 34 insertions(+), 194 deletions(-) diff --git a/src/ncc/Managers/ConfigurationManager.php b/src/ncc/Managers/ConfigurationManager.php index 8ec173c..7df457e 100644 --- a/src/ncc/Managers/ConfigurationManager.php +++ b/src/ncc/Managers/ConfigurationManager.php @@ -121,202 +121,18 @@ */ public function updateProperty(string $property, $value): bool { - // composer.options.quiet - $result = match (strtolower(explode('.', $property)[0])) + $keys = explode('.', $property); + $current = &$this->Configuration; + foreach ($keys as $k) { - 'ncc' => $this->updateNccProperties($property, $value), - 'php' => $this->updatePhpProperties($property, $value), - 'git' => $this->updateGitProperties($property, $value), - 'runners' => $this->updateRunnerProperties($property, $value), - 'composer' => $this->updateComposerProperties($property, $value), - default => false, - }; - + if (!array_key_exists($k, $current)) + { + return false; + } + $current = &$current[$k]; + } + $current = Functions::stringTypeCast($value); $this->save(); - return $result; - } - - /** - * Updates NCC configuration properties in the configuration - * - * @param string $property - * @param $value - * @return bool - */ - private function updateNccProperties(string $property, $value): bool - { - $delete = false; - if(is_null($value)) - $delete = true; - - switch(strtolower($property)) - { - case 'ncc.cli.no_colors': - $this->Configuration['ncc']['cli']['no_colors'] = Functions::cbool($value); - break; - case 'ncc.cli.basic_ascii': - $this->Configuration['ncc']['cli']['basic_ascii'] = Functions::cbool($value); - break; - case 'ncc.cli.logging': - $this->Configuration['ncc']['cli']['logging'] = ($delete ? LogLevel::Info : (string)$value); - break; - - default: - return false; - } - - return true; - } - - /** - * Updates PHP properties in the configuraiton - * - * @param string $property - * @param $value - * @return bool - */ - private function updatePhpProperties(string $property, $value): bool - { - $delete = false; - if(is_null($value)) - $delete = true; - - switch(strtolower($property)) - { - case 'php.executable_path': - $this->Configuration['php']['executable_path'] = ($delete ? null : (string)$value); - break; - case 'php.runtime.initialize_on_require': - $this->Configuration['php']['runtime']['initialize_on_require'] = Functions::cbool($value); - break; - case 'php.runtime.handle_exceptions': - $this->Configuration['php']['runtime']['handle_exceptions'] = Functions::cbool($value); - break; - - default: - return false; - } - - return true; - } - - /** - * Updated git properties - * - * @param string $property - * @param $value - * @return bool - */ - private function updateGitProperties(string $property, $value): bool - { - $delete = false; - if(is_null($value)) - $delete = true; - - switch(strtolower($property)) - { - case 'git.enabled': - $this->Configuration['git']['enabled'] = Functions::cbool($value); - break; - case 'git.executable_path': - $this->Configuration['git']['executable_path'] = ($delete? null : (string)$value); - break; - default: - return false; - } - - return true; - } - - /** - * Updaters runner properties - * - * @param string $property - * @param $value - * @return bool - */ - private function updateRunnerProperties(string $property, $value): bool - { - $delete = false; - if(is_null($value)) - $delete = true; - - switch(strtolower($property)) - { - case 'runners.php': - $this->Configuration['runners']['php'] = ($delete? null : (string)$value); - break; - case 'runners.bash': - $this->Configuration['runners']['bash'] = ($delete? null : (string)$value); - break; - case 'runners.sh': - $this->Configuration['runners']['sh'] = ($delete? null : (string)$value); - break; - case 'runners.python': - $this->Configuration['runners']['python'] = ($delete? null : (string)$value); - break; - case 'runners.python3': - $this->Configuration['runners']['python3'] = ($delete? null : (string)$value); - break; - case 'runners.python2': - $this->Configuration['runners']['python2'] = ($delete? null : (string)$value); - break; - - default: - return false; - } - - return true; - } - - /** - * Updates a composer property value - * - * @param string $property - * @param $value - * @return bool - */ - private function updateComposerProperties(string $property, $value): bool - { - $delete = false; - if(is_null($value)) - $delete = true; - - switch(strtolower($property)) - { - case 'composer.enabled': - $this->Configuration['composer']['enabled'] = Functions::cbool($value); - break; - case 'composer.enable_internal_composer': - $this->Configuration['composer']['enable_internal_composer'] = Functions::cbool($value); - break; - case 'composer.executable_path': - $this->Configuration['composer']['executable_path'] = ($delete? null : (string)$value); - break; - case 'composer.options.quiet': - $this->Configuration['composer']['options']['quiet'] = Functions::cbool($value); - break; - case 'composer.options.no_ansi': - $this->Configuration['composer']['options']['no_ansi'] = Functions::cbool($value); - break; - case 'composer.options.no_interaction': - $this->Configuration['composer']['options']['no_interaction'] = Functions::cbool($value); - break; - case 'composer.options.profile': - $this->Configuration['composer']['options']['profile'] = Functions::cbool($value); - break; - case 'composer.options.no_scripts': - $this->Configuration['composer']['options']['no_scripts'] = Functions::cbool($value); - break; - case 'composer.options.no_cache': - $this->Configuration['composer']['options']['no_cache'] = Functions::cbool($value); - break; - case 'composer.options.logging': - $this->Configuration['composer']['options']['logging'] = ((int)$value > 0 ? (int)$value : 1); - break; - default: - return false; - } return true; } diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 5d8cd52..226bcbe 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -918,4 +918,28 @@ return $selected; } + + /** + * Attempts to cast the correct type of the given value + * + * @param string $input + * @return float|int|mixed|string + */ + public static function stringTypeCast(string $input) + { + if (is_numeric($input)) + { + if (strpos($input, '.') !== false) + return (float)$input; + + if (ctype_digit($input)) + return (int)$input; + } + elseif (in_array(strtolower($input), ['true', 'false'])) + { + return filter_var($input, FILTER_VALIDATE_BOOLEAN); + } + + return (string)$input; + } } \ No newline at end of file -- 2.45.3 From 1b5991425df6ac07b7da64c16c3f13bc6ef3d518 Mon Sep 17 00:00:00 2001 From: Netkas Date: Tue, 20 Dec 2022 15:00:03 -0500 Subject: [PATCH 130/212] Updated \ncc\Objects > PackageLock > addPackage() https://git.n64.cc/nosial/ncc/-/issues/41 --- src/ncc/Objects/PackageLock.php | 3 ++- src/ncc/Runtime.php | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php index 989164c..b79bc49 100644 --- a/src/ncc/Objects/PackageLock.php +++ b/src/ncc/Objects/PackageLock.php @@ -73,7 +73,8 @@ } $this->Packages[$package->Assembly->Package]->UpdateSource = $package->Header->UpdateSource; - $this->Packages[$package->Assembly->Package]->addVersion($package, true); + $this->Packages[$package->Assembly->Package]->addVersion($package, $install_path, true); + $this->Packages[$package->Assembly->Package]->addVersion($package, $install_path, true); $this->Packages[$package->Assembly->Package]->getDataPath(); $this->update(); } diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php index 6bb63ba..3e45114 100644 --- a/src/ncc/Runtime.php +++ b/src/ncc/Runtime.php @@ -98,7 +98,6 @@ throw new ImportException(sprintf('Version %s of %s is not installed', $version, $package), $e); } - try { if (self::isImported($package, $version)) -- 2.45.3 From c0db3ac4c62f0c28454450039e82d3da2730eeb6 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 22 Dec 2022 13:01:25 -0500 Subject: [PATCH 131/212] Updated method \ncc\Managers > PackageManager > getPackageTree() --- src/ncc/Managers/PackageManager.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index c3e846f..67505ba 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -674,7 +674,15 @@ $exploded = explode('=', $package); try { - foreach ($this->getPackage($exploded[0])?->getVersion($exploded[1])?->Dependencies as $dependency) + $package = $this->getPackage($exploded[0]); + if($package == null) + throw new PackageNotFoundException('Package ' . $exploded[0] . ' not found'); + + $version = $package->getVersion($exploded[1]); + if($version == null) + throw new VersionNotFoundException('Version ' . $exploded[1] . ' not found for package ' . $exploded[0]); + + foreach ($version->Dependencies as $dependency) { if(!in_array($dependency->PackageName . '=' . $dependency->Version, $tree)) $packages[] = $dependency->PackageName . '=' . $dependency->Version; -- 2.45.3 From fa31416932c6abf0d5937f51f590f6841892e0a0 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 22 Dec 2022 17:32:15 -0500 Subject: [PATCH 132/212] Added a shutdown task to finalize permissions for some directories that could be made un-writable after certain operations. --- src/ncc/CLI/Main.php | 3 ++- src/ncc/Utilities/Functions.php | 36 ++++++++++++++++++++++++++++++ src/ncc/Utilities/RuntimeCache.php | 2 ++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index 00cc511..dc87436 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -17,6 +17,7 @@ use ncc\Exceptions\RuntimeException; use ncc\ncc; use ncc\Utilities\Console; + use ncc\Utilities\Functions; use ncc\Utilities\Resolver; use ncc\Utilities\RuntimeCache; @@ -182,8 +183,8 @@ */ public static function shutdown(): void { - Console::outDebug('clearing cache'); RuntimeCache::clearCache(); + Functions::finalizePermissions(); } } \ No newline at end of file diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 226bcbe..9f6f6b0 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -942,4 +942,40 @@ return (string)$input; } + + /** + * Finalizes the permissions + * + * @return void + * @throws InvalidScopeException + */ + public static function finalizePermissions() + { + if(Resolver::resolveScope() !== Scopes::System) + return; + + Console::outVerbose('Finalizing permissions...'); + $filesystem = new Filesystem(); + + try + { + if($filesystem->exists(PathFinder::getDataPath() . DIRECTORY_SEPARATOR . 'data')) + $filesystem->chmod(PathFinder::getDataPath() . DIRECTORY_SEPARATOR . 'data', 0777, 0000, true); + } + catch(Exception $e) + { + Console::outWarning(sprintf('Failed to finalize permissions for %s: %s', PathFinder::getDataPath() . DIRECTORY_SEPARATOR . 'data', $e->getMessage())); + } + + try + { + if($filesystem->exists(PathFinder::getCachePath())) + $filesystem->chmod(PathFinder::getCachePath(), 0777, 0000, true); + } + catch(Exception $e) + { + Console::outWarning(sprintf('Failed to finalize permissions for %s: %s', PathFinder::getDataPath() . DIRECTORY_SEPARATOR . 'data', $e->getMessage())); + } + + } } \ No newline at end of file diff --git a/src/ncc/Utilities/RuntimeCache.php b/src/ncc/Utilities/RuntimeCache.php index 48708c8..0371b03 100644 --- a/src/ncc/Utilities/RuntimeCache.php +++ b/src/ncc/Utilities/RuntimeCache.php @@ -86,6 +86,8 @@ */ public static function clearCache(bool $clear_memory=true, bool $clear_files=true): void { + Console::outDebug('clearing cache'); + if($clear_memory) { Console::outDebug(sprintf('clearing memory cache (%d entries)', count(self::$cache))); -- 2.45.3 From 8557c33b4af494b83112988b2c5c8836cefd8e30 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 23 Dec 2022 01:27:11 -0500 Subject: [PATCH 133/212] Minor correction in \ncc\CLI\Management > PackageManagerMenu > installPackage() where $require_dependencies is not always set. --- src/ncc/CLI/Management/PackageManagerMenu.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ncc/CLI/Management/PackageManagerMenu.php b/src/ncc/CLI/Management/PackageManagerMenu.php index fa64d7d..e8db3f3 100644 --- a/src/ncc/CLI/Management/PackageManagerMenu.php +++ b/src/ncc/CLI/Management/PackageManagerMenu.php @@ -312,6 +312,8 @@ $dependencies = []; foreach($package->Dependencies as $dependency) { + $require_dependency = false; + if(in_array(InstallPackageOptions::Reinstall, $installer_options)) { $require_dependency = true; -- 2.45.3 From 233d5ce6d2c8853ccf1173c754df9d499cf0eb1e Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 23 Dec 2022 01:27:30 -0500 Subject: [PATCH 134/212] Implemented DataPaths for packages --- src/ncc/Utilities/Functions.php | 8 ++++---- src/ncc/Utilities/PathFinder.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 9f6f6b0..7c9c568 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -959,8 +959,8 @@ try { - if($filesystem->exists(PathFinder::getDataPath() . DIRECTORY_SEPARATOR . 'data')) - $filesystem->chmod(PathFinder::getDataPath() . DIRECTORY_SEPARATOR . 'data', 0777, 0000, true); + if($filesystem->exists(PathFinder::getDataPath(Scopes::System))) + $filesystem->chmod(PathFinder::getDataPath(Scopes::System), 0777, 0000, true); } catch(Exception $e) { @@ -969,8 +969,8 @@ try { - if($filesystem->exists(PathFinder::getCachePath())) - $filesystem->chmod(PathFinder::getCachePath(), 0777, 0000, true); + if($filesystem->exists(PathFinder::getCachePath(Scopes::System))) + $filesystem->chmod(PathFinder::getCachePath(Scopes::System), 0777, 0000, true); } catch(Exception $e) { diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index df457fc..1e37d33 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -218,7 +218,7 @@ if(!Validate::packageName($package)) throw new InvalidPackageNameException($package); - return self::getDataPath() . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package; + return self::getDataPath(Scopes::System) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . $package; } /** -- 2.45.3 From b06661f595efb97d9dfdfa562c67725f80058b1e Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 23 Dec 2022 01:27:58 -0500 Subject: [PATCH 135/212] Updated \ncc\Managers > PackageManager --- src/ncc/Managers/PackageManager.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 67505ba..7345d00 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -32,7 +32,6 @@ use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\PackageParsingException; use ncc\Exceptions\UnsupportedCompilerExtensionException; - use ncc\Exceptions\UnsupportedRemoteSourceTypeException; use ncc\Exceptions\UnsupportedRunnerException; use ncc\Exceptions\VersionNotFoundException; use ncc\Objects\DefinedRemoteSource; -- 2.45.3 From 7db78a51ae5fefb37a4fea9c06723cfe15e3f6b9 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 23 Dec 2022 03:43:34 -0500 Subject: [PATCH 136/212] Updated \ncc\Classes\PhpExtension > PhpCompiler > prepare so that the libs folder is only created when it's being written to. --- src/ncc/Classes/PhpExtension/PhpCompiler.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index 5450b5c..f594ef9 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -214,7 +214,6 @@ $lib_path = $selected_build_configuration->OutputPath . DIRECTORY_SEPARATOR . 'libs'; if($filesystem->exists($lib_path)) $filesystem->remove($lib_path); - $filesystem->mkdir($lib_path); Console::outVerbose('Scanning for dependencies... '); foreach($selected_dependencies as $dependency) @@ -230,6 +229,10 @@ $package = $package_lock_manager->getPackageLock()->getPackage($dependency->Name); $version = $package->getVersion($dependency->Version); Console::outDebug(sprintf('copying shadow package %s=%s to %s', $dependency->Name, $dependency->Version, $out_path)); + + if(!$filesystem->exists($lib_path)) + $filesystem->mkdir($lib_path); + $filesystem->copy($version->Location, $out_path); $dependency->Source = 'libs' . DIRECTORY_SEPARATOR . sprintf('%s=%s.lib', $dependency->Name, $dependency->Version); -- 2.45.3 From b3a75958e253f6b421c3a58bb825dc7f78e3f60b Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 31 Dec 2022 06:17:24 -0500 Subject: [PATCH 137/212] Moved BuildConfiguration --- src/installer/extension | 10 +++++----- .../ComposerExtension/ComposerSourceBuiltin.php | 2 +- src/ncc/Managers/ProjectManager.php | 4 ++-- src/ncc/Objects/ProjectConfiguration.php | 2 +- src/ncc/Objects/ProjectConfiguration/Build.php | 1 + .../{ => Build}/BuildConfiguration.php | 3 ++- 6 files changed, 12 insertions(+), 10 deletions(-) rename src/ncc/Objects/ProjectConfiguration/{ => Build}/BuildConfiguration.php (98%) diff --git a/src/installer/extension b/src/installer/extension index bbdcffa..64b76f4 100644 --- a/src/installer/extension +++ b/src/installer/extension @@ -4,11 +4,11 @@ use ncc\Exceptions\ConstantReadonlyException; use ncc\Exceptions\ImportException; use ncc\Exceptions\InvalidConstantNameException; -use ncc\Exceptions\InvalidPackageNameException; -use ncc\Exceptions\InvalidScopeException; -use ncc\Exceptions\PackageLockException; -use ncc\Exceptions\PackageNotFoundException; -use ncc\ncc; + use ncc\Exceptions\InvalidPackageNameException; + use ncc\Exceptions\InvalidScopeException; + use ncc\Exceptions\PackageLockException; + use ncc\Exceptions\PackageNotFoundException; + use ncc\ncc; use ncc\Runtime; if(!defined('NCC_INIT')) diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index a210837..55da655 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -333,7 +333,7 @@ } // Create a build configuration - $build_configuration = new ProjectConfiguration\BuildConfiguration(); + $build_configuration = new ProjectConfiguration\Build\BuildConfiguration(); $build_configuration->Name = 'default'; $build_configuration->OutputPath = 'build'; diff --git a/src/ncc/Managers/ProjectManager.php b/src/ncc/Managers/ProjectManager.php index 286910b..a9187b5 100644 --- a/src/ncc/Managers/ProjectManager.php +++ b/src/ncc/Managers/ProjectManager.php @@ -140,12 +140,12 @@ $this->ProjectConfiguration->Build->DefineConstants['ASSEMBLY_UID'] = '%ASSEMBLY.UID%'; // Generate configurations - $DebugConfiguration = new ProjectConfiguration\BuildConfiguration(); + $DebugConfiguration = new ProjectConfiguration\Build\BuildConfiguration(); $DebugConfiguration->Name = 'debug'; $DebugConfiguration->OutputPath = 'build/debug'; $DebugConfiguration->DefineConstants["DEBUG"] = '1'; // Debugging constant if the program wishes to check for this $this->ProjectConfiguration->Build->Configurations[] = $DebugConfiguration; - $ReleaseConfiguration = new ProjectConfiguration\BuildConfiguration(); + $ReleaseConfiguration = new ProjectConfiguration\Build\BuildConfiguration(); $ReleaseConfiguration->Name = 'release'; $ReleaseConfiguration->OutputPath = 'build/release'; $ReleaseConfiguration->DefineConstants["DEBUG"] = '0'; // Debugging constant if the program wishes to check for this diff --git a/src/ncc/Objects/ProjectConfiguration.php b/src/ncc/Objects/ProjectConfiguration.php index a0e4c83..216091f 100644 --- a/src/ncc/Objects/ProjectConfiguration.php +++ b/src/ncc/Objects/ProjectConfiguration.php @@ -21,7 +21,7 @@ use ncc\Exceptions\UnsupportedExtensionVersionException; use ncc\Objects\ProjectConfiguration\Assembly; use ncc\Objects\ProjectConfiguration\Build; - use ncc\Objects\ProjectConfiguration\BuildConfiguration; + use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; use ncc\Objects\ProjectConfiguration\Installer; use ncc\Objects\ProjectConfiguration\Project; diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index aea3594..797ab55 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -9,6 +9,7 @@ use ncc\Exceptions\InvalidBuildConfigurationException; use ncc\Exceptions\InvalidConstantNameException; use ncc\Exceptions\InvalidProjectBuildConfiguration; + use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration; use ncc\Utilities\Functions; use ncc\Utilities\Validate; diff --git a/src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php b/src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php similarity index 98% rename from src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php rename to src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php index 3d228db..8653268 100644 --- a/src/ncc/Objects/ProjectConfiguration/BuildConfiguration.php +++ b/src/ncc/Objects/ProjectConfiguration/Build/BuildConfiguration.php @@ -2,10 +2,11 @@ /** @noinspection PhpMissingFieldTypeInspection */ - namespace ncc\Objects\ProjectConfiguration; + namespace ncc\Objects\ProjectConfiguration\Build; use ncc\Exceptions\InvalidBuildConfigurationException; use ncc\Exceptions\InvalidDependencyConfiguration; + use ncc\Objects\ProjectConfiguration\Dependency; use ncc\Utilities\Functions; use ncc\Utilities\Validate; -- 2.45.3 From 17b5a73b652f866ff207b883676a58bdfcf10294 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 31 Dec 2022 08:53:14 -0500 Subject: [PATCH 138/212] Added property 'CreateSymlink' to \ncc\Objects\ProjectConfiguration > Build --- src/ncc/Objects/ProjectConfiguration/Build.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index 797ab55..6f095f3 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -61,6 +61,14 @@ */ public $Main; + /** + * If Main is not null, and this is true. + * NCC Will create a symlink to the main executable in the installation directory. + * + * @var bool + */ + public $CreateSymlink; + /** * An array of constants to define by default * @@ -106,6 +114,7 @@ $this->DefineConstants = []; $this->Dependencies = []; $this->Configurations = []; + $this->CreateSymlink = false; } /** @@ -277,7 +286,10 @@ if($this->Scope !== null) $ReturnResults[($bytecode ? Functions::cbc('scope') : 'scope')] = $this->Scope; if($this->Main !== null) - $ReturnResults[($bytecode ? Functions::cbc('main') : 'main')] = $this->Main; + { + $ReturnResults[($bytecode ? Functions::cbc('main') : 'main')] = $this->Main; + $ReturnResults[($bytecode ? Functions::cbc('create_symlink') : 'create_symlink')] = $this->CreateSymlink; + } if($this->DefineConstants !== null && count($this->DefineConstants) > 0) $ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants; if($this->PreBuild !== null && count($this->PreBuild) > 0) @@ -322,6 +334,7 @@ $BuildObject->Options = (Functions::array_bc($data, 'options') ?? []); $BuildObject->Scope = Functions::array_bc($data, 'scope'); $BuildObject->Main = Functions::array_bc($data, 'main'); + $BuildObject->CreateSymlink = (Functions::array_bc($data, 'create_symlink') ?? false); $BuildObject->DefineConstants = (Functions::array_bc($data, 'define_constants') ?? []); $BuildObject->PreBuild = (Functions::array_bc($data, 'pre_build') ?? []); $BuildObject->PostBuild = (Functions::array_bc($data, 'post_build') ?? []); -- 2.45.3 From f0946c6827a614e16ca0169226b92d78dd0a3d2f Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 31 Dec 2022 09:00:14 -0500 Subject: [PATCH 139/212] Added CODE_OF_CONDUCT.md --- CODE_OF_CONDUCT.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f7a58e1 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,36 @@ + +# Code of Conduct + +We are committed to maintaining a welcoming and inclusive environment for all contributors. In order to ensure that +everyone feels safe and respected, we have established the following code of conduct. + +## Our Standards + +We expect all contributors to: + +- Be respectful and considerate of others +- Use inclusive language +- Avoid demeaning, discriminatory, or harassing behavior +- Respect the boundaries of others + +We will not tolerate any behavior that does not align with these standards. + +## Consequences of Unacceptable Behavior + +Unacceptable behavior will not be tolerated and may result in consequences such as warning, blocking of access, or +permanent removal from the project. + +## Reporting Unacceptable Behavior + +If you witness or experience any behavior that is not aligned with our code of conduct, please report it immediately by +contacting the project maintainers. You can open an issue on the project's repository at [https://git.n64.cc/nosial/ncc](https://git.n64.cc/nosial/ncc). + +## Attribution + +This Code of Conduct is adapted from the Contributor Covenant, version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html](https://www.contributor-covenant.org/version/2/0/code_of_conduct.html). + +## License + +This Code of Conduct is licensed under the Creative Commons Attribution 4.0 International License. To view a copy of +this license, visit [http://creativecommons.org/licenses/by/4.0/](http://creativecommons.org/licenses/by/4.0/). -- 2.45.3 From 4f5c706dd9446fff803a8c9cf191d95bbd4e986c Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 31 Dec 2022 09:00:21 -0500 Subject: [PATCH 140/212] Added CONTRIBUTING.md --- CONTRIBUTING.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2cd7c78 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing to NCC + +We welcome contributions to NCC! If you have an idea for how to improve the project, please don't hesitate to reach out. +There are many ways to contribute, and we appreciate all forms of support. + +## How to Contribute + +- **Report a bug**: If you think you have found a bug in NCC, please open an issue and include as much detail as + possible to help us reproduce and fix the issue. +- **Request a feature**: Have an idea for a new feature or improvement? Open an issue to start a discussion. +- **Submit a pull request**: If you have developed a fix for a bug or have implemented a new feature, please submit a + pull request for review. + +## Code of Conduct + +We are committed to maintaining a welcoming and inclusive environment for all contributors. Please read and follow our +[Code of Conduct](https://git.n64.cc/nosial/ncc/CODE_OF_CONDUCT.md). + +## License + +By contributing to NCC, you agree that your contributions will be licensed under the MIT License. + +## Attribution + +NCC is Copyright (c) Nosial. Please include the copyright notice in any distributed code. -- 2.45.3 From 3dcc5ee9898e777d9a9b058edd556bee7b9dac3d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 31 Dec 2022 09:07:12 -0500 Subject: [PATCH 141/212] Updated changelog --- changelog/v1.0.0_alpha.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/changelog/v1.0.0_alpha.md b/changelog/v1.0.0_alpha.md index 1ccc539..814a5f0 100644 --- a/changelog/v1.0.0_alpha.md +++ b/changelog/v1.0.0_alpha.md @@ -2,13 +2,17 @@ First release of NCC (Nosial Code Compiler) in alpha stage. -## Note +## Alpha Stage -NCC is in it's alpha stage, meaning that it's not fully +NCC is in its alpha stage, meaning that it's not fully functional and may not work on your system. If you find any bugs or issues please report them to the [Issue Tracker](https://git.n64.cc/intellivoid/ncc/issues). At the moment NCC is currently being used while developing other software, this serves as a test run to improve on -changes for the next version. \ No newline at end of file +changes for the next version. + +## Changelog + + - Initial release \ No newline at end of file -- 2.45.3 From 39d98f8ff36e9777801f7cce1e99075a3372cd0b Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 31 Dec 2022 09:07:19 -0500 Subject: [PATCH 142/212] Updated README.md --- README.md | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 4d02c30..9e9d0cf 100644 --- a/README.md +++ b/README.md @@ -12,25 +12,41 @@ or issues please report them to the [GitHub Issue Tracker](https://git.n64.cc/in At the moment NCC is currently being used while developing other software, this serves as a test run to improve on changes for the next version. -### Notes +### Version History - > Compiler extensions requires their own set of dependencies to be met, for example Java compilers will require JDK + - 1.0.0 Alpha - Initial release ([changelog](changelog/v1.0.0_alpha.md)) - > NCC is designed to run only on a PHP 8.0+ environment, compiler extensions can have support for different PHP versions. - - > Third-party dependencies and included libraries has a dedicated namespace for `ncc` to avoid user land conflicts if - > the user wishes to install and use one of the same dependencies that NCC uses. ## Authors + - Zi Xing Narrakas (netkas) <[netkas@n64.cc](mailto:netkas@64.cc)> + ## Special Thanks + - Marc Gutt (mgutt) <[marc@gutt.it](mailto:marc@gutt.it)> - Debusschère Alexandre ([debuss](https://github.com/debuss)) + ## Copyright + - Copyright (c) 2022-2022, Nosial - All Rights Reserved + +## Contributing + +We welcome contributions to NCC! If you have an idea for how to improve the project, please don't hesitate to reach out. +There are many ways to contribute, and we appreciate all forms of support. + +For more information on how to contribute, please read the [CONTRIBUTING.md](CONTRIBUTING.md) file. + + +## Code of Conduct + +We are committed to maintaining a welcoming and inclusive environment for all contributors. Please read and follow our +[Code of Conduct](CODE_OF_CONDUCT.md). + + # Licenses NCC is licensed under the MIT License, see [LICENSE](LICENSE) for more information. -- 2.45.3 From 7c2735ce1b53752783697cb614be3278d0ed6fd3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 16:20:32 -0500 Subject: [PATCH 143/212] Added Logging calls to \ncc\Managers > ConfigurationManager --- src/ncc/Managers/ConfigurationManager.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ncc/Managers/ConfigurationManager.php b/src/ncc/Managers/ConfigurationManager.php index 7df457e..8dd2b50 100644 --- a/src/ncc/Managers/ConfigurationManager.php +++ b/src/ncc/Managers/ConfigurationManager.php @@ -5,7 +5,6 @@ namespace ncc\Managers; use Exception; - use ncc\Abstracts\LogLevel; use ncc\Abstracts\Scopes; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; @@ -50,6 +49,8 @@ */ public function load(): void { + Console::outDebug(sprintf('loading configuration file from %s', PathFinder::getConfigurationFile())); + $this->Configuration = RuntimeCache::get('ncc.yaml'); if($this->Configuration !== null) return; @@ -68,6 +69,8 @@ */ public function save(): void { + Console::outDebug(sprintf('saving configuration file to %s', PathFinder::getConfigurationFile())); + if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Cannot save configuration file, insufficient permissions'); @@ -89,6 +92,8 @@ */ public function getProperty(string $property) { + Console::outDebug(sprintf('getting property %s', $property)); + Console::outDebug($property); $current_selection = $this->getConfiguration(); foreach(explode('.', strtolower($property)) as $property) @@ -121,6 +126,8 @@ */ public function updateProperty(string $property, $value): bool { + Console::outDebug(sprintf('updating property %s', $property)); + $keys = explode('.', $property); $current = &$this->Configuration; foreach ($keys as $k) -- 2.45.3 From f311e60e8f9c8353b944cc6a51c69a6623ebe1b0 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 16:21:19 -0500 Subject: [PATCH 144/212] Added Logging calls to \ncc\Managers > CredentialManager --- src/ncc/Managers/CredentialManager.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ncc/Managers/CredentialManager.php b/src/ncc/Managers/CredentialManager.php index d90bcc1..d17eba1 100644 --- a/src/ncc/Managers/CredentialManager.php +++ b/src/ncc/Managers/CredentialManager.php @@ -12,6 +12,7 @@ use ncc\Exceptions\IOException; use ncc\Exceptions\RuntimeException; use ncc\Objects\Vault; + use ncc\Utilities\Console; use ncc\Utilities\IO; use ncc\Utilities\PathFinder; use ncc\Utilities\Resolver; @@ -61,6 +62,8 @@ */ public function constructStore(): void { + Console::outDebug(sprintf('constructing credentials store at %s', $this->CredentialsPath)); + // Do not continue the function if the file already exists, if the file is damaged a separate function // is to be executed to fix the damaged file. if(file_exists($this->CredentialsPath)) @@ -86,6 +89,8 @@ */ private function loadVault(): void { + Console::outDebug(sprintf('loading credentials store from %s', $this->CredentialsPath)); + if($this->Vault !== null) return; @@ -114,6 +119,8 @@ */ public function saveVault(): void { + Console::outDebug(sprintf('saving credentials store to %s', $this->CredentialsPath)); + if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Cannot save credentials store without system permissions'); -- 2.45.3 From 3055547452f8d7fa7ffd3aec0f92e3157a4da826 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 16:49:15 -0500 Subject: [PATCH 145/212] Deleted LICENSES since all the same licenses are already present in the project source. --- LICENSES | 346 ------------------------------------------------------- 1 file changed, 346 deletions(-) delete mode 100644 LICENSES diff --git a/LICENSES b/LICENSES deleted file mode 100644 index 6a475e7..0000000 --- a/LICENSES +++ /dev/null @@ -1,346 +0,0 @@ -Symfony - Process - -Copyright (c) 2004-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------------------- -defuse - php-encryption - -The MIT License (MIT) - -Copyright (c) 2016 Taylor Hornby -Copyright (c) 2016 Paragon Initiative Enterprises . - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ------------------------- -Symfony - uid - -Copyright (c) 2020-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - polyfill-mbstring - -Copyright (c) 2015-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - polyfill-ctype - -Copyright (c) 2018-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - polyfill-uuid - -Copyright (c) 2018-2019 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - - ------------------------- -dealnews.com, Inc. - Inline ProgressBar CLI - -Copyright (c) 2010, dealnews.com, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of dealnews.com, Inc. nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -Symfony - Filesystem - -Copyright (c) 2004-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - - ------------------------- -Symfony - Yaml - -Copyright (c) 2004-2022 Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------------------- -theseer - Autoload - -Autoload Builder - -Copyright (c) 2010-2016 Arne Blankerts and Contributors -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Arne Blankerts nor the names of contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -theseer - DirectoryScanner - -DirectoryScanner - -Copyright (c) 2009-2014 Arne Blankerts -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of Arne Blankerts nor the names of contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, -OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -nikic - PhpParser - -BSD 3-Clause License - -Copyright (c) 2011, Nikita Popov -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - ------------------------- -jelix - version - -Copyright (C) 2009-2016 Laurent Jouanneau - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file -- 2.45.3 From 59277226b93a7f95e6d7fb9ebe67332e6361a285 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 16:54:29 -0500 Subject: [PATCH 146/212] Added dependency php-parallel-lint\php-console-color --- .gitignore | 1 + Makefile | 6 + .../php_console_color/CHANGELOG.md | 93 ++++++ .../php_console_color/ConsoleColor.php | 295 ++++++++++++++++++ .../InvalidStyleException.php | 11 + .../php_console_color/LICENSE | 27 ++ .../php_console_color/README.md | 19 ++ .../php_console_color/VERSION | 1 + 8 files changed, 453 insertions(+) create mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md create mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php create mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php create mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/LICENSE create mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/README.md create mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/VERSION diff --git a/.gitignore b/.gitignore index 570cd0f..4e93986 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ build src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php src/ncc/ThirdParty/jelix/version/autoload_spl.php src/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php +src/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php src/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php src/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php src/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php diff --git a/Makefile b/Makefile index f5eaa17..f360276 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ autoload: make $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/jelix/version/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/nikic/php-parser/autoload_spl.php + make $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php @@ -32,6 +33,10 @@ $(SRC_PATH)/ncc/ThirdParty/nikic/php-parser/autoload_spl.php: $(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php \ $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser +$(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php: + $(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php \ + $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color + $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php: $(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php \ $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype @@ -109,6 +114,7 @@ clean: rm -f $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/jelix/version/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php + rm -f $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php diff --git a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md new file mode 100644 index 0000000..4093b4d --- /dev/null +++ b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md @@ -0,0 +1,93 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [Unreleased] + +_Nothing yet._ + + +## [1.0.1] - 2021-12-25 + +### Changed + +- Support for PHP 5.3 has been restored, [#22] from [@jrfnl]. + +### Internal +- Welcome [@jrfnl] as new co-maintainer. +- Improvements to the test suite, [#14], [#16], [#19], [#23], [#24] from [@jrfnl]. +- Improvements to the code consistency, [#13], [#23], [#25] from [@jrfnl]. +- Improvements to the CI/QA setup, [#12], [#17], [#18], [#20], [#27], [#28] from [@jrfnl]. +- Improvements to the changelog, [#21] from [@jrfnl]. + +[#12]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/12 +[#13]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/13 +[#14]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/14 +[#16]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/16 +[#17]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/17 +[#18]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/18 +[#19]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/19 +[#20]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/20 +[#21]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/21 +[#22]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/22 +[#23]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/23 +[#24]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/24 +[#25]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/25 +[#27]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/27 +[#28]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/28 + + +## [1.0] - 2020-10-31 + +### Changed + +- BC-Break: The top-level namespace for all classes has changed from `JakubOnderka` to `PHP_Parallel_Lint`. [#10] from [@grogy]. + +### Added + +- Added downloading per month badge from [@grogy]. +- Added license badge from [@grogy]. +- Added instruction for installation from [@grogy]. +- Composer: add description [#11] from [@jrfnl]. + +### Internal + +- Updated PHP Parallel Lint dependency version restraint [#8] from [@jrfnl]. +- Travis: changed from "trusty" to "xenial" [#7] from [@jrfnl]. +- Update the unit tests setup [#9] from [@jrfnl]. + +[#7]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/7 +[#8]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/8 +[#9]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/9 +[#10]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/10 +[#11]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/11 + + +## [0.3] - 2020-05-14 + +### Added + +- Added changelog from [@reedy]. + +### Internal + +- Travis: test against PHP 7.3 from [@samnela]. +- Cleaned readme - new organization from previous package from [@grogy]. +- Composer: updated dependancies to use new php-parallel-lint organisation from [@grogy]. +- Composer: marked package as replacing jakub-onderka/php-console-color from [@jrfnl]. +- Added a .gitattributes file from [@reedy]. +- Travis: test against PHP 7.4 and nightly from [@jrfnl]. +- Travis: only run PHPCS on PHP 7.4 from [@jrfnl]. + + +[Unreleased]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v1.0.1...HEAD +[1.0.1]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v1.0...v1.0.1 +[1.0]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v0.3...v1.0 +[0.3]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v0.2...v0.3 + +[@grogy]: https://github.com/grogy +[@jrfnl]: https://github.com/jrfnl +[@reedy]: https://github.com/reedy +[@samnela]: https://github.com/samnela diff --git a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php new file mode 100644 index 0000000..4cdcb08 --- /dev/null +++ b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php @@ -0,0 +1,295 @@ + null, + 'bold' => '1', + 'dark' => '2', + 'italic' => '3', + 'underline' => '4', + 'blink' => '5', + 'reverse' => '7', + 'concealed' => '8', + + 'default' => '39', + 'black' => '30', + 'red' => '31', + 'green' => '32', + 'yellow' => '33', + 'blue' => '34', + 'magenta' => '35', + 'cyan' => '36', + 'light_gray' => '37', + + 'dark_gray' => '90', + 'light_red' => '91', + 'light_green' => '92', + 'light_yellow' => '93', + 'light_blue' => '94', + 'light_magenta' => '95', + 'light_cyan' => '96', + 'white' => '97', + + 'bg_default' => '49', + 'bg_black' => '40', + 'bg_red' => '41', + 'bg_green' => '42', + 'bg_yellow' => '43', + 'bg_blue' => '44', + 'bg_magenta' => '45', + 'bg_cyan' => '46', + 'bg_light_gray' => '47', + + 'bg_dark_gray' => '100', + 'bg_light_red' => '101', + 'bg_light_green' => '102', + 'bg_light_yellow' => '103', + 'bg_light_blue' => '104', + 'bg_light_magenta' => '105', + 'bg_light_cyan' => '106', + 'bg_white' => '107', + ); + + /** @var array */ + private $themes = array(); + + public function __construct() + { + $this->isSupported = $this->isSupported(); + } + + /** + * @param string|array $style + * @param string $text + * @return string + * @throws InvalidStyleException + * @throws \InvalidArgumentException + */ + public function apply($style, $text) + { + if (!$this->isStyleForced() && !$this->isSupported()) { + return $text; + } + + if (is_string($style)) { + $style = array($style); + } + if (!is_array($style)) { + throw new \InvalidArgumentException("Style must be string or array."); + } + + $sequences = array(); + + foreach ($style as $s) { + if (isset($this->themes[$s])) { + $sequences = array_merge($sequences, $this->themeSequence($s)); + } elseif ($this->isValidStyle($s)) { + $sequences[] = $this->styleSequence($s); + } else { + throw new InvalidStyleException($s); + } + } + + $sequences = array_filter($sequences, function ($val) { + return $val !== null; + }); + + if (empty($sequences)) { + return $text; + } + + return $this->escSequence(implode(';', $sequences)) . $text . $this->escSequence(self::RESET_STYLE); + } + + /** + * @param bool $forceStyle + */ + public function setForceStyle($forceStyle) + { + $this->forceStyle = (bool) $forceStyle; + } + + /** + * @return bool + */ + public function isStyleForced() + { + return $this->forceStyle; + } + + /** + * @param array $themes + * @throws InvalidStyleException + * @throws \InvalidArgumentException + */ + public function setThemes(array $themes) + { + $this->themes = array(); + foreach ($themes as $name => $styles) { + $this->addTheme($name, $styles); + } + } + + /** + * @param string $name + * @param array|string $styles + * @throws \InvalidArgumentException + * @throws InvalidStyleException + */ + public function addTheme($name, $styles) + { + if (is_string($styles)) { + $styles = array($styles); + } + if (!is_array($styles)) { + throw new \InvalidArgumentException("Style must be string or array."); + } + + foreach ($styles as $style) { + if (!$this->isValidStyle($style)) { + throw new InvalidStyleException($style); + } + } + + $this->themes[$name] = $styles; + } + + /** + * @return array + */ + public function getThemes() + { + return $this->themes; + } + + /** + * @param string $name + * @return bool + */ + public function hasTheme($name) + { + return isset($this->themes[$name]); + } + + /** + * @param string $name + */ + public function removeTheme($name) + { + unset($this->themes[$name]); + } + + /** + * @codeCoverageIgnore + * + * @return bool + */ + public function isSupported() + { + if (DIRECTORY_SEPARATOR === '\\') { + // phpcs:ignore Generic.PHP.NoSilencedErrors,PHPCompatibility.FunctionUse.NewFunctions.sapi_windows_vt100_supportFound + if (function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT)) { + return true; + } elseif (getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON') { + return true; + } + return false; + } else { + // phpcs:ignore Generic.PHP.NoSilencedErrors + return function_exists('posix_isatty') && @posix_isatty(STDOUT); + } + } + + /** + * @codeCoverageIgnore + * + * @return bool + */ + public function are256ColorsSupported() + { + if (DIRECTORY_SEPARATOR === '\\') { + // phpcs:ignore Generic.PHP.NoSilencedErrors,PHPCompatibility.FunctionUse.NewFunctions.sapi_windows_vt100_supportFound + return function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT); + } else { + return strpos(getenv('TERM'), '256color') !== false; + } + } + + /** + * @return array + */ + public function getPossibleStyles() + { + return array_keys($this->styles); + } + + /** + * @param string $name + * @return string[] + */ + private function themeSequence($name) + { + $sequences = array(); + foreach ($this->themes[$name] as $style) { + $sequences[] = $this->styleSequence($style); + } + return $sequences; + } + + /** + * @param string $style + * @return string + */ + private function styleSequence($style) + { + if (array_key_exists($style, $this->styles)) { + return $this->styles[$style]; + } + + if (!$this->are256ColorsSupported()) { + return null; + } + + preg_match(self::COLOR256_REGEXP, $style, $matches); + + $type = $matches[1] === 'bg_' ? self::BACKGROUND : self::FOREGROUND; + $value = $matches[2]; + + return "$type;5;$value"; + } + + /** + * @param string $style + * @return bool + */ + private function isValidStyle($style) + { + return array_key_exists($style, $this->styles) || preg_match(self::COLOR256_REGEXP, $style); + } + + /** + * @param string|int $value + * @return string + */ + private function escSequence($value) + { + return "\033[{$value}m"; + } +} diff --git a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php new file mode 100644 index 0000000..6bb0336 --- /dev/null +++ b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php @@ -0,0 +1,11 @@ + Date: Mon, 2 Jan 2023 16:56:26 -0500 Subject: [PATCH 147/212] Oops. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f360276..97dd9bb 100644 --- a/Makefile +++ b/Makefile @@ -114,7 +114,7 @@ clean: rm -f $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/jelix/version/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php - rm -f $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color + rm -f $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php -- 2.45.3 From e878ce4ff995121172e049dcd4481833149e997e Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 19:42:40 -0500 Subject: [PATCH 148/212] Added Logging calls to \ncc\Managers > ExecutionPointerManager --- src/ncc/Managers/ExecutionPointerManager.php | 42 +++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 765b5dc..0132fb8 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -84,10 +84,13 @@ if(count($this->TemporaryUnits) == 0) return; + Console::outVerbose('Cleaning temporary units...'); + try { foreach($this->TemporaryUnits as $datum) { + Console::outDebug(sprintf('deleting unit %s=%s.%s', $datum['package'], $datum['version'], $datum['name'])); $this->removeUnit($datum['package'], $datum['version'], $datum['name']); } } @@ -122,16 +125,23 @@ * @throws IOException * @throws UnsupportedRunnerException * @noinspection PhpUnused + * @noinspection DuplicatedCode */ public function addUnit(string $package, string $version, ExecutionUnit $unit, bool $temporary=false): void { if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Cannot add new ExecutionUnit \'' . $unit->ExecutionPolicy->Name .'\' for ' . $package . ', insufficient permissions'); + Console::outVerbose(sprintf('Adding new ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package)); + $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; + Console::outDebug(sprintf('package_id=%s', $package_id)); + Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); + Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); + $filesystem = new Filesystem(); // Either load or create the pointers file @@ -156,6 +166,8 @@ default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; + Console::outDebug(sprintf('bin_file=%s', $bin_file)); + if($filesystem->exists($bin_file) && $temporary) return; @@ -189,16 +201,23 @@ * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException + * @noinspection DuplicatedCode */ public function removeUnit(string $package, string $version, string $name): bool { if(Resolver::resolveScope() !== Scopes::System) throw new AccessDeniedException('Cannot remove ExecutionUnit \'' . $name .'\' for ' . $package . ', insufficient permissions'); + Console::outVerbose(sprintf('Removing ExecutionUnit \'%s\' for %s', $name, $package)); + $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; + Console::outDebug(sprintf('package_id=%s', $package_id)); + Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); + Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); + $filesystem = new Filesystem(); if(!$filesystem->exists($package_config_path)) return false; @@ -237,6 +256,8 @@ */ public function getUnits(string $package, string $version): array { + Console::outVerbose(sprintf('getting execution units for %s', $package)); + $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; @@ -247,6 +268,7 @@ $results = []; foreach($execution_pointers->getPointers() as $pointer) { + Console::outDebug(sprintf('unit %s', $pointer->ExecutionPolicy->Name)); $results[] = $pointer->ExecutionPolicy->Name; } @@ -270,6 +292,8 @@ */ public function executeUnit(string $package, string $version, string $name): void { + Console::outVerbose(sprintf('executing unit %s for %s', $name, $package)); + $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; @@ -282,6 +306,10 @@ if($unit == null) throw new ExecutionUnitNotFoundException('The execution unit \'' . $name . '\' was not found for \'' . $package . '=' .$version .'\''); + Console::outDebug(sprintf('unit=%s', $unit->ExecutionPolicy->Name)); + Console::outDebug(sprintf('runner=%s', $unit->ExecutionPolicy->Runner)); + Console::outDebug(sprintf('file=%s', $unit->FilePointer)); + $process = match (strtolower($unit->ExecutionPolicy->Runner)) { Runners::bash => BashRunner::prepareProcess($unit), @@ -289,7 +317,7 @@ Runners::perl => PerlRunner::prepareProcess($unit), Runners::python => PythonRunner::prepareProcess($unit), Runners::python2 => Python2Runner::prepareProcess($unit), - Runners::python3 => Python3Runner::prepareProcess($unt), + Runners::python3 => Python3Runner::prepareProcess($unit), Runners::lua => LuaRunner::prepareProcess($unit), default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; @@ -314,12 +342,18 @@ $process->enableOutput(); } + Console::outDebug(sprintf('working_directory=%s', $process->getWorkingDirectory())); + Console::outDebug(sprintf('timeout=%s', ($process->getTimeout() ?? 0))); + Console::outDebug(sprintf('silent=%s', ($unit->ExecutionPolicy->Execute->Silent ? 'true' : 'false'))); + Console::outDebug(sprintf('tty=%s', ($unit->ExecutionPolicy->Execute->Tty ? 'true' : 'false'))); + try { if($unit->ExecutionPolicy->Message !== null) Console::out($unit->ExecutionPolicy->Message); - $process->run(function ($type, $buffer) { + $process->run(function ($type, $buffer) + { Console::out($buffer); }); @@ -331,6 +365,8 @@ $this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Error); } + Console::outDebug(sprintf('exit_code=%s', $process->getExitCode())); + if($unit->ExecutionPolicy->ExitHandlers !== null) { if($process->isSuccessful() && $unit->ExecutionPolicy->ExitHandlers->Success !== null) @@ -428,11 +464,13 @@ } elseif($exitHandle->EndProcess) { + Console::outDebug(sprintf('exit_code=%s', $process->getExitCode())); exit($exitHandle->ExitCode); } if($exitHandle->Run !== null) { + Console::outVerbose('Running unit \'' . $exitHandle->Run . '\''); $this->executeUnit($package, $version, $exitHandle->Run); } -- 2.45.3 From 0281ba2af4188a29cfe50c0723c483a65a2ad8cb Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 19:46:15 -0500 Subject: [PATCH 149/212] Added Logging calls to \ncc\Managers > PackageLockManager --- src/ncc/Objects/PackageLock.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php index b79bc49..0655682 100644 --- a/src/ncc/Objects/PackageLock.php +++ b/src/ncc/Objects/PackageLock.php @@ -5,8 +5,11 @@ namespace ncc\Objects; use ncc\Abstracts\Versions; + use ncc\Exceptions\InvalidPackageNameException; + use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\VersionNotFoundException; use ncc\Objects\PackageLock\PackageEntry; + use ncc\Utilities\Console; use ncc\Utilities\Functions; class PackageLock @@ -56,9 +59,13 @@ * @param Package $package * @param string $install_path * @return void + * @throws InvalidPackageNameException + * @throws InvalidScopeException */ public function addPackage(Package $package, string $install_path): void { + Console::outVerbose("Adding package {$package->Assembly->Package} to package lock file"); + if(!isset($this->Packages[$package->Assembly->Package])) { $package_entry = new PackageEntry(); @@ -88,6 +95,8 @@ */ public function removePackageVersion(string $package, string $version): bool { + Console::outVerbose(sprintf('Removing package %s version %s from package lock file', $package, $version)); + if(isset($this->Packages[$package])) { $r = $this->Packages[$package]->removeVersion($version); @@ -110,9 +119,11 @@ * * @param string $package * @return bool + * @noinspection PhpUnused */ public function removePackage(string $package): bool { + Console::outVerbose(sprintf('Removing package %s from package lock file', $package)); if(isset($this->Packages[$package])) { unset($this->Packages[$package]); @@ -130,6 +141,8 @@ */ public function getPackage(string $package): ?PackageEntry { + Console::outDebug(sprintf('getting package %s from package lock file', $package)); + if(isset($this->Packages[$package])) { return $this->Packages[$package]; -- 2.45.3 From a995732ff7d18a7529dbc92670ff121585eb13d4 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 19:50:19 -0500 Subject: [PATCH 150/212] Improved logging in \ncc\Classes > GitClient --- src/ncc/Classes/GitClient.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/ncc/Classes/GitClient.php b/src/ncc/Classes/GitClient.php index c7daca4..cef173d 100644 --- a/src/ncc/Classes/GitClient.php +++ b/src/ncc/Classes/GitClient.php @@ -22,6 +22,7 @@ */ public static function cloneRepository(string $url): string { + Console::outVerbose('Cloning repository: ' . $url); $path = Functions::getTmpDir(); $process = new Process(["git", "clone", $url, $path]); $process->setTimeout(3600); // 1 hour @@ -33,7 +34,8 @@ if (!$process->isSuccessful()) throw new GitCloneException($process->getErrorOutput()); - Console::outVerbose('Repository cloned to ' . $path); + Console::outVerbose('Repository cloned to: ' . $path); + return $path; } @@ -46,6 +48,7 @@ */ public static function checkout(string $path, string $branch) { + Console::outVerbose('Checking out branch' . $branch); $process = new Process(["git", "checkout", $branch], $path); $process->setTimeout(3600); // 1 hour $process->run(function ($type, $buffer) @@ -63,7 +66,7 @@ if (!$process->isSuccessful()) throw new GitCheckoutException($process->getErrorOutput()); - Console::outVerbose('Checked out branch ' . $branch); + Console::outVerbose('Checked out branch: ' . $branch); } /** @@ -75,6 +78,7 @@ */ public static function getTags(string $path): array { + Console::outVerbose('Getting tags for repository: ' . $path); $process = new Process(["git", "fetch", '--all', '--tags'] , $path); $process->setTimeout(3600); // 1 hour $process->run(function ($type, $buffer) @@ -96,6 +100,12 @@ throw new GitTagsException($process->getErrorOutput()); $tags = explode(PHP_EOL, $process->getOutput()); + $tags = array_filter($tags, function ($tag) + { + return !empty($tag); + }); + + Console::outDebug('found ' . count($tags) . ' tags'); return array_filter($tags); } -- 2.45.3 From 5d9f02512f044cb955db5c1a7c18a53b8e26b4b1 Mon Sep 17 00:00:00 2001 From: Netkas Date: Mon, 2 Jan 2023 19:57:28 -0500 Subject: [PATCH 151/212] Added Logging calls to \ncc\Managers > PackageManager --- src/ncc/Managers/PackageManager.php | 74 +++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 7345d00..0475a4d 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -22,6 +22,7 @@ use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\InstallationException; + use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; use ncc\Exceptions\MissingDependencyException; @@ -89,6 +90,7 @@ * @throws FileNotFoundException * @throws IOException * @throws InstallationException + * @throws InvalidScopeException * @throws MissingDependencyException * @throws NotImplementedException * @throws PackageAlreadyInstalledException @@ -98,6 +100,7 @@ * @throws UnsupportedCompilerExtensionException * @throws UnsupportedRunnerException * @throws VersionNotFoundException + * @throws InvalidPackageNameException */ public function install(string $package_path, ?Entry $entry=null, array $options=[]): string { @@ -393,9 +396,12 @@ if($input->Version == null) $input->Version = Versions::Latest; + Console::outVerbose('Fetching package ' . $input->Package . ' from ' . $input->Source . ' (' . $input->Version . ')'); + $remote_source_type = Resolver::detectRemoteSourceType($input->Source); if($remote_source_type == RemoteSourceType::Builtin) { + Console::outDebug('using builtin source ' . $input->Source); switch($input->Source) { case BuiltinRemoteSourceType::Composer: @@ -415,6 +421,7 @@ if($remote_source_type == RemoteSourceType::Defined) { + Console::outDebug('using defined source ' . $input->Source); $remote_source_manager = new RemoteSourcesManager(); $source = $remote_source_manager->getRemoteSource($input->Source); if($source == null) @@ -427,11 +434,13 @@ { try { + Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->ZipballUrl)); $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->ZipballUrl, $entry); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); } catch(Throwable $e) { + Console::outDebug('cannot fetch package from zipball url, ' . $e->getMessage()); $exceptions[] = $e; } } @@ -440,11 +449,13 @@ { try { + Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->TarballUrl)); $archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->TarballUrl, $entry); return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version); } catch(Exception $e) { + Console::outDebug('cannot fetch package from tarball url, ' . $e->getMessage()); $exceptions[] = $e; } } @@ -453,10 +464,12 @@ { try { + Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->PackageUrl)); return Functions::downloadGitServiceFile($repositoryQueryResults->Files->PackageUrl, $entry); } catch(Exception $e) { + Console::outDebug('cannot fetch package from package url, ' . $e->getMessage()); $exceptions[] = $e; } } @@ -465,6 +478,7 @@ { try { + Console::outDebug(sprintf('fetching package %s from %s', $input->Package, $repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl)); $git_repository = GitClient::cloneRepository($repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl); foreach(GitClient::getTags($git_repository) as $tag) @@ -475,9 +489,12 @@ return PackageCompiler::tryCompile($git_repository, $repositoryQueryResults->Version); } } + + Console::outDebug('cannot fetch package from git repository, no matching tag found'); } catch(Exception $e) { + Console::outDebug('cannot fetch package from git repository, ' . $e->getMessage()); $exceptions[] = $e; } } @@ -525,6 +542,7 @@ { try { + Console::outVerbose(sprintf('Installing package from source %s', $source)); $package = $this->fetchFromSource($source, $entry); return $this->install($package, $entry); } @@ -544,6 +562,8 @@ * @throws FileNotFoundException * @throws IOException * @throws InstallationException + * @throws InvalidPackageNameException + * @throws InvalidScopeException * @throws MissingDependencyException * @throws NotImplementedException * @throws PackageAlreadyInstalledException @@ -562,41 +582,42 @@ if ($dependent_package !== null && $dependency->Version !== null && Validate::version($dependency->Version)) { + Console::outDebug('dependency has version constraint, checking if package is installed'); $dependent_version = $this->getPackageVersion($dependency->Name, $dependency->Version); if ($dependent_version !== null) $dependency_met = true; } elseif ($dependent_package !== null && $dependency->Version == null) { + Console::outDebug(sprintf('dependency %s has no version specified, assuming dependency is met', $dependency->Name)); $dependency_met = true; } - if ($dependency->SourceType !== null) + Console::outDebug('dependency met: ' . ($dependency_met ? 'true' : 'false')); + + if ($dependency->SourceType !== null && !$dependency_met) { - if(!$dependency_met) + Console::outVerbose(sprintf('Installing dependency %s=%s for %s=%s', $dependency->Name, $dependency->Version, $package->Assembly->Package, $package->Assembly->Version)); + switch ($dependency->SourceType) { - Console::outVerbose(sprintf('Installing dependency %s=%s for %s=%s', $dependency->Name, $dependency->Version, $package->Assembly->Package, $package->Assembly->Version)); - switch ($dependency->SourceType) - { - case DependencySourceType::Local: - Console::outDebug('installing from local source ' . $dependency->Source); - $basedir = dirname($package_path); - if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->Source)) - throw new FileNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->Source); - $this->install($basedir . DIRECTORY_SEPARATOR . $dependency->Source); - break; + case DependencySourceType::Local: + Console::outDebug('installing from local source ' . $dependency->Source); + $basedir = dirname($package_path); + if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->Source)) + throw new FileNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->Source); + $this->install($basedir . DIRECTORY_SEPARATOR . $dependency->Source); + break; - case DependencySourceType::StaticLinking: - throw new PackageNotFoundException('Static linking not possible, package ' . $dependency->Name . ' is not installed'); + case DependencySourceType::StaticLinking: + throw new PackageNotFoundException('Static linking not possible, package ' . $dependency->Name . ' is not installed'); - case DependencySourceType::RemoteSource: - Console::outDebug('installing from remote source ' . $dependency->Source); - $this->installFromSource($dependency->Source, $entry); - break; + case DependencySourceType::RemoteSource: + Console::outDebug('installing from remote source ' . $dependency->Source); + $this->installFromSource($dependency->Source, $entry); + break; - default: - throw new NotImplementedException('Dependency source type ' . $dependency->SourceType . ' is not implemented'); - } + default: + throw new NotImplementedException('Dependency source type ' . $dependency->SourceType . ' is not implemented'); } } else @@ -614,6 +635,7 @@ */ public function getPackage(string $package): ?PackageEntry { + Console::outDebug('getting package ' . $package); return $this->getPackageLockManager()->getPackageLock()->getPackage($package); } @@ -628,6 +650,7 @@ */ public function getPackageVersion(string $package, string $version): ?VersionEntry { + Console::outDebug('getting package version ' . $package . '=' . $version); return $this->getPackage($package)?->getVersion($version); } @@ -638,9 +661,11 @@ * @return VersionEntry|null * @throws VersionNotFoundException * @throws PackageLockException + * @noinspection PhpUnused */ public function getLatestVersion(string $package): ?VersionEntry { + Console::outDebug('getting latest version of package ' . $package); return $this->getPackage($package)?->getVersion($this->getPackage($package)?->getLatestVersion()); } @@ -775,12 +800,15 @@ if($filesystem->exists($version_entry->Location)) { + Console::outVerbose(sprintf('Removing package files from %s', $version_entry->Location)); + /** @var SplFileInfo $item */ /** @noinspection PhpRedundantOptionalArgumentInspection */ foreach($scanner($version_entry->Location, true) as $item) { if(is_file($item->getPath())) { + Console::outDebug('removing file ' . $item->getPath()); Console::outDebug(sprintf('deleting %s', $item->getPath())); $filesystem->remove($item->getPath()); } @@ -828,6 +856,7 @@ foreach($package_entry->getVersions() as $version) { $version_entry = $package_entry->getVersion($version); + try { $this->uninstallPackageVersion($package, $version_entry->Version); @@ -846,6 +875,8 @@ */ private static function initData(Package $package, InstallationPaths $paths): void { + Console::outVerbose(sprintf('Initializing data for %s', $package->Assembly->Name)); + // Create data files $dependencies = []; foreach($package->Dependencies as $dependency) @@ -868,6 +899,7 @@ { try { + Console::outDebug(sprintf('generating data file %s', $file)); IO::fwrite($file, $data); } catch (IOException $e) -- 2.45.3 From 45cac3ec75c98d02535745557466887c9d457ecf Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 7 Jan 2023 02:47:27 -0500 Subject: [PATCH 152/212] Added methods getConstant() and setConstant() in \ncc\Runtime --- src/ncc/Runtime.php | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php index 3e45114..40d4aa6 100644 --- a/src/ncc/Runtime.php +++ b/src/ncc/Runtime.php @@ -8,13 +8,16 @@ use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\Versions; use ncc\Classes\PhpExtension\PhpRuntime; + use ncc\Exceptions\ConstantReadonlyException; use ncc\Exceptions\ImportException; + use ncc\Exceptions\InvalidConstantNameException; use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\VersionNotFoundException; use ncc\Managers\PackageManager; use ncc\Objects\PackageLock\VersionEntry; use ncc\Objects\ProjectConfiguration\Dependency; + use ncc\Runtime\Constants; class Runtime { @@ -133,7 +136,6 @@ throw new ImportException(sprintf('Failed to import package %s', $package), $e); } - self::addImport($package, $version); } @@ -176,4 +178,31 @@ { return array_keys(self::$imported_packages); } + + /** + * Returns a registered constant + * + * @param string $package + * @param string $name + * @return string|null + */ + public static function getConstant(string $package, string $name): ?string + { + return Constants::get($package, $name); + } + + /** + * Registers a new constant + * + * @param string $package + * @param string $name + * @param string $value + * @return void + * @throws ConstantReadonlyException + * @throws InvalidConstantNameException + */ + public static function setConstant(string $package, string $name, string $value): void + { + Constants::register($package, $name, $value); + } } \ No newline at end of file -- 2.45.3 From 334c40c1f31195e1ee08693d9290b3574ab46d7e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 7 Jan 2023 02:47:49 -0500 Subject: [PATCH 153/212] Improved Import function in \ncc\Classes\PhpExtension > PhpRuntime > import() --- src/ncc/Classes/PhpExtension/PhpRuntime.php | 73 ++++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/src/ncc/Classes/PhpExtension/PhpRuntime.php b/src/ncc/Classes/PhpExtension/PhpRuntime.php index 1e5cf22..b3d7471 100644 --- a/src/ncc/Classes/PhpExtension/PhpRuntime.php +++ b/src/ncc/Classes/PhpExtension/PhpRuntime.php @@ -2,12 +2,16 @@ namespace ncc\Classes\PhpExtension; + use Exception; use ncc\Abstracts\Options\RuntimeImportOptions; - use ncc\Exceptions\AccessDeniedException; - use ncc\Exceptions\FileNotFoundException; - use ncc\Exceptions\IOException; + use ncc\Classes\NccExtension\ConstantCompiler; + use ncc\Exceptions\ConstantReadonlyException; + use ncc\Exceptions\ImportException; + use ncc\Exceptions\InvalidConstantNameException; use ncc\Interfaces\RuntimeInterface; use ncc\Objects\PackageLock\VersionEntry; + use ncc\Objects\ProjectConfiguration\Assembly; + use ncc\Runtime\Constants; use ncc\Utilities\IO; use ncc\ZiProto\ZiProto; @@ -20,14 +24,57 @@ * @param VersionEntry $versionEntry * @param array $options * @return bool - * @throws AccessDeniedException - * @throws FileNotFoundException - * @throws IOException + * @throws ImportException */ public static function import(VersionEntry $versionEntry, array $options=[]): bool { $autoload_path = $versionEntry->getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php'; $static_files = $versionEntry->getInstallPaths()->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin'; + $constants_path = $versionEntry->getInstallPaths()->getDataPath() . DIRECTORY_SEPARATOR . 'const'; + $assembly_path = $versionEntry->getInstallPaths()->getDataPath() . DIRECTORY_SEPARATOR . 'assembly'; + + if(!file_exists($assembly_path)) + throw new ImportException('Cannot locate assembly file \'' . $assembly_path . '\''); + + try + { + $assembly_content = ZiProto::decode(IO::fread($assembly_path)); + $assembly = Assembly::fromArray($assembly_content); + } + catch(Exception $e) + { + throw new ImportException('Failed to load assembly file \'' . $assembly_path . '\': ' . $e->getMessage()); + } + + if(file_exists($constants_path)) + { + try + { + $constants = ZiProto::decode(IO::fread($constants_path)); + } + catch(Exception $e) + { + throw new ImportException('Failed to load constants file \'' . $constants_path . '\': ' . $e->getMessage()); + } + + foreach($constants as $name => $value) + { + $value = ConstantCompiler::compileRuntimeConstants($value); + + try + { + Constants::register($assembly->Package, $name, $value, true); + } + catch (ConstantReadonlyException $e) + { + trigger_error('Constant \'' . $name . '\' is readonly (' . $assembly->Package . ')', E_USER_WARNING); + } + catch (InvalidConstantNameException $e) + { + throw new ImportException('Invalid constant name \'' . $name . '\' (' . $assembly->Package . ')', $e); + } + } + } if(file_exists($autoload_path) && !in_array(RuntimeImportOptions::ImportAutoloader, $options)) { @@ -36,9 +83,17 @@ if(file_exists($static_files) && !in_array(RuntimeImportOptions::ImportStaticFiles, $options)) { - $static_files = ZiProto::decode(IO::fread($static_files)); - foreach($static_files as $file) - require_once($file); + try + { + $static_files = ZiProto::decode(IO::fread($static_files)); + foreach($static_files as $file) + require_once($file); + } + catch(Exception $e) + { + throw new ImportException('Failed to load static files: ' . $e->getMessage(), $e); + } + } if(!file_exists($autoload_path) && !file_exists($static_files)) -- 2.45.3 From bb0eb22f26a1886fbd78d65f03535518ac45514d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 7 Jan 2023 02:48:08 -0500 Subject: [PATCH 154/212] Added public methods get_constant() and set_constant() in extension --- src/installer/extension | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/installer/extension b/src/installer/extension index 64b76f4..2ccc72b 100644 --- a/src/installer/extension +++ b/src/installer/extension @@ -134,4 +134,37 @@ return Runtime::getDataPath($package); } } + + if(!function_exists('get_constant')) + { + /** + * Returns the value of a constant defined in NCC's runtime environment + * + * @param string $package + * @param string $name + * @return string|null + */ + function get_constant(string $package, string $name): ?string + { + return Runtime::getConstant($package, $name); + } + } + + if(!function_exists('set_constant')) + { + /** + * Sets the value of a constant defined in NCC's runtime environment + * + * @param string $package + * @param string $name + * @param string $value + * @return void + * @throws ConstantReadonlyException + * @throws InvalidConstantNameException + */ + function set_constant(string $package, string $name, string $value): void + { + Runtime::setConstant($package, $name, $value); + } + } } \ No newline at end of file -- 2.45.3 From 0010a7257c8dab840b4a3b6632f860b746ee504f Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 7 Jan 2023 02:49:40 -0500 Subject: [PATCH 155/212] Added Runtime Constant compiler --- .../SpecialConstants/RuntimeConstants.php | 5 ++++ .../Classes/NccExtension/ConstantCompiler.php | 27 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/ncc/Abstracts/SpecialConstants/RuntimeConstants.php b/src/ncc/Abstracts/SpecialConstants/RuntimeConstants.php index 751d28c..7d17c75 100644 --- a/src/ncc/Abstracts/SpecialConstants/RuntimeConstants.php +++ b/src/ncc/Abstracts/SpecialConstants/RuntimeConstants.php @@ -5,4 +5,9 @@ abstract class RuntimeConstants { const CWD = '%CWD%'; + + const PID = '%PID%'; + const UID = '%UID%'; + const GID = '%GID%'; + const User = '%USER%'; } \ No newline at end of file diff --git a/src/ncc/Classes/NccExtension/ConstantCompiler.php b/src/ncc/Classes/NccExtension/ConstantCompiler.php index 5ab4597..2b9c512 100644 --- a/src/ncc/Classes/NccExtension/ConstantCompiler.php +++ b/src/ncc/Classes/NccExtension/ConstantCompiler.php @@ -6,9 +6,8 @@ use ncc\Abstracts\SpecialConstants\DateTimeConstants; use ncc\Abstracts\SpecialConstants\InstallConstants; use ncc\Abstracts\SpecialConstants\AssemblyConstants; + use ncc\Abstracts\SpecialConstants\RuntimeConstants; use ncc\Objects\InstallationPaths; - use ncc\Objects\Package; - use ncc\Objects\ProjectConfiguration; use ncc\Objects\ProjectConfiguration\Assembly; class ConstantCompiler @@ -126,4 +125,28 @@ return $input; } + + /** + * @param string|null $input + * @return string|null + * @noinspection PhpUnnecessaryLocalVariableInspection + */ + public static function compileRuntimeConstants(?string $input): ?string + { + if ($input == null) + return null; + + if(function_exists('getcwd')) + $input = str_replace(RuntimeConstants::CWD, getcwd(), $input); + if(function_exists('getmypid')) + $input = str_replace(RuntimeConstants::PID, getmypid(), $input); + if(function_exists('getmyuid')) + $input = str_replace(RuntimeConstants::UID, getmyuid(), $input); + if(function_exists('getmygid')) + $input = str_replace(RuntimeConstants::GID, getmygid(), $input); + if(function_exists('get_current_user')) + $input = str_replace(RuntimeConstants::User, get_current_user(), $input); + + return $input; + } } \ No newline at end of file -- 2.45.3 From c08bc485a50a342984ec417729eed91f5393de77 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 8 Jan 2023 16:10:17 -0500 Subject: [PATCH 156/212] Updated Default Values --- src/ncc/Abstracts/CompilerExtensionDefaultVersions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Abstracts/CompilerExtensionDefaultVersions.php b/src/ncc/Abstracts/CompilerExtensionDefaultVersions.php index e590c70..328fceb 100644 --- a/src/ncc/Abstracts/CompilerExtensionDefaultVersions.php +++ b/src/ncc/Abstracts/CompilerExtensionDefaultVersions.php @@ -9,5 +9,5 @@ // [1] = MaximumVersion // ---------------------------------------------------------------- - const PHP = ['8.0', '8.1']; + const PHP = ['8.0', '8.2']; } \ No newline at end of file -- 2.45.3 From ffcae1b8a0dfa227b1f0f9855d7e4b1671abee7f Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 11 Jan 2023 19:55:19 -0500 Subject: [PATCH 157/212] Various changes, added more functions for executing packages (not finished) & updated documentation/project files. --- .idea/ncc.iml | 2 + DOCUMENTATION.md | 4 +- README.md | 39 +++-- src/ncc/Abstracts/ConstantReferences.php | 2 + .../{BuildMenu.php => BuildCommand.php} | 5 +- src/ncc/CLI/Commands/ExecCommand.php | 155 ++++++++++++++++++ src/ncc/CLI/Main.php | 4 +- src/ncc/CLI/Management/CredentialMenu.php | 3 +- .../Classes/NccExtension/PackageCompiler.php | 54 +++--- src/ncc/Classes/PhpExtension/PhpCompiler.php | 6 +- src/ncc/Interfaces/RunnerInterface.php | 1 - src/ncc/Interfaces/RuntimeInterface.php | 1 - src/ncc/Managers/ExecutionPointerManager.php | 20 ++- src/ncc/Managers/PackageManager.php | 8 +- src/ncc/Objects/Package/MagicBytes.php | 1 + src/ncc/Objects/PackageLock.php | 2 +- .../ExecutionPolicy/Execute.php | 32 +++- src/ncc/Utilities/Functions.php | 2 +- src/ncc/Utilities/RuntimeCache.php | 2 - tests/example_project/scripts/unit.bash | 2 +- 20 files changed, 283 insertions(+), 62 deletions(-) rename src/ncc/CLI/Commands/{BuildMenu.php => BuildCommand.php} (96%) create mode 100644 src/ncc/CLI/Commands/ExecCommand.php diff --git a/.idea/ncc.iml b/.idea/ncc.iml index 2c5c861..f554332 100644 --- a/.idea/ncc.iml +++ b/.idea/ncc.iml @@ -8,6 +8,8 @@ + + diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 629dfaa..d8f9515 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -9,10 +9,10 @@ NCC, from basic installation, basic usage, standards and much more. - What is NCC? - Advantages over other software - ------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------ -# Introduction (May 24, 2022) +# Introduction This section serves the basic introduction of NCC, what it's used for and how you can use it in your own projects or use it to run and build other projects that are designed diff --git a/README.md b/README.md index 9e9d0cf..0f1c508 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Nosial Code Compiler is a program written in PHP designed to be a multi-purpose This program is a complete re-write of the now defunct [PHP Package Manager (PPM)](https://git.n64.cc/intellivoid/ppm) toolkit offering more features, security and proper code licensing and copyrighting for the components used for the project. -### Alpha Stage +## Alpha Stage NCC is currently in alpha stage, meaning that it's not fully functional and may not work on your system. If you find any bugs or issues please report them to the [GitHub Issue Tracker](https://git.n64.cc/intellivoid/ncc/issues). @@ -12,28 +12,12 @@ or issues please report them to the [GitHub Issue Tracker](https://git.n64.cc/in At the moment NCC is currently being used while developing other software, this serves as a test run to improve on changes for the next version. -### Version History +## Version History - 1.0.0 Alpha - Initial release ([changelog](changelog/v1.0.0_alpha.md)) -## Authors - - - Zi Xing Narrakas (netkas) <[netkas@n64.cc](mailto:netkas@64.cc)> - - -## Special Thanks - - - Marc Gutt (mgutt) <[marc@gutt.it](mailto:marc@gutt.it)> - - Debusschère Alexandre ([debuss](https://github.com/debuss)) - - -## Copyright - -- Copyright (c) 2022-2022, Nosial - All Rights Reserved - - -## Contributing +# Contributing We welcome contributions to NCC! If you have an idea for how to improve the project, please don't hesitate to reach out. There are many ways to contribute, and we appreciate all forms of support. @@ -41,11 +25,26 @@ There are many ways to contribute, and we appreciate all forms of support. For more information on how to contribute, please read the [CONTRIBUTING.md](CONTRIBUTING.md) file. -## Code of Conduct +# Code of Conduct We are committed to maintaining a welcoming and inclusive environment for all contributors. Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md). +# Authors + +- Zi Xing Narrakas (netkas) <[netkas@n64.cc](mailto:netkas@64.cc)> + + +# Special Thanks + +- Marc Gutt (mgutt) <[marc@gutt.it](mailto:marc@gutt.it)> +- Debusschère Alexandre ([debuss](https://github.com/debuss)) + + +# Copyright + +- Copyright (c) 2022-2023, Nosial - All Rights Reserved + # Licenses diff --git a/src/ncc/Abstracts/ConstantReferences.php b/src/ncc/Abstracts/ConstantReferences.php index 43cf7ae..b2b7303 100644 --- a/src/ncc/Abstracts/ConstantReferences.php +++ b/src/ncc/Abstracts/ConstantReferences.php @@ -11,4 +11,6 @@ const DateTime = 'date_time'; const Install = 'install'; + + const Runtime = 'runtime'; } \ No newline at end of file diff --git a/src/ncc/CLI/Commands/BuildMenu.php b/src/ncc/CLI/Commands/BuildCommand.php similarity index 96% rename from src/ncc/CLI/Commands/BuildMenu.php rename to src/ncc/CLI/Commands/BuildCommand.php index 15d3411..b6573f4 100644 --- a/src/ncc/CLI/Commands/BuildMenu.php +++ b/src/ncc/CLI/Commands/BuildCommand.php @@ -7,8 +7,9 @@ use ncc\Managers\ProjectManager; use ncc\Objects\CliHelpSection; use ncc\Utilities\Console; + use ncc\Utilities\Functions; - class BuildMenu + class BuildCommand { /** * Displays the main help menu @@ -103,7 +104,7 @@ new CliHelpSection(['build', '--config'], 'Builds the current project with a specified build configuration') ]; - $options_padding = \ncc\Utilities\Functions::detectParametersPadding($options) + 4; + $options_padding = Functions::detectParametersPadding($options) + 4; Console::out('Usage: ncc build [options]'); Console::out('Options:' . PHP_EOL); diff --git a/src/ncc/CLI/Commands/ExecCommand.php b/src/ncc/CLI/Commands/ExecCommand.php new file mode 100644 index 0000000..a5d3171 --- /dev/null +++ b/src/ncc/CLI/Commands/ExecCommand.php @@ -0,0 +1,155 @@ + $value) + { + if(!in_array($key, $whitelist_arguments)) + $arguments[$key] = $value; + } + + $execution_pointer_manager = new ExecutionPointerManager(); + + try + { + $units = $execution_pointer_manager->getUnits($package, $version); + } + catch(Exception $e) + { + Console::outException(sprintf('Cannot load execution units for package \'%s\'', $package), $e, 1); + return; + } + + if(!isset($units[$entry])) + { + Console::outError(sprintf('Cannot find execution point \'%s\' in package \'%s\'', $entry, $package), true, 1); + return; + } + + /** @var ExecutionUnit $exec_unit */ + $exec_unit = $units[$entry]; + $exec_path = ''; + + $process = new Process(array_merge([$exec_path], $arguments)); + if($exec_unit->ExecutionPolicy->Execute->Pty !== null) + $process->setPty($exec_unit->ExecutionPolicy->Execute->Pty); + + if($exec_unit->ExecutionPolicy->Execute->Tty !== null) + { + $process->setTty($exec_unit->ExecutionPolicy->Execute->Tty); + $process->setPty(false); + } + + if($exec_unit->ExecutionPolicy->Execute->WorkingDirectory !== null) + $process->setWorkingDirectory($exec_unit->ExecutionPolicy->Execute->WorkingDirectory); + if($exec_unit->ExecutionPolicy->Execute->EnvironmentVariables !== null) + $process->setEnv($exec_unit->ExecutionPolicy->Execute->EnvironmentVariables); + if($exec_unit->ExecutionPolicy->Execute->Timeout !== null) + $process->setTimeout($exec_unit->ExecutionPolicy->Execute->Timeout); + if($exec_unit->ExecutionPolicy->Execute->IdleTimeout !== null) + $process->setIdleTimeout($exec_unit->ExecutionPolicy->Execute->IdleTimeout); + if($exec_unit->ExecutionPolicy->Execute->Options !== null) + $process->setOptions($exec_unit->ExecutionPolicy->Execute->Options); + + if($process->isTty() || $process->isPty()) + { + $process->start(); + $process->wait(); + } + else + { + $process->start(); + + while($process->isRunning()) + { + if($exec_unit->ExecutionPolicy->Execute->Silent) + { + $process->wait(); + } + else + { + $process->waitUntil(function($type, $buffer) + { + if($type == Process::ERR) + { + Console::outError($buffer); + } + else + { + Console::out($buffer); + } + }); + } + } + } + + exit(0); + } + + /** + * Displays the main options section + * + * @return void + */ + private static function displayOptions(): void + { + $options = [ + new CliHelpSection(['help'], 'Displays this help menu about the value command'), + new CliHelpSection(['exec', '--package'], '(Required) The package to execute'), + new CliHelpSection(['--version'], '(default: latest) The version of the package to execute'), + new CliHelpSection(['--entry'], '(default: main) The entry point of the package to execute'), + ]; + + $options_padding = Functions::detectParametersPadding($options) + 4; + + Console::out('Usage: ncc exec --package [options] [arguments]'); + Console::out('Options:' . PHP_EOL); + foreach($options as $option) + { + Console::out(' ' . $option->toString($options_padding)); + } + + Console::out(PHP_EOL . 'Arguments:' . PHP_EOL); + Console::out(' The arguments to pass to the program'); + Console::out(PHP_EOL . 'Example Usage:' . PHP_EOL); + Console::out(' ncc exec --package com.example.program'); + Console::out(' ncc exec --package com.example.program --version 1.0.0'); + Console::out(' ncc exec --package com.example.program --version 1.0.0 --entry setup'); + Console::out(' ncc exec --package com.example.program --foo --bar --extra=test'); + } + } \ No newline at end of file diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index dc87436..a0f03d0 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -7,7 +7,7 @@ use Exception; use ncc\Abstracts\LogLevel; use ncc\Abstracts\NccBuildFlags; - use ncc\CLI\Commands\BuildMenu; + use ncc\CLI\Commands\BuildCommand; use ncc\CLI\Management\ConfigMenu; use ncc\CLI\Management\CredentialMenu; use ncc\CLI\Management\PackageManagerMenu; @@ -114,7 +114,7 @@ exit(0); case 'build': - BuildMenu::start(self::$args); + BuildCommand::start(self::$args); exit(0); case 'cred': diff --git a/src/ncc/CLI/Management/CredentialMenu.php b/src/ncc/CLI/Management/CredentialMenu.php index d01e84d..7b75272 100644 --- a/src/ncc/CLI/Management/CredentialMenu.php +++ b/src/ncc/CLI/Management/CredentialMenu.php @@ -163,9 +163,10 @@ return; } + Console::out('Entries:'); foreach($entries as $entry) { - Console::out(sprintf('%s%s', $entry->getName(), ($entry->isEncrypted() ? ' (encrypted)' : ''))); + Console::out(sprintf(' - %s (%s)', $entry->getName(), $entry->isEncrypted() ? ' (encrypted)' : '')); } Console::out('Total: ' . count($entries)); diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index 459afc4..5d824ff 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -185,17 +185,25 @@ */ public static function writePackage(string $path, Package $package, ProjectConfiguration $configuration, string $build_configuration=BuildConfigurationValues::DefaultConfiguration): string { + Console::outVerbose(sprintf('Writing package to %s', $path)); + // Write the package to disk $FileSystem = new Filesystem(); $BuildConfiguration = $configuration->Build->getBuildConfiguration($build_configuration); if(!$FileSystem->exists($path . $BuildConfiguration->OutputPath)) + { + Console::outDebug(sprintf('creating output directory %s', $path . $BuildConfiguration->OutputPath)); $FileSystem->mkdir($path . $BuildConfiguration->OutputPath); + } // Finally write the package to the disk $FileSystem->mkdir($path . $BuildConfiguration->OutputPath); $output_file = $path . $BuildConfiguration->OutputPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '.ncc'; if($FileSystem->exists($output_file)) + { + Console::outDebug(sprintf('removing existing package %s', $output_file)); $FileSystem->remove($output_file); + } $FileSystem->touch($output_file); try @@ -210,35 +218,13 @@ return $output_file; } - /** - * Compiles the special formatted constants - * - * @param Package $package - * @param int $timestamp - * @return array - */ - public static function compileRuntimeConstants(Package $package, int $timestamp): array - { - $compiled_constants = []; - - foreach($package->Header->RuntimeConstants as $name => $value) - { - $compiled_constants[$name] = self::compileConstants($value, [ - ConstantReferences::Assembly => $package->Assembly, - ConstantReferences::DateTime => $timestamp, - ConstantReferences::Build => null - ]); - } - - return $compiled_constants; - } - /** * Compiles the constants in the package object * * @param Package $package * @param array $refs * @return void + * @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection */ public static function compilePackageConstants(Package &$package, array $refs): void { @@ -247,6 +233,7 @@ $assembly = []; foreach($package->Assembly->toArray() as $key => $value) { + Console::outDebug(sprintf('compiling consts Assembly.%s (%s)', $key, implode(', ', array_keys($refs)))); $assembly[$key] = self::compileConstants($value, $refs); } $package->Assembly = Assembly::fromArray($assembly); @@ -258,11 +245,29 @@ $units = []; foreach($package->ExecutionUnits as $executionUnit) { + Console::outDebug(sprintf('compiling execution unit consts %s (%s)', $executionUnit->Name, implode(', ', array_keys($refs)))); $units[] = self::compileExecutionUnitConstants($executionUnit, $refs); } $package->ExecutionUnits = $units; unset($units); } + + $compiled_constants = []; + foreach($package->Header->RuntimeConstants as $name => $value) + { + Console::outDebug(sprintf('compiling runtime const %s (%s)', $name, implode(', ', array_keys($refs)))); + $compiled_constants[$name] = self::compileConstants($value, $refs); + } + + $options = []; + foreach($package->Header->Options as $name => $value) + { + Console::outDebug(sprintf('compiling options const %s (%s)', $name, implode(', ', array_keys($refs)))); + $options[$name] = self::compileConstants($value, $refs); + } + $package->Header->Options = $options; + + $package->Header->RuntimeConstants = $compiled_constants; } /** @@ -344,6 +349,9 @@ if(isset($refs[ConstantReferences::Install])) $value = ConstantCompiler::compileInstallConstants($value, $refs[ConstantReferences::Install]); + if(isset($refs[ConstantReferences::Runtime])) + $value = ConstantCompiler::compileRuntimeConstants($value); + return $value; } } \ No newline at end of file diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index f594ef9..f9a74e9 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -23,7 +23,6 @@ use ncc\Exceptions\VersionNotFoundException; use ncc\Interfaces\CompilerInterface; use ncc\Managers\PackageLockManager; - use ncc\ncc; use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; use ncc\ThirdParty\nikic\PhpParser\ParserFactory; @@ -92,6 +91,10 @@ $this->package->Dependencies = $this->project->Build->Dependencies; $this->package->MainExecutionPolicy = $this->project->Build->Main; + // Add the option to create a symbolic link to the package + if($this->project->Build->CreateSymlink) + $this->package->Header->Options['create_symlink'] = true; + // Add both the defined constants from the build configuration and the global constants. // Global constants are overridden $this->package->Header->RuntimeConstants = []; @@ -105,6 +108,7 @@ $this->package->Header->CompilerVersion = NCC_VERSION_NUMBER; $this->package->Header->Options = $this->project->Project->Options; + Console::outDebug('scanning project files'); Console::outDebug('theseer\DirectoryScanner - Copyright (c) 2009-2014 Arne Blankerts All rights reserved.'); diff --git a/src/ncc/Interfaces/RunnerInterface.php b/src/ncc/Interfaces/RunnerInterface.php index 4d118c4..1d92644 100644 --- a/src/ncc/Interfaces/RunnerInterface.php +++ b/src/ncc/Interfaces/RunnerInterface.php @@ -7,7 +7,6 @@ use ncc\Exceptions\IOException; use ncc\Exceptions\RunnerExecutionException; use ncc\Objects\ExecutionPointers\ExecutionPointer; - use ncc\Objects\InstallationPaths; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; use ncc\ThirdParty\Symfony\Process\Process; diff --git a/src/ncc/Interfaces/RuntimeInterface.php b/src/ncc/Interfaces/RuntimeInterface.php index 7b70e51..55cb1c5 100644 --- a/src/ncc/Interfaces/RuntimeInterface.php +++ b/src/ncc/Interfaces/RuntimeInterface.php @@ -2,7 +2,6 @@ namespace ncc\Interfaces; - use ncc\Abstracts\Versions; use ncc\Exceptions\MissingDependencyException; use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageNotFoundException; diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 0132fb8..9b89551 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -155,7 +155,8 @@ } $bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name); - $bin_file .= match ($unit->ExecutionPolicy->Runner) { + $bin_file .= match ($unit->ExecutionPolicy->Runner) + { Runners::bash => BashRunner::getFileExtension(), Runners::php => PhpRunner::getFileExtension(), Runners::perl => PerlRunner::getFileExtension(), @@ -183,6 +184,7 @@ if($temporary) { + Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package)); $this->TemporaryUnits[] = [ 'package' => $package, 'version' => $version, @@ -275,6 +277,22 @@ return $results; } + public function getUnit(string $package, string $version, string $name): ExecutionUnit + { + Console::outVerbose(sprintf('getting execution unit %s for %s', $name, $package)); + + $package_id = $this->getPackageId($package, $version); + $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; + + if(!file_exists($package_config_path)) + throw new NoAvailableUnitsException('No ExecutionUnits available for ' . $package); + + $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); + $unit = $execution_pointers->getUnit($name); + + + } + /** * Executes a unit * diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 0475a4d..aafa985 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -309,7 +309,6 @@ } // Install execution units - // TODO: Implement symlink support if(count($package->ExecutionUnits) > 0) { $execution_pointer_manager = new ExecutionPointerManager(); @@ -325,6 +324,13 @@ IO::fwrite($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'exec', ZiProto::encode($unit_paths)); } + if(isset($package->Header->Options['create_symlink']) && $package->Header->Options['create_symlink']) + { + $paths = [ + DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'bin' + ]; + } + // Execute the post-installation stage after the installation is complete try { diff --git a/src/ncc/Objects/Package/MagicBytes.php b/src/ncc/Objects/Package/MagicBytes.php index 3e86446..6ed89ae 100644 --- a/src/ncc/Objects/Package/MagicBytes.php +++ b/src/ncc/Objects/Package/MagicBytes.php @@ -6,6 +6,7 @@ use ncc\Abstracts\EncoderType; use ncc\Abstracts\Versions; + use ncc\Utilities\Console; class MagicBytes { diff --git a/src/ncc/Objects/PackageLock.php b/src/ncc/Objects/PackageLock.php index 0655682..604987e 100644 --- a/src/ncc/Objects/PackageLock.php +++ b/src/ncc/Objects/PackageLock.php @@ -81,7 +81,6 @@ $this->Packages[$package->Assembly->Package]->UpdateSource = $package->Header->UpdateSource; $this->Packages[$package->Assembly->Package]->addVersion($package, $install_path, true); - $this->Packages[$package->Assembly->Package]->addVersion($package, $install_path, true); $this->Packages[$package->Assembly->Package]->getDataPath(); $this->update(); } @@ -127,6 +126,7 @@ if(isset($this->Packages[$package])) { unset($this->Packages[$package]); + $this->update(); return true; } diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php index 8fe5b02..b9184e6 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php @@ -30,6 +30,13 @@ */ public $Options; + /** + * An array of environment variables to pass on to the process + * + * @var array|null + */ + public $EnvironmentVariables; + /** * Indicates if the output should be displayed or suppressed * @@ -38,20 +45,32 @@ public $Silent; /** - * Indicates if the process should run in Tty mode (Overrides Silent mode) + * Indicates if the process should run in Tty mode (Overrides Silent & Pty mode) * * @var bool|null */ public $Tty; + /** + * Indicates if the process should run in Pty mode (Overrides Silent mode) + * + * @var bool|null + */ + public $Pty; + /** * The number of seconds to wait before giving up on the process, will automatically execute the error handler * if one is set. * - * @var int + * @var int|null */ public $Timeout; + /** + * @var int|null + */ + public $IdleTimeout; + /** * Public Constructor */ @@ -60,6 +79,7 @@ $this->Tty = false; $this->Silent = false; $this->Timeout = null; + $this->IdleTimeout = null; $this->WorkingDirectory = "%CWD%"; } @@ -82,6 +102,9 @@ if($this->Options !== null) $results[($bytecode ? Functions::cbc("options") : "options")] = $this->Options; + if($this->EnvironmentVariables !== null) + $results[($bytecode ? Functions::cbc("environment_variables") : "environment_variables")] = $this->EnvironmentVariables; + if($this->Silent !== null) $results[($bytecode ? Functions::cbc("silent") : "silent")] = (bool)$this->Silent; @@ -91,6 +114,9 @@ if($this->Timeout !== null) $results[($bytecode ? Functions::cbc("timeout") : "timeout")] = (int)$this->Timeout; + if($this->IdleTimeout !== null) + $results[($bytecode ? Functions::cbc("idle_timeout") : "idle_timeout")] = (int)$this->IdleTimeout; + return $results; } @@ -107,9 +133,11 @@ $object->Target = Functions::array_bc($data, 'target'); $object->WorkingDirectory = Functions::array_bc($data, 'working_directory'); $object->Options = Functions::array_bc($data, 'options'); + $object->EnvironmentVariables = Functions::array_bc($data, 'environment_variables'); $object->Silent = Functions::array_bc($data, 'silent'); $object->Tty = Functions::array_bc($data, 'tty'); $object->Timeout = Functions::array_bc($data, 'timeout'); + $object->IdleTimeout = Functions::array_bc($data, 'idle_timeout'); return $object; } diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index 7c9c568..5ce0129 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -929,7 +929,7 @@ { if (is_numeric($input)) { - if (strpos($input, '.') !== false) + if (str_contains($input, '.')) return (float)$input; if (ctype_digit($input)) diff --git a/src/ncc/Utilities/RuntimeCache.php b/src/ncc/Utilities/RuntimeCache.php index 0371b03..a948333 100644 --- a/src/ncc/Utilities/RuntimeCache.php +++ b/src/ncc/Utilities/RuntimeCache.php @@ -32,7 +32,6 @@ */ public static function set($key, $value): mixed { - Console::outDebug($key); self::$cache[$key] = $value; return $value; } @@ -45,7 +44,6 @@ */ public static function get($key): mixed { - Console::outDebug($key); if(isset(self::$cache[$key])) return self::$cache[$key]; diff --git a/tests/example_project/scripts/unit.bash b/tests/example_project/scripts/unit.bash index cf03e95..9a59108 100644 --- a/tests/example_project/scripts/unit.bash +++ b/tests/example_project/scripts/unit.bash @@ -1,3 +1,3 @@ echo "Hello World!" -read -p "What is your name? " name +read -r -p "What is your name? " name echo "Hello $name" \ No newline at end of file -- 2.45.3 From 2d7e71be847a041cae5399721de55c8e8b666a20 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 11 Jan 2023 19:55:47 -0500 Subject: [PATCH 158/212] Removed unused import statements --- src/ncc/Classes/GithubExtension/GithubService.php | 1 - src/ncc/Classes/PhpExtension/PhpInstaller.php | 2 -- src/ncc/Interfaces/PasswordInterface.php | 2 -- src/ncc/Objects/HttpResponseCache.php | 2 -- src/ncc/Objects/Package/MagicBytes.php | 1 - src/ncc/Objects/ProjectConfiguration/Dependency.php | 1 - src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php | 1 - src/ncc/Utilities/Console.php | 2 -- src/ncc/Utilities/PathFinder.php | 1 - 9 files changed, 13 deletions(-) diff --git a/src/ncc/Classes/GithubExtension/GithubService.php b/src/ncc/Classes/GithubExtension/GithubService.php index 440f4c9..0ee80c4 100644 --- a/src/ncc/Classes/GithubExtension/GithubService.php +++ b/src/ncc/Classes/GithubExtension/GithubService.php @@ -19,7 +19,6 @@ use ncc\Objects\Vault\Entry; use ncc\ThirdParty\jelix\Version\VersionComparator; use ncc\Utilities\Functions; - use ncc\Utilities\Validate; class GithubService implements RepositorySourceInterface { diff --git a/src/ncc/Classes/PhpExtension/PhpInstaller.php b/src/ncc/Classes/PhpExtension/PhpInstaller.php index 490d739..583ee03 100644 --- a/src/ncc/Classes/PhpExtension/PhpInstaller.php +++ b/src/ncc/Classes/PhpExtension/PhpInstaller.php @@ -13,7 +13,6 @@ use ncc\Exceptions\ComponentChecksumException; use ncc\Exceptions\ComponentDecodeException; use ncc\Exceptions\FileNotFoundException; - use ncc\Exceptions\InstallationException; use ncc\Exceptions\IOException; use ncc\Exceptions\NoUnitsFoundException; use ncc\Exceptions\ResourceChecksumException; @@ -31,7 +30,6 @@ use ncc\ThirdParty\theseer\Autoload\Factory; use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\ZiProto\ZiProto; use ReflectionClass; use ReflectionException; use RuntimeException; diff --git a/src/ncc/Interfaces/PasswordInterface.php b/src/ncc/Interfaces/PasswordInterface.php index 488c7dd..9b7ebef 100644 --- a/src/ncc/Interfaces/PasswordInterface.php +++ b/src/ncc/Interfaces/PasswordInterface.php @@ -2,8 +2,6 @@ namespace ncc\Interfaces; - use ncc\Abstracts\AuthenticationType; - interface PasswordInterface { /** diff --git a/src/ncc/Objects/HttpResponseCache.php b/src/ncc/Objects/HttpResponseCache.php index dde55ce..9b2a6d2 100644 --- a/src/ncc/Objects/HttpResponseCache.php +++ b/src/ncc/Objects/HttpResponseCache.php @@ -4,8 +4,6 @@ namespace ncc\Objects; - use ncc\Utilities\RuntimeCache; - class HttpResponseCache { /** diff --git a/src/ncc/Objects/Package/MagicBytes.php b/src/ncc/Objects/Package/MagicBytes.php index 6ed89ae..3e86446 100644 --- a/src/ncc/Objects/Package/MagicBytes.php +++ b/src/ncc/Objects/Package/MagicBytes.php @@ -6,7 +6,6 @@ use ncc\Abstracts\EncoderType; use ncc\Abstracts\Versions; - use ncc\Utilities\Console; class MagicBytes { diff --git a/src/ncc/Objects/ProjectConfiguration/Dependency.php b/src/ncc/Objects/ProjectConfiguration/Dependency.php index 067f785..d664618 100644 --- a/src/ncc/Objects/ProjectConfiguration/Dependency.php +++ b/src/ncc/Objects/ProjectConfiguration/Dependency.php @@ -4,7 +4,6 @@ namespace ncc\Objects\ProjectConfiguration; - use ncc\Abstracts\DependencySourceType; use ncc\Exceptions\InvalidDependencyConfiguration; use ncc\Utilities\Functions; use ncc\Utilities\Validate; diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php index e0b0a58..be98067 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php @@ -4,7 +4,6 @@ namespace ncc\Objects\ProjectConfiguration; - use ncc\Objects\InstallationPaths; use ncc\Objects\ProjectConfiguration\ExecutionPolicy\Execute; use ncc\Objects\ProjectConfiguration\ExecutionPolicy\ExitHandlers; use ncc\Utilities\Functions; diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index 642d3fb..fcd3128 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -9,8 +9,6 @@ use ncc\Abstracts\LogLevel; use ncc\CLI\Main; use ncc\ncc; - use ncc\Objects\CliHelpSection; - use ncc\ThirdParty\Symfony\Process\ExecutableFinder; use Throwable; class Console diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index 1e37d33..c3fb587 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -2,7 +2,6 @@ namespace ncc\Utilities; - use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidScopeException; -- 2.45.3 From 63560ba64bee93bc0f28cc376460df294a507875 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 12 Jan 2023 15:00:10 -0500 Subject: [PATCH 159/212] Updated method \ncc\Manager > PackageManager > processDependency() to only throw an error regarding the dependency not being met if it is not met. --- src/ncc/Managers/PackageManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index aafa985..3b4e6cc 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -626,7 +626,7 @@ throw new NotImplementedException('Dependency source type ' . $dependency->SourceType . ' is not implemented'); } } - else + elseif(!$dependency_met) { throw new MissingDependencyException(sprintf('The dependency %s=%s for %s=%s is not met', $dependency->Name, $dependency->Version, $package->Assembly->Package, $package->Assembly->Version)); } -- 2.45.3 From 272c3b9d946deae290dac52210f8ea531655bd66 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 12 Jan 2023 15:00:39 -0500 Subject: [PATCH 160/212] Added handler for arrays in \ncc\Classes\NccExtension > PackageCompiler > compilePackageConstants() --- .../Classes/NccExtension/PackageCompiler.php | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index 5d824ff..bc90f78 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -262,11 +262,26 @@ $options = []; foreach($package->Header->Options as $name => $value) { - Console::outDebug(sprintf('compiling options const %s (%s)', $name, implode(', ', array_keys($refs)))); - $options[$name] = self::compileConstants($value, $refs); - } - $package->Header->Options = $options; + if(is_array($value)) + { + $options[$name] = []; + foreach($value as $key => $val) + { + if(!is_string($val)) + continue; + Console::outDebug(sprintf('compiling option %s.%s (%s)', $name, $key, implode(', ', array_keys($refs)))); + $options[$name][$key] = self::compileConstants($val, $refs); + } + } + else + { + Console::outDebug(sprintf('compiling option %s (%s)', $name, implode(', ', array_keys($refs)))); + $options[$name] = self::compileConstants((string)$value, $refs); + } + } + + $package->Header->Options = $options; $package->Header->RuntimeConstants = $compiled_constants; } -- 2.45.3 From 5beb06abda6c8cc77bc384cd624fd8efce01c23c Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 12 Jan 2023 15:57:10 -0500 Subject: [PATCH 161/212] Added basic syntax highlighting and performance tick indicators --- src/ncc/Utilities/Console.php | 37 ++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/ncc/Utilities/Console.php b/src/ncc/Utilities/Console.php index fcd3128..6124181 100644 --- a/src/ncc/Utilities/Console.php +++ b/src/ncc/Utilities/Console.php @@ -18,6 +18,11 @@ */ private static $largestTickLength = 0; + /** + * @var float|int + */ + private static $lastTickTime; + /** * Inline Progress bar, created by dealnews.com. * @@ -118,13 +123,35 @@ }; $tick_time = (string)microtime(true); + if(strlen($tick_time) > self::$largestTickLength) + { self::$largestTickLength = strlen($tick_time); + } + if(strlen($tick_time) < self::$largestTickLength) + { /** @noinspection PhpRedundantOptionalArgumentInspection */ $tick_time = str_pad($tick_time, (strlen($tick_time) + (self::$largestTickLength - strlen($tick_time))), ' ', STR_PAD_RIGHT); + } - return '[' . $tick_time . '] ' . $input; + $fmt_tick = $tick_time; + if(self::$lastTickTime !== null) + { + $timeDiff = microtime(true) - self::$lastTickTime; + + if ($timeDiff > 1.0) + { + $fmt_tick = Console::formatColor($tick_time, ConsoleColors::LightRed); + } + elseif ($timeDiff > 0.5) + { + $fmt_tick = Console::formatColor($tick_time, ConsoleColors::LightYellow); + } + } + + self::$lastTickTime = $tick_time; + return '[' . $fmt_tick . '] ' . $input; } /** @@ -182,6 +209,14 @@ $trace_msg .= ' > '; } + /** Apply syntax highlighting using regular expressions */ + + // Hyperlinks + $message = preg_replace('/(https?:\/\/[^\s]+)/', Console::formatColor('$1', ConsoleColors::LightBlue), $message); + + // File Paths + $message = preg_replace('/(\/[^\s]+)/', Console::formatColor('$1', ConsoleColors::LightCyan), $message); + /** @noinspection PhpUnnecessaryStringCastInspection */ $message = self::setPrefix(LogLevel::Debug, (string)$trace_msg . $message); -- 2.45.3 From b8f508d326395cdcc6acd0c66827760c54e2f8d8 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 12 Jan 2023 16:15:33 -0500 Subject: [PATCH 162/212] Typo Correction in \ncc\CLI\Management > ConfigMenu > start() --- src/ncc/CLI/Management/ConfigMenu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/CLI/Management/ConfigMenu.php b/src/ncc/CLI/Management/ConfigMenu.php index d41936a..ad739f4 100644 --- a/src/ncc/CLI/Management/ConfigMenu.php +++ b/src/ncc/CLI/Management/ConfigMenu.php @@ -83,7 +83,7 @@ { if(Resolver::resolveScope() !== Scopes::System) { - Console::outError('Insufficent permissions, cannot modify configuration values', true, 1); + Console::outError('Insufficient permissions, cannot modify configuration values', true, 1); return; } -- 2.45.3 From b62bb725ccff5fb95b2f9a4dd8975a2e38f128a3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 12 Jan 2023 16:19:23 -0500 Subject: [PATCH 163/212] Typo correction in \ncc\Utilities > PathFinder > getRemoteSource() --- src/ncc/Utilities/PathFinder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index c3fb587..8093f7d 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -179,7 +179,7 @@ * @return string * @throws InvalidScopeException */ - public static function getRemouteSources(string $scope=Scopes::Auto, bool $win32=false): string + public static function getRemoteSources(string $scope=Scopes::Auto, bool $win32=false): string { return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'sources'; } -- 2.45.3 From b51b7203e05d77f12a09e59a647132eab61a1805 Mon Sep 17 00:00:00 2001 From: Netkas Date: Wed, 18 Jan 2023 16:33:48 -0500 Subject: [PATCH 164/212] Added 'sdc' command to \ncc\CLI\Management > PackageManagerMenu to allow for semi-decompiling packages for debugging purposes. --- src/ncc/CLI/Management/PackageManagerMenu.php | 112 ++++++++++++++++-- 1 file changed, 103 insertions(+), 9 deletions(-) diff --git a/src/ncc/CLI/Management/PackageManagerMenu.php b/src/ncc/CLI/Management/PackageManagerMenu.php index e8db3f3..c8b0982 100644 --- a/src/ncc/CLI/Management/PackageManagerMenu.php +++ b/src/ncc/CLI/Management/PackageManagerMenu.php @@ -85,6 +85,20 @@ } } + if(isset($args['sdc'])) + { + try + { + self::semiDecompile($args); + return; + } + catch(Exception $e) + { + Console::outException('List Failed', $e, 1); + return; + } + } + self::displayOptions(); exit(0); } @@ -117,6 +131,91 @@ } } + /** + * Semi-Decompiles a package and prints it to the console + * + * @param $args + * @return void + * @throws FileNotFoundException + */ + private static function semiDecompile($args): void + { + $path = ($args['package'] ?? $args['p']); + + if(!file_exists($path) || !is_file($path) || !is_readable($path)) + throw new FileNotFoundException('The specified file \'' . $path .' \' does not exist or is not readable.'); + + try + { + $package = Package::load($path); + } + catch(Exception $e) + { + Console::outException('Error while loading package', $e, 1); + return; + } + + Console::out('magic_bytes: ' . json_encode(($package->MagicBytes?->toArray() ?? []), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + Console::out('header: ' . json_encode(($package->Header?->toArray() ?? []), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + Console::out('assembly: ' . json_encode(($package->Assembly?->toArray() ?? []), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + Console::out('main: ' . ($package->MainExecutionPolicy ?? 'N/A')); + Console::out('installer: ' . ($package->Installer?->toArray() ?? 'N/A')); + + if($package->Dependencies !== null && count($package->Dependencies) > 0) + { + Console::out('dependencies:'); + foreach($package->Dependencies as $dependency) + { + Console::out(' - ' . json_encode($dependency->toArray(), JSON_UNESCAPED_SLASHES)); + } + } + else + { + Console::out('dependencies: N/A'); + } + + if($package->ExecutionUnits !== null && count($package->ExecutionUnits) > 0) + { + Console::out('execution_units:'); + foreach($package->ExecutionUnits as $unit) + { + Console::out(' - ' . json_encode($unit->toArray(), JSON_UNESCAPED_SLASHES)); + } + } + else + { + Console::out('execution_units: N/A'); + } + + if($package->Resources !== null && count($package->Resources) > 0) + { + Console::out('resources:'); + foreach($package->Resources as $resource) + { + Console::out(' - ' . sprintf('%s - (%s)', $resource->Name, Functions::b2u(strlen($resource->Data)))); + } + } + else + { + Console::out('resources: N/A'); + } + + if($package->Components !== null && count($package->Components) > 0) + { + Console::out('components:'); + foreach($package->Components as $component) + { + Console::out(' - ' . sprintf('#%s %s - %s', $component->DataType, $component->Name, json_encode(($component->Flags ?? []), JSON_UNESCAPED_SLASHES))); + } + } + else + { + Console::out('components: N/A'); + } + + exit(0); + } + /** * Displays all installed packages * @@ -314,11 +413,7 @@ { $require_dependency = false; - if(in_array(InstallPackageOptions::Reinstall, $installer_options)) - { - $require_dependency = true; - } - else + if(!in_array(InstallPackageOptions::SkipDependencies, $installer_options)) { try { @@ -342,10 +437,8 @@ $dependency_version = null; } - if($dependency_version !== null) - { - $require_dependency = false; - } + if($dependency_version == null) + $require_dependency = true; } } @@ -553,6 +646,7 @@ new CliHelpSection(['uninstall', '--package', '-p'], 'Uninstalls a specified NCC package'), new CliHelpSection(['uninstall', '--package', '-p', '--version', '-v'], 'Uninstalls a specified NCC package version'), new CliHelpSection(['uninstall-all'], 'Uninstalls all packages'), + new CliHelpSection(['sdc', '--package', '-p'], '(Debug) Semi-decompiles a specified NCC package and prints the result to the console'), ]; $options_padding = Functions::detectParametersPadding($options) + 4; -- 2.45.3 From e89a71da2ffccb6de5d2e613c1c7ad226bbbc9bc Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 06:28:02 -0500 Subject: [PATCH 165/212] Added .gitlab-ci.yaml (Experimental) --- .gitlab-ci.yaml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .gitlab-ci.yaml diff --git a/.gitlab-ci.yaml b/.gitlab-ci.yaml new file mode 100644 index 0000000..1433a7b --- /dev/null +++ b/.gitlab-ci.yaml @@ -0,0 +1,28 @@ +image: php:8.1 + +before_script: + # Install some stuff that the image doesn't come with + - apt update -yqq + - apt install git libpq-dev libzip-dev zip make -yqq + + # Install phive + - wget -O phive.phar https://phar.io/releases/phive.phar + - wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc + - gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 + - gpg --verify phive.phar.asc phive.phar + - chmod +x phive.phar + - sudo mv phive.phar /usr/local/bin/phive + + # install phpab + - phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C + +build: + script: + - make redist tar + artifacts: + paths: + - build/src/ncc.tar.gz + +test: + script: + - build/src/INSTALL --auto --install-composer \ No newline at end of file -- 2.45.3 From b8e4fe80af730041df4a50d1d6ab783f1aa4c41a Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 06:28:30 -0500 Subject: [PATCH 166/212] Updated Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 97dd9bb..b8565c1 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ PHPCC=/usr/bin/php -PHPAB=/usr/bin/phpab +PHPAB=/usr/local/bin/phpab BUILD_PATH=build SRC_PATH=src -- 2.45.3 From ee99d4d465cd0dae46f8d2470f43797421967e3e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 06:29:45 -0500 Subject: [PATCH 167/212] Lol --- .gitlab-ci.yaml => .gitlab-ci.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .gitlab-ci.yaml => .gitlab-ci.yml (100%) diff --git a/.gitlab-ci.yaml b/.gitlab-ci.yml similarity index 100% rename from .gitlab-ci.yaml rename to .gitlab-ci.yml -- 2.45.3 From 0b79f5598a78d95a129b6fff87b243d9a662b147 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:45:18 -0500 Subject: [PATCH 168/212] Updated README.md to include information about mirrors --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 0f1c508..83fa984 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,15 @@ improve on changes for the next version. - 1.0.0 Alpha - Initial release ([changelog](changelog/v1.0.0_alpha.md)) +## Repository Mirrors + +The official repository for NCC is hosted on [GitLab](https://git.n64.cc/intellivoid/ncc), however, you can also find +mirrors of the repository mirrored on different platforms, including +community powered mirrors. (more to come) + + - [git.it-kuny.ch](https://git.it-kuny.ch) + - [git.martinvlba.eu](https://git.martinvlba.eu/Nosial/ncc) + # Contributing -- 2.45.3 From 2cc0d6f582998a3fa24a8704218c5f716b30ba50 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:49:43 -0500 Subject: [PATCH 169/212] Added 'wget' to .gitlab-ci.yml --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1433a7b..f62dfbd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,7 +3,7 @@ image: php:8.1 before_script: # Install some stuff that the image doesn't come with - apt update -yqq - - apt install git libpq-dev libzip-dev zip make -yqq + - apt install git libpq-dev libzip-dev zip make wget -yqq # Install phive - wget -O phive.phar https://phar.io/releases/phive.phar -- 2.45.3 From d34d857a840846fc19c546e3d0dcc3f175eef539 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:51:30 -0500 Subject: [PATCH 170/212] Commented out gpg for now --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f62dfbd..76d6eff 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,9 +7,9 @@ before_script: # Install phive - wget -O phive.phar https://phar.io/releases/phive.phar - - wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc - - gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 - - gpg --verify phive.phar.asc phive.phar + #- wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc + #- gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 + #- gpg --verify phive.phar.asc phive.phar - chmod +x phive.phar - sudo mv phive.phar /usr/local/bin/phive -- 2.45.3 From ec7e7a31ca99f6fe4c2b82d9804046c39ad1428c Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:53:05 -0500 Subject: [PATCH 171/212] Minor changes, removed the use of 'sudo' & changed build archive name from ncc.tar.gz to build.tar.gz --- .gitlab-ci.yml | 4 ++-- Makefile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 76d6eff..74d0af1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,7 +11,7 @@ before_script: #- gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 #- gpg --verify phive.phar.asc phive.phar - chmod +x phive.phar - - sudo mv phive.phar /usr/local/bin/phive + - mv phive.phar /usr/local/bin/phive # install phpab - phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C @@ -21,7 +21,7 @@ build: - make redist tar artifacts: paths: - - build/src/ncc.tar.gz + - build/src/build.tar.gz test: script: diff --git a/Makefile b/Makefile index b8565c1..39cd589 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ redist: autoload cp -rf $(SRC_PATH)/default_repositories/*.json $(BUILD_PATH)/src/repositories tar: redist - cd $(BUILD_PATH)/src; tar -czvf ../ncc.tar.gz * + cd $(BUILD_PATH)/src; tar -czvf ../build.tar.gz * clean: rm -rf $(BUILD_PATH) -- 2.45.3 From eda127da48c4b36596bed82d708c5253911037c5 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:54:20 -0500 Subject: [PATCH 172/212] Okay fine asshole, I'll use gpg --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 74d0af1..8b291d1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,13 +3,13 @@ image: php:8.1 before_script: # Install some stuff that the image doesn't come with - apt update -yqq - - apt install git libpq-dev libzip-dev zip make wget -yqq + - apt install git libpq-dev libzip-dev zip make wget gnupg -yqq # Install phive - wget -O phive.phar https://phar.io/releases/phive.phar - #- wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc - #- gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 - #- gpg --verify phive.phar.asc phive.phar + - wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc + - gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 + - gpg --verify phive.phar.asc phive.phar - chmod +x phive.phar - mv phive.phar /usr/local/bin/phive -- 2.45.3 From 39bba1b532e2544d190c8cffea0e925b5a19ff74 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:56:35 -0500 Subject: [PATCH 173/212] Updated Makefile --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 39cd589..fee0f12 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -PHPCC=/usr/bin/php -PHPAB=/usr/local/bin/phpab +PHPCC:=$(shell which php) +PHPAB:=$(shell which phpab) BUILD_PATH=build SRC_PATH=src -- 2.45.3 From 9cd424ec5bf56303afe528e53a42001338f63cfe Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 09:59:26 -0500 Subject: [PATCH 174/212] Removed 'test' from .gitlab-ci.yml and corrected artifact path --- .gitlab-ci.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8b291d1..d4f6562 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,8 +21,4 @@ build: - make redist tar artifacts: paths: - - build/src/build.tar.gz - -test: - script: - - build/src/INSTALL --auto --install-composer \ No newline at end of file + - build/build.tar.gz \ No newline at end of file -- 2.45.3 From 417603e09dc1afde19267908852f715bcb97418c Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 10:01:16 -0500 Subject: [PATCH 175/212] Minor change --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d4f6562..084173f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,7 +18,7 @@ before_script: build: script: - - make redist tar + - make redist artifacts: paths: - - build/build.tar.gz \ No newline at end of file + - build/src \ No newline at end of file -- 2.45.3 From ab620886c0c5a68737890be1867b93a066c6b77e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 10:05:36 -0500 Subject: [PATCH 176/212] Seperated build & release jobs in .gitlab-ci.yml --- .gitlab-ci.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 084173f..3d6fcbe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,9 +16,17 @@ before_script: # install phpab - phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C -build: +build-job: + script: + - make redist + rules: + - if: $CI_COMMIT_BRANCH + +release-job: script: - make redist artifacts: paths: - - build/src \ No newline at end of file + - build/src + rules: + - if: $CI_COMMIT_TAG \ No newline at end of file -- 2.45.3 From e0262ab1344439165d3afaf72f937e79e5e29e00 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 21 Jan 2023 10:06:12 -0500 Subject: [PATCH 177/212] Changed job names --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3d6fcbe..d240dd9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,13 +16,13 @@ before_script: # install phpab - phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C -build-job: +build: script: - make redist rules: - if: $CI_COMMIT_BRANCH -release-job: +release: script: - make redist artifacts: -- 2.45.3 From 2f711bb509776773933152a4442c742168f236d3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 27 Jan 2023 04:38:26 -0500 Subject: [PATCH 178/212] Various improvements here and there, mostly regarding ExecutionUnits --- src/config/ncc.yaml | 3 - src/installer/installer | 8 +- src/ncc/CLI/Commands/ExecCommand.php | 119 +++++++----------- src/ncc/CLI/Main.php | 22 ++-- src/ncc/CLI/Management/PackageManagerMenu.php | 6 +- src/ncc/CLI/Management/ProjectMenu.php | 1 + src/ncc/Classes/BashExtension/BashRunner.php | 14 +-- .../ComposerSourceBuiltin.php | 3 +- src/ncc/Classes/LuaExtension/LuaRunner.php | 14 +-- .../Classes/NccExtension/PackageCompiler.php | 4 +- src/ncc/Classes/PerlExtension/PerlRunner.php | 14 +-- src/ncc/Classes/PhpExtension/PhpCompiler.php | 14 ++- src/ncc/Classes/PhpExtension/PhpRunner.php | 16 +-- .../Classes/PythonExtension/Python2Runner.php | 14 +-- .../Classes/PythonExtension/Python3Runner.php | 14 +-- .../Classes/PythonExtension/PythonRunner.php | 14 +-- src/ncc/Interfaces/RunnerInterface.php | 8 -- src/ncc/Managers/ExecutionPointerManager.php | 85 +++++++++---- src/ncc/Managers/PackageManager.php | 23 ++-- src/ncc/Managers/RemoteSourcesManager.php | 2 +- src/ncc/Objects/ExecutionPointers.php | 23 +++- .../ExecutionPointers/ExecutionPointer.php | 4 + src/ncc/Objects/Package/ExecutionUnit.php | 3 + src/ncc/Objects/PackageLock/PackageEntry.php | 7 ++ src/ncc/Objects/ProjectConfiguration.php | 37 ++++++ .../Objects/ProjectConfiguration/Build.php | 13 -- .../ProjectConfiguration/ExecutionPolicy.php | 2 +- .../ExecutionPolicy/Execute.php | 11 +- src/ncc/Utilities/PathFinder.php | 11 ++ 29 files changed, 254 insertions(+), 255 deletions(-) diff --git a/src/config/ncc.yaml b/src/config/ncc.yaml index f552647..36c6488 100644 --- a/src/config/ncc.yaml +++ b/src/config/ncc.yaml @@ -19,9 +19,6 @@ ncc: php: # The main executable path for PHP that NCC should use executable_path: "/usr/bin/php" - runtime: - # Whether to initialize NCC when running `require('ncc');` - initialize_on_require: true git: # if git is enabled or not diff --git a/src/installer/installer b/src/installer/installer index a064276..9996434 100644 --- a/src/installer/installer +++ b/src/installer/installer @@ -14,11 +14,11 @@ use ncc\Abstracts\ConsoleColors; use ncc\Exceptions\FileNotFoundException; -use ncc\Managers\RemoteSourcesManager; -use ncc\ncc; + use ncc\Managers\RemoteSourcesManager; + use ncc\ncc; use ncc\Objects\CliHelpSection; -use ncc\Objects\DefinedRemoteSource; -use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException; + use ncc\Objects\DefinedRemoteSource; + use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\ThirdParty\Symfony\Process\Exception\ProcessFailedException; use ncc\ThirdParty\Symfony\Process\ExecutableFinder; diff --git a/src/ncc/CLI/Commands/ExecCommand.php b/src/ncc/CLI/Commands/ExecCommand.php index a5d3171..5411b99 100644 --- a/src/ncc/CLI/Commands/ExecCommand.php +++ b/src/ncc/CLI/Commands/ExecCommand.php @@ -4,9 +4,8 @@ use Exception; use ncc\Managers\ExecutionPointerManager; + use ncc\Managers\PackageLockManager; use ncc\Objects\CliHelpSection; - use ncc\Objects\Package\ExecutionUnit; - use ncc\ThirdParty\Symfony\Process\Process; use ncc\Utilities\Console; use ncc\Utilities\Functions; @@ -21,8 +20,9 @@ public static function start($args): void { $package = $args['package'] ?? null; - $version = $args['version'] ?? 'latest'; - $entry = $args['entry'] ?? null; + $version = $args['exec-version'] ?? 'latest'; + $unit_name = $args['exec-unit'] ?? 'main'; + $set_args = $args['exec-args'] ?? null; if($package == null) { @@ -30,24 +30,32 @@ exit(0); } - $arguments = []; - $whitelist_arguments = [ - 'package', - 'version', - 'entry', - 'help', - ]; - foreach($args as $key => $value) - { - if(!in_array($key, $whitelist_arguments)) - $arguments[$key] = $value; - } - + $package_lock_manager = new PackageLockManager(); $execution_pointer_manager = new ExecutionPointerManager(); try { - $units = $execution_pointer_manager->getUnits($package, $version); + $package_entry = $package_lock_manager->getPackageLock()->getPackage($package); + } + catch(Exception $e) + { + Console::outException('Package ' . $package . ' is not installed', $e, 1); + return; + } + + try + { + $version_entry = $package_entry->getVersion($version); + } + catch(Exception $e) + { + Console::outException('Version ' . $version . ' is not installed', $e, 1); + return; + } + + try + { + $units = $execution_pointer_manager->getUnits($package_entry->Name, $version_entry->Version); } catch(Exception $e) { @@ -55,70 +63,30 @@ return; } - if(!isset($units[$entry])) + if(!in_array($unit_name, $units)) { - Console::outError(sprintf('Cannot find execution point \'%s\' in package \'%s\'', $entry, $package), true, 1); + Console::outError(sprintf('Unit \'%s\' is not configured for package \'%s\'', $unit_name, $package), true, 1); return; } - /** @var ExecutionUnit $exec_unit */ - $exec_unit = $units[$entry]; - $exec_path = ''; + $options = []; - $process = new Process(array_merge([$exec_path], $arguments)); - if($exec_unit->ExecutionPolicy->Execute->Pty !== null) - $process->setPty($exec_unit->ExecutionPolicy->Execute->Pty); - - if($exec_unit->ExecutionPolicy->Execute->Tty !== null) + if($set_args != null) { - $process->setTty($exec_unit->ExecutionPolicy->Execute->Tty); - $process->setPty(false); + global $argv; + $args_index = array_search('--exec-args', $argv); + $options = array_slice($argv, $args_index + 1); } - if($exec_unit->ExecutionPolicy->Execute->WorkingDirectory !== null) - $process->setWorkingDirectory($exec_unit->ExecutionPolicy->Execute->WorkingDirectory); - if($exec_unit->ExecutionPolicy->Execute->EnvironmentVariables !== null) - $process->setEnv($exec_unit->ExecutionPolicy->Execute->EnvironmentVariables); - if($exec_unit->ExecutionPolicy->Execute->Timeout !== null) - $process->setTimeout($exec_unit->ExecutionPolicy->Execute->Timeout); - if($exec_unit->ExecutionPolicy->Execute->IdleTimeout !== null) - $process->setIdleTimeout($exec_unit->ExecutionPolicy->Execute->IdleTimeout); - if($exec_unit->ExecutionPolicy->Execute->Options !== null) - $process->setOptions($exec_unit->ExecutionPolicy->Execute->Options); - - if($process->isTty() || $process->isPty()) + try { - $process->start(); - $process->wait(); + exit($execution_pointer_manager->executeUnit($package_entry->Name, $version_entry->Version, $unit_name, $options)); } - else + catch(Exception $e) { - $process->start(); - - while($process->isRunning()) - { - if($exec_unit->ExecutionPolicy->Execute->Silent) - { - $process->wait(); - } - else - { - $process->waitUntil(function($type, $buffer) - { - if($type == Process::ERR) - { - Console::outError($buffer); - } - else - { - Console::out($buffer); - } - }); - } - } + Console::outException(sprintf('Cannot execute execution point \'%s\' in package \'%s\'', $unit_name, $package), $e, 1); + return; } - - exit(0); } /** @@ -131,8 +99,9 @@ $options = [ new CliHelpSection(['help'], 'Displays this help menu about the value command'), new CliHelpSection(['exec', '--package'], '(Required) The package to execute'), - new CliHelpSection(['--version'], '(default: latest) The version of the package to execute'), - new CliHelpSection(['--entry'], '(default: main) The entry point of the package to execute'), + new CliHelpSection(['--exec-version'], '(default: latest) The version of the package to execute'), + new CliHelpSection(['--exec-unit'], '(default: main) The unit point of the package to execute'), + new CliHelpSection(['--exec-args'], '(optional) Anything past this point will be passed to the execution unit'), ]; $options_padding = Functions::detectParametersPadding($options) + 4; @@ -148,8 +117,8 @@ Console::out(' The arguments to pass to the program'); Console::out(PHP_EOL . 'Example Usage:' . PHP_EOL); Console::out(' ncc exec --package com.example.program'); - Console::out(' ncc exec --package com.example.program --version 1.0.0'); - Console::out(' ncc exec --package com.example.program --version 1.0.0 --entry setup'); - Console::out(' ncc exec --package com.example.program --foo --bar --extra=test'); + Console::out(' ncc exec --package com.example.program --exec-version 1.0.0'); + Console::out(' ncc exec --package com.example.program --exec-version 1.0.0 --unit setup'); + Console::out(' ncc exec --package com.example.program --exec-args --foo --bar --extra=test'); } } \ No newline at end of file diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index a0f03d0..7b0a308 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -8,6 +8,7 @@ use ncc\Abstracts\LogLevel; use ncc\Abstracts\NccBuildFlags; use ncc\CLI\Commands\BuildCommand; + use ncc\CLI\Commands\ExecCommand; use ncc\CLI\Management\ConfigMenu; use ncc\CLI\Management\CredentialMenu; use ncc\CLI\Management\PackageManagerMenu; @@ -107,36 +108,40 @@ { default: Console::out('Unknown command ' . strtolower(self::$args['ncc-cli'])); - exit(1); + break; case 'project': ProjectMenu::start(self::$args); - exit(0); + break; case 'build': BuildCommand::start(self::$args); - exit(0); + break; + + case 'exec': + ExecCommand::start(self::$args); + break; case 'cred': CredentialMenu::start(self::$args); - exit(0); + break; case 'package': PackageManagerMenu::start(self::$args); - exit(0); + break; case 'config': ConfigMenu::start(self::$args); - exit(0); + break; case 'source': SourcesMenu::start(self::$args); - exit(0); + break; case '1': case 'help': HelpMenu::start(self::$args); - exit(0); + break; } } catch(Exception $e) @@ -145,6 +150,7 @@ exit(1); } + exit(0); } } diff --git a/src/ncc/CLI/Management/PackageManagerMenu.php b/src/ncc/CLI/Management/PackageManagerMenu.php index c8b0982..2b4ebab 100644 --- a/src/ncc/CLI/Management/PackageManagerMenu.php +++ b/src/ncc/CLI/Management/PackageManagerMenu.php @@ -256,6 +256,7 @@ $package_version = $package_manager->getPackageVersion($package, $version); if($package_version == null) continue; + Console::out(sprintf('%s=%s (%s)', Console::formatColor($package, ConsoleColors::LightGreen), Console::formatColor($version, ConsoleColors::LightMagenta), @@ -265,9 +266,10 @@ catch(Exception $e) { unset($e); - Console::out(sprintf('%s=%s', + Console::out(sprintf('%s=%s (%s)', Console::formatColor($package, ConsoleColors::LightGreen), - Console::formatColor($version, ConsoleColors::LightMagenta) + Console::formatColor($version, ConsoleColors::LightMagenta), + Console::formatColor('N/A', ConsoleColors::LightRed) )); } } diff --git a/src/ncc/CLI/Management/ProjectMenu.php b/src/ncc/CLI/Management/ProjectMenu.php index 233ceb2..1eab0bf 100644 --- a/src/ncc/CLI/Management/ProjectMenu.php +++ b/src/ncc/CLI/Management/ProjectMenu.php @@ -64,6 +64,7 @@ else { Console::outError('The selected source directory \'' . $full_path . '\' was not found or is not a directory', true, 1); + return; } } else diff --git a/src/ncc/Classes/BashExtension/BashRunner.php b/src/ncc/Classes/BashExtension/BashRunner.php index 6a8e953..f9aaf5d 100644 --- a/src/ncc/Classes/BashExtension/BashRunner.php +++ b/src/ncc/Classes/BashExtension/BashRunner.php @@ -26,7 +26,7 @@ throw new FileNotFoundException($path); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -38,16 +38,4 @@ { return '.bash'; } - - /** - * @inheritDoc - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $bash_bin = PathFinder::findRunner(Runners::bash); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$bash_bin, '-c', $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$bash_bin, '-c', $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index 55da655..79583e1 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -479,7 +479,8 @@ self::prepareProcess($process, $tmp_dir, $options); Console::outDebug(sprintf('executing %s', $process->getCommandLine())); - $process->run(function ($type, $buffer) { + $process->run(function ($type, $buffer) + { Console::out($buffer, false); }); diff --git a/src/ncc/Classes/LuaExtension/LuaRunner.php b/src/ncc/Classes/LuaExtension/LuaRunner.php index fba88c4..fa15e75 100644 --- a/src/ncc/Classes/LuaExtension/LuaRunner.php +++ b/src/ncc/Classes/LuaExtension/LuaRunner.php @@ -23,7 +23,7 @@ $execution_unit = new ExecutionUnit(); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -35,16 +35,4 @@ { return '.lua'; } - - /** - * @inheritDoc - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $lua_bin = PathFinder::findRunner(Runners::lua); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$lua_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$lua_bin, $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index bc90f78..c9de1a0 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -157,6 +157,8 @@ /** @var ProjectConfiguration\ExecutionPolicy $policy */ foreach($configuration->ExecutionPolicies as $policy) { + Console::outVerbose(sprintf('Compiling Execution Policy %s', $policy->Name)); + if($total_items > 5) { Console::inlineProgressBar($processed_items, $total_items); @@ -245,7 +247,7 @@ $units = []; foreach($package->ExecutionUnits as $executionUnit) { - Console::outDebug(sprintf('compiling execution unit consts %s (%s)', $executionUnit->Name, implode(', ', array_keys($refs)))); + Console::outDebug(sprintf('compiling execution unit consts %s (%s)', $executionUnit->ExecutionPolicy->Name, implode(', ', array_keys($refs)))); $units[] = self::compileExecutionUnitConstants($executionUnit, $refs); } $package->ExecutionUnits = $units; diff --git a/src/ncc/Classes/PerlExtension/PerlRunner.php b/src/ncc/Classes/PerlExtension/PerlRunner.php index 0be4cdb..325badc 100644 --- a/src/ncc/Classes/PerlExtension/PerlRunner.php +++ b/src/ncc/Classes/PerlExtension/PerlRunner.php @@ -26,7 +26,7 @@ if(!file_exists($path) && !is_file($path)) throw new FileNotFoundException($path); $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -38,16 +38,4 @@ { return '.pl'; } - - /** - * @inheritDoc - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $perl_bin = PathFinder::findRunner(Runners::perl); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$perl_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$perl_bin, $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index f9a74e9..a422f84 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -92,14 +92,14 @@ $this->package->MainExecutionPolicy = $this->project->Build->Main; // Add the option to create a symbolic link to the package - if($this->project->Build->CreateSymlink) + if(isset($this->project->Project->Options['create_symlink']) && $this->project->Project->Options['create_symlink'] === True) $this->package->Header->Options['create_symlink'] = true; // Add both the defined constants from the build configuration and the global constants. // Global constants are overridden $this->package->Header->RuntimeConstants = []; $this->package->Header->RuntimeConstants = array_merge( - ($selected_build_configuration?->DefineConstants ?? []), + ($selected_build_configuration->DefineConstants ?? []), ($this->project->Build->DefineConstants ?? []), ($this->package->Header->RuntimeConstants ?? []) ); @@ -108,6 +108,10 @@ $this->package->Header->CompilerVersion = NCC_VERSION_NUMBER; $this->package->Header->Options = $this->project->Project->Options; + if($this->project->Project->UpdateSource !== null) + { + $this->package->Header->UpdateSource = $this->project->Project->UpdateSource; + } Console::outDebug('scanning project files'); Console::outDebug('theseer\DirectoryScanner - Copyright (c) 2009-2014 Arne Blankerts All rights reserved.'); @@ -161,8 +165,8 @@ } // Clear previous excludes and includes - $DirectoryScanner->setExcludes([]); - $DirectoryScanner->setIncludes([]); + $DirectoryScanner->setExcludes(); + $DirectoryScanner->setIncludes(); // Ignore component files if($selected_build_configuration->ExcludeFiles !== null && count($selected_build_configuration->ExcludeFiles) > 0) @@ -423,7 +427,7 @@ */ public function compileExecutionPolicies(): void { - PackageCompiler::compileExecutionPolicies($this->path, $this->project); + $this->package->ExecutionUnits = PackageCompiler::compileExecutionPolicies($this->path, $this->project); } /** diff --git a/src/ncc/Classes/PhpExtension/PhpRunner.php b/src/ncc/Classes/PhpExtension/PhpRunner.php index 6792057..962ae44 100644 --- a/src/ncc/Classes/PhpExtension/PhpRunner.php +++ b/src/ncc/Classes/PhpExtension/PhpRunner.php @@ -33,7 +33,7 @@ throw new FileNotFoundException($path); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -47,18 +47,4 @@ { return '.php'; } - - /** - * @param ExecutionPointer $pointer - * @return Process - * @throws RunnerExecutionException - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $php_bin = PathFinder::findRunner(Runners::php); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$php_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$php_bin, $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Classes/PythonExtension/Python2Runner.php b/src/ncc/Classes/PythonExtension/Python2Runner.php index 0f8ca05..ddbaa0f 100644 --- a/src/ncc/Classes/PythonExtension/Python2Runner.php +++ b/src/ncc/Classes/PythonExtension/Python2Runner.php @@ -26,7 +26,7 @@ throw new FileNotFoundException($path); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -38,16 +38,4 @@ { return '.py'; } - - /** - * @inheritDoc - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $python_bin = PathFinder::findRunner(Runners::python2); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$python_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$python_bin, $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Classes/PythonExtension/Python3Runner.php b/src/ncc/Classes/PythonExtension/Python3Runner.php index 94b5447..a610d21 100644 --- a/src/ncc/Classes/PythonExtension/Python3Runner.php +++ b/src/ncc/Classes/PythonExtension/Python3Runner.php @@ -26,7 +26,7 @@ throw new FileNotFoundException($path); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -38,16 +38,4 @@ { return '.py'; } - - /** - * @inheritDoc - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $python_bin = PathFinder::findRunner(Runners::python3); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$python_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$python_bin, $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Classes/PythonExtension/PythonRunner.php b/src/ncc/Classes/PythonExtension/PythonRunner.php index d3b2baa..ed40778 100644 --- a/src/ncc/Classes/PythonExtension/PythonRunner.php +++ b/src/ncc/Classes/PythonExtension/PythonRunner.php @@ -26,7 +26,7 @@ throw new FileNotFoundException($path); $policy->Execute->Target = null; $execution_unit->ExecutionPolicy = $policy; - $execution_unit->Data = Base64::encode(IO::fread($path)); + $execution_unit->Data = IO::fread($path); return $execution_unit; } @@ -38,16 +38,4 @@ { return '.py'; } - - /** - * @inheritDoc - */ - public static function prepareProcess(ExecutionPointer $pointer): Process - { - $python_bin = PathFinder::findRunner(Runners::python); - - if($pointer->ExecutionPolicy->Execute->Options !== null && count($pointer->ExecutionPolicy->Execute->Options) > 0) - return new Process(array_merge([$python_bin, $pointer->FilePointer], $pointer->ExecutionPolicy->Execute->Options)); - return new Process([$python_bin, $pointer->FilePointer]); - } } \ No newline at end of file diff --git a/src/ncc/Interfaces/RunnerInterface.php b/src/ncc/Interfaces/RunnerInterface.php index 1d92644..bd0c73f 100644 --- a/src/ncc/Interfaces/RunnerInterface.php +++ b/src/ncc/Interfaces/RunnerInterface.php @@ -32,12 +32,4 @@ */ public static function getFileExtension(): string; - /** - * Prepares a process object for the execution pointer - * - * @param ExecutionPointer $pointer - * @return Process - * @throws RunnerExecutionException - */ - public static function prepareProcess(ExecutionPointer $pointer): Process; } \ No newline at end of file diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 9b89551..f522625 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -9,6 +9,7 @@ use ncc\Abstracts\Scopes; use ncc\Classes\BashExtension\BashRunner; use ncc\Classes\LuaExtension\LuaRunner; + use ncc\Classes\NccExtension\ConstantCompiler; use ncc\Classes\PerlExtension\PerlRunner; use ncc\Classes\PhpExtension\PhpRunner; use ncc\Classes\PythonExtension\Python2Runner; @@ -109,6 +110,7 @@ */ private function getPackageId(string $package, string $version): string { + Console::outDebug(sprintf('calculating package id for %s=%s', $package, $version)); return hash('haval128,4', $package . $version); } @@ -263,8 +265,14 @@ $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; + Console::outDebug(sprintf('package_id=%s', $package_id)); + Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); + if(!file_exists($package_config_path)) + { + Console::outWarning(sprintf('Path \'%s\' does not exist', $package_config_path)); return []; + } $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); $results = []; @@ -277,20 +285,40 @@ return $results; } - public function getUnit(string $package, string $version, string $name): ExecutionUnit + /** + * Returns an existing ExecutionUnit for a package version + * + * @param string $package + * @param string $version + * @param string $name + * @return ExecutionPointers\ExecutionPointer + * @throws AccessDeniedException + * @throws FileNotFoundException + * @throws IOException + */ + public function getUnit(string $package, string $version, string $name): ExecutionPointers\ExecutionPointer { - Console::outVerbose(sprintf('getting execution unit %s for %s', $name, $package)); + /** @noinspection DuplicatedCode */ + if(Resolver::resolveScope() !== Scopes::System) + throw new AccessDeniedException('Cannot remove ExecutionUnit \'' . $name .'\' for ' . $package . ', insufficient permissions'); + + Console::outVerbose(sprintf('Removing ExecutionUnit \'%s\' for %s', $name, $package)); $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; + $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; - if(!file_exists($package_config_path)) - throw new NoAvailableUnitsException('No ExecutionUnits available for ' . $package); + Console::outDebug(sprintf('package_id=%s', $package_id)); + Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); + Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); + $filesystem = new Filesystem(); + if(!$filesystem->exists($package_config_path)) + { + throw new FileNotFoundException(sprintf('Path \'%s\' does not exist', $package_config_path)); + } $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); - $unit = $execution_pointers->getUnit($name); - - + return $execution_pointers->getUnit($name); } /** @@ -299,16 +327,17 @@ * @param string $package * @param string $version * @param string $name - * @return void + * @param array $args + * @return int * @throws AccessDeniedException * @throws ExecutionUnitNotFoundException * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException - * @throws UnsupportedRunnerException * @throws RunnerExecutionException + * @throws UnsupportedRunnerException */ - public function executeUnit(string $package, string $version, string $name): void + public function executeUnit(string $package, string $version, string $name, array $args=[]): int { Console::outVerbose(sprintf('executing unit %s for %s', $name, $package)); @@ -327,23 +356,33 @@ Console::outDebug(sprintf('unit=%s', $unit->ExecutionPolicy->Name)); Console::outDebug(sprintf('runner=%s', $unit->ExecutionPolicy->Runner)); Console::outDebug(sprintf('file=%s', $unit->FilePointer)); + Console::outDebug(sprintf('pass_thru_args=%s', json_encode($args, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE))); - $process = match (strtolower($unit->ExecutionPolicy->Runner)) + // Handle the arguments + if($unit->ExecutionPolicy->Execute->Options !== null && count($unit->ExecutionPolicy->Execute->Options) > 0) { - Runners::bash => BashRunner::prepareProcess($unit), - Runners::php => PhpRunner::prepareProcess($unit), - Runners::perl => PerlRunner::prepareProcess($unit), - Runners::python => PythonRunner::prepareProcess($unit), - Runners::python2 => Python2Runner::prepareProcess($unit), - Runners::python3 => Python3Runner::prepareProcess($unit), - Runners::lua => LuaRunner::prepareProcess($unit), - default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), - }; + $args = array_merge($args, $unit->ExecutionPolicy->Execute->Options); + + foreach($unit->ExecutionPolicy->Execute->Options as $option) + { + $args[] = ConstantCompiler::compileRuntimeConstants($option); + } + } + + $process = new Process(array_merge([ + PathFinder::findRunner(strtolower($unit->ExecutionPolicy->Runner)), + $unit->FilePointer + ], $args)); if($unit->ExecutionPolicy->Execute->WorkingDirectory !== null) - $process->setWorkingDirectory($unit->ExecutionPolicy->Execute->WorkingDirectory); + { + $process->setWorkingDirectory(ConstantCompiler::compileRuntimeConstants($unit->ExecutionPolicy->Execute->WorkingDirectory)); + } + if($unit->ExecutionPolicy->Execute->Timeout !== null) + { $process->setTimeout((float)$unit->ExecutionPolicy->Execute->Timeout); + } if($unit->ExecutionPolicy->Execute->Silent) { @@ -364,6 +403,8 @@ Console::outDebug(sprintf('timeout=%s', ($process->getTimeout() ?? 0))); Console::outDebug(sprintf('silent=%s', ($unit->ExecutionPolicy->Execute->Silent ? 'true' : 'false'))); Console::outDebug(sprintf('tty=%s', ($unit->ExecutionPolicy->Execute->Tty ? 'true' : 'false'))); + Console::outDebug(sprintf('options=%s', implode(' ', $args))); + Console::outDebug(sprintf('cmd=%s', $process->getCommandLine())); try { @@ -402,6 +443,8 @@ $this->handleExit($package, $version, $unit->ExecutionPolicy->ExitHandlers->Error, $process); } } + + return $process->getExitCode(); } /** diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 3b4e6cc..86c4eca 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -309,13 +309,15 @@ } // Install execution units - if(count($package->ExecutionUnits) > 0) + if($package->ExecutionUnits !== null && count($package->ExecutionUnits) > 0) { $execution_pointer_manager = new ExecutionPointerManager(); $unit_paths = []; + /** @var Package\ExecutionUnit $executionUnit */ foreach($package->ExecutionUnits as $executionUnit) { + Console::outDebug(sprintf('processing execution unit %s', $executionUnit->ExecutionPolicy->Name)); $execution_pointer_manager->addUnit($package->Assembly->Package, $package->Assembly->Version, $executionUnit); $current_steps += 1; Console::inlineProgressBar($current_steps, $steps); @@ -751,14 +753,21 @@ try { $version_entry = $this->getPackageVersion($package_e[0], $package_e[1]); - $tree[$package] = null; - if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0) + if($version_entry == null) { - $tree[$package] = []; - foreach($version_entry->Dependencies as $dependency) + Console::outWarning('Version ' . $package_e[1] . ' of package ' . $package_e[0] . ' not found'); + } + else + { + $tree[$package] = null; + if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0) { - $dependency_name = sprintf('%s=%s', $dependency->PackageName, $dependency->Version); - $tree[$package] = $this->getPackageTree($tree[$package], $dependency_name); + $tree[$package] = []; + foreach($version_entry->Dependencies as $dependency) + { + $dependency_name = sprintf('%s=%s', $dependency->PackageName, $dependency->Version); + $tree[$package] = $this->getPackageTree($tree[$package], $dependency_name); + } } } } diff --git a/src/ncc/Managers/RemoteSourcesManager.php b/src/ncc/Managers/RemoteSourcesManager.php index 95f156b..f1e3df1 100644 --- a/src/ncc/Managers/RemoteSourcesManager.php +++ b/src/ncc/Managers/RemoteSourcesManager.php @@ -37,7 +37,7 @@ public function __construct() { /** @noinspection PhpUnhandledExceptionInspection */ - $this->DefinedSourcesPath = PathFinder::getRemouteSources(Scopes::System); + $this->DefinedSourcesPath = PathFinder::getRemoteSources(Scopes::System); $this->load(); } diff --git a/src/ncc/Objects/ExecutionPointers.php b/src/ncc/Objects/ExecutionPointers.php index 9181c03..ceedb5b 100644 --- a/src/ncc/Objects/ExecutionPointers.php +++ b/src/ncc/Objects/ExecutionPointers.php @@ -7,6 +7,7 @@ use ncc\Exceptions\FileNotFoundException; use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; + use ncc\Utilities\Functions; use ncc\Utilities\Validate; class ExecutionPointers @@ -41,8 +42,10 @@ * Adds an Execution Unit as a pointer * * @param ExecutionUnit $unit + * @param string $bin_file * @param bool $overwrite * @return bool + * @throws FileNotFoundException */ public function addUnit(ExecutionUnit $unit, string $bin_file, bool $overwrite=true): bool { @@ -96,6 +99,7 @@ */ public function getUnit(string $name): ?ExecutionPointer { + /** @var ExecutionPointer $pointer */ foreach($this->Pointers as $pointer) { if($pointer->ExecutionPolicy->Name == $name) @@ -148,7 +152,11 @@ { $pointers[] = $pointer->toArray($bytecode); } - return $pointers; + return [ + ($bytecode ? Functions::cbc('package') : 'package') => $this->Package, + ($bytecode ? Functions::cbc('version') : 'version') => $this->Version, + ($bytecode ? Functions::cbc('pointers') : 'pointers') => $pointers + ]; } /** @@ -161,9 +169,18 @@ { $object = new self(); - foreach($data as $datum) + $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) { - $object->Pointers[] = ExecutionPointer::fromArray($datum); + $pointers = []; + foreach($object->Pointers as $pointer) + { + $pointers[] = ExecutionPointer::fromArray($pointer); + } + $object->Pointers = $pointers; } return $object; diff --git a/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php b/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php index 9a5747e..4328640 100644 --- a/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php +++ b/src/ncc/Objects/ExecutionPointers/ExecutionPointer.php @@ -33,6 +33,7 @@ * Public Constructor with optional ExecutionUnit parameter to construct object from * * @param ExecutionUnit|null $unit + * @param string|null $bin_file */ public function __construct(?ExecutionUnit $unit=null, ?string $bin_file=null) { @@ -73,6 +74,9 @@ $object->ExecutionPolicy = Functions::array_bc($data, 'execution_policy'); $object->FilePointer = Functions::array_bc($data, 'file_pointer'); + if($object->ExecutionPolicy !== null) + $object->ExecutionPolicy = ExecutionPolicy::fromArray($object->ExecutionPolicy); + return $object; } } \ No newline at end of file diff --git a/src/ncc/Objects/Package/ExecutionUnit.php b/src/ncc/Objects/Package/ExecutionUnit.php index 75940cc..fd02648 100644 --- a/src/ncc/Objects/Package/ExecutionUnit.php +++ b/src/ncc/Objects/Package/ExecutionUnit.php @@ -55,6 +55,9 @@ $object->ExecutionPolicy = Functions::array_bc($data, 'execution_policy'); $object->Data = Functions::array_bc($data, 'data'); + if($object->ExecutionPolicy !== null) + $object->ExecutionPolicy = ExecutionPolicy::fromArray($object->ExecutionPolicy); + return $object; } diff --git a/src/ncc/Objects/PackageLock/PackageEntry.php b/src/ncc/Objects/PackageLock/PackageEntry.php index 2c58990..3a301e5 100644 --- a/src/ncc/Objects/PackageLock/PackageEntry.php +++ b/src/ncc/Objects/PackageLock/PackageEntry.php @@ -5,6 +5,7 @@ namespace ncc\Objects\PackageLock; use ncc\Abstracts\Scopes; + use ncc\Abstracts\Versions; use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\VersionNotFoundException; @@ -64,6 +65,9 @@ */ public function getVersion(string $version, bool $throw_exception=false): ?VersionEntry { + if($version == Versions::Latest) + $version = $this->LatestVersion; + foreach($this->Versions as $versionEntry) { if($versionEntry->Version == $version) @@ -142,6 +146,9 @@ $version->MainExecutionPolicy = $package->MainExecutionPolicy; $version->Location = $install_path; + foreach($version->ExecutionUnits as $unit) + $unit->Data = null; + foreach($package->Dependencies as $dependency) { $version->Dependencies[] = new DependencyEntry($dependency); diff --git a/src/ncc/Objects/ProjectConfiguration.php b/src/ncc/Objects/ProjectConfiguration.php index 216091f..4d49f68 100644 --- a/src/ncc/Objects/ProjectConfiguration.php +++ b/src/ncc/Objects/ProjectConfiguration.php @@ -9,6 +9,7 @@ use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\BuildConfigurationNotFoundException; use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\InvalidBuildConfigurationException; use ncc\Exceptions\InvalidConstantNameException; use ncc\Exceptions\InvalidProjectBuildConfiguration; use ncc\Exceptions\InvalidProjectConfigurationException; @@ -93,6 +94,7 @@ * @throws UndefinedExecutionPolicyException * @throws UnsupportedCompilerExtensionException * @throws UnsupportedExtensionVersionException + * @throws InvalidBuildConfigurationException */ public function validate(bool $throw_exception=True): bool { @@ -116,6 +118,41 @@ return false; } + if($this->Build->Main !== null) + { + if($this->ExecutionPolicies == null || count($this->ExecutionPolicies) == 0) + { + if($throw_exception) + throw new UndefinedExecutionPolicyException(sprintf('Build configuration build.main uses an execution policy "%s" but no policies are defined', $this->Build->Main)); + return false; + } + + + $found = false; + foreach($this->ExecutionPolicies as $policy) + { + if($policy->Name == $this->Build->Main) + { + $found = true; + break; + } + } + + if(!$found) + { + if($throw_exception) + throw new UndefinedExecutionPolicyException(sprintf('Build configuration build.main points to a undefined execution policy "%s"', $this->Build->Main)); + return false; + } + + if($this->Build->Main == BuildConfigurationValues::AllConfigurations) + { + if($throw_exception) + throw new InvalidBuildConfigurationException(sprintf('Build configuration build.main cannot be set to "%s"', BuildConfigurationValues::AllConfigurations)); + return false; + } + } + return true; } diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index 6f095f3..cbb3cd7 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -61,14 +61,6 @@ */ public $Main; - /** - * If Main is not null, and this is true. - * NCC Will create a symlink to the main executable in the installation directory. - * - * @var bool - */ - public $CreateSymlink; - /** * An array of constants to define by default * @@ -114,7 +106,6 @@ $this->DefineConstants = []; $this->Dependencies = []; $this->Configurations = []; - $this->CreateSymlink = false; } /** @@ -286,10 +277,7 @@ if($this->Scope !== null) $ReturnResults[($bytecode ? Functions::cbc('scope') : 'scope')] = $this->Scope; if($this->Main !== null) - { $ReturnResults[($bytecode ? Functions::cbc('main') : 'main')] = $this->Main; - $ReturnResults[($bytecode ? Functions::cbc('create_symlink') : 'create_symlink')] = $this->CreateSymlink; - } if($this->DefineConstants !== null && count($this->DefineConstants) > 0) $ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants; if($this->PreBuild !== null && count($this->PreBuild) > 0) @@ -334,7 +322,6 @@ $BuildObject->Options = (Functions::array_bc($data, 'options') ?? []); $BuildObject->Scope = Functions::array_bc($data, 'scope'); $BuildObject->Main = Functions::array_bc($data, 'main'); - $BuildObject->CreateSymlink = (Functions::array_bc($data, 'create_symlink') ?? false); $BuildObject->DefineConstants = (Functions::array_bc($data, 'define_constants') ?? []); $BuildObject->PreBuild = (Functions::array_bc($data, 'pre_build') ?? []); $BuildObject->PostBuild = (Functions::array_bc($data, 'post_build') ?? []); diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php index be98067..7a2f488 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php @@ -94,7 +94,7 @@ $object->Name = Functions::array_bc($data, 'name'); $object->Runner = Functions::array_bc($data, 'runner'); $object->Message = Functions::array_bc($data, 'message'); - $object->Execute = Functions::array_bc($data, 'exec'); + $object->Execute = Functions::array_bc($data, 'execute'); $object->ExitHandlers = Functions::array_bc($data, 'exit_handlers'); if($object->Execute !== null) diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php index b9184e6..0edf196 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy/Execute.php @@ -24,9 +24,9 @@ public $WorkingDirectory; /** - * An array of options to pass on to the process + * Options to pass to the process * - * @var array|null + * @var array */ public $Options; @@ -51,13 +51,6 @@ */ public $Tty; - /** - * Indicates if the process should run in Pty mode (Overrides Silent mode) - * - * @var bool|null - */ - public $Pty; - /** * The number of seconds to wait before giving up on the process, will automatically execute the error handler * if one is set. diff --git a/src/ncc/Utilities/PathFinder.php b/src/ncc/Utilities/PathFinder.php index 8093f7d..a2ea82e 100644 --- a/src/ncc/Utilities/PathFinder.php +++ b/src/ncc/Utilities/PathFinder.php @@ -184,6 +184,17 @@ return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'sources'; } + /** + * @param string $scope + * @param bool $win32 + * @return string + * @throws InvalidScopeException + */ + public static function getSymlinkDictionary(string $scope=Scopes::Auto, bool $win32=false): string + { + return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'symlinks'; + } + /** * Returns an array of all the package lock files the current user can access (For global-cross referencing) * -- 2.45.3 From a5c1124b6b0f899b1c0c5fe7fb497bb5c13a0a24 Mon Sep 17 00:00:00 2001 From: Netkas Date: Fri, 27 Jan 2023 04:50:45 -0500 Subject: [PATCH 179/212] Removed unused method getUnit() in \ncc\Managers > ExecutionPointerManager --- src/ncc/Managers/ExecutionPointerManager.php | 36 -------------------- 1 file changed, 36 deletions(-) diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index f522625..5676ae9 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -285,42 +285,6 @@ return $results; } - /** - * Returns an existing ExecutionUnit for a package version - * - * @param string $package - * @param string $version - * @param string $name - * @return ExecutionPointers\ExecutionPointer - * @throws AccessDeniedException - * @throws FileNotFoundException - * @throws IOException - */ - public function getUnit(string $package, string $version, string $name): ExecutionPointers\ExecutionPointer - { - /** @noinspection DuplicatedCode */ - if(Resolver::resolveScope() !== Scopes::System) - throw new AccessDeniedException('Cannot remove ExecutionUnit \'' . $name .'\' for ' . $package . ', insufficient permissions'); - - Console::outVerbose(sprintf('Removing ExecutionUnit \'%s\' for %s', $name, $package)); - - $package_id = $this->getPackageId($package, $version); - $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; - $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; - - Console::outDebug(sprintf('package_id=%s', $package_id)); - Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); - Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); - - $filesystem = new Filesystem(); - if(!$filesystem->exists($package_config_path)) - { - throw new FileNotFoundException(sprintf('Path \'%s\' does not exist', $package_config_path)); - } - $execution_pointers = ExecutionPointers::fromArray(ZiProto::decode(IO::fread($package_config_path))); - return $execution_pointers->getUnit($name); - } - /** * Executes a unit * -- 2.45.3 From bf73360f2cb21e17a5bf97228abc25665b6c8c9d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 06:21:20 -0500 Subject: [PATCH 180/212] Implemented Symlinks --- src/ncc/CLI/Commands/ExecCommand.php | 2 +- src/ncc/Managers/ExecutionPointerManager.php | 40 +- src/ncc/Managers/PackageLockManager.php | 11 + src/ncc/Managers/PackageManager.php | 12 +- src/ncc/Managers/SymlinkManager.php | 358 ++++++++++++++++++ src/ncc/Objects/SymlinkDictionary.php | 8 + .../SymlinkDictionary/SymlinkEntry.php | 73 ++++ src/ncc/ncc.php | 9 +- 8 files changed, 503 insertions(+), 10 deletions(-) create mode 100644 src/ncc/Managers/SymlinkManager.php create mode 100644 src/ncc/Objects/SymlinkDictionary.php create mode 100644 src/ncc/Objects/SymlinkDictionary/SymlinkEntry.php diff --git a/src/ncc/CLI/Commands/ExecCommand.php b/src/ncc/CLI/Commands/ExecCommand.php index 5411b99..30826a9 100644 --- a/src/ncc/CLI/Commands/ExecCommand.php +++ b/src/ncc/CLI/Commands/ExecCommand.php @@ -118,7 +118,7 @@ Console::out(PHP_EOL . 'Example Usage:' . PHP_EOL); Console::out(' ncc exec --package com.example.program'); Console::out(' ncc exec --package com.example.program --exec-version 1.0.0'); - Console::out(' ncc exec --package com.example.program --exec-version 1.0.0 --unit setup'); + Console::out(' ncc exec --package com.example.program --exec-version 1.0.0 --exec-unit setup'); Console::out(' ncc exec --package com.example.program --exec-args --foo --bar --extra=test'); } } \ No newline at end of file diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index 5676ae9..6d68eb1 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -114,6 +114,27 @@ return hash('haval128,4', $package . $version); } + /** + * Returns the path to the execution pointer file + * + * @param string $package + * @param string $version + * @param string $name + * @return string + * @throws FileNotFoundException + */ + public function getEntryPointPath(string $package, string $version, string $name): string + { + $package_id = $this->getPackageId($package, $version); + $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; + $entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $name) . '.entrypoint'; + + if(!file_exists($entry_point_path)) + throw new FileNotFoundException('Cannot find entry point for ' . $package . '=' . $version . '.' . $name); + + return $entry_point_path; + } + /** * Adds a new Execution Unit to the * @@ -139,10 +160,12 @@ $package_id = $this->getPackageId($package, $version); $package_config_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id . '.inx'; $package_bin_path = $this->RunnerPath . DIRECTORY_SEPARATOR . $package_id; + $entry_point_path = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name) . '.entrypoint'; Console::outDebug(sprintf('package_id=%s', $package_id)); Console::outDebug(sprintf('package_config_path=%s', $package_config_path)); Console::outDebug(sprintf('package_bin_path=%s', $package_bin_path)); + Console::outDebug(sprintf('entry_point_path=%s', $entry_point_path)); $filesystem = new Filesystem(); @@ -184,6 +207,16 @@ $execution_pointers->addUnit($unit, $bin_file); IO::fwrite($package_config_path, ZiProto::encode($execution_pointers->toArray(true))); + $entry_point = sprintf("#!%s\nncc exec --package=\"%s\" --exec-version=\"%s\" --exec-unit=\"%s\" --exec-args \"$@\"", + '/bin/bash', + $package, $version, $unit->ExecutionPolicy->Name + ); + + if(file_exists($entry_point_path)) + $filesystem->remove($entry_point_path); + IO::fwrite($entry_point_path, $entry_point); + chmod($entry_point_path, 0755); + if($temporary) { Console::outVerbose(sprintf('Adding temporary ExecutionUnit \'%s\' for %s', $unit->ExecutionPolicy->Name, $package)); @@ -333,10 +366,9 @@ } } - $process = new Process(array_merge([ - PathFinder::findRunner(strtolower($unit->ExecutionPolicy->Runner)), - $unit->FilePointer - ], $args)); + $process = new Process(array_merge( + [PathFinder::findRunner(strtolower($unit->ExecutionPolicy->Runner)), $unit->FilePointer], $args) + ); if($unit->ExecutionPolicy->Execute->WorkingDirectory !== null) { diff --git a/src/ncc/Managers/PackageLockManager.php b/src/ncc/Managers/PackageLockManager.php index 56d7daf..23215d6 100644 --- a/src/ncc/Managers/PackageLockManager.php +++ b/src/ncc/Managers/PackageLockManager.php @@ -125,6 +125,17 @@ { throw new PackageLockException('Cannot save the package lock file to disk', $e); } + + try + { + Console::outDebug('synchronizing symlinks'); + $symlink_manager = new SymlinkManager(); + $symlink_manager->sync(); + } + catch(Exception $e) + { + throw new PackageLockException('Failed to synchronize symlinks', $e); + } } /** diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 86c4eca..b60d8b3 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -326,11 +326,14 @@ IO::fwrite($installation_paths->getDataPath() . DIRECTORY_SEPARATOR . 'exec', ZiProto::encode($unit_paths)); } + // After execution units are installed, create a symlink if needed if(isset($package->Header->Options['create_symlink']) && $package->Header->Options['create_symlink']) { - $paths = [ - DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'bin' - ]; + if($package->MainExecutionPolicy === null) + throw new InstallationException('Cannot create symlink, no main execution policy is defined'); + + $SymlinkManager = new SymlinkManager(); + $SymlinkManager->add($package->Assembly->Package, $package->MainExecutionPolicy); } // Execute the post-installation stage after the installation is complete @@ -847,6 +850,9 @@ Console::outDebug(sprintf('warning: removing execution unit %s failed', $executionUnit->ExecutionPolicy->Name)); } } + + $symlink_manager = new SymlinkManager(); + $symlink_manager->sync(); } /** diff --git a/src/ncc/Managers/SymlinkManager.php b/src/ncc/Managers/SymlinkManager.php new file mode 100644 index 0000000..4f9d018 --- /dev/null +++ b/src/ncc/Managers/SymlinkManager.php @@ -0,0 +1,358 @@ +SymlinkDictionaryPath = PathFinder::getSymlinkDictionary(Scopes::System); + $this->load(); + } + catch(Exception $e) + { + Console::outWarning(sprintf('failed to load symlink dictionary from %s', $this->SymlinkDictionaryPath)); + } + finally + { + if($this->SymlinkDictionary === null) + $this->SymlinkDictionary = []; + + unset($e); + } + } + + /** + * Loads the symlink dictionary from the file + * + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + public function load(): void + { + if($this->SymlinkDictionary !== null) + return; + + Console::outDebug(sprintf('loading symlink dictionary from %s', $this->SymlinkDictionaryPath)); + + if(!file_exists($this->SymlinkDictionaryPath)) + { + Console::outDebug('symlink dictionary does not exist, creating new dictionary'); + $this->SymlinkDictionary = []; + $this->save(false); + return; + } + + try + { + $this->SymlinkDictionary = []; + + foreach(ZiProto::decode(IO::fread($this->SymlinkDictionaryPath)) as $entry) + { + $this->SymlinkDictionary[] = SymlinkEntry::fromArray($entry); + } + } + catch(Exception $e) + { + $this->SymlinkDictionary = []; + + Console::outDebug('symlink dictionary is corrupted, creating new dictionary'); + $this->save(false); + } + finally + { + unset($e); + } + } + + /** + * Saves the symlink dictionary to the file + * + * @param bool $throw_exception + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + private function save(bool $throw_exception=true): void + { + if(Resolver::resolveScope() !== Scopes::System) + throw new AccessDeniedException('Insufficient Permissions to write to the system symlink dictionary'); + + Console::outDebug(sprintf('saving symlink dictionary to %s', $this->SymlinkDictionaryPath)); + + try + { + $dictionary = []; + foreach($this->SymlinkDictionary as $entry) + { + $dictionary[] = $entry->toArray(true); + } + + IO::fwrite($this->SymlinkDictionaryPath, ZiProto::encode($dictionary)); + } + catch(Exception $e) + { + if($throw_exception) + throw new IOException(sprintf('failed to save symlink dictionary to %s', $this->SymlinkDictionaryPath), $e); + + Console::outWarning(sprintf('failed to save symlink dictionary to %s', $this->SymlinkDictionaryPath)); + } + finally + { + unset($e); + } + } + + /** + * @return string + */ + public function getSymlinkDictionaryPath(): string + { + return $this->SymlinkDictionaryPath; + } + + /** + * @return array + */ + public function getSymlinkDictionary(): array + { + return $this->SymlinkDictionary; + } + + /** + * Checks if a package is defined in the symlink dictionary + * + * @param string $package + * @return bool + */ + public function exists(string $package): bool + { + foreach($this->SymlinkDictionary as $entry) + { + if($entry->Package === $package) + return true; + } + + return false; + } + + /** + * Adds a new entry to the symlink dictionary + * + * @param string $package + * @param string $unit + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + public function add(string $package, string $unit='main'): void + { + if(Resolver::resolveScope() !== Scopes::System) + throw new AccessDeniedException('Insufficient Permissions to add to the system symlink dictionary'); + + if($this->exists($package)) + $this->remove($package); + + $entry = new SymlinkEntry(); + $entry->Package = $package; + $entry->ExecutionPolicyName = $unit; + + $this->SymlinkDictionary[] = $entry; + $this->save(); + } + + /** + * Removes an entry from the symlink dictionary + * + * @param string $package + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + public function remove(string $package): void + { + if(Resolver::resolveScope() !== Scopes::System) + throw new AccessDeniedException('Insufficient Permissions to remove from the system symlink dictionary'); + + if(!$this->exists($package)) + return; + + foreach($this->SymlinkDictionary as $key => $entry) + { + if($entry->Package === $package) + { + if($entry->Registered) + { + $filesystem = new Filesystem(); + + $symlink_name = explode('.', $entry->Package)[count(explode('.', $entry->Package)) - 1]; + $symlink = self::$BinPath . DIRECTORY_SEPARATOR . $symlink_name; + + if($filesystem->exists($symlink)) + $filesystem->remove($symlink); + + } + + unset($this->SymlinkDictionary[$key]); + $this->save(); + return; + } + } + + throw new IOException(sprintf('failed to remove package %s from the symlink dictionary', $package)); + } + + /** + * Sets the package as registered + * + * @param string $package + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + private function setAsRegistered(string $package): void + { + foreach($this->SymlinkDictionary as $key => $entry) + { + if($entry->Package === $package) + { + $entry->Registered = true; + $this->SymlinkDictionary[$key] = $entry; + $this->save(); + return; + } + } + } + + /** + * Sets the package as unregistered + * + * @param string $package + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + private function setAsUnregistered(string $package): void + { + foreach($this->SymlinkDictionary as $key => $entry) + { + if($entry->Package === $package) + { + $entry->Registered = false; + $this->SymlinkDictionary[$key] = $entry; + $this->save(); + return; + } + } + } + + /** + * Syncs the symlink dictionary with the filesystem + * + * @return void + * @throws AccessDeniedException + * @throws IOException + */ + public function sync(): void + { + if(Resolver::resolveScope() !== Scopes::System) + throw new AccessDeniedException('Insufficient Permissions to sync the system symlink dictionary'); + + $filesystem = new Filesystem(); + $execution_pointer_manager = new ExecutionPointerManager(); + $package_lock_manager = new PackageLockManager(); + + foreach($this->SymlinkDictionary as $entry) + { + if($entry->Registered) + continue; + + $symlink_name = explode('.', $entry->Package)[count(explode('.', $entry->Package)) - 1]; + $symlink = self::$BinPath . DIRECTORY_SEPARATOR . $symlink_name; + + if($filesystem->exists($symlink)) + { + Console::outWarning(sprintf('Symlink %s already exists, skipping', $symlink)); + continue; + } + + try + { + $package_entry = $package_lock_manager->getPackageLock()->getPackage($entry->Package); + + if($package_entry == null) + { + Console::outWarning(sprintf('Package %s is not installed, skipping', $entry->Package)); + continue; + } + + $latest_version = $package_entry->getLatestVersion(); + + } + catch(Exception $e) + { + $filesystem->remove($symlink); + Console::outWarning(sprintf('Failed to get package %s, skipping', $entry->Package)); + continue; + } + + try + { + $entry_point_path = $execution_pointer_manager->getEntryPointPath($entry->Package, $latest_version, $entry->ExecutionPolicyName); + $filesystem->symlink($entry_point_path, $symlink); + } + catch(Exception $e) + { + $filesystem->remove($symlink); + Console::outWarning(sprintf('Failed to create symlink %s, skipping', $symlink)); + continue; + } + finally + { + unset($e); + } + + $this->setAsRegistered($entry->Package); + + } + } + } \ No newline at end of file diff --git a/src/ncc/Objects/SymlinkDictionary.php b/src/ncc/Objects/SymlinkDictionary.php new file mode 100644 index 0000000..c5ea087 --- /dev/null +++ b/src/ncc/Objects/SymlinkDictionary.php @@ -0,0 +1,8 @@ +ExecutionPolicyName = 'main'; + $this->Registered = false; + } + + /** + * Returns a string representation of the object + * + * @param bool $bytecode + * @return array + */ + public function toArray(bool $bytecode=false): array + { + return [ + ($bytecode ? Functions::cbc('package') : 'package') => $this->Package, + ($bytecode ? Functions::cbc('registered') : 'registered') => $this->Registered, + ($bytecode ? Functions::cbc('execution_policy_name') : 'execution_policy_name') => $this->ExecutionPolicyName + ]; + } + + /** + * Constructs a new SymlinkEntry from an array representation + * + * @param array $data + * @return SymlinkEntry + */ + public static function fromArray(array $data): SymlinkEntry + { + $entry = new SymlinkEntry(); + + $entry->Package = Functions::array_bc($data, 'package'); + $entry->Registered = (bool)Functions::array_bc($data, 'registered'); + $entry->ExecutionPolicyName = Functions::array_bc($data, 'execution_policy_name'); + + return $entry; + } + + } \ No newline at end of file diff --git a/src/ncc/ncc.php b/src/ncc/ncc.php index 192f311..1ce02ee 100644 --- a/src/ncc/ncc.php +++ b/src/ncc/ncc.php @@ -2,6 +2,9 @@ namespace ncc; + use ncc\Exceptions\AccessDeniedException; + use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\IOException; use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\RuntimeException; use ncc\Objects\NccVersionInformation; @@ -34,8 +37,10 @@ * * @param boolean $reload Indicates if the cached version is to be ignored and the version file to be reloaded and validated * @return NccVersionInformation - * @throws Exceptions\FileNotFoundException - * @throws Exceptions\RuntimeException + * @throws AccessDeniedException + * @throws FileNotFoundException + * @throws IOException + * @throws RuntimeException */ public static function getVersionInformation(bool $reload=False): NccVersionInformation { -- 2.45.3 From d65795fcb54a073946f90effd2b542ff3b1595b9 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 07:10:22 -0500 Subject: [PATCH 181/212] Refactored documentation into DOCUMENTATION.md --- DOCUMENTATION.md | 333 +++++++++++++++++- docs/building_ncc.md | 94 ----- docs/package_name.md | 43 --- .../project_configuration/execution_policy.md | 279 --------------- 4 files changed, 325 insertions(+), 424 deletions(-) delete mode 100644 docs/building_ncc.md delete mode 100644 docs/package_name.md delete mode 100644 docs/project_configuration/execution_policy.md diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index d8f9515..f19e8da 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -5,14 +5,31 @@ NCC, from basic installation, basic usage, standards and much more. ## Table of contents - - Introduction - - What is NCC? - - Advantages over other software - ------------------------------------------------------------------------------------- + +* [NCC Documentation](#ncc-documentation) + * [Table of contents](#table-of-contents) + * [Introduction](#introduction) + * [What is NCC?](#what-is-ncc) +* [Building NCC from source](#building-ncc-from-source) + * [Requirements to build](#requirements-to-build) + * [Installing phpab](#installing-phpab) + * [Building NCC](#building-ncc) + * [Redist](#redist) + * [Tar](#tar) +* [Installing NCC](#installing-ncc) + * [Command line arguments](#command-line-arguments) +* [Uninstalling NCC](#uninstalling-ncc) +* [Projects](#projects) + * [Creating a project](#creating-a-project) + * [project.json structure](#projectjson-structure) + * [project](#project) + * [project.compiler](#projectcompiler) +* [Naming a package](#naming-a-package) + * [Naming conventions](#naming-conventions) + * [References](#references) + - -# Introduction +## Introduction This section serves the basic introduction of NCC, what it's used for and how you can use it in your own projects or use it to run and build other projects that are designed @@ -31,4 +48,304 @@ NCC can make the process of building your code into a redistributable package mu more efficient by treating each building block of your project as a component that is interconnected in your environment instead of the more popular route taken by package/dependency managers such as [composer](https://getcomposer.org/), -[npm](https://www.npmjs.com/) or [pypi (or pip)](https://pypi.org/). \ No newline at end of file +[npm](https://www.npmjs.com/) or [pypi (or pip)](https://pypi.org/). + + +------------------------------------------------------------------------------------ + +# Building NCC from source + +Building NCC from source is easy with very few requirements +to start building. At the moment ncc can only be debugged +or tested by building a redistributable source and +installing it. + +## Requirements to build + +- php8.0+ +- php-mbstring +- php-ctype +- php-common (covers tokenizer & posix among others) +- make +- phpab +- tar *(optional)* + +## Installing phpab + +phpab is also known as [PHP Autoload Builder](https://github.com/theseer/Autoload), +phpab is an open source tool used for creating autoload +files, ncc needs this tool in order to generate it's +autoload files whenever there's any changes to its source +code. + +This tool is only required for building and or creating a +redistributable package of ncc. This component is not +required to be installed to use ncc. + +for some components that require static loading, ncc will +automatically load it using it's own +[autoloader](../src/autoload/autoload.php) + +The recommended way to install phpab is by using [phive](https://phar.io/), +if you don't have phive installed you can install it by +running these commands in your terminal (from the official documentation) + +```shell +wget -O phive.phar https://phar.io/releases/phive.phar +wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc +gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 +gpg --verify phive.phar.asc phive.phar +chmod +x phive.phar +sudo mv phive.phar /usr/local/bin/phive +``` + +Once phive is installed, you can run the final command to +install phpab +```shell +sudo phive install phpab --global +``` + +or you can run this command to install it locally +```shell +phive install phpab +``` + +**Note:** Optionally, you may want to have `phab` available in your +`$PATH`, this can be done with this command. *(Replace `x.xx.x` with your +version number)* this is if you installed it locally + +```shell +ln -s /home/user/.phive/phars/phpab-x.xx.x.phar /usr/bin/phpab +``` + +## Building NCC + +First, navigate to the main directory of NCC's source code +where the [Makefile](../Makefile) is present. If you +already attempted to or had built ncc before, it's +recommended to use `make clean` before building. + + +### Redist + +Running `redist` from the Makefile will generate all the +required autoloader for ncc and move all the required +files into one redistributable source folder under a +directory called `build/src` + +```shell +make redist +``` + + +### Tar + +Running `tar` will run redist before packaging the +redistributable source into a tar.gz file that can +be distributed to other machines, this process is not +a requirement. + +```shell +make tar +``` + +Once you have a populated `build/src` folder, you can +simply run execute the `installer` file to install your +build of ncc onto the running machine. + +------------------------------------------------------------------------------------ + +# Installing NCC + +Installing NCC is easy, you can either download the +redistributable source from the [releases](https://git.n64.cc/nosial/ncc/-/releases) +page or you can build it from source using the +instructions above. + +Once you have the redistributable source, you can +simply run execute the `INSTALL` file to install +ncc onto the running machine. + +## Command line arguments + +The installer accepts a few command line arguments +that can be used to customize the installation +process. + +`--help` Displays the help message + +`--auto` Automatically installs ncc without asking for user input. + +**Note:** To install composer along with ncc, you must +also provide the `--install-composer` argument. + +`--install-composer` Installs composer along with ncc. +By default, ncc will not install composer and during the +installation process you will be asked if you want to +install composer along-side ncc, this will not conflict +with any existing composer installation. + +`--install-dir` Specifies the directory where ncc will be +installed to. By default, ncc will be installed to `/etc/ncc` + +`--bypass-cli-check` Bypasses the check in the installer +that checks if the installer is being run from the command +line, this is useful if you want to install ncc from a script. + +`--bypass-checksum` Bypasses the checksum check in the +installer, this is useful if you made modifications to +the installation files and want to install a modified +version of ncc. + +But this isn't recommended and the proper way to do this +is to modify the source code and build ncc from source, +the Makefile task will automatically rebuild the checksum +file for you. + + +------------------------------------------------------------------------------------ + +# Uninstalling NCC + +Uninstalling NCC is easy, simply delete the directory +where ncc was installed to, by default this is `/etc/ncc`. + +To delete all the data that ncc has created, you can +also delete the `/var/ncc` directory. + +Finally, remove the symlink that was created in `/usr/local/bin` +to the `ncc` entry point file. + +------------------------------------------------------------------------------------ + +# Projects + +A project is a directory that contains all the source files +to your program, it's similar to a workspace in +other IDEs. Usually contains a `project.json` file which +contains all the information about the project that +ncc needs to know. + +This can include the name of the program, the version +of the program, the author of the program, the +dependencies of the program, build configurations, +and more. + +This section will cover the basics of creating a +project and managing it and the technical details +of the `project.json` file. + + +## Creating a project + +This is the first step in using ncc, you must create a +project before you can do anything else (*not really +because you can install packages without needing to create +a project and run them directly, but you get the point*) + +The NCC command-line tool provides a management command +called `project` that can be used to create a new project +or to manage an existing project. + +```shell +ncc project create --package "com.example.program" --name "Example Program" +``` + +This command will create a new project in the current +directory, the `--package` argument specifies the +package name of the project, this is used to identify +the project and to avoid conflicts with other projects +that may have the same name. + +The `--name` argument specifies the name of the project, +this is used to display the name of the project in the +project manager and in the project settings. This doesn't +have to be the same as the package name or unique. + +**Note:** If the options are not provided, the command +will prompt you for the package name and the project name. + +For more information about the project command, you can +run `ncc project --help` to display the help message. + +## project.json structure + +The `project.json` file is a JSON file that contains +all the information about the project. + +When a project is created, the `project.json` file is +automatically created and populated with the default +values, you can modify this file to change the default +values or to add more information about the project. + +This section will go over the structure of the `project.json` +file and what each field does. + +### project + +The `project` field contains information about the project, +such as what compiler extension to use, options to pass on +to the compiler, and more. + +| Name | Type | Required | Description | +|---------------|--------------------------------------|----------|----------------------------------------------------------------------------------------------------| +| compiler | [project.compiler](#projectcompiler) | Yes | The compiler extension that the project uses to compile the program | +| options | `array` | No | An array of options to pass on to the compiler, the options vary depending on the compiler and NCC | +| update_source | `project.update_source` | No | The source for where the program can fetch updates from | + +### project.compiler + +The `project.compiler` field contains information about +the compiler extension that the project uses to compile +the program. + +| Name | Type | Required | Description | +|-----------------|----------|----------|------------------------------------------------------------------------------------------------| +| extension | `string` | Yes | The name of the compiler extension that the project uses to compile the program | +| minimum_version | `string` | No | The minimum version of the compiler extension that the project requires to compile the program | +| maximum_version | `string` | No | The maximum version of the compiler extension that the project requires to compile the program | + + +------------------------------------------------------------------------------------ + +# Naming a package + +NCC Follows the same naming convention as Java's naming +convention. The purpose of naming a package this way is +to easily create a "Name" of the package, this string +of information contains + +- The developer/organization behind the package +- The package name itself + + +## Naming conventions + +Package names are written in all lower-case due to the +fact that some operating systems treats file names +differently, for example on Linux `Aa.txt` and `aa.txt` +are two entirely different file names because of the +capitalization and on Windows it's treated as the same +file name. + +Organizations or small developers use their domain name +in reverse to begin their package names, for example +`net.nosial.example` is a package named `example` +created by a programmer at `nosial.net` + +Just like the Java naming convention, to avoid conflicts +of the same package name developers can use something +different, for example as pointed out in Java's package +naming convention developers can instead use something +like a region to name packages, for example +`net.nosial.region.example` + + +## References + +For Java's package naming conventions see +[Naming a Package](https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html) +from the Oracle's Java documentation resource, as the +same rules apply to NCC except for *some* illegal naming +conventions such as packages not being able to begin +with `int` or numbers \ No newline at end of file diff --git a/docs/building_ncc.md b/docs/building_ncc.md deleted file mode 100644 index 2d3b6f6..0000000 --- a/docs/building_ncc.md +++ /dev/null @@ -1,94 +0,0 @@ -# Building NCC from source - -Building NCC from source is easy with very few requirements -to start building. At the moment ncc can only be debugged -or tested by building a redistributable source and -installing it. - -## Requirements to build - - - php8.0+ - - php-mbstring - - php-ctype - - php-tokenizer *(or php-common)* - - make - - phpab - - tar *(optional)* - -## Installing phpab - -phpab is also known as [PHP Autoload Builder](https://github.com/theseer/Autoload), -phpab is an open source tool used for creating autoload -files, ncc needs this tool in order to generate it's -autoload files whenever there's any changes to its source -code. - -This tool is only required for building and or creating a -redistributable package of ncc. This component is not -required to be installed to use ncc. - -for some components that require static loading, ncc will -automatically load it using it's own -[autoloader](../src/autoload/autoload.php) - -The recommended way to install phpab is by using [phive](https://phar.io/), -if you don't have phive installed you can install it by -running these commands in your terminal (from the official documentation) - -```shell -wget -O phive.phar https://phar.io/releases/phive.phar -wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc -gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 -gpg --verify phive.phar.asc phive.phar -chmod +x phive.phar -sudo mv phive.phar /usr/local/bin/phive -``` - -Once phive is installed, you can run the final command to -install phpab -```shell -phive install phpab -``` - -**Note:** Optionally, you may want to have `phab` available in your -`$PATH`, this can be done with this command. *(Replace `x.xx.x` with your -version number)* - -```shell -ln -s /home/user/.phive/phars/phpab-x.xx.x.phar /usr/bin/phpab -``` - -## Building NCC - -First, navigate to the main directory of NCC's source code -where the [Makefile](../Makefile) is present. If you -already attempted to or had built ncc before, it's -recommended to use `make clean` before building. - - -### Redist - -Running `redist` from the Makefile will generate all the -required autoloaders for ncc and move all the required -files into one redistributable source folder under a -directory called `build/src` - -```shell -make redist -``` - - -### Tar - -Running `tar` will run redist before packaging the -redistributable source into a tar.gz file that can -be distributed to other machines, this process is not -a requirement. - -```shell -make tar -``` - -Once you have a populated `build/src` folder, you can -simply run execute the `installer` file to install your -build of ncc onto the running machine. \ No newline at end of file diff --git a/docs/package_name.md b/docs/package_name.md deleted file mode 100644 index 0b4586e..0000000 --- a/docs/package_name.md +++ /dev/null @@ -1,43 +0,0 @@ -# Naming a package - -**Updated on Tuesday, July 26, 2022** - -NCC Follows the same naming convention as Java's naming -convention. The purpose of naming a package this way is -to easily create a "Name" of the package, this string -of information contains - - - The developer/organization behind the package - - The package name itself - - -# Naming conventions - -Package names are written in all lower-case due to the -fact that some operating systems treats file names -differently, for example on Linux `Aa.txt` and `aa.txt` -are two entirely different file names because of the -capitalization and on Windows it's treated as the same -file name. - -Organizations or small developers use their domain name -in reverse to begin their package names, for example -`net.nosial.example` is a package named `example` -created by a programmer at `nosial.net` - -Just like the Java naming convention, to avoid conflicts -of the same package name developers can use something -different, for example as pointed out in Java's package -naming convention developers can instead use something -like a region to name packages, for example -`net.nosial.region.example` - - -# References - -For Java's package naming conventions see -[Naming a Package](https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html) -from the Oracle's Java documentation resource, as the -same rules apply to NCC except for *some* illegal naming -conventions such as packages not being able to begin -with `int` or numbers \ No newline at end of file diff --git a/docs/project_configuration/execution_policy.md b/docs/project_configuration/execution_policy.md deleted file mode 100644 index db304c2..0000000 --- a/docs/project_configuration/execution_policy.md +++ /dev/null @@ -1,279 +0,0 @@ -# Execution Policies - -**Updated on Wednesday, December 07, 2022** - -An execution policy is a policy defined in the Project -configuration file (`project.json`) that can be used -to execute a script or program in any stage of the package - -For instance, you can have a script that is executed before -the build process starts, or in different installation stages -when the user is installing your package you can have a unit -run before or after the installation/uninstallation process -starts.# - -Use cases such as this allows you to properly implement -and control your program's files & assets that are not -handled by NCC's compiler extensions. - -## Table of Contents - - -* [Execution Policies](#execution-policies) - * [Table of Contents](#table-of-contents) - * [JSON Example](#json-example) - * [ExecutionPolicy Object](#executionpolicy-object) - * [Object Properties](#object-properties) - * [JSON Example](#json-example-1) - * [ExecutionConfiguration Object](#executionconfiguration-object) - * [Object Properties](#object-properties-1) - * [JSON Example](#json-example-2) - * [ExitHandler Object](#exithandler-object) - * [Object Properties](#object-properties-2) - * [JSON Example](#json-example-3) - * [More Examples](#more-examples) - * [bash](#bash) - * [lua](#lua) - * [php](#php) - * [perl](#perl) - * [python (or python2/python3)](#python--or-python2python3-) - * [shell](#shell) - - - -## JSON Example - -```json -{ - "execution_policies": { - "main": { - "runner": "php", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.php", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - }, - "hello_world": { - "runner": "shell", - "message": "Running HTOP", - "options": { - "htop": null - }, - "exec": { - "tty": true - } - } - } -} -``` - ------------------------------------------------------------- - -## ExecutionPolicy Object - -Execution Policies for your project **must** have unique -names, because they way you tell NCC to execute these -policies is by referencing their name in the configuration. - -Invalid names/undefined policies will raise errors when -building the project - -### Object Properties - -| Property Name | Value Type | Example Value | Description | -|-----------------|---------------------------------|----------------------|--------------------------------------------------------------------------------------------| -| `runner` | string | bash | The name of a supported runner instance, see runners in this document | -| `message` | string, null | Starting foo_bar ... | *Optional* the message to display before running the execution policy | -| `exec` | ExecutionConfiguration | N/A | The configuration object that tells how the runner should execute the process | -| `exit_handlers` | ExitHandlersConfiguration, null | N/A | *Optional* Exit Handler Configurations that tells NCC how to handle exits from the process | - -### JSON Example - -```json -{ - "name": "foo_bar", - "runner": "bash", - "message": "Running foo_bar ...", - "exec": null, - "exit_handlers": null -} -``` - ------------------------------------------------------------- - -## ExecutionConfiguration Object - -### Object Properties - -| Property Name | Value Type | Example Value | Description | -|---------------------|-------------------|---------------------------------|------------------------------------------------------------------------| -| `target` | `string` | scripts/foo_bar.bash | The target file to execute | -| `working_directory` | `string`, `null` | %INSTALL_PATH.SRC% | *optional* The working directory to execute the process in | -| `options` | `array`, `null` | {"run": null, "log": "verbose"} | Commandline Parameters to pass on to the target or process | -| `silent` | `boolean`, `null` | False | Indicates if the target should run silently, by default this is false. | -| `tty` | `boolean`, `null` | False | Indicates if the target should run in TTY mode | -| `timeout` | `integer`, `null` | 60 | The amount of seconds to wait before the process is killed | - -### JSON Example - -```json -{ - "target": "scripts/foo_bar.bash", - "working_directory": "%INSTALL_PATH.SRC%", - "options": {"run": null, "log": "verbose"}, - "silent": false, - "tty": false, - "timeout": 10 -} -``` - - ------------------------------------------------------------- - -## ExitHandler Object - -An exit handler is executed once the specified exit code is -returned or the process exits with an error or normally, if -an exit handler is specified it will be executed. - -### Object Properties - -| Property Name | Value Type | Example Value | Description | -|---------------|--------------------|---------------|------------------------------------------------------------------------------| -| `message` | `string` | Hello World! | The message to display when the exit handler is triggered | -| `end_process` | `boolean`, `null` | False | *optional* Kills the process after this exit handler is triggered | -| `run` | `string`, `null` | `null` | *optional* A execution policy to execute once this exit handler is triggered | -| `exit_code` | `int`, `null` | 1 | The exit code that triggers this exit handler | -### JSON Example - -```json -{ - "message": "Hello World", - "end_process": false, - "run": null, - "exit_code": 1 -} -``` - - -## More Examples - -Just like the `project.json` file, you can have multiple -execution policies in your project, here are some examples -of how you can use them: - -### bash - -```json -{ - "execution_policies": [ - { - "name": "main", - "runner": "bash", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.bash", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - } - ] -} -``` - -### lua - -```json -{ - "execution_policies": [ - { - "name": "main", - "runner": "lua", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.lua", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - } - ] -} -``` - -### php - -```json -{ - "execution_policies": [ - { - "name": "main", - "runner": "php", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.php", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - } - ] -} -``` - -### perl - -```json -{ - "execution_policies": [ - { - "name": "main", - "runner": "perl", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.pl", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - } - ] -} -``` - -### python (or python2/python3) - -```json -{ - "execution_policies": [ - { - "name": "main", - "runner": "python", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.py", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - } - ] -} -``` - -### shell - -```json -{ - "execution_policies": [ - { - "name": "main", - "runner": "shell", - "message": "Running main %ASSEMBLY.PACKAGE%", - "exec": { - "target": "scripts/main.sh", - "working_directory": "%INSTALL_PATH.SRC%", - "silent": false - } - } - ] -} -``` \ No newline at end of file -- 2.45.3 From b530376af4538909c6dc55859171d9a59920a095 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 07:35:03 -0500 Subject: [PATCH 182/212] Reformatted DOCUMENTATION.md --- DOCUMENTATION.md | 243 +++++++++++++++++------------------------------ 1 file changed, 85 insertions(+), 158 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index f19e8da..21ef75e 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -31,34 +31,28 @@ NCC, from basic installation, basic usage, standards and much more. ## Introduction -This section serves the basic introduction of NCC, what it's used for and how you can -use it in your own projects or use it to run and build other projects that are designed -to be used with NCC. +This section serves the basic introduction of NCC, what it's used for and how you can use it in your own projects or use +it to run and build other projects that are designed to be used with NCC. ## What is NCC? -NCC (*Acronym for **N**osial **C**ode **C**ompiler*) is a multi-purpose compiler, -package manager and toolkit. Allowing projects to be managed and built more easily -without having to mess with all the traditional tools that comes with your language -of choice. Right now NCC only supports PHP as it's written in PHP but extensions -for other languages/frameworks can be built into the software in the future when -the need comes for it. +NCC (*Acronym for **N**osial **C**ode **C**ompiler*) is a multi-purpose compiler, package manager and toolkit. Allowing +projects to be managed and built more easily without having to mess with all the traditional tools that comes with your +language of choice. Right now NCC only supports PHP as it's written in PHP but extensions for other languages/frameworks +can be built into the software in the future when the need comes for it. -NCC can make the process of building your code into a redistributable package much -more efficient by treating each building block of your project as a component that -is interconnected in your environment instead of the more popular route taken by -package/dependency managers such as [composer](https://getcomposer.org/), -[npm](https://www.npmjs.com/) or [pypi (or pip)](https://pypi.org/). +NCC can make the process of building your code into a redistributable package much more efficient by treating each +building block of your project as a component that is interconnected in your environment instead of the more popular +route taken by package/dependency managers such as [composer](https://getcomposer.org/),[npm](https://www.npmjs.com/) or +[pypi (or pip)](https://pypi.org/). ------------------------------------------------------------------------------------ # Building NCC from source -Building NCC from source is easy with very few requirements -to start building. At the moment ncc can only be debugged -or tested by building a redistributable source and -installing it. +Building NCC from source is easy with very few requirements to start building. At the moment ncc can only be debugged or +tested by building a redistributable source and installing it. ## Requirements to build @@ -72,23 +66,18 @@ installing it. ## Installing phpab -phpab is also known as [PHP Autoload Builder](https://github.com/theseer/Autoload), -phpab is an open source tool used for creating autoload -files, ncc needs this tool in order to generate it's -autoload files whenever there's any changes to its source -code. +phpab is also known as [PHP Autoload Builder](https://github.com/theseer/Autoload), phpab is an open source tool used +for creating autoload files, ncc needs this tool in order to generate it's autoload files whenever there's any changes +to its source code. -This tool is only required for building and or creating a -redistributable package of ncc. This component is not +This tool is only required for building and or creating a redistributable package of ncc. This component is not required to be installed to use ncc. -for some components that require static loading, ncc will -automatically load it using it's own -[autoloader](../src/autoload/autoload.php) +for some components that require static loading, ncc will automatically load it using its own +[autoloader](src/autoload/autoload.php) -The recommended way to install phpab is by using [phive](https://phar.io/), -if you don't have phive installed you can install it by -running these commands in your terminal (from the official documentation) +The recommended way to install phpab is by using [phive](https://phar.io/), if you don't have phive installed you can +install it by running these commands in your terminal (from the official documentation) ```shell wget -O phive.phar https://phar.io/releases/phive.phar @@ -99,39 +88,34 @@ chmod +x phive.phar sudo mv phive.phar /usr/local/bin/phive ``` -Once phive is installed, you can run the final command to -install phpab +Once phive is installed, you can run the final command to install phpab + ```shell sudo phive install phpab --global ``` or you can run this command to install it locally + ```shell phive install phpab ``` -**Note:** Optionally, you may want to have `phab` available in your -`$PATH`, this can be done with this command. *(Replace `x.xx.x` with your -version number)* this is if you installed it locally +**Note:** Optionally, you may want to have `phab` available in your `$PATH`, this can be done with this command. +*(Replace `x.xx.x` with your version number)* this is if you installed it locally ```shell -ln -s /home/user/.phive/phars/phpab-x.xx.x.phar /usr/bin/phpab +ln -s /home/user/.phive/phars/phpab-x.xx.x.phar /usr/local/bin/phpab ``` ## Building NCC -First, navigate to the main directory of NCC's source code -where the [Makefile](../Makefile) is present. If you -already attempted to or had built ncc before, it's -recommended to use `make clean` before building. - +First, navigate to the main directory of NCC's source code where the [Makefile](Makefile) is present. If you +already attempted to or had built ncc before, it's recommended to use `make clean` before building. ### Redist -Running `redist` from the Makefile will generate all the -required autoloader for ncc and move all the required -files into one redistributable source folder under a -directory called `build/src` +Running `redist` from the Makefile will generate all the required autoloader for ncc and move all the required files +into one redistributable source folder under a directory called `build/src` ```shell make redist @@ -140,151 +124,108 @@ make redist ### Tar -Running `tar` will run redist before packaging the -redistributable source into a tar.gz file that can -be distributed to other machines, this process is not -a requirement. +Running `tar` will run redist before packaging the redistributable source into a tar.gz file that can be distributed to +other machines, this process is not a requirement. ```shell make tar ``` -Once you have a populated `build/src` folder, you can -simply run execute the `installer` file to install your -build of ncc onto the running machine. +Once you have a populated `build/src` folder, you can simply run execute the `installer` file to install your build of +ncc onto the running machine. ------------------------------------------------------------------------------------ # Installing NCC -Installing NCC is easy, you can either download the -redistributable source from the [releases](https://git.n64.cc/nosial/ncc/-/releases) -page or you can build it from source using the -instructions above. +Installing NCC is easy, you can either download the redistributable source from the [releases](https://git.n64.cc/nosial/ncc/-/releases) +page or you can build it from source using the instructions above. -Once you have the redistributable source, you can -simply run execute the `INSTALL` file to install -ncc onto the running machine. +Once you have the redistributable source, you can simply run execute the `INSTALL` file to install ncc onto the running +machine. ## Command line arguments -The installer accepts a few command line arguments -that can be used to customize the installation -process. +The installer accepts a few command line arguments that can be used to customize the installation process. `--help` Displays the help message `--auto` Automatically installs ncc without asking for user input. -**Note:** To install composer along with ncc, you must -also provide the `--install-composer` argument. +**Note:** To install composer along with ncc, you must also provide the `--install-composer` argument. -`--install-composer` Installs composer along with ncc. -By default, ncc will not install composer and during the -installation process you will be asked if you want to -install composer along-side ncc, this will not conflict +`--install-composer` Installs composer along with ncc. By default, ncc will not install composer and during the +installation process you will be asked if you want to install composer along-side ncc, this will not conflict with any existing composer installation. -`--install-dir` Specifies the directory where ncc will be -installed to. By default, ncc will be installed to `/etc/ncc` +`--install-dir` Specifies the directory where ncc will be installed to. By default, ncc will be installed to `/etc/ncc` -`--bypass-cli-check` Bypasses the check in the installer -that checks if the installer is being run from the command +`--bypass-cli-check` Bypasses the check in the installer that checks if the installer is being run from the command line, this is useful if you want to install ncc from a script. -`--bypass-checksum` Bypasses the checksum check in the -installer, this is useful if you made modifications to -the installation files and want to install a modified -version of ncc. +`--bypass-checksum` Bypasses the checksum check in the installer, this is useful if you made modifications to the +installation files and want to install a modified version of ncc. -But this isn't recommended and the proper way to do this -is to modify the source code and build ncc from source, -the Makefile task will automatically rebuild the checksum -file for you. +But this isn't recommended and the proper way to do this is to modify the source code and build ncc from source, +the Makefile task will automatically rebuild the checksum file for you. ------------------------------------------------------------------------------------ # Uninstalling NCC -Uninstalling NCC is easy, simply delete the directory -where ncc was installed to, by default this is `/etc/ncc`. - -To delete all the data that ncc has created, you can -also delete the `/var/ncc` directory. - -Finally, remove the symlink that was created in `/usr/local/bin` -to the `ncc` entry point file. + - Uninstalling NCC is easy, simply delete the directory where ncc was installed to, by default this is `/etc/ncc`. + - To delete all the data that ncc has created, you can also delete the `/var/ncc` directory. + - Finally, remove the symlink that was created in `/usr/local/bin`to the `ncc` entry point file. ------------------------------------------------------------------------------------ # Projects -A project is a directory that contains all the source files -to your program, it's similar to a workspace in -other IDEs. Usually contains a `project.json` file which -contains all the information about the project that -ncc needs to know. +A project is a directory that contains all the source files to your program, it's similar to a workspace in other IDEs. +Usually contains a `project.json` file which contains all the information about the project that ncc needs to know. -This can include the name of the program, the version -of the program, the author of the program, the -dependencies of the program, build configurations, -and more. +This can include the name of the program, the version of the program, the author of the program, the dependencies of the +program, build configurations, and more. -This section will cover the basics of creating a -project and managing it and the technical details -of the `project.json` file. +This section will cover the basics of creating a project and managing it and the technical details of the `project.json` +file. ## Creating a project -This is the first step in using ncc, you must create a -project before you can do anything else (*not really -because you can install packages without needing to create -a project and run them directly, but you get the point*) +This is the first step in using ncc, you must create a project before you can do anything else (*not really because you +can install packages without needing to create a project and run them directly, but you get the point*) -The NCC command-line tool provides a management command -called `project` that can be used to create a new project +The NCC command-line tool provides a management command called `project` that can be used to create a new project or to manage an existing project. ```shell ncc project create --package "com.example.program" --name "Example Program" ``` -This command will create a new project in the current -directory, the `--package` argument specifies the -package name of the project, this is used to identify -the project and to avoid conflicts with other projects -that may have the same name. +This command will create a new project in the current directory, the `--package` argument specifies the package name of +the project, this is used to identify the project and to avoid conflicts with other projects that may have the same name. -The `--name` argument specifies the name of the project, -this is used to display the name of the project in the -project manager and in the project settings. This doesn't -have to be the same as the package name or unique. +The `--name` argument specifies the name of the project, this is used to display the name of the project in the project +manager and in the project settings. This doesn't have to be the same as the package name or unique. -**Note:** If the options are not provided, the command -will prompt you for the package name and the project name. +**Note:** If the options are not provided, the command will prompt you for the package name and the project name. -For more information about the project command, you can -run `ncc project --help` to display the help message. +For more information about the project command, you can run `ncc project --help` to display the help message. ## project.json structure -The `project.json` file is a JSON file that contains -all the information about the project. +The `project.json` file is a JSON file that contains all the information about the project. -When a project is created, the `project.json` file is -automatically created and populated with the default -values, you can modify this file to change the default -values or to add more information about the project. +When a project is created, the `project.json` file is automatically created and populated with the default values, you +can modify this file to change the default values or to add more information about the project. -This section will go over the structure of the `project.json` -file and what each field does. +This section will go over the structure of the `project.json` file and what each field does. ### project -The `project` field contains information about the project, -such as what compiler extension to use, options to pass on +The `project` field contains information about the project, such as what compiler extension to use, options to pass on to the compiler, and more. | Name | Type | Required | Description | @@ -295,8 +236,7 @@ to the compiler, and more. ### project.compiler -The `project.compiler` field contains information about -the compiler extension that the project uses to compile +The `project.compiler` field contains information about the compiler extension that the project uses to compile the program. | Name | Type | Required | Description | @@ -310,10 +250,8 @@ the program. # Naming a package -NCC Follows the same naming convention as Java's naming -convention. The purpose of naming a package this way is -to easily create a "Name" of the package, this string -of information contains +NCC Follows the same naming convention as Java's naming convention. The purpose of naming a package this way is +to easily create a "Name" of the package, this string of information contains - The developer/organization behind the package - The package name itself @@ -321,31 +259,20 @@ of information contains ## Naming conventions -Package names are written in all lower-case due to the -fact that some operating systems treats file names -differently, for example on Linux `Aa.txt` and `aa.txt` -are two entirely different file names because of the -capitalization and on Windows it's treated as the same -file name. +Package names are written in all lower-case due to the fact that some operating systems treats file names +differently, for example on Linux `Aa.txt` and `aa.txt`are two entirely different file names because of the +capitalization and on Windows it's treated as the same file name. -Organizations or small developers use their domain name -in reverse to begin their package names, for example -`net.nosial.example` is a package named `example` -created by a programmer at `nosial.net` +Organizations or small developers use their domain name in reverse to begin their package names, for example +`net.nosial.example` is a package named `example` created by a programmer at `nosial.net` -Just like the Java naming convention, to avoid conflicts -of the same package name developers can use something -different, for example as pointed out in Java's package -naming convention developers can instead use something -like a region to name packages, for example -`net.nosial.region.example` +Just like the Java naming convention, to avoid conflicts of the same package name developers can use something +different, for example as pointed out in Java's package naming convention developers can instead use something +like a region to name packages, for example `net.nosial.region.example` ## References -For Java's package naming conventions see -[Naming a Package](https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html) -from the Oracle's Java documentation resource, as the -same rules apply to NCC except for *some* illegal naming -conventions such as packages not being able to begin -with `int` or numbers \ No newline at end of file +For Java's package naming conventions see [Naming a Package](https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html) +from the Oracle's Java documentation resource, as the same rules apply to NCC except for *some* illegal naming +conventions such as packages not being able to begin with `int` or numbers \ No newline at end of file -- 2.45.3 From 02963ee853a27179b3db5804ba7dff99938b7dd9 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 07:36:06 -0500 Subject: [PATCH 183/212] Updated uninstallation section in DOCUMENTATION.md --- DOCUMENTATION.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 21ef75e..bd624b8 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -174,7 +174,9 @@ the Makefile task will automatically rebuild the checksum file for you. # Uninstalling NCC - - Uninstalling NCC is easy, simply delete the directory where ncc was installed to, by default this is `/etc/ncc`. +Uninstalling NCC is easy, simply delete the directory where ncc was installed to, by default this is `/etc/ncc`. + +**Note:** - To delete all the data that ncc has created, you can also delete the `/var/ncc` directory. - Finally, remove the symlink that was created in `/usr/local/bin`to the `ncc` entry point file. -- 2.45.3 From 0be4224364c17770961b6ff3406a7ddbc99783f3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 08:44:02 -0500 Subject: [PATCH 184/212] Added documentation for remote sources in DOCUMENTATION.md https://git.n64.cc/nosial/ncc/-/issues/35 --- DOCUMENTATION.md | 111 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index bd624b8..10546b5 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -24,6 +24,14 @@ NCC, from basic installation, basic usage, standards and much more. * [project.json structure](#projectjson-structure) * [project](#project) * [project.compiler](#projectcompiler) + * [project.update_source](#projectupdatesource) +* [Remote Sources](#remote-sources) + * [Supported sources](#supported-sources) + * [Default sources](#default-sources) + * [Managing sources](#managing-sources) + * [Adding a source](#adding-a-source) + * [Removing a source](#removing-a-source) + * [Listing sources](#listing-sources) * [Naming a package](#naming-a-package) * [Naming conventions](#naming-conventions) * [References](#references) @@ -176,6 +184,9 @@ the Makefile task will automatically rebuild the checksum file for you. Uninstalling NCC is easy, simply delete the directory where ncc was installed to, by default this is `/etc/ncc`. +It's recommended to run `ncc package --uninstall-all` before uninstalling ncc, this will uninstall all the packages +that were installed using ncc and remove any artifacts that were created by these packages. + **Note:** - To delete all the data that ncc has created, you can also delete the `/var/ncc` directory. - Finally, remove the symlink that was created in `/usr/local/bin`to the `ncc` entry point file. @@ -247,6 +258,106 @@ the program. | minimum_version | `string` | No | The minimum version of the compiler extension that the project requires to compile the program | | maximum_version | `string` | No | The maximum version of the compiler extension that the project requires to compile the program | +### project.update_source + +The `project.update_source` field contains information about the source where the program can fetch updates from. + +| Name | Type | Required | Description | +|------|----------|----------|-----------------------------------------------------------| +|source| `string` | Yes | The source where the program can fetch updates from, see | + +------------------------------------------------------------------------------------ + +# Remote Sources + +Remote Sources are the locations where packages can be downloaded from, they are similar to repositories in other package +managers. They follow a simple syntax that allows you to specify the type of source, the location of the source, and more. + +Examples of sources are: + +- `symfony/process=latest@composer` - This is a package from the `symfony/process` package from the `composer` source +- `nosial/libs.config=latest@n64` - This is a package from the `nosial/libs.config` package from the `git.n64.cc` source + +A full example syntax may look like this: + +``` +/:=@ +``` + +This syntax is used to specify a package from a source, the syntax is split into 4 parts: + +- The vendor of the package +- The name of the package +- The branch of the package (optional) +- The version of the package (optional) +- The name of the source (needs to be configured in ncc) + +## Supported sources + +NCC supports the following sources: + +- `github` - This source uses the GitHub API to fetch packages from GitHub (Included in the default sources) +- `gitlab` - This source uses the GitLab API to fetch packages from GitLab (Can be used with self-hosted GitLab instances) + +Additional support for other sources will be added in the future. + +## Default sources + +NCC comes with a few default sources that are configured by default, these sources are: + +- packagist.org (`composer`) **Note:** This is an internal source that uses `composer` to fetch packages from packagist.org. + this is not configurable by the user. +- api.github.com (`github`) +- gitlab.com (`gitlab`) +- git.n64.cc (`n64`) +- gitgud.io (`gitgud`) + +Additional sources can be added by the user. See [Adding a source](#adding-a-source) for more information. + +## Managing sources + +You can manage sources using the `source` command in the ncc command-line tool. This command can be used to add, remove, +and list sources. For more information about the `source` command, you can run `ncc source --help` to display the help +message. + +### Adding a source + +To add a source, you can use the `add` command in the ncc `source` command-line tool. + +```shell +ncc source add --name "github" --type "github" --host "github.com" --ssl +``` + +This command will add a new source called `github` with the type `github` and the host `github.com`, the `--ssl` option +will tell ncc to use HTTPS instead of HTTP when fetching packages from this source. + +The reason to specify the type of source is to tell ncc what API to use when fetching packages from this source, for +example if you specify the type as `github` then ncc will use the GitHub API to fetch packages from this source so it's +important to specify the correct type when adding a source. + +> **Note:** You need root permissions to add a source + + +### Removing a source + +To remove a source, you can use the `remove` command in the ncc `source` command-line tool. + +```shell +ncc source remove --name "github" +``` + +> **Note:** You need root permissions to remove a source + +> **Note:** Removing a source also removes the ability for some packages to be fetched or updated from this source + + +### Listing sources + +To list all the sources, you can use the `list` command in the ncc `source` command-line tool. + +```shell +ncc source list +``` ------------------------------------------------------------------------------------ -- 2.45.3 From 5f951d35fda02fc1962ba2369ad8cdabc93439f2 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 09:05:29 -0500 Subject: [PATCH 185/212] Added documentation for credentials in DOCUMENTATION.md https://git.n64.cc/nosial/ncc/-/issues/35 --- DOCUMENTATION.md | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 10546b5..d4a5f54 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -32,6 +32,8 @@ NCC, from basic installation, basic usage, standards and much more. * [Adding a source](#adding-a-source) * [Removing a source](#removing-a-source) * [Listing sources](#listing-sources) + * [Credential Management](#credential-management) + * [Adding credentials](#adding-credentials) * [Naming a package](#naming-a-package) * [Naming conventions](#naming-conventions) * [References](#references) @@ -359,6 +361,62 @@ To list all the sources, you can use the `list` command in the ncc `source` comm ncc source list ``` +## Credential Management + +Some sources require credentials to be able to fetch packages from them, for example the `gitlab` source requires +credentials to be able to fetch packages from a self-hosted GitLab instance. NCC supports storing credentials for +sources in a secure way using the `cred` command in the ncc command-line tool. + +### Adding credentials + +To add credentials for a source, you can use the `add` command in the ncc `cred` command-line tool. + +```shell +ncc cred add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" +``` + +To add a private access token as a credential, you can specify the `--auth-type` as `pat` and specify the token as +`--token` instead of providing `--username` and `--password`. + +```shell +ncc cred add --alias "My Alias" --auth-type pat --token="mytoken" +``` + +By default, ncc will encrypt the entry except for the alias using the password/token that you provide. + +However, because it's encrypted you will need to provide the password/token when using the credential since ncc will +not be able to decrypt the entry without a password. To avoid being asked for the password/token every time you use the +credential, you can pass on the `--no-encryption` option to the `cred` command-line tool. + +```shell +ncc cred add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" --no-encryption +``` + +Encryption is applied individually to each credential, so you can have some credentials encrypted and some not encrypted. + +> **Note:** You need root permissions to add credentials + + +### Removing credentials + +To remove credentials, you can use the `remove` command in the ncc `cred` command-line tool. + +```shell +ncc cred remove --alias "My Alias" +``` + +> **Note:** You need root permissions to remove credentials + + +### Listing credentials + +To list all the credentials, you can use the `list` command in the ncc `cred` command-line tool. this will return +a list of all the credentials that are stored in the credential store with additional information about each entry. + +```shell +ncc cred list +``` + ------------------------------------------------------------------------------------ # Naming a package -- 2.45.3 From 546e6e03a95fba8eb1af25d8a5229cd5386be1d9 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 09:06:00 -0500 Subject: [PATCH 186/212] Added TOC in DOCUMENTATION.md https://git.n64.cc/nosial/ncc/-/issues/35 --- DOCUMENTATION.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index d4a5f54..b54bec0 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -34,6 +34,8 @@ NCC, from basic installation, basic usage, standards and much more. * [Listing sources](#listing-sources) * [Credential Management](#credential-management) * [Adding credentials](#adding-credentials) + * [Removing credentials](#removing-credentials) + * [Listing credentials](#listing-credentials) * [Naming a package](#naming-a-package) * [Naming conventions](#naming-conventions) * [References](#references) -- 2.45.3 From 5556c034029d7ee3e16defa4a237366791916829 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 09:38:49 -0500 Subject: [PATCH 187/212] Added documentation for assembly, versioning & UUIDs in DOCUMENTATION.md https://git.n64.cc/nosial/ncc/-/issues/35 --- DOCUMENTATION.md | 92 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index b54bec0..46171ac 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -25,6 +25,8 @@ NCC, from basic installation, basic usage, standards and much more. * [project](#project) * [project.compiler](#projectcompiler) * [project.update_source](#projectupdatesource) + * [project.update_source.repository](#projectupdatesourcerepository) + * [assembly](#assembly) * [Remote Sources](#remote-sources) * [Supported sources](#supported-sources) * [Default sources](#default-sources) @@ -36,6 +38,10 @@ NCC, from basic installation, basic usage, standards and much more. * [Adding credentials](#adding-credentials) * [Removing credentials](#removing-credentials) * [Listing credentials](#listing-credentials) +* [UUIDs](#uuids) +* [Versioning](#versioning) + * [Version Format](#version-format) + * [Version Format Compatibility](#version-format-compatibility) * [Naming a package](#naming-a-package) * [Naming conventions](#naming-conventions) * [References](#references) @@ -266,9 +272,42 @@ the program. The `project.update_source` field contains information about the source where the program can fetch updates from. -| Name | Type | Required | Description | -|------|----------|----------|-----------------------------------------------------------| -|source| `string` | Yes | The source where the program can fetch updates from, see | +| Name | Type | Required | Description | +|------------|------------------------------------|----------|-----------------------------------------------------------------------------------------------------------------------| +| source | `string` | Yes | The source where the program can fetch updates from, see [Remote Sources](#remote-sources) for additional information | +| repository | `project.update_source.repository` | Yes | The source to configure in NCC when installing the package | + +### project.update_source.repository + +The `project.update_source.repository` field contains information about the source to configure in NCC when installing +the package. This allows you to set up a remote source that your package can use to fetch updates from, this is useful +if you want to distribute your program to other people. + +It would be useful to read more about [Remote Sources](#remote-sources) before continuing. + +| Name | Type | Required | Description | +|------|----------|----------|---------------------------------------------------------------------------------------| +| name | `string` | Yes | The name of the source to configure in NCC when installing the package (eg; `github`) | +| type | `string` | Yes | The API type to use with this source, see [Supported sources](#supported-sources) | +| host | `string` | Yes | The host of the source, this is the domain name of the source (eg; `api.github.com`) | +| ssl | `bool` | No | Whether to use SSL or not when connecting to this source | + + +### assembly + +The `assembly` field contains metadata about the program, such as the name, version, description, so on. + +| Name | Type | Required | Description | +|-------------|----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| name | `string` | Yes | The name of the package, this is used to display the name of the package (eg; `Example Program`) | +| package | `string` | Yes | The package name of the program, this is used to identify the package and to avoid conflicts with other packages that may have the same name, see [Package names](#package-names) for additional information | +| description | `string` | No | The description of the package, this is used to display a description of the package when installing | +| company | `string` | No | The company that created the package, this is used to display the company that created the package when installing | +| product | `string` | No | The product that the package is a part of, this is used to display the product that the package is a part of when installing | +| copyright | `string` | No | The copyright of the package | +| trademark | `string` | No | The trademark of the package | +| version | `string` | Yes | The version of the package, see [Versioning](#versioning) for additional information | +| uuid | `string` | No | The UUID of the package, see [UUIDs](#uuids) for additional information | ------------------------------------------------------------------------------------ @@ -421,6 +460,53 @@ ncc cred list ------------------------------------------------------------------------------------ +# UUIDs + +UUIDs are used to uniquely identify a package, at the moment ncc doesn't do anything meaningful with UUIDs but in the +future it will be used to identify packages and to prevent conflicts between packages with the same name. + +The standard UUID format used is version 1, which is a time-based UUID. This means that the UUID is generated using +the current time and the MAC address of the computer that generated the UUID. + +`````` +xxxxxxxx-xxxx-1xxx-yxxx-xxxxxxxxxxxx +`````` + +UUIDs are automatically generated when a package is created, you can also manually specify a UUID by editing the +`project.json` file in the project directory, this field is found under `assembly.uuid`, see [assembly](#assembly) for +more information. + +> **Note:** Invalid UUIDs will cause the package to be rejected by ncc + +------------------------------------------------------------------------------------ + +# Versioning + +NCC uses a standard versioning system, this system is based on the [Semantic Versioning](https://semver.org/) system. + +## Version Format + +The version format is as follows: + +`````` +MAJOR.MINOR.PATCH +`````` + +- `MAJOR` is the major version of the package, this version is incremented when a major change is made to the package +- `MINOR` is the minor version of the package, this version is incremented when a minor change is made to the package +- `PATCH` is the patch version of the package, this version is incremented when a patch is made to the package + + +## Version Format Compatibility + +NCC will attempt to convert non-compatible versions to a compatible version when it comes to installing packages that +isn't built for ncc. + +> **Note:** NCC will reject packages with invalid version numbers, sometimes this can happen when the compatibility layer +fails or when the version number is invalid. + +------------------------------------------------------------------------------------ + # Naming a package NCC Follows the same naming convention as Java's naming convention. The purpose of naming a package this way is -- 2.45.3 From cd3d5847cedb9c4d17bdfa04edd778151e7c8857 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 10:21:11 -0500 Subject: [PATCH 188/212] Updated LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index db24663..723b74e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2022 Nosial - All Rights Reserved. +Copyright 2022-2023 Nosial - All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -- 2.45.3 From f24d8611bf8f7ddd8f0f25b9367038abeb608391 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sat, 28 Jan 2023 10:55:03 -0500 Subject: [PATCH 189/212] Deleted unused dependency --- .../php_console_color/CHANGELOG.md | 93 ------ .../php_console_color/ConsoleColor.php | 295 ------------------ .../InvalidStyleException.php | 11 - .../php_console_color/LICENSE | 27 -- .../php_console_color/README.md | 19 -- .../php_console_color/VERSION | 1 - 6 files changed, 446 deletions(-) delete mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md delete mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php delete mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php delete mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/LICENSE delete mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/README.md delete mode 100644 src/ncc/ThirdParty/php_parallel_lint/php_console_color/VERSION diff --git a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md deleted file mode 100644 index 4093b4d..0000000 --- a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/CHANGELOG.md +++ /dev/null @@ -1,93 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - -## [Unreleased] - -_Nothing yet._ - - -## [1.0.1] - 2021-12-25 - -### Changed - -- Support for PHP 5.3 has been restored, [#22] from [@jrfnl]. - -### Internal -- Welcome [@jrfnl] as new co-maintainer. -- Improvements to the test suite, [#14], [#16], [#19], [#23], [#24] from [@jrfnl]. -- Improvements to the code consistency, [#13], [#23], [#25] from [@jrfnl]. -- Improvements to the CI/QA setup, [#12], [#17], [#18], [#20], [#27], [#28] from [@jrfnl]. -- Improvements to the changelog, [#21] from [@jrfnl]. - -[#12]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/12 -[#13]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/13 -[#14]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/14 -[#16]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/16 -[#17]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/17 -[#18]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/18 -[#19]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/19 -[#20]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/20 -[#21]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/21 -[#22]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/22 -[#23]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/23 -[#24]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/24 -[#25]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/25 -[#27]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/27 -[#28]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/28 - - -## [1.0] - 2020-10-31 - -### Changed - -- BC-Break: The top-level namespace for all classes has changed from `JakubOnderka` to `PHP_Parallel_Lint`. [#10] from [@grogy]. - -### Added - -- Added downloading per month badge from [@grogy]. -- Added license badge from [@grogy]. -- Added instruction for installation from [@grogy]. -- Composer: add description [#11] from [@jrfnl]. - -### Internal - -- Updated PHP Parallel Lint dependency version restraint [#8] from [@jrfnl]. -- Travis: changed from "trusty" to "xenial" [#7] from [@jrfnl]. -- Update the unit tests setup [#9] from [@jrfnl]. - -[#7]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/7 -[#8]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/8 -[#9]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/9 -[#10]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/10 -[#11]: https://github.com/php-parallel-lint/PHP-Console-Color/pull/11 - - -## [0.3] - 2020-05-14 - -### Added - -- Added changelog from [@reedy]. - -### Internal - -- Travis: test against PHP 7.3 from [@samnela]. -- Cleaned readme - new organization from previous package from [@grogy]. -- Composer: updated dependancies to use new php-parallel-lint organisation from [@grogy]. -- Composer: marked package as replacing jakub-onderka/php-console-color from [@jrfnl]. -- Added a .gitattributes file from [@reedy]. -- Travis: test against PHP 7.4 and nightly from [@jrfnl]. -- Travis: only run PHPCS on PHP 7.4 from [@jrfnl]. - - -[Unreleased]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v1.0.1...HEAD -[1.0.1]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v1.0...v1.0.1 -[1.0]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v0.3...v1.0 -[0.3]: https://github.com/php-parallel-lint/PHP-Console-Color/compare/v0.2...v0.3 - -[@grogy]: https://github.com/grogy -[@jrfnl]: https://github.com/jrfnl -[@reedy]: https://github.com/reedy -[@samnela]: https://github.com/samnela diff --git a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php deleted file mode 100644 index 4cdcb08..0000000 --- a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/ConsoleColor.php +++ /dev/null @@ -1,295 +0,0 @@ - null, - 'bold' => '1', - 'dark' => '2', - 'italic' => '3', - 'underline' => '4', - 'blink' => '5', - 'reverse' => '7', - 'concealed' => '8', - - 'default' => '39', - 'black' => '30', - 'red' => '31', - 'green' => '32', - 'yellow' => '33', - 'blue' => '34', - 'magenta' => '35', - 'cyan' => '36', - 'light_gray' => '37', - - 'dark_gray' => '90', - 'light_red' => '91', - 'light_green' => '92', - 'light_yellow' => '93', - 'light_blue' => '94', - 'light_magenta' => '95', - 'light_cyan' => '96', - 'white' => '97', - - 'bg_default' => '49', - 'bg_black' => '40', - 'bg_red' => '41', - 'bg_green' => '42', - 'bg_yellow' => '43', - 'bg_blue' => '44', - 'bg_magenta' => '45', - 'bg_cyan' => '46', - 'bg_light_gray' => '47', - - 'bg_dark_gray' => '100', - 'bg_light_red' => '101', - 'bg_light_green' => '102', - 'bg_light_yellow' => '103', - 'bg_light_blue' => '104', - 'bg_light_magenta' => '105', - 'bg_light_cyan' => '106', - 'bg_white' => '107', - ); - - /** @var array */ - private $themes = array(); - - public function __construct() - { - $this->isSupported = $this->isSupported(); - } - - /** - * @param string|array $style - * @param string $text - * @return string - * @throws InvalidStyleException - * @throws \InvalidArgumentException - */ - public function apply($style, $text) - { - if (!$this->isStyleForced() && !$this->isSupported()) { - return $text; - } - - if (is_string($style)) { - $style = array($style); - } - if (!is_array($style)) { - throw new \InvalidArgumentException("Style must be string or array."); - } - - $sequences = array(); - - foreach ($style as $s) { - if (isset($this->themes[$s])) { - $sequences = array_merge($sequences, $this->themeSequence($s)); - } elseif ($this->isValidStyle($s)) { - $sequences[] = $this->styleSequence($s); - } else { - throw new InvalidStyleException($s); - } - } - - $sequences = array_filter($sequences, function ($val) { - return $val !== null; - }); - - if (empty($sequences)) { - return $text; - } - - return $this->escSequence(implode(';', $sequences)) . $text . $this->escSequence(self::RESET_STYLE); - } - - /** - * @param bool $forceStyle - */ - public function setForceStyle($forceStyle) - { - $this->forceStyle = (bool) $forceStyle; - } - - /** - * @return bool - */ - public function isStyleForced() - { - return $this->forceStyle; - } - - /** - * @param array $themes - * @throws InvalidStyleException - * @throws \InvalidArgumentException - */ - public function setThemes(array $themes) - { - $this->themes = array(); - foreach ($themes as $name => $styles) { - $this->addTheme($name, $styles); - } - } - - /** - * @param string $name - * @param array|string $styles - * @throws \InvalidArgumentException - * @throws InvalidStyleException - */ - public function addTheme($name, $styles) - { - if (is_string($styles)) { - $styles = array($styles); - } - if (!is_array($styles)) { - throw new \InvalidArgumentException("Style must be string or array."); - } - - foreach ($styles as $style) { - if (!$this->isValidStyle($style)) { - throw new InvalidStyleException($style); - } - } - - $this->themes[$name] = $styles; - } - - /** - * @return array - */ - public function getThemes() - { - return $this->themes; - } - - /** - * @param string $name - * @return bool - */ - public function hasTheme($name) - { - return isset($this->themes[$name]); - } - - /** - * @param string $name - */ - public function removeTheme($name) - { - unset($this->themes[$name]); - } - - /** - * @codeCoverageIgnore - * - * @return bool - */ - public function isSupported() - { - if (DIRECTORY_SEPARATOR === '\\') { - // phpcs:ignore Generic.PHP.NoSilencedErrors,PHPCompatibility.FunctionUse.NewFunctions.sapi_windows_vt100_supportFound - if (function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT)) { - return true; - } elseif (getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON') { - return true; - } - return false; - } else { - // phpcs:ignore Generic.PHP.NoSilencedErrors - return function_exists('posix_isatty') && @posix_isatty(STDOUT); - } - } - - /** - * @codeCoverageIgnore - * - * @return bool - */ - public function are256ColorsSupported() - { - if (DIRECTORY_SEPARATOR === '\\') { - // phpcs:ignore Generic.PHP.NoSilencedErrors,PHPCompatibility.FunctionUse.NewFunctions.sapi_windows_vt100_supportFound - return function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT); - } else { - return strpos(getenv('TERM'), '256color') !== false; - } - } - - /** - * @return array - */ - public function getPossibleStyles() - { - return array_keys($this->styles); - } - - /** - * @param string $name - * @return string[] - */ - private function themeSequence($name) - { - $sequences = array(); - foreach ($this->themes[$name] as $style) { - $sequences[] = $this->styleSequence($style); - } - return $sequences; - } - - /** - * @param string $style - * @return string - */ - private function styleSequence($style) - { - if (array_key_exists($style, $this->styles)) { - return $this->styles[$style]; - } - - if (!$this->are256ColorsSupported()) { - return null; - } - - preg_match(self::COLOR256_REGEXP, $style, $matches); - - $type = $matches[1] === 'bg_' ? self::BACKGROUND : self::FOREGROUND; - $value = $matches[2]; - - return "$type;5;$value"; - } - - /** - * @param string $style - * @return bool - */ - private function isValidStyle($style) - { - return array_key_exists($style, $this->styles) || preg_match(self::COLOR256_REGEXP, $style); - } - - /** - * @param string|int $value - * @return string - */ - private function escSequence($value) - { - return "\033[{$value}m"; - } -} diff --git a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php b/src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php deleted file mode 100644 index 6bb0336..0000000 --- a/src/ncc/ThirdParty/php_parallel_lint/php_console_color/InvalidStyleException.php +++ /dev/null @@ -1,11 +0,0 @@ - Date: Sun, 29 Jan 2023 00:31:10 -0500 Subject: [PATCH 190/212] Minor changes --- src/ncc/Managers/SymlinkManager.php | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/ncc/Managers/SymlinkManager.php b/src/ncc/Managers/SymlinkManager.php index 4f9d018..0f3516a 100644 --- a/src/ncc/Managers/SymlinkManager.php +++ b/src/ncc/Managers/SymlinkManager.php @@ -7,7 +7,7 @@ use Exception; use ncc\Abstracts\Scopes; use ncc\Exceptions\AccessDeniedException; - use ncc\Exceptions\IOException; + use ncc\Exceptions\SymlinkException; use ncc\Objects\SymlinkDictionary\SymlinkEntry; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; use ncc\Utilities\Console; @@ -65,7 +65,7 @@ * * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ public function load(): void { @@ -110,7 +110,7 @@ * @param bool $throw_exception * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ private function save(bool $throw_exception=true): void { @@ -132,7 +132,7 @@ catch(Exception $e) { if($throw_exception) - throw new IOException(sprintf('failed to save symlink dictionary to %s', $this->SymlinkDictionaryPath), $e); + throw new SymlinkException(sprintf('failed to save symlink dictionary to %s', $this->SymlinkDictionaryPath), $e); Console::outWarning(sprintf('failed to save symlink dictionary to %s', $this->SymlinkDictionaryPath)); } @@ -182,7 +182,7 @@ * @param string $unit * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ public function add(string $package, string $unit='main'): void { @@ -206,7 +206,7 @@ * @param string $package * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ public function remove(string $package): void { @@ -229,7 +229,6 @@ if($filesystem->exists($symlink)) $filesystem->remove($symlink); - } unset($this->SymlinkDictionary[$key]); @@ -238,7 +237,7 @@ } } - throw new IOException(sprintf('failed to remove package %s from the symlink dictionary', $package)); + throw new SymlinkException(sprintf('failed to remove package %s from the symlink dictionary', $package)); } /** @@ -247,7 +246,7 @@ * @param string $package * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ private function setAsRegistered(string $package): void { @@ -269,7 +268,7 @@ * @param string $package * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ private function setAsUnregistered(string $package): void { @@ -290,7 +289,7 @@ * * @return void * @throws AccessDeniedException - * @throws IOException + * @throws SymlinkException */ public function sync(): void { -- 2.45.3 From f2d2839d0efc610a5bf848cb4cc7d04e3d05e72d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 01:11:14 -0500 Subject: [PATCH 191/212] Added SymlinkException --- src/ncc/Exceptions/SymlinkException.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/ncc/Exceptions/SymlinkException.php diff --git a/src/ncc/Exceptions/SymlinkException.php b/src/ncc/Exceptions/SymlinkException.php new file mode 100644 index 0000000..5a315eb --- /dev/null +++ b/src/ncc/Exceptions/SymlinkException.php @@ -0,0 +1,20 @@ +message = $message; + } + } \ No newline at end of file -- 2.45.3 From 893166ebf815c17fab93698e81686eaf873bd08f Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 01:11:23 -0500 Subject: [PATCH 192/212] Updated ExceptionCodes --- src/ncc/Abstracts/ExceptionCodes.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index dee6915..f8d2a87 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -2,6 +2,8 @@ namespace ncc\Abstracts; + use ncc\Exceptions\SymlinkException; + /** * @author Zi Xing Narrakas * @copyright Copyright (C) 2022-2022. Nosial - All Rights Reserved. @@ -348,6 +350,11 @@ */ const InvalidDependencyConfiguration = -1767; + /** + * @see SymlinkException + */ + const SymlinkException = -1768; + /** * All the exception codes from NCC */ @@ -417,5 +424,6 @@ self::PackageFetchException, self::InvalidBuildConfigurationException, self::InvalidDependencyConfiguration, + self::SymlinkException, ]; } \ No newline at end of file -- 2.45.3 From 10cd70ff79c570c5d2b82b20876ec15158836e61 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 01:28:06 -0500 Subject: [PATCH 193/212] Refactored Exceptions --- src/ncc/Exceptions/ArchiveException.php | 4 ++++ src/ncc/Exceptions/AuthenticationException.php | 1 - .../BuildConfigurationNotFoundException.php | 4 ---- src/ncc/Exceptions/BuildException.php | 7 ------- .../Exceptions/ComponentChecksumException.php | 6 ------ .../Exceptions/ComponentDecodeException.php | 7 ------- .../Exceptions/ComposerDisabledException.php | 7 ------- src/ncc/Exceptions/ComposerException.php | 7 ------- .../ComposerNotAvailableException.php | 7 ------- .../Exceptions/DirectoryNotFoundException.php | 1 - .../ExecutionUnitNotFoundException.php | 8 -------- src/ncc/Exceptions/FileNotFoundException.php | 1 - src/ncc/Exceptions/GitCheckoutException.php | 1 - src/ncc/Exceptions/GitCloneException.php | 1 - src/ncc/Exceptions/GitTagsException.php | 1 - src/ncc/Exceptions/GithubServiceException.php | 1 - src/ncc/Exceptions/GitlabServiceException.php | 1 - src/ncc/Exceptions/HttpException.php | 1 - src/ncc/Exceptions/IOException.php | 7 ------- src/ncc/Exceptions/ImportException.php | 1 - src/ncc/Exceptions/InstallationException.php | 7 ------- .../InternalComposerNotAvailableException.php | 7 ------- .../InvalidBuildConfigurationException.php | 1 - .../InvalidConstantNameException.php | 7 ------- .../InvalidDependencyConfiguration.php | 1 - .../Exceptions/InvalidExecutionPolicyName.php | 7 ++++++- src/ncc/Exceptions/InvalidPackageException.php | 4 ---- .../InvalidProjectBuildConfiguration.php | 4 ---- .../InvalidProjectConfigurationException.php | 18 ++++++++---------- .../InvalidPropertyValueException.php | 14 +++++++++++--- src/ncc/Exceptions/InvalidScopeException.php | 2 -- .../InvalidVersionConfigurationException.php | 7 ------- .../Exceptions/MissingDependencyException.php | 7 ------- .../Exceptions/NoAvailableUnitsException.php | 7 ------- src/ncc/Exceptions/NoUnitsFoundException.php | 7 ------- src/ncc/Exceptions/NotImplementedException.php | 7 ------- src/ncc/Exceptions/NotSupportedException.php | 1 - .../PackageAlreadyInstalledException.php | 7 ------- src/ncc/Exceptions/PackageFetchException.php | 4 ++++ src/ncc/Exceptions/PackageLockException.php | 7 ------- .../Exceptions/PackageNotFoundException.php | 7 ------- src/ncc/Exceptions/PackageParsingException.php | 7 ------- .../PackagePreparationFailedException.php | 7 ------- .../ProjectConfigurationNotFoundException.php | 8 +++++++- .../Exceptions/ResourceChecksumException.php | 8 -------- .../Exceptions/RunnerExecutionException.php | 7 ------- src/ncc/Exceptions/SymlinkException.php | 1 - .../UndefinedExecutionPolicyException.php | 7 ------- .../Exceptions/UnsupportedArchiveException.php | 1 - .../UnsupportedCompilerExtensionException.php | 7 ------- .../UnsupportedComponentTypeException.php | 7 ------- .../UnsupportedExtensionVersionException.php | 10 ++++++++-- .../Exceptions/UnsupportedPackageException.php | 4 ---- .../UnsupportedProjectTypeException.php | 1 - .../UnsupportedRemoteSourceTypeException.php | 1 - .../Exceptions/UnsupportedRunnerException.php | 11 ----------- .../UserAbortedOperationException.php | 7 ------- .../Exceptions/VersionNotFoundException.php | 7 ------- 58 files changed, 48 insertions(+), 260 deletions(-) delete mode 100644 src/ncc/Exceptions/ExecutionUnitNotFoundException.php delete mode 100644 src/ncc/Exceptions/UnsupportedRunnerException.php diff --git a/src/ncc/Exceptions/ArchiveException.php b/src/ncc/Exceptions/ArchiveException.php index a7e7a22..065c445 100644 --- a/src/ncc/Exceptions/ArchiveException.php +++ b/src/ncc/Exceptions/ArchiveException.php @@ -8,6 +8,10 @@ class ArchiveException extends Exception { + /** + * @param string $message + * @param Throwable|null $previous + */ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::ArchiveException, $previous); diff --git a/src/ncc/Exceptions/AuthenticationException.php b/src/ncc/Exceptions/AuthenticationException.php index 29a927c..d8dd399 100644 --- a/src/ncc/Exceptions/AuthenticationException.php +++ b/src/ncc/Exceptions/AuthenticationException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::AuthenticationException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/BuildConfigurationNotFoundException.php b/src/ncc/Exceptions/BuildConfigurationNotFoundException.php index 59d0e43..e12dd75 100644 --- a/src/ncc/Exceptions/BuildConfigurationNotFoundException.php +++ b/src/ncc/Exceptions/BuildConfigurationNotFoundException.php @@ -10,8 +10,6 @@ class BuildConfigurationNotFoundException extends Exception { - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -19,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::BuildConfigurationNotFoundException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/BuildException.php b/src/ncc/Exceptions/BuildException.php index 7fbb3d8..877f3a2 100644 --- a/src/ncc/Exceptions/BuildException.php +++ b/src/ncc/Exceptions/BuildException.php @@ -10,11 +10,6 @@ class BuildException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::BuildException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ComponentChecksumException.php b/src/ncc/Exceptions/ComponentChecksumException.php index 68bb520..b8e193a 100644 --- a/src/ncc/Exceptions/ComponentChecksumException.php +++ b/src/ncc/Exceptions/ComponentChecksumException.php @@ -10,10 +10,6 @@ class ComponentChecksumException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; /** * @param string $message @@ -22,7 +18,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::ComponentChecksumException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ComponentDecodeException.php b/src/ncc/Exceptions/ComponentDecodeException.php index 593255f..40012fd 100644 --- a/src/ncc/Exceptions/ComponentDecodeException.php +++ b/src/ncc/Exceptions/ComponentDecodeException.php @@ -10,11 +10,6 @@ class ComponentDecodeException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::ComponentDecodeException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ComposerDisabledException.php b/src/ncc/Exceptions/ComposerDisabledException.php index 01c5be6..3538443 100644 --- a/src/ncc/Exceptions/ComposerDisabledException.php +++ b/src/ncc/Exceptions/ComposerDisabledException.php @@ -9,11 +9,6 @@ class ComposerDisabledException extends \Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -21,7 +16,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::ComposerDisabledException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ComposerException.php b/src/ncc/Exceptions/ComposerException.php index 9e37388..8e6607b 100644 --- a/src/ncc/Exceptions/ComposerException.php +++ b/src/ncc/Exceptions/ComposerException.php @@ -10,11 +10,6 @@ class ComposerException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::ComposerException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ComposerNotAvailableException.php b/src/ncc/Exceptions/ComposerNotAvailableException.php index 2fa1d4b..453de30 100644 --- a/src/ncc/Exceptions/ComposerNotAvailableException.php +++ b/src/ncc/Exceptions/ComposerNotAvailableException.php @@ -10,11 +10,6 @@ class ComposerNotAvailableException extends Exception { - /** - * @var null - */ - private $previous; - /** * @param string $message * @param $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", $previous = null) { parent::__construct($message, ExceptionCodes::ComposerNotAvailableException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/DirectoryNotFoundException.php b/src/ncc/Exceptions/DirectoryNotFoundException.php index cb6fe49..26308dd 100644 --- a/src/ncc/Exceptions/DirectoryNotFoundException.php +++ b/src/ncc/Exceptions/DirectoryNotFoundException.php @@ -17,6 +17,5 @@ public function __construct(string $path = "", ?Throwable $previous = null) { parent::__construct('The file \'' . realpath($path) . '\' was not found', ExceptionCodes::DirectoryNotFoundException, $previous); - $this->code = ExceptionCodes::DirectoryNotFoundException; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ExecutionUnitNotFoundException.php b/src/ncc/Exceptions/ExecutionUnitNotFoundException.php deleted file mode 100644 index 228f512..0000000 --- a/src/ncc/Exceptions/ExecutionUnitNotFoundException.php +++ /dev/null @@ -1,8 +0,0 @@ -code = ExceptionCodes::FileNotFoundException; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/GitCheckoutException.php b/src/ncc/Exceptions/GitCheckoutException.php index cd84341..73bb744 100644 --- a/src/ncc/Exceptions/GitCheckoutException.php +++ b/src/ncc/Exceptions/GitCheckoutException.php @@ -14,6 +14,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::GitCheckoutException, $previous); - $this->message = $message; } } diff --git a/src/ncc/Exceptions/GitCloneException.php b/src/ncc/Exceptions/GitCloneException.php index a9cc009..547f3be 100644 --- a/src/ncc/Exceptions/GitCloneException.php +++ b/src/ncc/Exceptions/GitCloneException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::GitCloneException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/GitTagsException.php b/src/ncc/Exceptions/GitTagsException.php index 385de18..cfeda4d 100644 --- a/src/ncc/Exceptions/GitTagsException.php +++ b/src/ncc/Exceptions/GitTagsException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::GitTagsException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/GithubServiceException.php b/src/ncc/Exceptions/GithubServiceException.php index 5d62b3b..f4deb06 100644 --- a/src/ncc/Exceptions/GithubServiceException.php +++ b/src/ncc/Exceptions/GithubServiceException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::GithubServiceException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/GitlabServiceException.php b/src/ncc/Exceptions/GitlabServiceException.php index 202ee1e..8cafebb 100644 --- a/src/ncc/Exceptions/GitlabServiceException.php +++ b/src/ncc/Exceptions/GitlabServiceException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::GitlabServiceException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/HttpException.php b/src/ncc/Exceptions/HttpException.php index 73d5cd7..c6904fc 100644 --- a/src/ncc/Exceptions/HttpException.php +++ b/src/ncc/Exceptions/HttpException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::HttpException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/IOException.php b/src/ncc/Exceptions/IOException.php index e733d0c..3bc85be 100644 --- a/src/ncc/Exceptions/IOException.php +++ b/src/ncc/Exceptions/IOException.php @@ -10,11 +10,6 @@ class IOException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::IOException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ImportException.php b/src/ncc/Exceptions/ImportException.php index 37defdf..a229f6a 100644 --- a/src/ncc/Exceptions/ImportException.php +++ b/src/ncc/Exceptions/ImportException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::ImportException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InstallationException.php b/src/ncc/Exceptions/InstallationException.php index 1b99c67..5caa275 100644 --- a/src/ncc/Exceptions/InstallationException.php +++ b/src/ncc/Exceptions/InstallationException.php @@ -10,11 +10,6 @@ class InstallationException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InstallationException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InternalComposerNotAvailableException.php b/src/ncc/Exceptions/InternalComposerNotAvailableException.php index 718114b..94ad473 100644 --- a/src/ncc/Exceptions/InternalComposerNotAvailableException.php +++ b/src/ncc/Exceptions/InternalComposerNotAvailableException.php @@ -10,11 +10,6 @@ class InternalComposerNotAvailableException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InternalComposerNotAvailable, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidBuildConfigurationException.php b/src/ncc/Exceptions/InvalidBuildConfigurationException.php index cc2ea91..8e1cf60 100644 --- a/src/ncc/Exceptions/InvalidBuildConfigurationException.php +++ b/src/ncc/Exceptions/InvalidBuildConfigurationException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidBuildConfigurationException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidConstantNameException.php b/src/ncc/Exceptions/InvalidConstantNameException.php index 1e8e36e..5e7b020 100644 --- a/src/ncc/Exceptions/InvalidConstantNameException.php +++ b/src/ncc/Exceptions/InvalidConstantNameException.php @@ -10,11 +10,6 @@ class InvalidConstantNameException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidConstantNameException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidDependencyConfiguration.php b/src/ncc/Exceptions/InvalidDependencyConfiguration.php index 8745d53..caa31bb 100644 --- a/src/ncc/Exceptions/InvalidDependencyConfiguration.php +++ b/src/ncc/Exceptions/InvalidDependencyConfiguration.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidDependencyConfiguration, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidExecutionPolicyName.php b/src/ncc/Exceptions/InvalidExecutionPolicyName.php index 2699960..b5e96ca 100644 --- a/src/ncc/Exceptions/InvalidExecutionPolicyName.php +++ b/src/ncc/Exceptions/InvalidExecutionPolicyName.php @@ -3,12 +3,17 @@ namespace ncc\Exceptions; use Exception; + use ncc\Abstracts\ExceptionCodes; use Throwable; class InvalidExecutionPolicyName extends Exception { + /** + * @param string $message + * @param Throwable|null $previous + */ public function __construct(string $message = "", ?Throwable $previous = null) { - parent::__construct($message, $code, $previous); + parent::__construct($message, ExceptionCodes::InvalidExecutionPolicyName, $previous); } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidPackageException.php b/src/ncc/Exceptions/InvalidPackageException.php index 04d3ff9..6175501 100644 --- a/src/ncc/Exceptions/InvalidPackageException.php +++ b/src/ncc/Exceptions/InvalidPackageException.php @@ -10,8 +10,6 @@ class InvalidPackageException extends Exception { - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -19,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidPackageException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php b/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php index 51d12fb..cce36d5 100644 --- a/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php +++ b/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php @@ -10,8 +10,6 @@ class InvalidProjectBuildConfiguration extends Exception { - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -19,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidProjectBuildConfiguration, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidProjectConfigurationException.php b/src/ncc/Exceptions/InvalidProjectConfigurationException.php index 4923365..1662fc7 100644 --- a/src/ncc/Exceptions/InvalidProjectConfigurationException.php +++ b/src/ncc/Exceptions/InvalidProjectConfigurationException.php @@ -12,15 +12,7 @@ */ class InvalidProjectConfigurationException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - - /** - * The full property name that needs correcting - * * @var string|null */ private ?string $property; @@ -33,8 +25,14 @@ public function __construct(string $message = "", ?string $property=null, ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidProjectConfigurationException, $previous); - $this->message = $message; - $this->previous = $previous; $this->property = $property; } + + /** + * @return string|null + */ + public function getProperty(): ?string + { + return $this->property; + } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidPropertyValueException.php b/src/ncc/Exceptions/InvalidPropertyValueException.php index eb1ac64..0606ace 100644 --- a/src/ncc/Exceptions/InvalidPropertyValueException.php +++ b/src/ncc/Exceptions/InvalidPropertyValueException.php @@ -2,10 +2,18 @@ namespace ncc\Exceptions; - class InvalidPropertyValueException extends \Exception + use Exception; + use ncc\Abstracts\ExceptionCodes; + use Throwable; + + class InvalidPropertyValueException extends Exception { - public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) + /** + * @param string $message + * @param Throwable|null $previous + */ + public function __construct(string $message = "", ?Throwable $previous = null) { - parent::__construct($message, $code, $previous); + parent::__construct($message, ExceptionCodes::InvalidPropertyValueException, $previous); } } \ No newline at end of file diff --git a/src/ncc/Exceptions/InvalidScopeException.php b/src/ncc/Exceptions/InvalidScopeException.php index 2bc6070..cebd2ea 100644 --- a/src/ncc/Exceptions/InvalidScopeException.php +++ b/src/ncc/Exceptions/InvalidScopeException.php @@ -9,8 +9,6 @@ class InvalidScopeException extends Exception { /** - * Public Constructor - * * @param string $scope * @param Throwable|null $previous */ diff --git a/src/ncc/Exceptions/InvalidVersionConfigurationException.php b/src/ncc/Exceptions/InvalidVersionConfigurationException.php index 3895476..9c45021 100644 --- a/src/ncc/Exceptions/InvalidVersionConfigurationException.php +++ b/src/ncc/Exceptions/InvalidVersionConfigurationException.php @@ -10,11 +10,6 @@ class InvalidVersionConfigurationException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::InvalidVersionConfigurationException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/MissingDependencyException.php b/src/ncc/Exceptions/MissingDependencyException.php index bd3104e..df2b8e6 100644 --- a/src/ncc/Exceptions/MissingDependencyException.php +++ b/src/ncc/Exceptions/MissingDependencyException.php @@ -10,11 +10,6 @@ class MissingDependencyException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::MissingDependencyException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/NoAvailableUnitsException.php b/src/ncc/Exceptions/NoAvailableUnitsException.php index 56d61ac..86f4de6 100644 --- a/src/ncc/Exceptions/NoAvailableUnitsException.php +++ b/src/ncc/Exceptions/NoAvailableUnitsException.php @@ -10,11 +10,6 @@ class NoAvailableUnitsException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::NoAvailableUnitsException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/NoUnitsFoundException.php b/src/ncc/Exceptions/NoUnitsFoundException.php index a59e3da..5bd312a 100644 --- a/src/ncc/Exceptions/NoUnitsFoundException.php +++ b/src/ncc/Exceptions/NoUnitsFoundException.php @@ -8,11 +8,6 @@ class NoUnitsFoundException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -20,7 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::NoUnitsFoundException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/NotImplementedException.php b/src/ncc/Exceptions/NotImplementedException.php index e53d390..69d005f 100644 --- a/src/ncc/Exceptions/NotImplementedException.php +++ b/src/ncc/Exceptions/NotImplementedException.php @@ -10,11 +10,6 @@ class NotImplementedException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::NotImplementedException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/NotSupportedException.php b/src/ncc/Exceptions/NotSupportedException.php index 9ea4f25..14ba7c7 100644 --- a/src/ncc/Exceptions/NotSupportedException.php +++ b/src/ncc/Exceptions/NotSupportedException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::NotSupportedException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/PackageAlreadyInstalledException.php b/src/ncc/Exceptions/PackageAlreadyInstalledException.php index fbf5c49..7b3685d 100644 --- a/src/ncc/Exceptions/PackageAlreadyInstalledException.php +++ b/src/ncc/Exceptions/PackageAlreadyInstalledException.php @@ -10,11 +10,6 @@ class PackageAlreadyInstalledException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::PackageAlreadyInstalledException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/PackageFetchException.php b/src/ncc/Exceptions/PackageFetchException.php index 031f860..27d60ec 100644 --- a/src/ncc/Exceptions/PackageFetchException.php +++ b/src/ncc/Exceptions/PackageFetchException.php @@ -7,6 +7,10 @@ class PackageFetchException extends \Exception { + /** + * @param string $message + * @param Throwable|null $previous + */ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::PackageFetchException, $previous); diff --git a/src/ncc/Exceptions/PackageLockException.php b/src/ncc/Exceptions/PackageLockException.php index b86c20c..c5623d0 100644 --- a/src/ncc/Exceptions/PackageLockException.php +++ b/src/ncc/Exceptions/PackageLockException.php @@ -10,11 +10,6 @@ class PackageLockException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::PackageLockException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/PackageNotFoundException.php b/src/ncc/Exceptions/PackageNotFoundException.php index 88bd370..3fc7ab0 100644 --- a/src/ncc/Exceptions/PackageNotFoundException.php +++ b/src/ncc/Exceptions/PackageNotFoundException.php @@ -10,11 +10,6 @@ class PackageNotFoundException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::PackageNotFoundException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/PackageParsingException.php b/src/ncc/Exceptions/PackageParsingException.php index 70c1be7..ae1dfaa 100644 --- a/src/ncc/Exceptions/PackageParsingException.php +++ b/src/ncc/Exceptions/PackageParsingException.php @@ -10,11 +10,6 @@ class PackageParsingException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::PackageParsingException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/PackagePreparationFailedException.php b/src/ncc/Exceptions/PackagePreparationFailedException.php index 5a45e3e..2a7fccb 100644 --- a/src/ncc/Exceptions/PackagePreparationFailedException.php +++ b/src/ncc/Exceptions/PackagePreparationFailedException.php @@ -10,11 +10,6 @@ class PackagePreparationFailedException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::PackagePreparationFailedException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ProjectConfigurationNotFoundException.php b/src/ncc/Exceptions/ProjectConfigurationNotFoundException.php index 2897f72..933a095 100644 --- a/src/ncc/Exceptions/ProjectConfigurationNotFoundException.php +++ b/src/ncc/Exceptions/ProjectConfigurationNotFoundException.php @@ -3,11 +3,17 @@ namespace ncc\Exceptions; use Exception; + use ncc\Abstracts\ExceptionCodes; + use Throwable; class ProjectConfigurationNotFoundException extends Exception { + /** + * @param string $message + * @param Throwable|null $previous + */ public function __construct(string $message = "", ?Throwable $previous = null) { - parent::__construct($message, $previous); + parent::__construct($message, ExceptionCodes::ProjectConfigurationNotFoundException, $previous); } } \ No newline at end of file diff --git a/src/ncc/Exceptions/ResourceChecksumException.php b/src/ncc/Exceptions/ResourceChecksumException.php index 911a885..edc0b82 100644 --- a/src/ncc/Exceptions/ResourceChecksumException.php +++ b/src/ncc/Exceptions/ResourceChecksumException.php @@ -9,11 +9,6 @@ class ResourceChecksumException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param int $code @@ -22,8 +17,5 @@ public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) { parent::__construct($message, $code, $previous); - $this->message = $message; - $this->code = $code; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/RunnerExecutionException.php b/src/ncc/Exceptions/RunnerExecutionException.php index e568dd1..7022c73 100644 --- a/src/ncc/Exceptions/RunnerExecutionException.php +++ b/src/ncc/Exceptions/RunnerExecutionException.php @@ -10,11 +10,6 @@ class RunnerExecutionException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::RunnerExecutionException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/SymlinkException.php b/src/ncc/Exceptions/SymlinkException.php index 5a315eb..a10038f 100644 --- a/src/ncc/Exceptions/SymlinkException.php +++ b/src/ncc/Exceptions/SymlinkException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::SymlinkException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UndefinedExecutionPolicyException.php b/src/ncc/Exceptions/UndefinedExecutionPolicyException.php index 8797b5e..ffd4e54 100644 --- a/src/ncc/Exceptions/UndefinedExecutionPolicyException.php +++ b/src/ncc/Exceptions/UndefinedExecutionPolicyException.php @@ -10,11 +10,6 @@ class UndefinedExecutionPolicyException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UndefinedExecutionPolicyException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedArchiveException.php b/src/ncc/Exceptions/UnsupportedArchiveException.php index c667c79..114012c 100644 --- a/src/ncc/Exceptions/UnsupportedArchiveException.php +++ b/src/ncc/Exceptions/UnsupportedArchiveException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UnsupportedArchiveException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php b/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php index ddd520c..ba91f2b 100644 --- a/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php +++ b/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php @@ -10,11 +10,6 @@ class UnsupportedCompilerExtensionException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UnsupportedCompilerExtensionException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedComponentTypeException.php b/src/ncc/Exceptions/UnsupportedComponentTypeException.php index ecd4c79..50887f7 100644 --- a/src/ncc/Exceptions/UnsupportedComponentTypeException.php +++ b/src/ncc/Exceptions/UnsupportedComponentTypeException.php @@ -10,11 +10,6 @@ class UnsupportedComponentTypeException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UnsupportedComponentTypeException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedExtensionVersionException.php b/src/ncc/Exceptions/UnsupportedExtensionVersionException.php index f24b429..9196106 100644 --- a/src/ncc/Exceptions/UnsupportedExtensionVersionException.php +++ b/src/ncc/Exceptions/UnsupportedExtensionVersionException.php @@ -3,11 +3,17 @@ namespace ncc\Exceptions; use Exception; + use ncc\Abstracts\ExceptionCodes; + use Throwable; class UnsupportedExtensionVersionException extends Exception { - public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) + /** + * @param string $message + * @param Throwable|null $previous + */ + public function __construct(string $message = "", ?Throwable $previous = null) { - parent::__construct($message, $code, $previous); + parent::__construct($message, ExceptionCodes::UnsupportedExtensionVersionException, $previous); } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedPackageException.php b/src/ncc/Exceptions/UnsupportedPackageException.php index e16c0e2..2e1f108 100644 --- a/src/ncc/Exceptions/UnsupportedPackageException.php +++ b/src/ncc/Exceptions/UnsupportedPackageException.php @@ -10,8 +10,6 @@ class UnsupportedPackageException extends Exception { - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -19,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UnsupportedPackageException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedProjectTypeException.php b/src/ncc/Exceptions/UnsupportedProjectTypeException.php index 384a2b2..24367fd 100644 --- a/src/ncc/Exceptions/UnsupportedProjectTypeException.php +++ b/src/ncc/Exceptions/UnsupportedProjectTypeException.php @@ -16,6 +16,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UnsupportedProjectTypeException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php b/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php index 6548f35..bf8d2ff 100644 --- a/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php +++ b/src/ncc/Exceptions/UnsupportedRemoteSourceTypeException.php @@ -15,6 +15,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::UnsupportedRemoteSourceTypeException, $previous); - $this->message = $message; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/UnsupportedRunnerException.php b/src/ncc/Exceptions/UnsupportedRunnerException.php deleted file mode 100644 index 830a7a1..0000000 --- a/src/ncc/Exceptions/UnsupportedRunnerException.php +++ /dev/null @@ -1,11 +0,0 @@ -message = $message; - $this->previous = $previous; } } \ No newline at end of file diff --git a/src/ncc/Exceptions/VersionNotFoundException.php b/src/ncc/Exceptions/VersionNotFoundException.php index b7b4acc..6127154 100644 --- a/src/ncc/Exceptions/VersionNotFoundException.php +++ b/src/ncc/Exceptions/VersionNotFoundException.php @@ -10,11 +10,6 @@ class VersionNotFoundException extends Exception { - /** - * @var Throwable|null - */ - private ?Throwable $previous; - /** * @param string $message * @param Throwable|null $previous @@ -22,7 +17,5 @@ public function __construct(string $message = "", ?Throwable $previous = null) { parent::__construct($message, ExceptionCodes::VersionNotFoundException, $previous); - $this->message = $message; - $this->previous = $previous; } } \ No newline at end of file -- 2.45.3 From 0975aaf88a83ea8bc21ef7938ad55fbdb79e7a06 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 02:24:12 -0500 Subject: [PATCH 194/212] Added error codes in DOCUMENTATION.md --- DOCUMENTATION.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 46171ac..84041b0 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -45,6 +45,7 @@ NCC, from basic installation, basic usage, standards and much more. * [Naming a package](#naming-a-package) * [Naming conventions](#naming-conventions) * [References](#references) +* [Error Codes](#error-codes) ## Introduction @@ -534,4 +535,83 @@ like a region to name packages, for example `net.nosial.region.example` For Java's package naming conventions see [Naming a Package](https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html) from the Oracle's Java documentation resource, as the same rules apply to NCC except for *some* illegal naming -conventions such as packages not being able to begin with `int` or numbers \ No newline at end of file +conventions such as packages not being able to begin with `int` or numbers + +------------------------------------------------------------------------------------ + +# Error Codes + +NCC uses error codes to identify errors, these error codes are used to identify errors in the ncc command-line tool +and in the ncc API. + +| Error Code | Name | +|:----------:|:--------------------------------------| +| `-1700` | InvalidProjectConfigurationException | +| `-1701` | FileNotFoundException | +| `-1702` | DirectoryNotFoundException | +| `-1703` | InvalidScopeException | +| `-1704` | AccessDeniedException | +| `-1705` | MalformedJsonException | +| `-1706` | RuntimeException | +| `-1707` | InvalidCredentialsEntryException | +| `-1708` | ComponentVersionNotFoundException | +| `-1709` | ConstantReadonlyException | +| `-1710` | InvalidPackageNameException | +| `-1711` | InvalidVersionNumberException | +| `-1712` | InvalidProjectNameException | +| `-1713` | ProjectAlreadyExistsException | +| `-1714` | AutoloadGeneratorException | +| `-1715` | NoUnitsFoundException | +| `-1716` | UnsupportedPackageException | +| `-1717` | NotImplementedException | +| `-1718` | InvalidPackageException | +| `-1719` | InvalidConstantNameException | +| `-1720` | PackagePreparationFailedException | +| `-1721` | BuildConfigurationNotFoundException | +| `-1722` | InvalidProjectBuildConfiguration | +| `-1723` | UnsupportedCompilerExtensionException | +| `-1724` | InvalidPropertyValueException | +| `-1725` | InvalidVersionConfigurationException | +| `-1726` | UnsupportedExtensionVersionException | +| `-1727` | BuildException | +| `-1728` | PackageParsingException | +| `-1729` | PackageLockException | +| `-1730` | InstallationException | +| `-1731` | UnsupportedComponentTypeException | +| `-1732` | ComponentDecodeException | +| `-1733` | ComponentChecksumException | +| `-1734` | ResourceChecksumException | +| `-1735` | IOException | +| `-1736` | UnsupportedRunnerException | +| `-1737` | VersionNotFoundException | +| `-1738` | UndefinedExecutionPolicyException | +| `-1739` | InvalidExecutionPolicyName | +| `-1740` | ProjectConfigurationNotFoundException | +| `-1741` | RunnerExecutionException | +| `-1742` | NoAvailableUnitsException | +| `-1743` | ExecutionUnitNotFoundException | +| `-1744` | PackageAlreadyInstalledException | +| `-1745` | PackageNotFoundException | +| `-1746` | ComposerDisabledException | +| `-1747` | InternalComposerNotAvailable | +| `-1748` | ComposerNotAvailableException | +| `-1749` | ComposerException | +| `-1750` | UserAbortedOperationException | +| `-1751` | MissingDependencyException | +| `-1752` | HttpException | +| `-1753` | UnsupportedRemoteSourceTypeException | +| `-1754` | GitCloneException | +| `-1755` | GitCheckoutException | +| `-1756` | GitlabServiceException | +| `-1757` | ImportException | +| `-1758` | GitTagsException | +| `-1759` | GithubServiceException | +| `-1760` | AuthenticationException | +| `-1761` | NotSupportedException | +| `-1762` | UnsupportedProjectTypeException | +| `-1763` | UnsupportedArchiveException | +| `-1764` | ArchiveException | +| `-1765` | PackageFetchException | +| `-1766` | InvalidBuildConfigurationException | +| `-1767` | InvalidDependencyConfiguration | +| `-1768` | SymlinkException | -- 2.45.3 From 3a4e7413b6b17ccbab3d7682aa144b3d28c4b534 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 02:30:49 -0500 Subject: [PATCH 195/212] Updated Makefile --- Makefile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Makefile b/Makefile index fee0f12..f2a4382 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ autoload: make $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/jelix/version/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/nikic/php-parser/autoload_spl.php - make $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php make $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php @@ -33,10 +32,6 @@ $(SRC_PATH)/ncc/ThirdParty/nikic/php-parser/autoload_spl.php: $(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php \ $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser -$(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php: - $(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php \ - $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color - $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php: $(PHPCC) $(PHPAB) --output $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php \ $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype @@ -114,7 +109,6 @@ clean: rm -f $(SRC_PATH)/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/jelix/version/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php - rm -f $(SRC_PATH)/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php rm -f $(SRC_PATH)/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php -- 2.45.3 From 2bd04cc48162a94fe677e66e6b25e66d35ff0ad5 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 13:23:07 -0500 Subject: [PATCH 196/212] Cleaned up abstract classes --- src/ncc/Abstracts/AuthenticationSource.php | 12 ------------ src/ncc/Abstracts/BuiltinRemoteSourceType.php | 17 ----------------- src/ncc/Abstracts/CompilerOptions.php | 8 -------- src/ncc/Abstracts/ComposerPackageTypes.php | 2 +- src/ncc/Abstracts/StringPaddingMethod.php | 12 ------------ .../Exceptions/InvalidProjectNameException.php | 2 +- 6 files changed, 2 insertions(+), 51 deletions(-) delete mode 100644 src/ncc/Abstracts/AuthenticationSource.php delete mode 100644 src/ncc/Abstracts/BuiltinRemoteSourceType.php delete mode 100644 src/ncc/Abstracts/CompilerOptions.php delete mode 100644 src/ncc/Abstracts/StringPaddingMethod.php diff --git a/src/ncc/Abstracts/AuthenticationSource.php b/src/ncc/Abstracts/AuthenticationSource.php deleted file mode 100644 index c5b29f8..0000000 --- a/src/ncc/Abstracts/AuthenticationSource.php +++ /dev/null @@ -1,12 +0,0 @@ - Date: Sun, 29 Jan 2023 13:32:34 -0500 Subject: [PATCH 197/212] Updated Intellij Idea scopes --- .idea/scopes/Autoloaders.xml | 3 +++ .idea/scopes/Installer_Source_files.xml | 3 +++ .idea/scopes/NCC_Source_files.xml | 2 +- .idea/scopes/Symfony_Filesystem.xml | 3 +++ .idea/scopes/Symfony_Process.xml | 3 +++ .idea/scopes/Symfony_Uid.xml | 3 +++ .idea/scopes/Symfony_Yaml.xml | 3 +++ .idea/scopes/Symfony_polyfill_ctype.xml | 3 +++ .idea/scopes/Symfony_polyfill_mbstring.xml | 3 +++ .idea/scopes/Symfony_polyfill_uuid.xml | 3 +++ .idea/scopes/defuse.xml | 3 +++ .idea/scopes/defuse_php_encryption.xml | 3 +++ .idea/scopes/jelix.xml | 3 +++ .idea/scopes/jelix_version.xml | 3 +++ .idea/scopes/nikic.xml | 3 +++ .idea/scopes/nikic_PhpParser.xml | 3 +++ .idea/scopes/theseer.xml | 3 +++ .idea/scopes/theseer_Autoload.xml | 3 +++ .idea/scopes/theseer_DirectoryScanner.xml | 3 +++ 19 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 .idea/scopes/Autoloaders.xml create mode 100644 .idea/scopes/Installer_Source_files.xml create mode 100644 .idea/scopes/Symfony_Filesystem.xml create mode 100644 .idea/scopes/Symfony_Process.xml create mode 100644 .idea/scopes/Symfony_Uid.xml create mode 100644 .idea/scopes/Symfony_Yaml.xml create mode 100644 .idea/scopes/Symfony_polyfill_ctype.xml create mode 100644 .idea/scopes/Symfony_polyfill_mbstring.xml create mode 100644 .idea/scopes/Symfony_polyfill_uuid.xml create mode 100644 .idea/scopes/defuse.xml create mode 100644 .idea/scopes/defuse_php_encryption.xml create mode 100644 .idea/scopes/jelix.xml create mode 100644 .idea/scopes/jelix_version.xml create mode 100644 .idea/scopes/nikic.xml create mode 100644 .idea/scopes/nikic_PhpParser.xml create mode 100644 .idea/scopes/theseer.xml create mode 100644 .idea/scopes/theseer_Autoload.xml create mode 100644 .idea/scopes/theseer_DirectoryScanner.xml diff --git a/.idea/scopes/Autoloaders.xml b/.idea/scopes/Autoloaders.xml new file mode 100644 index 0000000..e193470 --- /dev/null +++ b/.idea/scopes/Autoloaders.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Installer_Source_files.xml b/.idea/scopes/Installer_Source_files.xml new file mode 100644 index 0000000..f4cf65d --- /dev/null +++ b/.idea/scopes/Installer_Source_files.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/NCC_Source_files.xml b/.idea/scopes/NCC_Source_files.xml index 6e38ebb..a65b319 100644 --- a/.idea/scopes/NCC_Source_files.xml +++ b/.idea/scopes/NCC_Source_files.xml @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/.idea/scopes/Symfony_Filesystem.xml b/.idea/scopes/Symfony_Filesystem.xml new file mode 100644 index 0000000..00b6846 --- /dev/null +++ b/.idea/scopes/Symfony_Filesystem.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Symfony_Process.xml b/.idea/scopes/Symfony_Process.xml new file mode 100644 index 0000000..7d46ad8 --- /dev/null +++ b/.idea/scopes/Symfony_Process.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Symfony_Uid.xml b/.idea/scopes/Symfony_Uid.xml new file mode 100644 index 0000000..0b4c6e4 --- /dev/null +++ b/.idea/scopes/Symfony_Uid.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Symfony_Yaml.xml b/.idea/scopes/Symfony_Yaml.xml new file mode 100644 index 0000000..d2796d6 --- /dev/null +++ b/.idea/scopes/Symfony_Yaml.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Symfony_polyfill_ctype.xml b/.idea/scopes/Symfony_polyfill_ctype.xml new file mode 100644 index 0000000..93bc242 --- /dev/null +++ b/.idea/scopes/Symfony_polyfill_ctype.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Symfony_polyfill_mbstring.xml b/.idea/scopes/Symfony_polyfill_mbstring.xml new file mode 100644 index 0000000..9125e7b --- /dev/null +++ b/.idea/scopes/Symfony_polyfill_mbstring.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/Symfony_polyfill_uuid.xml b/.idea/scopes/Symfony_polyfill_uuid.xml new file mode 100644 index 0000000..fc04e03 --- /dev/null +++ b/.idea/scopes/Symfony_polyfill_uuid.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/defuse.xml b/.idea/scopes/defuse.xml new file mode 100644 index 0000000..3c1064b --- /dev/null +++ b/.idea/scopes/defuse.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/defuse_php_encryption.xml b/.idea/scopes/defuse_php_encryption.xml new file mode 100644 index 0000000..bff7e6a --- /dev/null +++ b/.idea/scopes/defuse_php_encryption.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/jelix.xml b/.idea/scopes/jelix.xml new file mode 100644 index 0000000..6e134aa --- /dev/null +++ b/.idea/scopes/jelix.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/jelix_version.xml b/.idea/scopes/jelix_version.xml new file mode 100644 index 0000000..89f8c5e --- /dev/null +++ b/.idea/scopes/jelix_version.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/nikic.xml b/.idea/scopes/nikic.xml new file mode 100644 index 0000000..471928a --- /dev/null +++ b/.idea/scopes/nikic.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/nikic_PhpParser.xml b/.idea/scopes/nikic_PhpParser.xml new file mode 100644 index 0000000..22f7509 --- /dev/null +++ b/.idea/scopes/nikic_PhpParser.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/theseer.xml b/.idea/scopes/theseer.xml new file mode 100644 index 0000000..c46f520 --- /dev/null +++ b/.idea/scopes/theseer.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/theseer_Autoload.xml b/.idea/scopes/theseer_Autoload.xml new file mode 100644 index 0000000..f64a6e8 --- /dev/null +++ b/.idea/scopes/theseer_Autoload.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/scopes/theseer_DirectoryScanner.xml b/.idea/scopes/theseer_DirectoryScanner.xml new file mode 100644 index 0000000..72d0ec3 --- /dev/null +++ b/.idea/scopes/theseer_DirectoryScanner.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file -- 2.45.3 From b5cc0d4b7002110b6427e961be0e02bcaafa11c3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 13:36:05 -0500 Subject: [PATCH 198/212] Updated \ncc\CLI > HelpMenu --- src/ncc/CLI/HelpMenu.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index 6fa874e..c7e7eb0 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -39,7 +39,6 @@ self::displayMainOptions(); self::displayManagementCommands(); self::displayMainCommands(); - self::displayExtensions(); } /** @@ -53,7 +52,6 @@ Console::outHelpSections([ new CliHelpSection(['{command} --help'], 'Displays help information about a specific command'), new CliHelpSection(['-v', '--version'], 'Display NCC version information'), - new CliHelpSection(['-D', '--debug'], 'Enables debug mode'), new CliHelpSection(['-l', '--log-level={debug|info|warn|error|fatal}'], 'Set the logging level', 'info'), new CliHelpSection(['--basic-ascii'], 'Uses basic ascii characters'), new CliHelpSection(['--no-color'], 'Omits the use of colors'), @@ -72,7 +70,6 @@ Console::outHelpSections([ new CliHelpSection(['project'], 'Manages the current project'), new CliHelpSection(['package'], 'Manages the package system'), - new CliHelpSection(['cache'], 'Manages the system cache'), new CliHelpSection(['cred'], 'Manages credentials'), new CliHelpSection(['config'], 'Changes NCC configuration values'), new CliHelpSection(['source'], 'Manages remote sources'), @@ -92,17 +89,4 @@ new CliHelpSection(['main'], 'Executes the main entrypoint of a package') ]); } - - /** - * Displays the main commands section - * - * @return void - */ - private static function displayExtensions(): void - { - Console::out('Extensions:'); - Console::outHelpSections([ - new CliHelpSection(['exphp'], 'The PHP compiler extension') - ]); - } } \ No newline at end of file -- 2.45.3 From 625a4184d8547e6fce9451bd8b991e8328e67691 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 13:38:02 -0500 Subject: [PATCH 199/212] Updated \ncc\CLI > Main --- src/ncc/CLI/Main.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/ncc/CLI/Main.php b/src/ncc/CLI/Main.php index 7b0a308..7c7f5a4 100644 --- a/src/ncc/CLI/Main.php +++ b/src/ncc/CLI/Main.php @@ -138,6 +138,10 @@ SourcesMenu::start(self::$args); break; + case 'version': + Console::out(sprintf('NCC version %s (%s)', NCC_VERSION_NUMBER, NCC_VERSION_BRANCH)); + break; + case '1': case 'help': HelpMenu::start(self::$args); @@ -189,8 +193,15 @@ */ public static function shutdown(): void { - RuntimeCache::clearCache(); - Functions::finalizePermissions(); + try + { + RuntimeCache::clearCache(); + Functions::finalizePermissions(); + } + catch (Exception $e) + { + Console::outWarning('An error occurred while shutting down NCC, ' . $e->getMessage()); + } } } \ No newline at end of file -- 2.45.3 From 813860fef65f85da32c4edad484f243210d4f8f3 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 14:41:05 -0500 Subject: [PATCH 200/212] Added copyright --- src/ncc/Abstracts/AuthenticationType.php | 22 ++++++- .../CompilerExtensionDefaultVersions.php | 22 ++++++- .../CompilerExtensionSupportedVersions.php | 22 ++++++- src/ncc/Abstracts/CompilerExtensions.php | 22 ++++++- src/ncc/Abstracts/ComponentDataType.php | 22 ++++++- src/ncc/Abstracts/ComponentFileExtensions.php | 22 ++++++- src/ncc/Abstracts/ComposerPackageTypes.php | 22 ++++++- src/ncc/Abstracts/ComposerStabilityTypes.php | 22 ++++++- src/ncc/Abstracts/ConsoleColors.php | 22 ++++++- src/ncc/Abstracts/ConstantReferences.php | 22 ++++++- src/ncc/Abstracts/DefinedRemoteSourceType.php | 22 ++++++- src/ncc/Abstracts/DependencySourceType.php | 22 ++++++- src/ncc/Abstracts/EncoderType.php | 22 ++++++- src/ncc/Abstracts/ExceptionCodes.php | 22 ++++++- src/ncc/Abstracts/HttpRequestType.php | 22 ++++++- src/ncc/Abstracts/HttpStatusCodes.php | 22 ++++++- src/ncc/Abstracts/LogLevel.php | 22 ++++++- src/ncc/Abstracts/NccBuildFlags.php | 22 ++++++- .../Options/BuildConfigurationValues.php | 22 ++++++- .../Options/InitializeProjectOptions.php | 22 ++++++- .../Options/InstallPackageOptions.php | 22 ++++++- .../Options/RuntimeImportOptions.php | 22 ++++++- src/ncc/Abstracts/PackageStandardVersions.php | 22 ++++++- .../Abstracts/PackageStructureVersions.php | 22 ++++++- src/ncc/Abstracts/ProjectType.php | 22 ++++++- src/ncc/Abstracts/RegexPatterns.php | 22 ++++++- src/ncc/Abstracts/RemoteSourceType.php | 22 ++++++- src/ncc/Abstracts/Runners.php | 22 ++++++- src/ncc/Abstracts/Scopes.php | 22 ++++++- .../SpecialConstants/AssemblyConstants.php | 22 ++++++- .../SpecialConstants/BuildConstants.php | 22 ++++++- .../SpecialConstants/DateTimeConstants.php | 22 ++++++- .../SpecialConstants/InstallConstants.php | 22 ++++++- .../SpecialConstants/RuntimeConstants.php | 22 ++++++- src/ncc/Abstracts/Versions.php | 22 ++++++- src/ncc/CLI/Commands/BuildCommand.php | 22 ++++++- src/ncc/CLI/Commands/ExecCommand.php | 22 ++++++- src/ncc/CLI/HelpMenu.php | 22 ++++++- src/ncc/CLI/Main.php | 20 +++++++ src/ncc/CLI/Management/ConfigMenu.php | 22 ++++++- src/ncc/CLI/Management/CredentialMenu.php | 22 ++++++- src/ncc/CLI/Management/PackageManagerMenu.php | 22 ++++++- src/ncc/CLI/Management/ProjectMenu.php | 22 ++++++- src/ncc/CLI/Management/SourcesMenu.php | 22 ++++++- src/ncc/Classes/BashExtension/BashRunner.php | 22 ++++++- .../ComposerSourceBuiltin.php | 22 ++++++- src/ncc/Classes/EnvironmentConfiguration.php | 22 ++++++- src/ncc/Classes/GitClient.php | 22 ++++++- .../Classes/GithubExtension/GithubService.php | 22 ++++++- .../Classes/GitlabExtension/GitlabService.php | 22 ++++++- src/ncc/Classes/HttpClient.php | 22 ++++++- src/ncc/Classes/LuaExtension/LuaRunner.php | 22 ++++++- .../Classes/NccExtension/ConstantCompiler.php | 22 ++++++- .../Classes/NccExtension/PackageCompiler.php | 22 ++++++- src/ncc/Classes/NccExtension/Runner.php | 22 ++++++- src/ncc/Classes/PerlExtension/PerlRunner.php | 22 ++++++- src/ncc/Classes/PhpExtension/PhpCompiler.php | 20 +++++++ src/ncc/Classes/PhpExtension/PhpInstaller.php | 20 +++++++ src/ncc/Classes/PhpExtension/PhpRunner.php | 22 ++++++- src/ncc/Classes/PhpExtension/PhpRuntime.php | 22 ++++++- .../Classes/PythonExtension/Python2Runner.php | 22 ++++++- .../Classes/PythonExtension/Python3Runner.php | 22 ++++++- .../Classes/PythonExtension/PythonRunner.php | 22 ++++++- src/ncc/Exceptions/AccessDeniedException.php | 22 ++++++- src/ncc/Exceptions/ArchiveException.php | 22 ++++++- .../Exceptions/AuthenticationException.php | 22 ++++++- .../Exceptions/AutoloadGeneratorException.php | 22 ++++++- .../BuildConfigurationNotFoundException.php | 20 +++++++ src/ncc/Exceptions/BuildException.php | 20 +++++++ .../Exceptions/ComponentChecksumException.php | 20 +++++++ .../Exceptions/ComponentDecodeException.php | 20 +++++++ .../ComponentVersionNotFoundException.php | 22 ++++++- .../Exceptions/ComposerDisabledException.php | 20 +++++++ src/ncc/Exceptions/ComposerException.php | 20 +++++++ .../ComposerNotAvailableException.php | 20 +++++++ .../Exceptions/ConstantReadonlyException.php | 22 ++++++- .../Exceptions/DirectoryNotFoundException.php | 22 ++++++- src/ncc/Exceptions/FileNotFoundException.php | 22 ++++++- src/ncc/Exceptions/GitCheckoutException.php | 22 ++++++- src/ncc/Exceptions/GitCloneException.php | 22 ++++++- src/ncc/Exceptions/GitTagsException.php | 22 ++++++- src/ncc/Exceptions/GithubServiceException.php | 22 ++++++- src/ncc/Exceptions/GitlabServiceException.php | 22 ++++++- src/ncc/Exceptions/HttpException.php | 22 ++++++- src/ncc/Exceptions/IOException.php | 20 +++++++ src/ncc/Exceptions/ImportException.php | 22 ++++++- src/ncc/Exceptions/InstallationException.php | 20 +++++++ .../InternalComposerNotAvailableException.php | 20 +++++++ .../InvalidBuildConfigurationException.php | 22 ++++++- .../InvalidConstantNameException.php | 20 +++++++ .../InvalidCredentialsEntryException.php | 22 ++++++- .../InvalidDependencyConfiguration.php | 22 ++++++- .../Exceptions/InvalidExecutionPolicyName.php | 22 ++++++- .../Exceptions/InvalidPackageException.php | 20 +++++++ .../InvalidPackageNameException.php | 22 ++++++- .../InvalidProjectBuildConfiguration.php | 20 +++++++ .../InvalidProjectConfigurationException.php | 22 ++++++- .../InvalidProjectNameException.php | 22 ++++++- .../InvalidPropertyValueException.php | 22 ++++++- src/ncc/Exceptions/InvalidScopeException.php | 22 ++++++- .../InvalidVersionConfigurationException.php | 20 +++++++ .../InvalidVersionNumberException.php | 22 ++++++- src/ncc/Exceptions/MalformedJsonException.php | 22 ++++++- .../Exceptions/MissingDependencyException.php | 20 +++++++ .../Exceptions/NoAvailableUnitsException.php | 20 +++++++ src/ncc/Exceptions/NoUnitsFoundException.php | 22 ++++++- .../Exceptions/NotImplementedException.php | 20 +++++++ src/ncc/Exceptions/NotSupportedException.php | 22 ++++++- .../PackageAlreadyInstalledException.php | 20 +++++++ src/ncc/Exceptions/PackageFetchException.php | 22 ++++++- src/ncc/Exceptions/PackageLockException.php | 20 +++++++ .../Exceptions/PackageNotFoundException.php | 20 +++++++ .../Exceptions/PackageParsingException.php | 20 +++++++ .../PackagePreparationFailedException.php | 20 +++++++ .../ProjectAlreadyExistsException.php | 22 ++++++- .../ProjectConfigurationNotFoundException.php | 22 ++++++- .../Exceptions/ResourceChecksumException.php | 20 +++++++ .../Exceptions/RunnerExecutionException.php | 20 +++++++ src/ncc/Exceptions/RuntimeException.php | 22 ++++++- src/ncc/Exceptions/SymlinkException.php | 22 ++++++- .../UndefinedExecutionPolicyException.php | 20 +++++++ .../UnsupportedArchiveException.php | 22 ++++++- .../UnsupportedCompilerExtensionException.php | 20 +++++++ .../UnsupportedComponentTypeException.php | 20 +++++++ .../UnsupportedExtensionVersionException.php | 22 ++++++- .../UnsupportedPackageException.php | 20 +++++++ .../UnsupportedProjectTypeException.php | 22 ++++++- .../UnsupportedRemoteSourceTypeException.php | 22 ++++++- .../UserAbortedOperationException.php | 20 +++++++ .../Exceptions/VersionNotFoundException.php | 20 +++++++ .../Extensions/ZiProto/Abstracts/Options.php | 22 ++++++- .../Extensions/ZiProto/Abstracts/Regex.php | 22 ++++++- src/ncc/Extensions/ZiProto/BufferStream.php | 23 +++++++- .../Extensions/ZiProto/DecodingOptions.php | 23 +++++++- .../Extensions/ZiProto/EncodingOptions.php | 22 ++++++- .../Exception/DecodingFailedException.php | 22 ++++++- .../Exception/EncodingFailedException.php | 22 ++++++- .../Exception/InsufficientDataException.php | 22 ++++++- .../Exception/IntegerOverflowException.php | 22 ++++++- .../Exception/InvalidOptionException.php | 22 ++++++- src/ncc/Extensions/ZiProto/Ext.php | 23 +++++++- src/ncc/Extensions/ZiProto/Packet.php | 22 ++++++- src/ncc/Extensions/ZiProto/Type/Binary.php | 22 ++++++- src/ncc/Extensions/ZiProto/Type/Map.php | 22 ++++++- .../TypeTransformer/BinaryTransformer.php | 22 ++++++- .../ZiProto/TypeTransformer/Extension.php | 22 ++++++- .../TypeTransformer/MapTransformer.php | 23 +++++++- .../ZiProto/TypeTransformer/Validator.php | 23 +++++++- src/ncc/Extensions/ZiProto/ZiProto.php | 22 ++++++- src/ncc/Interfaces/CompilerInterface.php | 22 ++++++- src/ncc/Interfaces/InstallerInterface.php | 22 ++++++- src/ncc/Interfaces/PasswordInterface.php | 22 ++++++- .../Interfaces/RepositorySourceInterface.php | 22 ++++++- src/ncc/Interfaces/RunnerInterface.php | 22 ++++++- src/ncc/Interfaces/RuntimeInterface.php | 22 ++++++- src/ncc/Interfaces/ServiceSourceInterface.php | 22 ++++++- src/ncc/Managers/ConfigurationManager.php | 20 +++++++ src/ncc/Managers/CredentialManager.php | 20 +++++++ src/ncc/Managers/ExecutionPointerManager.php | 20 +++++++ src/ncc/Managers/PackageLockManager.php | 20 +++++++ src/ncc/Managers/PackageManager.php | 20 +++++++ src/ncc/Managers/ProjectManager.php | 20 +++++++ src/ncc/Managers/RemoteSourcesManager.php | 20 +++++++ src/ncc/Managers/SymlinkManager.php | 20 +++++++ src/ncc/Objects/CliHelpSection.php | 20 +++++++ src/ncc/Objects/ComposerJson.php | 20 +++++++ src/ncc/Objects/ComposerJson/Author.php | 20 +++++++ src/ncc/Objects/ComposerJson/Autoloader.php | 20 +++++++ src/ncc/Objects/ComposerJson/Funding.php | 22 ++++++- .../Objects/ComposerJson/NamespacePointer.php | 22 ++++++- src/ncc/Objects/ComposerJson/PackageLink.php | 22 ++++++- src/ncc/Objects/ComposerJson/Suggestion.php | 22 ++++++- src/ncc/Objects/ComposerJson/Support.php | 22 ++++++- src/ncc/Objects/ComposerLock.php | 20 +++++++ src/ncc/Objects/Constant.php | 22 ++++++- src/ncc/Objects/DefinedRemoteSource.php | 20 +++++++ src/ncc/Objects/ExecutionPointers.php | 20 +++++++ .../ExecutionPointers/ExecutionPointer.php | 20 +++++++ src/ncc/Objects/HttpRequest.php | 20 +++++++ src/ncc/Objects/HttpResponse.php | 20 +++++++ src/ncc/Objects/HttpResponseCache.php | 20 +++++++ src/ncc/Objects/InstallationPaths.php | 20 +++++++ src/ncc/Objects/NccUpdateInformation.php | 20 +++++++ src/ncc/Objects/NccVersionInformation.php | 20 +++++++ .../NccVersionInformation/Component.php | 20 +++++++ src/ncc/Objects/Package.php | 20 +++++++ src/ncc/Objects/Package/Component.php | 20 +++++++ src/ncc/Objects/Package/ExecutionUnit.php | 20 +++++++ src/ncc/Objects/Package/Header.php | 20 +++++++ src/ncc/Objects/Package/Installer.php | 20 +++++++ src/ncc/Objects/Package/MagicBytes.php | 20 +++++++ src/ncc/Objects/Package/Resource.php | 20 +++++++ src/ncc/Objects/PackageLock.php | 20 +++++++ .../Objects/PackageLock/DependencyEntry.php | 20 +++++++ src/ncc/Objects/PackageLock/PackageEntry.php | 20 +++++++ src/ncc/Objects/PackageLock/VersionEntry.php | 20 +++++++ src/ncc/Objects/PhpConfiguration.php | 20 +++++++ src/ncc/Objects/ProjectConfiguration.php | 20 +++++++ .../Objects/ProjectConfiguration/Assembly.php | 20 +++++++ .../Objects/ProjectConfiguration/Build.php | 20 +++++++ .../Build/BuildConfiguration.php | 20 +++++++ .../Objects/ProjectConfiguration/Compiler.php | 20 +++++++ .../ProjectConfiguration/Dependency.php | 20 +++++++ .../ProjectConfiguration/ExecutionPolicy.php | 20 +++++++ .../ExecutionPolicy/Execute.php | 20 +++++++ .../ExecutionPolicy/ExitHandle.php | 20 +++++++ .../ExecutionPolicy/ExitHandlers.php | 20 +++++++ .../ProjectConfiguration/Installer.php | 20 +++++++ .../Objects/ProjectConfiguration/Project.php | 20 +++++++ .../ProjectConfiguration/UpdateSource.php | 20 +++++++ .../UpdateSource/Repository.php | 20 +++++++ src/ncc/Objects/ProjectDetectionResults.php | 59 ++++++++++++++++++- src/ncc/Objects/RemotePackageInput.php | 20 +++++++ src/ncc/Objects/RepositoryQueryResults.php | 20 +++++++ .../Objects/RepositoryQueryResults/Files.php | 20 +++++++ src/ncc/Objects/SymlinkDictionary.php | 20 +++++++ .../SymlinkDictionary/SymlinkEntry.php | 20 +++++++ src/ncc/Objects/Vault.php | 20 +++++++ src/ncc/Objects/Vault/Entry.php | 20 +++++++ .../Objects/Vault/Password/AccessToken.php | 20 +++++++ .../Vault/Password/UsernamePassword.php | 20 +++++++ src/ncc/Runtime.php | 20 +++++++ src/ncc/Runtime/Constants.php | 20 +++++++ src/ncc/Utilities/Base64.php | 22 ++++++- src/ncc/Utilities/Console.php | 20 +++++++ src/ncc/Utilities/Functions.php | 22 ++++++- src/ncc/Utilities/IO.php | 22 ++++++- src/ncc/Utilities/PathFinder.php | 22 ++++++- src/ncc/Utilities/Resolver.php | 20 +++++++ src/ncc/Utilities/RuntimeCache.php | 20 +++++++ src/ncc/Utilities/Security.php | 22 ++++++- src/ncc/Utilities/Validate.php | 22 ++++++- src/ncc/ncc | 22 ++++++- src/ncc/ncc.php | 22 ++++++- 234 files changed, 4860 insertions(+), 138 deletions(-) diff --git a/src/ncc/Abstracts/AuthenticationType.php b/src/ncc/Abstracts/AuthenticationType.php index 044a977..5981b9d 100644 --- a/src/ncc/Abstracts/AuthenticationType.php +++ b/src/ncc/Abstracts/AuthenticationType.php @@ -1,6 +1,26 @@ Date: Sun, 29 Jan 2023 14:46:27 -0500 Subject: [PATCH 201/212] Updated \ncc\CLI\Management > CredentialMenu to use '--no-encryption' argument instead of '--encrypt' --- src/ncc/CLI/Management/CredentialMenu.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/ncc/CLI/Management/CredentialMenu.php b/src/ncc/CLI/Management/CredentialMenu.php index 95a8c81..35e88f1 100644 --- a/src/ncc/CLI/Management/CredentialMenu.php +++ b/src/ncc/CLI/Management/CredentialMenu.php @@ -40,6 +40,7 @@ namespace ncc\CLI\Management; * * @param $args * @return void + * @noinspection DuplicatedCode */ public static function start($args): void { @@ -209,7 +210,7 @@ namespace ncc\CLI\Management; $username = $args['username'] ?? $args['usr'] ?? null; $password = $args['password'] ?? $args['pwd'] ?? null; $token = $args['token'] ?? $args['pat'] ?? $args['private-token'] ?? null; - $encrypt = $args['encrypt'] ?? $args['encrypted'] ?? null; + $encrypt = !isset($args['no-encryption']); if($name === null) $name = Console::getInput('Enter a name for the entry: '); @@ -235,9 +236,6 @@ namespace ncc\CLI\Management; Console::outError('Invalid authentication type'); } - if($encrypt === null) - $encrypt = Console::getBooleanInput('Encrypt entry with your password?'); - if($name === null) { Console::outError('You must specify a name for the entry (alias, name)', true, 1); @@ -373,7 +371,7 @@ namespace ncc\CLI\Management; Console::outHelpSections([ new CliHelpSection(['--name'], 'The name of the entry'), new CliHelpSection(['--auth-type', '--auth'], 'The type of authentication (login, pat)'), - new CliHelpSection(['--encrypted', '--encrypt'], 'Whether or not to encrypt the entry', true), + new CliHelpSection(['--no-encryption'], 'Omit encryption to the entry (By default it\'s encrypted)', true), ]); Console::out(' login authentication type options:'); @@ -392,8 +390,8 @@ namespace ncc\CLI\Management; Console::out(' pat' . PHP_EOL); Console::out('Examples:'); - Console::out(' ncc cred add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" --encrypt'); - Console::out(' ncc cred add --alias "My Alias" --auth-type pat --token "mytoken"'); + Console::out(' ncc cred add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword"'); + Console::out(' ncc cred add --alias "My Alias" --auth-type pat --token "mytoken" --no-encryption'); Console::out(' ncc cred remove --alias "My Alias"'); } } \ No newline at end of file -- 2.45.3 From ba580994f5f66d59ba9de67359a7e5932c868ebd Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 14:58:58 -0500 Subject: [PATCH 202/212] Updated HelpMenu --- src/ncc/CLI/HelpMenu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index 2b3780d..c0b5b01 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -72,7 +72,7 @@ namespace ncc\CLI; Console::outHelpSections([ new CliHelpSection(['{command} --help'], 'Displays help information about a specific command'), new CliHelpSection(['-v', '--version'], 'Display NCC version information'), - new CliHelpSection(['-l', '--log-level={debug|info|warn|error|fatal}'], 'Set the logging level', 'info'), + new CliHelpSection(['-l', '--log-level={silent|debug|verbose|info|warn|error|fatal}'], 'Set the logging level', 'info'), new CliHelpSection(['--basic-ascii'], 'Uses basic ascii characters'), new CliHelpSection(['--no-color'], 'Omits the use of colors'), new CliHelpSection(['--no-banner'], 'Omits displaying the NCC ascii banner') -- 2.45.3 From ccfacbf2967047cf8263a72ea165f36293808ecf Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 14:59:48 -0500 Subject: [PATCH 203/212] Updated DOCUMENTATION.md --- DOCUMENTATION.md | 72 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 84041b0..ddb2b6c 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -19,6 +19,10 @@ NCC, from basic installation, basic usage, standards and much more. * [Installing NCC](#installing-ncc) * [Command line arguments](#command-line-arguments) * [Uninstalling NCC](#uninstalling-ncc) +* [NCC Command-line Interface](#ncc-command-line-interface) + * [Management Commands](#management-commands) + * [Utility Commands](#utility-commands) + * [Options](#options) * [Projects](#projects) * [Creating a project](#creating-a-project) * [project.json structure](#projectjson-structure) @@ -204,6 +208,52 @@ that were installed using ncc and remove any artifacts that were created by thes ------------------------------------------------------------------------------------ +# NCC Command-line Interface + +NCC provides a command-line interface that can be used to manage packages, create projects, compile source code, manage +remote sources, configure ncc, and more. You can run `ncc --help` to see a list of all the available commands. + +![ncc cli](assets/ncc_cli.png) + +## Management Commands + +Management commands are used to manage ncc's configuration, remote sources, and packages. + + +`project` Manage or create a project (*see [Projects](#projects) section*) + +`package` Manage packages + +`source` Manage remote sources + +`config` Manage ncc's configuration + +## Utility Commands + +Utility commands are used to perform tasks in the current directory or project. + +`build` Compile source code of the project + +`exec` Executes a package's entry point file (package must be installed) + +## Options + +NCC also accepts a few command line arguments that can be used to alter the behavior of the command-line interface. + +`-l , --log-level ` Sets the log level, this can be one of `debug`, `verbose`, `info`, `warn`, `error`, `fatal` + +`-v, --version` Displays the version of ncc + +`-h, --help` Displays the help message + +`--basic-ascii` Renders some messages using basic ASCII characters instead of unicode characters + +`--no-color` Disables colored output + +`--no-banner` Omits displaying the NCC graphical banner + +------------------------------------------------------------------------------------ + # Projects A project is a directory that contains all the source files to your program, it's similar to a workspace in other IDEs. @@ -298,17 +348,17 @@ It would be useful to read more about [Remote Sources](#remote-sources) before c The `assembly` field contains metadata about the program, such as the name, version, description, so on. -| Name | Type | Required | Description | -|-------------|----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| name | `string` | Yes | The name of the package, this is used to display the name of the package (eg; `Example Program`) | -| package | `string` | Yes | The package name of the program, this is used to identify the package and to avoid conflicts with other packages that may have the same name, see [Package names](#package-names) for additional information | -| description | `string` | No | The description of the package, this is used to display a description of the package when installing | -| company | `string` | No | The company that created the package, this is used to display the company that created the package when installing | -| product | `string` | No | The product that the package is a part of, this is used to display the product that the package is a part of when installing | -| copyright | `string` | No | The copyright of the package | -| trademark | `string` | No | The trademark of the package | -| version | `string` | Yes | The version of the package, see [Versioning](#versioning) for additional information | -| uuid | `string` | No | The UUID of the package, see [UUIDs](#uuids) for additional information | +| Name | Type | Required | Description | +|-------------|----------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| name | `string` | Yes | The name of the package, this is used to display the name of the package (eg; `Example Program`) | +| package | `string` | Yes | The package name of the program, this is used to identify the package and to avoid conflicts with other packages that may have the same name, see [Naming a package](#naming-a-package) for additional information | +| description | `string` | No | The description of the package, this is used to display a description of the package when installing | +| company | `string` | No | The company that created the package, this is used to display the company that created the package when installing | +| product | `string` | No | The product that the package is a part of, this is used to display the product that the package is a part of when installing | +| copyright | `string` | No | The copyright of the package | +| trademark | `string` | No | The trademark of the package | +| version | `string` | Yes | The version of the package, see [Versioning](#versioning) for additional information | +| uuid | `string` | No | The UUID of the package, see [UUIDs](#uuids) for additional information | ------------------------------------------------------------------------------------ -- 2.45.3 From 29e2ba1594c5c284daaba28342ffc96456ef7b4d Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 15:00:08 -0500 Subject: [PATCH 204/212] Updated DOCUMENTATION.md --- DOCUMENTATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index ddb2b6c..f08b78b 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -358,7 +358,7 @@ The `assembly` field contains metadata about the program, such as the name, vers | copyright | `string` | No | The copyright of the package | | trademark | `string` | No | The trademark of the package | | version | `string` | Yes | The version of the package, see [Versioning](#versioning) for additional information | -| uuid | `string` | No | The UUID of the package, see [UUIDs](#uuids) for additional information | +| uuid | `string` | Yes | The UUID of the package, see [UUIDs](#uuids) for additional information | ------------------------------------------------------------------------------------ -- 2.45.3 From 4484200bb725be0ad3db68417fa788aa65fa3fab Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 15:27:43 -0500 Subject: [PATCH 205/212] Added documentation regarding ExecutionPolicies & Runners --- DOCUMENTATION.md | 112 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index f08b78b..fe90396 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -31,6 +31,14 @@ NCC, from basic installation, basic usage, standards and much more. * [project.update_source](#projectupdatesource) * [project.update_source.repository](#projectupdatesourcerepository) * [assembly](#assembly) + * [execution_policies](#executionpolicies) + * [execution_policy](#executionpolicy) + * [execution_policy.execute](#executionpolicyexecute) + * [execution_policy.exit_handlers](#executionpolicyexithandlers) + * [exit_handler](#exithandler) +* [Execution Policies](#execution-policies) + * [Supported Runners](#supported-runners) + * [Configuring Runners](#configuring-runners) * [Remote Sources](#remote-sources) * [Supported sources](#supported-sources) * [Default sources](#default-sources) @@ -360,6 +368,110 @@ The `assembly` field contains metadata about the program, such as the name, vers | version | `string` | Yes | The version of the package, see [Versioning](#versioning) for additional information | | uuid | `string` | Yes | The UUID of the package, see [UUIDs](#uuids) for additional information | +### execution_policies + +The `execution_policies` field contains information about the execution policies that the program uses, such as +the execution policy that the program uses to run additional programs during different stages of the installation +process of the package or used as the main execution policy for the program. + +Note that this field is an array of `execution_policy` objects, see [execution_policy](#executionpolicy) for additional +information. + +For more information about execution policies, see [Execution Policies](#execution-policies). + +#### execution_policy + +The `execution_policy` object contains information about the execution policy. + +| Name | Type | Required | Description | +|---------------|----------------------------------|----------|----------------------------------------------------------------------------------------------------| +| name | `string` | Yes | The name of the execution policy, this is used to identify the execution policy | +| runner | `string` | Yes | The name of the runner that the execution policy uses, see [Supported runners](#supported-runners) | +| message | `string` | No | The message to display when the execution policy is being run | +| execute | `execution_policy.execute` | Yes | The execution policy to run when the execution policy is being run | +| exit_handlers | `execution_policy.exit_handlers` | No | The exit handlers to run when the execution policy has finished running | + +#### execution_policy.execute + +The `execution_policy.execute` object contains information about how to run the execution policy when triggered. + +| Name | Type | Required | Description | +|-----------------------|------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| target | `string` | Yes | The target file to run when the execution policy is triggered, file path is relative to the location of your project.json file (eg; scripts/main.php) | +| working_directory | `string` | No | The working directory to run the process in. If not specified, the working directory will be your current working directory. | +| options | `string[]` | No | The options to pass to the process when running it. (eg; ["--foo", "bar", "-f"]) | +| environment_variables | `string[]` | No | The environment variables to pass to the process when running it. (eg; ["FOO=bar"]) | +| silent | `bool` | No | Whether to run the process silently or not. If not specified, the process will not be run silently. | +| tty | `bool` | No | Whether to run the process in a TTY or not. If not specified, the process will not be run in a TTY. | +| timeout | `int` | No | The timeout of the process in seconds. If not specified, the process will not have a timeout. | +| idle_timeout | `int` | No | The idle timeout of the process in seconds. If not specified, the process will not have an idle timeout. | + +#### execution_policy.exit_handlers + +The `execution_policy.exit_handlers` object contains information about how to run the exit handlers when the execution +policy has finished running. This is useful for running additional policies when the process has exited in a specific +way. + +The two handlers that can be executed automatically despite the exit code are `success` and `error`. Which means if the +process exits with a success exit code, the `success` handler will be run, and if the process exits with an error exit +code, the `error` handler will be run. The `warning` handler will only be run if the process exits with specified exit +code. + +| Name | Type | Required | Description | +|---------|----------------|----------|-------------------------------------------------------------------------------| +| success | `exit_handler` | No | The exit handler to run when the process has exited successfully. | +| warning | `exit_handler` | No | The exit handler to run when the process has exited with a warning exit code. | +| error | `exit_handler` | No | The exit handler to run when the process has exited with an error exit code. | + +#### exit_handler + +The `exit_handler` object contains information about how to run the exit handler when the execution policy has finished +running. + +| Name | Type | Required | Description | +|---------------|----------|----------|---------------------------------------------------------------------------------------------------------------------------------------------| +| message | `string` | No | The message to display when the exit handler is triggered | +| end_execution | `bool` | No | Whether to end the execution of the program or not if this exit handler is triggered. If not specified, the program will not end execution. | +| run | `string` | No | The name of the execution policy to run when this exit handler is triggered. | +| exit_code | `int` | No | The exit code that the process must have exited with for this exit handler to be triggered. | + +------------------------------------------------------------------------------------ + +# Execution Policies + +Execution policies are the policies that are used to run additional programs during different stages of the installation +or execution of the package. These policies are defined in your project.json `execution_policies` field with unique +names for each policy, so that these policies can be referenced by other policies or by NCC if configured to do so. + +## Supported Runners + +At the moment, NCC only supports a select few "runners" that can be used to run the policies, these runners are: + +- `php` - This runner is used to run PHP scripts, it is the default runner for NCC +- `bash` - This runner is used to run bash scripts +- `python` - This runner is used to run python scripts +- `python2` - This runner is used to run python2 scripts +- `python3` - This runner is used to run python3 scripts +- `perl` - This runner is used to run perl scripts +- `lua` - This runner is used to run lua scripts + + > Note: these runners are not installed by default, you will need to install them yourself. + +## Configuring Runners + +If for some reason NCC cannot automatically detect the runner that you want to use, you can configure the runner yourself +by modifying your configuration file. The configuration file is located at `/var/ncc/ncc.yaml` under the `runners` field. + +Or you can modify the configuration file by running the following command: + +```bash +ncc config -p runners.bash -v /usr/bin/bash +``` + +This will set the `bash` runner to use the `/usr/bin/bash` binary. + + > **Note:** You must have root permissions to modify the configuration file. + ------------------------------------------------------------------------------------ # Remote Sources -- 2.45.3 From 74b356867fc7ed1f6a1690011e851dc682bc73ba Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 15:30:49 -0500 Subject: [PATCH 206/212] Added documentation regarding installer --- DOCUMENTATION.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index fe90396..57d9dea 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -36,6 +36,7 @@ NCC, from basic installation, basic usage, standards and much more. * [execution_policy.execute](#executionpolicyexecute) * [execution_policy.exit_handlers](#executionpolicyexithandlers) * [exit_handler](#exithandler) + * [installer](#installer) * [Execution Policies](#execution-policies) * [Supported Runners](#supported-runners) * [Configuring Runners](#configuring-runners) @@ -435,6 +436,22 @@ running. | run | `string` | No | The name of the execution policy to run when this exit handler is triggered. | | exit_code | `int` | No | The exit code that the process must have exited with for this exit handler to be triggered. | +### installer + +The `installer` field contains allows you to configure the execution of policies during different stages of the +installation process of the package. Note that these files only accepts an array of strings, which are the names of +the execution policies that you want to run during the specified stage. NCC will reject the package if the execution +policy does not exist. + +| Name | Type | Required | Description | +|----------------|------------|----------|-------------------------------------------------------------------------| +| pre_install | `string[]` | No | The execution policies to run before the installation of the package. | +| post_install | `string[]` | No | The execution policies to run after the installation of the package. | +| pre_uninstall | `string[]` | No | The execution policies to run before the uninstallation of the package. | +| post_uninstall | `string[]` | No | The execution policies to run after the uninstallation of the package. | +| pre_update | `string[]` | No | The execution policies to run before the update of the package. | +| post_update | `string[]` | No | The execution policies to run after the update of the package. | + ------------------------------------------------------------------------------------ # Execution Policies -- 2.45.3 From 6c5168cdd67ecd61549cddc3bbd6b7c85749615a Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 15:31:47 -0500 Subject: [PATCH 207/212] Added missing files --- .idea/copyright/Nosial.xml | 6 ++++++ .idea/copyright/profiles_settings.xml | 7 +++++++ assets/ncc_cli.png | Bin 0 -> 92689 bytes 3 files changed, 13 insertions(+) create mode 100644 .idea/copyright/Nosial.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 assets/ncc_cli.png diff --git a/.idea/copyright/Nosial.xml b/.idea/copyright/Nosial.xml new file mode 100644 index 0000000..ea25c5d --- /dev/null +++ b/.idea/copyright/Nosial.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..85fcaf5 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/assets/ncc_cli.png b/assets/ncc_cli.png new file mode 100644 index 0000000000000000000000000000000000000000..64fb3c4ae7ce144ad7b86965e16319180e73732d GIT binary patch literal 92689 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 az5f5>$-Gt5RAYJ=fWXt$&t;ucLK6V4YqMzp literal 0 HcmV?d00001 -- 2.45.3 From 15b723401b781864a98ed30e39809e6228b85d9e Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 16:28:51 -0500 Subject: [PATCH 208/212] Updated DOCUMENTATION.md --- DOCUMENTATION.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md index 57d9dea..31793f0 100644 --- a/DOCUMENTATION.md +++ b/DOCUMENTATION.md @@ -37,6 +37,9 @@ NCC, from basic installation, basic usage, standards and much more. * [execution_policy.exit_handlers](#executionpolicyexithandlers) * [exit_handler](#exithandler) * [installer](#installer) + * [build](#build) + * [dependency](#dependency) + * [Source Types](#source-types) * [Execution Policies](#execution-policies) * [Supported Runners](#supported-runners) * [Configuring Runners](#configuring-runners) @@ -452,6 +455,50 @@ policy does not exist. | pre_update | `string[]` | No | The execution policies to run before the update of the package. | | post_update | `string[]` | No | The execution policies to run after the update of the package. | + +### build + +The `build` field contains the configuration for the build process of the package. This field is required and must be +configured correctly for the package to be built successfully. + +| Name | Type | Required | Description | +|-----------------------|-------------------------|----------|----------------------------------------------------------------------------------------------------------------------------| +| source_path | `string` | Yes | The path to the source directory of the package. (eg; src) | +| default_configuration | `string` | Yes | The default build configuration to use when building the package. | +| exclude_files | `string[]` | No | The files to exclude from the build process. | +| options | `string[]` | No | The options to pass to the build process. | +| main | `string` | No | The main execution policy to run when the package is executed, this is like the main entry point of the package. | +| define_constants | `string[]` | No | Environment constants to define during the execution of your program, these values can be accessed by the NCC Runtime API. | +| pre_build | `string[]` | No | The execution policies to run before the build process. | +| post_build | `string[]` | No | The execution policies to run after the build process. | +| dependencies | `dependency[]` | No | The dependencies that the package requires | +| configurations | `build_configuration[]` | No | Predefined build configurations that can be used to produce different builds of the package | + +### dependency + +The `dependency` object contains information about a dependency that the package requires. + +| Name | Type | Required | Description | +|-------------|----------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| name | `string` | Yes | The package name of the dependency (eg; com.example.package) | +| source_type | `string` | No | Where NCC should get the dependency from, accepted values are `static`, `local` or `remote`. If not specified, NCC will assume `remote`. | +| source | `string` | No | The source of the dependency, this can a remote source (see [Remote Sources](#remote-sources)) if the source is `remote` or a a local file path if the source is `static` | +| version | `string` | No | The version of the dependency to use, if not specified, NCC will use the latest version of the dependency. (eg; 'latest') | + +#### Source Types + +Dependency source types are used to specify where NCC should get the dependency from, these are: + +- `static` - This source type is used to specify that the dependency is a local file path, this is useful for dependencies +that are not available on the remote package repository or to bundle dependencies with the package. You can only link to +pre-compiled .ncc packages, otherwise NCC will fail to install the package. +- `local` - This source type is used to specify that the dependency is a local package that is already installed on the +system. This is useful for dependencies that are already installed on the system, and you want to use them in your package +but doesn't necessarily need to pull them from a remote repository or local path. NCC expects the package to be installed +otherwise installing the package will fail unless `--skip-dependencies` is specified. +- `remote` - This source type is used to specify that the dependency is a remote package that is available on the remote +repository. This is the recommended source type to use for dependencies that are available on the remote repository. + ------------------------------------------------------------------------------------ # Execution Policies -- 2.45.3 From 209d15acbea21821966b700c937478db072d1d47 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 16:59:25 -0500 Subject: [PATCH 209/212] Updated HelpMenu --- src/ncc/CLI/HelpMenu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ncc/CLI/HelpMenu.php b/src/ncc/CLI/HelpMenu.php index c0b5b01..8381429 100644 --- a/src/ncc/CLI/HelpMenu.php +++ b/src/ncc/CLI/HelpMenu.php @@ -106,7 +106,7 @@ namespace ncc\CLI; Console::out('Commands:'); Console::outHelpSections([ new CliHelpSection(['build'], 'Builds the current project'), - new CliHelpSection(['main'], 'Executes the main entrypoint of a package') + new CliHelpSection(['exec'], 'Executes the main entrypoint of a package') ]); } } \ No newline at end of file -- 2.45.3 From 4e0ce1fdb876c41a77ca7d5d1942aa97b937fda5 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 17:03:23 -0500 Subject: [PATCH 210/212] Updated PackageManager --- src/ncc/Managers/PackageManager.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index 55d41a6..e0820e3 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -25,7 +25,6 @@ namespace ncc\Managers; use Exception; - use ncc\Abstracts\BuiltinRemoteSourceType; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\ConstantReferences; use ncc\Abstracts\DependencySourceType; @@ -52,8 +51,8 @@ use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\PackageParsingException; + use ncc\Exceptions\SymlinkException; use ncc\Exceptions\UnsupportedCompilerExtensionException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Exceptions\VersionNotFoundException; use ncc\Objects\DefinedRemoteSource; use ncc\Objects\InstallationPaths; @@ -121,6 +120,7 @@ * @throws UnsupportedRunnerException * @throws VersionNotFoundException * @throws InvalidPackageNameException + * @throws SymlinkException */ public function install(string $package_path, ?Entry $entry=null, array $options=[]): string { @@ -435,7 +435,7 @@ Console::outDebug('using builtin source ' . $input->Source); switch($input->Source) { - case BuiltinRemoteSourceType::Composer: + case 'composer': try { return ComposerSourceBuiltin::fetch($input); @@ -601,8 +601,8 @@ * @throws PackageLockException * @throws PackageNotFoundException * @throws PackageParsingException + * @throws SymlinkException * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException * @throws VersionNotFoundException */ private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null): void @@ -814,6 +814,7 @@ * @throws IOException * @throws PackageLockException * @throws PackageNotFoundException + * @throws SymlinkException * @throws VersionNotFoundException */ public function uninstallPackageVersion(string $package, string $version): void -- 2.45.3 From de83f53a2d52c5783c484de8ee250fc8b2315c5c Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 17:22:24 -0500 Subject: [PATCH 211/212] Code Refactoring --- src/ncc/Abstracts/BuiltinRemoteSourceType.php | 37 ++++++++ src/ncc/CLI/Main.php | 5 +- src/ncc/CLI/Management/PackageManagerMenu.php | 1 - src/ncc/CLI/Management/ProjectMenu.php | 25 ++++- src/ncc/Classes/BashExtension/BashRunner.php | 5 - .../ComposerSourceBuiltin.php | 4 - src/ncc/Classes/EnvironmentConfiguration.php | 91 ------------------- src/ncc/Classes/GitClient.php | 2 +- .../Classes/GithubExtension/GithubService.php | 3 +- src/ncc/Classes/HttpClient.php | 7 +- src/ncc/Classes/LuaExtension/LuaRunner.php | 5 - .../Classes/NccExtension/PackageCompiler.php | 5 +- src/ncc/Classes/NccExtension/Runner.php | 13 +-- src/ncc/Classes/PerlExtension/PerlRunner.php | 5 - src/ncc/Classes/PhpExtension/PhpCompiler.php | 5 +- src/ncc/Classes/PhpExtension/PhpInstaller.php | 8 +- src/ncc/Classes/PhpExtension/PhpRunner.php | 6 -- .../Classes/PythonExtension/Python2Runner.php | 5 - .../Classes/PythonExtension/Python3Runner.php | 5 - .../Classes/PythonExtension/PythonRunner.php | 5 - .../BuildConfigurationNotFoundException.php | 4 +- src/ncc/Exceptions/BuildException.php | 4 +- .../Exceptions/ComponentChecksumException.php | 4 +- .../Exceptions/ComponentDecodeException.php | 4 +- .../Exceptions/ComposerDisabledException.php | 7 +- src/ncc/Exceptions/ComposerException.php | 4 +- .../ComposerNotAvailableException.php | 5 +- src/ncc/Exceptions/GitCheckoutException.php | 3 +- src/ncc/Exceptions/IOException.php | 4 +- src/ncc/Exceptions/InstallationException.php | 4 +- .../InternalComposerNotAvailableException.php | 4 +- .../InvalidConstantNameException.php | 4 +- .../Exceptions/InvalidPackageException.php | 4 +- .../InvalidProjectBuildConfiguration.php | 4 +- .../InvalidVersionConfigurationException.php | 4 +- .../Exceptions/MissingDependencyException.php | 4 +- .../Exceptions/NoAvailableUnitsException.php | 4 +- .../Exceptions/NotImplementedException.php | 4 +- .../PackageAlreadyInstalledException.php | 4 +- src/ncc/Exceptions/PackageFetchException.php | 3 +- src/ncc/Exceptions/PackageLockException.php | 4 +- .../Exceptions/PackageNotFoundException.php | 4 +- .../Exceptions/PackageParsingException.php | 4 +- .../PackagePreparationFailedException.php | 4 +- .../Exceptions/ResourceChecksumException.php | 4 +- .../Exceptions/RunnerExecutionException.php | 4 +- .../UndefinedExecutionPolicyException.php | 4 +- .../UnsupportedCompilerExtensionException.php | 4 +- .../UnsupportedComponentTypeException.php | 4 +- .../UnsupportedPackageException.php | 4 +- .../UserAbortedOperationException.php | 4 +- .../Exceptions/VersionNotFoundException.php | 4 +- .../Extensions/ZiProto/Abstracts/Regex.php | 2 +- src/ncc/Extensions/ZiProto/BufferStream.php | 10 +- .../Extensions/ZiProto/DecodingOptions.php | 7 +- src/ncc/Extensions/ZiProto/Packet.php | 28 +++--- .../TypeTransformer/BinaryTransformer.php | 2 +- .../ZiProto/TypeTransformer/Extension.php | 2 +- src/ncc/Interfaces/CompilerInterface.php | 3 - src/ncc/Interfaces/RunnerInterface.php | 3 - src/ncc/Managers/ExecutionPointerManager.php | 16 +--- src/ncc/Managers/PackageLockManager.php | 3 +- src/ncc/Managers/PackageManager.php | 12 ++- src/ncc/Managers/ProjectManager.php | 18 ++-- src/ncc/Managers/RemoteSourcesManager.php | 1 - src/ncc/Managers/SymlinkManager.php | 22 ----- src/ncc/Objects/Constant.php | 2 +- src/ncc/Objects/Package.php | 4 +- src/ncc/Objects/Package/Header.php | 2 +- src/ncc/Objects/PackageLock/PackageEntry.php | 2 +- src/ncc/Objects/PackageLock/VersionEntry.php | 2 +- .../Objects/ProjectConfiguration/Compiler.php | 3 +- .../ProjectConfiguration/ExecutionPolicy.php | 3 +- .../Objects/ProjectConfiguration/Project.php | 2 +- src/ncc/Objects/ProjectDetectionResults.php | 2 - src/ncc/Runtime.php | 2 +- src/ncc/Utilities/Functions.php | 33 +++---- src/ncc/Utilities/Resolver.php | 1 - src/ncc/Utilities/Security.php | 7 +- src/ncc/ncc | 8 +- src/ncc/ncc.php | 8 +- 81 files changed, 186 insertions(+), 396 deletions(-) create mode 100644 src/ncc/Abstracts/BuiltinRemoteSourceType.php delete mode 100644 src/ncc/Classes/EnvironmentConfiguration.php diff --git a/src/ncc/Abstracts/BuiltinRemoteSourceType.php b/src/ncc/Abstracts/BuiltinRemoteSourceType.php new file mode 100644 index 0000000..7568d42 --- /dev/null +++ b/src/ncc/Abstracts/BuiltinRemoteSourceType.php @@ -0,0 +1,37 @@ +getVersion($version_entry, false); diff --git a/src/ncc/CLI/Management/ProjectMenu.php b/src/ncc/CLI/Management/ProjectMenu.php index 6cfe135..b7ce09e 100644 --- a/src/ncc/CLI/Management/ProjectMenu.php +++ b/src/ncc/CLI/Management/ProjectMenu.php @@ -26,13 +26,20 @@ namespace ncc\CLI\Management; use ncc\Abstracts\CompilerExtensionDefaultVersions; use ncc\Abstracts\CompilerExtensions; use ncc\Abstracts\CompilerExtensionSupportedVersions; + use ncc\Exceptions\AccessDeniedException; + use ncc\Exceptions\DirectoryNotFoundException; + use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\InvalidPackageNameException; use ncc\Exceptions\InvalidProjectNameException; + use ncc\Exceptions\IOException; + use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\ProjectAlreadyExistsException; + use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Managers\ProjectManager; use ncc\Objects\CliHelpSection; use ncc\Objects\ProjectConfiguration\Compiler; use ncc\Utilities\Console; + use ncc\Utilities\Functions; class ProjectMenu { @@ -41,6 +48,12 @@ namespace ncc\CLI\Management; * * @param $args * @return void + * @throws AccessDeniedException + * @throws DirectoryNotFoundException + * @throws FileNotFoundException + * @throws IOException + * @throws MalformedJsonException + * @throws ProjectConfigurationNotFoundException */ public static function start($args): void { @@ -50,13 +63,17 @@ namespace ncc\CLI\Management; } self::displayOptions(); - exit(0); - } /** * @param $args * @return void + * @throws AccessDeniedException + * @throws DirectoryNotFoundException + * @throws FileNotFoundException + * @throws IOException + * @throws MalformedJsonException + * @throws ProjectConfigurationNotFoundException */ public static function createProject($args): void { @@ -93,7 +110,7 @@ namespace ncc\CLI\Management; } // Remove basename from real_src - $real_src = \ncc\Utilities\Functions::removeBasename($real_src, $current_directory); + $real_src = Functions::removeBasename($real_src, $current_directory); // Fetch the rest of the information needed for the project //$compiler_extension = Console::getOptionInput($args, 'ce', 'Compiler Extension (php, java): '); @@ -242,7 +259,7 @@ namespace ncc\CLI\Management; new CliHelpSection(['create-makefile'], 'Generates a Makefile for the project'), ]; - $options_padding = \ncc\Utilities\Functions::detectParametersPadding($options) + 4; + $options_padding = Functions::detectParametersPadding($options) + 4; Console::out('Usage: ncc project {command} [options]'); Console::out('Options:' . PHP_EOL); diff --git a/src/ncc/Classes/BashExtension/BashRunner.php b/src/ncc/Classes/BashExtension/BashRunner.php index ff6ae82..c10b993 100644 --- a/src/ncc/Classes/BashExtension/BashRunner.php +++ b/src/ncc/Classes/BashExtension/BashRunner.php @@ -22,16 +22,11 @@ namespace ncc\Classes\BashExtension; - use ncc\Abstracts\Runners; use ncc\Exceptions\FileNotFoundException; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class BashRunner implements RunnerInterface { diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index f5593a7..a70bb18 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -48,7 +48,6 @@ namespace ncc\Classes\ComposerExtension; use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\RuntimeException; use ncc\Exceptions\UnsupportedCompilerExtensionException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Exceptions\UserAbortedOperationException; use ncc\Interfaces\ServiceSourceInterface; use ncc\Managers\ProjectManager; @@ -99,7 +98,6 @@ namespace ncc\Classes\ComposerExtension; * @throws ProjectConfigurationNotFoundException * @throws RuntimeException * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException * @throws UserAbortedOperationException */ public static function fetch(RemotePackageInput $packageInput): string @@ -138,7 +136,6 @@ namespace ncc\Classes\ComposerExtension; * @throws PackagePreparationFailedException * @throws ProjectConfigurationNotFoundException * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException * @throws UserAbortedOperationException */ public static function fromLocal(string $path): string @@ -196,7 +193,6 @@ namespace ncc\Classes\ComposerExtension; * @throws PackagePreparationFailedException * @throws ProjectConfigurationNotFoundException * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException */ private static function compilePackages(string $composer_lock_path): array { diff --git a/src/ncc/Classes/EnvironmentConfiguration.php b/src/ncc/Classes/EnvironmentConfiguration.php deleted file mode 100644 index ae169e5..0000000 --- a/src/ncc/Classes/EnvironmentConfiguration.php +++ /dev/null @@ -1,91 +0,0 @@ - $config) - { - $results[$name] = PhpConfiguration::fromArray($config); - } - - return $results; - } - - /** - * Returns an array of only the changed configuration values - * - * @return PhpConfiguration[] - */ - public static function getChangedValues(): array - { - $results = []; - - foreach(ini_get_all() as $name => $config) - { - $config = PhpConfiguration::fromArray($config); - if($config->LocalValue !== $config->GlobalValue) - { - $results[$name] = $config; - } - } - - return $results; - } - - /** - * @param string $file_path - * @return void - */ - public static function export(string $file_path) - { - $configuration = []; - foreach(self::getChangedValues() as $changedValue) - { - $configuration[$changedValue->getName()] = $changedValue->getValue(); - } - - // TODO: Implement ini writing process here - } - - public static function import(string $file_path) - { - // TODO: Implement ini reading process here - $configuration = []; - foreach($configuration as $item => $value) - { - ini_set($item, $value); - } - } - } \ No newline at end of file diff --git a/src/ncc/Classes/GitClient.php b/src/ncc/Classes/GitClient.php index 053b17e..6245ed7 100644 --- a/src/ncc/Classes/GitClient.php +++ b/src/ncc/Classes/GitClient.php @@ -66,7 +66,7 @@ namespace ncc\Classes; * @param string $branch * @throws GitCheckoutException */ - public static function checkout(string $path, string $branch) + public static function checkout(string $path, string $branch): void { Console::outVerbose('Checking out branch' . $branch); $process = new Process(["git", "checkout", $branch], $path); diff --git a/src/ncc/Classes/GithubExtension/GithubService.php b/src/ncc/Classes/GithubExtension/GithubService.php index 0331d75..4b8bcc2 100644 --- a/src/ncc/Classes/GithubExtension/GithubService.php +++ b/src/ncc/Classes/GithubExtension/GithubService.php @@ -204,8 +204,7 @@ namespace ncc\Classes\GithubExtension; if ($response->StatusCode != 200) throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode)); - $response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY); - return $response_decoded; + return Functions::loadJson($response->Body, Functions::FORCE_ARRAY); } /** diff --git a/src/ncc/Classes/HttpClient.php b/src/ncc/Classes/HttpClient.php index 192ce75..11b47e9 100644 --- a/src/ncc/Classes/HttpClient.php +++ b/src/ncc/Classes/HttpClient.php @@ -191,14 +191,11 @@ namespace ncc\Classes; /** * Displays the download progress in the console * - * @param $resource * @param $downloadSize * @param $downloaded - * @param $uploadSize - * @param $uploaded * @return void */ - public static function displayProgress($resource, $downloadSize, $downloaded, $uploadSize, $uploaded): void + public static function displayProgress($downloadSize, $downloaded): void { if(Main::getLogLevel() !== null) { @@ -223,7 +220,7 @@ namespace ncc\Classes; /** * Takes the return headers of a cURL request and parses them into an array. * - * @param string $headers + * @param string $input * @return array */ private static function parseHeaders(string $input): array diff --git a/src/ncc/Classes/LuaExtension/LuaRunner.php b/src/ncc/Classes/LuaExtension/LuaRunner.php index 78dcc32..599c5b2 100644 --- a/src/ncc/Classes/LuaExtension/LuaRunner.php +++ b/src/ncc/Classes/LuaExtension/LuaRunner.php @@ -22,15 +22,10 @@ namespace ncc\Classes\LuaExtension; - use ncc\Abstracts\Runners; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class LuaRunner implements RunnerInterface { diff --git a/src/ncc/Classes/NccExtension/PackageCompiler.php b/src/ncc/Classes/NccExtension/PackageCompiler.php index 480f9eb..8233e31 100644 --- a/src/ncc/Classes/NccExtension/PackageCompiler.php +++ b/src/ncc/Classes/NccExtension/PackageCompiler.php @@ -39,9 +39,9 @@ namespace ncc\Classes\NccExtension; use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\PackagePreparationFailedException; use ncc\Exceptions\ProjectConfigurationNotFoundException; + use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\UnsupportedProjectTypeException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Interfaces\CompilerInterface; use ncc\Managers\ProjectManager; use ncc\ncc; @@ -70,7 +70,6 @@ namespace ncc\Classes\NccExtension; * @throws PackagePreparationFailedException * @throws ProjectConfigurationNotFoundException * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException */ public static function compile(ProjectManager $manager, string $build_configuration=BuildConfigurationValues::DefaultConfiguration): string { @@ -162,7 +161,7 @@ namespace ncc\Classes\NccExtension; * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException - * @throws UnsupportedRunnerException + * @throws RunnerExecutionException */ public static function compileExecutionPolicies(string $path, ProjectConfiguration $configuration): array { diff --git a/src/ncc/Classes/NccExtension/Runner.php b/src/ncc/Classes/NccExtension/Runner.php index 9637eb9..5a71e81 100644 --- a/src/ncc/Classes/NccExtension/Runner.php +++ b/src/ncc/Classes/NccExtension/Runner.php @@ -22,19 +22,14 @@ namespace ncc\Classes\NccExtension; - use ncc\Abstracts\Runners; use ncc\Abstracts\Scopes; use ncc\Exceptions\AccessDeniedException; - use ncc\Exceptions\ExecutionUnitNotFoundException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; use ncc\Exceptions\NoAvailableUnitsException; use ncc\Exceptions\RunnerExecutionException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Managers\ExecutionPointerManager; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; - use ncc\Utilities\PathFinder; use ncc\Utilities\Resolver; class Runner @@ -47,21 +42,19 @@ namespace ncc\Classes\NccExtension; * @param ExecutionUnit $unit * @return void * @throws AccessDeniedException - * @throws UnsupportedRunnerException - * @throws ExecutionUnitNotFoundException * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException * @throws RunnerExecutionException */ - public static function temporaryExecute(string $package, string $version, ExecutionUnit $unit) + public static function temporaryExecute(string $package, string $version, ExecutionUnit $unit): void { if(Resolver::resolveScope() !== Scopes::System) - throw new AccessDeniedException('Cannot temporarily execute a unit with insufficent permissions'); + throw new AccessDeniedException('Cannot temporarily execute a unit with insufficient permissions'); $ExecutionPointerManager = new ExecutionPointerManager(); $ExecutionPointerManager->addUnit($package, $version, $unit, true); $ExecutionPointerManager->executeUnit($package, $version, $unit->ExecutionPolicy->Name); - $ExecutionPointerManager->cleanTemporaryUnits();; + $ExecutionPointerManager->cleanTemporaryUnits(); } } \ No newline at end of file diff --git a/src/ncc/Classes/PerlExtension/PerlRunner.php b/src/ncc/Classes/PerlExtension/PerlRunner.php index 5017af6..46ee10d 100644 --- a/src/ncc/Classes/PerlExtension/PerlRunner.php +++ b/src/ncc/Classes/PerlExtension/PerlRunner.php @@ -22,16 +22,11 @@ namespace ncc\Classes\PerlExtension; - use ncc\Abstracts\Runners; use ncc\Exceptions\FileNotFoundException; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class PerlRunner implements RunnerInterface { diff --git a/src/ncc/Classes/PhpExtension/PhpCompiler.php b/src/ncc/Classes/PhpExtension/PhpCompiler.php index ab9a5f6..bc5142b 100644 --- a/src/ncc/Classes/PhpExtension/PhpCompiler.php +++ b/src/ncc/Classes/PhpExtension/PhpCompiler.php @@ -39,7 +39,7 @@ use ncc\Exceptions\IOException; use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackagePreparationFailedException; - use ncc\Exceptions\UnsupportedRunnerException; + use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\VersionNotFoundException; use ncc\Interfaces\CompilerInterface; use ncc\Managers\PackageLockManager; @@ -304,7 +304,6 @@ * @throws BuildException * @throws FileNotFoundException * @throws IOException - * @throws UnsupportedRunnerException */ public function build(): ?Package { @@ -443,7 +442,7 @@ * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException - * @throws UnsupportedRunnerException + * @throws RunnerExecutionException */ public function compileExecutionPolicies(): void { diff --git a/src/ncc/Classes/PhpExtension/PhpInstaller.php b/src/ncc/Classes/PhpExtension/PhpInstaller.php index affea6b..323df19 100644 --- a/src/ncc/Classes/PhpExtension/PhpInstaller.php +++ b/src/ncc/Classes/PhpExtension/PhpInstaller.php @@ -288,15 +288,13 @@ * * @param string $src * @param string $output - * @param bool $ignore_units * @return string * @throws AccessDeniedException * @throws CollectorException * @throws FileNotFoundException * @throws IOException - * @throws NoUnitsFoundException */ - private function generateAutoload(string $src, string $output, bool $ignore_units=true): string + private function generateAutoload(string $src, string $output): string { // Construct configuration $configuration = new Config([$src]); @@ -317,10 +315,6 @@ $result = self::runCollector($factory, $configuration); // Exception raises when there are no files in the project that can be processed by the autoloader - if(!$result->hasUnits() && !$ignore_units) - { - throw new NoUnitsFoundException('No units were found in the project'); - } $template = IO::fread($configuration->getTemplate()); diff --git a/src/ncc/Classes/PhpExtension/PhpRunner.php b/src/ncc/Classes/PhpExtension/PhpRunner.php index 87621e3..89f9898 100644 --- a/src/ncc/Classes/PhpExtension/PhpRunner.php +++ b/src/ncc/Classes/PhpExtension/PhpRunner.php @@ -22,19 +22,13 @@ namespace ncc\Classes\PhpExtension; - use ncc\Abstracts\Runners; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; - use ncc\Exceptions\RunnerExecutionException; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class PhpRunner implements RunnerInterface { diff --git a/src/ncc/Classes/PythonExtension/Python2Runner.php b/src/ncc/Classes/PythonExtension/Python2Runner.php index d1f265f..b411a06 100644 --- a/src/ncc/Classes/PythonExtension/Python2Runner.php +++ b/src/ncc/Classes/PythonExtension/Python2Runner.php @@ -22,16 +22,11 @@ namespace ncc\Classes\PythonExtension; - use ncc\Abstracts\Runners; use ncc\Exceptions\FileNotFoundException; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class Python2Runner implements RunnerInterface { diff --git a/src/ncc/Classes/PythonExtension/Python3Runner.php b/src/ncc/Classes/PythonExtension/Python3Runner.php index 443c170..bc6ff39 100644 --- a/src/ncc/Classes/PythonExtension/Python3Runner.php +++ b/src/ncc/Classes/PythonExtension/Python3Runner.php @@ -22,16 +22,11 @@ namespace ncc\Classes\PythonExtension; - use ncc\Abstracts\Runners; use ncc\Exceptions\FileNotFoundException; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class Python3Runner implements RunnerInterface { diff --git a/src/ncc/Classes/PythonExtension/PythonRunner.php b/src/ncc/Classes/PythonExtension/PythonRunner.php index 86033ea..b3d5168 100644 --- a/src/ncc/Classes/PythonExtension/PythonRunner.php +++ b/src/ncc/Classes/PythonExtension/PythonRunner.php @@ -22,16 +22,11 @@ namespace ncc\Classes\PythonExtension; - use ncc\Abstracts\Runners; use ncc\Exceptions\FileNotFoundException; use ncc\Interfaces\RunnerInterface; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; - use ncc\Utilities\Base64; use ncc\Utilities\IO; - use ncc\Utilities\PathFinder; class PythonRunner implements RunnerInterface { diff --git a/src/ncc/Exceptions/BuildConfigurationNotFoundException.php b/src/ncc/Exceptions/BuildConfigurationNotFoundException.php index bea470d..cff197b 100644 --- a/src/ncc/Exceptions/BuildConfigurationNotFoundException.php +++ b/src/ncc/Exceptions/BuildConfigurationNotFoundException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/BuildException.php b/src/ncc/Exceptions/BuildException.php index 99e4196..4394f96 100644 --- a/src/ncc/Exceptions/BuildException.php +++ b/src/ncc/Exceptions/BuildException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/ComponentChecksumException.php b/src/ncc/Exceptions/ComponentChecksumException.php index c466eb5..9261aa7 100644 --- a/src/ncc/Exceptions/ComponentChecksumException.php +++ b/src/ncc/Exceptions/ComponentChecksumException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/ComponentDecodeException.php b/src/ncc/Exceptions/ComponentDecodeException.php index cb307d5..6d08524 100644 --- a/src/ncc/Exceptions/ComponentDecodeException.php +++ b/src/ncc/Exceptions/ComponentDecodeException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/ComposerDisabledException.php b/src/ncc/Exceptions/ComposerDisabledException.php index 4300464..5ecbf63 100644 --- a/src/ncc/Exceptions/ComposerDisabledException.php +++ b/src/ncc/Exceptions/ComposerDisabledException.php @@ -20,14 +20,13 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; + use Exception; use ncc\Abstracts\ExceptionCodes; use Throwable; - class ComposerDisabledException extends \Exception + class ComposerDisabledException extends Exception { /** * @param string $message diff --git a/src/ncc/Exceptions/ComposerException.php b/src/ncc/Exceptions/ComposerException.php index bf1a3f7..52bc4b7 100644 --- a/src/ncc/Exceptions/ComposerException.php +++ b/src/ncc/Exceptions/ComposerException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/ComposerNotAvailableException.php b/src/ncc/Exceptions/ComposerNotAvailableException.php index 62e328e..2f99a51 100644 --- a/src/ncc/Exceptions/ComposerNotAvailableException.php +++ b/src/ncc/Exceptions/ComposerNotAvailableException.php @@ -20,10 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - /** @noinspection PhpMissingFieldTypeInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/GitCheckoutException.php b/src/ncc/Exceptions/GitCheckoutException.php index bd81a82..aaad3c4 100644 --- a/src/ncc/Exceptions/GitCheckoutException.php +++ b/src/ncc/Exceptions/GitCheckoutException.php @@ -22,10 +22,11 @@ namespace ncc\Exceptions; + use Exception; use ncc\Abstracts\ExceptionCodes; use Throwable; - class GitCheckoutException extends \Exception + class GitCheckoutException extends Exception { /** * @param string $message diff --git a/src/ncc/Exceptions/IOException.php b/src/ncc/Exceptions/IOException.php index 7ae5e9f..51d8c98 100644 --- a/src/ncc/Exceptions/IOException.php +++ b/src/ncc/Exceptions/IOException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/InstallationException.php b/src/ncc/Exceptions/InstallationException.php index 2f775f1..de66444 100644 --- a/src/ncc/Exceptions/InstallationException.php +++ b/src/ncc/Exceptions/InstallationException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/InternalComposerNotAvailableException.php b/src/ncc/Exceptions/InternalComposerNotAvailableException.php index 6271b56..1d4808c 100644 --- a/src/ncc/Exceptions/InternalComposerNotAvailableException.php +++ b/src/ncc/Exceptions/InternalComposerNotAvailableException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/InvalidConstantNameException.php b/src/ncc/Exceptions/InvalidConstantNameException.php index 1b245bd..836848b 100644 --- a/src/ncc/Exceptions/InvalidConstantNameException.php +++ b/src/ncc/Exceptions/InvalidConstantNameException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/InvalidPackageException.php b/src/ncc/Exceptions/InvalidPackageException.php index 5738ba7..5af8de4 100644 --- a/src/ncc/Exceptions/InvalidPackageException.php +++ b/src/ncc/Exceptions/InvalidPackageException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php b/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php index 5e06619..b5ec73a 100644 --- a/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php +++ b/src/ncc/Exceptions/InvalidProjectBuildConfiguration.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/InvalidVersionConfigurationException.php b/src/ncc/Exceptions/InvalidVersionConfigurationException.php index 0a73a18..373646a 100644 --- a/src/ncc/Exceptions/InvalidVersionConfigurationException.php +++ b/src/ncc/Exceptions/InvalidVersionConfigurationException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/MissingDependencyException.php b/src/ncc/Exceptions/MissingDependencyException.php index 338f30e..62cdf44 100644 --- a/src/ncc/Exceptions/MissingDependencyException.php +++ b/src/ncc/Exceptions/MissingDependencyException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/NoAvailableUnitsException.php b/src/ncc/Exceptions/NoAvailableUnitsException.php index 778c7ea..eb7f325 100644 --- a/src/ncc/Exceptions/NoAvailableUnitsException.php +++ b/src/ncc/Exceptions/NoAvailableUnitsException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/NotImplementedException.php b/src/ncc/Exceptions/NotImplementedException.php index a0887ce..55de1d1 100644 --- a/src/ncc/Exceptions/NotImplementedException.php +++ b/src/ncc/Exceptions/NotImplementedException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/PackageAlreadyInstalledException.php b/src/ncc/Exceptions/PackageAlreadyInstalledException.php index a437d20..fcbd34c 100644 --- a/src/ncc/Exceptions/PackageAlreadyInstalledException.php +++ b/src/ncc/Exceptions/PackageAlreadyInstalledException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/PackageFetchException.php b/src/ncc/Exceptions/PackageFetchException.php index 40d147c..4dbbbed 100644 --- a/src/ncc/Exceptions/PackageFetchException.php +++ b/src/ncc/Exceptions/PackageFetchException.php @@ -22,10 +22,11 @@ namespace ncc\Exceptions; + use Exception; use ncc\Abstracts\ExceptionCodes; use Throwable; - class PackageFetchException extends \Exception + class PackageFetchException extends Exception { /** * @param string $message diff --git a/src/ncc/Exceptions/PackageLockException.php b/src/ncc/Exceptions/PackageLockException.php index 9a4b1a0..58bbced 100644 --- a/src/ncc/Exceptions/PackageLockException.php +++ b/src/ncc/Exceptions/PackageLockException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/PackageNotFoundException.php b/src/ncc/Exceptions/PackageNotFoundException.php index 98fc89f..070d601 100644 --- a/src/ncc/Exceptions/PackageNotFoundException.php +++ b/src/ncc/Exceptions/PackageNotFoundException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/PackageParsingException.php b/src/ncc/Exceptions/PackageParsingException.php index e208737..7106d1a 100644 --- a/src/ncc/Exceptions/PackageParsingException.php +++ b/src/ncc/Exceptions/PackageParsingException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/PackagePreparationFailedException.php b/src/ncc/Exceptions/PackagePreparationFailedException.php index 67edb24..223795f 100644 --- a/src/ncc/Exceptions/PackagePreparationFailedException.php +++ b/src/ncc/Exceptions/PackagePreparationFailedException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/ResourceChecksumException.php b/src/ncc/Exceptions/ResourceChecksumException.php index d7e14ce..3de79cc 100644 --- a/src/ncc/Exceptions/ResourceChecksumException.php +++ b/src/ncc/Exceptions/ResourceChecksumException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use Throwable; diff --git a/src/ncc/Exceptions/RunnerExecutionException.php b/src/ncc/Exceptions/RunnerExecutionException.php index a6be30d..244a0b5 100644 --- a/src/ncc/Exceptions/RunnerExecutionException.php +++ b/src/ncc/Exceptions/RunnerExecutionException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/UndefinedExecutionPolicyException.php b/src/ncc/Exceptions/UndefinedExecutionPolicyException.php index 92ba1f5..34e8096 100644 --- a/src/ncc/Exceptions/UndefinedExecutionPolicyException.php +++ b/src/ncc/Exceptions/UndefinedExecutionPolicyException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php b/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php index e136cd1..d2ffdd4 100644 --- a/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php +++ b/src/ncc/Exceptions/UnsupportedCompilerExtensionException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/UnsupportedComponentTypeException.php b/src/ncc/Exceptions/UnsupportedComponentTypeException.php index 20b2626..5352a41 100644 --- a/src/ncc/Exceptions/UnsupportedComponentTypeException.php +++ b/src/ncc/Exceptions/UnsupportedComponentTypeException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/UnsupportedPackageException.php b/src/ncc/Exceptions/UnsupportedPackageException.php index 6d60852..6e08431 100644 --- a/src/ncc/Exceptions/UnsupportedPackageException.php +++ b/src/ncc/Exceptions/UnsupportedPackageException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/UserAbortedOperationException.php b/src/ncc/Exceptions/UserAbortedOperationException.php index a360e56..fa27d21 100644 --- a/src/ncc/Exceptions/UserAbortedOperationException.php +++ b/src/ncc/Exceptions/UserAbortedOperationException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Exceptions/VersionNotFoundException.php b/src/ncc/Exceptions/VersionNotFoundException.php index f25f29a..c1348ea 100644 --- a/src/ncc/Exceptions/VersionNotFoundException.php +++ b/src/ncc/Exceptions/VersionNotFoundException.php @@ -20,9 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - - namespace ncc\Exceptions; +namespace ncc\Exceptions; use Exception; use ncc\Abstracts\ExceptionCodes; diff --git a/src/ncc/Extensions/ZiProto/Abstracts/Regex.php b/src/ncc/Extensions/ZiProto/Abstracts/Regex.php index cbc3209..1727946 100644 --- a/src/ncc/Extensions/ZiProto/Abstracts/Regex.php +++ b/src/ncc/Extensions/ZiProto/Abstracts/Regex.php @@ -31,7 +31,7 @@ namespace ncc\ZiProto\Abstracts; const UTF8_REGEX = '/\A(?: [\x00-\x7F]++ # ASCII | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte - | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding over longs | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 diff --git a/src/ncc/Extensions/ZiProto/BufferStream.php b/src/ncc/Extensions/ZiProto/BufferStream.php index fb6bf2b..92fde68 100644 --- a/src/ncc/Extensions/ZiProto/BufferStream.php +++ b/src/ncc/Extensions/ZiProto/BufferStream.php @@ -210,8 +210,11 @@ namespace ncc\ZiProto; case 0xc3: return true; // bin + case 0xd9: case 0xc4: return $this->decodeStrData($this->decodeUint8()); + case 0xda: case 0xc5: return $this->decodeStrData($this->decodeUint16()); + case 0xdb: case 0xc6: return $this->decodeStrData($this->decodeUint32()); // float @@ -231,9 +234,6 @@ namespace ncc\ZiProto; case 0xd3: return $this->decodeInt64(); // str - case 0xd9: return $this->decodeStrData($this->decodeUint8()); - case 0xda: return $this->decodeStrData($this->decodeUint16()); - case 0xdb: return $this->decodeStrData($this->decodeUint32()); // array case 0xdc: return $this->decodeArrayData($this->decodeUint16()); @@ -372,7 +372,7 @@ namespace ncc\ZiProto; } /** - * @return bool|string + * @return string */ public function decodeStr() { @@ -408,7 +408,7 @@ namespace ncc\ZiProto; } /** - * @return bool|string + * @return string */ public function decodeBin() { diff --git a/src/ncc/Extensions/ZiProto/DecodingOptions.php b/src/ncc/Extensions/ZiProto/DecodingOptions.php index 43fdf48..347b2a1 100644 --- a/src/ncc/Extensions/ZiProto/DecodingOptions.php +++ b/src/ncc/Extensions/ZiProto/DecodingOptions.php @@ -61,7 +61,7 @@ namespace ncc\ZiProto; { $self = new self(); - $self->bigIntMode = self::getSingleOption('bigint', $bitmask, + $self->bigIntMode = self::getSingleOption($bitmask, Options::BIGINT_AS_STR | Options::BIGINT_AS_GMP | Options::BIGINT_AS_EXCEPTION @@ -87,12 +87,11 @@ namespace ncc\ZiProto; } /** - * @param string $name * @param int $bitmask * @param int $validBitmask * @return int */ - private static function getSingleOption(string $name, int $bitmask, int $validBitmask) : int + private static function getSingleOption(int $bitmask, int $validBitmask) : int { $option = $bitmask & $validBitmask; if ($option === ($option & -$option)) @@ -112,6 +111,6 @@ namespace ncc\ZiProto; $validOptions[] = __CLASS__.'::'.$map[$i]; } - throw InvalidOptionException::outOfRange($name, $validOptions); + throw InvalidOptionException::outOfRange('bigint', $validOptions); } } diff --git a/src/ncc/Extensions/ZiProto/Packet.php b/src/ncc/Extensions/ZiProto/Packet.php index 5e9cde6..3db2473 100644 --- a/src/ncc/Extensions/ZiProto/Packet.php +++ b/src/ncc/Extensions/ZiProto/Packet.php @@ -112,7 +112,7 @@ namespace ncc\ZiProto; * @param $value * @return false|string */ - public function encode($value) + public function encode($value): false|string { if (is_int($value)) { @@ -185,7 +185,7 @@ namespace ncc\ZiProto; /** * @return string */ - public function encodeNil() + public function encodeNil(): string { return "\xc0"; } @@ -194,7 +194,7 @@ namespace ncc\ZiProto; * @param $bool * @return string */ - public function encodeBool($bool) + public function encodeBool($bool): string { return $bool ? "\xc3" : "\xc2"; } @@ -203,7 +203,7 @@ namespace ncc\ZiProto; * @param $int * @return string */ - public function encodeInt($int) + public function encodeInt($int): string { if ($int >= 0) { @@ -257,7 +257,7 @@ namespace ncc\ZiProto; * @param $float * @return string */ - public function encodeFloat($float) + public function encodeFloat($float): string { return $this->isForceFloat32 ? "\xca". pack('G', $float) @@ -268,7 +268,7 @@ namespace ncc\ZiProto; * @param $str * @return string */ - public function encodeStr($str) + public function encodeStr($str): string { $length = strlen($str); @@ -294,7 +294,7 @@ namespace ncc\ZiProto; * @param $str * @return string */ - public function encodeBin($str) + public function encodeBin($str): string { $length = strlen($str); @@ -313,9 +313,9 @@ namespace ncc\ZiProto; /** * @param $array - * @return false|string + * @return string */ - public function encodeArray($array) + public function encodeArray($array): string { $data = $this->encodeArrayHeader(count($array)); @@ -331,7 +331,7 @@ namespace ncc\ZiProto; * @param $size * @return string */ - public function encodeArrayHeader($size) + public function encodeArrayHeader($size): string { if ($size <= 0xf) { @@ -348,9 +348,9 @@ namespace ncc\ZiProto; /** * @param $map - * @return false|string + * @return string */ - public function encodeMap($map) + public function encodeMap($map): string { $data = $this->encodeMapHeader(count($map)); @@ -391,7 +391,7 @@ namespace ncc\ZiProto; * @param $size * @return string */ - public function encodeMapHeader($size) + public function encodeMapHeader($size): string { if ($size <= 0xf) { @@ -411,7 +411,7 @@ namespace ncc\ZiProto; * @param $data * @return string */ - public function encodeExt($type, $data) + public function encodeExt($type, $data): string { $length = strlen($data); diff --git a/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php b/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php index bc1ac56..54d2f34 100644 --- a/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php +++ b/src/ncc/Extensions/ZiProto/TypeTransformer/BinaryTransformer.php @@ -34,7 +34,7 @@ namespace ncc\ncc\ZiProto\TypeTransformer; /** * @param Packet $packer * @param $value - * @return string + * @return string|null */ public function pack(Packet $packer, $value): ?string { diff --git a/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php b/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php index 1633e91..dffa49a 100644 --- a/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php +++ b/src/ncc/Extensions/ZiProto/TypeTransformer/Extension.php @@ -40,5 +40,5 @@ namespace ncc\ncc\ZiProto\TypeTransformer; * @param int $extLength * @return mixed */ - public function decode(BufferStream $stream, int $extLength); + public function decode(BufferStream $stream, int $extLength): mixed; } \ No newline at end of file diff --git a/src/ncc/Interfaces/CompilerInterface.php b/src/ncc/Interfaces/CompilerInterface.php index 37c1683..7ab44de 100644 --- a/src/ncc/Interfaces/CompilerInterface.php +++ b/src/ncc/Interfaces/CompilerInterface.php @@ -27,7 +27,6 @@ namespace ncc\Interfaces; use ncc\Exceptions\BuildException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; @@ -57,7 +56,6 @@ namespace ncc\Interfaces; * @throws BuildException * @throws FileNotFoundException * @throws IOException - * @throws UnsupportedRunnerException */ public function build(): ?Package; @@ -88,7 +86,6 @@ namespace ncc\Interfaces; * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException - * @throws UnsupportedRunnerException */ public function compileExecutionPolicies(): void; diff --git a/src/ncc/Interfaces/RunnerInterface.php b/src/ncc/Interfaces/RunnerInterface.php index 3b3d7f3..6b09f8d 100644 --- a/src/ncc/Interfaces/RunnerInterface.php +++ b/src/ncc/Interfaces/RunnerInterface.php @@ -25,11 +25,8 @@ namespace ncc\Interfaces; use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\IOException; - use ncc\Exceptions\RunnerExecutionException; - use ncc\Objects\ExecutionPointers\ExecutionPointer; use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\ProjectConfiguration\ExecutionPolicy; - use ncc\ThirdParty\Symfony\Process\Process; interface RunnerInterface { diff --git a/src/ncc/Managers/ExecutionPointerManager.php b/src/ncc/Managers/ExecutionPointerManager.php index ca52b12..9bedc3b 100644 --- a/src/ncc/Managers/ExecutionPointerManager.php +++ b/src/ncc/Managers/ExecutionPointerManager.php @@ -36,13 +36,11 @@ use ncc\Classes\PythonExtension\Python3Runner; use ncc\Classes\PythonExtension\PythonRunner; use ncc\Exceptions\AccessDeniedException; - use ncc\Exceptions\ExecutionUnitNotFoundException; use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; use ncc\Exceptions\NoAvailableUnitsException; use ncc\Exceptions\RunnerExecutionException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Objects\ExecutionPointers; use ncc\Objects\Package; use ncc\Objects\Package\ExecutionUnit; @@ -166,9 +164,8 @@ * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException - * @throws UnsupportedRunnerException + * @throws RunnerExecutionException * @noinspection PhpUnused - * @noinspection DuplicatedCode */ public function addUnit(string $package, string $version, ExecutionUnit $unit, bool $temporary=false): void { @@ -209,7 +206,7 @@ Runners::python2 => Python2Runner::getFileExtension(), Runners::python3 => Python3Runner::getFileExtension(), Runners::lua => LuaRunner::getFileExtension(), - default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), + default => throw new RunnerExecutionException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'), }; Console::outDebug(sprintf('bin_file=%s', $bin_file)); @@ -258,7 +255,6 @@ * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException - * @noinspection DuplicatedCode */ public function removeUnit(string $package, string $version, string $name): bool { @@ -347,12 +343,10 @@ * @param array $args * @return int * @throws AccessDeniedException - * @throws ExecutionUnitNotFoundException * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException * @throws RunnerExecutionException - * @throws UnsupportedRunnerException */ public function executeUnit(string $package, string $version, string $name, array $args=[]): int { @@ -368,7 +362,7 @@ $unit = $execution_pointers->getUnit($name); if($unit == null) - throw new ExecutionUnitNotFoundException('The execution unit \'' . $name . '\' was not found for \'' . $package . '=' .$version .'\''); + throw new RunnerExecutionException('The execution unit \'' . $name . '\' was not found for \'' . $package . '=' .$version .'\''); Console::outDebug(sprintf('unit=%s', $unit->ExecutionPolicy->Name)); Console::outDebug(sprintf('runner=%s', $unit->ExecutionPolicy->Runner)); @@ -470,12 +464,10 @@ * @param string $unit_name * @return void * @throws AccessDeniedException - * @throws ExecutionUnitNotFoundException * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException * @throws RunnerExecutionException - * @throws UnsupportedRunnerException */ public function temporaryExecute(Package $package, string $unit_name): void { @@ -522,12 +514,10 @@ * @param Process|null $process * @return bool * @throws AccessDeniedException - * @throws ExecutionUnitNotFoundException * @throws FileNotFoundException * @throws IOException * @throws NoAvailableUnitsException * @throws RunnerExecutionException - * @throws UnsupportedRunnerException */ public function handleExit(string $package, string $version, ExitHandle $exitHandle, ?Process $process=null): bool { diff --git a/src/ncc/Managers/PackageLockManager.php b/src/ncc/Managers/PackageLockManager.php index ec41f0e..46134d6 100644 --- a/src/ncc/Managers/PackageLockManager.php +++ b/src/ncc/Managers/PackageLockManager.php @@ -20,8 +20,7 @@ * */ - /** @noinspection PhpPropertyOnlyWrittenInspection */ - /** @noinspection PhpMissingFieldTypeInspection */ +/** @noinspection PhpMissingFieldTypeInspection */ namespace ncc\Managers; diff --git a/src/ncc/Managers/PackageManager.php b/src/ncc/Managers/PackageManager.php index e0820e3..fb2cde0 100644 --- a/src/ncc/Managers/PackageManager.php +++ b/src/ncc/Managers/PackageManager.php @@ -51,6 +51,7 @@ use ncc\Exceptions\PackageLockException; use ncc\Exceptions\PackageNotFoundException; use ncc\Exceptions\PackageParsingException; + use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\SymlinkException; use ncc\Exceptions\UnsupportedCompilerExtensionException; use ncc\Exceptions\VersionNotFoundException; @@ -109,6 +110,7 @@ * @throws FileNotFoundException * @throws IOException * @throws InstallationException + * @throws InvalidPackageNameException * @throws InvalidScopeException * @throws MissingDependencyException * @throws NotImplementedException @@ -116,11 +118,10 @@ * @throws PackageLockException * @throws PackageNotFoundException * @throws PackageParsingException - * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException - * @throws VersionNotFoundException - * @throws InvalidPackageNameException + * @throws RunnerExecutionException * @throws SymlinkException + * @throws UnsupportedCompilerExtensionException + * @throws VersionNotFoundException */ public function install(string $package_path, ?Entry $entry=null, array $options=[]): string { @@ -604,6 +605,7 @@ * @throws SymlinkException * @throws UnsupportedCompilerExtensionException * @throws VersionNotFoundException + * @throws RunnerExecutionException */ private function processDependency(Dependency $dependency, Package $package, string $package_path, ?Entry $entry=null): void { @@ -930,7 +932,7 @@ $paths->getDataPath() . DIRECTORY_SEPARATOR . 'assembly' => ZiProto::encode($package->Assembly->toArray(true)), $paths->getDataPath() . DIRECTORY_SEPARATOR . 'ext' => - ZiProto::encode($package->Header->CompilerExtension->toArray(true)), + ZiProto::encode($package->Header->CompilerExtension->toArray()), $paths->getDataPath() . DIRECTORY_SEPARATOR . 'const' => ZiProto::encode($package->Header->RuntimeConstants), $paths->getDataPath() . DIRECTORY_SEPARATOR . 'dependencies' => diff --git a/src/ncc/Managers/ProjectManager.php b/src/ncc/Managers/ProjectManager.php index cfde399..9e28ba6 100644 --- a/src/ncc/Managers/ProjectManager.php +++ b/src/ncc/Managers/ProjectManager.php @@ -40,7 +40,6 @@ use ncc\Exceptions\ProjectAlreadyExistsException; use ncc\Exceptions\ProjectConfigurationNotFoundException; use ncc\Exceptions\UnsupportedCompilerExtensionException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Objects\ProjectConfiguration; use ncc\Objects\ProjectConfiguration\Compiler; use ncc\ThirdParty\Symfony\Uid\Uuid; @@ -192,14 +191,10 @@ // Process options foreach($options as $option) { - switch($option) - { - case InitializeProjectOptions::CREATE_SOURCE_DIRECTORY: - if(!file_exists($this->ProjectConfiguration->Build->SourcePath)) - { - mkdir($this->ProjectConfiguration->Build->SourcePath); - } - break; + if ($option == InitializeProjectOptions::CREATE_SOURCE_DIRECTORY) { + if (!file_exists($this->ProjectConfiguration->Build->SourcePath)) { + mkdir($this->ProjectConfiguration->Build->SourcePath); + } } } } @@ -227,7 +222,7 @@ * @throws FileNotFoundException * @throws IOException */ - public function load() + public function load(): void { if(!file_exists($this->ProjectFilePath) && !is_file($this->ProjectFilePath)) throw new ProjectConfigurationNotFoundException('The project configuration file \'' . $this->ProjectFilePath . '\' was not found'); @@ -241,7 +236,7 @@ * @return void * @throws MalformedJsonException */ - public function save() + public function save(): void { if(!$this->projectLoaded()) return; @@ -294,7 +289,6 @@ * @throws BuildException * @throws PackagePreparationFailedException * @throws UnsupportedCompilerExtensionException - * @throws UnsupportedRunnerException */ public function build(string $build_configuration=BuildConfigurationValues::DefaultConfiguration): string { diff --git a/src/ncc/Managers/RemoteSourcesManager.php b/src/ncc/Managers/RemoteSourcesManager.php index 24e5e62..dc1f884 100644 --- a/src/ncc/Managers/RemoteSourcesManager.php +++ b/src/ncc/Managers/RemoteSourcesManager.php @@ -56,7 +56,6 @@ */ public function __construct() { - /** @noinspection PhpUnhandledExceptionInspection */ $this->DefinedSourcesPath = PathFinder::getRemoteSources(Scopes::System); $this->load(); diff --git a/src/ncc/Managers/SymlinkManager.php b/src/ncc/Managers/SymlinkManager.php index 8dff5e9..ce3e2e1 100644 --- a/src/ncc/Managers/SymlinkManager.php +++ b/src/ncc/Managers/SymlinkManager.php @@ -282,28 +282,6 @@ } } - /** - * Sets the package as unregistered - * - * @param string $package - * @return void - * @throws AccessDeniedException - * @throws SymlinkException - */ - private function setAsUnregistered(string $package): void - { - foreach($this->SymlinkDictionary as $key => $entry) - { - if($entry->Package === $package) - { - $entry->Registered = false; - $this->SymlinkDictionary[$key] = $entry; - $this->save(); - return; - } - } - } - /** * Syncs the symlink dictionary with the filesystem * diff --git a/src/ncc/Objects/Constant.php b/src/ncc/Objects/Constant.php index 4a466cd..a4ec300 100644 --- a/src/ncc/Objects/Constant.php +++ b/src/ncc/Objects/Constant.php @@ -114,7 +114,7 @@ namespace ncc\Objects; */ public function setValue(string $value, bool $readonly=false): void { - if($this->Readonly == true) + if($this->Readonly) { throw new ConstantReadonlyException('Cannot set value to the constant \'' . $this->getFullName() . '\', constant is readonly'); } diff --git a/src/ncc/Objects/Package.php b/src/ncc/Objects/Package.php index 5a0d3e6..e5fce9d 100644 --- a/src/ncc/Objects/Package.php +++ b/src/ncc/Objects/Package.php @@ -129,7 +129,7 @@ * @param Dependency $dependency * @return void */ - public function addDependency(Dependency $dependency) + public function addDependency(Dependency $dependency): void { foreach($this->Dependencies as $dep) { @@ -149,7 +149,7 @@ * @param string $name * @return void */ - private function removeDependency(string $name) + private function removeDependency(string $name): void { foreach($this->Dependencies as $key => $dep) { diff --git a/src/ncc/Objects/Package/Header.php b/src/ncc/Objects/Package/Header.php index 3007fca..b53779d 100644 --- a/src/ncc/Objects/Package/Header.php +++ b/src/ncc/Objects/Package/Header.php @@ -84,7 +84,7 @@ public function toArray(bool $bytecode=false): array { return [ - ($bytecode ? Functions::cbc('compiler_extension') : 'compiler_extension') => $this->CompilerExtension->toArray($bytecode), + ($bytecode ? Functions::cbc('compiler_extension') : 'compiler_extension') => $this->CompilerExtension->toArray(), ($bytecode ? Functions::cbc('runtime_constants') : 'runtime_constants') => $this->RuntimeConstants, ($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->CompilerVersion, ($bytecode ? Functions::cbc('update_source') : 'update_source') => ($this->UpdateSource?->toArray($bytecode) ?? null), diff --git a/src/ncc/Objects/PackageLock/PackageEntry.php b/src/ncc/Objects/PackageLock/PackageEntry.php index e144139..e1f2dc8 100644 --- a/src/ncc/Objects/PackageLock/PackageEntry.php +++ b/src/ncc/Objects/PackageLock/PackageEntry.php @@ -239,7 +239,7 @@ if(!file_exists($path) && Resolver::resolveScope() == Scopes::System) { $filesystem = new Filesystem(); - $filesystem->mkdir($path, 0777); + $filesystem->mkdir($path); } return $path; diff --git a/src/ncc/Objects/PackageLock/VersionEntry.php b/src/ncc/Objects/PackageLock/VersionEntry.php index 01cd1e7..a90a22b 100644 --- a/src/ncc/Objects/PackageLock/VersionEntry.php +++ b/src/ncc/Objects/PackageLock/VersionEntry.php @@ -112,7 +112,7 @@ return [ ($bytecode ? Functions::cbc('version') : 'version') => $this->Version, - ($bytecode ? Functions::cbc('compiler') : 'compiler') => $this->Compiler->toArray($bytecode), + ($bytecode ? Functions::cbc('compiler') : 'compiler') => $this->Compiler->toArray(), ($bytecode ? Functions::cbc('dependencies') : 'dependencies') => $dependencies, ($bytecode ? Functions::cbc('execution_units') : 'execution_units') => $execution_units, ($bytecode ? Functions::cbc('main_execution_policy') : 'main_execution_policy') => $this->MainExecutionPolicy, diff --git a/src/ncc/Objects/ProjectConfiguration/Compiler.php b/src/ncc/Objects/ProjectConfiguration/Compiler.php index d1501b6..64ce759 100644 --- a/src/ncc/Objects/ProjectConfiguration/Compiler.php +++ b/src/ncc/Objects/ProjectConfiguration/Compiler.php @@ -145,10 +145,9 @@ /** * Returns an array representation of the object * - * @param bool $bytecode * @return array */ - public function toArray(bool $bytecode=false): array + public function toArray(): array { $return_results = []; if($this->Extension !== null && strlen($this->Extension) > 0) diff --git a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php index f2b6c5d..efc175c 100644 --- a/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php +++ b/src/ncc/Objects/ProjectConfiguration/ExecutionPolicy.php @@ -66,10 +66,9 @@ public $ExitHandlers; /** - * @param bool $throw_exception * @return bool */ - public function validate(bool $throw_exception=True): bool + public function validate(): bool { // TODO: Implement validation method return true; diff --git a/src/ncc/Objects/ProjectConfiguration/Project.php b/src/ncc/Objects/ProjectConfiguration/Project.php index 458cabd..77e15db 100644 --- a/src/ncc/Objects/ProjectConfiguration/Project.php +++ b/src/ncc/Objects/ProjectConfiguration/Project.php @@ -88,7 +88,7 @@ { $ReturnResults = []; - $ReturnResults[($bytecode ? Functions::cbc('compiler') : 'compiler')] = $this->Compiler->toArray($bytecode); + $ReturnResults[($bytecode ? Functions::cbc('compiler') : 'compiler')] = $this->Compiler->toArray(); $ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options; if($this->UpdateSource !== null) diff --git a/src/ncc/Objects/ProjectDetectionResults.php b/src/ncc/Objects/ProjectDetectionResults.php index 5ead723..b5bb92e 100644 --- a/src/ncc/Objects/ProjectDetectionResults.php +++ b/src/ncc/Objects/ProjectDetectionResults.php @@ -59,8 +59,6 @@ namespace ncc\Objects; - use ncc\Abstracts\ProjectType; - class ProjectDetectionResults { /** diff --git a/src/ncc/Runtime.php b/src/ncc/Runtime.php index 6792a4e..b9ab941 100644 --- a/src/ncc/Runtime.php +++ b/src/ncc/Runtime.php @@ -174,7 +174,7 @@ $package = self::getPackageManager()->getPackage($package); if($package == null) - throw new PackageNotFoundException(sprintf('Package %s not found', $package)); + throw new PackageNotFoundException('Package not found (null entry error, possible bug)'); return $package->getDataPath(); } diff --git a/src/ncc/Utilities/Functions.php b/src/ncc/Utilities/Functions.php index fb75342..863520b 100644 --- a/src/ncc/Utilities/Functions.php +++ b/src/ncc/Utilities/Functions.php @@ -47,8 +47,8 @@ namespace ncc\Utilities; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\IOException; use ncc\Exceptions\MalformedJsonException; + use ncc\Exceptions\RunnerExecutionException; use ncc\Exceptions\UnsupportedArchiveException; - use ncc\Exceptions\UnsupportedRunnerException; use ncc\Managers\ConfigurationManager; use ncc\Managers\CredentialManager; use ncc\Managers\PackageLockManager; @@ -298,10 +298,10 @@ namespace ncc\Utilities; * @param string $path * @param ExecutionPolicy $policy * @return ExecutionUnit - * @throws UnsupportedRunnerException * @throws AccessDeniedException * @throws FileNotFoundException * @throws IOException + * @throws RunnerExecutionException */ public static function compileRunner(string $path, ExecutionPolicy $policy): ExecutionUnit { @@ -313,7 +313,7 @@ namespace ncc\Utilities; Runners::python2 => Python2Runner::processUnit($path, $policy), Runners::python3 => Python3Runner::processUnit($path, $policy), Runners::lua => LuaRunner::processUnit($path, $policy), - default => throw new UnsupportedRunnerException('The runner \'' . $policy->Runner . '\' is not supported'), + default => throw new RunnerExecutionException('The runner \'' . $policy->Runner . '\' is not supported'), }; } @@ -676,21 +676,13 @@ namespace ncc\Utilities; if (!in_array($mimeType, $supportedTypes)) throw new UnsupportedArchiveException("Unsupported archive type: $mimeType"); - switch($mimeType) - { - case 'application/zip': - $command = [$unzip_executable, $path, '-d', $out_path]; - break; - case 'application/x-tar': - $command = [$tar_executable, '--verbose', '-xf', $path, '-C', $out_path]; - break; - case 'application/x-gzip': - $command = [$tar_executable, '--verbose', '-xzf', $path, '-C', $out_path]; - break; - case 'application/x-bzip2': - $command = [$tar_executable, '--verbose', '-xjf', $path, '-C', $out_path]; - break; - } + $command = match ($mimeType) { + 'application/zip' => [$unzip_executable, $path, '-d', $out_path], + 'application/x-tar' => [$tar_executable, '--verbose', '-xf', $path, '-C', $out_path], + 'application/x-gzip' => [$tar_executable, '--verbose', '-xzf', $path, '-C', $out_path], + 'application/x-bzip2' => [$tar_executable, '--verbose', '-xjf', $path, '-C', $out_path], + default => throw new UnsupportedArchiveException("Unsupported archive type: $mimeType"), + }; Console::out("Extracting archive $path"); $process = new Process($command); @@ -746,7 +738,6 @@ namespace ncc\Utilities; $minor = (string)null; $patch = (string)null; - $buildmetadata = (string)null; if(count($parts) >= 1) $major = $parts[0]; if(count($parts) >= 2) @@ -945,7 +936,7 @@ namespace ncc\Utilities; * @param string $input * @return float|int|mixed|string */ - public static function stringTypeCast(string $input) + public static function stringTypeCast(string $input): mixed { if (is_numeric($input)) { @@ -969,7 +960,7 @@ namespace ncc\Utilities; * @return void * @throws InvalidScopeException */ - public static function finalizePermissions() + public static function finalizePermissions(): void { if(Resolver::resolveScope() !== Scopes::System) return; diff --git a/src/ncc/Utilities/Resolver.php b/src/ncc/Utilities/Resolver.php index d30bf64..c58edab 100644 --- a/src/ncc/Utilities/Resolver.php +++ b/src/ncc/Utilities/Resolver.php @@ -292,7 +292,6 @@ * Detects the project type from the specified path * * @param string $path - * @param array $exlucde * @return ProjectDetectionResults */ public static function detectProjectType(string $path): ProjectDetectionResults diff --git a/src/ncc/Utilities/Security.php b/src/ncc/Utilities/Security.php index 07856f6..f2d3de2 100644 --- a/src/ncc/Utilities/Security.php +++ b/src/ncc/Utilities/Security.php @@ -48,8 +48,7 @@ namespace ncc\Utilities; if ($beautify) $input = self::beautifyFilename($input); // maximize filename length to 255 bytes http://serverfault.com/a/9548/44086 $ext = pathinfo($input, PATHINFO_EXTENSION); - $input = mb_strcut(pathinfo($input, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($input)) . ($ext ? '.' . $ext : ''); - return $input; + return mb_strcut(pathinfo($input, PATHINFO_FILENAME), 0, 255 - ($ext ? strlen($ext) + 1 : 0), mb_detect_encoding($input)) . ($ext ? '.' . $ext : ''); } /** @@ -77,8 +76,6 @@ namespace ncc\Utilities; // lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625 $input = mb_strtolower($input, mb_detect_encoding($input)); // ".file-name.-" becomes "file-name" - $input = trim($input, '.-'); - - return $input; + return trim($input, '.-'); } } \ No newline at end of file diff --git a/src/ncc/ncc b/src/ncc/ncc index a5d251f..fd7b4af 100644 --- a/src/ncc/ncc +++ b/src/ncc/ncc @@ -19,6 +19,8 @@ * DEALINGS IN THE SOFTWARE. * */ - - require('autoload.php'); - \ncc\CLI\Main::start($argv); \ No newline at end of file + +use ncc\CLI\Main; + +require('autoload.php'); + Main::start($argv); \ No newline at end of file diff --git a/src/ncc/ncc.php b/src/ncc/ncc.php index 186bc61..72e609f 100644 --- a/src/ncc/ncc.php +++ b/src/ncc/ncc.php @@ -38,7 +38,7 @@ namespace ncc; { /** - * The cache'd version of the version information object. + * The cached version of the version information object. * * @var NccVersionInformation|null */ @@ -98,7 +98,9 @@ namespace ncc; * Initializes the NCC environment * * @return bool - * @throws Exceptions\FileNotFoundException + * @throws AccessDeniedException + * @throws FileNotFoundException + * @throws IOException * @throws RuntimeException */ public static function initialize(): bool @@ -146,7 +148,7 @@ namespace ncc; */ public static function getConstants(): array { - if(defined('NCC_INIT') == false) + if(!defined('NCC_INIT')) { throw new RuntimeException('NCC Must be initialized before executing ' . get_called_class() . '::getConstants()'); } -- 2.45.3 From 018918b4e9026f41abcddae7bbe264a9ce2b10da Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 29 Jan 2023 18:22:47 -0500 Subject: [PATCH 212/212] Updated .gitlab-ci.yml --- .gitlab-ci.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d240dd9..7a5e944 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,15 +18,16 @@ before_script: build: script: - - make redist + - make tar rules: - - if: $CI_COMMIT_BRANCH + - if: $CI_COMMIT_BRANCH release: script: - - make redist + - make tar + - mv build/build.tar.gz build/ncc_$CI_COMMIT_TAG.tar.gz artifacts: paths: - - build/src + - build/ncc_$CI_COMMIT_TAG.tar.gz rules: - - if: $CI_COMMIT_TAG \ No newline at end of file + - if: $CI_COMMIT_TAG \ No newline at end of file -- 2.45.3