Compare commits

..

No commits in common. "master" and "2.0.3" have entirely different histories.

509 changed files with 12614 additions and 16683 deletions

View file

@ -1,136 +0,0 @@
name: CI Pipeline
on:
push:
branches:
- '**'
pull_request:
branches:
- '**'
release:
types:
- created
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: mbstring, ctype, common, zip
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y git libpq-dev libzip-dev zip make wget gnupg
- name: Install Phive
run: |
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
- name: Install PHPAB
run: sudo phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C
- name: Build project
run: make redist
- name: Find NCC build directory
id: find-ncc-dir
run: echo "NCC_DIR=$(find build/ -type d -name 'ncc_*' | head -n 1)" >> $GITHUB_ENV
- name: Upload NCC build directory
uses: actions/upload-artifact@v3
with:
name: ncc-build
path: ${{ env.NCC_DIR }}
- name: Create redist.zip
run: zip -r redist.zip ${{ env.NCC_DIR }}
- name: Upload redist.zip
uses: actions/upload-artifact@v3
with:
name: redist-zip
path: redist.zip
- name: Build Debian package
run: make deb
- name: Find Debian package
id: find-deb
run: echo "DEB_FILE=$(find build/ -type f -name '*.deb' | head -n 1)" >> $GITHUB_ENV
- name: Upload Debian package
uses: actions/upload-artifact@v3
with:
name: ncc-deb
path: ${{ env.DEB_FILE }}
test-install:
runs-on: ubuntu-latest
needs: build
steps:
- name: Download NCC build directory
uses: actions/download-artifact@v3
with:
name: ncc-build
path: build
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: mbstring, ctype, common, zip
- name: Test NCC installation
run: |
ls -l build
sudo php build/INSTALL --auto
upload-release:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'release' && github.event.action == 'created'
permissions: write-all
steps:
- name: Download redist.zip
uses: actions/download-artifact@v3
with:
name: redist-zip
path: .
- name: Download Debian package
uses: actions/download-artifact@v3
with:
name: ncc-deb
path: .
- name: Set DEB_FILE environment variable
run: echo "DEB_FILE=$(find . -type f -name '*.deb' | head -n 1)" >> $GITHUB_ENV
- name: Upload redist.zip to release
uses: softprops/action-gh-release@v1
with:
files: redist.zip
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload ncc.deb to release
uses: softprops/action-gh-release@v1
with:
files: ${{ env.DEB_FILE }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

5
.gitignore vendored
View file

@ -8,7 +8,7 @@
build build
# Autoload files # Autoload files
src/ncc/ThirdParty/composer/Semver/autoload_spl.php src/ncc/ThirdParty/composer/semver/autoload_spl.php
src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php
src/ncc/ThirdParty/jelix/version/autoload_spl.php src/ncc/ThirdParty/jelix/version/autoload_spl.php
src/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php src/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php
@ -29,6 +29,3 @@ src/ncc/autoload.php
tests/example_project/project.json tests/example_project/project.json
tests/example_project/ncc tests/example_project/ncc
tests/example_project/build tests/example_project/build
/.phpunit.result.cache
/.idea/php-test-framework.xml
/.idea/gbrowser_project.xml

View file

@ -1,7 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<ScalaCodeStyleSettings>
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
</ScalaCodeStyleSettings>
</code_scheme>
</component>

8
.idea/php.xml generated
View file

@ -12,9 +12,10 @@
<component name="PhpIncludePathManager"> <component name="PhpIncludePathManager">
<include_path> <include_path>
<path value="/usr/share/php" /> <path value="/usr/share/php" />
<path value="$PROJECT_DIR$/../loglib" />
</include_path> </include_path>
</component> </component>
<component name="PhpProjectSharedConfiguration" php_language_level="8.3"> <component name="PhpProjectSharedConfiguration" php_language_level="8.2">
<option name="suggestChangeDefaultLanguageLevel" value="false" /> <option name="suggestChangeDefaultLanguageLevel" value="false" />
</component> </component>
<component name="PhpRuntimeConfiguration"> <component name="PhpRuntimeConfiguration">
@ -25,11 +26,6 @@
<component name="PhpStanOptionsConfiguration"> <component name="PhpStanOptionsConfiguration">
<option name="transferred" value="true" /> <option name="transferred" value="true" />
</component> </component>
<component name="PhpUnit">
<phpunit_settings>
<PhpUnitSettings load_method="PHPUNIT_PHAR" custom_loader_path="" phpunit_phar_path="$USER_HOME$/phpunit.phar" />
</phpunit_settings>
</component>
<component name="PsalmOptionsConfiguration"> <component name="PsalmOptionsConfiguration">
<option name="transferred" value="true" /> <option name="transferred" value="true" />
</component> </component>

View file

@ -5,170 +5,6 @@ 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/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [2.1.6] - 2024-10-29
This update introduces critical bug fixes
### Fixed
- Validate package instance before checking execution policy
## [2.1.5] - 2024-10-14
This update introduces a critical bug fix
## [2.1.4] - 2024-10-13
This update introduces minor bug fixes & improvements
### Added
- Added new constant `%DEFAULT_BUILD_CONFIGURATION%` which points to the project's default build configuration
- Added new dynamic constant `%BUILD_OUTPUT_PATH%` which can be used as `%BUILD_OUTPUT_PATH%:release` to show the
output path of a specific build configuration
- Refactor CI templates to support dynamic build targets
- Added template `phpexe` & `phpgz` for generating executable binaries and compressed executables for the project
### Changed
- Refactor phpmake template to support dynamic build targets
### Fixed
- ncc will now correctly handle package execution where the main unit is not defined in the package instead of
throwing an exception.
- Executable Compiler will now correctly create a directory if it does not exist when compiling a package using gcc
## [2.1.3] - 2024-09-27
This update introduces bug fixes
### Fixed
- Null-pointer fix
## [2.1.2] - 2024-09-27
This update introduces bug fixes
### Added
- Add getter methods for installation lifecycle steps
- Added pre-install & post-install execution unit handling
### Changed
- Updated DocStrings in PackageManager
### Fixed
- Fixed incorrect enum usage in RepositoryMenu
## [2.1.1] - 2024-09-24
This update introduces a couple of new features and quality of life improvements
### Added
- Added new PHP template `phpunit` for generating PhpUnit tests for the project
- Added new PHP template `phpmake` for generating a Makefile for the project
- Added new PHP template `phplib_full` That combines `phplib`, `phpmake` and `phpunit` templates
- Added new PHP template `phpcli_full` That combines `phpcli`, `phplib`, `phpmake` and `phpunit` templates
- Added new PHP template `phpci_github` that generates a Github CI workflow for the project
### Changed
- The template `phpcli` no longer includes a Makefile, instead use `phpmake` to generate a Makefile for the project
### Fixed
- Fixed incorrect enum usage with a logging method call.
## [2.1.0] - 2024-09-20
This update introduces a refactored code-base, code quality improvements, and better exception handling.
### Added
- Added Test unit tests/ncc/Objects/Package/ComponentTest.php
- Added Test unit tests/ncc/Utilities/ResolverTest.php
- Added Test unit tests/ncc/Utilities/SecurityTest.php
- Added Test unit tests/ncc/Utilities/ValidateTest.php
- Add support for runtime constants
### Changed
- Convert Versions constants to enum cases
- Update Scopes to enum and adjust scope checks
- Convert Runners class to enum with string cases
- Convert RegexPatterns constants to enum cases
- Convert ProjectTemplates constants to enum cases
- Convert PackageStructureVersions constants to enum cases
- Convert PackageStructure constants to enum cases
- Convert PackageDirectory constants to enum cases
- Convert LogLevel constants to enum cases
- Convert FileDescriptor constants to enum cases
- Convert ExceptionCodes constants to enum cases
- Convert ConsoleColors constants to enum cases
- Convert CompilerExtensions constants to enum cases
- Convert RepositoryType constants to enum cases
- Convert RepositoryResultType constants to enum cases
- Convert ProjectType constants to enum cases
- Convert HttpRequestType constants to enum cases
- Convert ComposerStabilityTypes constants to enum cases
- Convert ComposerPackageTypes constants to enum cases
- Convert ComponentDataType constants to enum cases
- Convert BuildOutputType constants to enum cases
- Convert AuthenticationType constants to enum cases
- Convert RuntimeConstants constants to enum cases
- Convert InstallConstants constants to enum cases
- Convert DateTimeConstants constants to enum cases
- Convert BuildConstants constants to enum cases
- Convert AssemblyConstants constants to enum cases
- Convert ProjectOptions constants to enum cases
- Convert InstallPackageOptions constants to enum cases
- Convert InitializeProjectOptions constants to enum cases
- Convert ComponentDecodeOptions constants to enum cases
- Convert BuildConfigurationValues constants to enum cases
- Convert BuildConfigurationOptions constants to enum cases
- Convert CompressionOptions constants to enum cases
- Convert PackageFlags constants to enum cases
- Convert NccBuildFlags constants to enum cases
- Convert ComponentFlags constants to enum cases
- Refactor flag handling to use PackageFlags enum directly
- Refactor checkLogLevel to correctly utilize LogLevel cases
- Refactor code to improve readability in Resolver.php
- Update PHP include paths in project configuration
- Refactor logging level checks to use LogLevel enum directly
- Refactor log level parsing with enum method
- Refactor log level checking to enum method
- Updated Symfony/Filesystem from version 6.3.1 to 7.1.2
- Refactor ProjectType handling
- Validate and enforce repository type enum usage
- Updated Composer/Semver to 3.4.3
- Rename 'semver' directory to 'Semver' in composer package
- Refactor project constants handling in NccCompiler
- Updated Symfony/Yaml to version 7.1.4
- Updated Symfony/Uid to version 7.1.4
- Updated Symfony/Process to version 7.1.3
- Updated Symfony/polyfill-ctype to version 1.31.0
- Updated Symfony/polyfill-mbstring to version 1.31.0
- Updated Symfony/polyfill-uuid to version 1.31.0
- Updated nikic/PhpParser to version 5.2.0
### Fixed
- Fixed Division by zero in PackageManager
- Fixed runner argument passing for ExecCommand
### Removed
- Removed EncoderType enum file, unused.
- Removed PackageStandardVersions.php
- Removed ConstantReferences.php
- Removed HttpStatusCodes.php
- Removed CompilerExtensionDefaultVersions.php
- Removed RemoteSourceType
- Removed DependencySourceType
- Removed BuiltinRemoteSourceType
- Removed RuntimeImportOptions
- Remove ComponentFileExtensions enum
- Remove unused import and redundant scope validation method
## [2.0.3] - 2023-10-17 ## [2.0.3] - 2023-10-17
This update includes enhanced support for PHP statements in AST traversal, a friendly CLI Progress Bar, and fixes This update includes enhanced support for PHP statements in AST traversal, a friendly CLI Progress Bar, and fixes
@ -184,7 +20,7 @@ The changes improve the system's efficiency, error resilience, and user experien
### Fixed ### Fixed
- When finding package versions in the package lock, ncc will try to find a satisfying version rather than the exact - When finding package versions in the package lock, ncc will try to find a satisfying version rather than the exact
version, this is to prevent[CHANGELOG.md](CHANGELOG.md) errors when the package lock contains a version that is not available in the repository. version, this is to prevent errors when the package lock contains a version that is not available in the repository.
- Fixed issue when registering ncc's extension, when using the INSTALLER, the installation path used in the process - Fixed issue when registering ncc's extension, when using the INSTALLER, the installation path used in the process
appears to be incorrect, added a optional parameter to the `registerExtension` method to allow the installer to pass appears to be incorrect, added a optional parameter to the `registerExtension` method to allow the installer to pass
the correct installation path. the correct installation path.

View file

@ -18,7 +18,7 @@ DEBIAN_PACKAGE_BUILD_PATH := $(BUILD_PATH)/ncc_$(BUILD_VERSION)_all.deb
# List of paths for autoloading # List of paths for autoloading
AUTOLOAD_PATHS := $(addprefix $(SRC_PATH)/ncc/ThirdParty/, \ AUTOLOAD_PATHS := $(addprefix $(SRC_PATH)/ncc/ThirdParty/, \
composer/Semver \ composer/semver \
defuse/php-encryption \ defuse/php-encryption \
jelix/version \ jelix/version \
nikic/PhpParser \ nikic/PhpParser \

View file

@ -1,9 +0,0 @@
<?php
$autoload_path = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'autoload.php';
if(!file_exists($autoload_path))
{
throw new Exception("Autoload file not found");
}
require $autoload_path;

View file

@ -1,11 +0,0 @@
<phpunit bootstrap="bootstrap.php">
<testsuites>
<testsuite name="ncc Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<php>
<ini name="error_reporting" value="-1"/>
<server name="KERNEL_DIR" value="app/"/>
</php>
</phpunit>

View file

@ -13,7 +13,7 @@
$third_party_path = __DIR__ . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR; $third_party_path = __DIR__ . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR;
$target_files = [ $target_files = [
__DIR__ . DIRECTORY_SEPARATOR . 'autoload_spl.php', __DIR__ . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'composer' . DIRECTORY_SEPARATOR . 'Semver' . DIRECTORY_SEPARATOR . 'autoload_spl.php', $third_party_path . 'composer' . DIRECTORY_SEPARATOR . 'semver' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'defuse' . DIRECTORY_SEPARATOR . 'php-encryption' . DIRECTORY_SEPARATOR . 'autoload_spl.php', $third_party_path . 'defuse' . DIRECTORY_SEPARATOR . 'php-encryption' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'jelix' . DIRECTORY_SEPARATOR . 'version' . DIRECTORY_SEPARATOR . 'autoload_spl.php', $third_party_path . 'jelix' . DIRECTORY_SEPARATOR . 'version' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'nikic' . DIRECTORY_SEPARATOR . 'PhpParser' . DIRECTORY_SEPARATOR . 'autoload_spl.php', $third_party_path . 'nikic' . DIRECTORY_SEPARATOR . 'PhpParser' . DIRECTORY_SEPARATOR . 'autoload_spl.php',

View file

@ -2,7 +2,7 @@ Package: ncc
Source: ncc Source: ncc
Section: devel Section: devel
Priority: optional Priority: optional
Version: 2.0.4 Version: 2.0.3
Maintainer: netkas <netkas@nosial.net> Maintainer: netkas <netkas@nosial.net>
Build-Depends: debhelper-compat (= 13) Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.5.1 Standards-Version: 4.5.1

View file

@ -75,7 +75,7 @@
if($output_path !== null) if($output_path !== null)
{ {
$options[BuildConfigurationOptions::OUTPUT_FILE->value] = $output_path; $options[BuildConfigurationOptions::OUTPUT_FILE] = $output_path;
} }
// Load the project // Load the project
@ -92,7 +92,7 @@
// Build the project // Build the project
try try
{ {
$build_configuration = $args['config'] ?? $args['c'] ?? BuildConfigurationValues::DEFAULT->value; $build_configuration = $args['config'] ?? $args['c'] ?? BuildConfigurationValues::DEFAULT;
$output = $project_manager->build($build_configuration, $options); $output = $project_manager->build($build_configuration, $options);
} }
catch (Exception $e) catch (Exception $e)

View file

@ -24,11 +24,9 @@
use Exception; use Exception;
use ncc\Classes\Runtime; use ncc\Classes\Runtime;
use ncc\CLI\Main;
use ncc\Objects\CliHelpSection; use ncc\Objects\CliHelpSection;
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\Functions; use ncc\Utilities\Functions;
use ncc\Utilities\Resolver;
class ExecCommand class ExecCommand
{ {
@ -42,12 +40,6 @@
{ {
$package = $args['package'] ?? null; $package = $args['package'] ?? null;
$version = $args['exec-version'] ?? 'latest'; $version = $args['exec-version'] ?? 'latest';
$program_arguments = [];
if(isset($args['exec-args']))
{
$program_arguments = Resolver::splitArguments(Main::getRawArgs(), '--exec-args');
}
if($package === null) if($package === null)
{ {
@ -66,7 +58,7 @@
try try
{ {
return Runtime::execute($package_name, $program_arguments); return Runtime::execute($package_name);
} }
catch(Exception $e) catch(Exception $e)
{ {

View file

@ -50,12 +50,7 @@
private static $args; private static $args;
/** /**
* @var array * @var string|null
*/
private static $raw_args;
/**
* @var LogLevel|null
*/ */
private static $log_level; private static $log_level;
@ -68,7 +63,6 @@
public static function start(array $argv): int public static function start(array $argv): int
{ {
self::$args = Resolver::parseArguments(implode(' ', $argv)); self::$args = Resolver::parseArguments(implode(' ', $argv));
self::$raw_args = $argv;
if(!isset(self::$args['ncc-cli'])) if(!isset(self::$args['ncc-cli']))
{ {
@ -97,14 +91,30 @@
if(isset(self::$args['l']) || isset(self::$args['log-level'])) if(isset(self::$args['l']) || isset(self::$args['log-level']))
{ {
self::$log_level = LogLevel::fromOrDefault(strtolower(self::$args['l'] ?? self::$args['log-level'])); switch(strtolower(self::$args['l'] ?? self::$args['log-level']))
{
case LogLevel::SILENT:
case LogLevel::FATAL:
case LogLevel::ERROR:
case LogLevel::WARNING:
case LogLevel::INFO:
case LogLevel::DEBUG:
case LogLevel::VERBOSE:
self::$log_level = strtolower(self::$args['l'] ?? self::$args['log-level']);
break;
default:
Console::outWarning('Unknown log level: ' . (self::$args['l'] ?? self::$args['log-level']) . ', using \'info\'');
self::$log_level = LogLevel::INFO;
break;
}
} }
else else
{ {
self::$log_level = LogLevel::INFO; self::$log_level = LogLevel::INFO;
} }
if(self::$log_level->checkLogLevel(LogLevel::DEBUG)) if(Resolver::checkLogLevel(self::$log_level, LogLevel::DEBUG))
{ {
Console::outDebug('Debug logging enabled'); Console::outDebug('Debug logging enabled');
@ -115,12 +125,12 @@
Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES))); Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES)));
} }
if(in_array(NccBuildFlags::UNSTABLE->value, NCC_VERSION_FLAGS, true)) if(in_array(NccBuildFlags::UNSTABLE, NCC_VERSION_FLAGS, true))
{ {
Console::outWarning('This is an unstable build of ncc, expect some features to not work as expected'); Console::outWarning('This is an unstable build of ncc, expect some features to not work as expected');
} }
if(in_array(NccBuildFlags::BETA->value, NCC_VERSION_FLAGS, true)) if(in_array(NccBuildFlags::BETA, NCC_VERSION_FLAGS, true))
{ {
Console::outWarning('This is a beta build of ncc, expect some features to not work as expected'); Console::outWarning('This is a beta build of ncc, expect some features to not work as expected');
} }
@ -220,19 +230,9 @@
} }
/** /**
* Returns the raw arguments passed to ncc * @return string
*
* @return array
*/ */
public static function getRawArgs(): array public static function getLogLevel(): string
{
return self::$raw_args;
}
/**
* @return LogLevel
*/
public static function getLogLevel(): LogLevel
{ {
if(self::$log_level === null) if(self::$log_level === null)
{ {

View file

@ -101,7 +101,7 @@
if(isset($args['v'])) if(isset($args['v']))
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('Insufficient permissions, cannot modify configuration values', true, 1); Console::outError('Insufficient permissions, cannot modify configuration values', true, 1);
return 1; return 1;

View file

@ -187,7 +187,7 @@
{ {
$ResolvedScope = Resolver::resolveScope(); $ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::SYSTEM->value) if($ResolvedScope !== Scopes::SYSTEM)
{ {
Console::outError('Insufficient permissions to add entries'); Console::outError('Insufficient permissions to add entries');
} }
@ -313,7 +313,7 @@
{ {
$ResolvedScope = Resolver::resolveScope(); $ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::SYSTEM->value) if($ResolvedScope !== Scopes::SYSTEM)
{ {
Console::outError('Insufficient permissions to remove entries'); Console::outError('Insufficient permissions to remove entries');
} }

View file

@ -132,7 +132,7 @@
*/ */
private static function installPackage(array $args): int private static function installPackage(array $args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You cannot install packages in a user scope, please run this command as root', true, 1); Console::outError('You cannot install packages in a user scope, please run this command as root', true, 1);
return 1; return 1;
@ -155,22 +155,17 @@
if(isset($args['reinstall'])) if(isset($args['reinstall']))
{ {
$options[InstallPackageOptions::REINSTALL->value] = true; $options[InstallPackageOptions::REINSTALL] = true;
} }
if(isset($args['prefer-static']) || isset($args['static'])) if(isset($args['prefer-static']) || isset($args['static']))
{ {
$options[InstallPackageOptions::PREFER_STATIC->value] = true; $options[InstallPackageOptions::PREFER_STATIC] = true;
} }
if(isset($args['skip-dependencies'])) if(isset($args['skip-dependencies']))
{ {
$options[InstallPackageOptions::SKIP_DEPENDENCIES->value] = true; $options[InstallPackageOptions::SKIP_DEPENDENCIES] = true;
}
if(isset($args['build-source']))
{
$options[InstallPackageOptions::BUILD_SOURCE->value] = true;
} }
if($authentication !== null) if($authentication !== null)
@ -204,7 +199,7 @@
$authentication_entry = $entry->getPassword(); $authentication_entry = $entry->getPassword();
} }
if(preg_match(RegexPatterns::REMOTE_PACKAGE->value, $package) === 1) if(preg_match(RegexPatterns::REMOTE_PACKAGE, $package) === 1)
{ {
$package_input = RemotePackageInput::fromString($package); $package_input = RemotePackageInput::fromString($package);
@ -393,7 +388,7 @@
*/ */
private static function uninstallPackage($args): int private static function uninstallPackage($args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You cannot uninstall packages in a user scope, please run this command as root', true, 1); Console::outError('You cannot uninstall packages in a user scope, please run this command as root', true, 1);
return 1; return 1;
@ -424,7 +419,7 @@
*/ */
private static function uninstallAllPackages(array $args): int private static function uninstallAllPackages(array $args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You cannot uninstall all packages in a user scope, please run this command as root', true, 1); Console::outError('You cannot uninstall all packages in a user scope, please run this command as root', true, 1);
return 1; return 1;
@ -460,7 +455,7 @@
*/ */
private static function fixBrokenPackages(array $args): int private static function fixBrokenPackages(array $args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You cannot fix broken packages in a user scope, please run this command as root', true, 1); Console::outError('You cannot fix broken packages in a user scope, please run this command as root', true, 1);
return 1; return 1;
@ -565,7 +560,6 @@
new CliHelpSection(['install', '-p', '--skip-dependencies'], 'Installs a specified ncc package but skips the installation of dependencies'), 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(['install', '-p', '--reinstall'], 'Installs a specified ncc package, reinstall if already installed'),
new CliHelpSection(['install', '--prefer-static', '--static'], 'Installs a static version of the package from the remote repository if available'), new CliHelpSection(['install', '--prefer-static', '--static'], 'Installs a static version of the package from the remote repository if available'),
new CliHelpSection(['install', '--build-source'], 'Forces ncc to build the packages from source rather than trying to use a pre-built binary'),
new CliHelpSection(['uninstall', '--package', '-p'], 'Uninstalls a specified ncc package'), 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', '--package', '-p', '--version', '-v'], 'Uninstalls a specified ncc package version'),
new CliHelpSection(['uninstall-all'], 'Uninstalls all packages'), new CliHelpSection(['uninstall-all'], 'Uninstalls all packages'),

View file

@ -23,7 +23,6 @@
namespace ncc\CLI\Management; namespace ncc\CLI\Management;
use Exception; use Exception;
use ncc\Enums\CompilerExtensions;
use ncc\Enums\ProjectTemplates; use ncc\Enums\ProjectTemplates;
use ncc\Enums\Scopes; use ncc\Enums\Scopes;
use ncc\Managers\CredentialManager; use ncc\Managers\CredentialManager;
@ -103,12 +102,7 @@
if(isset($args['ext'])) if(isset($args['ext']))
{ {
$compiler_extension = CompilerExtensions::tryFrom($args['ext']); $compiler_extension = $args['ext'];
if($compiler_extension === null)
{
Console::outError('Invalid compiler extension, please specify a valid compiler extension', true, 1);
return 1;
}
} }
else else
{ {
@ -140,7 +134,7 @@
*/ */
private static function installProject(array $args): int private static function installProject(array $args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You cannot install packages in a user scope, please run this command as root', true, 1); Console::outError('You cannot install packages in a user scope, please run this command as root', true, 1);
return 1; return 1;
@ -298,9 +292,9 @@
} }
Console::out(PHP_EOL . 'Available Templates:'); Console::out(PHP_EOL . 'Available Templates:');
foreach(ProjectTemplates::cases() as $template) foreach(ProjectTemplates::ALL as $template)
{ {
Console::out(' ' . $template->value); Console::out(' ' . $template);
} }
return 0; return 0;

View file

@ -25,7 +25,6 @@
use Exception; use Exception;
use ncc\Enums\ConsoleColors; use ncc\Enums\ConsoleColors;
use ncc\Enums\Scopes; use ncc\Enums\Scopes;
use ncc\Enums\Types\RepositoryType;
use ncc\Managers\RepositoryManager; use ncc\Managers\RepositoryManager;
use ncc\Objects\CliHelpSection; use ncc\Objects\CliHelpSection;
use ncc\Objects\RepositoryConfiguration; use ncc\Objects\RepositoryConfiguration;
@ -119,7 +118,7 @@
$output = sprintf('%s (%s) [%s]', $output = sprintf('%s (%s) [%s]',
$source->getName(), $source->getName(),
Console::formatColor($source->getHost(), ConsoleColors::GREEN), Console::formatColor($source->getHost(), ConsoleColors::GREEN),
Console::formatColor($source->getType()->value, ConsoleColors::YELLOW) Console::formatColor($source->getType(), ConsoleColors::YELLOW)
); );
if(!$source->isSsl()) if(!$source->isSsl())
@ -142,7 +141,7 @@
*/ */
private static function addEntry(array $args): int private static function addEntry(array $args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You must be running as root to add a new repository', true, 1); Console::outError('You must be running as root to add a new repository', true, 1);
return 1; return 1;
@ -165,13 +164,6 @@
return 1; return 1;
} }
$parsed_type = RepositoryType::tryFrom($type);
if($parsed_type === null)
{
Console::outError(sprintf('Unknown repository type \'%s\'.', $type), true, 1);
return 1;
}
if($host === null) if($host === null)
{ {
Console::outError(sprintf('Missing required argument \'%s\'.', 'host'), true, 1); Console::outError(sprintf('Missing required argument \'%s\'.', 'host'), true, 1);
@ -180,7 +172,7 @@
try try
{ {
(new RepositoryManager())->addRepository(new RepositoryConfiguration($name, $host, $parsed_type, $ssl)); (new RepositoryManager())->addRepository(new RepositoryConfiguration($name, $host, $type, $ssl));
} }
catch(Exception $e) catch(Exception $e)
{ {
@ -238,7 +230,7 @@
*/ */
private static function removeEntry(array $args): int private static function removeEntry(array $args): int
{ {
if(Resolver::resolveScope() !== Scopes::SYSTEM->value) if(Resolver::resolveScope() !== Scopes::SYSTEM)
{ {
Console::outError('You must be running as root to remove a repository', true, 1); Console::outError('You must be running as root to remove a repository', true, 1);
return 1; return 1;

View file

@ -31,7 +31,6 @@
use ncc\Classes\PhpExtension\PhpRunner; use ncc\Classes\PhpExtension\PhpRunner;
use ncc\Enums\Runners; use ncc\Enums\Runners;
use ncc\Exceptions\ConfigurationException; use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IntegrityException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException; use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException; use ncc\Exceptions\OperationException;
@ -55,11 +54,11 @@
{ {
$bin = match($unit->getExecutionPolicy()->getRunner()) $bin = match($unit->getExecutionPolicy()->getRunner())
{ {
Runners::PHP->value => (new ExecutableFinder())->find('php'), Runners::PHP => (new ExecutableFinder())->find('php'),
Runners::BASH->value => (new ExecutableFinder())->find('bash'), Runners::BASH => (new ExecutableFinder())->find('bash'),
Runners::PYTHON->value => (new ExecutableFinder())->find('python'), Runners::PYTHON => (new ExecutableFinder())->find('python'),
Runners::LUA->value => (new ExecutableFinder())->find('lua'), Runners::LUA => (new ExecutableFinder())->find('lua'),
Runners::PERL->value => (new ExecutableFinder())->find('perl'), Runners::PERL => (new ExecutableFinder())->find('perl'),
default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $unit->getExecutionPolicy()->getName(), $unit->getExecutionPolicy()->getRunner())) default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $unit->getExecutionPolicy()->getName(), $unit->getExecutionPolicy()->getRunner()))
}; };
@ -77,19 +76,11 @@
{ {
$process->setTimeout($unit->getExecutionPolicy()->getExecute()->getTimeout()); $process->setTimeout($unit->getExecutionPolicy()->getExecute()->getTimeout());
} }
else
{
$process->setTimeout(null);
}
if($unit->getExecutionPolicy()->getExecute()->getIdleTimeout() !== null) if($unit->getExecutionPolicy()->getExecute()->getIdleTimeout() !== null)
{ {
$process->setIdleTimeout($unit->getExecutionPolicy()->getExecute()->getIdleTimeout()); $process->setIdleTimeout($unit->getExecutionPolicy()->getExecute()->getIdleTimeout());
} }
else
{
$process->setIdleTimeout(null);
}
return $process; return $process;
} }
@ -118,8 +109,8 @@
$execution_unit = ExecutionUnit::fromArray(ZiProto::decode(IO::fread($unit_path))); $execution_unit = ExecutionUnit::fromArray(ZiProto::decode(IO::fread($unit_path)));
return match ($execution_unit->getExecutionPolicy()->getRunner()) return match ($execution_unit->getExecutionPolicy()->getRunner())
{ {
Runners::PHP->value => PhpRunner::executeUnit($execution_unit, $args), Runners::PHP => PhpRunner::executeUnit($execution_unit, $args),
Runners::BASH->value => BashRunner::executeUnit($execution_unit, $args), Runners::BASH => BashRunner::executeUnit($execution_unit, $args),
default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())), default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())),
}; };
} }
@ -138,7 +129,6 @@
* @return int * @return int
* @throws ConfigurationException * @throws ConfigurationException
* @throws OperationException * @throws OperationException
* @throws IntegrityException
*/ */
public static function executeFromPackage(PackageReader $package_reader, string $policy_name, array $args=[]): int public static function executeFromPackage(PackageReader $package_reader, string $policy_name, array $args=[]): int
{ {
@ -148,8 +138,8 @@
{ {
return match ($execution_unit->getExecutionPolicy()->getRunner()) return match ($execution_unit->getExecutionPolicy()->getRunner())
{ {
Runners::PHP->value => PhpRunner::executeUnit($execution_unit, $args, false), Runners::PHP => PhpRunner::executeUnit($execution_unit, $args, false),
Runners::BASH->value => BashRunner::executeUnit($execution_unit, $args), Runners::BASH => BashRunner::executeUnit($execution_unit, $args),
default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())), default => throw new NotSupportedException(sprintf('The execution policy %s is not supported because it uses the %s runner', $execution_unit->getExecutionPolicy()->getName(), $execution_unit->getExecutionPolicy()->getRunner())),
}; };
} }

View file

@ -39,7 +39,6 @@
use ncc\Objects\Vault\Password\AccessToken; use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword; use ncc\Objects\Vault\Password\UsernamePassword;
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache; use ncc\Utilities\RuntimeCache;
use RuntimeException; use RuntimeException;
@ -48,7 +47,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST->value, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult
{ {
try try
{ {
@ -65,7 +64,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST->value, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult
{ {
return self::getReleasePackage($repository, $vendor, $project, $version, $authentication, $options); return self::getReleasePackage($repository, $vendor, $project, $version, $authentication, $options);
} }
@ -98,21 +97,15 @@
'User-Agent: ncc' 'User-Agent: ncc'
]; ];
if($authentication !== null) if($authentication !== null)
{ {
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -169,7 +162,7 @@
*/ */
private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication=null): RepositoryResult private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication=null): RepositoryResult
{ {
if($tag === Versions::LATEST->value) if($tag === Versions::LATEST)
{ {
$tag = self::getLatestTag($repository, $group, $project, $authentication); $tag = self::getLatestTag($repository, $group, $project, $authentication);
} }
@ -193,17 +186,10 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_URL => $endpoint, CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -212,11 +198,11 @@
if(isset($response['zipball_url'])) if(isset($response['zipball_url']))
{ {
$result = new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE->value, $tag); $result = new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE, $tag);
} }
elseif(isset($response['tarball_url'])) elseif(isset($response['tarball_url']))
{ {
$result = new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE->value, $tag); $result = new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE, $tag);
} }
else else
{ {
@ -260,17 +246,10 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_URL => $endpoint, CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -328,7 +307,7 @@
private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null, array $options=[]): RepositoryResult private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null, array $options=[]): RepositoryResult
{ {
/** @noinspection DuplicatedCode */ /** @noinspection DuplicatedCode */
if($release === Versions::LATEST->value) if($release === Versions::LATEST)
{ {
$release = self::getLatestRelease($repository, $group, $project, $authentication); $release = self::getLatestRelease($repository, $group, $project, $authentication);
} }
@ -358,17 +337,10 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_URL => $endpoint, CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -383,7 +355,7 @@
$release, $group, $project)); $release, $group, $project));
} }
$static_preferred = isset($options[InstallPackageOptions::PREFER_STATIC->value]); $static_preferred = isset($options[InstallPackageOptions::PREFER_STATIC]);
$preferred_asset = null; $preferred_asset = null;
$fallback_asset = null; $fallback_asset = null;
@ -407,7 +379,7 @@
if($asset_url) if($asset_url)
{ {
$result = new RepositoryResult($asset_url, RepositoryResultType::PACKAGE->value, $release); $result = new RepositoryResult($asset_url, RepositoryResultType::PACKAGE, $release);
RuntimeCache::set($endpoint, $result); RuntimeCache::set($endpoint, $result);
return $result; return $result;
@ -437,7 +409,7 @@
private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{ {
/** @noinspection DuplicatedCode */ /** @noinspection DuplicatedCode */
if ($release === Versions::LATEST->value) if ($release === Versions::LATEST)
{ {
$release = self::getLatestRelease($repository, $group, $project, $authentication); $release = self::getLatestRelease($repository, $group, $project, $authentication);
} }
@ -461,17 +433,10 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_URL => $endpoint, CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -480,11 +445,11 @@
if(isset($response['zipball_url'])) if(isset($response['zipball_url']))
{ {
$results = new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE->value, $release); $results = new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE, $release);
} }
elseif(isset($response['tarball_url'])) elseif(isset($response['tarball_url']))
{ {
$results = new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE->value, $release); $results = new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE, $release);
} }
else else
{ {
@ -515,7 +480,7 @@
break; break;
} }
throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()->value)); throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()));
case AuthenticationType::USERNAME_PASSWORD: case AuthenticationType::USERNAME_PASSWORD:
if($authentication instanceof UsernamePassword) if($authentication instanceof UsernamePassword)
@ -524,7 +489,7 @@
break; break;
} }
throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()->value)); throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()));
} }
return $headers; return $headers;

View file

@ -47,7 +47,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST->value, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult
{ {
try try
{ {
@ -64,7 +64,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST->value, ?AuthenticationType $authentication = null, array $options=[]): RepositoryResult public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null, array $options=[]): RepositoryResult
{ {
return self::getReleasePackage($repository, $vendor, $project, $version, $authentication, $options); return self::getReleasePackage($repository, $vendor, $project, $version, $authentication, $options);
} }
@ -104,7 +104,7 @@
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -161,7 +161,7 @@
*/ */
private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication = null): RepositoryResult private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication = null): RepositoryResult
{ {
if($tag === Versions::LATEST->value) if($tag === Versions::LATEST)
{ {
$tag = self::getLatestTag($repository, $group, $project, $authentication); $tag = self::getLatestTag($repository, $group, $project, $authentication);
} }
@ -186,7 +186,7 @@
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_NOBODY => true, CURLOPT_NOBODY => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers, CURLOPT_HTTPHEADER => $headers,
CURLOPT_FOLLOWLOCATION => true CURLOPT_FOLLOWLOCATION => true
]); ]);
@ -207,7 +207,7 @@
throw new NetworkException(sprintf('Server responded with HTTP code %s when getting tag archive for %s/%s/%s', $http_code, $group, $project, $tag)); throw new NetworkException(sprintf('Server responded with HTTP code %s when getting tag archive for %s/%s/%s', $http_code, $group, $project, $tag));
} }
$result = new RepositoryResult(curl_getinfo($curl, CURLINFO_EFFECTIVE_URL), RepositoryResultType::SOURCE->value, $tag); $result = new RepositoryResult(curl_getinfo($curl, CURLINFO_EFFECTIVE_URL), RepositoryResultType::SOURCE, $tag);
curl_close($curl); curl_close($curl);
RuntimeCache::set($endpoint, $result); RuntimeCache::set($endpoint, $result);
@ -249,7 +249,7 @@
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -307,7 +307,7 @@
private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null, array $options=[]): RepositoryResult private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null, array $options=[]): RepositoryResult
{ {
/** @noinspection DuplicatedCode */ /** @noinspection DuplicatedCode */
if($release === Versions::LATEST->value) if($release === Versions::LATEST)
{ {
$release = self::getLatestRelease($repository, $group, $project, $authentication); $release = self::getLatestRelease($repository, $group, $project, $authentication);
} }
@ -331,7 +331,7 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_HTTPHEADER => $headers]); curl_setopt_array($curl, [CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET, CURLOPT_HTTPHEADER => $headers]);
Console::outDebug(sprintf('Fetching release package for %s/%s/%s from %s', $group, $project, $release, $endpoint)); Console::outDebug(sprintf('Fetching release package for %s/%s/%s from %s', $group, $project, $release, $endpoint));
$response = self::processHttpResponse($curl, $group, $project); $response = self::processHttpResponse($curl, $group, $project);
@ -341,7 +341,7 @@
throw new NetworkException(sprintf('Failed to get release package for %s/%s/%s: No assets found', $group, $project, $release)); throw new NetworkException(sprintf('Failed to get release package for %s/%s/%s: No assets found', $group, $project, $release));
} }
$static_preferred = isset($options[InstallPackageOptions::PREFER_STATIC->value]); $static_preferred = isset($options[InstallPackageOptions::PREFER_STATIC]);
$preferred_asset = null; $preferred_asset = null;
$fallback_asset = null; $fallback_asset = null;
@ -363,7 +363,7 @@
{ {
$asset_url = $target_asset['browser_download_url']; $asset_url = $target_asset['browser_download_url'];
$result = new RepositoryResult($asset_url, RepositoryResultType::PACKAGE->value, $release); $result = new RepositoryResult($asset_url, RepositoryResultType::PACKAGE, $release);
RuntimeCache::set($endpoint, $result); RuntimeCache::set($endpoint, $result);
return $result; return $result;
@ -389,7 +389,7 @@
private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication = null): RepositoryResult private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication = null): RepositoryResult
{ {
/** @noinspection DuplicatedCode */ /** @noinspection DuplicatedCode */
if($release === Versions::LATEST->value) if($release === Versions::LATEST)
{ {
$release = self::getLatestRelease($repository, $group, $project, $authentication); $release = self::getLatestRelease($repository, $group, $project, $authentication);
} }
@ -415,7 +415,7 @@
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -425,11 +425,11 @@
if(isset($response['zipball_url'])) if(isset($response['zipball_url']))
{ {
$result = new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE->value, $release); $result = new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE, $release);
} }
elseif(isset($response['tarball_url'])) elseif(isset($response['tarball_url']))
{ {
$result = new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE->value, $release); $result = new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE, $release);
} }
else else
{ {
@ -459,7 +459,7 @@
$headers[] = 'Authorization: Bearer ' . $authentication->getAccessToken(); $headers[] = 'Authorization: Bearer ' . $authentication->getAccessToken();
break; break;
} }
throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()->value)); throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()));
case AuthenticationType::USERNAME_PASSWORD: case AuthenticationType::USERNAME_PASSWORD:
if($authentication instanceof UsernamePassword) if($authentication instanceof UsernamePassword)
@ -468,7 +468,7 @@
break; break;
} }
throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()->value)); throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()));
} }
return $headers; return $headers;

