- Cleaned up imports

- Various bug fixes and improved performance on package reading/writing
 - Corrected CHANGELOG.md
 - Updated dependency `Symfony/polyfill-mbstring` to 1.28.0
 - Updated dependency `Symfony/polyfill-uuid` to 1.28.0
 - Updated dependency `Symfony/Process` to 6.3.4
 - Updated dependency `Symfony/Uid` to 6.3.0
 - Updated dependency `Symfony/Yaml` to 6.3.3
 - Added support for Gitea repositories
 - Added support for Packagist repositories
 - Added a new default Gitea repository nocturn9x at git.nocturn9x.space
 - Added a new default Gitea repository martinvlba at git.martinvlba.eu
 - Added a new default Gitea repository kuny at git.it-kuny.ch
 - Added dependency composer/semver version 3.4.0 for composer version comparison compatibility
 - Added a new class \ncc\Classes\ArchiveExtractor to extract multiple archive types
 - Refactored \ncc\Objects\RemoteRepository
 - Refactored the repository system
 - Refactored Github's repository interface
 - Refactored Gitlab's repository interface
 - Refactored SourcesMenu in the CLI to use the new repository system
 - Updated dependency nikic/php-parser to version 4.17.1
 - Added a simple security measure in \ncc\Objects\Value\Entry to delay returns randomly when the password is incorrect
 - Refactored the CLI menu system to use a return exit code system
 - Updated the installer to remove unused components and installation steps
 - Updated dependency Symfony/Filesystem to 6.3.1
 - Updated dependency Symfony/polyfill-ctype to 1.28.0
 - Enforced credential storage security by applying 600 permissions to the storage file so that only the owner can read/write to the file; this will require root access to perform any operations on the credential file. A password will still be needed to decrypt entries in the file if any entries are encrypted.
 - Removed \ncc\Classes\NccExtension\Runner in favor of the new Execution Unit system
 - Removed \ncc\Managers\ExecutionPointerManager in favor of the new Execution Unit system
This commit is contained in:
Netkas 2023-09-21 17:24:12 -04:00
parent 5da97e4b3d
commit f62856b530
No known key found for this signature in database
GPG key ID: 5DAF58535614062B
281 changed files with 12577 additions and 109543 deletions

7
.gitignore vendored
View file

@ -8,13 +8,14 @@
build
# Autoload files
src/ncc/ThirdParty/composer/semver/autoload_spl.php
src/ncc/ThirdParty/defuse/php-encryption/autoload_spl.php
src/ncc/ThirdParty/jelix/version/autoload_spl.php
src/ncc/ThirdParty/nikic/PhpParser/autoload_spl.php
src/ncc/ThirdParty/php_parallel_lint/php_console_color/autoload_spl.php
src/ncc/ThirdParty/Symfony/polyfill-ctype/autoload_spl.php
src/ncc/ThirdParty/Symfony/polyfill-mbstring/autoload_spl.php
src/ncc/ThirdParty/Symfony/polyfill-uuid/autoload_spl.php
src/ncc/ThirdParty/Symfony/polyfill_ctype/autoload_spl.php
src/ncc/ThirdParty/Symfony/polyfill_mbstring/autoload_spl.php
src/ncc/ThirdParty/Symfony/polyfill_uuid/autoload_spl.php
src/ncc/ThirdParty/Symfony/Process/autoload_spl.php
src/ncc/ThirdParty/Symfony/Uid/autoload_spl.php
src/ncc/ThirdParty/Symfony/Filesystem/autoload_spl.php

View file

@ -1,3 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Symfony\polyfill-ctype" pattern="file[ncc]:src/ncc/ThirdParty/Symfony/polyfill-ctype//*" />
<scope name="Symfony\polyfill-ctype" pattern="file[ncc]:src/ncc/ThirdParty/Symfony/polyfill_ctype//*" />
</component>

View file

@ -1,3 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Symfony\polyfill-mbstring" pattern="file[ncc]:src/ncc/ThirdParty/Symfony/polyfill-mbstring//*" />
<scope name="Symfony\polyfill-mbstring" pattern="file[ncc]:src/ncc/ThirdParty/Symfony/polyfill_mbstring//*" />
</component>

View file

@ -1,3 +1,3 @@
<component name="DependencyValidationManager">
<scope name="Symfony\polyfill-uuid" pattern="file[ncc]:src/ncc/ThirdParty/Symfony/polyfill-uuid//*" />
<scope name="Symfony\polyfill-uuid" pattern="file[ncc]:src/ncc/ThirdParty/Symfony/polyfill_uuid//*" />
</component>

View file

