- 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

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

@ -0,0 +1,37 @@
<?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 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

@ -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';
}

View file

@ -0,0 +1,41 @@
<?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 RepositoryType
{
public const GITLAB = 'gitlab';
public const GITHUB = 'github';
public const GITEA = 'gitea';
public const PACKAGIST = 'packagist';
public const ALL = [
self::GITLAB,
self::GITHUB,
self::GITEA,
self::PACKAGIST
];
}

View file

@ -1,4 +1,5 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
@ -24,7 +25,6 @@
use Exception;
use InvalidArgumentException;
use JsonSerializable;
/**
* ZiProto Class

View file

@ -22,7 +22,7 @@
namespace ncc\Interfaces;
interface PasswordInterface extends BytecodeObjectInterface
interface AuthenticationInterface extends BytecodeObjectInterface
{
/**
* @return string

View file

@ -23,12 +23,7 @@
namespace ncc\Interfaces;
use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Exceptions\BuildException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Managers\ProjectManager;
use ncc\Objects\Package;
use ncc\Objects\ProjectConfiguration;
interface CompilerInterface
{

View file

@ -0,0 +1,63 @@
<?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\Interfaces;
use ncc\Enums\Types\AuthenticationType;
use ncc\Enums\Versions;
use ncc\Exceptions\AuthenticationException;
use ncc\Exceptions\NetworkException;
use ncc\Objects\RepositoryConfiguration;
use ncc\Objects\RepositoryResult;
interface RepositoryInterface
{
/**
* Returns the archive URL for the source code of the specified group and project.
* This is useful for building the project from source.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $vendor The vendor to get the source for (eg; "Nosial")
* @param string $project The project to get the source for (eg; "ncc" or "libs/config")
* @param string $version Optional. The version to get the source for. By default, it will get the latest version
* @param AuthenticationType|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The result of the request
* @throws AuthenticationException If the authentication is invalid
* @throws NetworkException If there was an error getting the source
*/
public static function fetchSourceArchive(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult;
/**
* Returns the archive URL for the ncc package of the specified group and project.
* This is useful for downloading the package.
*
* @param RepositoryConfiguration $repository The remote repository to make the request to
* @param string $vendor The vendor to get the package for (eg; "Nosial")
* @param string $project The project to get the package for (eg; "ncc" or "libs/config")
* @param string $version Optional. The version to get the package for. By default, it will get the latest version
* @param AuthenticationType|null $authentication Optional. The authentication to use. If null, No authentication will be used.
* @return RepositoryResult The result of the request
* @throws AuthenticationException If the authentication is invalid
* @throws NetworkException If there was an error getting the package
*/
public static function fetchPackage(RepositoryConfiguration $repository, string $vendor, string $project, string $version=Versions::LATEST, ?AuthenticationType $authentication=null): RepositoryResult;
}

View file

@ -1,61 +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\Interfaces;
use ncc\Objects\DefinedRemoteSource;
use ncc\Objects\RemotePackageInput;
use ncc\Objects\RepositoryQueryResults;
use ncc\Objects\Vault\Entry;
interface 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
*/
public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): RepositoryQueryResults;
/**
* Returns the release url of the repository, versions can be specified.
*
* @param RemotePackageInput $package_input
* @param DefinedRemoteSource $defined_remote_source
* @param Entry|null $entry
* @return RepositoryQueryResults
*/
public static function getRelease(RemotePackageInput $package_input, DefinedRemoteSource $defined_remote_source, ?Entry $entry = null): RepositoryQueryResults;
/**
* Returns the download URL of the pre-compiled .ncc package if available
*
* @param RemotePackageInput $packageInput
* @param DefinedRemoteSource $definedRemoteSource
* @param Entry|null $entry
* @return RepositoryQueryResults
*/
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults;
}

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