View file

@ -39,7 +39,6 @@
use ncc\Objects\Vault\Password\AccessToken; use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword; use ncc\Objects\Vault\Password\UsernamePassword;
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache; use ncc\Utilities\RuntimeCache;
use RuntimeException; use RuntimeException;
@ -48,7 +47,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST->value, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult
{ {
try try
{ {
@ -65,7 +64,7 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST->value, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null, array $options=[]): RepositoryResult
{ {
return self::getReleasePackage($repository, $vendor, $project, $version, $authentication, $options); return self::getReleasePackage($repository, $vendor, $project, $version, $authentication, $options);
} }
@ -104,17 +103,10 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_URL => $endpoint, CURLOPT_URL => $endpoint,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -172,7 +164,7 @@
*/ */
private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication=null): RepositoryResult private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication=null): RepositoryResult
{ {
if($tag === Versions::LATEST->value) if($tag === Versions::LATEST)
{ {
$tag = self::getLatestTag($repository, $group, $project, $authentication); $tag = self::getLatestTag($repository, $group, $project, $authentication);
} }
@ -195,17 +187,10 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_NOBODY => true, CURLOPT_NOBODY => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers, CURLOPT_HTTPHEADER => $headers,
CURLOPT_FOLLOWLOCATION => true CURLOPT_FOLLOWLOCATION => true
]); ]);
@ -225,7 +210,7 @@
throw new NetworkException(sprintf('Server responded with HTTP code %s when getting tag archive for %s/%s/%s', $http_code, $group, $project, $tag)); throw new NetworkException(sprintf('Server responded with HTTP code %s when getting tag archive for %s/%s/%s', $http_code, $group, $project, $tag));
} }
$results = new RepositoryResult(curl_getinfo($curl, CURLINFO_EFFECTIVE_URL), RepositoryResultType::SOURCE->value, $tag); $results = new RepositoryResult(curl_getinfo($curl, CURLINFO_EFFECTIVE_URL), RepositoryResultType::SOURCE, $tag);
RuntimeCache::set($endpoint, $results); RuntimeCache::set($endpoint, $results);
return $results; return $results;
@ -265,16 +250,9 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -330,7 +308,7 @@
*/ */
private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null, array $options=[]): RepositoryResult private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null, array $options=[]): RepositoryResult
{ {
if($release === Versions::LATEST->value) if($release === Versions::LATEST)
{ {
$release = self::getLatestRelease($repository, $group, $project, $authentication); $release = self::getLatestRelease($repository, $group, $project, $authentication);
} }
@ -355,21 +333,14 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
$response = self::processHttpResponse($curl, $group, $project); $response = self::processHttpResponse($curl, $group, $project);
$static_preferred = isset($options[InstallPackageOptions::PREFER_STATIC->value]); $static_preferred = isset($options[InstallPackageOptions::PREFER_STATIC]);
$preferred_asset = null; $preferred_asset = null;
$fallback_asset = null; $fallback_asset = null;
@ -393,7 +364,7 @@
if ($asset_url) if ($asset_url)
{ {
$result = new RepositoryResult($asset_url, RepositoryResultType::PACKAGE->value, $release); $result = new RepositoryResult($asset_url, RepositoryResultType::PACKAGE, $release);
RuntimeCache::set($endpoint, $result); RuntimeCache::set($endpoint, $result);
return $result; return $result;
@ -422,7 +393,7 @@
private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{ {
/** @noinspection DuplicatedCode */ /** @noinspection DuplicatedCode */
if($release === Versions::LATEST->value) if($release === Versions::LATEST)
{ {
$release = self::getLatestRelease($repository, $group, $project, $authentication); $release = self::getLatestRelease($repository, $group, $project, $authentication);
} }
@ -447,16 +418,9 @@
$headers = self::injectAuthentication($authentication, $curl, $headers); $headers = self::injectAuthentication($authentication, $curl, $headers);
} }
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -476,11 +440,11 @@
if($asset['format'] === 'zip') if($asset['format'] === 'zip')
{ {
$results = new RepositoryResult($asset['url'], RepositoryResultType::SOURCE->value, $release); $results = new RepositoryResult($asset['url'], RepositoryResultType::SOURCE, $release);
} }
elseif($asset['format'] === 'tar') elseif($asset['format'] === 'tar')
{ {
$results = new RepositoryResult($asset['url'], RepositoryResultType::SOURCE->value, $release); $results = new RepositoryResult($asset['url'], RepositoryResultType::SOURCE, $release);
} }
else else
{ {
@ -507,23 +471,23 @@
{ {
switch($authentication->getAuthenticationType()) switch($authentication->getAuthenticationType())
{ {
case AuthenticationType::ACCESS_TOKEN->value: case AuthenticationType::ACCESS_TOKEN:
if($authentication instanceof AccessToken) if($authentication instanceof AccessToken)
{ {
$headers[] = 'Private-Token: ' . $authentication->getAccessToken(); $headers[] = 'Private-Token: ' . $authentication->getAccessToken();
break; break;
} }
throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()->value)); throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()));
case AuthenticationType::USERNAME_PASSWORD->value: case AuthenticationType::USERNAME_PASSWORD:
if($authentication instanceof UsernamePassword) if($authentication instanceof UsernamePassword)
{ {
curl_setopt($curl, CURLOPT_USERPWD, $authentication->getUsername() . ':' . $authentication->getPassword()); curl_setopt($curl, CURLOPT_USERPWD, $authentication->getUsername() . ':' . $authentication->getPassword());
break; break;
} }
throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()->value)); throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()));
} }
return $headers; return $headers;

View file