@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.0.0] - Unreleased
This update introduces major changes in the codebase, including the removal of Win32 support, and the addition of new
features and reduced the number of exceptions down to 15 exceptions.
features. This is the Mk II of ncc, and it is a major update, so please read the changelog carefully.
### Added
@ -29,6 +29,13 @@ features and reduced the number of exceptions down to 15 exceptions.
- Added new template PhpLibraryTemplate `phplib`
- Added the ability to clean arrays in `\ncc\Utilities > Functions > cleanArray()`
- Added the ability to compile executable binaries for php using `gcc`
- Added support for Gitea repositories
- Added support for Packagist repositories
- Added a new default gitea repository `nocturn9x` git.nocturn9x.space
- Added a new default gitea repository `martinvlba` git.martinvlba.eu
- Added a new default gitea repository `kuny` git.it-kuny.ch
- Added dependency `composer/semver` version 3.4.0 for composer version comparison compatibility
- Added new class `\ncc\Classes > ArchiveExtractor` to extract multiple archive types
### Fixed
- Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()`
@ -234,6 +241,27 @@ features and reduced the number of exceptions down to 15 exceptions.
- Refactored `LuaRunner` to use the new execution pointer system
- Refactored `PerlRunner` to use the new execution pointer system
- Refactored `PythonRunner` to use the new execution pointer system
- Refactored `\ncc\Objects > RemoteRepository`
- Refactored the repository system
- Refactored Github's repository interface
- Refactored Gitlab's repository interface
- Refactored SourcesMenu in the CLI to use the new repository system
- Updated dependency `nikic/php-parser` to version 4.17.1
- Added a simple security measure in `\ncc\Objects\Value > Entry > unlock()` to delay returns randomly when the password
is incorrect
- Refactored the CLI menu system to use a return exit code system
- Updated the installer to remove unused components and installation steps
- Updated dependency `Symfony/Filesystem` to 6.3.1
- Updated dependency `Symfony/polyfill-ctype` to 1.28.0
- Enforced credential storage security by applying `600` permissions to the storage file so that only the owner can
read/write to the file, this will require root to do anything with the credential file. A password will still be
needed to decrypt entries in the file if any entries are encrypted.
- Updated dependency `Symfony/polyfill-mbstring` to 1.28.0
- Updated dependency `Symfony/polyfill-uuid` to 1.28.0
- Updated dependency `Symfony/Process` to 6.3.4
- Updated dependency `Symfony/Uid` to 6.3.0
- Updated dependency `Symfony/Yaml` to 6.3.3
- Refactored ZiProto
### Removed
@ -298,8 +326,9 @@ features and reduced the number of exceptions down to 15 exceptions.
- Removed unused `\ncc\Objects > PhpConfiguration`
- Removed parameter `$throw_exception` from `\ncc\Objects\ProjectConfiguration > Project > validate()`
- Removed dependency `theseer\Autoload` in favor of ncc's own autoloader (screw you Arne Blankerts)
- Refactored ZiProto
- Removed runners `Python2` & `Python3` in favor of `Python`
- Removed `\ncc\Classes\NccExtension > Runner` in favor of the new Execution Unit system
- Removed `\ncc\Managers > ExecutionPointerManager` in favor of the new Execution Unit system

View file

@ -9,12 +9,13 @@ TIMESTAMP := $(shell date +%Y%m%d%H%M%S)
# List of paths for autoloading
AUTOLOAD_PATHS := $(addprefix $(SRC_PATH)/ncc/ThirdParty/, \
composer/semver \
defuse/php-encryption \
jelix/version \
nikic/PhpParser \
Symfony/polyfill-ctype \
Symfony/polyfill-mbstring \
Symfony/polyfill-uuid \
Symfony/polyfill_ctype \
Symfony/polyfill_mbstring \
Symfony/polyfill_uuid \
Symfony/Process \
Symfony/Uid \
Symfony/Filesystem \
@ -63,6 +64,8 @@ redist: autoload
cp -f $(INSTALLER_PATH)/ncc.sh $(BUILD_PATH)/src/ncc.sh
cp -f $(CONFIG_PATH)/ncc.yaml $(BUILD_PATH)/src/default_config.yaml
cp -f $(CONFIG_PATH)/ncc.yaml $(BUILD_PATH)/src/CLI/template_config.yaml
cp -f $(CONFIG_PATH)/default_repositories.json $(BUILD_PATH)/src/default_repositories.json
cp -f $(CONFIG_PATH)/ncc-package.xml $(BUILD_PATH)/src/ncc-package.xml
cp -f $(INSTALLER_PATH)/extension $(BUILD_PATH)/src/extension
chmod +x $(BUILD_PATH)/src/INSTALL
cp -f LICENSE $(BUILD_PATH)/src/LICENSE
@ -73,8 +76,6 @@ redist: autoload
cp -f $(INSTALLER_PATH)/generate_build_files.php $(BUILD_PATH)/src/generate_build_files.php
$(PHPCC) $(BUILD_PATH)/src/generate_build_files.php
rm $(BUILD_PATH)/src/generate_build_files.php
mkdir -p $(BUILD_PATH)/src/repositories
cp -rf $(SRC_PATH)/default_repositories/*.json $(BUILD_PATH)/src/repositories
$(BUILD_PATH)/build_$(TIMESTAMP).tar.gz: redist
cd $(BUILD_PATH)/src; tar -czvf ../build_$(TIMESTAMP).tar.gz *

View file

@ -13,15 +13,16 @@
$third_party_path = __DIR__ . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR;
$target_files = [
__DIR__ . 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 . 'jelix' . DIRECTORY_SEPARATOR . 'version' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'nikic' . DIRECTORY_SEPARATOR . 'PhpParser' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-ctype' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-ctype' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-mbstring' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-mbstring' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-uuid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-uuid' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill_ctype' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill_ctype' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill_mbstring' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill_mbstring' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill_uuid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill_uuid' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Process' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php',

View file

@ -0,0 +1,50 @@
[
{
"name": "n64",
"type": "gitlab",
"host": "git.n64.cc",
"ssl": true
},
{
"name": "packagist",
"type": "packagist",
"host": "packagist.org",
"ssl": true
},
{
"name": "github",
"type": "github",
"host": "api.github.com",
"ssl": true
},
{
"name": "gitlab",
"type": "gitlab",
"host": "gitlab.com",
"ssl": true
},
{
"name": "gitgud",
"type": "gitlab",
"host": "gitgud.io",
"ssl": true
},
{
"name": "nocturn9x",
"type": "gitea",
"host": "git.nocturn9x.space",
"ssl": true
},
{
"name": "martinvlba",
"type": "gitea",
"host": "git.martinvlba.eu",
"ssl": true
},
{
"name": "kuny",
"type": "gitea",
"host": "git.it-kuny.ch",
"ssl": true
}
]

View file

@ -13,75 +13,4 @@ ncc:
# The default logging level to use in the CLI
# Values can be (silent, verbose, debug, info, warn, error or fatal)
logging: "info"
# Configuration section for the PHP configuration that NCC will use to run
php:
# The main executable path for PHP that NCC should use
executable_path: "/usr/bin/php"
git:
# if git is enabled or not
enabled: true
# The executable path of git
executable_path: "/usr/bin/git"
# When enabled, NCC will use it's builtin version of composer
# to execute composer tasks, if disabled it will fall back to
# the `executable_path` option and attempt to use that specified
# location of composer
composer:
# if composer is enabled or not
enabled: true
# If internal composer is enabled (install must be executed with --install-composer)
enable_internal_composer: true
# The executable path to the system's installed composer executable
executable_path: "/home/user/composer.phar"
# Composer options
options:
# Do not output any message
quiet: false
# Disable ANSI output
no_ansi: true
# Do not ask any interactive question
no_interaction: true
# Display timing and memory usage information
profile: false
# Skips the execution of all scripts defined in composer.json file.
no_scripts: true
# Prevent use of the cache
no_cache: false
# 1 normal output, 2 for more verbose output and 3 for debug output, 4 to match NCC's logging level
logging: 1
# NCC Composer Extension options
extension:
# If licenses should be displayed in the conversion process of a composer package
display_licenses: true
# If authors should be displayed in the conversion process of a composer package
display_authors: true
# If NCC should try to install suggested packages
try_install_suggested: true
# Supported runners executable paths
runners:
php: "/usr/bin/php"
bash: "/usr/bin/bash"
sh: "/usr/bin/sh"
python: "/usr/bin/python"
python3: "/usr/bin/python3"
python2: "/usr/bin/python2"
logging: "info"

View file

@ -1,6 +0,0 @@
[
"gitgud.json",
"github.json",
"gitlab.json",
"n64.json"
]

View file

@ -1,6 +0,0 @@
{
"name": "gitgud",
"type": "gitlab",
"host": "gitgud.io",
"ssl": true
}

View file

@ -1,6 +0,0 @@
{
"name": "github",
"type": "github",
"host": "api.github.com",
"ssl": true
}

View file

@ -1,6 +0,0 @@
{
"name": "gitlab",
"type": "gitlab",
"host": "gitlab.com",
"ssl": true
}

View file

@ -1,6 +0,0 @@
{
"name": "n64",
"type": "gitlab",
"host": "git.n64.cc",
"ssl": true
}

View file

@ -2,9 +2,7 @@
use ncc\Classes\Runtime;
use ncc\Enums\Versions;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\ImportException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\ConfigurationException;
use ncc\ncc;
if(!defined('NCC_INIT'))

View file

@ -6,30 +6,34 @@
print('Could not find \'autoload.php\', this script is intended to be executed during the redistribution process');
exit(1);
}
/** @noinspection PhpIncludeInspection */
require(__DIR__ . DIRECTORY_SEPARATOR . 'autoload.php');
// Start script
function scanContents($dir, &$results = array())
function scanContents($dir)
{
$files = scandir($dir);
$results = [];
foreach ($files as $key => $value)
foreach (scandir($dir, SCANDIR_SORT_NONE) as $key => $value)
{
$path = realpath($dir . DIRECTORY_SEPARATOR . $value);
if (!is_dir($path))
{
$results[] = str_ireplace(__DIR__ . DIRECTORY_SEPARATOR, (string)null, $path);
$results[] = str_ireplace(__DIR__ . DIRECTORY_SEPARATOR, '', $path);
}
else if ($value != '.' && $value != '..')
elseif ($value !== '.' && $value !== '..')
{
$results[] = str_ireplace(__DIR__ . DIRECTORY_SEPARATOR, (string)null, $path);
scanContents($path, $results);
/** @noinspection SlowArrayOperationsInLoopInspection */
$results = array_merge($results, scanContents($path));
}
}
return $results;
}
$excluded_files = [
'hash_check.php',
'generate_build_files.php',
@ -56,8 +60,10 @@
$build_files_content[] = $path;
}
}
$build_files = fopen(__DIR__ . DIRECTORY_SEPARATOR . 'build_files', 'a+');
$build_files = fopen(__DIR__ . DIRECTORY_SEPARATOR . 'build_files', 'ab+');
fwrite($build_files, implode("\n", $build_files_content));
fclose($build_files);
ncc\Utilities\Console::out('Created build_files');
exit(0);

View file

@ -3,8 +3,8 @@
# ------------------------------------------------------------------
# Nosial Code Compiler (NCC) Installation Script
#
# Nosial Code Compiler is a program written in PHP designed
# to be a multipurpose compiler, package manager and toolkit.
# Nosial Code Compiler is a program written in PHP designed
# to be a multipurpose compiler, package manager and toolkit.
#
# Dependency:
# PHP 8.0+
@ -13,17 +13,11 @@
<?PHP
use ncc\Enums\ConsoleColors;
use ncc\Exceptions\FileNotFoundException;
use ncc\Managers\RemoteSourcesManager;
use ncc\ncc;
use ncc\Objects\CliHelpSection;
use ncc\Objects\DefinedRemoteSource;
use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException;
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
use ncc\ThirdParty\Symfony\Process\Exception\ProcessFailedException;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
use ncc\ThirdParty\Symfony\process\PhpExecutableFinder;
use ncc\ThirdParty\Symfony\Process\Process;
use ncc\ThirdParty\Symfony\Yaml\Yaml;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
@ -34,60 +28,31 @@
use ncc\Extensions\ZiProto\ZiProto;
# Global Variables
$NCC_INSTALL_PATH=DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'ncc';
$NCC_DATA_PATH=DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'ncc';
$NCC_COMPOSER_UPDATE_SOURCE='https://getcomposer.org/installer';
$NCC_CHECKSUM=__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin';
$NCC_AUTOLOAD=__DIR__ . DIRECTORY_SEPARATOR . 'autoload.php';
$NCC_PHP_EXECUTABLE=null;
$NCC_FILESYSTEM=null;
/**
* A getParameter function to avoid code redundancy (Type-Safe)
*
* @param array|null $args
* @param string $option
* @param bool $require_content
* @return string|null
*/
function getParameter(?array $args, string $option, bool $require_content=true): ?string
{
if($args == null)
{
return null;
}
if(!isset($args[$option]))
{
return null;
}
if($require_content && ($args[$option] == null || strlen((string)$args[$option] == 0)))
{
return null;
}
return $args[$option];
}
$NCC_INSTALL_PATH = DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'share' . DIRECTORY_SEPARATOR . 'ncc';
$NCC_DATA_PATH = DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'ncc';
$NCC_CHECKSUM = __DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin';
$NCC_AUTOLOAD = __DIR__ . DIRECTORY_SEPARATOR . 'autoload.php';
$NCC_PHP_EXECUTABLE = null;
// Require NCC
if(!file_exists($NCC_AUTOLOAD))
{
print('The file \'autoload.php\' was not found, installation cannot proceed.' . PHP_EOL);
print(sprintf('Cannot find autoload file \'%s\', installation failed successfully.', $NCC_AUTOLOAD) . PHP_EOL);
exit(1);
}
require($NCC_AUTOLOAD);
// Initialize NCC
try
{
// Initialize NCC
define('NCC_CLI_MODE', 1);
ncc::initialize();
}
catch (FileNotFoundException|\ncc\Exceptions\RuntimeException $e)
catch (Exception $e)
{
Console::outError('Cannot initialize NCC, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')');
exit(1);
Console::outException('Cannot initialize NCC, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')', $e, 1);
return;
}
$NCC_ARGS = null;
@ -100,17 +65,14 @@
}
$NCC_AUTO_MODE = ($NCC_ARGS !== null && isset($NCC_ARGS['auto']));
$NCC_BYPASS_CLI_CHECK = ($NCC_ARGS !== null && isset($NCC_ARGS['bypass-cli-check']));
$NCC_BYPASS_OS_CHECK = ($NCC_ARGS !== null && isset($NCC_ARGS['bypass-os-check']));
$NCC_BYPASS_CHECKSUM = ($NCC_ARGS !== null && isset($NCC_ARGS['bypass-checksum']));
if(isset($NCC_ARGS['help']))
{
$options = [
new CliHelpSection(['--help'], 'Displays this help menu about the installer'),
new CliHelpSection(['--auto'], 'Automates the installation process'),
new CliHelpSection(['--install-composer'], 'Require composer to be installed alongside NCC'),
new CliHelpSection(['--install-dir'], 'Specifies the installation directory for NCC'),
new CliHelpSection(['--bypass-cli-check'], 'Bypasses the check for a CLI environment'),
new CliHelpSection(['--bypass-os-check'], 'Bypasses the check for the current operating system'),
new CliHelpSection(['--bypass-checksum'], 'Bypasses the checksum for the installation files'),
];
@ -126,55 +88,31 @@
}
// Detect if running in Windows
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
if(!$NCC_BYPASS_OS_CHECK && strtolower(PHP_OS_FAMILY) === 'windows')
{
print('This installer can only run on Linux based machines' . PHP_EOL);
Console::outError(sprintf('This installer is not compatible with Windows, detected OS: %s (This check can be bypassed with --bypass-os-check)', PHP_OS), true, 1);
return;
}
// Detect the server API
if(!$NCC_BYPASS_CLI_CHECK)
{
if(defined('PHP_SAPI'))
{
if(strtolower(PHP_SAPI) !== 'cli')
{
print('This installation script is meant to be running in your terminal' . PHP_EOL);
}
}
elseif(function_exists('php_sapi_name') && strtolower(php_sapi_name()) !== 'cli')
{
print('This installation script is meant to be running in your terminal' . PHP_EOL);
}
else
{
Console::outWarning(
'The installer cannot determine the Server API (SAPI), the installer will continue but it is ' .
'recommended to be running this installer in a terminal'
);
}
}
// Check if running as root
if(!function_exists('posix_getuid'))
{
Console::outError('The function posix_getuid() is not available on your system, please make sure the extension `php-common` is installed');
exit(1);
Console::outError('The function posix_getuid() is not available on your system, please make sure the extension `php-common` is installed', true, 1);
return;
}
if (posix_getuid() !== 0)
{
Console::outError('You must be running as root');
exit(1);
Console::outError('You must be running as root', true, 1);
return;
}
// Find the PHP executable
$executable_finder = new PhpExecutableFinder();
$NCC_PHP_EXECUTABLE = $executable_finder->find();
$NCC_EXECUTABLE_FINDER = new ExecutableFinder();
$NCC_PHP_EXECUTABLE = (new PhpExecutableFinder())->find();
if(!$NCC_PHP_EXECUTABLE)
{
Console::outError('Cannot find PHP executable path');
exit(1);
Console::outError('Cannot find PHP executable path', true ,1);
return;
}
// Check for the required files
@ -198,47 +136,41 @@
{
if(!$NCC_FILESYSTEM->exists($NCC_CHECKSUM))
{
Console::outWarning('The file \'checksum.bin\' was not found, the contents of the program cannot be verified to be safe');
Console::outError(sprintf('The checksum file \'%s\' was not found, the checksum cannot be validated', $NCC_CHECKSUM), 1, true);
return;
}
else
try
{
Console::out('Running checksum');
Console::out('Testing checksum...');
$checksum = ZiProto::decode(IO::fread($NCC_CHECKSUM));
}
catch(Exception $e)
{
Console::outError($e->getMessage(), true, 1);
return;
}
try
{
$checksum = ZiProto::decode(IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin'));
}
catch(Exception $e)
{
Console::outError($e->getMessage(), true, 1);
return;
}
$checksum_failed = false;
$checksum_failed = false;
foreach($checksum as $path => $hash)
{
if(!file_exists(__DIR__ . DIRECTORY_SEPARATOR . $path))
{
Console::outError('Cannot check file, \'' . $path . '\' not found.');
$checksum_failed = true;
}
elseif(hash_file('sha256', __DIR__ . DIRECTORY_SEPARATOR . $path) !== $hash)
{
Console::outWarning('The file \'' . $path . '\' does not match the original checksum');
$checksum_failed = true;
}
}
foreach($checksum as $path => $hash)
{
if(!file_exists(__DIR__ . DIRECTORY_SEPARATOR . $path))
{
Console::outError('Cannot check file, \'' . $path . '\' not found.');
$checksum_failed = true;
}
elseif(hash_file('sha256', __DIR__ . DIRECTORY_SEPARATOR . $path) !== $hash)
{
Console::outWarning('The file \'' . $path . '\' does not match the original checksum');
$checksum_failed = true;
}
}
if($checksum_failed)
{
Console::outError('Checksum failed, the contents of the program cannot be verified to be safe');
exit(1);
}
else
{
Console::out('Checksum passed');
}
if($checksum_failed)
{
Console::outError('Checksum failed, the contents of the program cannot be verified to be safe', true, 1);
return;
}
}
@ -257,39 +189,22 @@
}
}
// Check for curl if the installer requires it
$curl_available = true;
if(!$extensions['curl'])
{
if(getParameter($NCC_ARGS, 'install-composer') !== null)
{
Console::outError('This installer requires the \'curl\' extension to install composer', true, 1);
return;
}
$curl_available = false;
Console::outWarning('The extension \'curl\' is not installed, the installer will not be able to install composer');
}
// Attempt to load version information
try
{
$VersionInformation = ncc::getVersionInformation();
// Attempt to load version information
$version_information = ncc::getVersionInformation();
}
catch (FileNotFoundException|\ncc\Exceptions\RuntimeException $e)
catch (Exception $e)
{
Console::outError('Cannot get version information, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')');
exit(1);
Console::outException('Cannot get version information, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')', $e, 1);
return;
}
// Start of installer
Console::out('Started NCC installer');
// Display version information
Console::out('NCC Version: ' . NCC_VERSION_NUMBER . ' (' . NCC_VERSION_BRANCH . ')');
Console::out('Build Flags: ' . implode(',', NCC_VERSION_FLAGS));
foreach($VersionInformation->getComponents() as $component)
foreach($version_information->getComponents() as $component)
{
$full_name = $component->getVendor() . '/' . $component->getPackageName();
@ -303,153 +218,14 @@
}
}
if(!$NCC_AUTO_MODE && !Console::getBooleanInput('Do you want install NCC?'))
{
Console::outError('Installation cancelled by user', true, 1);
return;
}
Console::out('Starting installation');
// Determine the installation path
$skip_prompt = false;
$install_dir_arg = getParameter($NCC_ARGS, 'install-dir');
// Check the arguments
if($install_dir_arg !== null)
{
if(!Validate::unixFilepath($install_dir_arg))
{
Console::outError('The given file path is not valid');
exit(1);
}
if($NCC_FILESYSTEM->exists($install_dir_arg . DIRECTORY_SEPARATOR . 'ncc'))
{
Console::out('NCC Seems to already be installed, the installer will repair/upgrade your current install');
$NCC_INSTALL_PATH = $install_dir_arg;
$skip_prompt = true;
}
else
{
Console::outError('The given directory already exists, it must be deleted before proceeding');
exit(1);
}
}
if(!$NCC_AUTO_MODE && !$skip_prompt)
{
while(true)
{
$user_input = null;
$user_input = Console::getInput("Installation Path (Default: $NCC_INSTALL_PATH): ");
if(strlen($user_input) > 0 && $NCC_FILESYSTEM->exists($user_input) && Validate::unixFilepath($user_input))
{
if($NCC_FILESYSTEM->exists($user_input . DIRECTORY_SEPARATOR . 'ncc'))
{
$NCC_INSTALL_PATH = $user_input;
break;
}
else
{
Console::outError('The given directory already exists, it must be deleted before proceeding');
}
}
elseif(strlen($user_input) > 0)
{
Console::outError('The given file path is not valid');
}
else
{
break;
}
}
}
// Determine the data path
$skip_prompt = false;
$data_dir_arg = getParameter($NCC_ARGS, 'data-dir');
// Check the arguments
if($data_dir_arg !== null)
{
if(!Validate::unixFilepath($data_dir_arg))
{
Console::outError('The given file path \''. $data_dir_arg . '\' is not valid');
exit(1);
}
if($NCC_FILESYSTEM->exists($data_dir_arg . DIRECTORY_SEPARATOR . 'package.lck'))
{
$NCC_DATA_PATH = $data_dir_arg;
$skip_prompt = true;
}
else
{
Console::outError('The given directory \'' . $data_dir_arg . '\' already exists, it must be deleted before proceeding');
exit(1);
}
}
// Proceed with prompt if not in auto mode and argument was met
if(!$NCC_AUTO_MODE && !$skip_prompt)
{
while(true)
{
$user_input = null;
$user_input = Console::getInput("Data Path (Default: $NCC_DATA_PATH): ");
if(strlen($user_input) > 0 && $NCC_FILESYSTEM->exists($user_input) && Validate::unixFilepath($user_input))
{
if($NCC_FILESYSTEM->exists($user_input . DIRECTORY_SEPARATOR . 'package.lck'))
{
$NCC_DATA_PATH = $user_input;
break;
}
else
{
Console::outError('The given directory already exists, it must be deleted before proceeding');
}
}
elseif(strlen($user_input) > 0)
{
Console::outError('The given file path is not valid');
}
else
{
break;
}
}
}
// Ask to install composer if curl is available
if($curl_available)
{
if(getParameter($NCC_ARGS, 'install-composer') !== null)
{
$update_composer = true;
}
else
{
if(!$NCC_AUTO_MODE)
{
Console::out("Note: This doesn't affect your current install of composer (if you have composer installed)");
$update_composer = Console::getBooleanInput('Do you want to install composer for NCC? (Recommended)');
}
else
{
$update_composer = false;
}
}
}
else
{
$update_composer = false;
}
if(!$NCC_AUTO_MODE)
{
if(!Console::getBooleanInput('Do you want install NCC?'))
{
Console::outError('Installation cancelled by user');
exit(1);
}
}
// Prepare installation
if($NCC_FILESYSTEM->exists($NCC_INSTALL_PATH))
{
@ -459,8 +235,8 @@
}
catch(IOException $e)
{
Console::outError('Cannot delete directory \'' . $NCC_INSTALL_PATH . '\', ' . $e->getMessage());
exit(1);
Console::outException('Cannot delete directory \'' . $NCC_INSTALL_PATH . '\', ' . $e->getMessage(), $e, 1);
return;
}
}
@ -468,88 +244,25 @@
try
{
Functions::initializeFiles();
if(is_file(__DIR__ . DIRECTORY_SEPARATOR . 'default_repositories.json'))
{
Functions::initializeFiles(Functions::loadJsonFile(__DIR__ . DIRECTORY_SEPARATOR . 'default_repositories.json', Functions::FORCE_ARRAY));
}
else
{
Functions::initializeFiles();
}
}
catch(Exception $e)
{
Console::outError('Cannot initialize NCC files, ' . $e->getMessage());
exit(1);
Console::outException('Cannot initialize NCC files, ' . $e->getMessage(), $e, 1);
return;
}
// Install composer
if($update_composer)
{
Console::out('Installing composer for NCC');
$fp = fopen($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer-setup.php', 'w+');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $NCC_COMPOSER_UPDATE_SOURCE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 600);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, 'ncc/' . NCC_VERSION_NUMBER . ' (' . NCC_VERSION_BRANCH . ')');
curl_exec($ch);
curl_close($ch);
fclose($fp);
Console::out('Running composer installer');
$Process = Process::fromShellCommandline(implode(' ', [
$NCC_PHP_EXECUTABLE,
escapeshellcmd($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer-setup.php'),
'--install-dir=' . escapeshellcmd($NCC_INSTALL_PATH),
'--filename=composer.phar'
]));
$Process->setWorkingDirectory($NCC_INSTALL_PATH);
$Process->setTty(Functions::isTtyMode());
try
{
if($Process->isTty())
{
$Process->run();
}
else
{
Console::outWarning('Composer is running in non-interactive mode, this may cause issues');
$Process->run(function ($type, $buffer)
{
if (Process::ERR === $type)
{
Console::outError($buffer);
}
else
{
Console::out($buffer);
}
});
}
}
catch(ProcessFailedException $e)
{
Console::outError('Cannot install composer, ' . $e->getMessage());
exit(1);
}
// Verify install
if(!$NCC_FILESYSTEM->exists([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer.phar']))
{
Console::outError("Installation failed, the installation exited without any issues but composer doesn't seem to be installed correctly");
exit(1);
}
$NCC_FILESYSTEM->remove([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer-setup.php']);
$NCC_FILESYSTEM->chmod([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer.phar'], 0755);
Console::out('Installed composer successfully');
}
// Install NCC
Console::out('Copying files to \'' . $NCC_INSTALL_PATH . '\'');
// Copy files to the installation path
try
{
Console::out('Copying files to \'' . $NCC_INSTALL_PATH . '\'');
$build_files = explode("\n", IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'build_files'));
}
catch(Exception $e)
@ -557,100 +270,95 @@
Console::outError($e->getMessage(), true, 1);
return;
}
$total_items = count($build_files);
$processed_items = 1;
// Create all the directories first
foreach($build_files as $path)
foreach ($build_files as $item)
{
if(is_dir(__DIR__ . DIRECTORY_SEPARATOR . $path))
$source = __DIR__ . DIRECTORY_SEPARATOR . $item;
$destination = $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $item;
if (is_file($source))
{
$NCC_FILESYSTEM->mkdir([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $path]);
$NCC_FILESYSTEM->chmod([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $path], 0755);
$processed_items += 1;
}
$parent_directory = dirname($destination);
Console::inlineProgressBar($processed_items, $total_items);
}
// Copy over all the files
foreach($build_files as $file)
{
if(is_file(__DIR__ . DIRECTORY_SEPARATOR . $file))
{
$NCC_FILESYSTEM->copy(__DIR__ . DIRECTORY_SEPARATOR . $file, $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $file);
$NCC_FILESYSTEM->chmod([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $file], 0755);
if(!$NCC_FILESYSTEM->exists($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $file))
if(!is_dir($parent_directory))
{
Console::outError('Cannot create file \'' . $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $file . '\', installation failed.');
exit(1);
$NCC_FILESYSTEM->mkdir($parent_directory, 0755);
}
$processed_items += 1;
$NCC_FILESYSTEM->copy($source, $destination);
$NCC_FILESYSTEM->chmod([$destination], 0755);
if (!$NCC_FILESYSTEM->exists($destination))
{
Console::outError(sprintf('Failed to copy file \'%s\' to \'%s\'', $source, $destination), true, 1);
return;
}
}
++$processed_items;
Console::inlineProgressBar($processed_items, $total_items);
}
// Generate executable shortcut
Console::out('Creating shortcut');
// Generate executable shortcut
try
{
$executable_shortcut = IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'ncc.sh');
}
catch(Exception $e)
{
Console::outError($e->getMessage(), true, 1);
Console::outException(sprintf('Failed to read file \'%s\', %s', __DIR__ . DIRECTORY_SEPARATOR . 'ncc.sh', $e->getMessage()), $e, 1);
return;
}
$executable_shortcut = str_ireplace('%php_exec', $NCC_PHP_EXECUTABLE, $executable_shortcut);
$executable_shortcut = str_ireplace('%ncc_exec', $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'ncc', $executable_shortcut);
$executable_shortcut = str_ireplace(['%php_exec', '%ncc_exec'], [$NCC_PHP_EXECUTABLE, $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'ncc'],
$executable_shortcut
);
$bin_paths = [
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'local' . DIRECTORY_SEPARATOR . 'bin',
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'bin',
DIRECTORY_SEPARATOR . 'bin'
];
foreach($bin_paths as $path)
{
// Delete old versions of the executable shortcuts.
if($NCC_FILESYSTEM->exists($path . DIRECTORY_SEPARATOR . 'ncc'))
{
$NCC_FILESYSTEM->remove($path . DIRECTORY_SEPARATOR . 'ncc');
}
$path .= DIRECTORY_SEPARATOR . 'ncc';
// Delete old versions of the executable shortcuts.
if($NCC_FILESYSTEM->exists($path))
{
try
{
IO::fwrite($path . DIRECTORY_SEPARATOR . 'ncc', $executable_shortcut);
$NCC_FILESYSTEM->chmod([$path . DIRECTORY_SEPARATOR . 'ncc'], 0755);
}
catch (Exception $e)
{
Console::outException($e->getMessage(), $e, 1);
return;
}
$NCC_FILESYSTEM->remove($path);
}
try
{
IO::fwrite($path, $executable_shortcut);
$NCC_FILESYSTEM->chmod([$path], 0755);
}
catch (Exception $e)
{
Console::outException(sprintf('Failed to write file \'%s\', %s', $path, $e->getMessage()), $e, 1);
return;
}
}
// Register the ncc extension
Console::out('Registering extension');
try
{
$extension_shortcut = IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'extension');
Console::out('Registering extension');
$extension_shortcut = str_ireplace('%ncc_install', $NCC_INSTALL_PATH, IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'extension'));
}
catch(Exception $e)
{
Console::outError($e->getMessage(), true, 1);
Console::outException(sprintf('Failed to read file \'%s\', %s', __DIR__ . DIRECTORY_SEPARATOR . 'extension', $e->getMessage()), $e, 1);
return;
}
$extension_shortcut = str_ireplace('%ncc_install', $NCC_INSTALL_PATH, $extension_shortcut);
// Remove all the old extensions first.
/**
* @param string $path
* @param Filesystem $filesystem
@ -674,12 +382,7 @@
return false;
}
if ($filesystem->exists($path . DIRECTORY_SEPARATOR . 'ncc'))
{
return true;
}
return false;
return $filesystem->exists($path . DIRECTORY_SEPARATOR . 'ncc');
}
if(function_exists('get_include_path'))
@ -693,7 +396,9 @@
foreach($include_paths as $path)
{
if($extension_registered)
{
break;
}
switch($path)
{
@ -717,27 +422,6 @@
}
}
// Overwrite automatic values created by the installer
$config_obj['ncc']['data_directory'] = $NCC_DATA_PATH;
$config_obj['php']['executable_path'] = $NCC_PHP_EXECUTABLE;
$config_obj['git']['executable_path'] = $NCC_EXECUTABLE_FINDER->find('git');
$config_obj['composer']['executable_path'] = $NCC_EXECUTABLE_FINDER->find('composer');
if($config_obj['git']['executable_path'] == null)
{
Console::outWarning('Cannot locate the executable path for \'git\', run \'ncc config -p git.executable_path -v "GIT_PATH_HERE"\' as root to update the path');
}
if(!$update_composer)
{
Console::outWarning('Since composer is not installed alongside NCC, the installer will attempt to locate a install of composer on your system and configure NCC to use that');
$config_obj['composer']['enable_internal_composer'] = false;
if($config_obj['composer']['executable_path'] == null)
{
Console::outWarning('Cannot locate the executable path for \'composer\', run \'ncc config --composer.executable_path="composer.phar"\' as root to update the path');
}
}
// Backup the configuration file
$config_backup = null;
@ -770,18 +454,20 @@
{
// handle the arguments, merge one by one
$args = func_get_args();
$array = $args[0];
if (!is_array($array))
if (!is_array($args[0]))
{
return $array;
return $args[0];
}
for ($i = 1; $i < count($args); $i++)
for ($i = 1, $i_max = count($args); $i < $i_max; $i++)
{
if (is_array($args[$i]))
{
$array = recurse($array, $args[$i]);
}
}
return $array;
}
}
@ -799,7 +485,7 @@
{
foreach ($array1 as $key => $value)
{
// create new key in $array, if it is empty or not an array
// create new key in $array if it is empty or not an array
/** @noinspection PhpConditionAlreadyCheckedInspection */
if (!isset($array[$key]) || (isset($array[$key]) && !is_array($array[$key])))
{
@ -811,6 +497,7 @@
{
$value = recurse($array[$key], $value);
}
$array[$key] = $value;
}
return $array;
@ -819,9 +506,11 @@
if($config_backup !== null)
{
$config_obj = array_replace_recursive($config_obj, $config_backup);
}
if($config_backup == null)
if($config_backup === null)
{
Console::out('Generating ncc.yaml');
}
@ -840,57 +529,6 @@
return;
}
if($NCC_FILESYSTEM->exists(__DIR__ . DIRECTORY_SEPARATOR . 'repositories'))
{
if(!$NCC_FILESYSTEM->exists(__DIR__ . DIRECTORY_SEPARATOR . 'repositories' . DIRECTORY_SEPARATOR . 'custom_repositories.json'))
return;
try
{
$custom_repositories = Functions::loadJsonFile(__DIR__ . DIRECTORY_SEPARATOR . 'repositories' . DIRECTORY_SEPARATOR . 'custom_repositories.json', Functions::FORCE_ARRAY);
}
catch(Exception $e)
{
$custom_repositories = null;
Console::outWarning(sprintf('Failed to load custom repositories: %s', $e->getMessage()));
}
if($custom_repositories !== null)
{
$source_manager = new RemoteSourcesManager();
foreach($custom_repositories as $repository)
{
$repo_path = __DIR__ . DIRECTORY_SEPARATOR . 'repositories' . DIRECTORY_SEPARATOR . $repository;
if($NCC_FILESYSTEM->exists($repo_path))
{
try
{
$definedEntry = DefinedRemoteSource::fromArray(Functions::loadJsonFile($repo_path, Functions::FORCE_ARRAY));
if(!$source_manager->getRemoteSource($definedEntry->getName()))
$source_manager->addRemoteSource($definedEntry);
}
catch(Exception $e)
{
Console::outWarning(sprintf('Failed to load custom repository %s: %s', $repository, $e->getMessage()));
}
}
else
{
Console::outWarning(sprintf('Failed to load custom repository %s, file does not exist', $repository));
}
}
try
{
$source_manager->save();
}
catch (\ncc\Exceptions\IOException $e)
{
Console::outWarning(sprintf('Failed to save sources: %s', $e->getMessage()));
}
}
}
Console::out('NCC version: ' . NCC_VERSION_NUMBER . ' has been successfully installed');
Console::out('For licensing information see \'' . $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'LICENSE\' or run \'ncc help --license\'');

View file

@ -34,29 +34,26 @@
/**
* Displays the main help menu
*
* @param $args
* @return void
* @noinspection PhpNoReturnAttributeCanBeAddedInspection
* @param array $args
* @return int
*/
public static function start($args): void
public static function start(array $args): int
{
if(isset($args['help']))
{
self::displayOptions();
exit(0);
return self::displayOptions();
}
self::build($args);
exit(0);
return self::build($args);
}
/**
* Builds the current project
*
* @param $args
* @return void
* @param array $args
* @return int
*/
private static function build($args): void
private static function build(array $args): int
{
if(isset($args['path']) || isset($args['p']))
{
@ -69,7 +66,7 @@
else
{
Console::outError('Missing option: --path|-p, please specify the path to the project', true, 1);
return;
return 1;
}
// Load the project
@ -80,35 +77,31 @@
catch (Exception $e)
{
Console::outException('There was an error loading the project', $e, 1);
return;
return 1;
}
// Build the project
try
{
$build_configuration = BuildConfigurationValues::DEFAULT;
if(isset($args['config']))
{
$build_configuration = $args['config'];
}
$build_configuration = $args['config'] ?? BuildConfigurationValues::DEFAULT;
$output = $project_manager->build($build_configuration);
}
catch (Exception $e)
{
Console::outException('Failed to build project', $e, 1);
return;
return 1;
}
Console::out($output);
return 0;
}
/**
* Displays the main options section
*
* @return void
* @return int
*/
private static function displayOptions(): void
private static function displayOptions(): int
{
$options = [
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
@ -125,5 +118,7 @@
{
Console::out(' ' . $option->toString($options_padding));
}
return 0;
}
}

View file

@ -33,18 +33,17 @@
/**
* Displays the main help menu
*
* @param $args
* @return void
* @param array $args
* @return int
*/
public static function start($args): void
public static function start(array $args): int
{
$package = $args['package'] ?? null;
$version = $args['exec-version'] ?? 'latest';
if($package == null)
if($package === null)
{
self::displayOptions();
exit(0);
return self::displayOptions();
}
try
@ -54,26 +53,26 @@
catch(Exception $e)
{
Console::outException('Cannot import package ' . $package, $e, 1);
return;
return 1;
}
try
{
exit(Runtime::execute($package_name));
return Runtime::execute($package_name);
}
catch(Exception $e)
{
Console::outException($e->getMessage(), $e, 1);
return;
return 1;
}
}
/**
* Displays the main options section
*
* @return void
* @return int
*/
private static function displayOptions(): void
private static function displayOptions(): int
{
$options = [
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
@ -97,5 +96,7 @@
Console::out(' ncc exec --package com.example.program');
Console::out(' ncc exec --package com.example.program --exec-version 1.0.0');
Console::out(' ncc exec --package com.example.program --exec-args --foo --bar --extra=test');
return 0;
}
}

View file

@ -34,11 +34,11 @@
* Displays the main help menu
*
* @param $args
* @return void
* @return int
* @throws IOException
* @throws PathNotFoundException
*/
public static function start($args): void
public static function start($args): int
{
$basic_ascii = false;
@ -59,6 +59,8 @@
self::displayMainOptions();
self::displayManagementCommands();
self::displayMainCommands();
return 0;
}
/**
@ -89,10 +91,10 @@
Console::out('Management Commands:');
Console::outHelpSections([
new CliHelpSection(['project'], 'Manages the current project'),
new CliHelpSection(['package'], 'Manages the package system'),
new CliHelpSection(['package', 'pkg'], 'Manages the package system'),
new CliHelpSection(['cred'], 'Manages credentials'),
new CliHelpSection(['config'], 'Changes ncc configuration values'),
new CliHelpSection(['source'], 'Manages remote sources'),
new CliHelpSection(['repo'], 'Manages/Configure repositories'),
]);
}

View file

@ -25,21 +25,20 @@
namespace ncc\CLI;
use Exception;
use ncc\Enums\LogLevel;
use ncc\Enums\NccBuildFlags;
use ncc\Classes\ShutdownHandler;
use ncc\CLI\Commands\BuildCommand;
use ncc\CLI\Commands\ExecCommand;
use ncc\CLI\Management\ConfigMenu;
use ncc\CLI\Management\CredentialMenu;
use ncc\CLI\Management\PackageManagerMenu;
use ncc\CLI\Management\ProjectMenu;
use ncc\CLI\Management\SourcesMenu;
use ncc\CLI\Management\RepositoryMenu;
use ncc\Enums\Flags\NccBuildFlags;
use ncc\Enums\LogLevel;
use ncc\Exceptions\PathNotFoundException;
use ncc\ncc;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache;
class Main
{
@ -56,141 +55,141 @@
/**
* Executes the main CLI process
*
* @param $argv
* @return void
* @param array $argv
* @return int
*/
public static function start($argv): void
public static function start(array $argv): int
{
self::$args = Resolver::parseArguments(implode(' ', $argv));
if(isset(self::$args['ncc-cli']))
if(!isset(self::$args['ncc-cli']))
{
// Initialize ncc
try
{
ncc::initialize();
}
catch (PathNotFoundException $e)
{
Console::outException('Cannot initialize ncc, one or more files were not found.', $e, 1);
}
catch (Exception $e)
{
Console::outException('Cannot initialize ncc due to an unexpected error.', $e, 1);
}
define('NCC_CLI_MODE', 1);
register_shutdown_function('ncc\CLI\Main::shutdown');
if(isset(self::$args['l']) || isset(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
{
self::$log_level = LogLevel::INFO;
}
if(Resolver::checkLogLevel(self::$log_level, LogLevel::DEBUG))
{
Console::outDebug('Debug logging enabled');
/** @noinspection JsonEncodingApiUsageInspection */
Console::outDebug(sprintf('const: %s', json_encode(ncc::getConstants(), JSON_UNESCAPED_SLASHES)));
/** @noinspection JsonEncodingApiUsageInspection */
Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES)));
}
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');
}
if(isset(self::$args['version']))
{
self::displayVersion();
exit(0);
}
try
{
switch(strtolower(self::$args['ncc-cli']))
{
default:
Console::out('Unknown command ' . strtolower(self::$args['ncc-cli']));
break;
case 'project':
ProjectMenu::start(self::$args);
break;
case 'build':
BuildCommand::start(self::$args);
break;
case 'exec':
ExecCommand::start(self::$args);
break;
case 'cred':
CredentialMenu::start(self::$args);
break;
case 'package':
PackageManagerMenu::start(self::$args);
break;
case 'config':
ConfigMenu::start(self::$args);
break;
case 'source':
SourcesMenu::start(self::$args);
break;
case 'version':
self::displayVersion();
break;
case '1':
case 'help':
HelpMenu::start(self::$args);
break;
}
}
catch(Exception $e)
{
Console::outException($e->getMessage(), $e, 1);
exit(1);
}
exit(0);
Console::outError('No command specified, please verify your command and try again.', true, 1);
return 1;
}
// Initialize ncc
try
{
ncc::initialize();
}
catch (PathNotFoundException $e)
{
Console::outException('Cannot initialize ncc, one or more files were not found.', $e, 1);
return 1;
}
catch (Exception $e)
{
Console::outException('Cannot initialize ncc due to an unexpected error.', $e, 1);
return 1;
}
define('NCC_CLI_MODE', 1);
register_shutdown_function([ShutdownHandler::class, 'shutdown']);
if(isset(self::$args['l']) || isset(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
{
self::$log_level = LogLevel::INFO;
}
if(Resolver::checkLogLevel(self::$log_level, LogLevel::DEBUG))
{
Console::outDebug('Debug logging enabled');
/** @noinspection JsonEncodingApiUsageInspection */
Console::outDebug(sprintf('const: %s', json_encode(ncc::getConstants(), JSON_UNESCAPED_SLASHES)));
/** @noinspection JsonEncodingApiUsageInspection */
Console::outDebug(sprintf('args: %s', json_encode(self::$args, JSON_UNESCAPED_SLASHES)));
}
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');
}
if(isset(self::$args['version']))
{
self::displayVersion();
return 0;
}
try
{
switch(strtolower(self::$args['ncc-cli']))
{
default:
Console::out('Unknown command ' . strtolower(self::$args['ncc-cli']));
break;
case 'project':
return ProjectMenu::start(self::$args);
case 'build':
return BuildCommand::start(self::$args);
case 'exec':
return ExecCommand::start(self::$args);
case 'cred':
return CredentialMenu::start(self::$args);
case 'pkg':
case 'package':
return PackageManagerMenu::start(self::$args);
case 'config':
return ConfigMenu::start(self::$args);
case 'repo':
return RepositoryMenu::start(self::$args);
case 'version':
return self::displayVersion();
case '1':
case 'help':
return HelpMenu::start(self::$args);
}
}
catch(Exception $e)
{
Console::outException($e->getMessage(), $e, 1);
return 1;
}
return 0;
}
/**
* Displays the current version of ncc
*
* @return void
* @return int
*/
private static function displayVersion(): void
private static function displayVersion(): int
{
Console::out(sprintf('ncc version %s (%s)', NCC_VERSION_NUMBER, NCC_VERSION_BRANCH));
return 0;
}
/**
@ -228,21 +227,4 @@
return self::$log_level;
}
/**
* @return void
*/
public static function shutdown(): void
{
try
{
RuntimeCache::clearCache();
Functions::finalizePermissions();
}
catch (Exception $e)
{
Console::outWarning('An error occurred while shutting down ncc, ' . $e->getMessage());
}
}
}

View file

@ -39,19 +39,19 @@
* Displays the main help menu
*
* @param $args
* @return void
* @return int
* @throws IOException
* @throws AuthenticationException
*/
public static function start($args): void
public static function start($args): int
{
if(isset($args['sample']))
{
$sample_file = __DIR__ . DIRECTORY_SEPARATOR . 'template_config.yaml';
if(!file_exists($sample_file))
if(!is_file($sample_file))
{
Console::outError('Cannot display sample, file template_config.yaml was not found', true, 1);
return;
return 1;
}
$handle = fopen($sample_file, 'rb');
@ -59,7 +59,7 @@
if (!$handle)
{
Console::outError('Cannot display sample, error reading template_config.yaml', true, 1);
return;
return 1;
}
while (($line = fgets($handle)) !== false)
@ -68,22 +68,22 @@
}
fclose($handle);
exit(0);
return 0;
}
if(isset($args['read']))
{
if(!file_exists(PathFinder::getConfigurationFile()))
if(!is_file(PathFinder::getConfigurationFile()))
{
Console::outError('Cannot read configuration file, path not found', true, 1);
return;
return 1;
}
$handle = fopen(PathFinder::getConfigurationFile(), 'rb');
if (!$handle)
{
Console::outError('Cannot display configuration file, error reading file', true, 1);
return;
return 1;
}
while (($line = fgets($handle)) !== false)
@ -92,7 +92,7 @@
}
fclose($handle);
exit(0);
return 0;
}
if(isset($args['p']))
@ -104,7 +104,7 @@
if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
Console::outError('Insufficient permissions, cannot modify configuration values', true, 1);
return;
return 1;
}
if(strtolower($args['v']) === 'null')
@ -115,11 +115,11 @@
if($configuration_manager->updateProperty($args['p'], $args['v']))
{
$configuration_manager->save();
exit(0);
return 0;
}
Console::outError(sprintf('Unknown property %s', $args['p']), true, 1);
return;
return 1;
}
$value = $configuration_manager->getProperty($args['p']);
@ -144,20 +144,19 @@
Console::out((string)$value);
}
exit(0);
return 0;
}
self::displayOptions();
exit(0);
return self::displayOptions();
}
/**
* Displays the main options section
*
* @return void
* @return int
*/
private static function displayOptions(): void
private static function displayOptions(): int
{
$options = [
new CliHelpSection(['sample'], 'Displays a sample configuration file with documentation'),
@ -178,5 +177,6 @@
Console::out('If `v` is not specified the property will be displayed');
Console::out('If `v` is specified but `null` is set, the default value or null will be used');
Console::out('For documentation run `ncc config sample`');
return 0;
}
}

View file

@ -1,30 +1,29 @@
<?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.
*
*/
/*
* 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\CLI\Management;
namespace ncc\CLI\Management;
use Exception;
use ncc\Enums\Scopes;
use ncc\Exceptions\RuntimeException;
use ncc\Managers\CredentialManager;
use ncc\Objects\CliHelpSection;
use ncc\Objects\Vault\Password\AccessToken;
@ -39,93 +38,88 @@ namespace ncc\CLI\Management;
* Displays the main help menu
*
* @param $args
* @return void
* @return int
* @noinspection DuplicatedCode
*/
public static function start($args): void
public static function start($args): int
{
if(isset($args['add']))
{
try
{
self::addEntry($args);
return self::addEntry($args);
}
catch(Exception $e)
{
Console::outException('Error while adding entry.', $e, 1);
Console::outException(sprintf('Cannot add entry: %s', $e->getMessage()), $e, 1);
return 1;
}
return;
}
if(isset($args['remove']))
{
try
{
self::removeEntry($args);
return self::removeEntry($args);
}
catch(Exception $e)
{
Console::outException('Cannot remove entry.', $e, 1);
Console::outException(sprintf('Cannot remove entry: %s', $e->getMessage()), $e, 1);
return 1;
}
return;
}
if(isset($args['list']))
{
try
{
self::listEntries();
return self::listEntries();
}
catch(Exception $e)
{
Console::outException('Cannot list entries.', $e, 1);
Console::outException(sprintf('Cannot list entries: %s', $e->getMessage()), $e, 1);
return 1;
}
return;
}
if(isset($args['test']))
{
try
{
self::testEntry($args);
return self::testEntry($args);
}
catch(Exception $e)
{
Console::outException('Cannot test entry.', $e, 1);
Console::outException(sprintf('Cannot test entry: %s', $e->getMessage()), $e, 1);
return 1;
}
return;
}
self::displayOptions();
return self::displayOptions();
}
/**
* Tests an entry authentication
*
* @param $args
* @return void
* @return int
*/
public static function testEntry($args): void
public static function testEntry($args): int
{
$name = $args['name'] ?? $args['alias'] ?? null;
if($name === null)
{
Console::outError('Please specify a name or alias for the entry.', true, 1);
return;
return 1;
}
$credential_manager = new CredentialManager();
$entry = $credential_manager->getVault()->getEntry($name);
$entry = (new CredentialManager())->getVault()?->getEntry($name);
if($entry === null)
{
Console::out('Entry not found.', true, 1);
return;
return 1;
}
if($entry->isEncrypted())
@ -141,7 +135,7 @@ namespace ncc\CLI\Management;
if ($tries >= 3)
{
Console::outError('Too many failed attempts.', true, 1);
return;
return 1;
}
Console::outError('Invalid password.', true, 1);
@ -149,31 +143,31 @@ namespace ncc\CLI\Management;
else
{
Console::out('Authentication successful.');
return;
return 1;
}
}
}
else
{
Console::out('Authentication always successful, entry is not encrypted.');
}
return 0;
}
/**
* Prints the list of entries in the vault
*
* @return void
* @return int
*/
public static function listEntries(): void
public static function listEntries(): int
{
$credential_manager = new CredentialManager();
$entries = $credential_manager->getVault()->getEntries();
$entries = (new CredentialManager())->getVault()?->getEntries();
if(count($entries) === 0)
{
Console::out('No entries found.');
return;
return 0;
}
Console::out('Entries:');
@ -183,18 +177,21 @@ namespace ncc\CLI\Management;
}
Console::out('Total: ' . count($entries));
return 0;
}
/**
* @param $args
* @return void
* @return int
*/
public static function addEntry($args): void
public static function addEntry($args): int
{
$ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::SYSTEM)
{
Console::outError('Insufficient permissions to add entries');
}
// Really dumb-proofing this
$name = $args['alias'] ?? $args['name'] ?? null;
@ -205,39 +202,50 @@ namespace ncc\CLI\Management;
$encrypt = !isset($args['no-encryption']);
if($name === null)
{
$name = Console::getInput('Enter a name for the entry: ');
}
if($auth_type === null)
{
$auth_type = Console::getInput('Enter the authentication type (login or pat): ');
}
if($auth_type === 'login')
{
if($username === null)
{
$username = Console::getInput('Username: ');
}
if($password === null)
{
$password = Console::passwordInput('Password: ');
}
}
elseif($auth_type === 'pat')
{
if($token === null)
{
$token = Console::passwordInput('Token: ');
}
}
else
{
Console::outError('Invalid authentication type');
return 1;
}
if($name === null)
{
Console::outError('You must specify a name for the entry (alias, name)', true, 1);
return;
return 1;
}
if($auth_type === null)
{
Console::outError('You must specify an authentication type for the entry (auth-type, auth)', true, 1);
return;
return 1;
}
$encrypt = Functions::cbool($encrypt);
@ -245,106 +253,106 @@ namespace ncc\CLI\Management;
switch($auth_type)
{
case 'login':
if($username === null)
{
Console::outError('You must specify a username for the entry (username, usr)', true, 1);
return;
return 1;
}
if($password === null)
{
Console::outError('You must specify a password for the entry (password, pwd)', true, 1);
return;
return 1;
}
$pass_object = new UsernamePassword();
$pass_object->setUsername($username);
$pass_object->setPassword($password);
$pass_object = new UsernamePassword($username, $password);
break;
case 'pat':
if($token === null)
{
Console::outError('You must specify a token for the entry (token, pat, private-token)', true, 1);
return;
return 1;
}
$pass_object = new AccessToken();
$pass_object->setAccessToken($token);
$pass_object = new AccessToken($token);
break;
default:
Console::outError('Invalid authentication type specified', true, 1);
return;
return 1;
}
$credential_manager = new CredentialManager();
if(!$credential_manager->getVault()->addEntry($name, $pass_object, $encrypt))
if(!$credential_manager->getVault()?->addEntry($name, $pass_object, $encrypt))
{
Console::outError('Failed to add entry, entry already exists.', true, 1);
return;
return 1;
}
try
{
$credential_manager->saveVault();
$credential_manager->save();
}
catch(Exception $e)
{
Console::outException('Failed to save vault', $e, 1);
return;
return 1;
}
Console::out('Successfully added entry', true, 0);
return 0;
}
/**
* Removes an existing entry from the vault.
*
* @param $args
* @return void
* @return int
*/
private static function removeEntry($args): void
private static function removeEntry($args): int
{
$ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::SYSTEM)
{
Console::outError('Insufficient permissions to remove entries');
}
$name = $args['alias'] ?? $args['name'] ?? null;
if($name === null)
{
$name = Console::getInput('Enter the name of the entry to remove: ');
}
$credential_manager = new CredentialManager();
if(!$credential_manager->getVault()->deleteEntry($name))
if(!$credential_manager->getVault()?->deleteEntry($name))
{
Console::outError('Failed to remove entry, entry does not exist.', true, 1);
return;
return 1;
}
try
{
$credential_manager->saveVault();
$credential_manager->save();
}
catch(Exception $e)
{
Console::outException('Failed to save vault', $e, 1);
return;
return 1;
}
Console::out('Successfully removed entry', true, 0);
return 0;
}
/**
* Displays the main options section
*
* @return void
* @return int
*/
private static function displayOptions(): void
private static function displayOptions(): int
{
Console::out('Usage: ncc cred {command} [options]');
Console::out('Options:');
@ -385,5 +393,7 @@ namespace ncc\CLI\Management;
Console::out(' ncc cred add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword"');
Console::out(' ncc cred add --alias "My Alias" --auth-type pat --token "mytoken" --no-encryption');
Console::out(' ncc cred remove --alias "My Alias"');
return 0;
}
}

File diff suppressed because it is too large Load diff

View file

@ -35,32 +35,30 @@
* Displays the main help menu
*
* @param array $args
* @return void
* @return int
*/
public static function start(array $args): void
public static function start(array $args): int
{
if(isset($args['create']))
{
self::initializeProject($args);
return;
return self::initializeProject($args);
}
if(isset($args['template']))
{
self::applyTemplate($args);
return;
return self::applyTemplate($args);
}
self::displayOptions();
return self::displayOptions();
}
/**
* Initializes a new project
*
* @param array $args
* @return void
* @return int
*/
private static function initializeProject(array $args): void
private static function initializeProject(array $args): int
{
if(isset($args['path']) || isset($args['p']))
{
@ -69,7 +67,7 @@
else
{
Console::outError('Missing required option: --path|-p, please specify the path to the project', true, 1);
return;
return 1;
}
if(isset($args['name']) || isset($args['n']))
@ -79,7 +77,7 @@
else
{
Console::outError('Missing required option: --name|-n, please specify the name of the project', true, 1);
return;
return 1;
}
if(isset($args['package']) || isset($args['pkg']))
@ -89,7 +87,7 @@
else
{
Console::outError('Missing required option: --package|--pkg, please specify the package name of the project', true, 1);
return;
return 1;
}
if(isset($args['ext']))
@ -99,7 +97,7 @@
else
{
Console::outError('Missing required option: --ext, please specify the compiler extension of the project', true, 1);
return;
return 1;
}
try
@ -109,20 +107,21 @@
catch(Exception $e)
{
Console::outException('There was an error while trying to initialize the project', $e, 1);
return;
return 1;
}
Console::out(sprintf('Project successfully created in \'%s\'', $project_manager->getProjectPath()));
Console::out(sprintf('Modify the project configuration in \'%s\'', $project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'project.json'));
return 0;
}
/**
* Applies a template to the project
*
* @param array $args
* @return void
* @return int
*/
private static function applyTemplate(array $args): void
private static function applyTemplate(array $args): int
{
if(isset($args['path']) || isset($args['p']))
{
@ -135,7 +134,7 @@
else
{
Console::outError('Missing option: --path|-p, please specify the path to the project', true, 1);
return;
return 1;
}
if(isset($args['name']) || isset($args['n']))
@ -145,7 +144,7 @@
else
{
Console::outError('Missing required option: --name|-n, please specify the name of the template', true, 1);
return;
return 1;
}
try
@ -155,7 +154,7 @@
catch(Exception $e)
{
Console::outException('There was an error while trying to load the project', $e, 1);
return;
return 1;
}
try
@ -165,18 +164,19 @@
catch(Exception $e)
{
Console::outException('There was an error while trying to apply the template', $e, 1);
return;
return 1;
}
Console::out(sprintf('Template successfully applied to project in \'%s\'', $project_manager->getProjectPath()));
return 0;
}
/**
* Displays the main options section
*
* @return void
* @return int
*/
private static function displayOptions(): void
private static function displayOptions(): int
{
$options = [
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
@ -198,5 +198,7 @@
{
Console::out(' ' . $template);
}
return 0;
}
}

View file

@ -0,0 +1,297 @@
<?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\CLI\Management;
use Exception;
use ncc\Enums\ConsoleColors;
use ncc\Enums\Scopes;
use ncc\Managers\RepositoryManager;
use ncc\Objects\CliHelpSection;
use ncc\Objects\RepositoryConfiguration;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\Resolver;
class RepositoryMenu
{
/**
* Displays the main menu for managing repositories
*
* @param array $args
* @return int
*/
public static function start(array $args): int
{
if(isset($args['add']))
{
try
{
return self::addEntry($args);
}
catch(Exception $e)
{
Console::outException('Error while adding repository.', $e, 1);
return 1;
}
}
if(isset($args['export']))
{
try
{
return self::exportEntry($args);
}
catch(Exception $e)
{
Console::outException('Cannot export repository.', $e, 1);
return 1;
}
}
if(isset($args['remove']))
{
try
{
return self::removeEntry($args);
}
catch(Exception $e)
{
Console::outException('Cannot remove repository.', $e, 1);
return 1;
}
}
if(isset($args['list']))
{
try
{
return self::listEntries();
}
catch(Exception $e)
{
Console::outException('Cannot list entries.', $e, 1);
return 1;
}
}
return self::displayOptions();
}
/**
* Lists all the configured repositories
*
* @return int
*/
private static function listEntries(): int
{
$sources = (new RepositoryManager())->getRepositories();
if(count($sources) === 0)
{
Console::out('No remote sources defined.');
return 0;
}
foreach($sources as $source)
{
$output = sprintf('%s (%s) [%s]',
$source->getName(),
Console::formatColor($source->getHost(), ConsoleColors::GREEN),
Console::formatColor($source->getType(), ConsoleColors::YELLOW)
);
if(!$source->isSsl())
{
$output .= Console::formatColor('*', ConsoleColors::RED);
}
Console::out(' - ' . $output);
}
Console::out(sprintf('Total: %d', count($sources)));
return 0;
}
/**
* Adds a new repository to the system.
*
* @param array $args
* @return int
*/
private static function addEntry(array $args): int
{
if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
Console::outError('You must be running as root to add a new repository', true, 1);
return 1;
}
$name = $args['name'] ?? $args['n'] ?? null;
$type = $args['type'] ?? $args['t'] ?? null;
$host = $args['host'] ?? $args['h'] ?? null;
$ssl = Functions::cbool($args['ssl'] ?? $args['s'] ?? true);
if($name === null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1);
return 1;
}
if($type === null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'type'), true, 1);
return 1;
}
if($host === null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'host'), true, 1);
return 1;
}
try
{
(new RepositoryManager())->addRepository(new RepositoryConfiguration($name, $host, $type, $ssl));
}
catch(Exception $e)
{
Console::outException(sprintf('Cannot add repository \'%s\'.', $name), $e, 1);
return 1;
}
Console::out(sprintf('Repository \'%s\' added successfully.', $name));
return 0;
}
/**
* Exports the repository configuration to the console
*
* @param array $args
* @return int
*/
private static function exportEntry(array $args): int
{
$name = $args['name'] ?? $args['n'] ?? null;
if($name === null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1);
return 1;
}
$repository_manager = new RepositoryManager();
if(!$repository_manager->repositoryExists($name))
{
Console::outError(sprintf('Repository \'%s\' does not exist.', $name), true, 1);
return 1;
}
try
{
$repository = $repository_manager->getRepository($name);
Console::out(json_encode($repository->toArray(), JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}
catch(Exception $e)
{
Console::outException(sprintf('Cannot export repository \'%s\'.', $name), $e, 1);
return 1;
}
return 0;
}
/**
* Removes an existing repository from the system.
*
* @param array $args
* @return int
*/
private static function removeEntry(array $args): int
{
if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
Console::outError('You must be running as root to remove a repository', true, 1);
return 1;
}
$name = $args['name'] ?? $args['n'] ?? null;
if($name === null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1);
return 1;
}
$repository_manager = new RepositoryManager();
if(!$repository_manager->repositoryExists($name))
{
Console::outError(sprintf('Repository \'%s\' does not exist.', $name), true, 1);
return 1;
}
try
{
$repository_manager->removeRepository($name);
}
catch(Exception $e)
{
Console::outException(sprintf('Cannot remove repository \'%s\'.', $name), $e, 1);
return 1;
}
Console::out(sprintf('Repository \'%s\' removed successfully.', $name));
return 0;
}
/**
* Displays the main options section
*
* @return int
*/
private static function displayOptions(): int
{
Console::out('Usage: ncc repo {command} [options]');
Console::out('Options:');
Console::outHelpSections([
new CliHelpSection(['help'], 'Displays this help menu about the repository command'),
new CliHelpSection(['add', '--name|-n', '--type|-t', '--host|-h', '--ssl|-s'], 'Adds a new repository to the system'),
new CliHelpSection(['export', '--name|-n'], 'Prints out the repository configuration to the console (JSON)'),
new CliHelpSection(['remove', '--name|-n'], 'Removes an repository from the system'),
new CliHelpSection(['list'], 'Lists all configured repositories on your system'),
]);
Console::out('Examples:');
Console::out(' - ncc repo add --name github --type github --host api.github.com');
Console::out(' - ncc repo add --name gitlab --type gitlab --host gitlab.com');
Console::out(' - ncc repo add --name gitea --type gitea --host git.example.com --ssl false');
Console::out(' - ncc repo remove --name github');
Console::out(' - ncc repo list');
Console::out('Note: You must have root privileges to add or remove repositories from the system.');
return 0;
}
}

View file

@ -1,240 +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\CLI\Management;
use Exception;
use ncc\Enums\Scopes;
use ncc\Exceptions\IOException;
use ncc\Managers\RemoteSourcesManager;
use ncc\Objects\CliHelpSection;
use ncc\Objects\DefinedRemoteSource;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\Resolver;
class SourcesMenu
{
/**
* Displays the main help menu
*
* @param $args
* @return void
*/
public static function start($args): void
{
if(isset($args['add']))
{
try
{
self::addEntry($args);
}
catch(Exception $e)
{
Console::outException('Error while adding entry.', $e, 1);
}
return;
}
if(isset($args['remove']))
{
try
{
self::removeEntry($args);
}
catch(Exception $e)
{
Console::outException('Cannot remove entry.', $e, 1);
}
return;
}
if(isset($args['list']))
{
try
{
self::listEntries();
}
catch(Exception $e)
{
Console::outException('Cannot list entries.', $e, 1);
}
return;
}
self::displayOptions();
}
/**
* @return void
*/
public static function listEntries(): void
{
$source_manager = new RemoteSourcesManager();
$sources = $source_manager->getSources();
if(count($sources) == 0)
{
Console::out('No remote sources defined.', 1);
return;
}
Console::out('Remote sources:', 1);
foreach($sources as $source)
{
Console::out(' - ' . $source->getName() . ' (' . $source->getHost() . ')', 1);
}
Console::out('Total: ' . count($sources), 1);
}
/**
* @param $args
* @return void
*/
public static function addEntry($args): void
{
if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
Console::outError('Insufficient permissions to add entry.', true, 1);
return;
}
$name = $args['name'] ?? null;
$type = $args['type'] ?? null;
$host = $args['host'] ?? null;
$ssl = $args['ssl'] ?? null;
if($name == null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1);
return;
}
if($type == null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'type'), true, 1);
return;
}
if($host == null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'host'), true, 1);
return;
}
if($ssl !== null)
{
$ssl = Functions::cbool($ssl);
}
$source_manager = new RemoteSourcesManager();
$source = new DefinedRemoteSource();
$source->setName($name);
$source->setType($type);
$source->setHost($host);
$source->setSsl($ssl);
if(!$source_manager->addRemoteSource($source))
{
Console::outError(sprintf('Cannot add entry \'%s\', it already exists', $name), true, 1);
return;
}
try
{
$source_manager->save();
}
catch (IOException $e)
{
Console::outException('Cannot save remote sources file.', $e, 1);
return;
}
Console::out(sprintf('Entry \'%s\' added successfully.', $name));
}
/**
* Removes an existing entry from the vault.
*
* @param $args
* @return void
*/
private static function removeEntry($args): void
{
$ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::SYSTEM)
Console::outError('Insufficient permissions to remove entries');
$name = $args['name'] ?? null;
if($name == null)
{
Console::outError(sprintf('Missing required argument \'%s\'.', 'name'), true, 1);
return;
}
$source_manager = new RemoteSourcesManager();
if(!$source_manager->deleteRemoteSource($name))
{
Console::outError(sprintf('Cannot remove entry \'%s\', it does not exist', $name), true, 1);
return;
}
try
{
$source_manager->save();
}
catch (IOException $e)
{
Console::outException('Cannot save remote sources file.', $e, 1);
return;
}
Console::out(sprintf('Entry \'%s\' removed successfully.', $name));
}
/**
* Displays the main options section
*
* @return void
*/
private static function displayOptions(): void
{
Console::out('Usage: ncc sources {command} [options]');
Console::out('Options:');
Console::outHelpSections([
new CliHelpSection(['help'], 'Displays this help menu about the sources command'),
new CliHelpSection(['add'], 'Adds a new entry to the list of remote sources (See below)'),
new CliHelpSection(['remove', '--name'], 'Removes an entry from the list'),
new CliHelpSection(['list'], 'Lists all entries defined as remote sources'),
]);
Console::out((string)null);
}
}

View file

@ -0,0 +1,125 @@
<?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;
use Exception;
use finfo;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use PharData;
use RuntimeException;
use ZipArchive;
class ArchiveExtractor
{
/**
* Extracts a given archive to a directory path
*
* @param string $archive_path
* @param string $directory_path
* @return void
* @throws IOException
* @throws NotSupportedException
*/
public static function extract(string $archive_path, string $directory_path): void
{
if(!is_file($archive_path))
{
throw new IOException(sprintf('Archive file "%s" does not exist', $archive_path));
}
$file_info = new finfo(FILEINFO_MIME);
$mime = strtolower($file_info->file($archive_path));
if(($pos = strpos($mime, ';')) !== false)
{
$mime = substr($mime, 0, $pos);
}
switch($mime)
{
case 'application/zip':
self::extractZip($archive_path, $directory_path);
break;
case 'application/x-tar':
case 'application/x-gzip':
$phar = new PharData($archive_path);
$phar->extractTo($directory_path);
break;
default:
throw new NotSupportedException(sprintf('Unable to extract archive "%s" of type "%s"', $archive_path, $file_info->file($archive_path)));
}
}
/**
* Extracts a zip archive to a directory
*
* @param string $archive_path
* @param string $directory_path
* @return void
* @throws IOException
*/
private static function extractZip(string $archive_path, string $directory_path): void
{
$zip_archive = new ZipArchive();
if(!$zip_archive->open($archive_path))
{
throw new IOException(sprintf('Unable to open zip archive "%s"', $archive_path));
}
if(!is_dir($directory_path) && !mkdir($directory_path, 0777, true) && !is_dir($directory_path))
{
throw new IOException(sprintf('Unable to create directory "%s"', $directory_path));
}
for($i=0; $i < $zip_archive->numFiles; $i++)
{
$entry_name = $zip_archive->statIndex($i)['name'];
if(str_ends_with($entry_name, '/'))
{
$concurrent_directory = $directory_path . DIRECTORY_SEPARATOR . $entry_name;
if(!is_dir($concurrent_directory) && !mkdir($concurrent_directory, 0777, true) && !is_dir($concurrent_directory))
{
throw new RuntimeException(sprintf('Directory "%s" was not created', $concurrent_directory));
}
continue;
}
try
{
$zip_archive->extractTo($directory_path, $entry_name);
}
catch(Exception $e)
{
throw new IOException(sprintf('Unable to extract file "%s" from archive "%s"', $entry_name, $archive_path), $e);
}
}
$zip_archive->close();
}
}

View file

@ -23,15 +23,11 @@
namespace ncc\Classes\BashExtension;
use Exception;
use InvalidArgumentException;
use ncc\Classes\ExecutionUnitRunner;
use ncc\Enums\Runners;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException;
use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;

View file

@ -1,818 +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\ComposerExtension;
use Exception;
use FilesystemIterator;
use JsonException;
use ncc\Enums\CompilerExtensions;
use ncc\Enums\CompilerExtensionSupportedVersions;
use ncc\Enums\ComponentFileExtensions;
use ncc\Enums\DependencySourceType;
use ncc\Enums\LogLevel;
use ncc\Enums\Scopes;
use ncc\CLI\Main;
use ncc\Exceptions\BuildException;
use ncc\Exceptions\ComposerException;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException;
use ncc\Exceptions\PackageException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\RuntimeException;
use ncc\Interfaces\ServiceSourceInterface;
use ncc\Managers\ProjectManager;
use ncc\ncc;
use ncc\Objects\ComposerJson;
use ncc\Objects\ComposerLock;
use ncc\Objects\ProjectConfiguration;
use ncc\Objects\RemotePackageInput;
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
use ncc\ThirdParty\Symfony\Process\Process;
use ncc\ThirdParty\Symfony\Uid\Uuid;
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache;
use SplFileInfo;
class ComposerSourceBuiltin implements ServiceSourceInterface
{
/**
* Attempts to acquire the package from the composer repository and
* convert all composer packages to standard NCC packages by generating
* a package.json file and building all the required packages and dependencies.
*
* Returns the requested package, note that all the dependencies (if any) are also
* in the same directory as the requested package and are referenced as local
* packages that ncc can use to install the main package.
*
* @param RemotePackageInput $packageInput
* @return string
* @throws BuildException
* @throws ComposerException
* @throws ConfigurationException
* @throws IOException
* @throws NotSupportedException
* @throws OperationException
* @throws PackageException
* @throws PathNotFoundException
* @throws RuntimeException
*/
public static function fetch(RemotePackageInput $packageInput): string
{
$package_path = self::require($packageInput->getVendor(), $packageInput->getPackage(), $packageInput->getVersion());
$packages = self::compilePackages($package_path . DIRECTORY_SEPARATOR . 'composer.lock');
$real_package_name = explode('=', $packageInput->toStandard(false))[0];
RuntimeCache::setFileAsTemporary($package_path);
foreach($packages as $package => $path)
{
if(explode('=', $package)[0] === $real_package_name)
{
return $path;
}
}
throw new RuntimeException(sprintf('Could not find package %s in the compiled packages', $packageInput->toStandard()));
}
/**
* Works with a local composer.json file and attempts to compile the required packages
* and their dependencies, returns the path to the compiled package.
*
* @param string $path
* @return string
* @throws BuildException
* @throws ComposerException
* @throws ConfigurationException
* @throws IOException
* @throws NotSupportedException
* @throws OperationException
* @throws PackageException
* @throws PathNotFoundException
*/
public static function fromLocal(string $path): string
{
// Check if the file composer.json exists
if (!file_exists($path . DIRECTORY_SEPARATOR . 'composer.json'))
{
throw new PathNotFoundException(sprintf('File "%s" not found', $path . DIRECTORY_SEPARATOR . 'composer.json'));
}
// Execute composer with options
$options = self::getOptions();
$composer_exec = self::getComposerPath();
$process = new Process([$composer_exec, 'install']);
self::prepareProcess($process, $path, $options);
Console::outDebug(sprintf('executing %s', $process->getCommandLine()));
$process->run(function ($type, $buffer)
{
if($type === Process::ERR)
{
Console::outWarning($buffer, false);
}
else
{
Console::out($buffer, false);
}
});
if(!$process->isSuccessful())
{
throw new ComposerException($process->getErrorOutput());
}
$filesystem = new Filesystem();
if($filesystem->exists($path . DIRECTORY_SEPARATOR . 'build'))
{
$filesystem->remove($path . DIRECTORY_SEPARATOR . 'build');
}
$filesystem->mkdir($path . DIRECTORY_SEPARATOR . 'build');
// Compile dependencies
self::compilePackages($path . DIRECTORY_SEPARATOR . 'composer.lock');
$composer_lock = Functions::loadJson(IO::fread($path . DIRECTORY_SEPARATOR . 'composer.lock'), Functions::FORCE_ARRAY);
$version_map = self::getVersionMap(ComposerLock::fromArray($composer_lock));
// Finally, convert the main package's composer.json to package.json and compile it
self::convertProject($path, $version_map);
$project_manager = new ProjectManager($path);
$project_manager->load();
$built_package = $project_manager->build();
RuntimeCache::setFileAsTemporary($built_package);
return $built_package;
}
/**
* @param string $composer_lock_path
* @return array
* @throws BuildException
* @throws ConfigurationException
* @throws IOException
* @throws NotSupportedException
* @throws PackageException
* @throws PathNotFoundException
*/
private static function compilePackages(string $composer_lock_path): array
{
if (!file_exists($composer_lock_path))
{
throw new PathNotFoundException($composer_lock_path);
}
$base_dir = dirname($composer_lock_path);
try
{
$composer_lock = ComposerLock::fromArray(json_decode(IO::fread($composer_lock_path), true, 512, JSON_THROW_ON_ERROR));
}
catch(JsonException $e)
{
throw new IOException($composer_lock_path, $e);
}
$filesystem = new Filesystem();
$built_packages = [];
if ($filesystem->exists($base_dir . DIRECTORY_SEPARATOR . 'build'))
{
$filesystem->remove($base_dir . DIRECTORY_SEPARATOR . 'build');
}
$filesystem->mkdir($base_dir . DIRECTORY_SEPARATOR . 'build');
$version_map = self::getVersionMap($composer_lock);
foreach ($composer_lock->getPackages() as $package)
{
$package_path = $base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->getName();
// Load the composer lock file
$composer_package = $composer_lock->getPackage($package->getName());
if ($composer_package === null)
{
throw new PackageException(sprintf('Package "%s" not found in composer lock file', $package->getName()));
}
// Convert it to an NCC project configuration
$project_configuration = self::convertProject($package_path, $version_map, $composer_package);
// Load the project
$project_manager = new ProjectManager($package_path);
$project_manager->load();
$built_package = $project_manager->build();
// Copy the project to the build directory
$out_path = $base_dir . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . sprintf('%s.ncc', $project_configuration->getAssembly()->getPackage());
$filesystem->copy($built_package, $out_path);
$filesystem->remove($built_package);
$built_packages[$project_configuration->getAssembly()->getPackage()] = $out_path;
}
return $built_packages;
}
/**
* Returns array of versions from the ComposerLock file
*
* @param ComposerLock $composerLock
* @return array
*/
private static function getVersionMap(ComposerLock $composerLock): array
{
$version_map = [];
foreach($composerLock->getPackges() as $package)
{
$version_map[$package->getName()] = $package->getVersion();
}
return $version_map;
}
/**
* Converts a composer package name to a valid package name
*
* @param string $input
* @return string|null
*/
private static function toPackageName(string $input): ?string
{
if (strpos($input, ':'))
{
$input = explode(':', $input)[0];
}
$parsed_input = explode("/", $input);
if (count($parsed_input) === 2)
{
return str_ireplace(
"-", "_", 'com.' . $parsed_input[0] . "." . $parsed_input[1]
);
}
return null;
}
/**
* Returns a valid version from a version map
*
* @param string $package_name
* @param array $version_map
* @return string
*/
private static function versionMap(string $package_name, array $version_map): string
{
if (array_key_exists($package_name, $version_map))
{
return Functions::convertToSemVer($version_map[$package_name]);
}
return '1.0.0';
}
/**
* Generates a project configuration from a package selection
* from the composer.lock file
*
* @param ComposerJson $composer_package
* @param array $version_map
* @return ProjectConfiguration
*/
private static function generateProjectConfiguration(ComposerJson $composer_package, array $version_map): ProjectConfiguration
{
// Generate a new project configuration object
$project_configuration = new ProjectConfiguration();
$project_configuration->getAssembly()->setName($composer_package->getName());
$project_configuration->getAssembly()->setDescription($composer_package->getDescription());
if(isset($version_map[$composer_package->getName()]))
{
$project_configuration->getAssembly()->setVersion(self::versionMap($composer_package->getName(), $version_map));
}
if($project_configuration->getAssembly()->getVersion() === '')
{
$project_configuration->getAssembly()->setVersion('1.0.0');
}
$project_configuration->getAssembly()->setUuid(Uuid::v1()->toRfc4122());
$project_configuration->getAssembly()->setPackage(self::toPackageName($composer_package->getName()));
// Add the update source
$project_configuration->getProject()->setUpdateSource(new ProjectConfiguration\UpdateSource());
$project_configuration->getProject()->getUpdateSource()?->setSource(sprintf('%s@composer', str_ireplace('\\', '/', $composer_package->getName())));
$project_configuration->getProject()->getUpdateSource()?->setRepository(null);
// Process the dependencies
if($composer_package->getRequire() !== null && count($composer_package->getRequire()) > 0)
{
foreach ($composer_package->getRequire() as $item)
{
// Check if the dependency is already in the project configuration
$package_name = self::toPackageName($item->getPackageName());
if($package_name === null)
{
continue;
}
$dependency = new ProjectConfiguration\Dependency();
$dependency->setName($package_name);
$dependency->setSourceType(DependencySourceType::LOCAL);
$dependency->setVersion(self::versionMap($item->getPackageName(), $version_map));
$dependency->setSource($package_name . '.ncc');
$project_configuration->getBuild()->addDependency($dependency);
}
}
// Create a build configuration
$build_configuration = new ProjectConfiguration\Build\BuildConfiguration();
$build_configuration->setName('default');
$build_configuration->setOutputPath('build');
// Apply the final properties
$project_configuration->getBuild()->addBuildConfiguration($build_configuration);
$project_configuration->getBuild()->setDefaultConfiguration('default');
$project_configuration->getBuild()->setSourcePath('.src');
// Apply a compiler extension
$project_configuration->getProject()->getCompiler()->setExtension(CompilerExtensions::PHP);
$project_configuration->getProject()->getCompiler()->setMaximumVersion(CompilerExtensionSupportedVersions::PHP[0]);
$project_configuration->getProject()->getCompiler()->setMinimumVersion(CompilerExtensionSupportedVersions::PHP[(count(CompilerExtensionSupportedVersions::PHP) - 1)]);
return $project_configuration;
}
/**
* Gets the applicable options configured for composer
*
* @return array
*/
private static function getOptions(): array
{
$results = [];
$arguments = Main::getArgs();
// Anything beginning with --composer- is a composer option
foreach ($arguments as $argument => $value)
{
if (str_starts_with($argument, 'composer-') && !in_array($argument, $results, true))
{
if (is_bool($value) && $value)
{
$results[] = '--' . str_ireplace('composer-', '', $argument);
}
else
{
$results[] = '--' . str_ireplace('composer-', '', $argument) . '=' . $value;
}
}
}
$options = Functions::getConfigurationProperty('composer.options');
if (!is_array($options))
{
return $results;
}
if (isset($options['quiet']) && $options['quiet'])
{
$results[] = '--quiet';
}
if (isset($options['no_asni']) && $options['no_asni'])
{
$results[] = '--no-asni';
}
if (isset($options['no_interaction']) && $options['no_interaction'])
{
$results[] = '--no-interaction';
}
if(isset($options['profile']) && $options['profile'])
{
$results[] = '--profile';
}
if (isset($options['no_scripts']) && $options['no_scripts'])
{
$results[] = '--no-scripts';
$results[] = '--no-plugins'; // Also include this for safe measures
}
if (isset($options['no_cache']) && $options['no_cache'])
{
$results[] = '--no-cache';
}
// Determine the logging option
if (isset($options['logging']))
{
if ((int)$options['logging'] === 3)
{
$results[] = '-vvv';
}
elseif ((int)$options['logging'] === 2)
{
$results[] = '-vv';
}
elseif ((int)$options['logging'] === 1)
{
$results[] = '-v';
}
else
{
switch (Main::getLogLevel())
{
default:
case LogLevel::FATAL:
case LogLevel::WARNING:
case LogLevel::ERROR:
case LogLevel::INFO:
$results[] = '-v';
break;
case LogLevel::VERBOSE:
$results[] = '-vv';
break;
case LogLevel::DEBUG:
$results[] = '-vvv';
break;
case LogLevel::SILENT:
if (!in_array('--quiet', $results, true))
{
$results[] = '--quiet';
}
break;
}
}
}
return $results;
}
/**
* Uses composers require command to temporarily create a
* composer.json file and install the specified package
*
* @param string $vendor
* @param string $package
* @param string|null $version
* @return string
* @throws ComposerException
* @throws IOException
* @throws OperationException
* @throws PathNotFoundException
*/
private static function require(string $vendor, string $package, ?string $version = null): string
{
if (Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new \RuntimeException('Cannot require a package with insufficient permissions');
}
if ($version === null)
{
$version = '*';
}
if($version === 'latest')
{
$version = '*';
}
$tpl_file = __DIR__ . DIRECTORY_SEPARATOR . 'composer.jtpl';
if (!file_exists($tpl_file))
{
throw new PathNotFoundException($tpl_file);
}
$composer_exec = self::getComposerPath();
$template = IO::fread($tpl_file);
$template = str_ireplace('%VENDOR%', $vendor, $template);
$template = str_ireplace('%PACKAGE%', $package, $template);
$template = str_ireplace('%VERSION%', $version, $template);
$filesystem = new Filesystem();
$tmp_dir = PathFinder::getCachePath(Scopes::SYSTEM) . DIRECTORY_SEPARATOR . hash('haval128,3', $template);
$composer_json_path = $tmp_dir . DIRECTORY_SEPARATOR . 'composer.json';
if ($filesystem->exists($tmp_dir)) {
Console::outVerbose(sprintf('Deleting already existing %s', $tmp_dir));
$filesystem->remove($tmp_dir);
}
$filesystem->mkdir($tmp_dir);
IO::fwrite($composer_json_path, $template, 0777);
// Execute composer with options
$options = self::getOptions();
$process = new Process(array_merge([$composer_exec, 'require'], $options));
self::prepareProcess($process, $tmp_dir, $options);
Console::outDebug(sprintf('executing %s', $process->getCommandLine()));
$process->run(function ($type, $buffer)
{
Console::out($buffer, false);
});
if (!$process->isSuccessful())
{
throw new ComposerException($process->getErrorOutput());
}
return $tmp_dir;
}
/**
* Attempts to find the composer path to use that is currently configured
*
* @return string
* @throws ComposerException
*/
private static function getComposerPath(): string
{
Console::outVerbose(sprintf('Getting composer path for %s', Functions::getConfigurationProperty('composer.path')));
$composer_enabled = Functions::getConfigurationProperty('composer.enabled');
$internal_composer_enabled = Functions::getConfigurationProperty('composer.enable_internal_composer');
if ($composer_enabled !== null && $composer_enabled === false)
{
throw new ComposerException('Composer is disabled by the configuration `composer.enabled`');
}
$config_property = Functions::getConfigurationProperty('composer.executable_path');
Console::outDebug(sprintf('composer.enabled = %s', ($composer_enabled ?? 'n/a')));
Console::outDebug(sprintf('composer.enable_internal_composer = %s', ($internal_composer_enabled ?? 'n/a')));
Console::outDebug(sprintf('composer.executable_path = %s', ($config_property ?? 'n/a')));
if ($internal_composer_enabled && defined('NCC_EXEC_LOCATION'))
{
if (!file_exists(NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'composer.phar'))
{
throw new ComposerException(NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'composer.phar');
}
Console::outDebug(sprintf('using composer path from NCC_EXEC_LOCATION: %s', NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'composer.phar'));
return NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'composer.phar';
}
if ($config_property !== null && $config_property !== '')
{
if (!file_exists($config_property))
{
Console::outWarning('Cannot find composer executable path from configuration `composer.executable_path`');
}
else
{
Console::outDebug(sprintf('using composer path from configuration: %s', $config_property));
return $config_property;
}
}
throw new ComposerException('No composer executable path is configured');
}
/**
* @param Process $process
* @param string $path
* @param array $options
* @return void
* @throws OperationException
*/
private static function prepareProcess(Process $process, string $path, array $options): void
{
$process->setWorkingDirectory($path);
// Check if scripts are enabled while running as root
if (!in_array('--no-scripts', $options, true) && Resolver::resolveScope() === Scopes::SYSTEM)
{
Console::outWarning('composer scripts are enabled while running as root, this can allow malicious scripts to run as root');
if (!isset($options['--no-interaction']))
{
if(!Console::getBooleanInput('Do you want to continue?'))
{
throw new OperationException('The operation was aborted by the user');
}
// The user understands the risks and wants to continue
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
}
}
else
{
// Composer is running "safely". We can disable the superuser check
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
}
}
/**
* Converts a composer project to a NCC project
*
* @param string $package_path
* @param array $version_map
* @param mixed $composer_package
* @return ProjectConfiguration
* @throws IOException
* @throws PackageException
* @throws PathNotFoundException
*/
private static function convertProject(string $package_path, array $version_map, ?ComposerJson $composer_package=null): ProjectConfiguration
{
if($composer_package === null)
{
$composer_package = Functions::loadComposerJson($package_path . DIRECTORY_SEPARATOR . 'composer.json');
}
$project_configuration = self::generateProjectConfiguration($composer_package, $version_map);
$filesystem = new Filesystem();
// Process the source files
if ($composer_package->getAutoload() !== null)
{
$source_directory = $package_path . DIRECTORY_SEPARATOR . '.src';
if($filesystem->exists($source_directory))
{
$filesystem->remove($source_directory);
}
$filesystem->mkdir($source_directory);
$source_directories = [];
$static_files = [];
// Extract all the source directories
if ($composer_package->getAutoloadDev()->getPsr4() !== null && count($composer_package->getAutoload()->getPsr4()) > 0)
{
Console::outVerbose('Extracting PSR-4 source directories');
foreach ($composer_package->getAutoload()->getPsr4() as $namespace_pointer)
{
if ($namespace_pointer->getPath() !== null && !in_array($namespace_pointer->getPath(), $source_directories, true))
{
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->getPath();
}
}
}
if ($composer_package->getAutoload()->getPsr0() !== null && count($composer_package->getAutoload()->getPsr0()) > 0)
{
Console::outVerbose('Extracting PSR-0 source directories');
foreach ($composer_package->getAutoload()->getPsr0() as $namespace_pointer)
{
if ($namespace_pointer->getPath() !== null && !in_array($namespace_pointer->getPath(), $source_directories, true))
{
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->getPath();
}
}
}
if ($composer_package->getAutoload()->getFiles() !== null && count($composer_package->getAutoload()->getFiles()) > 0)
{
Console::outVerbose('Extracting static files');
foreach ($composer_package->getAutoload()->getFiles() as $file)
{
$static_files[] = $package_path . DIRECTORY_SEPARATOR . $file;
}
}
Console::outDebug(sprintf('source directories: %s', implode(', ', $source_directories)));
// First scan the project files and create a file struct.
$DirectoryScanner = new DirectoryScanner();
// TODO: Implement exclude-class handling
try
{
$DirectoryScanner->unsetFlag(FilesystemIterator::FOLLOW_SYMLINKS);
}
catch (Exception $e)
{
throw new PackageException('Cannot unset flag \'FOLLOW_SYMLINKS\' in DirectoryScanner, ' . $e->getMessage(), $e);
}
// Include file components that can be compiled
$DirectoryScanner->setIncludes(ComponentFileExtensions::PHP);
foreach ($source_directories as $directory)
{
/** @var SplFileInfo $item */
foreach ($DirectoryScanner($directory) as $item)
{
if(is_dir($item->getPathName()))
{
continue;
}
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName());
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $composer_package->getName()));
$filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
}
}
if (count($static_files) > 0)
{
$project_configuration->getProject()->addOption('static_files', $static_files);
foreach ($static_files as $file)
{
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $file);
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $composer_package->getName()));
$filesystem->copy($file, $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
unset($file);
}
}
}
$project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json');
// This part simply displays the package information to the command-line interface
if(ncc::cliMode())
{
$license_files = [
'LICENSE',
'license',
'LICENSE.txt',
'license.txt',
'LICENSE.md',
'license.md',
];
foreach($license_files as $license_file)
{
// Check configuration if composer.extension.display_licenses is set
if($filesystem->exists($package_path . DIRECTORY_SEPARATOR . $license_file) && Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_licenses')))
{
Console::out(sprintf('License for package %s:', $composer_package->getName()));
Console::out(IO::fread($package_path . DIRECTORY_SEPARATOR . $license_file));
break;
}
}
if(Functions::cbool(!is_null($composer_package->getAuthors()) && count($composer_package->getAuthors()) > 0 && Functions::getConfigurationProperty('composer.extension.display_authors')))
{
Console::out(sprintf('Authors for package %s:', $composer_package->getName()));
foreach($composer_package->getAuthors() as $author)
{
Console::out(sprintf(' - %s', $author->getName()));
if($author->getEmail() !== null)
{
Console::out(sprintf(' %s', $author->getEmail()));
}
if($author->getHomepage() !== null)
{
Console::out(sprintf(' %s', $author->getHomepage()));
}
if($author->getRole() !== null)
{
Console::out(sprintf(' %s', $author->getRole()));
}
}
}
}
return $project_configuration;
}
}

View file

@ -1,5 +0,0 @@
{
"require": {
"%VENDOR%/%PACKAGE%": "%VERSION%"
}
}

View file

@ -121,7 +121,7 @@
}
/**
* Executes the execution policy directly from a package (if supported)
* Executes the execution policy directly from a package (if supported) and returns the exit code
*
* @param PackageReader $package_reader
* @param string $policy_name

View file

@ -1,163 +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;
use ncc\Exceptions\GitException;
use ncc\ThirdParty\Symfony\Process\Process;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
class GitClient
{
/**
* Clones a remote repository to a temporary directory.
*
* @param string $url
* @return string
* @throws GitException
*/
public static function cloneRepository(string $url): string
{
Console::outVerbose('Cloning repository: ' . $url);
$path = Functions::getTmpDir();
$process = new Process(["git", "clone", "--recurse-submodules", $url, $path]);
$process->setTimeout(3600); // 1 hour
$process->run(function ($type, $buffer)
{
if(Process::ERR === $type)
{
Console::outWarning($buffer);
}
{
Console::outVerbose($buffer);
}
});
if (!$process->isSuccessful())
{
throw new GitException(sprintf('Failed to clone repository %s: %s', $url, $process->getErrorOutput()));
}
Console::outVerbose('Repository cloned to: ' . $path);
return $path;
}
/**
* Checks out a specific branch or tag.
*
* @param string $path
* @param string $branch
* @throws GitException
*/
public static function checkout(string $path, string $branch): void
{
Console::outVerbose('Checking out branch' . $branch);
$process = new Process(["git", "checkout", $branch], $path);
$process->setTimeout(3600); // 1 hour
$process->run(function ($type, $buffer)
{
if (Process::ERR === $type)
{
Console::outWarning($buffer);
}
else
{
Console::outVerbose($buffer);
}
});
if (!$process->isSuccessful())
{
throw new GitException(sprintf('Failed to checkout branch %s in repository %s: %s', $branch, $path, $process->getErrorOutput()));
}
Console::outVerbose('Checked out branch: ' . $branch);
Console::outVerbose('Updating submodules');
$process = new Process(["git", "submodule", "update", "--init", "--recursive"], $path);
$process->setTimeout(3600); // 1 hour
$process->run(function ($type, $buffer)
{
if (Process::ERR === $type)
{
Console::outWarning($buffer);
}
else
{
Console::outVerbose($buffer);
}
});
if (!$process->isSuccessful())
{
throw new GitException(sprintf('Failed to update submodules in repository %s: %s', $path, $process->getErrorOutput()));
}
Console::outVerbose('Submodules updated');
}
/**
* Returns an array of tags that are available in the repository.
*
* @param string $path
* @return array
* @throws GitException
*/
public static function getTags(string $path): array
{
Console::outVerbose('Getting tags for repository: ' . $path);
$process = new Process(["git", "fetch", '--all', '--tags'] , $path);
$process->setTimeout(3600); // 1 hour
$process->run(function ($type, $buffer)
{
Console::outVerbose($buffer);
});
if (!$process->isSuccessful())
{
throw new GitException(sprintf('Failed to fetch tags in repository %s: %s', $path, $process->getErrorOutput()));
}
$process = new Process(['git', '--no-pager', 'tag', '-l'] , $path);
$process->run(function ($type, $buffer)
{
Console::outVerbose($buffer);
});
if (!$process->isSuccessful())
{
throw new GitException(sprintf('Failed to get tags in repository %s: %s', $path, $process->getErrorOutput()));
}
$tags = explode(PHP_EOL, $process->getOutput());
$tags = array_filter($tags, static function ($tag)
{
return !empty($tag);
});
Console::outDebug('found ' . count($tags) . ' tags');
return array_filter($tags);
}
}

View file

@ -0,0 +1,451 @@
<?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\GiteaExtension;
use CurlHandle;
use Exception;
use JsonException;
use ncc\Enums\Types\AuthenticationType;
use ncc\Enums\Types\HttpRequestType;
use ncc\Enums\Types\RepositoryResultType;
use ncc\Enums\Versions;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\NetworkException;
use ncc\Interfaces\AuthenticationInterface;
use ncc\Interfaces\RepositoryInterface;
use ncc\Objects\RepositoryConfiguration;
use ncc\Objects\RepositoryResult;
use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword;
use RuntimeException;
class GiteaRepository implements RepositoryInterface
{
/**
* @inheritDoc
*/
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult
{
try
{
return self::getReleaseArchive($repository, $vendor, $project, $version, $authentication);
}
catch(Exception $e)
{
unset($e);
}
return self::getTagArchive($repository, $vendor, $project, $version, $authentication);
}
/**
* @inheritDoc
*/
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult
{
return self::getReleasePackage($repository, $vendor, $project, $version, $authentication);
}
/**
* Returns an array of tags for the specified group and project, usually
* sorted by the most recent tag first if the server supports it.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tags for (eg; "Nosial")
* @param string $project The project to get the tags for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string[] An array of tags for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getTags(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): array
{
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v1/repos/%s/%s/tags', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($group), rawurlencode($project));
$headers = [
'Accept: application/json',
'Content-Type: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$results = [];
foreach(self::processHttpResponse($curl, $group, $project) as $tag)
{
if(isset($tag['name']))
{
$results[] = $tag['name'];
}
}
return $results;
}
/**
* Returns the latest tag for the specified group and project.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tag for (eg; "Nosial")
* @param string $project The project to get the tag for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string The latest tag for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getLatestTag(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): string
{
$results = self::getTags($repository, $group, $project, $authentication);
if(count($results) === 0)
{
throw new NetworkException(sprintf('No tags found for %s/%s', $group, $project));
}
return $results[0];
}
/**
* Returns a downloadable archive of the specified tag for the specified group and project.
* The function will try to find a .zip archive first, and if it can't find one, it will
* try to find a .tar.gz archive. If it can't find either, it will throw an exception.
*
* @param RepositoryConfiguration $repository
* @param string $group The group to get the tag for (eg; "Nosial")
* @param string $project The project to get the tag for (eg; "ncc" or "libs/config")
* @param string $tag The tag to get the tag for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication=null): RepositoryResult
{
if($tag === Versions::LATEST)
{
$tag = self::getLatestTag($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v1/repos/%s/%s/tags/%s', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($group), rawurlencode($project), rawurlencode($tag));
$headers = [
'Accept: application/json',
'Content-Type: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
if(isset($response['zipball_url']))
{
return $response['zipball_url'];
}
if(isset($response['tarball_url']))
{
return $response['tarball_url'];
}
throw new NetworkException(sprintf('Failed to get tag archive %s url for %s/%s', $tag, $group, $project));
}
/**
* Returns an array of tags for the specified group and project,
* usually sorted by the most recent tag first if the server supports it.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tags for (eg; "Nosial")
* @param string $project The project to get the tags for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return array An array of tag names for releases
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleases(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): array
{
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v1/repos/%s/%s/releases', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($group), rawurlencode($project));
$headers = [
'Accept: application/json',
'Content-Type: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$results = [];
foreach(self::processHttpResponse($curl, $group, $project) as $release)
{
if(isset($release['tag_name']))
{
$results[] = $release['tag_name'];
}
}
return $results;
}
/**
* Returns the latest release for the specified group and project.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string The latest release for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getLatestRelease(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): string
{
$results = self::getReleases($repository, $group, $project, $authentication);
if(count($results) === 0)
{
throw new NetworkException(sprintf('No releases found for %s/%s', $group, $project));
}
return $results[0];
}
/**
* Returns a downloadable ncc package of the specified release for the specified group and project.
* If the function can't find a .ncc package, it will throw an exception.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param string $release The release to get the release for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{
/** @noinspection DuplicatedCode */
if($release === Versions::LATEST)
{
$release = self::getLatestRelease($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v1/repos/%s/%s/releases/tags/%s', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($group), rawurlencode($project), rawurlencode($release));
$headers = [
'Accept: application/json',
'Content-Type: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
if(!isset($response['assets']))
{
throw new NetworkException(sprintf('Failed to get release %s package url for %s/%s', $release, $group, $project));
}
foreach($response['assets'] as $asset)
{
if(isset($asset['name'], $asset['browser_download_url']) && preg_match('/\.ncc$/', $asset['name']))
{
return new RepositoryResult($asset['browser_download_url'], RepositoryResultType::PACKAGE, $release);
}
}
throw new NetworkException(sprintf('No ncc package found for %s/%s/%s', $group, $project, $release));
}
/**
* Returns a downloadable archive of the specified release for the specified group and project.
* The function will try to find a .zip archive first, and if it can't find one, it will
* try to find a .tar.gz archive. If it can't find either, it will throw an exception.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param string $release The release to get the release for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{
/** @noinspection DuplicatedCode */
if ($release === Versions::LATEST)
{
$release = self::getLatestRelease($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v1/repos/%s/%s/releases/tags/%s', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($group), rawurlencode($project), rawurlencode($release));
$headers = [
'Accept: application/json',
'Content-Type: application/json',
'User-Agent: ncc'
];
if ($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
if(isset($response['zipball_url']))
{
return new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE, $release);
}
if(isset($response['tarball_url']))
{
return new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE, $release);
}
throw new NetworkException(sprintf('Failed to get release %s archive url for %s/%s', $release, $group, $project));
}
/**
* Injects the authentication into the curl request
*
* @param AuthenticationInterface $authentication
* @param CurlHandle $curl
* @param array $headers
* @return array
* @throws AuthenticationException
*/
private static function injectAuthentication(AuthenticationInterface $authentication, CurlHandle $curl, array $headers): array
{
switch($authentication->getAuthenticationType())
{
case AuthenticationType::ACCESS_TOKEN:
if($authentication instanceof AccessToken)
{
$headers[] = 'Authorization: token ' . $authentication->getAccessToken();
break;
}
throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()));
case AuthenticationType::USERNAME_PASSWORD:
if($authentication instanceof UsernamePassword)
{
curl_setopt($curl, CURLOPT_USERPWD, $authentication->getUsername() . ':' . $authentication->getPassword());
break;
}
throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()));
}
return $headers;
}
/**
* Executes the HTTP request and processes the response
* Throws an exception if the request failed
*
* @param CurlHandle $curl
* @param string $group
* @param string $project
* @return array
* @throws AuthenticationException
* @throws NetworkException
*/
private static function processHttpResponse(CurlHandle $curl, string $group, string $project): array
{
$response = curl_exec($curl);
if($response === false)
{
throw new NetworkException(sprintf('HTTP request failed for %s/%s: %s', $group, $project, curl_error($curl)));
}
switch(curl_getinfo($curl, CURLINFO_HTTP_CODE))
{
case 200:
break;
case 401:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 401 Unauthorized, invalid/expired access token', $group, $project));
case 403:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 403 Forbidden, insufficient scope', $group, $project));
case 404:
throw new NetworkException(sprintf('HTTP request failed for %s/%s, 404 Not Found', $group, $project));
default:
throw new NetworkException(sprintf('Server responded with HTTP code %s for %s/%s: %s', curl_getinfo($curl, CURLINFO_HTTP_CODE), $group, $project, $response));
}
try
{
return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
catch(JsonException $e)
{
throw new RuntimeException(sprintf('Failed to parse response from %s/%s: %s', $group, $project, $e->getMessage()), $e);
}
}
}

View file

@ -0,0 +1,452 @@
<?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\GithubExtension;
use CurlHandle;
use Exception;
use JsonException;
use ncc\Enums\Types\AuthenticationType;
use ncc\Enums\Types\HttpRequestType;
use ncc\Enums\Types\RepositoryResultType;
use ncc\Enums\Versions;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\NetworkException;
use ncc\Interfaces\AuthenticationInterface;
use ncc\Interfaces\RepositoryInterface;
use ncc\Objects\RepositoryConfiguration;
use ncc\Objects\RepositoryResult;
use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword;
use RuntimeException;
class GithubRepository implements RepositoryInterface
{
/**
* @inheritDoc
*/
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult
{
try
{
return self::getReleaseArchive($repository, $vendor, $project, $version, $authentication);
}
catch(Exception $e)
{
unset($e);
}
return self::getTagArchive($repository, $vendor, $project, $version, $authentication);
}
/**
* @inheritDoc
*/
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult
{
return self::getReleasePackage($repository, $vendor, $project, $version, $authentication);
}
/**
* Returns an array of tags for the specified group and project, usually
* sorted by the most recent tag first if the server supports it.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tags for (eg; "Nosial")
* @param string $project The project to get the tags for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string[] An array of tags for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getTags(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication = null): array
{
$curl = curl_init();
$endpoint = sprintf('%s://%s/repos/%s/%s/tags', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), $group, $project);
$headers = [
'Accept: application/vnd.github+json',
'X-GitHub-Api-Version: 2022-11-28',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$results = [];
foreach(self::processHttpResponse($curl, $group, $project) as $tag)
{
if(isset($tag['name']))
{
$results[] = $tag['name'];
}
}
return $results;
}
/**
* Returns the latest tag for the specified group and project.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tag for (eg; "Nosial")
* @param string $project The project to get the tag for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string The latest tag for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getLatestTag(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication = null): string
{
$results = self::getTags($repository, $group, $project, $authentication);
if(count($results) === 0)
{
throw new NetworkException(sprintf('No tags found for %s/%s', $group, $project));
}
return $results[0];
}
/**
* Returns a downloadable archive of the specified tag for the specified group and project.
* The function will try to find a .zip archive first, and if it can't find one, it will
* try to find a .tar.gz archive. If it can't find either, it will throw an exception.
*
* @param RepositoryConfiguration $repository
* @param string $group The group to get the tag for (eg; "Nosial")
* @param string $project The project to get the tag for (eg; "ncc" or "libs/config")
* @param string $tag The tag to get the tag for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication = null): RepositoryResult
{
if($tag === Versions::LATEST)
{
$tag = self::getLatestTag($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/repos/%s/%s/zipball/refs/tags/%s', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), $group, $project, $tag);
$headers = [
'User-Agent: ncc'
];
if ($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
if ($response === false)
{
throw new NetworkException(sprintf('Failed to get tag archive for %s/%s/%s: %s', $group, $project, $tag, curl_error($curl)));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code !== 200)
{
throw new NetworkException(sprintf('Server responded with HTTP code %s when getting tag archive for %s/%s/%s', $http_code, $group, $project, $tag));
}
return new RepositoryResult(curl_getinfo($curl, CURLINFO_EFFECTIVE_URL), RepositoryResultType::SOURCE, $tag);
}
/**
* Returns an array of tags for the specified group and project,
* usually sorted by the most recent tag first if the server supports it.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tags for (eg; "Nosial")
* @param string $project The project to get the tags for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return array An array of tag names for releases
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleases(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): array
{
$curl = curl_init();
$endpoint = sprintf('%s://%s/repos/%s/%s/releases', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), $group, $project);
$headers = [
'Accept: application/vnd.github+json',
'X-GitHub-Api-Version: 2022-11-28',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$results = [];
foreach(self::processHttpResponse($curl, $group, $project) as $release)
{
if(isset($release['tag_name']))
{
$results[] = $release['tag_name'];
}
}
return $results;
}
/**
* Returns the latest release for the specified group and project.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string The latest release for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getLatestRelease(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): string
{
$results = self::getReleases($repository, $group, $project, $authentication);
if(count($results) === 0)
{
throw new NetworkException(sprintf('No releases found for %s/%s', $group, $project));
}
return $results[0];
}
/**
* Returns a downloadable ncc package of the specified release for the specified group and project.
* If the function can't find a .ncc package, it will throw an exception.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param string $release The release to get the release for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{
/** @noinspection DuplicatedCode */
if($release === Versions::LATEST)
{
$release = self::getLatestRelease($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/repos/%s/%s/releases/tags/%s', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), $group, $project, $release);
$headers = [
'Accept: application/vnd.github+json',
'X-GitHub-Api-Version: 2022-11-28',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
if(!isset($response['assets']))
{
throw new NetworkException(sprintf('Failed to get release package for %s/%s/%s: No assets found', $group, $project, $release));
}
foreach($response['assets'] as $asset)
{
if(preg_match('/\.ncc$/', $asset['name']) === 1)
{
return new RepositoryResult($asset['browser_download_url'], RepositoryResultType::PACKAGE, $release);
}
}
throw new NetworkException(sprintf('Failed to get release package for %s/%s/%s: No assets found', $group, $project, $release));
}
/**
* Returns a downloadable archive of the specified release for the specified group and project.
* The function will try to find a .zip archive first, and if it can't find one, it will
* try to find a .tar.gz archive. If it can't find either, it will throw an exception.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param string $release The release to get the release for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication = null): RepositoryResult
{
/** @noinspection DuplicatedCode */
if($release === Versions::LATEST)
{
$release = self::getLatestRelease($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/repos/%s/%s/releases/tags/%s', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), $group, $project, $release);
$headers = [
'Accept: application/vnd.github+json',
'X-GitHub-Api-Version: 2022-11-28',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
if(isset($response['zipball_url']))
{
return new RepositoryResult($response['zipball_url'], RepositoryResultType::SOURCE, $release);
}
if(isset($response['tarball_url']))
{
return new RepositoryResult($response['tarball_url'], RepositoryResultType::SOURCE, $release);
}
throw new NetworkException(sprintf('Failed to get release archive for %s/%s/%s: No archive found', $group, $project, $release));
}
/**
* Injects the authentication into the curl request
*
* @param AuthenticationInterface $authentication
* @param CurlHandle $curl
* @param array $headers
* @return array
* @throws AuthenticationException
*/
private static function injectAuthentication(AuthenticationInterface $authentication, CurlHandle $curl, array $headers): array
{
switch($authentication->getAuthenticationType())
{
case AuthenticationType::ACCESS_TOKEN:
if($authentication instanceof AccessToken)
{
$headers[] = 'Authorization: Bearer ' . $authentication->getAccessToken();
break;
}
throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()));
case AuthenticationType::USERNAME_PASSWORD:
if($authentication instanceof UsernamePassword)
{
curl_setopt($curl, CURLOPT_USERPWD, $authentication->getUsername() . ':' . $authentication->getPassword());
break;
}
throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()));
}
return $headers;
}
/**
* Executes the HTTP request and processes the response
* Throws an exception if the request failed
*
* @param CurlHandle $curl
* @param string $group
* @param string $project
* @return array
* @throws AuthenticationException
* @throws NetworkException
*/
private static function processHttpResponse(CurlHandle $curl, string $group, string $project): array
{
$response = curl_exec($curl);
if($response === false)
{
throw new NetworkException(sprintf('HTTP request failed for %s/%s: %s', $group, $project, curl_error($curl)));
}
switch (curl_getinfo($curl, CURLINFO_HTTP_CODE))
{
case 200:
break;
case 401:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 401 Unauthorized, invalid/expired access token', $group, $project));
case 403:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 403 Forbidden, insufficient scope', $group, $project));
case 404:
throw new NetworkException(sprintf('Resource not found for %s/%s, server returned 404 Not Found', $group, $project));
default:
throw new NetworkException(sprintf('Server responded with HTTP code %s for %s/%s: %s', curl_getinfo($curl, CURLINFO_HTTP_CODE), $group, $project, $response));
}
try
{
return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
catch(JsonException $e)
{
throw new RuntimeException(sprintf('Failed to parse response from %s/%s: %s', $group, $project, $e->getMessage()), $e);
}
}
}

View file

@ -1,281 +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\GithubExtension;
use ncc\Enums\HttpRequestType;
use ncc\Enums\Versions;
use ncc\Classes\HttpClient;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\GitException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NetworkException;
use ncc\Interfaces\RepositorySourceInterface;
use ncc\Objects\DefinedRemoteSource;
use ncc\Objects\HttpRequest;
use ncc\Objects\RemotePackageInput;
use ncc\Objects\RepositoryQueryResults;
use ncc\Objects\Vault\Entry;
use ncc\ThirdParty\jelix\Version\VersionComparator;
use ncc\Utilities\Functions;
class GithubService implements RepositorySourceInterface
{
/**
* Returns the git repository url of the repository, versions cannot be specified.
*
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return RepositoryQueryResults
* @throws AuthenticationException
* @throws GitException
* @throws NetworkException
* @throws IOException
*/
public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
{
$httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->isSsl() ? "https" : "http");
$owner_f = str_ireplace(array("/", "."), "%2F", $packageInput->getVendor());
$repository = urlencode($packageInput->getPackage());
$httpRequest->setUrl($protocol . '://' . $definedRemoteSource->getHost() . "/repos/$owner_f/$repository");
$response_decoded = self::getJsonResponse($httpRequest, $entry);
$query = new RepositoryQueryResults();
$query->getFiles()->GitSshUrl = ($response_decoded['ssh_url'] ?? null);
$query->getFiles()->GitHttpUrl = ($response_decoded['clone_url'] ?? null);
$query->setVersion(Functions::convertToSemVer($response_decoded['default_branch'] ?? null));
$query->setReleaseDescription($response_decoded['description'] ?? null);
$query->setReleaseName($response_decoded['name'] ?? null);
return $query;
}
/**
* Returns the download URL of the requested version of the package.
*
* @param RemotePackageInput $package_input
* @param DefinedRemoteSource $defined_remote_source
* @param Entry|null $entry
* @return RepositoryQueryResults
* @throws AuthenticationException
* @throws GitException
* @throws NetworkException
* @throws IOException
*/
public static function getRelease(RemotePackageInput $package_input, DefinedRemoteSource $defined_remote_source, ?Entry $entry = null): RepositoryQueryResults
{
return self::processReleases($package_input, $defined_remote_source, $entry);
}
/**
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return RepositoryQueryResults
* @throws AuthenticationException
* @throws GitException
* @throws NetworkException
* @throws IOException
*/
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
{
return self::processReleases($packageInput, $definedRemoteSource, $entry);
}
/**
* Returns a list of all releases of the given repository with their download URL.
*
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return array
* @throws AuthenticationException
* @throws GitException
* @throws NetworkException
* @throws IOException
*/
private static function getReleases(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): array
{
$httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->isSsl() ? "https" : "http");
$owner_f = str_ireplace(array("/", "."), "%2F", $packageInput->getVersion());
$repository = urlencode($packageInput->getPackage());
$httpRequest->setUrl($protocol . '://' . $definedRemoteSource->getHost() . "/repos/$owner_f/$repository/releases");
$response_decoded = self::getJsonResponse($httpRequest, $entry);
if(count($response_decoded) === 0)
{
return [];
}
$return = [];
foreach($response_decoded as $release)
{
$query_results = new RepositoryQueryResults();
$query_results->setVersion(Functions::convertToSemVer($release['tag_name']));
$query_results->setReleaseName($release['name']);
$query_results->getReleaseDescription($release['body']);
$query_results->getFiles()->ZipballUrl = ($release['zipball_url'] ?? null);
$query_results->getFiles()->TarballUrl = ($release['tarball_url'] ?? null);
if(isset($release['assets']))
{
foreach($release['assets'] as $asset)
{
$parsed_asset = self::parseAsset($asset);
if($parsed_asset !== null)
{
$query_results->getFiles()->PackageUrl = $parsed_asset;
}
}
}
$return[$query_results->getVersion()] = $query_results;
}
return $return;
}
/**
* Returns the asset download URL if it points to a .ncc package.
*
* @param array $asset
* @return string|null'
*/
private static function parseAsset(array $asset): ?string
{
if(isset($asset['browser_download_url']))
{
$file_extension = pathinfo($asset['browser_download_url'], PATHINFO_EXTENSION);
if($file_extension === 'ncc')
{
return $asset['browser_download_url'];
}
}
return null;
}
/**
* @param HttpRequest $httpRequest
* @param Entry|null $entry
* @return array
* @throws AuthenticationException
* @throws GitException
* @throws IOException
* @throws NetworkException
*/
private static function getJsonResponse(HttpRequest $httpRequest, ?Entry $entry): array
{
$httpRequest->setType(HttpRequestType::GET);
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false);
$httpRequest->addHeader('X-GitHub-Api-Version: 2022-11-28');
$httpRequest->addHeader('Accept: application/vnd.github+json');
$response = HttpClient::request($httpRequest, true);
if ($response->getStatusCode() !== 200)
{
throw new GitException(sprintf('Github returned an error (%s): %s', $response->getStatusCode(), $response->getBody()));
}
return Functions::loadJson($response->getBody(), Functions::FORCE_ARRAY);
}
/**
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return mixed
* @throws AuthenticationException
* @throws GitException
* @throws NetworkException
* @throws IOException
*/
private static function processReleases(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): mixed
{
$releases = self::getReleases($packageInput, $definedRemoteSource, $entry);
if (count($releases) === 0)
{
throw new GitException(sprintf('No releases found for %s/%s on %s.', $packageInput->getVendor(), $packageInput->getPackage(), $definedRemoteSource->getHost()));
}
if ($packageInput->getVersion() === Versions::LATEST)
{
$latest_version = null;
foreach ($releases as $release)
{
if ($latest_version === null)
{
$latest_version = $release->Version;
continue;
}
if (VersionComparator::compareVersion($release->Version, $latest_version) === 1)
{
$latest_version = $release->Version;
}
}
return $releases[$latest_version];
}
// Query a specific version
if (!isset($releases[$packageInput->getVersion()]))
{
// Find the closest thing to the requested version
$selected_version = null;
foreach ($releases as $version => $url)
{
if ($selected_version === null)
{
$selected_version = $version;
continue;
}
if (VersionComparator::compareVersion($version, $packageInput->getVersion()) === 1)
{
$selected_version = $version;
}
}
if ($selected_version === null)
{
throw new GitException(sprintf('Version %s not found for %s/%s on %s.', $packageInput->getVersion(), $packageInput->getVendor(), $packageInput->getPackage(), $definedRemoteSource->getHost()));
}
}
else
{
$selected_version = $packageInput->getVersion();
}
if (!isset($releases[$selected_version]))
{
throw new GitException(sprintf('Version %s not found for %s/%s on %s.', $packageInput->getVersion(), $packageInput->getVendor(), $packageInput->getPackage(), $definedRemoteSource->getHost()));
}
return $releases[$selected_version];
}
}

View file

@ -0,0 +1,471 @@
<?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\GitlabExtension;
use CurlHandle;
use Exception;
use JsonException;
use ncc\Enums\Types\AuthenticationType;
use ncc\Enums\Types\HttpRequestType;
use ncc\Enums\Types\RepositoryResultType;
use ncc\Enums\Versions;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\NetworkException;
use ncc\Interfaces\AuthenticationInterface;
use ncc\Interfaces\RepositoryInterface;
use ncc\Objects\RepositoryConfiguration;
use ncc\Objects\RepositoryResult;
use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword;
use RuntimeException;
class GitlabRepository implements RepositoryInterface
{
/**
* @inheritDoc
*/
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult
{
try
{
return self::getReleaseArchive($repository, $vendor, $project, $version, $authentication);
}
catch(Exception $e)
{
unset($e);
}
return self::getTagArchive($repository, $vendor, $project, $version, $authentication);
}
/**
* @inheritDoc
*/
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult
{
return self::getReleasePackage($repository, $vendor, $project, $version, $authentication);
}
/**
* Returns an array of tags for the specified group and project, usually
* sorted by the most recent tag first if the server supports it.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tags for (eg; "Nosial")
* @param string $project The project to get the tags for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string[] An array of tags for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getTags(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): array
{
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v4/projects/%s%%2F%s/repository/tags?order_by=updated&sort=desc', $repository->isSsl() ? 'https' : 'http', $repository->getHost(), $group, rawurlencode($project));
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$results = [];
foreach(self::processHttpResponse($curl, $group, $project) as $tag)
{
if(isset($tag['release']['tag_name']))
{
$results[] = $tag['release']['tag_name'];
}
}
return $results;
}
/**
* Returns the latest tag for the specified group and project.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tag for (eg; "Nosial")
* @param string $project The project to get the tag for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string The latest tag for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getLatestTag(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): string
{
$results = self::getTags($repository, $group, $project, $authentication);
if(count($results) === 0)
{
throw new NetworkException(sprintf('No tags found for %s/%s', $group, $project));
}
return $results[0];
}
/**
* Returns a downloadable archive of the specified tag for the specified group and project.
* The function will try to find a .zip archive first, and if it can't find one, it will
* try to find a .tar.gz archive. If it can't find either, it will throw an exception.
*
* @param RepositoryConfiguration $repository
* @param string $group The group to get the tag for (eg; "Nosial")
* @param string $project The project to get the tag for (eg; "ncc" or "libs/config")
* @param string $tag The tag to get the tag for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getTagArchive(RepositoryConfiguration $repository, string $group, string $project, string $tag, ?AuthenticationInterface $authentication=null): RepositoryResult
{
if($tag === Versions::LATEST)
{
$tag = self::getLatestTag($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v4/projects/%s%%2F%s/repository/archive.zip?sha=%s', $repository->isSsl() ? 'https' : 'http', $repository->getHost(), $group, rawurlencode($project), rawurlencode($tag));
$headers = [
'User-Agent: ncc'
];
if ($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_NOBODY, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($curl);
if ($response === false)
{
throw new NetworkException(sprintf('Failed to get tag archive for %s/%s/%s: %s', $group, $project, $tag, curl_error($curl)));
}
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($http_code !== 200)
{
throw new NetworkException(sprintf('Server responded with HTTP code %s when getting tag archive for %s/%s/%s', $http_code, $group, $project, $tag));
}
return new RepositoryResult(curl_getinfo($curl, CURLINFO_EFFECTIVE_URL), RepositoryResultType::SOURCE, $tag);
}
/**
* Returns an array of tags for the specified group and project,
* usually sorted by the most recent tag first if the server supports it.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the tags for (eg; "Nosial")
* @param string $project The project to get the tags for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return array An array of tag names for releases
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleases(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): array
{
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v4/projects/%s%%2F%s/releases?order_by=released_at&sort=desc', $repository->isSsl() ? 'https' : 'http', $repository->getHost(), $group, rawurlencode($project));
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$results = [];
foreach(self::processHttpResponse($curl, $group, $project) as $item)
{
if(isset($item['tag_name']))
{
$results[] = $item['tag_name'];
}
}
return $results;
}
/**
* Returns the latest release for the specified group and project.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return string The latest release for the specified group and project
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getLatestRelease(RepositoryConfiguration $repository, string $group, string $project, ?AuthenticationInterface $authentication=null): string
{
$results = self::getReleases($repository, $group, $project, $authentication);
if(count($results) === 0)
{
throw new NetworkException(sprintf('No releases found for %s/%s', $group, $project));
}
return $results[0];
}
/**
* Returns a downloadable ncc package of the specified release for the specified group and project.
* If the function can't find a .ncc package, it will throw an exception.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param string $release The release to get the release for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleasePackage(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{
/** @noinspection DuplicatedCode */
if($release === Versions::LATEST)
{
$release = self::getLatestRelease($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v4/projects/%s%%2F%s/releases/%s', $repository->isSsl() ? 'https' : 'http', $repository->getHost(), $group, rawurlencode($project), rawurlencode($release));
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
foreach($response['assets']['links'] as $asset)
{
if(preg_match('/\.ncc$/', $asset['name']) === 1)
{
if(isset($asset['direct_asset_url']))
{
return new RepositoryResult($asset['direct_asset_url'], RepositoryResultType::PACKAGE, $release);
}
if(isset($asset['url']))
{
return new RepositoryResult($asset['url'], RepositoryResultType::PACKAGE, $release);
}
throw new NetworkException(sprintf('No direct asset URL found for %s/%s/%s', $group, $project, $release));
}
}
throw new NetworkException(sprintf('No ncc package found for %s/%s/%s', $group, $project, $release));
}
/**
* Returns a downloadable archive of the specified release for the specified group and project.
* The function will try to find a .zip archive first, and if it can't find one, it will
* try to find a .tar.gz archive. If it can't find either, it will throw an exception.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $group The group to get the release for (eg; "Nosial")
* @param string $project The project to get the release for (eg; "ncc" or "libs/config")
* @param string $release The release to get the release for (eg; "v1.0.0")
* @param AuthenticationInterface|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The URL to the archive
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getReleaseArchive(RepositoryConfiguration $repository, string $group, string $project, string $release, ?AuthenticationInterface $authentication=null): RepositoryResult
{
/** @noinspection DuplicatedCode */
if($release === Versions::LATEST)
{
$release = self::getLatestRelease($repository, $group, $project, $authentication);
}
$curl = curl_init();
$endpoint = sprintf('%s://%s/api/v4/projects/%s%%2F%s/releases/%s', $repository->isSsl() ? 'https' : 'http', $repository->getHost(), $group, rawurlencode($project), rawurlencode($release));
$headers = [
'Content-Type: application/json',
'Accept: application/json',
'User-Agent: ncc'
];
if($authentication !== null)
{
$headers = self::injectAuthentication($authentication, $curl, $headers);
}
curl_setopt($curl, CURLOPT_URL, $endpoint);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $group, $project);
if(!isset($response['assets']['sources']))
{
throw new NetworkException(sprintf('No source assets found for %s/%s/%s', $group, $project, $release));
}
foreach($response['assets']['sources'] as $asset)
{
if(!isset($asset['format'], $asset['url']))
{
continue;
}
if($asset['format'] === 'zip')
{
return new RepositoryResult($asset['url'], RepositoryResultType::SOURCE, $release);
}
if($asset['format'] === 'tar')
{
return new RepositoryResult($asset['url'], RepositoryResultType::SOURCE, $release);
}
}
throw new NetworkException(sprintf('No archive found for %s/%s/%s', $group, $project, $release));
}
/**
* Injects the authentication into the curl request
*
* @param AuthenticationInterface $authentication
* @param CurlHandle $curl
* @param array $headers
* @return array
* @throws AuthenticationException
*/
private static function injectAuthentication(AuthenticationInterface $authentication, CurlHandle $curl, array $headers): array
{
switch($authentication->getAuthenticationType())
{
case AuthenticationType::ACCESS_TOKEN:
if($authentication instanceof AccessToken)
{
$headers[] = 'Private-Token: ' . $authentication->getAccessToken();
break;
}
throw new AuthenticationException(sprintf('Invalid authentication type for Access Token, got %s instead', $authentication->getAuthenticationType()));
case AuthenticationType::USERNAME_PASSWORD:
if($authentication instanceof UsernamePassword)
{
curl_setopt($curl, CURLOPT_USERPWD, $authentication->getUsername() . ':' . $authentication->getPassword());
break;
}
throw new AuthenticationException(sprintf('Invalid authentication type for Username/Password, got %s instead', $authentication->getAuthenticationType()));
}
return $headers;
}
/**
* Executes the HTTP request and processes the response
* Throws an exception if the request failed
*
* @param CurlHandle $curl
* @param string $group
* @param string $project
* @return array
* @throws AuthenticationException
* @throws NetworkException
*/
private static function processHttpResponse(CurlHandle $curl, string $group, string $project): array
{
$response = curl_exec($curl);
if($response === false)
{
throw new NetworkException(sprintf('HTTP request failed for %s/%s: %s', $group, $project, curl_error($curl)));
}
switch (curl_getinfo($curl, CURLINFO_HTTP_CODE))
{
case 200:
break;
case 401:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 401 Unauthorized, invalid/expired access token', $group, $project));
case 403:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 403 Forbidden, insufficient scope', $group, $project));
case 404:
throw new NetworkException(sprintf('Resource not found for %s/%s, server returned 404 Not Found', $group, $project));
default:
throw new NetworkException(sprintf('Server responded with HTTP code %s for %s/%s: %s', curl_getinfo($curl, CURLINFO_HTTP_CODE), $group, $project, $response));
}
try
{
return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
catch(JsonException $e)
{
throw new RuntimeException(sprintf('Failed to parse response from %s/%s: %s', $group, $project, $e->getMessage()), $e);
}
}
}

View file

@ -1,251 +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\GitlabExtension;
use ncc\Enums\Versions;
use ncc\Classes\HttpClient;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\GitException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NetworkException;
use ncc\Exceptions\NotSupportedException;
use ncc\Interfaces\RepositorySourceInterface;
use ncc\Objects\DefinedRemoteSource;
use ncc\Objects\HttpRequest;
use ncc\Objects\RemotePackageInput;
use ncc\Objects\RepositoryQueryResults;
use ncc\Objects\Vault\Entry;
use ncc\ThirdParty\jelix\Version\VersionComparator;
use ncc\Utilities\Functions;
class GitlabService implements RepositorySourceInterface
{
/**
* Attempts to return the gitRepositoryUrl of a release, cannot specify a version.
* This needs to be done using git
*
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return RepositoryQueryResults
* @throws AuthenticationException
* @throws GitException
* @throws IOException
* @throws NetworkException
*/
public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): RepositoryQueryResults
{
$httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->isSsl() ? "https" : "http");
$owner_f = str_ireplace(array("/", "."), "%2F", $packageInput->getVendor());
$project_f = str_ireplace(array("/", "."), "%2F", $packageInput->getPackage());
$httpRequest->setUrl($protocol . '://' . $definedRemoteSource->getHost() . "/api/v4/projects/$owner_f%2F$project_f");
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
$response = HttpClient::request($httpRequest, true);
if($response->getStatusCode() !== 200)
{
throw new GitException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->getStatusCode()));
}
$response_decoded = Functions::loadJson($response->getBody(), Functions::FORCE_ARRAY);
$query = new RepositoryQueryResults();
$query->getFiles()->GitSshUrl = ($response_decoded['ssh_url_to_repo'] ?? null);
$query->getFiles()->GitHttpUrl = ($response_decoded['http_url_to_repo'] ?? null);
$query->setVersion(Functions::convertToSemVer($response_decoded['default_branch']));
$query->setReleaseDescription($response_decoded['description'] ?? null);
$query->setReleaseName($response_decoded['name'] ?? null);
return $query;
}
/**
* Returns the download URL of the requested version of the package.
*
* @param RemotePackageInput $package_input
* @param DefinedRemoteSource $defined_remote_source
* @param Entry|null $entry
* @return RepositoryQueryResults
* @throws AuthenticationException
* @throws GitException
* @throws NetworkException
* @throws IOException
*/
public static function getRelease(RemotePackageInput $package_input, DefinedRemoteSource $defined_remote_source, ?Entry $entry = null): RepositoryQueryResults
{
$releases = self::getReleases($package_input->getVendor(), $package_input->getPackage(), $defined_remote_source, $entry);
if(count($releases) === 0)
{
throw new GitException(sprintf('No releases found for the repository %s/%s (selected version: %s)', $package_input->getVendor(), $package_input->getPackage(), $package_input->getVersion()));
}
// Query the latest package only
if($package_input->getVersion() === Versions::LATEST)
{
$latest_version = null;
foreach($releases as $release)
{
if($latest_version === null)
{
$latest_version = $release->Version;
continue;
}
if(VersionComparator::compareVersion($release->Version, $latest_version) === 1)
{
$latest_version = $release->Version;
}
}
return $releases[$latest_version];
}
// Query a specific version
if(!isset($releases[$package_input->getVersion()]))
{
// Find the closest thing to the requested version
$selected_version = null;
foreach($releases as $version => $url)
{
if($selected_version === null)
{
$selected_version = $version;
continue;
}
if(VersionComparator::compareVersion($version, $package_input->getVersion()) === 1)
{
$selected_version = $version;
}
}
if($selected_version === null)
{
throw new GitException(sprintf('Could not find a release for %s/%s with the version %s', $package_input->getVendor(), $package_input->getPackage(), $package_input->getVersion()));
}
}
else
{
$selected_version = $package_input->getVersion();
}
if(!isset($releases[$selected_version]))
{
throw new GitException(sprintf('Could not find a release for %s/%s with the version %s', $package_input->getVendor(), $package_input->getPackage(), $package_input->getVersion()));
}
return $releases[$selected_version];
}
/**
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return RepositoryQueryResults
* @throws NotSupportedException
*/
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
{
throw new NotSupportedException(sprintf('The given repository source "%s" does not support ncc packages.', $definedRemoteSource->getHost()));
}
/**
* Returns an array of all the tags for the given owner and repository name.
*
* @param string $owner
* @param string $repository
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return array
* @throws AuthenticationException
* @throws GitException
* @throws IOException
* @throws NetworkException
*/
private static function getReleases(string $owner, string $repository, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): array
{
$httpRequest = new HttpRequest();
$protocol = ($definedRemoteSource->isSsl() ? "https" : "http");
$owner_f = str_ireplace("/", "%2F", $owner);
$owner_f = str_ireplace(".", "%2F", $owner_f);
$repository_f = str_ireplace("/", "%2F", $repository);
$repository_f = str_ireplace(".", "%2F", $repository_f);
$httpRequest->setUrl($protocol . '://' . $definedRemoteSource->getHost() . "/api/v4/projects/$owner_f%2F$repository_f/releases");
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
$response = HttpClient::request($httpRequest, true);
if($response->getStatusCode() !== 200)
{
throw new GitException(sprintf('Failed to fetch releases for repository %s/%s. Status code: %s', $owner, $repository, $response->getStatusCode()));
}
$response_decoded = Functions::loadJson($response->getBody(), Functions::FORCE_ARRAY);
if(count($response_decoded) === 0)
{
return [];
}
$return = [];
foreach($response_decoded as $release)
{
$query_results = new RepositoryQueryResults();
$query_results->setReleaseName($release['name'] ?? null);
$query_results->setReleaseDescription($release['description'] ?? null);
$query_results->setVersion(Functions::convertToSemVer($release['tag_name']));
if(isset($release['assets']['sources']) && count($release['assets']['sources']) > 0)
{
foreach($release['assets']['sources'] as $source)
{
if($source['format'] === 'zip')
{
$query_results->getFiles()->ZipballUrl = $source['url'];
break;
}
if($source['format'] === 'tar.gz')
{
$query_results->getFiles()->ZipballUrl = $source['url'];
break;
}
if($source['format'] === 'ncc')
{
$query_results->getFiles()->PackageUrl = $source['url'];
break;
}
}
}
$return[$query_results->getVersion()] = $query_results;
}
return $return;
}
}

View file

@ -1,241 +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;
use CurlHandle;
use ncc\Enums\HttpRequestType;
use ncc\Enums\LogLevel;
use ncc\CLI\Main;
use ncc\Exceptions\NetworkException;
use ncc\Objects\HttpRequest;
use ncc\Objects\HttpResponse;
use ncc\Objects\HttpResponseCache;
use ncc\Utilities\Console;
use ncc\Utilities\RuntimeCache;
class HttpClient
{
/**
* Prepares the curl request
*
* @param HttpRequest $request
* @return CurlHandle
*/
private static function prepareCurl(HttpRequest $request): CurlHandle
{
$curl = curl_init($request->geturl());
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_MAXREDIRS, 5);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_HTTPHEADER, $request->getHeaders());
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getType());
curl_setopt($curl, CURLOPT_NOPROGRESS, false);
curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, static function($curl, $downloadSize, $downloaded)
{
if($downloadSize > 0 && ($downloaded !== $downloadSize) && Main::getLogLevel() !== null)
{
switch(Main::getLogLevel())
{
case LogLevel::VERBOSE:
case LogLevel::DEBUG:
case LogLevel::SILENT:
Console::outVerbose(sprintf(' <= %s of %s bytes downloaded', $downloaded, $downloadSize));
break;
default:
Console::inlineProgressBar($downloaded, $downloadSize + 1);
break;
}
}
});
switch($request->getType())
{
case HttpRequestType::GET:
curl_setopt($curl, CURLOPT_HTTPGET, true);
break;
case HttpRequestType::POST:
curl_setopt($curl, CURLOPT_POST, true);
if($request->getBody() !== null)
{
curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getBody());
}
break;
case HttpRequestType::PUT:
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
if($request->getBody() !== null)
{
curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getBody());
}
break;
case HttpRequestType::DELETE:
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
}
if (is_array($request->getAuthentication()))
{
curl_setopt($curl, CURLOPT_USERPWD, $request->getAuthentication()[0] . ':' . $request->getAuthentication()[1]);
}
else if (is_string($request->getAuthentication()))
{
curl_setopt($curl, CURLOPT_USERPWD, $request->getAuthentication());
}
foreach ($request->getOptions() as $option => $value)
{
curl_setopt($curl, $option, $value);
}
return $curl;
}
/**
* Creates a new HTTP request and returns the response.
*
* @param HttpRequest $httpRequest
* @param bool $cache
* @return HttpResponse
* @throws NetworkException
*/
public static function request(HttpRequest $httpRequest, bool $cache=false): HttpResponse
{
if($cache)
{
/** @var HttpResponseCache $cache */
$cache_value = RuntimeCache::get(sprintf('http_cache_%s', $httpRequest->requestHash()));
if($cache_value !== null && $cache_value->getTtl() > time())
{
Console::outDebug(sprintf('using cached response for %s', $httpRequest->requestHash()));
return $cache_value->getHttpResponse();
}
}
$curl = self::prepareCurl($httpRequest);
Console::outDebug(sprintf(' => %s request %s', $httpRequest->getType(), $httpRequest->getUrl()));
if(count($httpRequest->getHeaders()) > 0)
{
Console::outDebug(sprintf(' => headers: %s', implode(', ', $httpRequest->getHeaders())));
}
if($httpRequest->getBody() !== null)
{
Console::outDebug(sprintf(' => body: %s', $httpRequest->getBody()));
}
$response = curl_exec($curl);
if ($response === false)
{
$error = curl_error($curl);
curl_close($curl);
throw new NetworkException($error);
}
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
$body = substr($response, $headerSize);
$httpResponse = new HttpResponse();
$httpResponse->setStatusCode(curl_getinfo($curl, CURLINFO_HTTP_CODE));
$httpResponse->setHeaders(self::parseHeaders($headers));
$httpResponse->setBody($body);
Console::outDebug(sprintf(' <= %s response', $httpResponse->getStatusCode()));
Console::outDebug(sprintf(' <= headers: %s', (implode(', ', $httpResponse->getHeaders()))));
Console::outDebug(sprintf(' <= body: %s', $httpResponse->getBody()));
curl_close($curl);
if($cache)
{
$httpCacheObject = new HttpResponseCache($httpResponse, time() + 60);
RuntimeCache::set(sprintf('http_cache_%s', $httpRequest->requestHash()), $httpCacheObject);
Console::outDebug(sprintf('cached response for %s', $httpRequest->requestHash()));
}
return $httpResponse;
}
/**
* Downloads a file from the given url and saves it to the given path.
*
* @param HttpRequest $httpRequest
* @param string $path
* @return void
* @throws NetworkException
*/
public static function download(HttpRequest $httpRequest, string $path): void
{
$curl = self::prepareCurl($httpRequest);
$fp = fopen($path, 'wb');
curl_setopt($curl, CURLOPT_FILE, $fp);
curl_setopt($curl, CURLOPT_HEADER, 0);
$response = curl_exec($curl);
if ($response === false)
{
$error = curl_error($curl);
curl_close($curl);
throw new NetworkException($error);
}
curl_close($curl);
fclose($fp);
}
/**
* Takes the return headers of a cURL request and parses them into an array.
*
* @param string $input
* @return array
*/
private static function parseHeaders(string $input): array
{
$headers = array();
$lines = explode("\n", $input);
$headers['HTTP'] = array_shift($lines);
foreach ($lines as $line)
{
$header = explode(':', $line, 2);
if (count($header) === 2)
{
$headers[trim($header[0])] = trim($header[1]);
}
}
return $headers;
}
}

View file

@ -23,17 +23,11 @@
namespace ncc\Classes\LuaExtension;
use Exception;
use InvalidArgumentException;
use ncc\Classes\ExecutionUnitRunner;
use ncc\Enums\Runners;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;
@ -52,13 +46,21 @@
try
{
$process = ExecutionUnitRunner::constructProcess($unit, array_merge([$tmp], $args));
$process->run(static function($type, $buffer) use ($unit)
if($unit->getExecutionPolicy()->getExecute()->isTty())
{
if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
$process->run();
}
else
{
$process->run(static function($type, $buffer) use ($unit)
{
print($buffer);
}
});
if(!$unit->getExecutionPolicy()->getExecute()->isSilent())
{
print($buffer);
}
});
}
}
catch(Exception $e)
{

View file

@ -27,7 +27,6 @@
use ncc\Enums\SpecialConstants\InstallConstants;
use ncc\Enums\SpecialConstants\AssemblyConstants;
use ncc\Enums\SpecialConstants\RuntimeConstants;
use ncc\Managers\ProjectManager;
use ncc\Objects\InstallationPaths;
use ncc\Objects\ProjectConfiguration;
use ncc\Objects\ProjectConfiguration\Assembly;

View file

@ -27,11 +27,11 @@
use ncc\Classes\PackageWriter;
use ncc\CLI\Main;
use ncc\Enums\ComponentDataType;
use ncc\Enums\Flags\PackageFlags;
use ncc\Enums\LogLevel;
use ncc\Enums\Options\BuildConfigurationOptions;
use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Enums\Types\ComponentDataType;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
@ -162,6 +162,18 @@
$this->processResource($package_writer, $resource);
}
// Add the project dependencies
foreach($this->project_manager->getProjectConfiguration()->getBuild()->getDependencies() as $dependency)
{
$package_writer->addDependencyConfiguration($dependency);
}
// Add the build dependencies
foreach($configuration->getDependencies() as $dependency)
{
$package_writer->addDependencyConfiguration($dependency);
}
$package_writer->close();
return $package_path;
}
@ -216,7 +228,7 @@
public function processComponent(PackageWriter $package_writer, string $file_path): void
{
$package_writer->addComponent(new Package\Component(
Functions::removeBasename($file_path),
Functions::removeBasename($file_path, $this->project_manager->getProjectPath()),
Base64::encode(IO::fread($file_path)), ComponentDataType::BASE64_ENCODED
));
}
@ -234,7 +246,7 @@
public function processResource(PackageWriter $package_writer, string $file_path): void
{
$package_writer->addResource(new Package\Resource(
Functions::removeBasename($file_path), IO::fread($file_path)
Functions::removeBasename($file_path, $this->project_manager->getProjectPath()), IO::fread($file_path)
));
}

View file

@ -1,62 +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\NccExtension;
use ncc\Enums\Scopes;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Managers\ExecutionPointerManager;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Utilities\Resolver;
class Runner
{
/**
* Temporarily executes an execution unit, removes it once it is executed
*
* @param string $package
* @param string $version
* @param ExecutionUnit $unit
* @return void
* @throws AuthenticationException
* @throws IOException
* @throws OperationException
* @throws PathNotFoundException
* @throws NotSupportedException
*/
public static function temporaryExecute(string $package, string $version, ExecutionUnit $unit): void
{
if(Resolver::resolveScope() !== Scopes::SYSTEM)
{
throw new AuthenticationException('Cannot temporarily execute a unit with insufficient permissions');
}
$ExecutionPointerManager = new ExecutionPointerManager();
$ExecutionPointerManager->addUnit($package, $version, $unit, true);
$ExecutionPointerManager->executeUnit($package, $version, $unit->getExecutionPolicy()->getName());
$ExecutionPointerManager->cleanTemporaryUnits();
}
}

View file

@ -25,6 +25,7 @@
namespace ncc\Classes;
use Exception;
use ncc\Enums\Flags\PackageFlags;
use ncc\Enums\PackageDirectory;
use ncc\Exceptions\ConfigurationException;
@ -43,15 +44,40 @@
class PackageReader
{
/**
* @var array
* @var int
*/
private $headers;
private $package_offset;
/**
* @var int
*/
private $package_length;
/**
* @var int
*/
private $header_offset;
/**
* @var int
*/
private $header_length;
/**
* @var int
*/
private $data_offset;
/**
* @var int
*/
private $data_length;
/**
* @var array
*/
private $headers;
/**
* @var resource
*/
@ -81,51 +107,91 @@
throw new IOException(sprintf('Failed to open file \'%s\'', $file_path));
}
$pre_header = '';
$diameter_hit = false;
// Package begin: ncc_pkg
// Start of header: after ncc_pkg
// End of header: \x1F\x1F
// Start of data: after \x1F\x1F
// End of data: \xFF\xAA\x55\xF0
// Dynamically calculate header length until "ncc_pkg" is found
while (!feof($this->package_file))
// First find the offset of the package by searching for the magic bytes "ncc_pkg"
$this->package_offset = 0;
while(!feof($this->package_file))
{
$char = fread($this->package_file, 1);
$pre_header .= $char;
$buffer = fread($this->package_file, 1024);
$buffer_length = strlen($buffer);
$this->package_offset += $buffer_length;
if (str_ends_with($pre_header, 'ncc_pkg'))
if (($position = strpos($buffer, "ncc_pkg")) !== false)
{
$this->package_offset -= $buffer_length - $position;
$this->package_length = 7; // ncc_pkg
$this->header_offset = $this->package_offset + 7;
break;
}
}
// Calculate header length including "ncc_pkg"
$this->header_length = strlen($pre_header);
// Read everything after "ncc_pkg" up until the delimiter (0x1F 0x1F)
$header = '';
while(!feof($this->package_file))
// Check for sanity reasons
if($this->package_offset === null || $this->package_length === null)
{
$this->header_length++;
$header .= fread($this->package_file, 1);
throw new IOException(sprintf('File \'%s\' is not a valid package file (missing magic bytes)', $file_path));
}
if(str_ends_with($header, "\x1F\x1F"))
// Seek the header until the end of headers byte sequence (1F 1F 1F 1F)
fseek($this->package_file, $this->header_offset);
while (!feof($this->package_file))
{
$this->headers .= fread($this->package_file, 1024);
// Search for the position of "1F 1F 1F 1F" within the buffer
if (($position = strpos($this->headers, "\x1F\x1F\x1F\x1F")) !== false)
{
$diameter_hit = true;
$header = substr($header, 0, -2);
$this->headers = substr($this->headers, 0, $position);
$this->header_length = strlen($this->headers);
$this->package_length += $this->header_length + 4;
$this->data_offset = $this->header_offset + $this->header_length + 4;
break;
}
// Stop at 100MB
if($this->header_length >= 100000000)
if (strlen($this->headers) >= 100000000)
{
throw new IOException(sprintf('File \'%s\' is not a valid package file (header is too large)', $file_path));
}
}
if(!$diameter_hit)
try
{
$this->headers = ZiProto::decode($this->headers);
}
catch(Exception $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]))
{
throw new IOException(sprintf('File \'%s\' is not a valid package file (invalid header)', $file_path));
}
$this->headers = ZiProto::decode($header);
// Seek the data until the end of the package (FF AA 55 F0)
fseek($this->package_file, $this->data_offset);
while(!feof($this->package_file))
{
$buffer = fread($this->package_file, 1024);
$this->data_length += strlen($buffer);
if (($position = strpos($buffer, "\xFF\xAA\x55\xF0")) !== false)
{
$this->data_length -= strlen($buffer) - $position;
$this->package_length += $this->data_length + 4;
break;
}
}
if($this->data_length === null)
{
throw new IOException(sprintf('File \'%s\' is not a valid package file (missing end of package)', $file_path));
}
$this->cache = [];
}
@ -194,7 +260,7 @@
}
$location = explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
fseek($this->package_file, ($this->header_length + (int)$location[0]));
fseek($this->package_file, ($this->data_offset + (int)$location[0]));
if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
{
@ -533,6 +599,76 @@
return Resource::fromArray(ZiProto::decode($this->getByPointer($pointer, $length)));
}
/**
* Returns the offset of the package
*
* @return int
*/
public function getPackageOffset(): int
{
return $this->package_offset;
}
/**
* @return int
*/
public function getPackageLength(): int
{
return $this->package_length;
}
/**
* @return int
*/
public function getHeaderOffset(): int
{
return $this->header_offset;
}
/**
* @return false|int
*/
public function getHeaderLength(): false|int
{
return $this->header_length;
}
/**
* @return int
*/
public function getDataOffset(): int
{
return $this->data_offset;
}
/**
* @return int
*/
public function getDataLength(): int
{
return $this->data_length;
}
/**
* @param string $path
* @return void
* @throws IOException
*/
public function saveCopy(string $path): void
{
$destination = fopen($path, 'wb');
if($destination === false)
{
throw new IOException(sprintf('Failed to open file \'%s\'', $path));
}
// Copy the package file to the destination
stream_copy_to_stream($this->package_file, $destination, $this->package_length, $this->package_offset);
// Done!
fclose($destination);
}
/**
* PackageReader destructor.
*/

View file

@ -69,7 +69,6 @@
/**
* PackageWriter constructor.
*
* @param string $file_path
* @throws IOException
*/
public function __construct(string $file_path, bool $overwrite=true)
@ -153,6 +152,7 @@
*
* @param array $flags
* @return void
* @throws IOException
*/
public function setFlags(array $flags): void
{
@ -189,6 +189,7 @@
*
* @param string $flag
* @return void
* @throws IOException
*/
public function removeFlag(string $flag): void
{
@ -206,13 +207,12 @@
* @param string $name
* @param string $data
* @return array
* @throws IOException
*/
public function add(string $name, string $data): array
{
if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
{
throw new IOException(sprintf('Resource \'%s\' already exists in package', $name));
return explode(':', $this->headers[PackageStructure::DIRECTORY][$name]);
}
if(in_array(PackageFlags::COMPRESSION, $this->headers[PackageStructure::FLAGS], true))
@ -250,13 +250,12 @@
* @param int $offset
* @param int $length
* @return void
* @throws IOException
*/
public function addPointer(string $name, int $offset, int $length): void
{
if(isset($this->headers[PackageStructure::DIRECTORY][$name]))
{
throw new IOException(sprintf('Resource \'%s\' already exists in package', $name));
return;
}
$this->headers[PackageStructure::DIRECTORY][$name] = sprintf("%d:%d", $offset, $length);
@ -267,7 +266,6 @@
*
* @param Assembly $assembly
* @return array
* @throws IOException
*/
public function setAssembly(Assembly $assembly): array
{
@ -279,7 +277,6 @@
*
* @param Metadata $metadata
* @return array
* @throws IOException
*/
public function setMetadata(Metadata $metadata): array
{
@ -291,7 +288,6 @@
*
* @param Installer $installer
* @return array
* @throws IOException
*/
public function setInstaller(Installer $installer): array
{
@ -303,7 +299,6 @@
*
* @param Dependency $dependency
* @return array
* @throws IOException
*/
public function addDependencyConfiguration(Dependency $dependency): array
{
@ -315,7 +310,6 @@
*
* @param ExecutionUnit $unit
* @return array
* @throws IOException
*/
public function addExecutionUnit(ExecutionUnit $unit): array
{
@ -327,7 +321,6 @@
*
* @param Component $component
* @return array
* @throws IOException
*/
public function addComponent(Component $component): array
{
@ -339,11 +332,10 @@
*
* @param Resource $resource
* @return array
* @throws IOException
*/
public function addResource(Resource $resource): array
{
return $this->add(sprintf('@%s:%s', PackageDirectory::RESOURCES, $resource->getName()), $resource->getData());
return $this->add(sprintf('@%s:%s', PackageDirectory::RESOURCES, $resource->getName()), ZiProto::encode($resource->toArray(true)));
}
/**
@ -353,7 +345,6 @@
* @param int $offset
* @param int $length
* @return void
* @throws IOException
*/
public function mapClass(string $class, int $offset, int $length): void
{
@ -379,12 +370,15 @@
// Write the magic bytes "ncc_pkg" to the package and the header
fwrite($this->package_file, 'ncc_pkg');
fwrite($this->package_file, ZiProto::encode($this->headers));
fwrite($this->package_file, chr(0x1F) . chr(0x1F));
fwrite($this->package_file, "\x1F\x1F\x1F\x1F");
// Copy the temporary data file to the package
$temp_file = fopen($this->temporary_path, 'rb');
stream_copy_to_stream($temp_file, $this->package_file);
// End the package by writing the end-of-package delimiter (0xFFAA55F0)
fwrite($this->package_file, "\xFF\xAA\x55\xF0");
// Close the file handles
fclose($this->package_file);
fclose($temp_file);

View file

@ -0,0 +1,240 @@
<?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\PackagistExtension;
use CurlHandle;
use InvalidArgumentException;
use JsonException;
use ncc\Enums\Types\AuthenticationType;
use ncc\Enums\Types\HttpRequestType;
use ncc\Enums\Types\RepositoryResultType;
use ncc\Enums\Versions;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\NetworkException;
use ncc\Exceptions\NotSupportedException;
use ncc\Interfaces\RepositoryInterface;
use ncc\Objects\RepositoryConfiguration;
use ncc\Objects\RepositoryResult;
use ncc\ThirdParty\composer\Semver\Comparator;
use ncc\ThirdParty\composer\Semver\Semver;
use ncc\Utilities\Console;
use RuntimeException;
class PackagistRepository implements RepositoryInterface
{
/**
* @inheritDoc
*/
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult
{
if($version === Versions::LATEST)
{
$version = self::getLatestVersion($repository, $vendor, $project);
}
$version = self::resolveVersion($repository, $vendor, $project, $version);
$endpoint = sprintf('%s://%s/packages/%s/%s.json', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($vendor), rawurlencode($project));
Console::outDebug(sprintf('Fetching archive %s/%s version %s from %s', $vendor, $project, $version, $endpoint));
$curl = curl_init($endpoint);
$headers = [
'Accept: application/json',
'User-Agent: ncc'
];
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $vendor, $project);
if(!isset($response['package']['versions'][$version]))
{
throw new NetworkException(sprintf('Invalid response from %s/%s, version %s does not exist', $vendor, $project, $version));
}
if(!isset($response['package']['versions'][$version]['dist']['url']))
{
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, $version);
}
/**
* @inheritDoc
* @throws NotSupportedException
*/
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version = Versions::LATEST, ?AuthenticationType $authentication = null): RepositoryResult
{
throw new NotSupportedException('Fetching ncc packages from Packagist is not supported');
}
/**
* Returns an array of all versions for the specified vendor and project
*
* @param RepositoryConfiguration $repository
* @param string $vendor
* @param string $project
* @return array
* @throws AuthenticationException
* @throws NetworkException
*/
private static function getVersions(RepositoryConfiguration $repository, string $vendor, string $project): array
{
$endpoint = sprintf('%s://%s/packages/%s/%s.json', ($repository->isSsl() ? 'https' : 'http'), $repository->getHost(), rawurlencode($vendor), rawurlencode($project));
$curl = curl_init($endpoint);
$headers = [
'Accept: application/json',
'User-Agent: ncc'
];
Console::outDebug(sprintf('Fetching %s/%s versions from %s', $vendor, $project, $endpoint));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, HttpRequestType::GET);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$response = self::processHttpResponse($curl, $vendor, $project);
if(!isset($response['package']['versions']))
{
throw new NetworkException(sprintf('Invalid response from %s/%s, missing "package.versions" key', $vendor, $project));
}
return array_keys($response['package']['versions']);
}
/**
* Resolves the latest version for the specified vendor and project
*
* @param RepositoryConfiguration $repository
* @param string $vendor
* @param string $project
* @return string
* @throws AuthenticationException
* @throws NetworkException
*/
public static function getLatestVersion(RepositoryConfiguration $repository, string $vendor, string $project): string
{
$versions = self::getVersions($repository, $vendor, $project);
/** @noinspection KeysFragmentationWithArrayFunctionsInspection */
$versions = array_filter($versions, static function($version)
{
return !preg_match('/-alpha|-beta|-rc|dev/i', $version);
});
usort($versions, static function($a, $b)
{
return Comparator::lessThanOrEqualTo($a, $b) ? 1 : -1;
});
return $versions[0];
}
/**
* Resolves the requested version from a constraint for the specified vendor and project
*
* @param RepositoryConfiguration $repository
* @param string $vendor
* @param string $project
* @param string $version
* @return string
* @throws AuthenticationException
* @throws NetworkException
*/
public static function resolveVersion(RepositoryConfiguration $repository, string $vendor, string $project, string $version): string
{
$versions = self::getVersions($repository, $vendor, $project);
usort($versions, static function($a, $b)
{
return Comparator::lessThanOrEqualTo($a, $b) ? 1 : -1;
});
foreach($versions as $working_version)
{
// Avoid using dev versions if the requested version is not a dev version
if(false === stripos($version, "-dev") && false !== stripos($working_version, "-dev"))
{
continue;
}
if(Semver::satisfies($working_version, $version))
{
return $working_version;
}
}
throw new InvalidArgumentException(sprintf('Version %s for %s/%s does not exist', $version, $vendor, $project));
}
/**
* Processes the HTTP response from the server and returns the decoded JSON response
*
* @param CurlHandle $curl
* @param string $vendor
* @param string $project
* @return array
* @throws AuthenticationException
* @throws NetworkException
*/
private static function processHttpResponse(CurlHandle $curl, string $vendor, string $project): array
{
$response = curl_exec($curl);
if($response === false)
{
throw new NetworkException(sprintf('HTTP request failed for %s/%s: %s', $vendor, $project, curl_error($curl)));
}
switch (curl_getinfo($curl, CURLINFO_HTTP_CODE))
{
case 200:
break;
case 401:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 401 Unauthorized, invalid/expired access token', $vendor, $project));
case 403:
throw new AuthenticationException(sprintf('Authentication failed for %s/%s, 403 Forbidden, insufficient scope', $vendor, $project));
case 404:
throw new NetworkException(sprintf('Resource not found for %s/%s, server returned 404 Not Found', $vendor, $project));
default:
throw new NetworkException(sprintf('Server responded with HTTP code %s for %s/%s: %s', curl_getinfo($curl, CURLINFO_HTTP_CODE), $vendor, $project, $response));
}
try
{
return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
catch(JsonException $e)
{
throw new RuntimeException(sprintf('Failed to parse response from %s/%s: %s', $vendor, $project, $e->getMessage()), $e);
}
}
}

View file

@ -25,13 +25,9 @@
use Exception;
use ncc\Classes\ExecutionUnitRunner;
use ncc\Exceptions\IOException;
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\OperationException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;

View file

@ -24,6 +24,7 @@
use ncc\CLI\Main;
use ncc\Enums\LogLevel;
use ncc\Enums\Options\BuildConfigurationOptions;
use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Exceptions\BuildException;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
@ -42,14 +43,14 @@
{
$configuration = $this->getProjectManager()->getProjectConfiguration()->getBuild()->getBuildConfiguration($build_configuration);
if(!isset($configuration->getOptions()['ncc_configuration']))
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));
}
// Build the ncc package first
Console::outVerbose('Building ncc package.');
$ncc_package = parent::build($configuration->getOptions()['ncc_configuration']);
$ncc_package = parent::build($configuration->getOptions()[BuildConfigurationOptions::NCC_CONFIGURATION]);
// Prepare the ncc package for compilation
$hex_dump_file = PathFinder::getCachePath() . DIRECTORY_SEPARATOR . parent::getProjectManager()->getProjectConfiguration()->getAssembly()->getName() . '.c';
@ -134,19 +135,23 @@
*/
private function hexDump(string $input_path, string $output_path, string $variable_name): void
{
Console::out(sprintf('Processing %s to hex dump', $input_path));
$input = fopen($input_path, 'rb');
$output = fopen($output_path, 'wb');
fwrite($output, sprintf("unsigned char %s[] = {\n", Functions::toSnakeCase($variable_name)));
$byte_count = 0;
$total_bytes = filesize($input_path);
fwrite($output, sprintf("unsigned char %s[] = {\n", Functions::toSnakeCase($variable_name)));
// Convert the binary data to hex and write it to the output file
while (!feof($input))
{
Console::inlineProgressBar(ftell($input), $total_bytes);
$byte = fread($input, 1);
if (strlen($byte) === 1)
{
fwrite($output, sprintf(" 0x%02x,", ord($byte)));
fwrite($output, sprintf(" 0x%02x,", ord($byte)));
$byte_count++;
}

View file

@ -24,17 +24,17 @@
use Exception;
use ncc\Classes\PackageWriter;
use ncc\Enums\ComponentDataType;
use ncc\Enums\Flags\ComponentFlags;
use ncc\Enums\Types\ComponentDataType;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Extensions\ZiProto\ZiProto;
use ncc\Objects\Package\Component;
use ncc\ThirdParty\nikic\PhpParser\ParserFactory;
use ncc\Utilities\Base64;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\IO;
use ncc\Extensions\ZiProto\ZiProto;
class NccCompiler extends \ncc\Classes\NccExtension\NccCompiler
{
@ -48,7 +48,7 @@
*/
public function processComponent(PackageWriter $package_writer, string $file_path): void
{
$component_name = Functions::removeBasename($file_path);
$component_name = Functions::removeBasename($file_path, $this->getProjectManager()->getProjectPath());
try
{

View file

@ -31,7 +31,6 @@
use ncc\Exceptions\OperationException;
use ncc\Interfaces\RunnerInterface;
use ncc\Objects\Package\ExecutionUnit;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
use ncc\Utilities\IO;
use ncc\Utilities\PathFinder;

View file

@ -1,24 +1,24 @@
<?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.
*
*/
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
/** @noinspection PhpMissingFieldTypeInspection */
@ -27,7 +27,6 @@
use Exception;
use InvalidArgumentException;
use ncc\Enums\FileDescriptor;
use ncc\Enums\Runners;
use ncc\Enums\Versions;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\ImportException;

View file

@ -0,0 +1,110 @@
<?php
/** @noinspection PhpMissingFieldTypeInspection */
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes;
use Exception;
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\RuntimeCache;
class ShutdownHandler
{
/**
* @var bool
*/
private static $registered = false;
/**
* @var array
*/
private static $cleanup_paths = [];
/**
* Registers the shutdown handler
*
* @return void
*/
public static function register(): void
{
if(self::$registered)
{
return;
}
self::$registered = true;
register_shutdown_function([self::class, 'handle']);
}
/**
* The shutdown handler for ncc
*
* @return void
*/
public static function shutdown(): void
{
if(count(self::$cleanup_paths) > 0)
{
$filesystem = new Filesystem();
foreach(self::$cleanup_paths as $path)
{
try
{
//$filesystem->remove($path);
}
catch(Exception $e)
{
// ignore
}
}
}
try
{
RuntimeCache::clearCache();
Functions::finalizePermissions();
}
catch (Exception $e)
{
Console::outWarning('An error occurred while shutting down ncc, ' . $e->getMessage());
}
}
/**
* Declares a path to be cleaned up on shutdown
*
* @param string $path
* @return void
*/
public static function declareTemporaryPath(string $path): void
{
if(!in_array($path, self::$cleanup_paths, true))
{
self::$cleanup_paths[] = $path;
}
}
}

View file

@ -1,36 +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\Enums;
final class AuthenticationType
{
/**
* A combination of a username and password is used for authentication
*/
public const USERNAME_PASSWORD = 1;
/**
* A single private access token is used for authentication
*/
public const ACCESS_TOKEN = 2;
}

View file

@ -1,37 +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\Enums;
final class BuiltinRemoteSourceType
{
/**
* The remote source indicates the package is to be
* fetched using the composer utility.
*/
public const COMPOSER = 'composer';
public const ALL = [
self::COMPOSER
];
}

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class CompilerExtensionSupportedVersions
{

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,46 +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\Enums;
final class ComponentDataType
{
/**
* Indicates whether the component is represented as an AST representation
*/
public const AST = 'ast';
/**
* Indicates whether the component is represented as plaintext
*/
public const PLAIN = 'plain';
/**
* Indicates whether the component is represented as binary or executable
*/
public const BINARY = 'binary';
/**
* Indicates whether the component is represented as as a base64 encoded string (Raw bytes' representation)
*/
public const BASE64_ENCODED = 'b64enc';
}

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,55 +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\Enums;
final class ComposerPackageTypes
{
/**
* This is the default. It will copy the files to `vendor`
*/
public const LIBRARY = 'library';
/**
* This denotes a project rather than a library. For example
* application shells like the Symfony standard edition, CMSs
* like the SilverStripe installer or full-fledged applications
* distributed as packages. This can for example be used by IDEs
* to provide listings of projects to initialize when creating
* a new workspace.
*/
public const PROJECT = 'project';
/**
* An empty package that contains requirements and will trigger
* their installation, but contains no files and will not write
* anything to the filesystem. As such, it does not require a
* a dist or source key to be installable
*/
public const METAPACKAGE = 'metapackage';
/**
* A package of type `composer-plugin` may provide an installer
* for other packages that have a custom type.
*/
public const COMPOSER_PLUGIN = 'composer-plugin';
}

View file

@ -1,36 +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\Enums;
final class ComposerStabilityTypes
{
public const DEV = 'dev';
public const ALPHA = 'alpha';
public const BETA = 'beta';
public const RC = 'rc';
public const STABLE ='stable';
}

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class ConstantReferences
{

View file

@ -1,53 +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\Enums;
final class DefinedRemoteSourceType
{
/**
* THe remote source is from gitlab or a custom gitlab instance
*
* Will use an API wrapper to interact with the gitlab instance
* to fetch the package and check for updates without having to
* pull the entire repository
*
* Will still use git to fetch the package from the gitlab instance
*/
public const GITLAB = 'gitlab';
/**
* The remote source is from GitHub
*
* Will use an API wrapper to interact with the GitHub instance
* to fetch the package and check for updates without having to
* pull the entire repository
*
* Will still use git to fetch the package from the GitHub instance
*/
public const GITHUB = 'github';
public const ALL = [
self::GITLAB,
self::GITHUB
];
}

View file

@ -1,49 +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\Enums;
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

@ -1,28 +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\Enums;
final class EncoderType
{
public const ZI_PROTO = '3';
}

View file

@ -31,4 +31,8 @@
public const INSTALLER = 'INSTALLER';
public const CLASS_MAP = 'CLASS_MAP';
public const UPDATE = 'UPDATE';
public const SHADOW_PACKAGE = 'SHADOW_PKG';
}

View file

@ -0,0 +1,32 @@
<?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\Flags;
final class NccBuildFlags
{
/**
* Indicates if the build is currently unstable and some features may not work correctly
* and can cause errors
*/
public const UNSTABLE = 'unstable';
}

View file

@ -1,31 +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\Enums;
final class HttpRequestType
{
public const GET = 'GET';
public const POST = 'POST';
public const PUT = 'PUT';
public const DELETE = 'DELETE';
}

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class HttpStatusCodes
{

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class LogLevel
{

View file

@ -1,32 +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\Enums;
final class NccBuildFlags
{
/**
* Indicates if the build is currently unstable and some features may not work correctly
* and can cause errors
*/
public const UNSTABLE = 'unstable';
}

View file

@ -25,4 +25,8 @@
final class BuildConfigurationOptions
{
public const COMPRESSION = 'compression';
public const REQUIRE_FILES = 'require_files';
public const NCC_CONFIGURATION = 'ncc_configuration';
}

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;
@ -33,4 +33,14 @@
* A boolean option that indicates whether to overwrite the project file if it already exists
*/
public const OVERWRITE_PROJECT_FILE = 'OVERWRITE_PROJECT_FILE';
/**
* Composer Only, used to define the package's real version
*/
public const COMPOSER_PACKAGE_VERSION = 'COMPOSER_PACKAGE_VERSION';
/**
* Composer Only, used to define the package's update source
*/
public const COMPOSER_REMOTE_SOURCE = 'COMPOSER_REMOTE_SOURCE';
}

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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;

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class PackageStandardVersions
{

View file

@ -1,32 +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\Enums;
final class ProjectType
{
public const COMPOSER = 'composer';
public const NCC = 'ncc';
public const UNKNOWN = 'unknown';
}

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
/**
* @author Zi Xing Narrakas
@ -40,8 +40,6 @@ namespace ncc\Enums;
public const UNIX_PATH = '/^(((?:\.\/|\.\.\/|\/)?(?:\.?\w+\/)*)(\.?\w+\.?\w+))$/m';
public const WINDOWS_PATH = '/^(([%][^\/:*?<>""|]*[%])|([a-zA-Z][:])|(\\\\))((\\\\{1})|((\\\\{1})[^\\\\]([^\/:*?<>""|]*))+)$/m';
public const CONSTANT_NAME = '/^([^\x00-\x7F]|[\w_\ \.\+\-]){2,64}$/';
public const EXECUTION_POLICY_NAME = '/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/m';

View file

@ -1,56 +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\Enums;
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

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class Runners
{

View file

@ -1,31 +1,29 @@
<?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.
*
*/
/*
* 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;
namespace ncc\Enums;
final class Scopes
{
public const AUTO = 'AUTO';
public const USER = 'USER';
public const SYSTEM = 'SYSTEM';

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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\SpecialConstants;

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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\SpecialConstants;

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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\SpecialConstants;

View file

@ -1,26 +1,26 @@
<?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.
*
*/
/*
* 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\SpecialConstants;
namespace ncc\Enums\SpecialConstants;
final class InstallConstants
{

View file

@ -1,24 +1,24 @@
<?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.
*
*/
/*
* 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\SpecialConstants;

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\Types;
final class AuthenticationType
{
/**
* A combination of a username and password is used for authentication
*/
public const USERNAME_PASSWORD = 1;
/**
* A single private access token is used for authentication
*/
public const ACCESS_TOKEN = 2;
}

View file

@ -20,7 +20,7 @@
*
*/
namespace ncc\Enums;
namespace ncc\Enums\Types;
final class BuildOutputType
{

View file

@ -20,13 +20,18 @@
*
*/
$BuildDirectory = __DIR__ . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'build';
$AutoloadPath = $BuildDirectory . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'autoload.php';
namespace ncc\Enums\Types;
if(!file_exists($BuildDirectory) || !is_dir($BuildDirectory))
throw new RuntimeExcepion('Build directory does not exist, to run tests you must build the project.');
final class BuiltinRemoteSourceType
{
/**
* The remote source indicates the package is to be
* fetched using the composer utility.
*/
public const COMPOSER = 'composer';
if(!file($AutoloadPath) || !is_file($AutoloadPath))
throw new RuntimeException('Autoload file does not exist in \'' . $BuildDirectory .'\', to run tests you must build the project.');
require($AutoloadPath);
public const ALL = [
self::COMPOSER
];
}

View file

@ -0,0 +1,46 @@
<?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 ComponentDataType
{
/**
* Indicates whether the component is represented as an AST representation
*/
public const AST = 'ast';
/**
* Indicates whether the component is represented as plaintext
*/
public const PLAIN = 'plain';
/**
* Indicates whether the component is represented as binary or executable
*/
public const BINARY = 'binary';
/**
* Indicates whether the component is represented as as a base64 encoded string (Raw bytes' representation)
*/
public const BASE64_ENCODED = 'b64enc';
}

View file

@ -0,0 +1,55 @@
<?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 ComposerPackageTypes
{
/**
* This is the default. It will copy the files to `vendor`
*/
public const LIBRARY = 'library';
/**
* This denotes a project rather than a library. For example
* application shells like the Symfony standard edition, CMSs
* like the SilverStripe installer or full-fledged applications
* distributed as packages. This can for example be used by IDEs
* to provide listings of projects to initialize when creating
* a new workspace.
*/
public const PROJECT = 'project';
/**
* An empty package that contains requirements and will trigger
* their installation, but contains no files and will not write
* anything to the filesystem. As such, it does not require a
* a dist or source key to be installable
*/
public const METAPACKAGE = 'metapackage';
/**
* A package of type `composer-plugin` may provide an installer
* for other packages that have a custom type.
*/
public const COMPOSER_PLUGIN = 'composer-plugin';
}

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\Types;
final class ComposerStabilityTypes
{
public const DEV = 'dev';
public const ALPHA = 'alpha';
public const BETA = 'beta';
public const RC = 'rc';
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

@ -0,0 +1,31 @@
<?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 HttpRequestType
{
public const GET = 'GET';
public const POST = 'POST';
public const PUT = 'PUT';
public const DELETE = 'DELETE';
}

View file

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

@ -0,0 +1,30 @@
<?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 RepositoryResultType
{
public const SOURCE = 'source';
public const PACKAGE = 'package';
}

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