@ -22,10 +22,8 @@
namespace ncc\Classes\NccExtension; namespace ncc\Classes\NccExtension;
use InvalidArgumentException;
use ncc\Enums\SpecialConstants\BuildConstants; use ncc\Enums\SpecialConstants\BuildConstants;
use ncc\Enums\SpecialConstants\DateTimeConstants; use ncc\Enums\SpecialConstants\DateTimeConstants;
use ncc\Enums\SpecialConstants\GeneralConstants;
use ncc\Enums\SpecialConstants\InstallConstants; use ncc\Enums\SpecialConstants\InstallConstants;
use ncc\Enums\SpecialConstants\AssemblyConstants; use ncc\Enums\SpecialConstants\AssemblyConstants;
use ncc\Enums\SpecialConstants\RuntimeConstants; use ncc\Enums\SpecialConstants\RuntimeConstants;
@ -49,67 +47,6 @@
$input = self::compileBuildConstants($input); $input = self::compileBuildConstants($input);
$input = self::compileDateTimeConstants($input, time()); $input = self::compileDateTimeConstants($input, time());
$input = self::compileRuntimeConstants($input); $input = self::compileRuntimeConstants($input);
$input = self::compileGeneralConstants($input, $project_configuration);
return $input;
}
/**
* Compiles general constants from the given input string based on the provided project configuration.
*
* @param string|null $input The input string containing constants to be compiled.
* @param ProjectConfiguration $project_configuration The project configuration used to resolve constants.
* @return string|null The input string with constants replaced, or null if the input was null.
*/
public static function compileGeneralConstants(?string $input, ProjectConfiguration $project_configuration): ?string
{
if ($input === null)
{
return null;
}
// Replace %DEFAULT_BUILD_CONFIGURATION%
$input = str_replace(
[
GeneralConstants::DEFAULT_BUILD_CONFIGURATION->value
],
[
$project_configuration->getBuild()->getDefaultConfiguration()
],
$input
);
if (str_starts_with($input, GeneralConstants::BUILD_OUTPUT_PATH->value))
{
$build_name = null;
if (preg_match('/' . preg_quote(GeneralConstants::BUILD_OUTPUT_PATH->value, '/') . ':(\S+)/', $input, $matches))
{
$build_name = $matches[1];
}
if ($build_name === null)
{
Console::outWarning(sprintf("Cannot compile constant %s because it's not valid, usage: %%CONSTANT%%:<name>", $input));
}
else
{
try
{
$output_path = $project_configuration->getBuild()->getBuildConfiguration($build_name)->getOutput();
$input = preg_replace(
'/' . preg_quote(GeneralConstants::BUILD_OUTPUT_PATH->value, '/') . ':\S+/',
$output_path,
$input,
1
);
}
catch (InvalidArgumentException $e)
{
Console::outError(sprintf("Cannot compile constant %s because it does not point to an existing build configuration name", $input));
}
}
}
return $input; return $input;
} }
@ -130,10 +67,10 @@
$input = str_replace( $input = str_replace(
[ [
AssemblyConstants::ASSEMBLY_NAME->value, AssemblyConstants::ASSEMBLY_NAME,
AssemblyConstants::ASSEMBLY_PACKAGE->value, AssemblyConstants::ASSEMBLY_PACKAGE,
AssemblyConstants::ASSEMBLY_VERSION->value, AssemblyConstants::ASSEMBLY_VERSION,
AssemblyConstants::ASSEMBLY_UID->value, AssemblyConstants::ASSEMBLY_UID
], ],
[ [
$assembly->getName(), $assembly->getName(),
@ -144,27 +81,27 @@
if($assembly->getDescription() !== null) if($assembly->getDescription() !== null)
{ {
$input = str_replace(AssemblyConstants::ASSEMBLY_DESCRIPTION->value, $assembly->getDescription(), $input); $input = str_replace(AssemblyConstants::ASSEMBLY_DESCRIPTION, $assembly->getDescription(), $input);
} }
if($assembly->getCompany() !== null) if($assembly->getCompany() !== null)
{ {
$input = str_replace(AssemblyConstants::ASSEMBLY_COMPANY->value, $assembly->getCompany(), $input); $input = str_replace(AssemblyConstants::ASSEMBLY_COMPANY, $assembly->getCompany(), $input);
} }
if($assembly->getProduct() !== null) if($assembly->getProduct() !== null)
{ {
$input = str_replace(AssemblyConstants::ASSEMBLY_PRODUCT->value, $assembly->getProduct(), $input); $input = str_replace(AssemblyConstants::ASSEMBLY_PRODUCT, $assembly->getProduct(), $input);
} }
if($assembly->getCopyright() !== null) if($assembly->getCopyright() !== null)
{ {
$input = str_replace(AssemblyConstants::ASSEMBLY_COPYRIGHT->value, $assembly->getCopyright(), $input); $input = str_replace(AssemblyConstants::ASSEMBLY_COPYRIGHT, $assembly->getCopyright(), $input);
} }
if($assembly->getTrademark() !== null) if($assembly->getTrademark() !== null)
{ {
$input = str_replace(AssemblyConstants::ASSEMBLY_TRADEMARK->value, $assembly->getTrademark(), $input); $input = str_replace(AssemblyConstants::ASSEMBLY_TRADEMARK, $assembly->getTrademark(), $input);
} }
return $input; return $input;
} }
@ -184,10 +121,10 @@
return str_replace( return str_replace(
[ [
BuildConstants::COMPILE_TIMESTAMP->value, BuildConstants::COMPILE_TIMESTAMP,
BuildConstants::NCC_BUILD_VERSION->value, BuildConstants::NCC_BUILD_VERSION,
BuildConstants::NCC_BUILD_FLAGS->value, BuildConstants::NCC_BUILD_FLAGS,
BuildConstants::NCC_BUILD_BRANCH->value BuildConstants::NCC_BUILD_BRANCH
], ],
[ [
time(), time(),
@ -213,10 +150,10 @@
return str_replace( return str_replace(
[ [
InstallConstants::INSTALL_PATH->value, InstallConstants::INSTALL_PATH,
InstallConstants::INSTALL_PATH_BIN->value, InstallConstants::INSTALL_PATH_BIN,
InstallConstants::INSTALL_PATH_SRC->value, InstallConstants::INSTALL_PATH_SRC,
InstallConstants::INSTALL_PATH_DATA->value InstallConstants::INSTALL_PATH_DATA
], ],
[ [
$installation_paths->getInstallationpath(), $installation_paths->getInstallationpath(),
@ -241,36 +178,36 @@
} }
return str_replace([ return str_replace([
DateTimeConstants::d->value, DateTimeConstants::d,
DateTimeConstants::D->value, DateTimeConstants::D,
DateTimeConstants::j->value, DateTimeConstants::j,
DateTimeConstants::l->value, DateTimeConstants::l,
DateTimeConstants::N->value, DateTimeConstants::N,
DateTimeConstants::S->value, DateTimeConstants::S,
DateTimeConstants::w->value, DateTimeConstants::w,
DateTimeConstants::z->value, DateTimeConstants::z,
DateTimeConstants::W->value, DateTimeConstants::W,
DateTimeConstants::F->value, DateTimeConstants::F,
DateTimeConstants::m->value, DateTimeConstants::m,
DateTimeConstants::M->value, DateTimeConstants::M,
DateTimeConstants::n->value, DateTimeConstants::n,
DateTimeConstants::t->value, DateTimeConstants::t,
DateTimeConstants::L->value, DateTimeConstants::L,
DateTimeConstants::o->value, DateTimeConstants::o,
DateTimeConstants::Y->value, DateTimeConstants::Y,
DateTimeConstants::y->value, DateTimeConstants::y,
DateTimeConstants::a->value, DateTimeConstants::a,
DateTimeConstants::A->value, DateTimeConstants::A,
DateTimeConstants::B->value, DateTimeConstants::B,
DateTimeConstants::g->value, DateTimeConstants::g,
DateTimeConstants::G->value, DateTimeConstants::G,
DateTimeConstants::h->value, DateTimeConstants::h,
DateTimeConstants::H->value, DateTimeConstants::H,
DateTimeConstants::i->value, DateTimeConstants::i,
DateTimeConstants::s->value, DateTimeConstants::s,
DateTimeConstants::c->value, DateTimeConstants::c,
DateTimeConstants::r->value, DateTimeConstants::r,
DateTimeConstants::u->value DateTimeConstants::u
], ],
[ [
date('d', $timestamp), date('d', $timestamp),
@ -320,7 +257,7 @@
if(function_exists('getcwd')) if(function_exists('getcwd'))
{ {
$input = str_replace(RuntimeConstants::CWD->value, getcwd(), $input); $input = str_replace(RuntimeConstants::CWD, getcwd(), $input);
} }
else else
{ {
@ -329,7 +266,7 @@
if(function_exists('getmypid')) if(function_exists('getmypid'))
{ {
$input = str_replace(RuntimeConstants::PID->value, getmypid(), $input); $input = str_replace(RuntimeConstants::PID, getmypid(), $input);
} }
else else
{ {
@ -338,7 +275,7 @@
if(function_exists('getmyuid')) if(function_exists('getmyuid'))
{ {
$input = str_replace(RuntimeConstants::UID->value, getmyuid(), $input); $input = str_replace(RuntimeConstants::UID, getmyuid(), $input);
} }
else else
{ {
@ -347,7 +284,7 @@
if(function_exists('getmygid')) if(function_exists('getmygid'))
{ {
$input = str_replace(RuntimeConstants::GID->value, getmygid(), $input); $input = str_replace(RuntimeConstants::GID, getmygid(), $input);
} }
else else
{ {
@ -356,7 +293,7 @@
if(function_exists('get_current_user')) if(function_exists('get_current_user'))
{ {
$input = str_replace(RuntimeConstants::USER->value, get_current_user(), $input); $input = str_replace(RuntimeConstants::USER, get_current_user(), $input);
} }
else else
{ {

View file

@ -59,17 +59,11 @@
*/ */
private $project_manager; private $project_manager;
/**
* @var array
*/
private $merged_dependencies;
/** /**
* @param ProjectManager $project_manager * @param ProjectManager $project_manager
*/ */
public function __construct(ProjectManager $project_manager) public function __construct(ProjectManager $project_manager)
{ {
$this->merged_dependencies = [];
$this->project_manager = $project_manager; $this->project_manager = $project_manager;
} }
@ -93,17 +87,16 @@
* @throws PathNotFoundException * @throws PathNotFoundException
* @noinspection UnusedFunctionResultInspection * @noinspection UnusedFunctionResultInspection
*/ */
public function build(string $build_configuration=BuildConfigurationValues::DEFAULT->value, array $options=[]): string public function build(string $build_configuration=BuildConfigurationValues::DEFAULT, array $options=[]): string
{ {
$this->merged_dependencies = [];
$configuration = $this->project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration); $configuration = $this->project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
$configuration->setOptions(array_merge($configuration->getOptions(), $options)); $configuration->setOptions(array_merge($configuration->getOptions(), $options));
$static_dependencies = isset($configuration->getOptions()[BuildConfigurationOptions::STATIC_DEPENDENCIES->value]); $static_dependencies = isset($configuration->getOptions()[BuildConfigurationOptions::STATIC_DEPENDENCIES]);
if(isset($configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE->value])) if(isset($configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE]))
{ {
$package_path = ConstantCompiler::compileConstants( $package_path = ConstantCompiler::compileConstants(
$this->project_manager->getProjectConfiguration(), $configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE->value] $this->project_manager->getProjectConfiguration(), $configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE]
); );
} }
else else
@ -129,7 +122,7 @@
} }
// Debugging information // Debugging information
if(LogLevel::DEBUG->checkLogLevel(Main::getLogLevel())) if(Resolver::checkLogLevel(LogLevel::DEBUG, Main::getLogLevel()))
{ {
foreach($this->project_manager->getProjectConfiguration()->getAssembly()->toArray() as $prop => $value) foreach($this->project_manager->getProjectConfiguration()->getAssembly()->toArray() as $prop => $value)
{ {
@ -171,7 +164,7 @@
foreach($execution_units as $unit) foreach($execution_units as $unit)
{ {
$progress_bar->setMiscText(basename($unit->getExecutionPolicy()->getName())); $progress_bar->setMiscText($unit->getExecutionPolicy()->getName());
//$progress++; //$progress++;
//Console::inlineProgressBar($progress, $steps); //Console::inlineProgressBar($progress, $steps);
$package_writer->addExecutionUnit($unit); $package_writer->addExecutionUnit($unit);
@ -184,7 +177,7 @@
{ {
//$progress++; //$progress++;
//Console::inlineProgressBar($progress, $steps); //Console::inlineProgressBar($progress, $steps);
$progress_bar->setMiscText(basename($component)); $progress_bar->setMiscText($component);
Console::outVerbose(sprintf('Compiling \'%s\'', $component)); Console::outVerbose(sprintf('Compiling \'%s\'', $component));
$this->processComponent($package_writer, $component); $this->processComponent($package_writer, $component);
@ -196,7 +189,7 @@
{ {
//$progress++; //$progress++;
//Console::inlineProgressBar($progress, $steps); //Console::inlineProgressBar($progress, $steps);
$progress_bar->setMiscText(basename($resource)); $progress_bar->setMiscText($resource);
Console::outVerbose(sprintf('Processing \'%s\'', $resource)); Console::outVerbose(sprintf('Processing \'%s\'', $resource));
$this->processResource($package_writer, $resource); $this->processResource($package_writer, $resource);
@ -241,14 +234,13 @@
/** @noinspection UnusedFunctionResultInspection */ /** @noinspection UnusedFunctionResultInspection */
$package_writer->addDependencyConfiguration($dependency); $package_writer->addDependencyConfiguration($dependency);
if(!$static || in_array($dependency->getName(), $this->merged_dependencies, true)) if(!$static)
{ {
return; return;
} }
$entry = (new PackageManager())->getPackageLock()->getVersionEntry($dependency->getName(), $dependency->getVersion()); $entry = (new PackageManager())->getPackageLock()->getVersionEntry($dependency->getName(), $dependency->getVersion());
$package_writer->merge((new PackageReader($entry->getShadowPackagePath($dependency->getName())))); $package_writer->merge((new PackageReader($entry->getShadowPackagePath($dependency->getName()))));
$this->merged_dependencies[] = $dependency->getName();
foreach($entry->getDependencies() as $sub_dependency) foreach($entry->getDependencies() as $sub_dependency)
{ {
@ -269,25 +261,25 @@
{ {
$package_writer = new PackageWriter($path); $package_writer = new PackageWriter($path);
if(isset($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION->value])) if(isset($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]))
{ {
$package_writer->addFlag(PackageFlags::COMPRESSION); $package_writer->addFlag(PackageFlags::COMPRESSION);
switch(strtolower($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION->value])) switch(strtolower($build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]))
{ {
case BuildConfigurationOptions\CompressionOptions::HIGH->value: case BuildConfigurationOptions\CompressionOptions::HIGH:
$package_writer->addFlag(PackageFlags::HIGH_COMPRESSION); $package_writer->addFlag(PackageFlags::HIGH_COMPRESSION);
break; break;
case BuildConfigurationOptions\CompressionOptions::MEDIUM->value: case BuildConfigurationOptions\CompressionOptions::MEDIUM:
$package_writer->addFlag(PackageFlags::MEDIUM_COMPRESSION); $package_writer->addFlag(PackageFlags::MEDIUM_COMPRESSION);
break; break;
case BuildConfigurationOptions\CompressionOptions::LOW->value: case BuildConfigurationOptions\CompressionOptions::LOW:
$package_writer->addFlag(PackageFlags::LOW_COMPRESSION); $package_writer->addFlag(PackageFlags::LOW_COMPRESSION);
break; break;
default: default:
throw new NotSupportedException(sprintf('The compression level \'%s\' is not supported', $build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION->value])); throw new NotSupportedException(sprintf('The compression level \'%s\' is not supported', $build_configuration->getOptions()[BuildConfigurationOptions::COMPRESSION]));
} }
} }
@ -335,38 +327,29 @@
* @param string $build_configuration * @param string $build_configuration
* @return void * @return void
*/ */
public function processMetadata(PackageWriter $package_writer, string $build_configuration=BuildConfigurationValues::DEFAULT->value): void public function processMetadata(PackageWriter $package_writer, string $build_configuration=BuildConfigurationValues::DEFAULT): void
{ {
$metadata = new Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler()); $metadata = new Metadata($this->project_manager->getProjectConfiguration()->getProject()->getCompiler());
$metadata->addOptions($this->project_manager->getProjectConfiguration()->getBuild()->getOptions($build_configuration)); $metadata->addOptions($this->project_manager->getProjectConfiguration()->getBuild()->getOptions($build_configuration));
$metadata->addOptions($this->project_manager->getProjectConfiguration()->getProject()->getOptions()); $metadata->addOptions($this->project_manager->getProjectConfiguration()->getProject()->getOptions());
$metadata->addConstants($this->project_manager->getConstants($build_configuration));
$metadata->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource()); $metadata->setUpdateSource($this->project_manager->getProjectConfiguration()->getProject()->getUpdateSource());
$metadata->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain()); $metadata->setMainExecutionPolicy($this->project_manager->getProjectConfiguration()->getBuild()->getMain());
$metadata->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller()); $metadata->setInstaller($this->project_manager->getProjectConfiguration()->getInstaller());
// Strip out 'output_file' build artifact. // Strip out 'output_file' build artifact.
if(isset($metadata->getOptions()[BuildConfigurationOptions::OUTPUT_FILE->value])) if(isset($metadata->getOptions()[BuildConfigurationOptions::OUTPUT_FILE]))
{ {
$metadata->removeOption(BuildConfigurationOptions::OUTPUT_FILE->value); $metadata->removeOption(BuildConfigurationOptions::OUTPUT_FILE);
} }
// Strip out 'static' build artifact, PackageFlags::STATIC_DEPENDENCIES is used instead // Strip out 'static' build artifact, PackageFlags::STATIC_DEPENDENCIES is used instead
// Making this option redundant. // Making this option redundant.
if(isset($metadata->getOptions()[BuildConfigurationOptions::STATIC_DEPENDENCIES->value])) if(isset($metadata->getOptions()[BuildConfigurationOptions::STATIC_DEPENDENCIES]))
{ {
$metadata->removeOption(BuildConfigurationOptions::STATIC_DEPENDENCIES->value); $metadata->removeOption(BuildConfigurationOptions::STATIC_DEPENDENCIES);
} }
$compiled_constants = [];
foreach($this->project_manager->getConstants() as $constant => $value)
{
$compiled_constants[$constant] = ConstantCompiler::compileConstants($this->project_manager->getProjectConfiguration(), $value);
}
$metadata->addConstants($compiled_constants);
/** @noinspection UnusedFunctionResultInspection */ /** @noinspection UnusedFunctionResultInspection */
$package_writer->setMetadata($metadata); $package_writer->setMetadata($metadata);
} }

View file

@ -29,8 +29,8 @@
use ncc\Enums\Flags\PackageFlags; use ncc\Enums\Flags\PackageFlags;
use ncc\Enums\PackageDirectory; use ncc\Enums\PackageDirectory;
use ncc\Exceptions\ConfigurationException; use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IntegrityException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use ncc\Objects\Package\Component; use ncc\Objects\Package\Component;
use ncc\Objects\Package\ExecutionUnit; use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\Package\Metadata; use ncc\Objects\Package\Metadata;
@ -84,11 +84,6 @@
*/ */
private $package_file; private $package_file;
/**
* @var string
*/
private $package_path;
/** /**
* @var array * @var array
*/ */
@ -107,9 +102,7 @@
throw new IOException(sprintf('File \'%s\' does not exist', $file_path)); throw new IOException(sprintf('File \'%s\' does not exist', $file_path));
} }
$this->package_path = $file_path;
$this->package_file = fopen($file_path, 'rb'); $this->package_file = fopen($file_path, 'rb');
if($this->package_file === false) if($this->package_file === false)
{ {
throw new IOException(sprintf('Failed to open file \'%s\'', $file_path)); throw new IOException(sprintf('Failed to open file \'%s\'', $file_path));
@ -175,38 +168,27 @@
throw new IOException(sprintf('File \'%s\' is not a valid package file (corrupted header)', $file_path), $e); throw new IOException(sprintf('File \'%s\' is not a valid package file (corrupted header)', $file_path), $e);
} }
if(!isset($this->headers[PackageStructure::FILE_VERSION->value])) if(!isset($this->headers[PackageStructure::FILE_VERSION]))
{ {
throw new IOException(sprintf('File \'%s\' is not a valid package file (invalid header)', $file_path)); throw new IOException(sprintf('File \'%s\' is not a valid package file (invalid header)', $file_path));
} }
// Seek the data until the end of the package (FF AA 55 F0) // Seek the data until the end of the package (FF AA 55 F0)
fseek($this->package_file, $this->data_offset); fseek($this->package_file, $this->data_offset);
$buffer = '';
while(!feof($this->package_file)) while(!feof($this->package_file))
{ {
$current_chunk = fread($this->package_file, 1024); $buffer = fread($this->package_file, 1024);
$this->data_length += strlen($current_chunk); $this->data_length += strlen($buffer);
$buffer .= $current_chunk;
// If we detect the end-of-data byte sequence
if (($position = strpos($buffer, "\xFF\xAA\x55\xF0")) !== false) if (($position = strpos($buffer, "\xFF\xAA\x55\xF0")) !== false)
{ {
$this->data_length -= strlen($buffer) - $position; $this->data_length -= strlen($buffer) - $position;
$this->package_length += $this->data_length + 4; $this->package_length += $this->data_length + 4;
break; break;
} }
// Check if the buffer is 1MB or larger
if(strlen($buffer) > 1048576)
{
// Remove the first 512kb of the buffer
$buffer = substr($buffer, 512000);
} }
} if($this->data_length === null)
if($this->data_length === null || $this->data_length === 0)
{ {
throw new IOException(sprintf('File \'%s\' is not a valid package file (missing end of package)', $file_path)); throw new IOException(sprintf('File \'%s\' is not a valid package file (missing end of package)', $file_path));
} }
@ -231,7 +213,7 @@
*/ */
public function getFileVersion(): string public function getFileVersion(): string
{ {
return $this->headers[PackageStructure::FILE_VERSION->value]; return $this->headers[PackageStructure::FILE_VERSION];
} }
/** /**
@ -241,7 +223,7 @@
*/ */
public function getFlags(): array public function getFlags(): array
{ {
return $this->headers[PackageStructure::FLAGS->value]; return $this->headers[PackageStructure::FLAGS];
} }
/** /**
@ -252,7 +234,7 @@
*/ */
public function getFlag(string $name): bool public function getFlag(string $name): bool
{ {
return in_array($name, $this->headers[PackageStructure::FLAGS->value], true); return in_array($name, $this->headers[PackageStructure::FLAGS], true);
} }
/** /**
@ -262,7 +244,7 @@
*/ */
public function getDirectory(): array public function getDirectory(): array
{ {
return $this->headers[PackageStructure::DIRECTORY->value]; return $this->headers[PackageStructure::DIRECTORY];
} }
/** /**
@ -273,15 +255,15 @@
*/ */
public function get(string $name): string public function get(string $name): string
{ {
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$name]))
{ {
throw new RuntimeException(sprintf('File \'%s\' not found in package \'%s\'', $name, $this->package_path)); throw new RuntimeException(sprintf('File \'%s\' not found in package', $name));
} }
$location = explode(':', $this->headers[PackageStructure::DIRECTORY->value][$name]); $location = explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
fseek($this->package_file, ($this->data_offset + (int)$location[0])); fseek($this->package_file, ($this->data_offset + (int)$location[0]));
if(in_array(PackageFlags::COMPRESSION->value, $this->headers[PackageStructure::FLAGS->value], true)) if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
{ {
return gzuncompress(fread($this->package_file, (int)$location[1])); return gzuncompress(fread($this->package_file, (int)$location[1]));
} }
@ -297,12 +279,12 @@
*/ */
public function getPointer(string $name): array public function getPointer(string $name): array
{ {
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$name]))
{ {
throw new RuntimeException(sprintf('Resource \'%s\' not found in package \'%s\'', $name, $this->package_path)); throw new RuntimeException(sprintf('Resource \'%s\' not found in package', $name));
} }
$location = explode(':', $this->headers[PackageStructure::DIRECTORY->value][$name]); $location = explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
return [(int)$location[0], (int)$location[1]]; return [(int)$location[0], (int)$location[1]];
} }
@ -314,7 +296,7 @@
*/ */
public function exists(string $name): bool public function exists(string $name): bool
{ {
return isset($this->headers[PackageStructure::DIRECTORY->value][$name]); return isset($this->headers[PackageStructure::DIRECTORY][$name]);
} }
/** /**
@ -335,31 +317,22 @@
* *
* @return Assembly * @return Assembly
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException
*/ */
public function getAssembly(): Assembly public function getAssembly(): Assembly
{ {
$directory = sprintf('@%s', PackageDirectory::ASSEMBLY->value); $directory = sprintf('@%s', PackageDirectory::ASSEMBLY);
if(isset($this->cache[$directory])) if(isset($this->cache[$directory]))
{ {
return $this->cache[$directory]; return $this->cache[$directory];
} }
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$directory])) if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
{ {
throw new ConfigurationException(sprintf('Assembly object not found in package \'%s\'', $this->package_path)); throw new ConfigurationException('Package does not contain an assembly');
} }
try
{
$assembly = Assembly::fromArray(ZiProto::decode($this->get($directory))); $assembly = Assembly::fromArray(ZiProto::decode($this->get($directory)));
}
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode assembly from package \'%s\' using ZiProto: %s', $this->package_path, $e->getMessage()), $e);
}
$this->cache[$directory] = $assembly; $this->cache[$directory] = $assembly;
return $assembly; return $assembly;
} }
@ -369,31 +342,23 @@
* *
* @return Metadata * @return Metadata
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException * @throws NotSupportedException
*/ */
public function getMetadata(): Metadata public function getMetadata(): Metadata
{ {
$directory = sprintf('@%s', PackageDirectory::METADATA->value); $directory = sprintf('@%s', PackageDirectory::METADATA);
if(isset($this->cache[$directory])) if(isset($this->cache[$directory]))
{ {
return $this->cache[$directory]; return $this->cache[$directory];
} }
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$directory])) if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
{ {
throw new ConfigurationException(sprintf('Metadata object not found in package \'%s\'', $this->package_path)); throw new ConfigurationException('Package does not contain metadata');
} }
try
{
$metadata = Metadata::fromArray(ZiProto::decode($this->get($directory))); $metadata = Metadata::fromArray(ZiProto::decode($this->get($directory)));
}
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode metadata from package \'%s\' using ZiProto: %s', $this->package_path, $e->getMessage()), $e);
}
foreach($this->getFlags() as $flag) foreach($this->getFlags() as $flag)
{ {
$metadata->setOption($flag, true); $metadata->setOption($flag, true);
@ -407,31 +372,22 @@
* Optional. Returns the package's installer * Optional. Returns the package's installer
* *
* @return Installer|null * @return Installer|null
* @throws IntegrityException
*/ */
public function getInstaller(): ?Installer public function getInstaller(): ?Installer
{ {
$directory = sprintf('@%s', PackageDirectory::INSTALLER->value); $directory = sprintf('@%s', PackageDirectory::INSTALLER);
if(isset($this->cache[$directory])) if(isset($this->cache[$directory]))
{ {
return $this->cache[$directory]; return $this->cache[$directory];
} }
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$directory])) if(!isset($this->headers[PackageStructure::DIRECTORY][$directory]))
{ {
return null; return null;
} }
try
{
$installer = Installer::fromArray(ZiProto::decode($this->get($directory))); $installer = Installer::fromArray(ZiProto::decode($this->get($directory)));
}
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode installer from package \'%s\' using ZiProto: %s', $this->package_path, $e->getMessage()), $e);
}
$this->cache[$directory] = $installer; $this->cache[$directory] = $installer;
return $installer; return $installer;
} }
@ -444,9 +400,9 @@
public function getDependencies(): array public function getDependencies(): array
{ {
$dependencies = []; $dependencies = [];
$directory = sprintf('@%s:', PackageDirectory::DEPENDENCIES->value); $directory = sprintf('@%s:', PackageDirectory::DEPENDENCIES);
foreach($this->headers[PackageStructure::DIRECTORY->value] as $name => $location) foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{ {
if(str_starts_with($name, $directory)) if(str_starts_with($name, $directory))
{ {
@ -463,25 +419,17 @@
* @param string $name * @param string $name
* @return Dependency * @return Dependency
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException
*/ */
public function getDependency(string $name): Dependency public function getDependency(string $name): Dependency
{ {
$dependency_name = sprintf('@%s:%s', PackageDirectory::DEPENDENCIES->value, $name); $dependency_name = sprintf('@%s:%s', PackageDirectory::DEPENDENCIES, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$dependency_name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$dependency_name]))
{ {
throw new ConfigurationException(sprintf('Dependency \'%s\' not found in package \'%s\'', $name, $this->package_path)); throw new ConfigurationException(sprintf('Dependency \'%s\' not found in package', $name));
} }
try
{
return Dependency::fromArray(ZiProto::decode($this->get($dependency_name))); return Dependency::fromArray(ZiProto::decode($this->get($dependency_name)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode dependency \'%s\' from package \'%s\' using ZiProto: %s', $name, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns a dependency from the package by pointer * Returns a dependency from the package by pointer
@ -489,19 +437,12 @@
* @param int $pointer * @param int $pointer
* @param int $length * @param int $length
* @return Dependency * @return Dependency
* @throws IntegrityException * @throws ConfigurationException
*/ */
public function getDependencyByPointer(int $pointer, int $length): Dependency public function getDependencyByPointer(int $pointer, int $length): Dependency
{
try
{ {
return Dependency::fromArray(ZiProto::decode($this->getByPointer($pointer, $length))); return Dependency::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode dependency from pointer \'%s\' with length \'%s\' from package \'%s\' using ZiProto: %s', $pointer, $length, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns an array of execution units from the package * Returns an array of execution units from the package
@ -511,9 +452,9 @@
public function getExecutionUnits(): array public function getExecutionUnits(): array
{ {
$execution_units = []; $execution_units = [];
$directory = sprintf('@%s:', PackageDirectory::EXECUTION_UNITS->value); $directory = sprintf('@%s:', PackageDirectory::EXECUTION_UNITS);
foreach($this->headers[PackageStructure::DIRECTORY->value] as $name => $location) foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{ {
if(str_starts_with($name, $directory)) if(str_starts_with($name, $directory))
{ {
@ -530,36 +471,17 @@
* @param string $name * @param string $name
* @return ExecutionUnit * @return ExecutionUnit
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException
*/ */
public function getExecutionUnit(string $name): ExecutionUnit public function getExecutionUnit(string $name): ExecutionUnit
{ {
$execution_unit_name = sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS->value, $name); $execution_unit_name = sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$execution_unit_name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$execution_unit_name]))
{ {
throw new ConfigurationException(sprintf('Execution unit \'%s\' not found in package \'%s\'', $name, $this->package_path)); throw new ConfigurationException(sprintf('Execution unit \'%s\' not found in package', $name));
} }
try
{
return ExecutionUnit::fromArray(ZiProto::decode($this->get($execution_unit_name))); return ExecutionUnit::fromArray(ZiProto::decode($this->get($execution_unit_name)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode execution unit \'%s\' from package file \'%s\' using ZiProto: %s', $name, $this->package_path, $e->getMessage()), $e);
}
}
/**
* Checks if an execution unit with the specified name exists in the package.
*
* @param string $name The name of the execution unit to check.
* @return bool True if the execution unit exists, false otherwise.
*/
public function executionUnitExists(string $name): bool
{
return isset($this->headers[PackageStructure::DIRECTORY->value][sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS->value, $name)]);
}
/** /**
* Returns an execution unit from the package by pointer * Returns an execution unit from the package by pointer
@ -567,19 +489,12 @@
* @param int $pointer * @param int $pointer
* @param int $length * @param int $length
* @return ExecutionUnit * @return ExecutionUnit
* @throws IntegrityException * @throws ConfigurationException
*/ */
public function getExecutionUnitByPointer(int $pointer, int $length): ExecutionUnit public function getExecutionUnitByPointer(int $pointer, int $length): ExecutionUnit
{
try
{ {
return ExecutionUnit::fromArray(ZiProto::decode($this->getByPointer($pointer, $length))); return ExecutionUnit::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode execution unit from pointer \'%s\' with length \'%s\' from package \'%s\' using ZiProto: %s', $pointer, $length, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns the package's component pointers * Returns the package's component pointers
@ -589,9 +504,9 @@
public function getComponents(): array public function getComponents(): array
{ {
$components = []; $components = [];
$directory = sprintf('@%s:', PackageDirectory::COMPONENTS->value); $directory = sprintf('@%s:', PackageDirectory::COMPONENTS);
foreach($this->headers[PackageStructure::DIRECTORY->value] as $name => $location) foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{ {
if(str_starts_with($name, $directory)) if(str_starts_with($name, $directory))
{ {
@ -610,9 +525,9 @@
public function getClassMap(): array public function getClassMap(): array
{ {
$class_map = []; $class_map = [];
$directory = sprintf('@%s:', PackageDirectory::CLASS_POINTER->value); $directory = sprintf('@%s:', PackageDirectory::CLASS_POINTER);
foreach($this->headers[PackageStructure::DIRECTORY->value] as $name => $location) foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{ {
if(str_starts_with($name, $directory)) if(str_starts_with($name, $directory))
{ {
@ -629,25 +544,17 @@
* @param string $name * @param string $name
* @return Component * @return Component
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException
*/ */
public function getComponent(string $name): Component public function getComponent(string $name): Component
{ {
$component_name = sprintf('@%s:%s', PackageDirectory::COMPONENTS->value, $name); $component_name = sprintf('@%s:%s', PackageDirectory::COMPONENTS, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$component_name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$component_name]))
{ {
throw new ConfigurationException(sprintf('Component \'%s\' not found in package \'%s\'', $name, $this->package_path)); throw new ConfigurationException(sprintf('Component \'%s\' not found in package', $name));
} }
try
{
return Component::fromArray(ZiProto::decode($this->get($component_name))); return Component::fromArray(ZiProto::decode($this->get($component_name)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode component \'%s\' from package \'%s\' using ZiProto: %s', $name, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns a component from the package by pointer * Returns a component from the package by pointer
@ -655,19 +562,12 @@
* @param int $pointer * @param int $pointer
* @param int $length * @param int $length
* @return Component * @return Component
* @throws IntegrityException * @throws ConfigurationException
*/ */
public function getComponentByPointer(int $pointer, int $length): Component public function getComponentByPointer(int $pointer, int $length): Component
{
try
{ {
return Component::fromArray(ZiProto::decode($this->getByPointer($pointer, $length))); return Component::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode component from pointer \'%s\' with length \'%s\' from package \'%s\' using ZiProto: %s', $pointer, $length, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns a component from the package by a class pointer * Returns a component from the package by a class pointer
@ -675,25 +575,17 @@
* @param string $class * @param string $class
* @return Component * @return Component
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException
*/ */
public function getComponentByClass(string $class): Component public function getComponentByClass(string $class): Component
{ {
$class_name = sprintf('@%s:%s', PackageDirectory::CLASS_POINTER->value, $class); $class_name = sprintf('@%s:%s', PackageDirectory::CLASS_POINTER, $class);
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$class_name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$class_name]))
{ {
throw new ConfigurationException(sprintf('Class map \'%s\' not found in package \'%s\'', $class, $this->package_path)); throw new ConfigurationException(sprintf('Class map \'%s\' not found in package', $class));
} }
try
{
return Component::fromArray(ZiProto::decode($this->get($class_name))); return Component::fromArray(ZiProto::decode($this->get($class_name)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode component from class pointer \'%s\' from package \'%s\' using ZiProto: %s', $class, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns an array of resource pointers from the package * Returns an array of resource pointers from the package
@ -703,9 +595,9 @@
public function getResources(): array public function getResources(): array
{ {
$resources = []; $resources = [];
$directory = sprintf('@%s:', PackageDirectory::RESOURCES->value); $directory = sprintf('@%s:', PackageDirectory::RESOURCES);
foreach($this->headers[PackageStructure::DIRECTORY->value] as $name => $location) foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{ {
if(str_starts_with($name, $directory)) if(str_starts_with($name, $directory))
{ {
@ -722,25 +614,17 @@
* @param string $name * @param string $name
* @return Resource * @return Resource
* @throws ConfigurationException * @throws ConfigurationException
* @throws IntegrityException
*/ */
public function getResource(string $name): Resource public function getResource(string $name): Resource
{ {
$resource_name = sprintf('@%s:%s', PackageDirectory::RESOURCES->value, $name); $resource_name = sprintf('@%s:%s', PackageDirectory::RESOURCES, $name);
if(!isset($this->headers[PackageStructure::DIRECTORY->value][$resource_name])) if(!isset($this->headers[PackageStructure::DIRECTORY][$resource_name]))
{ {
throw new ConfigurationException(sprintf('Resource \'%s\' not found in package \'%s\'', $name, $this->package_path)); throw new ConfigurationException(sprintf('Resource \'%s\' not found in package', $name));
} }
try
{
return Resource::fromArray(ZiProto::decode($this->get($resource_name))); return Resource::fromArray(ZiProto::decode($this->get($resource_name)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode resource \'%s\' from package \'%s\' using ZiProto: %s', $name, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Returns a resource from the package by pointer * Returns a resource from the package by pointer
@ -748,19 +632,12 @@
* @param int $pointer * @param int $pointer
* @param int $length * @param int $length
* @return Resource * @return Resource
* @throws IntegrityException * @throws ConfigurationException
*/ */
public function getResourceByPointer(int $pointer, int $length): Resource public function getResourceByPointer(int $pointer, int $length): Resource
{
try
{ {
return Resource::fromArray(ZiProto::decode($this->getByPointer($pointer, $length))); return Resource::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
} }
catch(Exception $e)
{
throw new IntegrityException(sprintf('Failed to decode resource from pointer \'%s\' with length \'%s\' from package \'%s\' using ZiProto: %s', $pointer, $length, $this->package_path, $e->getMessage()), $e);
}
}
/** /**
* Searches the package's directory for a file that matches the given filename * Searches the package's directory for a file that matches the given filename
@ -770,7 +647,7 @@
*/ */
public function find(string $filename): string|false public function find(string $filename): string|false
{ {
foreach($this->headers[PackageStructure::DIRECTORY->value] as $name => $location) foreach($this->headers[PackageStructure::DIRECTORY] as $name => $location)
{ {
if(str_ends_with($name, $filename)) if(str_ends_with($name, $filename))
{ {
@ -878,7 +755,7 @@
fseek($this->package_file, $this->package_offset); fseek($this->package_file, $this->package_offset);
$remaining_bytes = $this->package_length; $remaining_bytes = $this->package_length;
while($remaining_bytes > 0) while ($remaining_bytes > 0)
{ {
$bytes_to_read = min($remaining_bytes, 4096); $bytes_to_read = min($remaining_bytes, 4096);
$data = fread($this->package_file, $bytes_to_read); $data = fread($this->package_file, $bytes_to_read);

View file

@ -25,7 +25,6 @@
namespace ncc\Classes; namespace ncc\Classes;
use InvalidArgumentException;
use ncc\Enums\Flags\PackageFlags; use ncc\Enums\Flags\PackageFlags;
use ncc\Enums\PackageDirectory; use ncc\Enums\PackageDirectory;
use ncc\Enums\PackageStructure; use ncc\Enums\PackageStructure;
@ -109,9 +108,9 @@
$this->temp_file = @fopen($this->temporary_path, 'wb'); // Create a temporary data file $this->temp_file = @fopen($this->temporary_path, 'wb'); // Create a temporary data file
$this->package_file = @fopen($file_path, 'wb'); $this->package_file = @fopen($file_path, 'wb');
$this->headers = [ $this->headers = [
PackageStructure::FILE_VERSION->value => PackageStructureVersions::_2_0->value, PackageStructure::FILE_VERSION => PackageStructureVersions::_2_0,
PackageStructure::FLAGS->value => [], PackageStructure::FLAGS => [],
PackageStructure::DIRECTORY->value => [] PackageStructure::DIRECTORY => []
]; ];
if($this->temp_file === false || $this->package_file === false) if($this->temp_file === false || $this->package_file === false)
@ -127,7 +126,7 @@
*/ */
public function getFileVersion(): string public function getFileVersion(): string
{ {
return (string)$this->headers[PackageStructure::FILE_VERSION->value]; return (string)$this->headers[PackageStructure::FILE_VERSION];
} }
/** /**
@ -138,7 +137,7 @@
*/ */
public function setFileVersion(string $version): void public function setFileVersion(string $version): void
{ {
$this->headers[PackageStructure::FILE_VERSION->value] = $version; $this->headers[PackageStructure::FILE_VERSION] = $version;
} }
/** /**
@ -148,13 +147,13 @@
*/ */
public function getFlags(): array public function getFlags(): array
{ {
return (array)$this->headers[PackageStructure::FLAGS->value]; return (array)$this->headers[PackageStructure::FLAGS];
} }
/** /**
* Sets the package flags * Sets the package flags
* *
* @param string[]|PackageFlags[] $flags * @param array $flags
* @return void * @return void
* @throws IOException * @throws IOException
*/ */
@ -165,47 +164,26 @@
throw new IOException('Cannot set flags after data has been written to the package'); throw new IOException('Cannot set flags after data has been written to the package');
} }
foreach($flags as $flag) $this->headers[PackageStructure::FLAGS] = $flags;
{
if(is_string($flag))
{
$flag = PackageFlags::tryFrom($flag);
if($flag === null)
{
throw new InvalidArgumentException(sprintf('Unexpected flag: %s', $flag));
}
}
$this->headers[PackageStructure::FLAGS->value] = $flag->value;
}
} }
/** /**
* Adds a flag to the package * Adds a flag to the package
* *
* @param PackageFlags|string $flag * @param string $flag
* @return void * @return void
* @throws IOException * @throws IOException
*/ */
public function addFlag(PackageFlags|string $flag): void public function addFlag(string $flag): void
{ {
if(is_string($flag))
{
$flag = PackageFlags::tryFrom($flag);
if($flag === null)
{
throw new InvalidArgumentException(sprintf('Unexpected flag: %s', $flag));
}
}
if($this->data_written) if($this->data_written)
{ {
throw new IOException('Cannot add a flag after data has been written to the package'); throw new IOException('Cannot add a flag after data has been written to the package');
} }
if(!in_array($flag, $this->headers[PackageStructure::FLAGS->value], true)) if(!in_array($flag, $this->headers[PackageStructure::FLAGS], true))
{ {
$this->headers[PackageStructure::FLAGS->value][] = $flag->value; $this->headers[PackageStructure::FLAGS][] = $flag;
} }
} }
@ -216,23 +194,14 @@
* @return void * @return void
* @throws IOException * @throws IOException
*/ */
public function removeFlag(PackageFlags|string $flag): void public function removeFlag(string $flag): void
{ {
if(is_string($flag))
{
$flag = PackageFlags::tryFrom($flag);
if($flag === null)
{
throw new InvalidArgumentException(sprintf('Unexpected flag: %s', $flag));
}
}
if($this->data_written) if($this->data_written)
{ {
throw new IOException('Cannot remove a flag after data has been written to the package'); throw new IOException('Cannot remove a flag after data has been written to the package');
} }
$this->headers[PackageStructure::FLAGS->value] = array_diff($this->headers[PackageStructure::FLAGS->value], [$flag->value]); $this->headers[PackageStructure::FLAGS] = array_diff($this->headers[PackageStructure::FLAGS], [$flag]);
} }
/** /**
@ -244,22 +213,22 @@
*/ */
public function add(string $name, string $data): array public function add(string $name, string $data): array
{ {
if(isset($this->headers[PackageStructure::DIRECTORY->value][$name])) if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
{ {
return explode(':', $this->headers[PackageStructure::DIRECTORY->value][$name]); return explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
} }
if(in_array(PackageFlags::COMPRESSION->value, $this->headers[PackageStructure::FLAGS->value], true)) if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
{ {
if(in_array(PackageFlags::LOW_COMPRESSION->value, $this->headers[PackageStructure::FLAGS->value], true)) if(in_array(PackageFlags::LOW_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
{ {
$data = gzcompress($data, 1); $data = gzcompress($data, 1);
} }
else if(in_array(PackageFlags::MEDIUM_COMPRESSION->value, $this->headers[PackageStructure::FLAGS->value], true)) else if(in_array(PackageFlags::MEDIUM_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
{ {
$data = gzcompress($data, 6); $data = gzcompress($data, 6);
} }
else if(in_array(PackageFlags::HIGH_COMPRESSION->value, $this->headers[PackageStructure::FLAGS->value], true)) else if(in_array(PackageFlags::HIGH_COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
{ {
$data = gzcompress($data, 9); $data = gzcompress($data, 9);
} }
@ -270,7 +239,7 @@
} }
$pointer = sprintf("%d:%d", ftell($this->temp_file), strlen($data)); $pointer = sprintf("%d:%d", ftell($this->temp_file), strlen($data));
$this->headers[PackageStructure::DIRECTORY->value][$name] = $pointer; $this->headers[PackageStructure::DIRECTORY][$name] = $pointer;
$this->data_written = true; $this->data_written = true;
fwrite($this->temp_file, $data); fwrite($this->temp_file, $data);
@ -287,12 +256,12 @@
*/ */
public function addPointer(string $name, int $offset, int $length): void public function addPointer(string $name, int $offset, int $length): void
{ {
if(isset($this->headers[PackageStructure::DIRECTORY->value][$name])) if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
{ {
return; return;
} }
$this->headers[PackageStructure::DIRECTORY->value][$name] = sprintf("%d:%d", $offset, $length); $this->headers[PackageStructure::DIRECTORY][$name] = sprintf("%d:%d", $offset, $length);
} }
/** /**
@ -303,7 +272,7 @@
*/ */
public function setAssembly(Assembly $assembly): array public function setAssembly(Assembly $assembly): array
{ {
return $this->add(sprintf('@%s', PackageDirectory::ASSEMBLY->value), ZiProto::encode($assembly->toArray(true))); return $this->add(sprintf('@%s', PackageDirectory::ASSEMBLY), ZiProto::encode($assembly->toArray(true)));
} }
/** /**
@ -314,7 +283,7 @@
*/ */
public function setMetadata(Metadata $metadata): array public function setMetadata(Metadata $metadata): array
{ {
return $this->add(sprintf('@%s', PackageDirectory::METADATA->value), ZiProto::encode($metadata->toArray(true))); return $this->add(sprintf('@%s', PackageDirectory::METADATA), ZiProto::encode($metadata->toArray(true)));
} }
/** /**
@ -325,7 +294,7 @@
*/ */
public function setInstaller(Installer $installer): array public function setInstaller(Installer $installer): array
{ {
return $this->add(sprintf('@%s', PackageDirectory::INSTALLER->value), ZiProto::encode($installer->toArray(true))); return $this->add(sprintf('@%s', PackageDirectory::INSTALLER), ZiProto::encode($installer->toArray(true)));
} }
/** /**
@ -336,7 +305,7 @@
*/ */
public function addDependencyConfiguration(Dependency $dependency): array public function addDependencyConfiguration(Dependency $dependency): array
{ {
return $this->add(sprintf('@%s:%s', PackageDirectory::DEPENDENCIES->value, $dependency->getName()), ZiProto::encode($dependency->toArray(true))); return $this->add(sprintf('@%s:%s', PackageDirectory::DEPENDENCIES, $dependency->getName()), ZiProto::encode($dependency->toArray(true)));
} }
/** /**
@ -347,7 +316,7 @@
*/ */
public function addExecutionUnit(ExecutionUnit $unit): array public function addExecutionUnit(ExecutionUnit $unit): array
{ {
return $this->add(sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS->value, $unit->getExecutionPolicy()->getName()), ZiProto::encode($unit->toArray(true))); return $this->add(sprintf('@%s:%s', PackageDirectory::EXECUTION_UNITS, $unit->getExecutionPolicy()->getName()), ZiProto::encode($unit->toArray(true)));
} }
/** /**
@ -358,7 +327,7 @@
*/ */
public function addComponent(Component $component): array public function addComponent(Component $component): array
{ {
return $this->add(sprintf('@%s:%s', PackageDirectory::COMPONENTS->value, $component->getName()), ZiProto::encode($component->toArray(true))); return $this->add(sprintf('@%s:%s', PackageDirectory::COMPONENTS, $component->getName()), ZiProto::encode($component->toArray(true)));
} }
/** /**
@ -369,7 +338,7 @@
*/ */
public function addResource(Resource $resource): array public function addResource(Resource $resource): array
{ {
return $this->add(sprintf('@%s:%s', PackageDirectory::RESOURCES->value, $resource->getName()), ZiProto::encode($resource->toArray(true))); return $this->add(sprintf('@%s:%s', PackageDirectory::RESOURCES, $resource->getName()), ZiProto::encode($resource->toArray(true)));
} }
/** /**
@ -382,7 +351,7 @@
*/ */
public function mapClass(string $class, int $offset, int $length): void public function mapClass(string $class, int $offset, int $length): void
{ {
$this->addPointer(sprintf('@%s:%s', PackageDirectory::CLASS_POINTER->value, $class), $offset, $length); $this->addPointer(sprintf('@%s:%s', PackageDirectory::CLASS_POINTER, $class), $offset, $length);
} }
/** /**
@ -403,10 +372,10 @@
switch((int)substr(explode(':', $name, 2)[0], 1)) switch((int)substr(explode(':', $name, 2)[0], 1))
{ {
case PackageDirectory::METADATA->value: case PackageDirectory::METADATA:
case PackageDirectory::ASSEMBLY->value: case PackageDirectory::ASSEMBLY:
case PackageDirectory::INSTALLER->value: case PackageDirectory::INSTALLER:
case PackageDirectory::EXECUTION_UNITS->value: case PackageDirectory::EXECUTION_UNITS:
Console::outDebug(sprintf('Skipping %s', $name)); Console::outDebug(sprintf('Skipping %s', $name));
break; break;

View file

@ -35,10 +35,9 @@
use ncc\Interfaces\RepositoryInterface; use ncc\Interfaces\RepositoryInterface;
use ncc\Objects\RepositoryConfiguration; use ncc\Objects\RepositoryConfiguration;
use ncc\Objects\RepositoryResult; use ncc\Objects\RepositoryResult;
use ncc\ThirdParty\composer\semver\Comparator; use ncc\ThirdParty\composer\Semver\Comparator;
use ncc\ThirdParty\composer\semver\Semver; use ncc\ThirdParty\composer\Semver\Semver;
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache; use ncc\Utilities\RuntimeCache;
use RuntimeException; use RuntimeException;
@ -47,9 +46,9 @@
/** /**
* @inheritDoc * @inheritDoc
*/ */
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST->value, ?AuthenticationType $authentication = null, array $options=[]): RepositoryResult public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null, array $options=[]): RepositoryResult
{ {
if($version === Versions::LATEST->value) if($version === Versions::LATEST)
{ {
$version = self::getLatestVersion($repository, $vendor, $project); $version = self::getLatestVersion($repository, $vendor, $project);
} }
@ -71,16 +70,9 @@
'User-Agent: ncc' 'User-Agent: ncc'
]; ];
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -99,14 +91,14 @@
throw new NetworkException(sprintf('Invalid response from %s/%s, version %s does not have a dist URL', $vendor, $project, $version)); throw new NetworkException(sprintf('Invalid response from %s/%s, version %s does not have a dist URL', $vendor, $project, $version));
} }
return new RepositoryResult($response['package']['versions'][$version]['dist']['url'], RepositoryResultType::SOURCE->value, $version); return new RepositoryResult($response['package']['versions'][$version]['dist']['url'], RepositoryResultType::SOURCE, $version);
} }
/** /**
* @inheritDoc * @inheritDoc
* @throws NotSupportedException * @throws NotSupportedException
*/ */
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST->value, ?AuthenticationType $authentication = null, array $options=[]): RepositoryResult public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null, array $options=[]): RepositoryResult
{ {
throw new NotSupportedException('Fetching ncc packages from Packagist is not supported'); throw new NotSupportedException('Fetching ncc packages from Packagist is not supported');
} }
@ -138,16 +130,9 @@
'User-Agent: ncc' 'User-Agent: ncc'
]; ];
$resolved_host = Resolver::getResolveOption($endpoint);
if($resolved_host !== null)
{
curl_setopt($curl, CURLOPT_RESOLVE, [$resolved_host]);
}
curl_setopt_array($curl, [ curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => HttpRequestType::GET->value, CURLOPT_CUSTOMREQUEST => HttpRequestType::GET,
CURLOPT_HTTPHEADER => $headers CURLOPT_HTTPHEADER => $headers
]); ]);
@ -178,21 +163,23 @@
{ {
$versions = self::getVersions($repository, $vendor, $project); $versions = self::getVersions($repository, $vendor, $project);
// Filter out pre-release versions such as alpha, beta, rc, dev /** @noinspection KeysFragmentationWithArrayFunctionsInspection */
$versions = array_filter($versions, static function($version) $versions = array_filter($versions, static function($version)
{ {
return !preg_match('/-alpha|-beta|-rc|dev/i', $version); return !preg_match('/-alpha|-beta|-rc|dev/i', $version);
}); });
// Sort versions in descending order using Semver::rsort usort($versions, static function($a, $b)
$versions = Semver::rsort($versions); {
return Comparator::lessThanOrEqualTo($a, $b) ? 1 : -1;
});
if (!isset($versions[0])) if($versions[0] === null)
{ {
throw new NetworkException(sprintf('Failed to resolve latest version for %s/%s', $vendor, $project)); throw new NetworkException(sprintf('Failed to resolve latest version for %s/%s', $vendor, $project));
} }
return $versions[0]; // The first version in the sorted array is the latest return $versions[0];
} }
/** /**

View file

@ -31,6 +31,27 @@
class AstWalker class AstWalker
{ {
/**
* Returns an array representation of the node recursively
*
* @param array|Node $node
* @return array
*/
public static function serialize(array|Node $node): array
{
if(is_array($node))
{
$serialized = [];
foreach($node as $sub_node)
{
$serialized[] = $sub_node->jsonSerialize();
}
return $serialized;
}
return $node->jsonSerialize();
}
/** /**
* Returns an array of classes associated with the node recursively * Returns an array of classes associated with the node recursively
* *
@ -91,4 +112,161 @@
return $classes; return $classes;
} }
/**
* Reconstructs nodes from an array representation recursively
*
* @param $value
* @return array|Comment|Node
* @noinspection PhpMissingReturnTypeInspection
* @throws ReflectionException
*/
public static function decodeRecursive($value)
{
if (is_array($value))
{
if (isset($value['nodeType']))
{
if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc')
{
return self::decodeComment($value);
}
return self::decodeNode($value);
}
return self::decodeArray($value);
}
return $value;
}
/**
* Decodes an array by recursively decoding each value
*
* @param array $array
* @return array
* @throws ReflectionException
*/
private static function decodeArray(array $array) : array
{
$decoded_array = [];
foreach ($array as $key => $value)
{
$decoded_array[$key] = self::decodeRecursive($value);
}
return $decoded_array;
}
/**
* Returns the node from the node type
*
* @param array $value
* @return Node
* @throws ReflectionException
*/
private static function decodeNode(array $value) : Node
{
$node_type = $value['nodeType'];
if (!is_string($node_type))
{
throw new RuntimeException('Node type must be a string');
}
/** @var Node $node */
$node = self::reflectionClassFromNodeType($node_type)->newInstanceWithoutConstructor();
if (isset($value['attributes'])) {
if (!is_array($value['attributes']))
{
throw new RuntimeException('Attributes must be an array');
}
$node->setAttributes(self::decodeArray($value['attributes']));
}
foreach ($value as $name => $sub_node) {
if ($name === 'nodeType' || $name === 'attributes')
{
continue;
}
$node->$name = self::decodeRecursive($sub_node);
}
return $node;
}
/**
* Returns the comment from the node type
*
* @param array $value
* @return Comment
*/
private static function decodeComment(array $value): Comment
{
$class_name = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
if (!isset($value['text']))
{
throw new RuntimeException('Comment must have text');
}
return new $class_name(
$value['text'],
$value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
$value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
);
}
/**
* Returns the reflection class from the node type
*
* @param string $node_type
* @return ReflectionClass
* @throws ReflectionException
*/
private static function reflectionClassFromNodeType(string $node_type): ReflectionClass
{
return new ReflectionClass(self::classNameFromNodeType($node_type));
}
/**
* Returns the class name from the node type
*
* @param string $nodeType
* @return string
*/
private static function classNameFromNodeType(string $nodeType): string
{
$class_name = 'ncc\\ThirdParty\\nikic\\PhpParser\\Node\\' . str_replace('_', '\\', $nodeType);
if (class_exists($class_name))
{
return $class_name;
}
$class_name .= '_';
if (class_exists($class_name))
{
return $class_name;
}
throw new RuntimeException("Unknown node type \"$nodeType\"");
}
/**
* Transforms include, include_once, require and require_once statements into function calls.
*
* @param Node|array $stmts The AST node or array of nodes to transform.
* @param string|null $package Optionally. The package name to pass to the transformed function calls.
* @return Node|array The transformed AST node or array of nodes.
*/
public static function transformRequireCalls(Node|array $stmts, ?string $package=null): Node|array
{
$traverser = new NodeTraverser();
$traverser->addVisitor(new ExpressionTraverser($package));
return $traverser->traverse($stmts);
}
} }

View file

@ -41,7 +41,7 @@
* @inheritDoc * @inheritDoc
* @throws BuildException * @throws BuildException
*/ */
public function build(string $build_configuration = BuildConfigurationValues::DEFAULT->value, array $options=[]): string public function build(string $build_configuration = BuildConfigurationValues::DEFAULT, array $options=[]): string
{ {
$configuration = $this->getProjectManager()->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration); $configuration = $this->getProjectManager()->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
@ -50,14 +50,14 @@
$configuration->setOptions(array_merge($configuration->getOptions(), $options)); $configuration->setOptions(array_merge($configuration->getOptions(), $options));
} }
if(!isset($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION->value])) if(!isset($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION]))
{ {
throw new BuildException(sprintf("Unable to compile the binary, the build configuration '%s' does not have a ncc_configuration.", $build_configuration)); throw new BuildException(sprintf("Unable to compile the binary, the build configuration '%s' does not have a ncc_configuration.", $build_configuration));
} }
// Build the ncc package first // Build the ncc package first
Console::outVerbose('Building ncc package.'); Console::outVerbose('Building ncc package.');
$ncc_package = parent::build($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION->value]); $ncc_package = parent::build($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION]);
// Prepare the ncc package for compilation // Prepare the ncc package for compilation
$hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . $this->getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c'; $hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . $this->getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c';
@ -72,11 +72,11 @@
// Prepare the gcc command // Prepare the gcc command
$gcc_path = (new ExecutableFinder())->find('gcc'); $gcc_path = (new ExecutableFinder())->find('gcc');
if(isset($configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE->value])) if(isset($configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE]))
{ {
$binary_path = ConstantCompiler::compileConstants( $binary_path = ConstantCompiler::compileConstants(
$this->getProjectManager()->getProjectConfiguration(), $this->getProjectManager()->getProjectConfiguration(),
$configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE->value] $configuration->getOptions()[BuildConfigurationOptions::OUTPUT_FILE]
); );
} }
else else
@ -84,12 +84,6 @@
$binary_path = ConstantCompiler::compileConstants($this->getProjectManager()->getProjectConfiguration(), $configuration->getOutput()); $binary_path = ConstantCompiler::compileConstants($this->getProjectManager()->getProjectConfiguration(), $configuration->getOutput());
} }
// Create the directory recursively if it does not exist
if(!is_dir(dirname($binary_path)))
{
mkdir(dirname($binary_path), 0777, true);
}
if($gcc_path === null) if($gcc_path === null)
{ {
throw new BuildException("Unable to find gcc executable, please make sure it is installed and in your PATH environment variable."); throw new BuildException("Unable to find gcc executable, please make sure it is installed and in your PATH environment variable.");

View file

@ -30,9 +30,7 @@
use ncc\Exceptions\PathNotFoundException; use ncc\Exceptions\PathNotFoundException;
use ncc\Extensions\ZiProto\ZiProto; use ncc\Extensions\ZiProto\ZiProto;
use ncc\Objects\Package\Component; use ncc\Objects\Package\Component;
use ncc\ThirdParty\nikic\PhpParser\NodeDumper;
use ncc\ThirdParty\nikic\PhpParser\ParserFactory; use ncc\ThirdParty\nikic\PhpParser\ParserFactory;
use ncc\ThirdParty\nikic\PhpParser\PhpVersion;
use ncc\Utilities\Base64; use ncc\Utilities\Base64;
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\Functions; use ncc\Utilities\Functions;
@ -54,9 +52,13 @@
try try
{ {
$stmts = ((new ParserFactory())->createForNewestSupportedVersion())->parse(IO::fread($file_path)); $stmts = (new ParserFactory())->create(ParserFactory::PREFER_PHP7)->parse(IO::fread($file_path));
$component = new Component($component_name, ZiProto::encode(Serializer::nodesToArray($stmts)), ComponentDataType::AST); $stmts = AstWalker::transformRequireCalls(
$component->addFlag(ComponentFlags::PHP_AST->value); $stmts, $this->getProjectManager()->getProjectConfiguration()->getAssembly()->getPackage()
);
$component = new Component($component_name, ZiProto::encode($stmts), ComponentDataType::AST);
$component->addFlag(ComponentFlags::PHP_AST);
$pointer = $package_writer->addComponent($component); $pointer = $package_writer->addComponent($component);
foreach(AstWalker::extractClasses($stmts) as $class) foreach(AstWalker::extractClasses($stmts) as $class)
@ -72,7 +74,7 @@
} }
$component = new Component($component_name, Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED); $component = new Component($component_name, Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED);
$component->addFlag(ComponentFlags::PHP_B64->value); $component->addFlag(ComponentFlags::PHP_B64);
$package_writer->addComponent($component); $package_writer->addComponent($component);
} }
} }

View file

@ -44,7 +44,7 @@
*/ */
public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int public static function executeUnit(ExecutionUnit $unit, array $args=[], bool $local=true): int
{ {
if($unit->getExecutionPolicy()->getRunner() !== Runners::PHP->value) if($unit->getExecutionPolicy()->getRunner() !== Runners::PHP)
{ {
throw new InvalidArgumentException(sprintf('The execution unit %s is not a php execution unit', $unit->getExecutionPolicy()->getName())); throw new InvalidArgumentException(sprintf('The execution unit %s is not a php execution unit', $unit->getExecutionPolicy()->getName()));
} }

View file

@ -1,151 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2024, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension;
use ncc\ThirdParty\nikic\PhpParser\Comment;
use ncc\ThirdParty\nikic\PhpParser\Node;
use ncc\ThirdParty\nikic\PhpParser\NodeAbstract;
use ReflectionClass;
use RuntimeException;
use function is_array;
use function is_string;
class Serializer
{
/** @var ReflectionClass<Node>[] Node type to reflection class map */
private static array $reflectionClassCache;
/**
* @param NodeAbstract[] $nodeAbstracts
* @return array
*/
public static function nodesToArray(array $nodeAbstracts): array
{
$serialized = [];
foreach ($nodeAbstracts as $nodeAbstract)
{
$serialized[] = $nodeAbstract->jsonSerialize();
}
return $serialized;
}
/**
* @param array $nodeAbstracts
* @return NodeAbstract[]
*/
public static function arrayToNodes(array $nodeAbstracts): array
{
return self::decodeRecursive($nodeAbstracts);
}
/**
* @param mixed $value
* @return mixed
*/
private static function decodeRecursive($value) {
if (is_array($value)) {
if (isset($value['nodeType'])) {
if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') {
return self::decodeComment($value);
}
return self::decodeNode($value);
}
return self::decodeArray($value);
}
return $value;
}
private static function decodeArray(array $array): array {
$decodedArray = [];
foreach ($array as $key => $value) {
$decodedArray[$key] = self::decodeRecursive($value);
}
return $decodedArray;
}
private static function decodeNode(array $value): Node {
$nodeType = $value['nodeType'];
if (!is_string($nodeType)) {
throw new RuntimeException('Node type must be a string');
}
$reflectionClass = self::reflectionClassFromNodeType($nodeType);
$node = $reflectionClass->newInstanceWithoutConstructor();
if (isset($value['attributes'])) {
if (!is_array($value['attributes'])) {
throw new RuntimeException('Attributes must be an array');
}
$node->setAttributes(self::decodeArray($value['attributes']));
}
foreach ($value as $name => $subNode) {
if ($name === 'nodeType' || $name === 'attributes') {
continue;
}
$node->$name = self::decodeRecursive($subNode);
}
return $node;
}
private static function decodeComment(array $value): Comment {
$className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class;
if (!isset($value['text'])) {
throw new RuntimeException('Comment must have text');
}
return new $className(
$value['text'],
$value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1,
$value['endLine'] ?? -1, $value['endFilePos'] ?? -1, $value['endTokenPos'] ?? -1
);
}
private static function reflectionClassFromNodeType(string $nodeType): ReflectionClass {
if (!isset(self::$reflectionClassCache[$nodeType])) {
$className = self::classNameFromNodeType($nodeType);
self::$reflectionClassCache[$nodeType] = new ReflectionClass($className);
}
return self::$reflectionClassCache[$nodeType];
}
/** @return class-string<Node> */
private static function classNameFromNodeType(string $nodeType): string {
$className = '\\ncc\\ThirdParty\\nikic\\PhpParser\\Node\\' . strtr($nodeType, '_', '\\');
if (class_exists($className)) {
return $className;
}
$className .= '_';
if (class_exists($className)) {
return $className;
}
throw new RuntimeException("Unknown node type \"$nodeType\"");
}
}

View file

@ -49,31 +49,32 @@
public static function applyTemplate(ProjectManager $project_manager): void public static function applyTemplate(ProjectManager $project_manager): void
{ {
$project_manager->getProjectConfiguration()->addExecutionPolicy( $project_manager->getProjectConfiguration()->addExecutionPolicy(
new ExecutionPolicy('main_policy', Runners::PHP->value, new ExecutionPolicy\Execute('main')) new ExecutionPolicy('main_policy', Runners::PHP, new ExecutionPolicy\Execute('main'))
); );
$project_manager->getProjectConfiguration()->getBuild()->setMain('main_policy'); $project_manager->getProjectConfiguration()->getBuild()->setMain('main_policy');
$project_manager->getProjectConfiguration()->getProject()->addOption(ProjectOptions::CREATE_SYMLINK->value, true); $project_manager->getProjectConfiguration()->getProject()->addOption(ProjectOptions::CREATE_SYMLINK, true);
// Create the release build configuration // Create the release build configuration
$release_executable = new BuildConfiguration('release_executable', $release_executable = new BuildConfiguration('release_executable',
'build' . DIRECTORY_SEPARATOR . 'release' . DIRECTORY_SEPARATOR . AssemblyConstants::ASSEMBLY_NAME->value 'build' . DIRECTORY_SEPARATOR . 'release' . DIRECTORY_SEPARATOR . AssemblyConstants::ASSEMBLY_NAME
); );
$release_executable->setBuildType(BuildOutputType::EXECUTABLE->value); $release_executable->setBuildType(BuildOutputType::EXECUTABLE);
$release_executable->setOption(BuildConfigurationOptions::NCC_CONFIGURATION->value, 'release'); $release_executable->setOption(BuildConfigurationOptions::NCC_CONFIGURATION, 'release');
$project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($release_executable); $project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($release_executable);
// Create the debug build configuration // Create the debug build configuration
$debug_executable = new BuildConfiguration('debug_executable', $debug_executable = new BuildConfiguration('debug_executable',
'build' . DIRECTORY_SEPARATOR . 'debug' . DIRECTORY_SEPARATOR . AssemblyConstants::ASSEMBLY_NAME->value 'build' . DIRECTORY_SEPARATOR . 'debug' . DIRECTORY_SEPARATOR . AssemblyConstants::ASSEMBLY_NAME
); );
$debug_executable->setDefinedConstant('DEBUG', '1'); $debug_executable->setDefinedConstant('DEBUG', '1');
$debug_executable->setBuildType(BuildOutputType::EXECUTABLE->value); $debug_executable->setBuildType(BuildOutputType::EXECUTABLE);
$debug_executable->setOption(BuildConfigurationOptions::NCC_CONFIGURATION->value, 'debug'); $debug_executable->setOption(BuildConfigurationOptions::NCC_CONFIGURATION, 'debug');
$project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($debug_executable); $project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($debug_executable);
self::writeProgramTemplate($project_manager); self::writeProgramTemplate($project_manager);
self::writeMainEntryTemplate($project_manager); self::writeMainEntryTemplate($project_manager);
self::writeMakefileTemplate($project_manager);
$project_manager->save(); $project_manager->save();
} }
@ -113,4 +114,22 @@
) )
); );
} }
/**
* Writes the Makefile to the project directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeMakefileTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'Makefile',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'Makefile.tpl')
)
);
}
} }

View file

@ -1,61 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2024, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension\Templates;
use ncc\Enums\Options\BuildConfigurationOptions;
use ncc\Enums\SpecialConstants\AssemblyConstants;
use ncc\Enums\Types\BuildOutputType;
use ncc\Exceptions\IOException;
use ncc\Interfaces\TemplateInterface;
use ncc\Managers\ProjectManager;
use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
class CompressedTemplate implements TemplateInterface
{
/**
* @inheritDoc
* @throws IOException
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
// Create the release build configuration
$release_compressed = new BuildConfiguration('release-compressed',
'build' . DIRECTORY_SEPARATOR . 'release' . DIRECTORY_SEPARATOR . AssemblyConstants::ASSEMBLY_PACKAGE->value . '.gz.ncc'
);
$release_compressed->setBuildType(BuildOutputType::NCC_PACKAGE->value);
$release_compressed->setOption(BuildConfigurationOptions::COMPRESSION->value, BuildConfigurationOptions\CompressionOptions::HIGH->value);
$project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($release_compressed);
// Create the debug build configuration
$debug_compressed = new BuildConfiguration('debug-compressed',
'build' . DIRECTORY_SEPARATOR . 'debug' . DIRECTORY_SEPARATOR . AssemblyConstants::ASSEMBLY_PACKAGE->value . '.gz.ncc'
);
$debug_compressed->setBuildType(BuildOutputType::NCC_PACKAGE->value);
$debug_compressed->setOption(BuildConfigurationOptions::COMPRESSION->value, BuildConfigurationOptions\CompressionOptions::HIGH->value);
$debug_compressed->setDefinedConstant('DEBUG', '1');
$project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($debug_compressed);
$project_manager->save();
}
}

View file

@ -1,77 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2024, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension\Templates;
use ncc\Enums\Options\BuildConfigurationOptions;
use ncc\Enums\SpecialConstants\AssemblyConstants;
use ncc\Enums\Types\BuildOutputType;
use ncc\Exceptions\IOException;
use ncc\Interfaces\TemplateInterface;
use ncc\Managers\ProjectManager;
use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
class ExecutableTemplate implements TemplateInterface
{
/**
* @inheritDoc
* @throws IOException
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
foreach($project_manager->getProjectConfiguration()->getBuild()->getBuildConfigurations() as $build_configuration)
{
$executable_name = sprintf('%s-executable', $build_configuration);
$configuration = $project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
// Skip if the executable version of the build configuration already exists
if($project_manager->getProjectConfiguration()->getBuild()->buildConfigurationExists($executable_name))
{
continue;
}
// Skip if the build configuration is not an ncc package that the executable can be based on
if($configuration->getBuildType() !== BuildOutputType::NCC_PACKAGE->value)
{
continue;
}
if(isset($configuration->getOptions()[BuildConfigurationOptions::COMPRESSION->value]))
{
$output = dirname($configuration->getOutput()) . DIRECTORY_SEPARATOR . str_replace('-', '_', $executable_name);
}
else
{
$output = dirname($configuration->getOutput()) . DIRECTORY_SEPARATOR . str_replace('-', '_', $executable_name) . '_gz';
}
// Create the executable build configuration
$executable = new BuildConfiguration($executable_name, $output);
$executable->setBuildType(BuildOutputType::EXECUTABLE->value);
$executable->setOption(BuildConfigurationOptions::NCC_CONFIGURATION->value, $configuration->getName());
$project_manager->getProjectConfiguration()->getBuild()->addBuildConfiguration($executable);
}
$project_manager->save();
}
}

View file

@ -1,117 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2024, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension\Templates;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Managers\ProjectManager;
use ncc\Utilities\IO;
class GitHubWorkflowTemplate
{
/**
* @inheritDoc
* @param ProjectManager $project_manager
* @throws IOException
* @throws PathNotFoundException
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
self::writeCiTemplate($project_manager);
}
/**
* Writes the Makefile to the project directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeCiTemplate(ProjectManager $project_manager): void
{
$ci_dir = $project_manager->getProjectPath() . DIRECTORY_SEPARATOR . '.github' . DIRECTORY_SEPARATOR . 'workflows';
if(!file_exists($ci_dir))
{
mkdir($ci_dir, 0777, true);
}
$template = IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'github_ci.yml.tpl');
$default_configuration = $project_manager->getProjectConfiguration()->getBuild()->getDefaultConfiguration();
$builds = [];
$releases = [];
$downloads = [];
foreach($project_manager->getProjectConfiguration()->getBuild()->getBuildConfigurations() as $build_name)
{
$build_template = IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'github_ci_build.yml.tpl');
$build_template = str_replace('%TPL_BUILD_NAME%', $build_name, $build_template);
$build_template = str_replace('%TPL_BUILD_OUTPUT%',
$project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_name)->getOutput(),
$build_template
);
$builds[$build_name] = $build_template;
$download_template = IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'github_ci_download.yml.tpl');
$download_template = str_replace('%TPL_BUILD_NAME%', $build_name, $download_template);
$downloads[$build_name] = $download_template;
$release_template = str_repeat(' ', 12) . $build_name . DIRECTORY_SEPARATOR . basename(
$project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_name)->getOutput()
);
$releases[$build_name] = $release_template;
}
$build_jobs = '';
foreach($builds as $name => $build_template)
{
$build_jobs .= $build_template . PHP_EOL;
}
$download_jobs = '';
foreach($downloads as $name => $download_template)
{
$download_jobs .= $download_template . PHP_EOL;
}
$release_jobs = '';
foreach($releases as $name => $release_template)
{
$release_jobs .= $release_template . PHP_EOL;
}
$template = str_replace('%TPL_BUILDS%', $build_jobs, $template);
$template = str_replace('%TPL_DOWNLOAD_ARTIFACTS%', $download_jobs, $template);
$template = str_replace('%TPL_ARTIFACT_FILES%', $release_jobs, $template);
$template = str_replace('%TPL_BUILD_NAMES%', implode(', ', array_keys($builds)), $template);
$template = str_replace('%TPL_DEFAULT_BUILD_CONFIGURATION%', $default_configuration, $template);
$template = str_replace('%TPL_DEFAULT_ARTIFACT_BUILD_OUTPUT%', $default_configuration . DIRECTORY_SEPARATOR . basename(
$project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($default_configuration)->getOutput()
), $template);
IO::fwrite($ci_dir . DIRECTORY_SEPARATOR . 'ncc_workflow.yml',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(), $template)
);
}
}

View file

@ -48,14 +48,8 @@
*/ */
private static function createClassTemplate(ProjectManager $project_manager): void private static function createClassTemplate(ProjectManager $project_manager): void
{ {
$class_directory = $project_manager->getProjectSourcePath() . DIRECTORY_SEPARATOR . $project_manager->getProjectConfiguration()->getAssembly()->getName();
if(!file_exists($class_directory))
{
mkdir($class_directory, 0777, true);
}
IO::fwrite( IO::fwrite(
$class_directory . DIRECTORY_SEPARATOR . $project_manager->getProjectConfiguration()->getAssembly()->getName() . '.php', $project_manager->getProjectSourcePath() . DIRECTORY_SEPARATOR . $project_manager->getProjectConfiguration()->getAssembly()->getName() . '.php',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(), ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'class.php.tpl') IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'class.php.tpl')
) )

View file

@ -1,21 +1,20 @@
# Variables # Variables
DEFAULT_CONFIGURATION ?= %TPL_DEFAULT_BUILD_CONFIGURATION% CONFIG ?= release
LOG_LEVEL = debug LOG_LEVEL = debug
OUTDIR = build/$(CONFIG)
PACKAGE = $(OUTDIR)/%ASSEMBLY.PACKAGE%.ncc
# Default Target # Default Target
all: %TPL_BUILD_NAMES% all: build
# Build Steps # Build Steps
%TPL_BUILDS% build:
ncc build --config=$(CONFIG) --log-level $(LOG_LEVEL)
install: %TPL_DEFAULT_BUILD_CONFIGURATION% install:
ncc package install --package=%TPL_DEFAULT_BUILD_PATH% --skip-dependencies --build-source --reinstall -y --log-level $(LOG_LEVEL) ncc package install --package=$(PACKAGE) --skip-dependencies --reinstall -y --log-level $(LOG_LEVEL)
test: %TPL_DEFAULT_BUILD_CONFIGURATION%
[ -f phpunit.xml ] || { echo "phpunit.xml not found"; exit 1; }
phpunit
clean: clean:
rm -rf build rm -rf build
.PHONY: all install test clean %TPL_BUILD_NAMES% .PHONY: all build install clean

View file

@ -1,78 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2024, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension\Templates;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Managers\ProjectManager;
use ncc\Utilities\IO;
class MakefileTemplate
{
/**
* @inheritDoc
* @param ProjectManager $project_manager
* @throws IOException
* @throws PathNotFoundException
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
self::writeMakefileTemplate($project_manager);
}
/**
* Writes the Makefile template for the given project.
*
* @param ProjectManager $project_manager The project manager containing project configurations.
* @throws IOException If there is an error reading or writing files.
* @throws PathNotFoundException If a required file path is not found.
*/
private static function writeMakefileTemplate(ProjectManager $project_manager): void
{
$makefile_template = IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'Makefile.tpl');
$builds = [];
foreach($project_manager->getProjectConfiguration()->getBuild()->getBuildConfigurations() as $build_name)
{
$builds[$build_name] = str_replace('%TPL_BUILD_NAME%', $build_name, IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'make_build.tpl'));
}
$default_build = $project_manager->getProjectConfiguration()->getBuild()->getDefaultConfiguration();
$makefile_template = str_replace('%TPL_DEFAULT_BUILD_CONFIGURATION%', $default_build, $makefile_template);
$makefile_template = str_replace('%TPL_DEFAULT_BUILD_PATH%', $project_manager->getProjectConfiguration()->getBuild()->getBuildConfiguration($default_build)->getOutput(), $makefile_template);
$makefile_template = str_replace('%TPL_BUILD_NAMES%', implode(' ', array_keys($builds)), $makefile_template);
$build_template = '';
foreach($builds as $name => $template)
{
$build_template .= $template . PHP_EOL;
}
$makefile_template = str_replace('%TPL_BUILDS%', $build_template, $makefile_template);
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'Makefile',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(), $makefile_template)
);
}
}

View file

@ -1,93 +0,0 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension\Templates;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Enums\Options\BuildConfigurationOptions;
use ncc\Enums\Options\ProjectOptions;
use ncc\Enums\Runners;
use ncc\Enums\SpecialConstants\AssemblyConstants;
use ncc\Enums\Types\BuildOutputType;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\TemplateInterface;
use ncc\Managers\ProjectManager;
use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Utilities\IO;
class PhpUnitTemplate implements TemplateInterface
{
/**
* Applies the necessary templates for the given project.
*
* @param ProjectManager $project_manager Manager responsible for handling project-related tasks.
*
* @return void
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
self::createPhpUnitBootstrapTemplate($project_manager);
self::createPhpUnitTemplate($project_manager);
}
/**
* Creates a PHPUnit template in the specified project directory.
*
* @param ProjectManager $project_manager The project manager instance containing project configuration and path details.
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function createPhpUnitTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'phpunit.xml',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml.tpl')
)
);
if(!file_exists($project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'tests'))
{
mkdir($project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'tests');
}
}
/**
* Creates the PHPUnit bootstrap template file for the given project.
*
* @param ProjectManager $project_manager The project manager instance handling project configuration and paths.
* @return void
*/
private static function createPhpUnitBootstrapTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'bootstrap.php',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'bootstrap.php.tpl')
)
);
}
}

View file

@ -1,3 +0,0 @@
<?php
require 'ncc';
import('%ASSEMBLY.PACKAGE%');

View file

@ -1,187 +0,0 @@
name: CI
on:
push:
branches:
- '**'
release:
types: [created]
workflow_dispatch:
jobs:
%TPL_BUILDS%
# Checking for phpunit.xml
check-phpunit:
runs-on: ubuntu-latest
outputs:
phpunit-exists: ${{ steps.check.outputs.phpunit-exists }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check for phpunit.xml
id: check
run: |
if [ -f phpunit.xml ]; then
echo "phpunit-exists=true" >> $GITHUB_OUTPUT
else
echo "phpunit-exists=false" >> $GITHUB_OUTPUT
fi
# Checking for phpdoc.dist.xml
check-phpdoc:
runs-on: ubuntu-latest
outputs:
phpdoc-exists: ${{ steps.check.outputs.phpdoc-exists }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Check for phpdoc.dist.xml
id: check
run: |
if [ -f phpdoc.dist.xml ]; then
echo "phpdoc-exists=true" >> $GITHUB_OUTPUT
else
echo "phpdoc-exists=false" >> $GITHUB_OUTPUT
fi
generate-phpdoc:
needs: [%TPL_DEFAULT_BUILD_CONFIGURATION%, check-phpdoc]
runs-on: ubuntu-latest
container:
image: php:8.3
if: needs.check-phpdoc.outputs.phpdoc-exists == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
apt update -yqq
apt install git libpq-dev libzip-dev zip make wget gnupg -yqq
- name: Download PHPDocumentor
run: |
wget https://phpdoc.org/phpDocumentor.phar
chmod +x phpDocumentor.phar
- name: Generate PHPDoc
run: |
php phpDocumentor.phar -d src -t docs
- name: Archive PHPDoc
run: |
zip -r docs.zip docs
- name: Upload PHPDoc
uses: actions/upload-artifact@v4
with:
name: documentation
path: docs.zip
test:
needs: [%TPL_BUILD_NAMES%, check-phpunit]
runs-on: ubuntu-latest
container:
image: php:8.3
if: needs.check-phpunit.outputs.phpunit-exists == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: %TPL_DEFAULT_BUILD_CONFIGURATION%
path: %TPL_DEFAULT_BUILD_CONFIGURATION%
- name: Install dependencies
run: |
apt update -yqq
apt install git libpq-dev libzip-dev zip make wget gnupg -yqq
curl -sSLf -o /usr/local/bin/install-php-extensions https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions
chmod +x /usr/local/bin/install-php-extensions
install-php-extensions zip
- name: Install phive
run: |
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
mv phive.phar /usr/local/bin/phive
- name: Install phab
run: |
phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C
- name: Install latest version of NCC
run: |
git clone https://git.n64.cc/nosial/ncc.git
cd ncc
make redist
NCC_DIR=$(find build/ -type d -name "ncc_*" | head -n 1)
if [ -z "$NCC_DIR" ]; then
echo "NCC build directory not found"
exit 1
fi
php "$NCC_DIR/INSTALL" --auto
cd .. && rm -rf ncc
- name: Install NCC packages
run: |
ncc package install --package="%TPL_DEFAULT_ARTIFACT_BUILD_OUTPUT%" --build-source --reinstall -y --log-level debug
- name: Run PHPUnit tests
run: |
wget https://phar.phpunit.de/phpunit-11.3.phar
php phpunit-11.3.phar --configuration phpunit.xml --log-junit reports/junit.xml --log-teamcity reports/teamcity --testdox-html reports/testdox.html --testdox-text reports/testdox.txt
- name: Upload test reports
uses: actions/upload-artifact@v4
with:
name: reports
path: reports
release-documentation:
needs: generate-phpdoc
permissions: write-all
runs-on: ubuntu-latest
container:
image: php:8.3
if: github.event_name == 'release'
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Download documentation artifact
uses: actions/download-artifact@v4
with:
name: documentation
path: documentation
- name: Upload documentation artifact
uses: softprops/action-gh-release@v1
with:
files: |
documentation/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
release-artifacts:
needs: [%TPL_BUILD_NAMES%]
permissions: write-all
runs-on: ubuntu-latest
container:
image: php:8.3
if: github.event_name == 'release'
steps:
- name: Checkout repository
uses: actions/checkout@v4
%TPL_DOWNLOAD_ARTIFACTS%

View file

@ -1,49 +0,0 @@
%TPL_BUILD_NAME%:
runs-on: ubuntu-latest
container:
image: php:8.3
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: |
apt update -yqq
apt install git libpq-dev libzip-dev zip make wget gnupg -yqq
- name: Install phive
run: |
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
mv phive.phar /usr/local/bin/phive
- name: Install phab
run: |
phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C
- name: Install latest version of NCC
run: |
git clone https://git.n64.cc/nosial/ncc.git
cd ncc
make redist
NCC_DIR=$(find build/ -type d -name "ncc_*" | head -n 1)
if [ -z "$NCC_DIR" ]; then
echo "NCC build directory not found"
exit 1
fi
php "$NCC_DIR/INSTALL" --auto
cd .. && rm -rf ncc
- name: Build project
run: |
ncc build --config %TPL_BUILD_NAME% --build-source --log-level debug
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: %TPL_BUILD_NAME%
path: %TPL_BUILD_OUTPUT%

View file

@ -1,12 +0,0 @@
- name: Download %TPL_BUILD_NAME% artifact
uses: actions/download-artifact@v4
with:
name: %TPL_BUILD_NAME%
path: %TPL_BUILD_NAME%
- name: Upload %TPL_BUILD_NAME% artifact to release
uses: softprops/action-gh-release@v1
with:
files: |
%TPL_BUILD_NAME%/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,2 +0,0 @@
%TPL_BUILD_NAME%:
ncc build --config=%TPL_BUILD_NAME% --log-level $(LOG_LEVEL)

View file

@ -1,11 +0,0 @@
<phpunit bootstrap="bootstrap.php">
<testsuites>
<testsuite name="%ASSEMBLY.NAME% Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<php>
<ini name="error_reporting" value="-1"/>
<server name="KERNEL_DIR" value="app/"/>
</php>
</phpunit>

View file

@ -34,7 +34,6 @@
use ncc\Enums\Versions; use ncc\Enums\Versions;
use ncc\Exceptions\ConfigurationException; use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\ImportException; use ncc\Exceptions\ImportException;
use ncc\Exceptions\IntegrityException;
use ncc\Exceptions\IOException; use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException; use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException; use ncc\Exceptions\OperationException;
@ -45,11 +44,9 @@
use ncc\Utilities\Console; use ncc\Utilities\Console;
use ncc\Utilities\IO; use ncc\Utilities\IO;
use ncc\Utilities\Resolver; use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache;
use ncc\Utilities\Validate; use ncc\Utilities\Validate;
use RuntimeException; use RuntimeException;
use Throwable; use Throwable;
use function trigger_error;
class Runtime class Runtime
{ {
@ -78,16 +75,14 @@
* This method may exit the program without returning a value * This method may exit the program without returning a value
* *
* @param string $package * @param string $package
* @param array $arguments
* @return mixed * @return mixed
* @throws ConfigurationException * @throws ConfigurationException
* @throws IOException * @throws IOException
* @throws IntegrityException
* @throws NotSupportedException * @throws NotSupportedException
* @throws OperationException
* @throws PathNotFoundException * @throws PathNotFoundException
* @throws OperationException
*/ */
public static function execute(string $package, array $arguments=[]): int public static function execute(string $package): int
{ {
if(!self::isImported($package)) if(!self::isImported($package))
{ {
@ -96,12 +91,6 @@
if(self::$imported_packages[$package] instanceof PackageReader) if(self::$imported_packages[$package] instanceof PackageReader)
{ {
if(self::$imported_packages[$package]?->getMetadata()?->getMainExecutionPolicy() === null)
{
Console::out('The package does not have a main execution policy, skipping execution');
return 0;
}
return ExecutionUnitRunner::executeFromPackage( return ExecutionUnitRunner::executeFromPackage(
self::$imported_packages[$package], self::$imported_packages[$package],
self::$imported_packages[$package]->getMetadata()->getMainExecutionPolicy() self::$imported_packages[$package]->getMetadata()->getMainExecutionPolicy()
@ -110,7 +99,7 @@
if(is_string(self::$imported_packages[$package])) if(is_string(self::$imported_packages[$package]))
{ {
$metadata_path = self::$imported_packages[$package] . DIRECTORY_SEPARATOR . FileDescriptor::METADATA->value; $metadata_path = self::$imported_packages[$package] . DIRECTORY_SEPARATOR . FileDescriptor::METADATA;
if(!is_file($metadata_path)) if(!is_file($metadata_path))
{ {
@ -119,8 +108,7 @@
return ExecutionUnitRunner::executeFromSystem( return ExecutionUnitRunner::executeFromSystem(
self::$imported_packages[$package], self::$imported_packages[$package],
Metadata::fromArray(ZiProto::decode(IO::fread($metadata_path)))->getMainExecutionPolicy(), Metadata::fromArray(ZiProto::decode(IO::fread($metadata_path)))->getMainExecutionPolicy()
$arguments
); );
} }
@ -133,7 +121,7 @@
* @return string * @return string
* @throws ImportException * @throws ImportException
*/ */
public static function import(string $package, string $version=Versions::LATEST->value): string public static function import(string $package, string $version=Versions::LATEST): string
{ {
if(self::isImported($package)) if(self::isImported($package))
{ {
@ -172,7 +160,7 @@
} }
} }
throw new RuntimeException(sprintf('Failed to import package "%s" because it does not exist', $package)); throw new RuntimeException('Importing from a package name is not supported yet');
} }
/** /**
@ -185,7 +173,7 @@
* @throws NotSupportedException * @throws NotSupportedException
* @throws PathNotFoundException * @throws PathNotFoundException
*/ */
private static function importFromSystem(string $package, string $version=Versions::LATEST->value): string private static function importFromSystem(string $package, string $version=Versions::LATEST): string
{ {
if(!self::getPackageManager()->getPackageLock()->entryExists($package)) if(!self::getPackageManager()->getPackageLock()->entryExists($package))
{ {
@ -201,81 +189,27 @@
self::$class_map[strtolower($class)] = $component_path; self::$class_map[strtolower($class)] = $component_path;
} }
if($entry->getMetadata($version)->getOption(BuildConfigurationOptions::REQUIRE_FILES->value) !== null) if($entry->getMetadata($version)->getOption(BuildConfigurationOptions::REQUIRE_FILES) !== null)
{ {
foreach($entry->getMetadata($version)->getOption(BuildConfigurationOptions::REQUIRE_FILES->value) as $item) foreach($entry->getMetadata($version)->getOption(BuildConfigurationOptions::REQUIRE_FILES) as $item)
{ {
$required_file = $entry->getPath($version) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . $item;
try try
{ {
if(!file_exists($required_file))
{
throw new PathNotFoundException($required_file);
}
// Get the file contents and prepare it // Get the file contents and prepare it
$evaluated_code = IO::fread($required_file); $required_file = IO::fread($entry->getPath($version) . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . $item);
$required_file = preg_replace('/^<\?php|<\?PHP/', '', $required_file, 1);
// Remove the PHP tags eval($required_file);
$evaluated_code = preg_replace('/^<\?php|<\?PHP/', '', $evaluated_code, 1); unset($required_file);
// Replace __DIR__ with the actual directory that the file is in }
$evaluated_code = str_replace('__DIR__', sprintf('"%s"', dirname($required_file)), $evaluated_code); catch(ConfigurationException $e)
set_error_handler(function ($error_number, $message, $file, $line) use ($item, $package)
{ {
throw new ImportException(sprintf('Fatal Evaluation Error: Failed to import "%s" from %s on %s:%s: %s', $item, $package, $file, $line, $message)); throw new ImportException(sprintf('Failed to import "%s" from %s: %s', $item, $package, $e->getMessage()), $e);
});
// Evaluate the code
eval($evaluated_code);
restore_error_handler();
unset($evaluated_code);
}
catch (ConfigurationException $e)
{
throw new ImportException(sprintf('%s: Failed to import "%s" from %s: %s', $required_file, $item, $package, $e->getMessage()), $e);
}
catch(ImportException $e)
{
throw $e;
}
catch (Throwable $e)
{
throw new ImportException(sprintf('%s: Failed to import "%s" from %s: %s', $required_file, $item, $package, $e->getMessage()), $e);
} }
} }
} }
$safe_package_name = strtoupper($entry->getAssembly($version)->getName()); if(isset($entry->getMetadata($version)->getOptions()[PackageFlags::STATIC_DEPENDENCIES]))
foreach($entry->getMetadata($version)->getConstants() as $constant => $value)
{
$constant_full_name = sprintf("%s_%s", $safe_package_name, $constant);
// Skip if already defined.
if(defined($constant_full_name))
{
if(RuntimeCache::get(sprintf("defined_%s", $constant_full_name)))
{
continue;
}
trigger_error(sprintf('Cannot define constant %s from package %s because the constant is already defined', $constant_full_name, $package), E_USER_WARNING);
continue;
}
if(!Validate::constantName($constant_full_name))
{
// trigger warning only
trigger_error(sprintf('Cannot define constant %s from package %s because the constant name is invalid', $constant_full_name, $package), E_USER_WARNING);
continue;
}
RuntimeCache::set(sprintf("defined_%s", $constant_full_name), true);
define($constant_full_name, $value);
}
if(isset($entry->getMetadata($version)->getOptions()[PackageFlags::STATIC_DEPENDENCIES->value]))
{ {
// Fake import the dependencies // Fake import the dependencies
foreach($entry->getVersion($version)->getDependencies() as $dependency) foreach($entry->getVersion($version)->getDependencies() as $dependency)
@ -303,7 +237,7 @@
* @return string * @return string
* @throws ConfigurationException * @throws ConfigurationException
* @throws ImportException * @throws ImportException
* @throws IntegrityException * @throws NotSupportedException
* @throws OperationException * @throws OperationException
*/ */
private static function importFromPackage(string $package_path): string private static function importFromPackage(string $package_path): string
@ -339,9 +273,9 @@
} }
// Import the required files // Import the required files
if($package_reader->getMetadata()->getOption(BuildConfigurationOptions::REQUIRE_FILES->value) !== null) if($package_reader->getMetadata()->getOption(BuildConfigurationOptions::REQUIRE_FILES) !== null)
{ {
foreach($package_reader->getMetadata()->getOption(BuildConfigurationOptions::REQUIRE_FILES->value) as $item) foreach($package_reader->getMetadata()->getOption(BuildConfigurationOptions::REQUIRE_FILES) as $item)
{ {
try try
{ {
@ -354,7 +288,7 @@
} }
} }
if($package_reader->getFlag(PackageFlags::STATIC_DEPENDENCIES->value)) if($package_reader->getFlag(PackageFlags::STATIC_DEPENDENCIES))
{ {
// Fake import the dependencies // Fake import the dependencies
foreach($package_reader->getDependencies() as $dependency_name) foreach($package_reader->getDependencies() as $dependency_name)
@ -522,7 +456,6 @@
* @throws IOException * @throws IOException
* @throws OperationException * @throws OperationException
* @throws PathNotFoundException * @throws PathNotFoundException
* @throws IntegrityException
*/ */
private static function acquireFile(string $path, ?string $package=null): string private static function acquireFile(string $path, ?string $package=null): string
{ {
@ -547,8 +480,8 @@
return match (Resolver::componentType($acquired_file)) return match (Resolver::componentType($acquired_file))
{ {
PackageDirectory::RESOURCES->value => self::$imported_packages[$package]->getResource(Resolver::componentName($acquired_file))->getData(), PackageDirectory::RESOURCES => self::$imported_packages[$package]->getResource(Resolver::componentName($acquired_file))->getData(),
PackageDirectory::COMPONENTS->value => self::$imported_packages[$package]->getComponent(Resolver::componentName($acquired_file))->getData([ComponentDecodeOptions::AS_FILE->value]), PackageDirectory::COMPONENTS => self::$imported_packages[$package]->getComponent(Resolver::componentName($acquired_file))->getData([ComponentDecodeOptions::AS_FILE]),
default => throw new IOException(sprintf('Unable to acquire file "%s" from package "%s" because it is not a resource or component', $path, $package)), default => throw new IOException(sprintf('Unable to acquire file "%s" from package "%s" because it is not a resource or component', $path, $package)),
}; };
} }
@ -639,16 +572,9 @@
return; return;
} }
$acquired_name = $path; if(!in_array($path, self::$included_files, true))
if(!is_file($path))
{ {
$acquired_name = hash('crc32', $acquired_file); self::$included_files[] = $path;
}
if(!in_array($acquired_name, self::$included_files, true))
{
self::$included_files[] = sprintf('virtual(%s)', $acquired_name);
} }
self::extendedEvaluate($acquired_file); self::extendedEvaluate($acquired_file);
@ -691,16 +617,9 @@
throw new RuntimeException(sprintf('Failed to acquire file "%s" at runtime: %s', $path, $e->getMessage()), $e->getCode(), $e); throw new RuntimeException(sprintf('Failed to acquire file "%s" at runtime: %s', $path, $e->getMessage()), $e->getCode(), $e);
} }
$acquired_name = $path; if(!in_array($path, self::$included_files, true))
if(!is_file($path))
{ {
$acquired_name = hash('crc32', $acquired_file); self::$included_files[] = $path;
}
if(!in_array($acquired_name, self::$included_files, true))
{
self::$included_files[] = sprintf('virtual(%s)', $acquired_name);
} }
self::extendedEvaluate($acquired_file); self::extendedEvaluate($acquired_file);

View file

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

View file

@ -24,6 +24,5 @@
final class CompilerExtensionSupportedVersions final class CompilerExtensionSupportedVersions
{ {
// TODO: Cannot convert this to enum, try another way
public const PHP = ['8.0', '8.1', '8.2']; public const PHP = ['8.0', '8.1', '8.2'];
} }

View file

@ -22,7 +22,11 @@
namespace ncc\Enums; namespace ncc\Enums;
enum CompilerExtensions : string final class CompilerExtensions
{ {
case PHP = 'php'; public const PHP = 'php';
public const ALL = [
CompilerExtensions::PHP
];
} }

View file

@ -0,0 +1,33 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Enums;
final class ComponentFileExtensions
{
/**
* The file extensions that the PHP compiler extension will accept as components.
*
* @var array
*/
public const PHP = ['*.php', '*.php3', '*.php4', '*.php5', '*.phtml'];
}

View file

@ -22,39 +22,39 @@
namespace ncc\Enums; namespace ncc\Enums;
enum ConsoleColors : string final class ConsoleColors
{ {
case DEFAULT = "\e[39m"; public const DEFAULT = "\e[39m";
case BLACK = "\e[30m"; public const BLACK = "\e[30m";
case RED = "\e[31m"; public const RED = "\e[31m";
case GREEN = "\e[32m"; public const GREEN = "\e[32m";
case YELLOW = "\e[33m"; public const YELLOW = "\e[33m";
case BLUE = "\e[34m"; public const BLUE = "\e[34m";
case MAGENTA = "\e[35m"; public const MAGENTA = "\e[35m";
case CYAN = "\e[36m"; public const CYAN = "\e[36m";
case LIGHT_GREY = "\e[37m"; public const LIGHT_GREY = "\e[37m";
case DARK_GREY = "\e[90m"; public const DARK_GREY = "\e[90m";
case LIGHT_RED = "\e[91m"; public const LIGHT_RED = "\e[91m";
case LIGHT_GREEN = "\e[92m"; public const LIGHT_GREEN = "\e[92m";
case LIGHT_YELLOW = "\e[93m"; public const LIGHT_YELLOW = "\e[93m";
case LIGHT_BLUE = "\e[94m"; public const LIGHT_BLUE = "\e[94m";
case LIGHT_MAGENTA = "\e[95m"; public const LIGHT_MAGENTA = "\e[95m";
case LIGHT_CYAN = "\e[96m"; public const LIGHT_CYAN = "\e[96m";
case WHITE = "\e[97m"; public const WHITE = "\e[97m";
} }

View file

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

View file

@ -26,80 +26,98 @@
* @author Zi Xing Narrakas * @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved. * @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved.
*/ */
enum ExceptionCodes : int final class ExceptionCodes
{ {
/** /**
* @see RuntimeException * @see RuntimeException
*/ */
case RUNTIME = -1706; public const RUNTIME = -1706;
/** /**
* @see BuildException * @see BuildException
*/ */
case BUILD_EXCEPTION = -1727; public const BUILD_EXCEPTION = -1727;
/** /**
* @see IOException * @see IOException
*/ */
case IO_EXCEPTION = -1735; public const IO_EXCEPTION = -1735;
/** /**
* @see ComposerException * @see ComposerException
*/ */
case COMPOSER_EXCEPTION = -1749; public const COMPOSER_EXCEPTION = -1749;
/** /**
* @see AuthenticationException * @see AuthenticationException
*/ */
case AUTHENTICATION_EXCEPTION = -1760; public const AUTHENTICATION_EXCEPTION = -1760;
/** /**
* @see NotSupportedException * @see NotSupportedException
*/ */
case NOT_SUPPORTED_EXCEPTION = -1761; public const NOT_SUPPORTED_EXCEPTION = -1761;
/** /**
* @see ArchiveException * @see ArchiveException
*/ */
case ARCHIVE_EXCEPTION = -1764; public const ARCHIVE_EXCEPTION = -1764;
/** /**
* @see PathNotFoundException * @see PathNotFoundException
*/ */
case PATH_NOT_FOUND = -1769; public const PATH_NOT_FOUND = -1769;
/** /**
* @see GitException * @see GitException
*/ */
case GIT_EXCEPTION = -1770; public const GIT_EXCEPTION = -1770;
/** /**
* @see ConfigurationException * @see ConfigurationException
*/ */
case CONFIGURATION_EXCEPTION = -1772; public const CONFIGURATION_EXCEPTION = -1772;
/** /**
* @see PackageException * @see PackageException
*/ */
case PACKAGE_EXCEPTION = -1773; public const PACKAGE_EXCEPTION = -1773;
/** /**
* @see NetworkException * @see NetworkException
*/ */
case NETWORK_EXCEPTION = -1774; public const NETWORK_EXCEPTION = -1774;
/** /**
* @see IntegrityException * @see IntegrityException
*/ */
case INTEGRITY_EXCEPTION = -1775; public const INTEGRITY_EXCEPTION = -1775;
/** /**
* @see OperationException * @see OperationException
*/ */
case OPERATION_EXCEPTION = -1776; public const OPERATION_EXCEPTION = -1776;
public const IMPORT_EXCEPTION = -1777;
/** /**
* @see ImportException * All the exception codes from NCC
*/ */
case IMPORT_EXCEPTION = -1777; public const All = [
self::RUNTIME,
self::BUILD_EXCEPTION,
self::IO_EXCEPTION,
self::COMPOSER_EXCEPTION,
self::AUTHENTICATION_EXCEPTION,
self::NOT_SUPPORTED_EXCEPTION,
self::ARCHIVE_EXCEPTION,
self::PATH_NOT_FOUND,
self::GIT_EXCEPTION,
self::CONFIGURATION_EXCEPTION,
self::PACKAGE_EXCEPTION,
self::NETWORK_EXCEPTION,
self::INTEGRITY_EXCEPTION,
self::OPERATION_EXCEPTION,
self::IMPORT_EXCEPTION
];
} }

View file

@ -22,17 +22,17 @@
namespace ncc\Enums; namespace ncc\Enums;
enum FileDescriptor : string final class FileDescriptor
{ {
case ASSEMBLY = 'ASSEMBLY'; public const ASSEMBLY = 'ASSEMBLY';
case METADATA = 'METADATA'; public const METADATA = 'METADATA';
case INSTALLER = 'INSTALLER'; public const INSTALLER = 'INSTALLER';
case CLASS_MAP = 'CLASS_MAP'; public const CLASS_MAP = 'CLASS_MAP';
case UPDATE = 'UPDATE'; public const UPDATE = 'UPDATE';
case SHADOW_PACKAGE = 'SHADOW_PKG'; public const SHADOW_PACKAGE = 'SHADOW_PKG';
} }

View file

@ -22,15 +22,23 @@
namespace ncc\Enums\Flags; namespace ncc\Enums\Flags;
enum ComponentFlags : string final class ComponentFlags
{ {
/** /**
* Indicates that the component is the AST of a PHP file encoded with msgpack. * Indicates that the component is the AST of a PHP file encoded with msgpack.
*/ */
case PHP_AST = 'php_ast'; public const PHP_AST = 'php_ast';
/** /**
* Indicates that the component is a PHP file encoded with base64. * Indicates that the component is a PHP file encoded with base64.
*/ */
case PHP_B64 = 'php_b64'; public const PHP_B64 = 'php_b64';
/**
* All the possible flags of a component
*/
public const ALL = [
self::PHP_AST,
self::PHP_B64
];
} }

View file

@ -22,16 +22,16 @@
namespace ncc\Enums\Flags; namespace ncc\Enums\Flags;
enum NccBuildFlags : string final class NccBuildFlags
{ {
/** /**
* Indicates if the build is currently unstable and some features may not work correctly * Indicates if the build is currently unstable and some features may not work correctly
* and can cause errors * and can cause errors
*/ */
case UNSTABLE = 'unstable'; public const UNSTABLE = 'unstable';
/** /**
* Indicates if the build is currently in beta testing phase * Indicates if the build is currently in beta testing phase
*/ */
case BETA = 'beta'; public const BETA = 'beta';
} }

View file

@ -22,15 +22,15 @@
namespace ncc\Enums\Flags; namespace ncc\Enums\Flags;
enum PackageFlags : string final class PackageFlags
{ {
case COMPRESSION = 'gzip'; public const COMPRESSION = 'gzip';
case LOW_COMPRESSION = 'low_gz`'; public const LOW_COMPRESSION = 'low_gz`';
case MEDIUM_COMPRESSION = 'medium_gz'; public const MEDIUM_COMPRESSION = 'medium_gz';
case HIGH_COMPRESSION = 'high_gz'; public const HIGH_COMPRESSION = 'high_gz';
case STATIC_DEPENDENCIES = 'static_dependencies'; public const STATIC_DEPENDENCIES = 'static_dependencies';
} }

View file

@ -0,0 +1,124 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Enums;
final class HttpStatusCodes
{
public const OK = 200;
public const CREATED = 201;
public const ACCEPTED = 202;
public const NO_CONTENT = 204;
public const MOVED_PERMANENTLY = 301;
public const FOUND = 302;
public const SEE_OTHER = 303;
public const NOT_MODIFIED = 304;
public const TEMPORARY_REDIRECT = 307;
public const PERMANENT_REDIRECT = 308;
public const BAD_REQUEST = 400;
public const UNAUTHORIZED = 401;
public const FORBIDDEN = 403;
public const NOT_FOUND = 404;
public const METHOD_NOT_ALLOWED = 405;
public const NOT_ACCEPTABLE = 406;
public const REQUEST_TIMEOUT = 408;
public const CONFLICT = 409;
public const GONE = 410;
public const LENGTH_REQUIRED = 411;
public const PRECONDITION_FAILED = 412;
public const PAYLOAD_TOO_LARGE = 413;
public const URI_TOO_LONG = 414;
public const UNSUPPORTED_MEDIA_TYPE = 415;
public const RANGE_NOT_SATISFIABLE = 416;
public const EXPECTATION_FAILED = 417;
public const IM_A_TEAPOT = 418;
public const MISDIRECTED_REQUEST = 421;
public const UNPROCESSABLE_ENTITY = 422;
public const LOCKED = 423;
public const FAILED_DEPENDENCY = 424;
public const UPGRADE_REQUIRED = 426;
public const PRECONDITION_REQUIRED = 428;
public const TOO_MANY_REQUESTS = 429;
public const REQUEST_HEADER_FIELDS_TOO_LARGE = 431;
public const UNAVAILABLE_FOR_LEGAL_REASONS = 451;
public const INTERNAL_SERVER_ERROR = 500;
public const NOT_IMPLEMENTED = 501;
public const BAD_GATEWAY = 502;
public const SERVICE_UNAVAILABLE = 503;
public const GATEWAY_TIMEOUT = 504;
public const HTTP_VERSION_NOT_SUPPORTED = 505;
public const VARIANT_ALSO_NEGOTIATES = 506;
public const INSUFFICIENT_STORAGE = 507;
public const LOOP_DETECTED = 508;
public const NOT_EXTENDED = 510;
public const NETWORK_AUTHENTICATION_REQUIRED = 511;
public const ALL = [
self::OK,
self::CREATED,
self::ACCEPTED,
self::NO_CONTENT,
self::MOVED_PERMANENTLY,
self::FOUND,
self::SEE_OTHER,
self::NOT_MODIFIED,
self::TEMPORARY_REDIRECT,
self::PERMANENT_REDIRECT,
self::BAD_REQUEST,
self::UNAUTHORIZED,
self::FORBIDDEN,
self::NOT_FOUND,
self::METHOD_NOT_ALLOWED,
self::NOT_ACCEPTABLE,
self::REQUEST_TIMEOUT,
self::CONFLICT,
self::GONE,
self::LENGTH_REQUIRED,
self::PRECONDITION_FAILED,
self::PAYLOAD_TOO_LARGE,
self::URI_TOO_LONG,
self::UNSUPPORTED_MEDIA_TYPE,
self::RANGE_NOT_SATISFIABLE,
self::EXPECTATION_FAILED,
self::IM_A_TEAPOT,
self::MISDIRECTED_REQUEST,
self::UNPROCESSABLE_ENTITY,
self::LOCKED,
self::FAILED_DEPENDENCY,
self::UPGRADE_REQUIRED,
self::PRECONDITION_REQUIRED,
self::TOO_MANY_REQUESTS,
self::REQUEST_HEADER_FIELDS_TOO_LARGE,
self::UNAVAILABLE_FOR_LEGAL_REASONS,
self::INTERNAL_SERVER_ERROR,
self::NOT_IMPLEMENTED,
self::BAD_GATEWAY,
self::SERVICE_UNAVAILABLE,
self::GATEWAY_TIMEOUT,
self::HTTP_VERSION_NOT_SUPPORTED,
self::VARIANT_ALSO_NEGOTIATES,
self::INSUFFICIENT_STORAGE,
self::LOOP_DETECTED,
self::NOT_EXTENDED,
self::NETWORK_AUTHENTICATION_REQUIRED
];
}

View file

@ -22,65 +22,29 @@
namespace ncc\Enums; namespace ncc\Enums;
use ncc\Utilities\Validate; final class LogLevel
enum LogLevel : string
{ {
case SILENT = 'silent'; public const SILENT = 'silent';
case VERBOSE = 'verbose'; public const VERBOSE = 'verbose';
case DEBUG = 'debug'; public const DEBUG = 'debug';
case INFO = 'info'; public const INFO = 'info';
case WARNING = 'warn'; public const WARNING = 'warn';
case ERROR = 'error'; public const ERROR = 'error';
case FATAL = 'fatal'; public const FATAL = 'fatal';
/** public const ALL = [
* Checks if the current log level permits logging at the specified level. self::SILENT,
* self::VERBOSE,
* @param LogLevel|null $current_level The log level to be checked. If null, the method returns false. self::DEBUG,
* @return bool Returns true if logging is permitted at the specified level, otherwise false. self::INFO,
*/ self::WARNING,
public function checkLogLevel(?LogLevel $current_level): bool self::ERROR,
{ self::FATAL,
if ($current_level === null) ];
{
return false;
}
return match ($current_level)
{
LogLevel::DEBUG => in_array($this, [LogLevel::DEBUG, LogLevel::VERBOSE, LogLevel::INFO, LogLevel::WARNING, LogLevel::FATAL, LogLevel::ERROR], true),
LogLevel::VERBOSE => in_array($this, [LogLevel::VERBOSE, LogLevel::INFO, LogLevel::WARNING, LogLevel::FATAL, LogLevel::ERROR], true),
LogLevel::INFO => in_array($this, [LogLevel::INFO, LogLevel::WARNING, LogLevel::FATAL, LogLevel::ERROR], true),
LogLevel::WARNING => in_array($this, [LogLevel::WARNING, LogLevel::FATAL, LogLevel::ERROR], true),
LogLevel::ERROR => in_array($this, [LogLevel::FATAL, LogLevel::ERROR], true),
LogLevel::FATAL => $this === LogLevel::FATAL,
default => false,
};
}
/**
* Converts the given string input to a LogLevel.
* If the input is invalid or not found, it defaults to LogLevel::INFO.
*
* @param string $input The input string to be converted to a LogLevel.
* @return LogLevel Returns the corresponding LogLevel for the input string or LogLevel::INFO if not found.
*/
public static function fromOrDefault(string $input): LogLevel
{
$value = self::tryFrom($input);
if($value === null)
{
return self::INFO;
}
return $value;
}
} }

View file

@ -22,15 +22,15 @@
namespace ncc\Enums\Options; namespace ncc\Enums\Options;
enum BuildConfigurationOptions : string final class BuildConfigurationOptions
{ {
case COMPRESSION = 'compression'; public const COMPRESSION = 'compression';
case REQUIRE_FILES = 'require_files'; public const REQUIRE_FILES = 'require_files';
case NCC_CONFIGURATION = 'ncc_configuration'; public const NCC_CONFIGURATION = 'ncc_configuration';
case OUTPUT_FILE = 'output_file'; public const OUTPUT_FILE = 'output_file';
case STATIC_DEPENDENCIES = 'static'; public const STATIC_DEPENDENCIES = 'static';
} }

View file

@ -22,11 +22,11 @@
namespace ncc\Enums\Options\BuildConfigurationOptions; namespace ncc\Enums\Options\BuildConfigurationOptions;
enum CompressionOptions : string final class CompressionOptions
{ {
case HIGH = 'high'; public const HIGH = 'high';
case MEDIUM = 'medium'; public const MEDIUM = 'medium';
case LOW = 'low'; public const LOW = 'low';
} }

View file

@ -22,9 +22,9 @@
namespace ncc\Enums\Options; namespace ncc\Enums\Options;
enum BuildConfigurationValues : string final class BuildConfigurationValues
{ {
case DEFAULT = 'default'; public const DEFAULT = 'default';
case ALL = 'all'; public const ALL = 'all';
} }

View file

@ -22,7 +22,7 @@
namespace ncc\Enums\Options; namespace ncc\Enums\Options;
enum ComponentDecodeOptions : string final class ComponentDecodeOptions
{ {
case AS_FILE = 'as_file'; public const AS_FILE = 'as_file';
} }

View file

@ -22,25 +22,25 @@
namespace ncc\Enums\Options; namespace ncc\Enums\Options;
enum InitializeProjectOptions : string final class InitializeProjectOptions
{ {
/** /**
* A custom path to the project's source directory * A custom path to the project's source directory
*/ */
case PROJECT_SRC_PATH = 'PROJECT_SRC_PATH'; public const PROJECT_SRC_PATH = 'PROJECT_SRC_PATH';
/** /**
* A boolean option that indicates whether to overwrite the project file if it already exists * A boolean option that indicates whether to overwrite the project file if it already exists
*/ */
case OVERWRITE_PROJECT_FILE = 'OVERWRITE_PROJECT_FILE'; public const OVERWRITE_PROJECT_FILE = 'OVERWRITE_PROJECT_FILE';
/** /**
* Composer Only, used to define the package's real version * Composer Only, used to define the package's real version
*/ */
case COMPOSER_PACKAGE_VERSION = 'COMPOSER_PACKAGE_VERSION'; public const COMPOSER_PACKAGE_VERSION = 'COMPOSER_PACKAGE_VERSION';
/** /**
* Composer Only, used to define the package's update source * Composer Only, used to define the package's update source
*/ */
case COMPOSER_REMOTE_SOURCE = 'COMPOSER_REMOTE_SOURCE'; public const COMPOSER_REMOTE_SOURCE = 'COMPOSER_REMOTE_SOURCE';
} }

View file

@ -22,7 +22,7 @@
namespace ncc\Enums\Options; namespace ncc\Enums\Options;
enum InstallPackageOptions : string final class InstallPackageOptions
{ {
/** /**
* Skips the installation of dependencies of the package * Skips the installation of dependencies of the package
@ -30,23 +30,17 @@
* @warning This will cause the package to fail to import of * @warning This will cause the package to fail to import of
* the dependencies are not met * the dependencies are not met
*/ */
case SKIP_DEPENDENCIES = 'skip-dependencies'; public const SKIP_DEPENDENCIES = 'skip_dependencies';
/** /**
* Reinstall all packages if they are already installed, * Reinstall all packages if they are already installed,
* Including dependencies if they are being processed. * Including dependencies if they are being processed.
*/ */
case REINSTALL = 'reinstall'; public const REINSTALL = 'reinstall';
/** /**
* Installs a static version of the package if it's available * Installs a static version of the package if it's available
* otherwise it will install non-static version * otherwise it will install non-static version
*/ */
case PREFER_STATIC = 'prefer-static'; public const PREFER_STATIC = 'prefer_static';
/**
* Forces ncc to build packages from source rather than trying to obtain
* a pre-built version of the package
*/
case BUILD_SOURCE = 'build-source';
} }

View file

@ -22,7 +22,7 @@
namespace ncc\Enums\Options; namespace ncc\Enums\Options;
enum ProjectOptions : string final class ProjectOptions
{ {
case CREATE_SYMLINK = 'create_symlink'; public const CREATE_SYMLINK = 'create_symlink';
} }

View file

@ -0,0 +1,38 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Enums\Options;
final class RuntimeImportOptions
{
/**
* Indicates if the import should require PHP's autoload.php file
* for the package (Only applies to PHP packages)
*/
public const IMPORT_AUTOLOADER = 'import_autoloader';
/**
* Indicates if the import should require all static files
* for the package (Only applies to PHP packages)
*/
public const IMPORT_STATIC_FILES = 'import_static_files';
}

View file

@ -22,21 +22,21 @@
namespace ncc\Enums; namespace ncc\Enums;
enum PackageDirectory : int final class PackageDirectory
{ {
case ASSEMBLY = 0x61737365; public const ASSEMBLY = 0x61737365;
case METADATA = 0x6D657461; public const METADATA = 0x6D657461;
case INSTALLER = 0x696E7374; public const INSTALLER = 0x696E7374;
case DEPENDENCIES = 0x64657065; public const DEPENDENCIES = 0x64657065;
case EXECUTION_UNITS = 0x65786563; public const EXECUTION_UNITS = 0x65786563;
case COMPONENTS = 0x636F6D70; public const COMPONENTS = 0x636F6D70;
case RESOURCES = 0x7265736F; public const RESOURCES = 0x7265736F;
case CLASS_POINTER = 0x636C6173; public const CLASS_POINTER = 0x636C6173;
} }

View file

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

View file

@ -22,11 +22,11 @@
namespace ncc\Enums; namespace ncc\Enums;
enum PackageStructure : int final class PackageStructure
{ {
case FILE_VERSION = 0x73746669; public const FILE_VERSION = 0x73746669;
case FLAGS = 0x73736166; public const FLAGS = 0x73736166;
case DIRECTORY = 0x6f746365; public const DIRECTORY = 0x6f746365;
} }

View file

@ -1,5 +1,5 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2023, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
@ -20,17 +20,25 @@
* *
*/ */
namespace ncc\Enums; namespace ncc\Enums;
enum PackageStructureVersions : string final class PackageStructureVersions
{ {
/** /**
* ncc 1.0.0 to 1.0.3 * ncc 1.0.0 to 1.0.3
*/ */
case _1_0 = '1.0'; public const _1_0 = '1.0';
/** /**
* ncc 1.0.4 and above * ncc 1.0.4 and above
*/ */
case _2_0 = '2.0'; public const _2_0 = '2.0';
/**
* All supported versions
*/
public const ALL = [
self::_1_0,
self::_2_0
];
} }

View file

@ -22,81 +22,23 @@
namespace ncc\Enums; namespace ncc\Enums;
enum ProjectTemplates : string final class ProjectTemplates
{ {
/** /**
* A template that is used to create a PHP library project * A template that is used to create a PHP library project
*/ */
case PHP_LIBRARY = 'phplib'; public const PHP_LIBRARY = 'phplib';
/** /**
* A template that is used to create a PHP CLI application project * A template that is used to create a PHP CLI application project
*/ */
case PHP_CLI = 'phpcli'; public const PHP_CLI = 'phpcli';
/** /**
* A template for generating a Makefile for the PHP project * An array of all the available project templates
*/ */
case PHP_MAKE = 'phpmake'; public const ALL = [
self::PHP_LIBRARY,
/** self::PHP_CLI
* A template used for creating PHP Unit testing bootstrap ];
*/
case PHP_UNIT = 'phpunit';
/**
* A template that is used to create a PHP executable project
*/
case PHP_COMPRESSED = 'phpgz';
/**
* A template that is used to create a PHP executable project
*/
case PHP_EXECUTABLE = 'phpexe';
/**
* Template that combines PHP_LIBRARY, PHP_MAKE and PHP_UNIT in one
*/
case PHP_LIBRARY_FULL = 'phplib_full';
/**
* Template that combines PHP_LIBRARY, PHP_MAKE, PHP_UNIT and PHP_CLI in one
*/
case PHP_CLI_FULL = 'phpcli_full';
/**
* Template that applies a GitHub workflow CI that builds the project, tests the project and creates
* automatic builds for releases
*/
case PHP_GITHUB_CI = 'phpci_github';
/**
* Suggests the closest matching `ProjectTemplates` instance based on the given input string.
*
* @param string $input The input string to compare against.
* @return ProjectTemplates|null The closest matching `ProjectTemplates` instance, or null if no close match is found.
*/
public static function suggest(string $input): ?ProjectTemplates
{
$closest = null;
$shortest_distance = -1;
foreach (self::cases() as $case)
{
$distance = levenshtein($input, $case->value);
if ($distance === 0)
{
return $case;
}
if ($shortest_distance === -1 || $distance < $shortest_distance)
{
$closest = $case;
$shortest_distance = $distance;
}
}
return $closest ?: null;
}
} }

View file

@ -26,27 +26,27 @@
* @author Zi Xing Narrakas * @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved. * @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved.
*/ */
enum RegexPatterns : string final class RegexPatterns
{ {
case UUID = '{^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$}Di'; public const UUID = '{^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$}Di';
case PACKAGE_NAME_FORMAT = '/^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$/'; public const PACKAGE_NAME_FORMAT = '/^[a-z][a-z0-9_]*(\.[a-z0-9_]+)+[0-9a-z_]$/';
case COMPOSER_VERSION_FORMAT = '/^([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/'; public const COMPOSER_VERSION_FORMAT = '/^([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/';
case PYTHON_VERSION_FORMAT = '/^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/'; public const PYTHON_VERSION_FORMAT = '/^([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+)?$/';
case SEMANTIC_VERSIONING_2 = '/^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/m'; public const SEMANTIC_VERSIONING_2 = '/^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/m';
case UNIX_PATH = '/^(((?:\.\/|\.\.\/|\/)?(?:\.?\w+\/)*)(\.?\w+\.?\w+))$/m'; public const UNIX_PATH = '/^(((?:\.\/|\.\.\/|\/)?(?:\.?\w+\/)*)(\.?\w+\.?\w+))$/m';
case CONSTANT_NAME = '/^([^\x00-\x7F]|[\w_.+]){2,64}$/'; public const CONSTANT_NAME = '/^([^\x00-\x7F]|[\w_\ \.\+\-]){2,64}$/';
case EXECUTION_POLICY_NAME = '/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/m'; public const EXECUTION_POLICY_NAME = '/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/m';
/** /**
* @author <purplex> * @author <purplex>
*/ */
case REMOTE_PACKAGE = '/^(?<vendor>[^\/\n]+)\/(?<package>[^:=\n@]+)(?:=(?<version>[^:@\n]+))?(?::(?<branch>[^@\n]+))?@(?<source>.*)$/m'; public const REMOTE_PACKAGE = '/^(?<vendor>[^\/\n]+)\/(?<package>[^:=\n@]+)(?:=(?<version>[^:@\n]+))?(?::(?<branch>[^@\n]+))?@(?<source>.*)$/m';
} }

View file

@ -22,15 +22,25 @@
namespace ncc\Enums; namespace ncc\Enums;
enum Runners : string final class Runners
{ {
case PHP = 'php'; public const PHP = 'php';
case BASH = 'bash'; public const BASH = 'bash';
case PYTHON = 'python'; public const PYTHON = 'python';
case PERL = 'perl'; public const PERL = 'perl';
case LUA = 'lua'; public const LUA = 'lua';
public const ALL = [
self::PHP,
self::BASH,
self::PYTHON,
self::PYTHON_3,
self::PYTHON_2,
self::PERL,
self::LUA
];
} }

View file

@ -22,9 +22,9 @@
namespace ncc\Enums; namespace ncc\Enums;
enum Scopes : string final class Scopes
{ {
case USER = 'USER'; public const USER = 'USER';
case SYSTEM = 'SYSTEM'; public const SYSTEM = 'SYSTEM';
} }

View file

@ -22,50 +22,50 @@
namespace ncc\Enums\SpecialConstants; namespace ncc\Enums\SpecialConstants;
enum AssemblyConstants : string final class AssemblyConstants
{ {
/** /**
* Assembly's Name Property * Assembly's Name Property
*/ */
case ASSEMBLY_NAME = '%ASSEMBLY.NAME%'; public const ASSEMBLY_NAME = '%ASSEMBLY.NAME%';
/** /**
* Assembly's Package Property * Assembly's Package Property
*/ */
case ASSEMBLY_PACKAGE = '%ASSEMBLY.PACKAGE%'; public const ASSEMBLY_PACKAGE = '%ASSEMBLY.PACKAGE%';
/** /**
* Assembly's Description Property * Assembly's Description Property
*/ */
case ASSEMBLY_DESCRIPTION = '%ASSEMBLY.DESCRIPTION%'; public const ASSEMBLY_DESCRIPTION = '%ASSEMBLY.DESCRIPTION%';
/** /**
* Assembly's Company Property * Assembly's Company Property
*/ */
case ASSEMBLY_COMPANY = '%ASSEMBLY.COMPANY%'; public const ASSEMBLY_COMPANY = '%ASSEMBLY.COMPANY%';
/** /**
* Assembly's Product Property * Assembly's Product Property
*/ */
case ASSEMBLY_PRODUCT = '%ASSEMBLY.PRODUCT%'; public const ASSEMBLY_PRODUCT = '%ASSEMBLY.PRODUCT%';
/** /**
* Assembly's Copyright Property * Assembly's Copyright Property
*/ */
case ASSEMBLY_COPYRIGHT = '%ASSEMBLY.COPYRIGHT%'; public const ASSEMBLY_COPYRIGHT = '%ASSEMBLY.COPYRIGHT%';
/** /**
* Assembly's Trademark Property * Assembly's Trademark Property
*/ */
case ASSEMBLY_TRADEMARK = '%ASSEMBLY.TRADEMARK%'; public const ASSEMBLY_TRADEMARK = '%ASSEMBLY.TRADEMARK%';
/** /**
* Assembly's Version Property * Assembly's Version Property
*/ */
case ASSEMBLY_VERSION = '%ASSEMBLY.VERSION%'; public const ASSEMBLY_VERSION = '%ASSEMBLY.VERSION%';
/** /**
* Assembly's UUID property * Assembly's UUID property
*/ */
case ASSEMBLY_UID = '%ASSEMBLY.UID%'; public const ASSEMBLY_UID = '%ASSEMBLY.UID%';
} }

View file

@ -22,25 +22,25 @@
namespace ncc\Enums\SpecialConstants; namespace ncc\Enums\SpecialConstants;
enum BuildConstants : string final class BuildConstants
{ {
/** /**
* The Unix Timestamp for when the package was compiled * The Unix Timestamp for when the package was compiled
*/ */
case COMPILE_TIMESTAMP = '%COMPILE_TIMESTAMP%'; public const COMPILE_TIMESTAMP = '%COMPILE_TIMESTAMP%';
/** /**
* The version of NCC that was used to compile the package * The version of NCC that was used to compile the package
*/ */
case NCC_BUILD_VERSION = '%NCC_BUILD_VERSION%'; public const NCC_BUILD_VERSION = '%NCC_BUILD_VERSION%';
/** /**
* NCC Build Flags exploded into spaces * NCC Build Flags exploded into spaces
*/ */
case NCC_BUILD_FLAGS = '%NCC_BUILD_FLAGS%'; public const NCC_BUILD_FLAGS = '%NCC_BUILD_FLAGS%';
/** /**
* NCC Build Branch * NCC Build Branch
*/ */
case NCC_BUILD_BRANCH = '%NCC_BUILD_BRANCH%'; public const NCC_BUILD_BRANCH = '%NCC_BUILD_BRANCH%';
} }

View file

@ -22,49 +22,49 @@
namespace ncc\Enums\SpecialConstants; namespace ncc\Enums\SpecialConstants;
enum DateTimeConstants : string final class DateTimeConstants
{ {
// Day Format // Day Format
/** /**
* Day of the month, 2 digits with leading zeros * Day of the month, 2 digits with leading zeros
*/ */
case d = '%d%'; // 01 through 31 public const d = '%d%'; // 01 through 31
/** /**
* A textual representation of a day, three letters * A textual representation of a day, three letters
*/ */
case D = '%D%'; // Mon through Sun public const D = '%D%'; // Mon through Sun
/** /**
* Day of the month without leading zeros * Day of the month without leading zeros
*/ */
case j = '%j%'; // 1 through 31 public const j = '%j%'; // 1 through 31
/** /**
* A full textual representation of the day of the week * A full textual representation of the day of the week
*/ */
case l = '%l%'; // Sunday through Saturday public const l = '%l%'; // Sunday through Saturday
/** /**
* ISO 8601 numeric representation of the day of the week * ISO 8601 numeric representation of the day of the week
*/ */
case N = '%N%'; // 1 (Monday) to 7 (Sunday) public const N = '%N%'; // 1 (Monday) to 7 (Sunday)
/** /**
* English ordinal suffix for the day of the month, 2 characters * English ordinal suffix for the day of the month, 2 characters
*/ */
case S = '%S%'; // st, nd, rd, th public const S = '%S%'; // st, nd, rd, th
/** /**
* Numeric representation of the day of the week * Numeric representation of the day of the week
*/ */
case w = '%w%'; // 0 (sunday) through 6 (Saturday) public const w = '%w%'; // 0 (sunday) through 6 (Saturday)
/** /**
* The day of the year (starting from 0) * The day of the year (starting from 0)
*/ */
case z = '%z%'; // 0 through 365 public const z = '%z%'; // 0 through 365
@ -73,7 +73,7 @@
/** /**
* ISO 8601 week number of year, weeks starting on Monday * ISO 8601 week number of year, weeks starting on Monday
*/ */
case W = '%W%'; // 42 (42nd week in year) public const W = '%W%'; // 42 (42nd week in year)
@ -82,27 +82,27 @@
/** /**
* A full textual representation of a month, such as January or March * A full textual representation of a month, such as January or March
*/ */
case F = '%F%'; // January through December public const F = '%F%'; // January through December
/** /**
* Numeric representation of a month, with leading zeros * Numeric representation of a month, with leading zeros
*/ */
case m = '%m%'; // 01 through 12 public const m = '%m%'; // 01 through 12
/** /**
* A short textual representation of a month, three letters * A short textual representation of a month, three letters
*/ */
case M = '%M%'; // Jan through Dec public const M = '%M%'; // Jan through Dec
/** /**
* Numeric representation of a month, without leading zeros * Numeric representation of a month, without leading zeros
*/ */
case n = '%n%'; // 1 through 12 public const n = '%n%'; // 1 through 12
/** /**
* Number of days in the given month * Number of days in the given month
*/ */
case t = '%t%'; // 28 through 31 public const t = '%t%'; // 28 through 31
@ -110,73 +110,73 @@
/** /**
* Whether it's a leap year * Whether it's a leap year
*/ */
case L = '%L%'; // 1 (leap year), 0 otherwise public const L = '%L%'; // 1 (leap year), 0 otherwise
/** /**
* ISO 8601 week-numbering year. This has the same value as Y, * ISO 8601 week-numbering year. This has the same value as Y,
* except that if the ISO week number (W) belongs to the previous * except that if the ISO week number (W) belongs to the previous
* or next year, that year is used instead. * or next year, that year is used instead.
*/ */
case o = '%o%'; // Same as Y, except that it use week number to decide which year it falls onto public const o = '%o%'; // Same as Y, except that it use week number to decide which year it falls onto
/** /**
* A full numeric representation of a year, at least 4 digits, with - for years BCE. * A full numeric representation of a year, at least 4 digits, with - for years BCE.
*/ */
case Y = '%Y%'; // 1991, 2012, 2014, ... public const Y = '%Y%'; // 1991, 2012, 2014, ...
/** /**
* A two digit representation of a year * A two digit representation of a year
*/ */
case y = '%y%'; // 91, 12, 14, ... public const y = '%y%'; // 91, 12, 14, ...
// Time Format // Time Format
/** /**
* Lowercase Ante meridiem and Post meridiem * Lowercase Ante meridiem and Post meridiem
*/ */
case a = '%a%'; // am or pm public const a = '%a%'; // am or pm
/** /**
* Uppercase Ante meridiem and Post meridiem * Uppercase Ante meridiem and Post meridiem
*/ */
case A = '%A%'; // AM or PM public const A = '%A%'; // AM or PM
/** /**
* Swatch Internet time * Swatch Internet time
*/ */
case B = '%B%'; // 000 through 999 public const B = '%B%'; // 000 through 999
/** /**
* 12-hour format of an hour without leading zeros * 12-hour format of an hour without leading zeros
*/ */
case g = '%g%'; // 1 through 12 public const g = '%g%'; // 1 through 12
/** /**
* 24-hour format of an hour without leading zeros * 24-hour format of an hour without leading zeros
*/ */
case G = '%G%'; // 0 through 23 public const G = '%G%'; // 0 through 23
/** /**
* 12-hour format of an hour with leading zeros * 12-hour format of an hour with leading zeros
*/ */
case h = '%h%'; // 01 through 12 public const h = '%h%'; // 01 through 12
/** /**
* 24-hour format of an hour with leading zeros * 24-hour format of an hour with leading zeros
*/ */
case H = '%H%'; // 01 through 23 public const H = '%H%'; // 01 through 23
/** /**
* Minutes with leading zeros * Minutes with leading zeros
*/ */
case i = '%i%'; // 01 through 59 public const i = '%i%'; // 01 through 59
/** /**
* Seconds with leading zeros * Seconds with leading zeros
*/ */
case s = '%s%'; // 00 through 59 public const s = '%s%'; // 00 through 59
// DateTime format // DateTime format
case c = '%c%'; // 2004-02-12T15:19:21 public const c = '%c%'; // 2004-02-12T15:19:21
case r = '%r%'; // Thu, 21 Dec 2000 16:01:07 public const r = '%r%'; // Thu, 21 Dec 2000 16:01:07
case u = '%u%'; // Unix Timestamp (seconds since Jan 1 1970 00:00:00) public const u = '%u%'; // Unix Timestamp (seconds since Jan 1 1970 00:00:00)
} }

View file

@ -22,13 +22,13 @@
namespace ncc\Enums\SpecialConstants; namespace ncc\Enums\SpecialConstants;
enum InstallConstants : string final class InstallConstants
{ {
case INSTALL_PATH = '%INSTALL_PATH%'; public const INSTALL_PATH = '%INSTALL_PATH%';
case INSTALL_PATH_BIN = '%INSTALL_PATH.BIN%'; public const INSTALL_PATH_BIN = '%INSTALL_PATH.BIN%';
case INSTALL_PATH_SRC = '%INSTALL_PATH.SRC%'; public const INSTALL_PATH_SRC = '%INSTALL_PATH.SRC%';
case INSTALL_PATH_DATA = '%INSTALL_PATH.DATA%'; public const INSTALL_PATH_DATA = '%INSTALL_PATH.DATA%';
} }

View file

@ -22,11 +22,11 @@
namespace ncc\Enums\SpecialConstants; namespace ncc\Enums\SpecialConstants;
enum RuntimeConstants : string final class RuntimeConstants
{ {
case CWD = '%CWD%'; public const CWD = '%CWD%';
case PID = '%PID%'; public const PID = '%PID%';
case UID = '%UID%'; public const UID = '%UID%';
case GID = '%GID%'; public const GID = '%GID%';
case USER = '%USER%'; public const USER = '%USER%';
} }

View file

@ -22,15 +22,15 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum AuthenticationType : int final class AuthenticationType
{ {
/** /**
* A combination of a username and password is used for authentication * A combination of a username and password is used for authentication
*/ */
case USERNAME_PASSWORD = 1; public const USERNAME_PASSWORD = 1;
/** /**
* A single private access token is used for authentication * A single private access token is used for authentication
*/ */
case ACCESS_TOKEN = 2; public const ACCESS_TOKEN = 2;
} }

View file

@ -22,8 +22,8 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum BuildOutputType : string final class BuildOutputType
{ {
case NCC_PACKAGE = 'ncc'; public const NCC_PACKAGE = 'ncc';
case EXECUTABLE = 'executable'; public const EXECUTABLE = 'executable';
} }

View file

@ -1,6 +1,6 @@
<?php <?php
/* /*
* Copyright (c) Nosial 2022-2024, all rights reserved. * Copyright (c) Nosial 2022-2023, all rights reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without * associated documentation files (the "Software"), to deal in the Software without restriction, including without
@ -20,18 +20,18 @@
* *
*/ */
namespace ncc\Enums\SpecialConstants; namespace ncc\Enums\Types;
enum GeneralConstants : string final class BuiltinRemoteSourceType
{ {
/** /**
* The project's default build configuration * The remote source indicates the package is to be
* fetched using the composer utility.
*/ */
case DEFAULT_BUILD_CONFIGURATION = '%DEFAULT_BUILD_CONFIGURATION%'; public const COMPOSER = 'composer';
/**
* Configurable build output path public const ALL = [
*/ self::COMPOSER
case BUILD_OUTPUT_PATH = '%BUILD_OUTPUT_PATH%'; ];
} }

View file

@ -22,25 +22,35 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum ComponentDataType : string final class ComponentDataType
{ {
/** /**
* Indicates whether the component is represented as an AST representation * Indicates whether the component is represented as an AST representation
*/ */
case AST = 'ast'; public const AST = 'ast';
/** /**
* Indicates whether the component is represented as plaintext * Indicates whether the component is represented as plaintext
*/ */
case PLAIN = 'plain'; public const PLAIN = 'plain';
/** /**
* Indicates whether the component is represented as binary or executable * Indicates whether the component is represented as binary or executable
*/ */
case BINARY = 'binary'; public const BINARY = 'binary';
/** /**
* Indicates whether the component is represented as as a base64 encoded string (Raw bytes' representation) * Indicates whether the component is represented as as a base64 encoded string (Raw bytes' representation)
*/ */
case BASE64_ENCODED = 'b64enc'; public const BASE64_ENCODED = 'b64enc';
/**
* All the possible data types of a component
*/
public const ALL = [
self::AST,
self::PLAIN,
self::BINARY,
self::BASE64_ENCODED
];
} }

View file

@ -22,12 +22,12 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum ComposerPackageTypes : string final class ComposerPackageTypes
{ {
/** /**
* This is the default. It will copy the files to `vendor` * This is the default. It will copy the files to `vendor`
*/ */
case LIBRARY = 'library'; public const LIBRARY = 'library';
/** /**
* This denotes a project rather than a library. For example * This denotes a project rather than a library. For example
@ -37,7 +37,7 @@
* to provide listings of projects to initialize when creating * to provide listings of projects to initialize when creating
* a new workspace. * a new workspace.
*/ */
case PROJECT = 'project'; public const PROJECT = 'project';
/** /**
* An empty package that contains requirements and will trigger * An empty package that contains requirements and will trigger
@ -45,11 +45,11 @@
* anything to the filesystem. As such, it does not require a * anything to the filesystem. As such, it does not require a
* a dist or source key to be installable * a dist or source key to be installable
*/ */
case METAPACKAGE = 'metapackage'; public const METAPACKAGE = 'metapackage';
/** /**
* A package of type `composer-plugin` may provide an installer * A package of type `composer-plugin` may provide an installer
* for other packages that have a custom type. * for other packages that have a custom type.
*/ */
case COMPOSER_PLUGIN = 'composer-plugin'; public const COMPOSER_PLUGIN = 'composer-plugin';
} }

View file

@ -22,15 +22,15 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum ComposerStabilityTypes : string final class ComposerStabilityTypes
{ {
case DEV = 'dev'; public const DEV = 'dev';
case ALPHA = 'alpha'; public const ALPHA = 'alpha';
case BETA = 'beta'; public const BETA = 'beta';
case RC = 'rc'; public const RC = 'rc';
case STABLE ='stable'; public const STABLE ='stable';
} }

View file

@ -0,0 +1,49 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Enums\Types;
final class DependencySourceType
{
/**
* The dependency pointer does not point to a package
*/
public const NONE = 'none';
/**
* Indicates if the dependency is statically linked and the
* reference points to the compiled package of the dependency
*/
public const STATIC = 'static';
/**
* Indicates if the pointer reference points to a remote source
* to fetch the dependency from
*/
public const REMOTE = 'remote';
/**
* Indicates if the pointer reference points to a relative file with the
* filename format "{package_name}=={version}.ncc" to fetch the dependency from
*/
public const LOCAL = 'local';
}

View file

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

View file

@ -22,10 +22,10 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum HttpRequestType : string final class HttpRequestType
{ {
case GET = 'GET'; public const GET = 'GET';
case POST = 'POST'; public const POST = 'POST';
case PUT = 'PUT'; public const PUT = 'PUT';
case DELETE = 'DELETE'; public const DELETE = 'DELETE';
} }

View file

@ -22,9 +22,14 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum ProjectType : string final class ProjectType
{ {
case COMPOSER = 'composer'; public const COMPOSER = 'composer';
case NCC = 'ncc'; public const NCC = 'ncc';
public const ALL = [
self::COMPOSER,
self::NCC,
];
} }

View file

@ -0,0 +1,56 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Enums\Types;
final class RemoteSourceType
{
/**
* A builtin source type is not defined by the user but handled by
* an extension built into NCC
*/
public const BUILTIN = 'builtin';
/**
* A defined source type is defined by the user in the remote sources file
* and handled by an extension designed by passing on the information of
* the source to the extension
*/
public const DEFINED = 'defined';
/**
* Unsupported or invalid source type
*/
public const UNKNOWN = 'unknown';
/**
* No remote source type
*/
public const NONE = 'none';
public const All = [
self::BUILTIN,
self::DEFINED,
self::UNKNOWN,
self::NONE
];
}

View file

@ -22,9 +22,9 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum RepositoryResultType : string final class RepositoryResultType
{ {
case SOURCE = 'source'; public const SOURCE = 'source';
case PACKAGE = 'package'; public const PACKAGE = 'package';
} }

View file

@ -22,13 +22,20 @@
namespace ncc\Enums\Types; namespace ncc\Enums\Types;
enum RepositoryType : string final class RepositoryType
{ {
case GITLAB = 'gitlab'; public const GITLAB = 'gitlab';
case GITHUB = 'github'; public const GITHUB = 'github';
case GITEA = 'gitea'; public const GITEA = 'gitea';
case PACKAGIST = 'packagist'; public const PACKAGIST = 'packagist';
public const ALL = [
self::GITLAB,
self::GITHUB,
self::GITEA,
self::PACKAGIST
];
} }

View file

@ -22,15 +22,25 @@
namespace ncc\Enums; namespace ncc\Enums;
enum Versions : string final class Versions
{ {
/** /**
* The current version of the credentials store file format * The current version of the credentials store file format
*/ */
case CREDENTIALS_STORE_VERSION = '1.0.0'; public const CREDENTIALS_STORE_VERSION = '1.0.0';
/**
* The current version of the package structure file format
*/
public const PACKAGE_STRUCTURE_VERSION = '2.0';
/**
* The current version of the package lock structure file format
*/
public const PACKAGE_LOCK_VERSION = '2.0.0';
/** /**
* Generic version of the package structure file format (latest) * Generic version of the package structure file format (latest)
*/ */
case LATEST = 'latest'; public const LATEST = 'latest';
} }

View file

@ -34,6 +34,6 @@
*/ */
public function __construct(string $message = "", ?Throwable $previous = null) public function __construct(string $message = "", ?Throwable $previous = null)
{ {
parent::__construct($message, ExceptionCodes::ARCHIVE_EXCEPTION->value, $previous); parent::__construct($message, ExceptionCodes::ARCHIVE_EXCEPTION, $previous);
} }
} }

View file

@ -34,6 +34,6 @@
*/ */
public function __construct(string $message = "", ?Throwable $previous = null) public function __construct(string $message = "", ?Throwable $previous = null)
{ {
parent::__construct($message, ExceptionCodes::AUTHENTICATION_EXCEPTION->value, $previous); parent::__construct($message, ExceptionCodes::AUTHENTICATION_EXCEPTION, $previous);
} }
} }

View file

@ -34,6 +34,6 @@ namespace ncc\Exceptions;
*/ */
public function __construct(string $message = "", ?Throwable $previous = null) public function __construct(string $message = "", ?Throwable $previous = null)
{ {
parent::__construct($message, ExceptionCodes::BUILD_EXCEPTION->value, $previous); parent::__construct($message, ExceptionCodes::BUILD_EXCEPTION, $previous);
} }
} }

View file

@ -34,6 +34,6 @@ namespace ncc\Exceptions;
*/ */
public function __construct(string $message = "", ?Throwable $previous = null) public function __construct(string $message = "", ?Throwable $previous = null)
{ {
parent::__construct($message, ExceptionCodes::COMPOSER_EXCEPTION->value, $previous); parent::__construct($message, ExceptionCodes::COMPOSER_EXCEPTION, $previous);
} }
} }

View file

@ -34,6 +34,6 @@
*/ */
public function __construct(string $message = "", ?Throwable $previous = null) public function __construct(string $message = "", ?Throwable $previous = null)
{ {
parent::__construct($message, ExceptionCodes::CONFIGURATION_EXCEPTION->value, $previous); parent::__construct($message, ExceptionCodes::CONFIGURATION_EXCEPTION, $previous);
} }
} }

Some files were not shown because too many files have changed in this diff Show more