Merge branch 'composerutils' into 'master'
Implemented Composer See merge request nosial/ncc!3
This commit is contained in:
commit
9fb26e9aa0
63 changed files with 6341 additions and 393 deletions
1
Makefile
1
Makefile
|
@ -89,6 +89,7 @@ redist: autoload
|
|||
cp $(SRC_PATH)/installer/installer $(BUILD_PATH)/$(SRC_PATH)/INSTALL
|
||||
cp $(SRC_PATH)/installer/ncc.sh $(BUILD_PATH)/$(SRC_PATH)/ncc.sh
|
||||
cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/$(SRC_PATH)/default_config.yaml;
|
||||
cp $(SRC_PATH)/config/ncc.yaml $(BUILD_PATH)/$(SRC_PATH)/CLI/template_config.yaml;
|
||||
cp $(SRC_PATH)/installer/extension $(BUILD_PATH)/$(SRC_PATH)/extension
|
||||
chmod +x $(BUILD_PATH)/$(SRC_PATH)/INSTALL
|
||||
cp LICENSE $(BUILD_PATH)/$(SRC_PATH)/LICENSE
|
||||
|
|
|
@ -1,38 +1,93 @@
|
|||
# NCC Default configuration file, upon installation the installer will generate a new configuration file
|
||||
# for your system or update the existing configuration file and only overwriting values that are no
|
||||
# longer applicable to the current version of NCC, incorrect configuration values can cause
|
||||
# unexpected behavior or bugs.
|
||||
|
||||
# NCC Default configuration file, upon installation the installer
|
||||
# will generate a new configuration file for your system or update
|
||||
# the existing configuration file and only overwriting values that
|
||||
# are no longer applicable to the current version of NCC, incorrect
|
||||
# configuration values can cause unexpected behavior or bugs.
|
||||
ncc:
|
||||
# The default data directory that is used by NCC to store packages,
|
||||
# cache, configuration files and other generated files. This includes
|
||||
# data stored by packages using the NCC storage API.
|
||||
data_directory: "/var/ncc"
|
||||
cli:
|
||||
# Omits colors from displaying in the CLI
|
||||
no_colors: false
|
||||
|
||||
# Display basic ascii characters in the CLI
|
||||
basic_ascii: false
|
||||
|
||||
# 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:
|
||||
# Configuration section for the PHP configuration that NCC will use to run
|
||||
|
||||
# The main executable path for PHP that NCC should use
|
||||
executable_path: "/usr/bin/php"
|
||||
|
||||
# Enables/Disables the environment configuration feature
|
||||
# Allowing packages to install environment configurations to NCC
|
||||
# that can be loaded during runtime using the NCC API
|
||||
#
|
||||
# If disabled packages may break if they depend on this feature.
|
||||
#
|
||||
# Leaving this enabled while installing and using unknown packages
|
||||
# without reviewing their source code could lead to potential security
|
||||
# issues/backdoors, use this feature for containerized environments
|
||||
enable_environment_configurations: false
|
||||
runtime:
|
||||
# Whether to initialize NCC when running `require('ncc');`
|
||||
initialize_on_require: true
|
||||
|
||||
# if NCC should handle fatal exceptions during execution
|
||||
handle_exceptions: true
|
||||
|
||||
git:
|
||||
# if git is enabled or not
|
||||
enabled: true
|
||||
|
||||
# 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:
|
||||
# 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
|
||||
|
||||
# if composer is enabled or not
|
||||
enabled: true
|
||||
|
||||
# If internal composer is enabled (install must be executed with --install-composer)
|
||||
enable_internal_composer: true
|
||||
executable_path: "/home/user/composer.phar"
|
||||
|
||||
# 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: false
|
||||
|
||||
# Do not ask any interactive question
|
||||
no_interaction: false
|
||||
|
||||
# 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"
|
|
@ -26,6 +26,7 @@
|
|||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\Validate;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
|
@ -151,12 +152,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Check if running in a TTY
|
||||
if(stream_isatty(STDERR) && !$NCC_BYPASS_CLI_CHECK)
|
||||
{
|
||||
Console::outWarning('Your terminal may have some issues rendering the output of this installer');
|
||||
}
|
||||
|
||||
// Check if running as root
|
||||
if(!function_exists('posix_getuid'))
|
||||
{
|
||||
|
@ -453,22 +448,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Backup the configuration file
|
||||
$config_backup = null;
|
||||
if($NCC_FILESYSTEM->exists($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'ncc.yaml'))
|
||||
{
|
||||
Console::out('ncc.yaml will be updated');
|
||||
try
|
||||
{
|
||||
$config_backup = IO::fread($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'ncc.yaml');
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outError($e->getMessage(), true, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare installation
|
||||
if($NCC_FILESYSTEM->exists($NCC_INSTALL_PATH))
|
||||
{
|
||||
|
@ -558,7 +537,7 @@
|
|||
return;
|
||||
}
|
||||
$total_items = count($build_files);
|
||||
$processed_items = 0;
|
||||
$processed_items = 1;
|
||||
|
||||
// Create all the directories first
|
||||
foreach($build_files as $path)
|
||||
|
@ -611,8 +590,7 @@
|
|||
|
||||
$bin_paths = [
|
||||
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'bin',
|
||||
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'local' . DIRECTORY_SEPARATOR . 'bin',
|
||||
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'share'
|
||||
DIRECTORY_SEPARATOR . 'bin'
|
||||
];
|
||||
|
||||
foreach($bin_paths as $path)
|
||||
|
@ -628,7 +606,6 @@
|
|||
try
|
||||
{
|
||||
IO::fwrite($path . DIRECTORY_SEPARATOR . 'ncc', $executable_shortcut);
|
||||
break;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
|
@ -718,6 +695,44 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// TODO: Implement Configuration Tools
|
||||
Console::outWarning('Cannot locate the executable path for \'composer\', run \'ncc config --composer.executable_path="composer.phar"\' as root to update the path');
|
||||
}
|
||||
}
|
||||
|
||||
// Backup the configuration file
|
||||
$config_backup = null;
|
||||
|
||||
try
|
||||
{
|
||||
if ($NCC_FILESYSTEM->exists(PathFinder::getConfigurationFile()))
|
||||
{
|
||||
$config_backup = IO::fread(PathFinder::getConfigurationFile());
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
Console::outError($e->getMessage(), true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Create/Update configuration file
|
||||
$config_obj = Yaml::parseFile(__DIR__ . DIRECTORY_SEPARATOR . 'default_config.yaml');
|
||||
|
||||
|
@ -744,28 +759,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 --git.executable_path="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)
|
||||
{
|
||||
// TODO: Implement Configuration Tools
|
||||
Console::outWarning('Cannot locate the executable path for \'composer\', run \'ncc config --composer.executable_path="composer.phar"\' as root to update the path');
|
||||
}
|
||||
}
|
||||
|
||||
if($config_backup == null)
|
||||
{
|
||||
Console::out('Generating ncc.yaml');
|
||||
|
@ -778,9 +771,9 @@
|
|||
|
||||
try
|
||||
{
|
||||
IO::fwrite($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'ncc.yaml', Yaml::dump($config_obj));
|
||||
IO::fwrite(PathFinder::getConfigurationFile(), Yaml::dump($config_obj), 0755);
|
||||
}
|
||||
catch (\ncc\Exceptions\IOException $e)
|
||||
catch (Exception $e)
|
||||
{
|
||||
Console::outException($e->getMessage(), $e, 1);
|
||||
return;
|
||||
|
|
35
src/ncc/Abstracts/ComposerPackageTypes.php
Normal file
35
src/ncc/Abstracts/ComposerPackageTypes.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Abstracts;
|
||||
|
||||
abstract class ComposerPackageTypes
|
||||
{
|
||||
/**
|
||||
* This is the default. It will copy the files to `vendor`
|
||||
*/
|
||||
const Library = 'library';
|
||||
|
||||
/**
|
||||
* This denotes a project rather than a library. For example
|
||||
* application shells like the Symfony standard edition, CMSs
|
||||
* like the SilverStripe instlaler 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.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
const MetaPackage = 'metapackage';
|
||||
|
||||
/**
|
||||
* A package of type `composer-plugin` may provide an installer
|
||||
* for other packages that have a custom type.
|
||||
*/
|
||||
const ComposerPlugin = 'composer-plugin';
|
||||
}
|
16
src/ncc/Abstracts/ComposerStabilityTypes.php
Normal file
16
src/ncc/Abstracts/ComposerStabilityTypes.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Abstracts;
|
||||
|
||||
abstract class ComposerStabilityTypes
|
||||
{
|
||||
const Dev = 'dev';
|
||||
|
||||
const Alpha = 'alpha';
|
||||
|
||||
const Beta = 'beta';
|
||||
|
||||
const RC = 'rc';
|
||||
|
||||
const Stable ='stable';
|
||||
}
|
29
src/ncc/Abstracts/DependencySourceType.php
Normal file
29
src/ncc/Abstracts/DependencySourceType.php
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Abstracts;
|
||||
|
||||
abstract class DependencySourceType
|
||||
{
|
||||
/**
|
||||
* The dependency pointer does not point to a package
|
||||
*/
|
||||
const None = 'none';
|
||||
|
||||
/**
|
||||
* Indicates if the dependency is statically linked and the
|
||||
* reference points to the compiled package of the dependency
|
||||
*/
|
||||
const StaticLinking = 'static';
|
||||
|
||||
/**
|
||||
* Indicates if the pointer reference points to a remote source
|
||||
* to fetch the dependency from
|
||||
*/
|
||||
const RemoteSource = 'remote';
|
||||
|
||||
/**
|
||||
* Indicates if the pointer reference points to a relative file with the
|
||||
* filename format "{package_name}=={version}.ncc" to fetch the dependency from
|
||||
*/
|
||||
const Local = 'local';
|
||||
}
|
|
@ -2,50 +2,6 @@
|
|||
|
||||
namespace ncc\Abstracts;
|
||||
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\AutoloadGeneratorException;
|
||||
use ncc\Exceptions\BuildConfigurationNotFoundException;
|
||||
use ncc\Exceptions\BuildException;
|
||||
use ncc\Exceptions\ComponentChecksumException;
|
||||
use ncc\Exceptions\ComponentDecodeException;
|
||||
use ncc\Exceptions\ComponentVersionNotFoundException;
|
||||
use ncc\Exceptions\ConstantReadonlyException;
|
||||
use ncc\Exceptions\DirectoryNotFoundException;
|
||||
use ncc\Exceptions\ExecutionUnitNotFoundException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InstallationException;
|
||||
use ncc\Exceptions\InvalidConstantNameException;
|
||||
use ncc\Exceptions\InvalidCredentialsEntryException;
|
||||
use ncc\Exceptions\InvalidExecutionPolicyName;
|
||||
use ncc\Exceptions\InvalidPackageException;
|
||||
use ncc\Exceptions\InvalidPackageNameException;
|
||||
use ncc\Exceptions\InvalidProjectBuildConfiguration;
|
||||
use ncc\Exceptions\InvalidProjectConfigurationException;
|
||||
use ncc\Exceptions\InvalidProjectNameException;
|
||||
use ncc\Exceptions\InvalidPropertyValueException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\InvalidVersionConfigurationException;
|
||||
use ncc\Exceptions\InvalidVersionNumberException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\MalformedJsonException;
|
||||
use ncc\Exceptions\NoAvailableUnitsException;
|
||||
use ncc\Exceptions\NoUnitsFoundException;
|
||||
use ncc\Exceptions\PackageAlreadyInstalledException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Exceptions\PackageNotFoundException;
|
||||
use ncc\Exceptions\PackageParsingException;
|
||||
use ncc\Exceptions\ProjectAlreadyExistsException;
|
||||
use ncc\Exceptions\ProjectConfigurationNotFoundException;
|
||||
use ncc\Exceptions\ResourceChecksumException;
|
||||
use ncc\Exceptions\RunnerExecutionException;
|
||||
use ncc\Exceptions\RuntimeException;
|
||||
use ncc\Exceptions\UndefinedExecutionPolicyException;
|
||||
use ncc\Exceptions\UnsupportedComponentTypeException;
|
||||
use ncc\Exceptions\UnsupportedCompilerExtensionException;
|
||||
use ncc\Exceptions\UnsupportedPackageException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Exceptions\VersionNotFoundException;
|
||||
|
||||
/**
|
||||
* @author Zi Xing Narrakas
|
||||
* @copyright Copyright (C) 2022-2022. Nosial - All Rights Reserved.
|
||||
|
@ -282,6 +238,36 @@
|
|||
*/
|
||||
const PackageNotFoundException = -1745;
|
||||
|
||||
/**
|
||||
* @see ComposerDisabledException
|
||||
*/
|
||||
const ComposerDisabledException = -1746;
|
||||
|
||||
/**
|
||||
* @see InternalComposerNotAvailableException
|
||||
*/
|
||||
const InternalComposerNotAvailable = -1747;
|
||||
|
||||
/**
|
||||
* @see ComposerNotAvailableException
|
||||
*/
|
||||
const ComposerNotAvailableException = -1748;
|
||||
|
||||
/**
|
||||
* @see ComposerException
|
||||
*/
|
||||
const ComposerException = -1749;
|
||||
|
||||
/**
|
||||
* @see UserAbortedOperationException
|
||||
*/
|
||||
const UserAbortedOperationException = -1750;
|
||||
|
||||
/**
|
||||
* @see MissingDependencyException
|
||||
*/
|
||||
const MissingDependencyException = -1751;
|
||||
|
||||
/**
|
||||
* All the exception codes from NCC
|
||||
*/
|
||||
|
@ -330,6 +316,12 @@
|
|||
self::NoAvailableUnitsException,
|
||||
self::ExecutionUnitNotFoundException,
|
||||
self::PackageAlreadyInstalledException,
|
||||
self::PackageNotFoundException
|
||||
self::PackageNotFoundException,
|
||||
self::ComposerDisabledException,
|
||||
self::InternalComposerNotAvailable,
|
||||
self::ComposerNotAvailableException,
|
||||
self::ComposerException,
|
||||
self::UserAbortedOperationException,
|
||||
self::MissingDependencyException
|
||||
];
|
||||
}
|
|
@ -25,4 +25,10 @@
|
|||
const ConstantName = '/^([^\x00-\x7F]|[\w_\ \.\+\-]){2,64}$/';
|
||||
|
||||
const ExecutionPolicyName = '/^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/m';
|
||||
|
||||
/**
|
||||
* @author <purplex>
|
||||
*/
|
||||
const RemotePackage = '/^(?<vendor>[^\/\n]+)\/(?<package>[^:=\n@]+)(?:=(?<version>[^:@\n]+))?(?::(?<branch>[^@\n]+))?@(?<source>.*)$/m';
|
||||
|
||||
}
|
|
@ -5,12 +5,12 @@
|
|||
abstract class RemoteSource
|
||||
{
|
||||
/**
|
||||
* The original source is from GitHub (Enterprise not supported yet)
|
||||
* The remote source is from composer
|
||||
*/
|
||||
const GitHub = 'GITHUB';
|
||||
const Composer = 'composer';
|
||||
|
||||
/**
|
||||
* The original source is from Gitlab or a Gitlab instance
|
||||
* The remote source is from a git repository
|
||||
*/
|
||||
const Gitlab = 'GITLAB';
|
||||
const Git = 'git';
|
||||
}
|
150
src/ncc/CLI/ConfigMenu.php
Normal file
150
src/ncc/CLI/ConfigMenu.php
Normal file
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\CLI;
|
||||
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Managers\ConfigurationManager;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
|
||||
class ConfigMenu
|
||||
{
|
||||
/**
|
||||
* Displays the main help menu
|
||||
*
|
||||
* @param $args
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
* @throws IOException
|
||||
* @throws InvalidScopeException
|
||||
*/
|
||||
public static function start($args): void
|
||||
{
|
||||
if(isset($args['sample']))
|
||||
{
|
||||
$sample_file = __DIR__ . DIRECTORY_SEPARATOR . 'template_config.yaml';
|
||||
if(!file_exists($sample_file))
|
||||
{
|
||||
Console::outError('Cannot display sample, file template_config.yaml was not found', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$handle = fopen($sample_file, 'r');
|
||||
if (!$handle)
|
||||
{
|
||||
Console::outError('Cannot display sample, error reading template_config.yaml', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
while (($line = fgets($handle)) !== false)
|
||||
{
|
||||
Console::out($line, false);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(isset($args['read']))
|
||||
{
|
||||
if(!file_exists(PathFinder::getConfigurationFile()))
|
||||
{
|
||||
Console::outError('Cannot read configuration file, path not found', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$handle = fopen(PathFinder::getConfigurationFile(), 'r');
|
||||
if (!$handle)
|
||||
{
|
||||
Console::outError('Cannot display configuration file, error reading file', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
while (($line = fgets($handle)) !== false)
|
||||
{
|
||||
Console::out($line, false);
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(isset($args['p']))
|
||||
{
|
||||
$configuration_manager = new ConfigurationManager();
|
||||
|
||||
if(isset($args['v']))
|
||||
{
|
||||
if(Resolver::resolveScope() !== Scopes::System)
|
||||
{
|
||||
Console::outError('Insufficent permissions, cannot modify configuration values', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(strtolower($args['v']) == 'null')
|
||||
$args['v'] = null;
|
||||
if($configuration_manager->updateProperty($args['p'], $args['v']))
|
||||
{
|
||||
$configuration_manager->save();
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::outError(sprintf('Unknown property %s', $args['p']), true, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = $configuration_manager->getProperty($args['p']);
|
||||
if(!is_null($value))
|
||||
{
|
||||
if(is_bool($value))
|
||||
$value = ($value ? 'true' : 'false');
|
||||
if(is_array($value))
|
||||
$value = json_encode($value, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
|
||||
Console::out((string)$value);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
self::displayOptions();
|
||||
exit(0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the main options section
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function displayOptions(): void
|
||||
{
|
||||
$options = [
|
||||
new CliHelpSection(['sample'], 'Displays a sample configuration file with documentation'),
|
||||
new CliHelpSection(['read'], 'Displays the current configuration file NCC is using'),
|
||||
new CliHelpSection(['-p'], 'Property value name (eg; composer.options.no_scripts)'),
|
||||
new CliHelpSection(['-v'], '(Optional) Value to set to property')
|
||||
];
|
||||
|
||||
$options_padding = Functions::detectParametersPadding($options) + 4;
|
||||
|
||||
Console::out('Usage: ncc config -p <property_name> -v <value>');
|
||||
Console::out('Options:');
|
||||
foreach($options as $option)
|
||||
{
|
||||
Console::out(' ' . $option->toString($options_padding));
|
||||
}
|
||||
|
||||
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`');
|
||||
}
|
||||
}
|
|
@ -72,6 +72,7 @@
|
|||
new CliHelpSection(['package'], 'Manages the package system'),
|
||||
new CliHelpSection(['cache'], 'Manages the system cache'),
|
||||
new CliHelpSection(['credential'], 'Manages credentials'),
|
||||
new CliHelpSection(['config'], 'Changes NCC configuration values'),
|
||||
];
|
||||
$commands_padding = \ncc\Utilities\Functions::detectParametersPadding($commands) + 2;
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
|
||||
if(in_array(NccBuildFlags::Unstable, NCC_VERSION_FLAGS))
|
||||
{
|
||||
Console::outWarning('This is an unstable build of NCC, expect some features to not work as expected');
|
||||
//Console::outWarning('This is an unstable build of NCC, expect some features to not work as expected');
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -115,6 +115,10 @@
|
|||
PackageManagerMenu::start(self::$args);
|
||||
exit(0);
|
||||
|
||||
case 'config':
|
||||
ConfigMenu::start(self::$args);
|
||||
exit(0);
|
||||
|
||||
case '1':
|
||||
case 'help':
|
||||
HelpMenu::start(self::$args);
|
||||
|
@ -123,7 +127,7 @@
|
|||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException($e->getMessage() . ' (Code: ' . $e->getCode() . ')', $e, 1);
|
||||
Console::outException($e->getMessage(), $e, 1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,16 @@
|
|||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ConsoleColors;
|
||||
use ncc\Abstracts\RemoteSource;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Classes\ComposerExtension\ComposerSource;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Exceptions\VersionNotFoundException;
|
||||
use ncc\Managers\PackageManager;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\Resolver;
|
||||
|
@ -54,11 +56,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
if(isset($args['uninstall-all']))
|
||||
{
|
||||
try
|
||||
{
|
||||
self::uninstallAllPackages($args);
|
||||
return;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
Console::outException('Uninstallation Failed', $e, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($args['list']))
|
||||
{
|
||||
try
|
||||
{
|
||||
self::getInstallPackages();
|
||||
self::getInstallPackages($args);
|
||||
return;
|
||||
}
|
||||
catch(Exception $e)
|
||||
|
@ -73,11 +89,40 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Displays all installed packages
|
||||
* Prints an ascii tree of an array
|
||||
*
|
||||
* @param $data
|
||||
* @param string $prefix
|
||||
* @return void
|
||||
*/
|
||||
private static function getInstallPackages(): void
|
||||
private static function printTree($data, string $prefix=''): void
|
||||
{
|
||||
$symbols = [
|
||||
'corner' => Console::formatColor(' └─', ConsoleColors::LightRed),
|
||||
'line' => Console::formatColor(' │ ', ConsoleColors::LightRed),
|
||||
'cross' => Console::formatColor(' ├─', ConsoleColors::LightRed),
|
||||
];
|
||||
|
||||
$keys = array_keys($data);
|
||||
$lastKey = end($keys);
|
||||
foreach ($data as $key => $value)
|
||||
{
|
||||
$isLast = $key === $lastKey;
|
||||
Console::out($prefix . ($isLast ? $symbols['corner'] : $symbols['cross']) . $key);
|
||||
if (is_array($value))
|
||||
{
|
||||
self::printTree($value, $prefix . ($isLast ? ' ' : $symbols['line']));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays all installed packages
|
||||
*
|
||||
* @param $args
|
||||
* @return void
|
||||
*/
|
||||
private static function getInstallPackages($args): void
|
||||
{
|
||||
$package_manager = new PackageManager();
|
||||
|
||||
|
@ -87,39 +132,44 @@
|
|||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
Console::out('No packages installed');
|
||||
exit(0);
|
||||
Console::outException('Failed to get installed packages', $e, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($installed_packages as $package => $versions)
|
||||
if(isset($args['tree']))
|
||||
{
|
||||
if(count($versions) == 0)
|
||||
self::printTree($package_manager->getPackageTree());
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach($installed_packages as $package => $versions)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach($versions as $version)
|
||||
{
|
||||
try
|
||||
if(count($versions) == 0)
|
||||
{
|
||||
$package_version = $package_manager->getPackageVersion($package, $version);
|
||||
if($package_version == null)
|
||||
throw new Exception();
|
||||
|
||||
Console::out(sprintf('%s==%s (%s)',
|
||||
Console::formatColor($package, ConsoleColors::LightGreen),
|
||||
Console::formatColor($version, ConsoleColors::LightMagenta),
|
||||
$package_manager->getPackageVersion($package, $version)->Compiler->Extension
|
||||
));
|
||||
continue;
|
||||
}
|
||||
catch(Exception $e)
|
||||
|
||||
foreach($versions as $version)
|
||||
{
|
||||
unset($e);
|
||||
Console::out(sprintf('%s==%s',
|
||||
Console::formatColor($package, ConsoleColors::LightGreen),
|
||||
Console::formatColor($version, ConsoleColors::LightMagenta)
|
||||
));
|
||||
try
|
||||
{
|
||||
$package_version = $package_manager->getPackageVersion($package, $version);
|
||||
if($package_version == null)
|
||||
continue;
|
||||
Console::out(sprintf('%s=%s (%s)',
|
||||
Console::formatColor($package, ConsoleColors::LightGreen),
|
||||
Console::formatColor($version, ConsoleColors::LightMagenta),
|
||||
$package_manager->getPackageVersion($package, $version)->Compiler->Extension
|
||||
));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
Console::out(sprintf('%s=%s',
|
||||
Console::formatColor($package, ConsoleColors::LightGreen),
|
||||
Console::formatColor($version, ConsoleColors::LightMagenta)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,16 +178,48 @@
|
|||
/**
|
||||
* @param $args
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
private static function installPackage($args): void
|
||||
{
|
||||
$path = ($args['path'] ?? $args['p']);
|
||||
$package = ($args['package'] ?? $args['p']);
|
||||
$package_manager = new PackageManager();
|
||||
|
||||
if(Resolver::resolveScope() !== Scopes::System)
|
||||
throw new AccessDeniedException('Insufficient permission to install packages');
|
||||
{
|
||||
Console::outError('Insufficient permissions to install packages', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
$path = $package;
|
||||
$parsed_source = new RemotePackageInput($path);
|
||||
if($parsed_source->Vendor !== null && $parsed_source->Package !== null)
|
||||
{
|
||||
if($parsed_source->Source == null)
|
||||
{
|
||||
Console::outError('No source specified', true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
switch($parsed_source->Source)
|
||||
{
|
||||
case RemoteSource::Composer:
|
||||
try
|
||||
{
|
||||
$path = ComposerSource::fetch($parsed_source);
|
||||
break;
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException(sprintf('Failed to fetch package %s', $package), $e, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
Console::outError('Cannot install package from source: ' . $parsed_source->Source, true, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(!file_exists($path) || !is_file($path) || !is_readable($path))
|
||||
throw new FileNotFoundException('The specified file \'' . $path .' \' does not exist or is not readable.');
|
||||
|
@ -184,14 +266,47 @@
|
|||
$dependencies = [];
|
||||
foreach($package->Dependencies as $dependency)
|
||||
{
|
||||
$dependencies[] = sprintf('%s v%s',
|
||||
Console::formatColor($dependency->Name, ConsoleColors::Green),
|
||||
Console::formatColor($dependency->Version, ConsoleColors::LightMagenta)
|
||||
);
|
||||
$require_dependency = true;
|
||||
|
||||
try
|
||||
{
|
||||
$dependency_package = $package_manager->getPackage($dependency->Name);
|
||||
}
|
||||
catch (PackageLockException $e)
|
||||
{
|
||||
unset($e);
|
||||
$dependency_package = null;
|
||||
}
|
||||
|
||||
if($dependency_package !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$dependency_version = $dependency_package->getVersion($dependency->Version);
|
||||
}
|
||||
catch (VersionNotFoundException $e)
|
||||
{
|
||||
unset($e);
|
||||
$dependency_version = null;
|
||||
}
|
||||
|
||||
if($dependency_version !== null)
|
||||
{
|
||||
$require_dependency = false;
|
||||
}
|
||||
}
|
||||
|
||||
if($require_dependency)
|
||||
{
|
||||
$dependencies[] = sprintf(' %s %s',
|
||||
Console::formatColor($dependency->Name, ConsoleColors::Green),
|
||||
Console::formatColor($dependency->Version, ConsoleColors::LightMagenta)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Console::out('The following dependencies will be installed:');
|
||||
Console::out(sprintf(' %s', implode(', ', $dependencies)) . PHP_EOL);
|
||||
Console::out(sprintf('%s', implode(PHP_EOL, $dependencies)));
|
||||
}
|
||||
|
||||
Console::out(sprintf('Extension: %s',
|
||||
|
@ -216,6 +331,7 @@
|
|||
try
|
||||
{
|
||||
$package_manager->install($path);
|
||||
Console::out(sprintf('Package %s installed successfully', $package->Assembly->Package));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
|
@ -237,7 +353,7 @@
|
|||
*/
|
||||
private static function uninstallPackage($args): void
|
||||
{
|
||||
$selected_package = ($args['package'] ?? $args['pkg']);
|
||||
$selected_package = ($args['package'] ?? $args['p']);
|
||||
$selected_version = null;
|
||||
if(isset($args['v']))
|
||||
$selected_version = $args['v'];
|
||||
|
@ -276,9 +392,9 @@
|
|||
return;
|
||||
}
|
||||
|
||||
if($version_entry == null & $selected_version !== null)
|
||||
if($version_entry == null && $selected_version !== null)
|
||||
{
|
||||
Console::outError(sprintf('Package "%s==%s" is not installed', $selected_package, $selected_version), true, 1);
|
||||
Console::outError(sprintf('Package "%s=%s" is not installed', $selected_package, $selected_version), true, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -286,7 +402,7 @@
|
|||
{
|
||||
if($selected_version !== null)
|
||||
{
|
||||
if(!Console::getBooleanInput(sprintf('Do you want to uninstall %s==%s', $selected_package, $selected_version)))
|
||||
if(!Console::getBooleanInput(sprintf('Do you want to uninstall %s=%s', $selected_package, $selected_version)))
|
||||
{
|
||||
Console::outError('User cancelled operation', true, 1);
|
||||
return;
|
||||
|
@ -320,6 +436,48 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls all packages
|
||||
*
|
||||
* @param $args
|
||||
* @return void
|
||||
* @throws PackageLockException
|
||||
*/
|
||||
private static function uninstallAllPackages($args): void
|
||||
{
|
||||
$user_confirmation = null;
|
||||
// For undefined array key warnings
|
||||
if(isset($args['y']) || isset($args['Y']))
|
||||
$user_confirmation = (bool)($args['y'] ?? $args['Y']);
|
||||
|
||||
if($user_confirmation == null)
|
||||
{
|
||||
if(!Console::getBooleanInput('Do you want to uninstall all packages'))
|
||||
{
|
||||
Console::outError('User cancelled operation', true, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$package_manager = new PackageManager();
|
||||
|
||||
foreach($package_manager->getInstalledPackages() as $package => $versions)
|
||||
{
|
||||
foreach($versions as $version)
|
||||
{
|
||||
try
|
||||
{
|
||||
$package_manager->uninstallPackageVersion($package, $version);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException('Uninstallation failed', $e, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the main options section
|
||||
*
|
||||
|
@ -329,8 +487,12 @@
|
|||
{
|
||||
$options = [
|
||||
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
|
||||
new CliHelpSection(['install', '--path', '-p'], 'Installs a specified NCC package file'),
|
||||
new CliHelpSection(['list'], 'Lists all installed packages on the system'),
|
||||
new CliHelpSection(['install', '--package', '-p'], 'Installs a specified NCC package'),
|
||||
new CliHelpSection(['install', '--package', '-p', '--version', '-v'], 'Installs a specified NCC package version'),
|
||||
new CliHelpSection(['uninstall', '--package', '-p'], 'Uninstalls a specified NCC package'),
|
||||
new CliHelpSection(['uninstall', '--package', '-p', '--version', '-v'], 'Uninstalls a specified NCC package version'),
|
||||
new CliHelpSection(['uninstall-all'], 'Uninstalls all packages'),
|
||||
];
|
||||
|
||||
$options_padding = Functions::detectParametersPadding($options) + 4;
|
||||
|
@ -341,5 +503,14 @@
|
|||
{
|
||||
Console::out(' ' . $option->toString($options_padding));
|
||||
}
|
||||
|
||||
Console::out('You can install a package from a local file or from a supported remote repository');
|
||||
Console::out('Note that installing from some repositories may require ncc to build the package');
|
||||
Console::out('Examples of usage:');
|
||||
Console::out(' ncc install --package=build/release/com.example.library.ncc');
|
||||
Console::out(' ncc install --package=symfony/console=5.2.0@composer');
|
||||
Console::out(' ncc install --package=symfony/console@composer -v=5.2.0');
|
||||
Console::out(' ncc install --package=foo/bar:master@gitlab');
|
||||
Console::out(' ncc install --package=foo/bar:dev@custom');
|
||||
}
|
||||
}
|
561
src/ncc/Classes/ComposerExtension/ComposerSource.php
Normal file
561
src/ncc/Classes/ComposerExtension/ComposerSource.php
Normal file
|
@ -0,0 +1,561 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Classes\ComposerExtension;
|
||||
|
||||
use Exception;
|
||||
use FilesystemIterator;
|
||||
use ncc\Abstracts\CompilerExtensions;
|
||||
use ncc\Abstracts\CompilerExtensionSupportedVersions;
|
||||
use ncc\Abstracts\ComponentFileExtensions;
|
||||
use ncc\Abstracts\DependencySourceType;
|
||||
use ncc\Abstracts\LogLevel;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\CLI\Main;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\BuildConfigurationNotFoundException;
|
||||
use ncc\Exceptions\BuildException;
|
||||
use ncc\Exceptions\ComposerDisabledException;
|
||||
use ncc\Exceptions\ComposerException;
|
||||
use ncc\Exceptions\ComposerNotAvailableException;
|
||||
use ncc\Exceptions\DirectoryNotFoundException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InternalComposerNotAvailableException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\MalformedJsonException;
|
||||
use ncc\Exceptions\PackageNotFoundException;
|
||||
use ncc\Exceptions\PackagePreparationFailedException;
|
||||
use ncc\Exceptions\ProjectConfigurationNotFoundException;
|
||||
use ncc\Exceptions\RuntimeException;
|
||||
use ncc\Exceptions\UnsupportedCompilerExtensionException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Exceptions\UserAbortedOperationException;
|
||||
use ncc\Interfaces\RemoteSourceInterface;
|
||||
use ncc\Managers\ProjectManager;
|
||||
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 ComposerSource implements RemoteSourceInterface
|
||||
{
|
||||
/**
|
||||
* 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 AccessDeniedException
|
||||
* @throws BuildConfigurationNotFoundException
|
||||
* @throws BuildException
|
||||
* @throws ComposerDisabledException
|
||||
* @throws ComposerException
|
||||
* @throws ComposerNotAvailableException
|
||||
* @throws DirectoryNotFoundException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws InternalComposerNotAvailableException
|
||||
* @throws InvalidScopeException
|
||||
* @throws MalformedJsonException
|
||||
* @throws PackageNotFoundException
|
||||
* @throws PackagePreparationFailedException
|
||||
* @throws ProjectConfigurationNotFoundException
|
||||
* @throws RuntimeException
|
||||
* @throws UnsupportedCompilerExtensionException
|
||||
* @throws UnsupportedRunnerException
|
||||
* @throws UserAbortedOperationException
|
||||
*/
|
||||
public static function fetch(RemotePackageInput $packageInput): string
|
||||
{
|
||||
$package_path = self::require($packageInput->Vendor, $packageInput->Package, $packageInput->Version);
|
||||
$packages = self::compilePackages($package_path . DIRECTORY_SEPARATOR . 'composer.lock');
|
||||
RuntimeCache::setFileAsTemporary($package_path);
|
||||
$real_package_name = explode('=', $packageInput->toStandard(false))[0];
|
||||
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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $composer_lock_path
|
||||
* @return array
|
||||
* @throws AccessDeniedException
|
||||
* @throws BuildConfigurationNotFoundException
|
||||
* @throws BuildException
|
||||
* @throws DirectoryNotFoundException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws MalformedJsonException
|
||||
* @throws PackageNotFoundException
|
||||
* @throws PackagePreparationFailedException
|
||||
* @throws ProjectConfigurationNotFoundException
|
||||
* @throws UnsupportedCompilerExtensionException
|
||||
* @throws UnsupportedRunnerException
|
||||
*/
|
||||
private static function compilePackages(string $composer_lock_path): array
|
||||
{
|
||||
if (!file_exists($composer_lock_path))
|
||||
{
|
||||
throw new FileNotFoundException($composer_lock_path);
|
||||
}
|
||||
|
||||
$base_dir = dirname($composer_lock_path);
|
||||
$composer_lock = ComposerLock::fromArray(json_decode(IO::fread($composer_lock_path), true));
|
||||
$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');
|
||||
|
||||
foreach ($composer_lock->Packages as $package)
|
||||
{
|
||||
$package_path = $base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->Name;
|
||||
// Generate the package configuration
|
||||
$project_configuration = ComposerSource::generateProjectConfiguration($package->Name, $composer_lock);
|
||||
|
||||
// Process the source files
|
||||
if ($package->Autoload !== null)
|
||||
{
|
||||
$source_directory = $package_path . DIRECTORY_SEPARATOR . '.src';
|
||||
if ($filesystem->exists($source_directory))
|
||||
{
|
||||
$filesystem->remove($source_directory);
|
||||
}
|
||||
$filesystem->mkdir($source_directory);
|
||||
$source_directories = [];
|
||||
$static_files = [];
|
||||
|
||||
// TODO: Implement static files handling
|
||||
|
||||
// Extract all the source directories
|
||||
if ($package->Autoload->Psr4 !== null && count($package->Autoload->Psr4) > 0)
|
||||
{
|
||||
Console::outVerbose('Extracting PSR-4 source directories');
|
||||
foreach ($package->Autoload->Psr4 as $namespace_pointer)
|
||||
{
|
||||
if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories))
|
||||
{
|
||||
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($package->Autoload->Psr0 !== null && count($package->Autoload->Psr0) > 0)
|
||||
{
|
||||
Console::outVerbose('Extracting PSR-0 source directories');
|
||||
foreach ($package->Autoload->Psr0 as $namespace_pointer)
|
||||
{
|
||||
if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories))
|
||||
{
|
||||
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($package->Autoload->Files !== null && count($package->Autoload->Files) > 0)
|
||||
{
|
||||
Console::outVerbose('Extracting static files');
|
||||
foreach ($package->Autoload->Files as $file)
|
||||
{
|
||||
$static_files[] = $package_path . DIRECTORY_SEPARATOR . $file;
|
||||
}
|
||||
}
|
||||
|
||||
Console::outDebug(sprintf('source directories: %s', implode(', ', $source_directories)));
|
||||
|
||||
// First scan the project files and create a file struct.
|
||||
$DirectoryScanner = new DirectoryScanner();
|
||||
|
||||
// TODO: Implement exclude-class handling
|
||||
try
|
||||
{
|
||||
$DirectoryScanner->unsetFlag(FilesystemIterator::FOLLOW_SYMLINKS);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new PackagePreparationFailedException('Cannot unset flag \'FOLLOW_SYMLINKS\' in DirectoryScanner, ' . $e->getMessage(), $e);
|
||||
}
|
||||
|
||||
// Include file components that can be compiled
|
||||
$DirectoryScanner->setIncludes(ComponentFileExtensions::Php);
|
||||
|
||||
foreach ($source_directories as $directory)
|
||||
{
|
||||
/** @var SplFileInfo $item */
|
||||
/** @noinspection PhpRedundantOptionalArgumentInspection */
|
||||
foreach ($DirectoryScanner($directory, True) as $item)
|
||||
{
|
||||
if (is_dir($item->getPathName()))
|
||||
continue;
|
||||
|
||||
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName());
|
||||
|
||||
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name));
|
||||
$filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($static_files) > 0)
|
||||
{
|
||||
$project_configuration->Project->Options['static_files'] = $static_files;
|
||||
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName());
|
||||
if (!$filesystem->exists($source_directory . DIRECTORY_SEPARATOR . $parsed_path))
|
||||
{
|
||||
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name));
|
||||
$filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
|
||||
}
|
||||
}
|
||||
|
||||
$project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json');
|
||||
}
|
||||
|
||||
// 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=%s.ncc', $project_configuration->Assembly->Package, $project_configuration->Assembly->Version);
|
||||
$filesystem->copy($built_package, $out_path);
|
||||
$built_packages[$project_configuration->Assembly->Package] = $out_path;
|
||||
|
||||
}
|
||||
|
||||
return $built_packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a composer package name to a valid package name
|
||||
*
|
||||
* @param string $input
|
||||
* @return string|null
|
||||
*/
|
||||
private static function toPackageName(string $input): ?string
|
||||
{
|
||||
if (stripos($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a project configuration from a package selection
|
||||
* from the composer.lock file
|
||||
*
|
||||
* @param string $package_name
|
||||
* @param ComposerLock $composer_lock
|
||||
* @return ProjectConfiguration
|
||||
* @throws PackageNotFoundException
|
||||
*/
|
||||
private static function generateProjectConfiguration(string $package_name, ComposerLock $composer_lock): ProjectConfiguration
|
||||
{
|
||||
// Load the composer lock file
|
||||
$composer_package = $composer_lock->getPackage($package_name);
|
||||
if ($composer_package == null)
|
||||
throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package_name));
|
||||
|
||||
// Generate a new project configuration object
|
||||
$project_configuration = new ProjectConfiguration();
|
||||
|
||||
if (isset($composer_package->Name))
|
||||
$project_configuration->Assembly->Name = $composer_package->Name;
|
||||
if (isset($composer_package->Description))
|
||||
$project_configuration->Assembly->Description = $composer_package->Description;
|
||||
if (isset($composer_package->Version))
|
||||
$project_configuration->Assembly->Version = Functions::parseVersion($composer_package->Version);
|
||||
|
||||
$project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122();
|
||||
$project_configuration->Assembly->Package = self::toPackageName($package_name);
|
||||
|
||||
// Process the dependencies
|
||||
foreach ($composer_package->Require as $item)
|
||||
{
|
||||
$package_name = self::toPackageName($item->PackageName);
|
||||
$package_version = $composer_lock->getPackage($item->PackageName)?->Version;
|
||||
if ($package_version == null)
|
||||
{
|
||||
$package_version = '1.0.0';
|
||||
}
|
||||
else
|
||||
{
|
||||
$package_version = Functions::parseVersion($package_version);
|
||||
}
|
||||
if ($package_name == null)
|
||||
continue;
|
||||
$dependency = new ProjectConfiguration\Dependency();
|
||||
$dependency->Name = $package_name;
|
||||
$dependency->SourceType = DependencySourceType::Local;
|
||||
$dependency->Version = $package_version;
|
||||
$dependency->Source = $package_name . '=' . $dependency->Version . '.ncc';
|
||||
$project_configuration->Build->Dependencies[] = $dependency;
|
||||
}
|
||||
|
||||
// Create a build configuration
|
||||
$build_configuration = new ProjectConfiguration\BuildConfiguration();
|
||||
$build_configuration->Name = 'default';
|
||||
$build_configuration->OutputPath = 'build';
|
||||
|
||||
// Apply the final properties
|
||||
$project_configuration->Build->Configurations[] = $build_configuration;
|
||||
$project_configuration->Build->DefaultConfiguration = 'default';
|
||||
$project_configuration->Build->SourcePath = '.src';
|
||||
|
||||
// Apply compiler extension
|
||||
$project_configuration->Project->Compiler->Extension = CompilerExtensions::PHP;
|
||||
$project_configuration->Project->Compiler->MinimumVersion = CompilerExtensionSupportedVersions::PHP[0];
|
||||
$project_configuration->Project->Compiler->MaximumVersion = CompilerExtensionSupportedVersions::PHP[(count(CompilerExtensionSupportedVersions::PHP) - 1)];
|
||||
|
||||
return $project_configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a version if available from the input
|
||||
*
|
||||
* @param string $input
|
||||
* @return string|null
|
||||
*/
|
||||
private static function extractVersion(string $input): ?string
|
||||
{
|
||||
if (stripos($input, ':'))
|
||||
{
|
||||
return explode(':', $input)[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the applicable options configured for composer
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getOptions(): array
|
||||
{
|
||||
$options = Functions::getConfigurationProperty('composer.options');
|
||||
if ($options == null || !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))
|
||||
$results[] = '--quiet';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses composer's require command to temporarily create a
|
||||
* composer.json file and install the specified package
|
||||
*
|
||||
* @param string $vendor
|
||||
* @param string $package
|
||||
* @param string|null $version
|
||||
* @param array $options
|
||||
* @return string
|
||||
* @throws AccessDeniedException
|
||||
* @throws ComposerDisabledException
|
||||
* @throws ComposerException
|
||||
* @throws ComposerNotAvailableException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws InternalComposerNotAvailableException
|
||||
* @throws InvalidScopeException
|
||||
* @throws UserAbortedOperationException
|
||||
*/
|
||||
private static function require(string $vendor, string $package, ?string $version = null, array $options = []): string
|
||||
{
|
||||
if (Resolver::resolveScope() !== Scopes::System)
|
||||
throw new AccessDeniedException('Insufficient permissions to require');
|
||||
|
||||
if ($version == null)
|
||||
$version = '*';
|
||||
|
||||
$tpl_file = __DIR__ . DIRECTORY_SEPARATOR . 'composer.jtpl';
|
||||
if (!file_exists($tpl_file))
|
||||
throw new FileNotFoundException($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));
|
||||
$process->setWorkingDirectory($tmp_dir);
|
||||
|
||||
// Check if scripts are enabled while running as root
|
||||
if (!in_array('--no-scripts', $options) && Resolver::resolveScope() == Scopes::System)
|
||||
{
|
||||
Console::outWarning('composer scripts are enabled while running as root, this can allow malicious scripts to run as root');
|
||||
if (!isset($options['--no-interaction']))
|
||||
{
|
||||
if (!Console::getBooleanInput('Do you want to continue?'))
|
||||
throw new UserAbortedOperationException('The operation was aborted by the user');
|
||||
|
||||
// The user understands the risks and wants to continue
|
||||
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Composer is running "safely". We can disable the superuser check
|
||||
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
|
||||
}
|
||||
|
||||
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 ComposerDisabledException
|
||||
* @throws ComposerNotAvailableException
|
||||
* @throws InternalComposerNotAvailableException
|
||||
*/
|
||||
private static function getComposerPath(): string
|
||||
{
|
||||
Console::outVerbose(sprintf('Getting composer path for %s', Functions::getConfigurationProperty('composer.path')));
|
||||
|
||||
$composer_enabled = Functions::getConfigurationProperty('composer.enabled');
|
||||
if ($composer_enabled !== null && $composer_enabled === false)
|
||||
throw new ComposerDisabledException('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.executable_path = %s', ($config_property ?? 'n/a')));
|
||||
|
||||
if ($config_property !== null && strlen($config_property) > 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if (defined('NCC_EXEC_LOCATION'))
|
||||
{
|
||||
if (!file_exists(NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'composer.phar'))
|
||||
throw new InternalComposerNotAvailableException(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';
|
||||
}
|
||||
|
||||
throw new ComposerNotAvailableException('No composer executable path is configured');
|
||||
}
|
||||
}
|
5
src/ncc/Classes/ComposerExtension/composer.jtpl
Normal file
5
src/ncc/Classes/ComposerExtension/composer.jtpl
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"require": {
|
||||
"%VENDOR%/%PACKAGE%": "%VERSION%"
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Classes;
|
||||
|
||||
use ncc\Objects\ProjectConfiguration;
|
||||
|
||||
class MakefileGenerator
|
||||
{
|
||||
/**
|
||||
* @var ProjectConfiguration
|
||||
*/
|
||||
private ProjectConfiguration $project;
|
||||
|
||||
/**
|
||||
* MakefileGenerator constructor.
|
||||
* @param ProjectConfiguration $project
|
||||
*/
|
||||
public function __construct(ProjectConfiguration $project)
|
||||
{
|
||||
$this->project = $project;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
use ncc\Abstracts\ConstantReferences;
|
||||
use ncc\Abstracts\LogLevel;
|
||||
use ncc\Abstracts\Options\BuildConfigurationValues;
|
||||
use ncc\Classes\PhpExtension\Compiler;
|
||||
use ncc\Classes\PhpExtension\PhpCompiler;
|
||||
use ncc\CLI\Main;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\BuildConfigurationNotFoundException;
|
||||
|
@ -67,7 +67,7 @@
|
|||
{
|
||||
case CompilerExtensions::PHP:
|
||||
/** @var CompilerInterface $Compiler */
|
||||
$Compiler = new Compiler($configuration, $manager->getProjectPath());
|
||||
$Compiler = new PhpCompiler($configuration, $manager->getProjectPath());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -75,6 +75,7 @@
|
|||
}
|
||||
|
||||
$build_configuration = $configuration->Build->getBuildConfiguration($build_configuration)->Name;
|
||||
Console::out(sprintf('Building %s=%s', $configuration->Assembly->Package, $configuration->Assembly->Version));
|
||||
$Compiler->prepare($build_configuration);
|
||||
$Compiler->build();
|
||||
|
||||
|
@ -102,7 +103,7 @@
|
|||
Console::out('Compiling Execution Policies');
|
||||
$total_items = count($configuration->ExecutionPolicies);
|
||||
$execution_units = [];
|
||||
$processed_items = 0;
|
||||
$processed_items = 1;
|
||||
|
||||
/** @var ProjectConfiguration\ExecutionPolicy $policy */
|
||||
foreach($configuration->ExecutionPolicies as $policy)
|
||||
|
@ -248,7 +249,7 @@
|
|||
|
||||
if($unit->ExecutionPolicy->ExitHandlers->Warning !== null)
|
||||
{
|
||||
$unit->ExecutionPolicy->ExitHandlers->Warning->Error = self::compileConstants($unit->ExecutionPolicy->ExitHandlers->Warning->Message, $refs);
|
||||
$unit->ExecutionPolicy->ExitHandlers->Warning->Message = self::compileConstants($unit->ExecutionPolicy->ExitHandlers->Warning->Message, $refs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
use ncc\Abstracts\ComponentFileExtensions;
|
||||
use ncc\Abstracts\ComponentDataType;
|
||||
use ncc\Abstracts\ConstantReferences;
|
||||
use ncc\Abstracts\DependencySourceType;
|
||||
use ncc\Abstracts\Options\BuildConfigurationValues;
|
||||
use ncc\Classes\NccExtension\PackageCompiler;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
|
@ -16,13 +17,17 @@
|
|||
use ncc\Exceptions\BuildException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Exceptions\PackagePreparationFailedException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Exceptions\VersionNotFoundException;
|
||||
use ncc\Interfaces\CompilerInterface;
|
||||
use ncc\Managers\PackageLockManager;
|
||||
use ncc\ncc;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\ProjectConfiguration;
|
||||
use ncc\ThirdParty\nikic\PhpParser\ParserFactory;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
|
||||
use ncc\Utilities\Base64;
|
||||
use ncc\Utilities\Console;
|
||||
|
@ -30,7 +35,7 @@
|
|||
use ncc\Utilities\IO;
|
||||
use SplFileInfo;
|
||||
|
||||
class Compiler implements CompilerInterface
|
||||
class PhpCompiler implements CompilerInterface
|
||||
{
|
||||
/**
|
||||
* @var ProjectConfiguration
|
||||
|
@ -91,16 +96,17 @@
|
|||
// Global constants are overridden
|
||||
$this->package->Header->RuntimeConstants = [];
|
||||
$this->package->Header->RuntimeConstants = array_merge(
|
||||
$selected_build_configuration->DefineConstants,
|
||||
$this->project->Build->DefineConstants,
|
||||
$this->package->Header->RuntimeConstants
|
||||
($selected_build_configuration?->DefineConstants ?? []),
|
||||
($this->project->Build->DefineConstants ?? []),
|
||||
($this->package->Header->RuntimeConstants ?? [])
|
||||
);
|
||||
|
||||
$this->package->Header->CompilerExtension = $this->project->Project->Compiler;
|
||||
$this->package->Header->CompilerVersion = NCC_VERSION_NUMBER;
|
||||
$this->package->Header->Options = $this->project->Project->Options;
|
||||
|
||||
Console::out('Scanning project files');
|
||||
Console::out('theseer\DirectoryScanner - Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de> All rights reserved.');
|
||||
Console::outDebug('scanning project files');
|
||||
Console::outDebug('theseer\DirectoryScanner - Copyright (c) 2009-2014 Arne Blankerts <arne@blankerts.de> All rights reserved.');
|
||||
|
||||
// First scan the project files and create a file struct.
|
||||
$DirectoryScanner = new DirectoryScanner();
|
||||
|
@ -116,12 +122,13 @@
|
|||
|
||||
// Include file components that can be compiled
|
||||
$DirectoryScanner->setIncludes(ComponentFileExtensions::Php);
|
||||
$DirectoryScanner->setExcludes($selected_build_configuration->ExcludeFiles);
|
||||
if($selected_build_configuration->ExcludeFiles !== null && count($selected_build_configuration->ExcludeFiles) > 0)
|
||||
$DirectoryScanner->setExcludes($selected_build_configuration->ExcludeFiles);
|
||||
$source_path = $this->path . $this->project->Build->SourcePath;
|
||||
|
||||
// TODO: Re-implement the scanning process outside the compiler, as this is will be redundant
|
||||
// Scan for components first.
|
||||
Console::out('Scanning for components... ');
|
||||
Console::outVerbose('Scanning for components... ');
|
||||
/** @var SplFileInfo $item */
|
||||
/** @noinspection PhpRedundantOptionalArgumentInspection */
|
||||
foreach($DirectoryScanner($source_path, True) as $item)
|
||||
|
@ -134,16 +141,16 @@
|
|||
$Component->Name = Functions::removeBasename($item->getPathname(), $this->path);
|
||||
$this->package->Components[] = $Component;
|
||||
|
||||
Console::outVerbose(sprintf('found component %s', $Component->Name));
|
||||
Console::outVerbose(sprintf('Found component %s', $Component->Name));
|
||||
}
|
||||
|
||||
if(count($this->package->Components) > 0)
|
||||
{
|
||||
Console::out(count($this->package->Components) . ' component(s) found');
|
||||
Console::outVerbose(count($this->package->Components) . ' component(s) found');
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::out('No components found');
|
||||
Console::outVerbose('No components found');
|
||||
}
|
||||
|
||||
// Clear previous excludes and includes
|
||||
|
@ -151,11 +158,16 @@
|
|||
$DirectoryScanner->setIncludes([]);
|
||||
|
||||
// Ignore component files
|
||||
$DirectoryScanner->setExcludes(array_merge(
|
||||
$selected_build_configuration->ExcludeFiles, ComponentFileExtensions::Php
|
||||
));
|
||||
if($selected_build_configuration->ExcludeFiles !== null && count($selected_build_configuration->ExcludeFiles) > 0)
|
||||
{
|
||||
$DirectoryScanner->setExcludes(array_merge($selected_build_configuration->ExcludeFiles, ComponentFileExtensions::Php));
|
||||
}
|
||||
else
|
||||
{
|
||||
$DirectoryScanner->setExcludes(ComponentFileExtensions::Php);
|
||||
}
|
||||
|
||||
Console::out('Scanning for resources... ');
|
||||
Console::outVerbose('Scanning for resources... ');
|
||||
/** @var SplFileInfo $item */
|
||||
foreach($DirectoryScanner($source_path) as $item)
|
||||
{
|
||||
|
@ -172,12 +184,77 @@
|
|||
|
||||
if(count($this->package->Resources) > 0)
|
||||
{
|
||||
Console::out(count($this->package->Resources) . ' resources(s) found');
|
||||
Console::outVerbose(count($this->package->Resources) . ' resources(s) found');
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::out('No resources found');
|
||||
Console::outVerbose('No resources found');
|
||||
}
|
||||
|
||||
$selected_dependencies = [];
|
||||
if($this->project->Build->Dependencies !== null && count($this->project->Build->Dependencies) > 0)
|
||||
$selected_dependencies = array_merge($selected_dependencies, $this->project->Build->Dependencies);
|
||||
if($selected_build_configuration->Dependencies !== null && count($selected_build_configuration->Dependencies) > 0)
|
||||
$selected_dependencies = array_merge($selected_dependencies, $selected_build_configuration->Dependencies);
|
||||
|
||||
// Process the dependencies
|
||||
if(count($selected_dependencies) > 0)
|
||||
{
|
||||
$package_lock_manager = new PackageLockManager();
|
||||
$filesystem = new Filesystem();
|
||||
|
||||
$lib_path = $selected_build_configuration->OutputPath . DIRECTORY_SEPARATOR . 'libs';
|
||||
if($filesystem->exists($lib_path))
|
||||
$filesystem->remove($lib_path);
|
||||
$filesystem->mkdir($lib_path);
|
||||
|
||||
Console::outVerbose('Scanning for dependencies... ');
|
||||
foreach($selected_dependencies as $dependency)
|
||||
{
|
||||
Console::outVerbose(sprintf('processing dependency %s', $dependency->Name));
|
||||
switch($dependency->SourceType)
|
||||
{
|
||||
case DependencySourceType::StaticLinking:
|
||||
|
||||
try
|
||||
{
|
||||
$out_path = $lib_path . DIRECTORY_SEPARATOR . sprintf('%s=%s.lib', $dependency->Name, $dependency->Version);
|
||||
$package = $package_lock_manager->getPackageLock()->getPackage($dependency->Name);
|
||||
$version = $package->getVersion($dependency->Version);
|
||||
Console::outDebug(sprintf('copying shadow package %s=%s to %s', $dependency->Name, $dependency->Version, $out_path));
|
||||
$filesystem->copy($version->Location, $out_path);
|
||||
$dependency->Source = 'libs' . DIRECTORY_SEPARATOR . sprintf('%s=%s.lib', $dependency->Name, $dependency->Version);
|
||||
|
||||
}
|
||||
catch (VersionNotFoundException $e)
|
||||
{
|
||||
throw new PackagePreparationFailedException('Static linking not possible, cannot find version ' . $dependency->Version . ' for dependency ' . $dependency->Name, $e);
|
||||
}
|
||||
catch (PackageLockException $e)
|
||||
{
|
||||
throw new PackagePreparationFailedException('Static linking not possible, cannot find package lock for dependency ' . $dependency->Name, $e);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
case DependencySourceType::RemoteSource:
|
||||
break;
|
||||
}
|
||||
|
||||
$this->package->Dependencies[] = $dependency;
|
||||
}
|
||||
|
||||
if(count($this->package->Dependencies) > 0)
|
||||
{
|
||||
Console::outVerbose(count($this->package->Dependencies) . ' dependency(ies) found');
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::outVerbose('No dependencies found');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,17 +300,17 @@
|
|||
return;
|
||||
|
||||
// Process the resources
|
||||
Console::out('Processing resources');
|
||||
$total_items = count($this->package->Resources);
|
||||
$processed_items = 0;
|
||||
$processed_items = 1;
|
||||
$resources = [];
|
||||
|
||||
if($total_items > 5)
|
||||
Console::out('Processing resources');
|
||||
|
||||
foreach($this->package->Resources as $resource)
|
||||
{
|
||||
if($total_items > 5)
|
||||
{
|
||||
Console::inlineProgressBar($processed_items, $total_items);
|
||||
}
|
||||
|
||||
// Get the data and
|
||||
$resource->Data = IO::fread(Functions::correctDirectorySeparator($this->path . $resource->Name));
|
||||
|
@ -266,11 +343,13 @@
|
|||
if(count($this->package->Components) == 0)
|
||||
return;
|
||||
|
||||
Console::out('Compiling components');
|
||||
$total_items = count($this->package->Components);
|
||||
$processed_items = 0;
|
||||
$processed_items = 1;
|
||||
$components = [];
|
||||
|
||||
if($total_items > 5)
|
||||
Console::out('Compiling components');
|
||||
|
||||
// Process the components and attempt to create an AST representation of the source
|
||||
foreach($this->package->Components as $component)
|
||||
{
|
||||
|
@ -316,11 +395,6 @@
|
|||
Console::outDebug(sprintf('processed component %s (%s)', $component->Name, $component->DataType));
|
||||
}
|
||||
|
||||
if(ncc::cliMode() && $total_items > 5)
|
||||
{
|
||||
print(PHP_EOL);
|
||||
}
|
||||
|
||||
// Update the components
|
||||
$this->package->Components = $components;
|
||||
}
|
|
@ -13,6 +13,7 @@
|
|||
use ncc\Exceptions\ComponentChecksumException;
|
||||
use ncc\Exceptions\ComponentDecodeException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InstallationException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\NoUnitsFoundException;
|
||||
use ncc\Exceptions\ResourceChecksumException;
|
||||
|
@ -30,6 +31,7 @@
|
|||
use ncc\ThirdParty\theseer\Autoload\Factory;
|
||||
use ncc\Utilities\Base64;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use ReflectionClass;
|
||||
use ReflectionException;
|
||||
use RuntimeException;
|
||||
|
@ -37,7 +39,7 @@
|
|||
use function is_array;
|
||||
use function is_string;
|
||||
|
||||
class Installer implements InstallerInterface
|
||||
class PhpInstaller implements InstallerInterface
|
||||
{
|
||||
/**
|
||||
* @var ReflectionClass[] Node type to reflection class map
|
||||
|
@ -113,8 +115,24 @@
|
|||
*/
|
||||
public function postInstall(InstallationPaths $installationPaths): void
|
||||
{
|
||||
$static_files_exists = false;
|
||||
if($this->package->Header->Options !== null && isset($this->package->Header->Options['static_files']))
|
||||
{
|
||||
$static_files = $this->package->Header->Options['static_files'];
|
||||
$static_files_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin';
|
||||
|
||||
foreach($static_files as $file)
|
||||
{
|
||||
if(!file_exists($file))
|
||||
throw new InstallationException(sprintf('Static file %s does not exist', $file));
|
||||
}
|
||||
|
||||
$static_files_exists = true;
|
||||
IO::fwrite($static_files_path, ZiProto::encode($static_files));
|
||||
}
|
||||
|
||||
$autoload_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php';
|
||||
$autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path);
|
||||
$autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path, $static_files_exists);
|
||||
IO::fwrite($autoload_path, $autoload_src);
|
||||
}
|
||||
|
||||
|
@ -268,6 +286,7 @@
|
|||
*
|
||||
* @param string $src
|
||||
* @param string $output
|
||||
* @param bool $ignore_units
|
||||
* @return string
|
||||
* @throws AccessDeniedException
|
||||
* @throws CollectorException
|
||||
|
@ -275,7 +294,7 @@
|
|||
* @throws IOException
|
||||
* @throws NoUnitsFoundException
|
||||
*/
|
||||
private function generateAutoload(string $src, string $output): string
|
||||
private function generateAutoload(string $src, string $output, bool $ignore_units=false): string
|
||||
{
|
||||
// Construct configuration
|
||||
$configuration = new Config([$src]);
|
||||
|
@ -286,6 +305,7 @@
|
|||
// Official PHP file extensions that are missing from the default configuration (whatever)
|
||||
$configuration->setInclude(ComponentFileExtensions::Php);
|
||||
$configuration->setQuietMode(true);
|
||||
$configuration->setTolerantMode(true);
|
||||
|
||||
// Construct factory
|
||||
$factory = new Factory();
|
||||
|
@ -295,7 +315,7 @@
|
|||
$result = self::runCollector($factory, $configuration);
|
||||
|
||||
// Exception raises when there are no files in the project that can be processed by the autoloader
|
||||
if(!$result->hasUnits())
|
||||
if(!$result->hasUnits() && !$ignore_units)
|
||||
{
|
||||
throw new NoUnitsFoundException('No units were found in the project');
|
||||
}
|
|
@ -15,7 +15,7 @@
|
|||
use ncc\Utilities\Base64;
|
||||
use ncc\Utilities\IO;
|
||||
|
||||
class Runner implements RunnerInterface
|
||||
class PhpRunner implements RunnerInterface
|
||||
{
|
||||
/**
|
||||
* @param string $path
|
27
src/ncc/Exceptions/ComposerDisabledException.php
Normal file
27
src/ncc/Exceptions/ComposerDisabledException.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class ComposerDisabledException extends \Exception
|
||||
{
|
||||
/**
|
||||
* @var Throwable|null
|
||||
*/
|
||||
private ?Throwable $previous;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::ComposerDisabledException, $previous);
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
}
|
28
src/ncc/Exceptions/ComposerException.php
Normal file
28
src/ncc/Exceptions/ComposerException.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class ComposerException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var Throwable|null
|
||||
*/
|
||||
private ?Throwable $previous;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::ComposerException, $previous);
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
}
|
28
src/ncc/Exceptions/ComposerNotAvailableException.php
Normal file
28
src/ncc/Exceptions/ComposerNotAvailableException.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
|
||||
class ComposerNotAvailableException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
private $previous;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param $previous
|
||||
*/
|
||||
public function __construct(string $message = "", $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::ComposerNotAvailableException, $previous);
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
}
|
28
src/ncc/Exceptions/InternalComposerNotAvailableException.php
Normal file
28
src/ncc/Exceptions/InternalComposerNotAvailableException.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class InternalComposerNotAvailableException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var Throwable|null
|
||||
*/
|
||||
private ?Throwable $previous;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::InternalComposerNotAvailable, $previous);
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
}
|
28
src/ncc/Exceptions/MissingDependencyException.php
Normal file
28
src/ncc/Exceptions/MissingDependencyException.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class MissingDependencyException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var Throwable|null
|
||||
*/
|
||||
private ?Throwable $previous;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::MissingDependencyException, $previous);
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
}
|
28
src/ncc/Exceptions/UserAbortedOperationException.php
Normal file
28
src/ncc/Exceptions/UserAbortedOperationException.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpPropertyOnlyWrittenInspection */
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class UserAbortedOperationException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var Throwable|null
|
||||
*/
|
||||
private ?Throwable $previous;
|
||||
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::UserAbortedOperationException, $previous);
|
||||
$this->message = $message;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
}
|
18
src/ncc/Interfaces/RemoteSourceInterface.php
Normal file
18
src/ncc/Interfaces/RemoteSourceInterface.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Interfaces;
|
||||
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
|
||||
interface RemoteSourceInterface
|
||||
{
|
||||
/**
|
||||
* Fetches a package and all it's dependencies from the given remote source
|
||||
* and optionally converts and compiles it to a local package, returns the
|
||||
* fetched package as a path to the ncc package file
|
||||
*
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @return string
|
||||
*/
|
||||
public static function fetch(RemotePackageInput $packageInput): string;
|
||||
}
|
|
@ -1,16 +1,342 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Managers;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\LogLevel;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\ThirdParty\Symfony\Yaml\Yaml;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\RuntimeCache;
|
||||
|
||||
class ConfigurationManager
|
||||
{
|
||||
/**
|
||||
* Public Constructor
|
||||
* The configuration contents parsed
|
||||
*
|
||||
* @param string $package
|
||||
* @var mixed
|
||||
*/
|
||||
public function __construct(string $package)
|
||||
private $Configuration;
|
||||
|
||||
/**
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws InvalidScopeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->Package = $package;
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file if it exists
|
||||
*
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws InvalidScopeException
|
||||
*/
|
||||
public function load(): void
|
||||
{
|
||||
$this->Configuration = RuntimeCache::get('ncc.yaml');
|
||||
if($this->Configuration !== null)
|
||||
return;
|
||||
$configuration_contents = IO::fread(PathFinder::getConfigurationFile());
|
||||
$this->Configuration = Yaml::parse($configuration_contents);
|
||||
RuntimeCache::set('ncc.yaml', $this->Configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration file to disk
|
||||
*
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
* @throws IOException
|
||||
* @throws InvalidScopeException
|
||||
*/
|
||||
public function save(): void
|
||||
{
|
||||
if(Resolver::resolveScope() !== Scopes::System)
|
||||
throw new AccessDeniedException('Cannot save configuration file, insufficient permissions');
|
||||
|
||||
if($this->Configuration == null)
|
||||
return;
|
||||
|
||||
IO::fwrite(PathFinder::getConfigurationFile(), Yaml::dump($this->Configuration), 0755);
|
||||
RuntimeCache::set('ncc.yaml', $this->Configuration);
|
||||
RuntimeCache::set('config_cache', []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a property
|
||||
* Returns null even if the property value exists & it's value is null
|
||||
*
|
||||
* @param string $property
|
||||
* @return mixed|null
|
||||
* @noinspection PhpMissingReturnTypeInspection
|
||||
*/
|
||||
public function getProperty(string $property)
|
||||
{
|
||||
$current_selection = $this->getConfiguration();
|
||||
foreach(explode('.', strtolower($property)) as $property)
|
||||
{
|
||||
$value_found = false;
|
||||
foreach($current_selection as $key => $value)
|
||||
{
|
||||
if($key == $property)
|
||||
{
|
||||
$current_selection = $value;
|
||||
$value_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$value_found)
|
||||
return null;
|
||||
}
|
||||
|
||||
return $current_selection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param $value
|
||||
* @return bool
|
||||
* @throws AccessDeniedException
|
||||
* @throws IOException
|
||||
* @throws InvalidScopeException
|
||||
*/
|
||||
public function updateProperty(string $property, $value): bool
|
||||
{
|
||||
// composer.options.quiet
|
||||
$result = match (strtolower(explode('.', $property)[0]))
|
||||
{
|
||||
'ncc' => $this->updateNccProperties($property, $value),
|
||||
'php' => $this->updatePhpProperties($property, $value),
|
||||
'git' => $this->updateGitProperties($property, $value),
|
||||
'runners' => $this->updateRunnerProperties($property, $value),
|
||||
'composer' => $this->updateComposerProperties($property, $value),
|
||||
default => false,
|
||||
};
|
||||
|
||||
$this->save();
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates NCC configuration properties in the configuration
|
||||
*
|
||||
* @param string $property
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function updateNccProperties(string $property, $value): bool
|
||||
{
|
||||
$delete = false;
|
||||
if(is_null($value))
|
||||
$delete = true;
|
||||
|
||||
switch(strtolower($property))
|
||||
{
|
||||
case 'ncc.cli.no_colors':
|
||||
$this->Configuration['ncc']['cli']['no_colors'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'ncc.cli.basic_ascii':
|
||||
$this->Configuration['ncc']['cli']['basic_ascii'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'ncc.cli.logging':
|
||||
$this->Configuration['ncc']['cli']['logging'] = ($delete ? LogLevel::Info : (string)$value);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates PHP properties in the configuraiton
|
||||
*
|
||||
* @param string $property
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function updatePhpProperties(string $property, $value): bool
|
||||
{
|
||||
$delete = false;
|
||||
if(is_null($value))
|
||||
$delete = true;
|
||||
|
||||
switch(strtolower($property))
|
||||
{
|
||||
case 'php.executable_path':
|
||||
$this->Configuration['php']['executable_path'] = ($delete ? null : (string)$value);
|
||||
break;
|
||||
case 'php.runtime.initialize_on_require':
|
||||
$this->Configuration['php']['runtime']['initialize_on_require'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'php.runtime.handle_exceptions':
|
||||
$this->Configuration['php']['runtime']['handle_exceptions'] = Functions::cbool($value);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updated git properties
|
||||
*
|
||||
* @param string $property
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function updateGitProperties(string $property, $value): bool
|
||||
{
|
||||
$delete = false;
|
||||
if(is_null($value))
|
||||
$delete = true;
|
||||
|
||||
switch(strtolower($property))
|
||||
{
|
||||
case 'git.enabled':
|
||||
$this->Configuration['git']['enabled'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'git.executable_path':
|
||||
$this->Configuration['git']['executable_path'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updaters runner properties
|
||||
*
|
||||
* @param string $property
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function updateRunnerProperties(string $property, $value): bool
|
||||
{
|
||||
$delete = false;
|
||||
if(is_null($value))
|
||||
$delete = true;
|
||||
|
||||
switch(strtolower($property))
|
||||
{
|
||||
case 'runners.php':
|
||||
$this->Configuration['runners']['php'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
case 'runners.bash':
|
||||
$this->Configuration['runners']['bash'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
case 'runners.sh':
|
||||
$this->Configuration['runners']['sh'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
case 'runners.python':
|
||||
$this->Configuration['runners']['python'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
case 'runners.python3':
|
||||
$this->Configuration['runners']['python3'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
case 'runners.python2':
|
||||
$this->Configuration['runners']['python2'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a composer property value
|
||||
*
|
||||
* @param string $property
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
private function updateComposerProperties(string $property, $value): bool
|
||||
{
|
||||
$delete = false;
|
||||
if(is_null($value))
|
||||
$delete = true;
|
||||
|
||||
switch(strtolower($property))
|
||||
{
|
||||
case 'composer.enabled':
|
||||
$this->Configuration['composer']['enabled'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.enable_internal_composer':
|
||||
$this->Configuration['composer']['enable_internal_composer'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.executable_path':
|
||||
$this->Configuration['composer']['executable_path'] = ($delete? null : (string)$value);
|
||||
break;
|
||||
case 'composer.options.quiet':
|
||||
$this->Configuration['composer']['options']['quiet'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.options.no_ansi':
|
||||
$this->Configuration['composer']['options']['no_ansi'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.options.no_interaction':
|
||||
$this->Configuration['composer']['options']['no_interaction'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.options.profile':
|
||||
$this->Configuration['composer']['options']['profile'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.options.no_scripts':
|
||||
$this->Configuration['composer']['options']['no_scripts'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.options.no_cache':
|
||||
$this->Configuration['composer']['options']['no_cache'] = Functions::cbool($value);
|
||||
break;
|
||||
case 'composer.options.logging':
|
||||
$this->Configuration['composer']['options']['logging'] = ((int)$value > 0 ? (int)$value : 1);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
private function getConfiguration(): mixed
|
||||
{
|
||||
if($this->Configuration == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->load();
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$this->Configuration = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $this->Configuration;
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
use Exception;
|
||||
use ncc\Abstracts\Runners;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Classes\PhpExtension\Runner;
|
||||
use ncc\Classes\PhpExtension\PhpRunner;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\ExecutionUnitNotFoundException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
|
@ -140,7 +140,7 @@
|
|||
|
||||
$bin_file = $package_bin_path . DIRECTORY_SEPARATOR . hash('haval128,4', $unit->ExecutionPolicy->Name);
|
||||
$bin_file .= match ($unit->ExecutionPolicy->Runner) {
|
||||
Runners::php => Runner::getFileExtension(),
|
||||
Runners::php => PhpRunner::getFileExtension(),
|
||||
default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'),
|
||||
};
|
||||
|
||||
|
@ -272,7 +272,7 @@
|
|||
|
||||
$process = match (strtolower($unit->ExecutionPolicy->Runner))
|
||||
{
|
||||
Runners::php => Runner::prepareProcess($unit),
|
||||
Runners::php => PhpRunner::prepareProcess($unit),
|
||||
default => throw new UnsupportedRunnerException('The runner \'' . $unit->ExecutionPolicy->Runner . '\' is not supported'),
|
||||
};
|
||||
|
||||
|
|
|
@ -56,8 +56,10 @@
|
|||
*/
|
||||
public function load(): void
|
||||
{
|
||||
Console::outDebug(sprintf('loading PackageLock from \'%s\'', $this->PackageLockPath));
|
||||
if(RuntimeCache::get($this->PackageLockPath) !== null)
|
||||
{
|
||||
Console::outDebug('package lock is cached, loading from cache');
|
||||
$this->PackageLock = RuntimeCache::get($this->PackageLockPath);
|
||||
return;
|
||||
}
|
||||
|
@ -66,7 +68,7 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
Console::outDebug('reading package lock file');
|
||||
Console::outDebug('package lock exists, loading from disk');
|
||||
$data = IO::fread($this->PackageLockPath);
|
||||
if(strlen($data) > 0)
|
||||
{
|
||||
|
@ -84,9 +86,11 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
Console::outDebug('package lock file does not exist, creating new package lock');
|
||||
$this->PackageLock = new PackageLock();
|
||||
}
|
||||
|
||||
Console::outDebug('caching PackageLock');
|
||||
RuntimeCache::set($this->PackageLockPath, $this->PackageLock);
|
||||
}
|
||||
|
||||
|
@ -99,15 +103,21 @@
|
|||
*/
|
||||
public function save(): void
|
||||
{
|
||||
Console::outDebug(sprintf('saving package lock to \'%s\'', $this->PackageLockPath));
|
||||
|
||||
// Don't save something that isn't loaded lol
|
||||
if($this->PackageLock == null)
|
||||
{
|
||||
Console::outDebug('warning: PackageLock is null, not saving to disk');
|
||||
return;
|
||||
}
|
||||
|
||||
if(Resolver::resolveScope() !== Scopes::System)
|
||||
throw new AccessDeniedException('Cannot write to PackageLock, insufficient permissions');
|
||||
|
||||
try
|
||||
{
|
||||
Console::outDebug(sprintf('saving PackageLock to \'%s\' & caching', $this->PackageLockPath));
|
||||
IO::fwrite($this->PackageLockPath, ZiProto::encode($this->PackageLock->toArray(true)), 0755);
|
||||
RuntimeCache::set($this->PackageLockPath, $this->PackageLock);
|
||||
}
|
||||
|
|
|
@ -7,16 +7,19 @@
|
|||
use Exception;
|
||||
use ncc\Abstracts\CompilerExtensions;
|
||||
use ncc\Abstracts\ConstantReferences;
|
||||
use ncc\Abstracts\DependencySourceType;
|
||||
use ncc\Abstracts\LogLevel;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Classes\NccExtension\PackageCompiler;
|
||||
use ncc\Classes\PhpExtension\Installer;
|
||||
use ncc\Classes\PhpExtension\PhpInstaller;
|
||||
use ncc\CLI\Main;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InstallationException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\MissingDependencyException;
|
||||
use ncc\Exceptions\NotImplementedException;
|
||||
use ncc\Exceptions\PackageAlreadyInstalledException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Exceptions\PackageNotFoundException;
|
||||
|
@ -28,12 +31,14 @@
|
|||
use ncc\Objects\Package;
|
||||
use ncc\Objects\PackageLock\PackageEntry;
|
||||
use ncc\Objects\PackageLock\VersionEntry;
|
||||
use ncc\Objects\ProjectConfiguration\Dependency;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\Validate;
|
||||
use ncc\ZiProto\ZiProto;
|
||||
use SplFileInfo;
|
||||
|
||||
|
@ -63,37 +68,39 @@
|
|||
/**
|
||||
* Installs a local package onto the system
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $package_path
|
||||
* @return string
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws InstallationException
|
||||
* @throws MissingDependencyException
|
||||
* @throws NotImplementedException
|
||||
* @throws PackageAlreadyInstalledException
|
||||
* @throws PackageLockException
|
||||
* @throws PackageNotFoundException
|
||||
* @throws PackageParsingException
|
||||
* @throws UnsupportedCompilerExtensionException
|
||||
* @throws UnsupportedRunnerException
|
||||
* @throws VersionNotFoundException
|
||||
*/
|
||||
public function install(string $input): string
|
||||
public function install(string $package_path): string
|
||||
{
|
||||
if(Resolver::resolveScope() !== Scopes::System)
|
||||
throw new AccessDeniedException('Insufficient permission to install packages');
|
||||
|
||||
Console::outVerbose(sprintf('Installing %s', $input));
|
||||
if(!file_exists($input) || !is_file($input) || !is_readable($input))
|
||||
throw new FileNotFoundException('The specified file \'' . $input .' \' does not exist or is not readable.');
|
||||
if(!file_exists($package_path) || !is_file($package_path) || !is_readable($package_path))
|
||||
throw new FileNotFoundException('The specified file \'' . $package_path .' \' does not exist or is not readable.');
|
||||
|
||||
$package = Package::load($input);
|
||||
$package = Package::load($package_path);
|
||||
|
||||
if($this->getPackageVersion($package->Assembly->Package, $package->Assembly->Version) !== null)
|
||||
throw new PackageAlreadyInstalledException('The package ' . $package->Assembly->Package . '==' . $package->Assembly->Version . ' is already installed');
|
||||
throw new PackageAlreadyInstalledException('The package ' . $package->Assembly->Package . '=' . $package->Assembly->Version . ' is already installed');
|
||||
|
||||
$extension = $package->Header->CompilerExtension->Extension;
|
||||
$installation_paths = new InstallationPaths($this->PackagesPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '==' . $package->Assembly->Version);
|
||||
$installation_paths = new InstallationPaths($this->PackagesPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '=' . $package->Assembly->Version);
|
||||
$installer = match ($extension) {
|
||||
CompilerExtensions::PHP => new Installer($package),
|
||||
CompilerExtensions::PHP => new PhpInstaller($package),
|
||||
default => throw new UnsupportedCompilerExtensionException('The compiler extension \'' . $extension . '\' is not supported'),
|
||||
};
|
||||
$execution_pointer_manager = new ExecutionPointerManager();
|
||||
|
@ -101,7 +108,16 @@
|
|||
ConstantReferences::Install => $installation_paths
|
||||
]);
|
||||
|
||||
Console::outVerbose(sprintf('Successfully parsed %s', $package->Assembly->Package));
|
||||
// Process all the required dependencies before installing the package
|
||||
if($package->Dependencies !== null && count($package->Dependencies) > 0)
|
||||
{
|
||||
foreach($package->Dependencies as $dependency)
|
||||
{
|
||||
$this->processDependency($dependency, $package, $package_path);
|
||||
}
|
||||
}
|
||||
|
||||
Console::outVerbose(sprintf('Installing %s', $package_path));
|
||||
|
||||
if(Resolver::checkLogLevel(LogLevel::Debug, Main::getLogLevel()))
|
||||
{
|
||||
|
@ -292,6 +308,71 @@
|
|||
return $package->Assembly->Package;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Dependency $dependency
|
||||
* @param Package $package
|
||||
* @param string $package_path
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
* @throws InstallationException
|
||||
* @throws MissingDependencyException
|
||||
* @throws NotImplementedException
|
||||
* @throws PackageAlreadyInstalledException
|
||||
* @throws PackageLockException
|
||||
* @throws PackageNotFoundException
|
||||
* @throws PackageParsingException
|
||||
* @throws UnsupportedCompilerExtensionException
|
||||
* @throws UnsupportedRunnerException
|
||||
* @throws VersionNotFoundException
|
||||
*/
|
||||
private function processDependency(Dependency $dependency, Package $package, string $package_path): void
|
||||
{
|
||||
Console::outVerbose('processing dependency ' . $dependency->Name . ' (' . $dependency->Version . ')');
|
||||
$dependent_package = $this->getPackage($dependency->Name);
|
||||
$dependency_met = false;
|
||||
|
||||
if ($dependent_package !== null && $dependency->Version !== null && Validate::version($dependency->Version))
|
||||
{
|
||||
$dependent_version = $this->getPackageVersion($dependency->Name, $dependency->Version);
|
||||
if ($dependent_version !== null)
|
||||
$dependency_met = true;
|
||||
}
|
||||
elseif ($dependent_package !== null && $dependency->Version == null)
|
||||
{
|
||||
$dependency_met = true;
|
||||
}
|
||||
|
||||
if ($dependency->SourceType !== null)
|
||||
{
|
||||
if(!$dependency_met)
|
||||
{
|
||||
Console::outVerbose(sprintf('Installing dependency %s=%s for %s=%s', $dependency->Name, $dependency->Version, $package->Assembly->Package, $package->Assembly->Version));
|
||||
switch ($dependency->SourceType)
|
||||
{
|
||||
case DependencySourceType::Local:
|
||||
Console::outDebug('installing from local source ' . $dependency->Source);
|
||||
$basedir = dirname($package_path);
|
||||
if (!file_exists($basedir . DIRECTORY_SEPARATOR . $dependency->Source))
|
||||
throw new FileNotFoundException($basedir . DIRECTORY_SEPARATOR . $dependency->Source);
|
||||
$this->install($basedir . DIRECTORY_SEPARATOR . $dependency->Source);
|
||||
break;
|
||||
|
||||
case DependencySourceType::StaticLinking:
|
||||
throw new PackageNotFoundException('Static linking not possible, package ' . $dependency->Name . ' is not installed');
|
||||
|
||||
default:
|
||||
throw new NotImplementedException('Dependency source type ' . $dependency->SourceType . ' is not implemented');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new MissingDependencyException(sprintf('The dependency %s=%s for %s=%s is not met', $dependency->Name, $dependency->Version, $package->Assembly->Package, $package->Assembly->Version));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an existing package entry, returns null if no such entry exists
|
||||
*
|
||||
|
@ -344,6 +425,82 @@
|
|||
return $this->getPackageLockManager()->getPackageLock()->getPackages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a package tree representation
|
||||
*
|
||||
* @param array $tree
|
||||
* @param string|null $package
|
||||
* @return array
|
||||
*/
|
||||
public function getPackageTree(array $tree=[], ?string $package=null): array
|
||||
{
|
||||
// First build the packages to scan first
|
||||
$packages = [];
|
||||
if($package !== null)
|
||||
{
|
||||
// If it's coming from a selected package, query the package and process its dependencies
|
||||
$exploded = explode('=', $package);
|
||||
try
|
||||
{
|
||||
foreach ($this->getPackage($exploded[0])?->getVersion($exploded[1])?->Dependencies as $dependency)
|
||||
{
|
||||
if(!in_array($dependency->PackageName . '=' . $dependency->Version, $tree))
|
||||
$packages[] = $dependency->PackageName . '=' . $dependency->Version;
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's coming from nothing, start with the installed packages on the system
|
||||
try
|
||||
{
|
||||
foreach ($this->getInstalledPackages() as $installed_package => $versions)
|
||||
{
|
||||
foreach ($versions as $version)
|
||||
{
|
||||
if (!in_array($installed_package . '=' . $version, $packages))
|
||||
$packages[] = $installed_package . '=' . $version;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (PackageLockException $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
}
|
||||
|
||||
// Go through each package
|
||||
foreach($packages as $package)
|
||||
{
|
||||
$package_e = explode('=', $package);
|
||||
try
|
||||
{
|
||||
$version_entry = $this->getPackageVersion($package_e[0], $package_e[1]);
|
||||
$tree[$package] = null;
|
||||
if($version_entry->Dependencies !== null && count($version_entry->Dependencies) > 0)
|
||||
{
|
||||
$tree[$package] = [];
|
||||
foreach($version_entry->Dependencies as $dependency)
|
||||
{
|
||||
$dependency_name = sprintf('%s=%s', $dependency->PackageName, $dependency->Version);
|
||||
$tree[$package] = $this->getPackageTree($tree[$package], $dependency_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
}
|
||||
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstalls a package version
|
||||
*
|
||||
|
@ -364,10 +521,10 @@
|
|||
|
||||
$version_entry = $this->getPackageVersion($package, $version);
|
||||
if($version_entry == null)
|
||||
throw new PackageNotFoundException(sprintf('The package %s==%s was not found', $package, $version));
|
||||
throw new PackageNotFoundException(sprintf('The package %s=%s was not found', $package, $version));
|
||||
|
||||
Console::out(sprintf('Uninstalling %s==%s', $package, $version));
|
||||
Console::outVerbose(sprintf('Removing package %s==%s from PackageLock', $package, $version));
|
||||
Console::out(sprintf('Uninstalling %s=%s', $package, $version));
|
||||
Console::outVerbose(sprintf('Removing package %s=%s from PackageLock', $package, $version));
|
||||
if(!$this->getPackageLockManager()->getPackageLock()->removePackageVersion($package, $version))
|
||||
Console::outDebug('warning: removing package from package lock failed');
|
||||
|
||||
|
@ -431,7 +588,7 @@
|
|||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outDebug(sprintf('warning: unable to uninstall package %s==%s, %s (%s)', $package, $version_entry->Version, $e->getMessage(), $e->getCode()));
|
||||
Console::outDebug(sprintf('warning: unable to uninstall package %s=%s, %s (%s)', $package, $version_entry->Version, $e->getMessage(), $e->getCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
534
src/ncc/Objects/ComposerJson.php
Normal file
534
src/ncc/Objects/ComposerJson.php
Normal file
|
@ -0,0 +1,534 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
use ncc\Abstracts\ComposerPackageTypes;
|
||||
use ncc\Abstracts\ComposerStabilityTypes;
|
||||
use ncc\Objects\ComposerJson\Author;
|
||||
use ncc\Objects\ComposerJson\Autoloader;
|
||||
use ncc\Objects\ComposerJson\PackageLink;
|
||||
use ncc\Objects\ComposerJson\Suggestion;
|
||||
use ncc\Objects\ComposerJson\Support;
|
||||
|
||||
class ComposerJson
|
||||
{
|
||||
/**
|
||||
* The name of the package, it consists of
|
||||
* the vendor name and project name, seperated by `/`
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Name;
|
||||
|
||||
/**
|
||||
* A short description of the package. Usually
|
||||
* this is one line long
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Description;
|
||||
|
||||
/**
|
||||
* The version of the package, in most cases this is not
|
||||
* required and should be omitted.
|
||||
*
|
||||
* If the package repository can infer the version from
|
||||
* somewhere. such as the VCS tag name in the VCS repository.
|
||||
* In the case it is also recommended to omit it
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Version;
|
||||
|
||||
/**
|
||||
* The type of package, it defaults to library
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Type;
|
||||
|
||||
/**
|
||||
* An array of keywords that the package is related to.
|
||||
* These can be used for searching and filtering
|
||||
*
|
||||
* Examples
|
||||
* - logging
|
||||
* - events
|
||||
* - database
|
||||
* - redis
|
||||
* - templating
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
public $Keywords;
|
||||
|
||||
/**
|
||||
* A URL to the website of the project
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Homepage;
|
||||
|
||||
/**
|
||||
* A relative path to the readme document
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Readme;
|
||||
|
||||
/**
|
||||
* Release date of the version
|
||||
*
|
||||
* YYY-MM-DD format or YYY-MM-DD HH:MM:SS
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Time;
|
||||
|
||||
/**
|
||||
* The license of the package. This can either be a string or
|
||||
* an array of strings
|
||||
*
|
||||
* @var string|string[]|null
|
||||
*/
|
||||
public $License;
|
||||
|
||||
/**
|
||||
* @var Author[]|null
|
||||
*/
|
||||
public $Authors;
|
||||
|
||||
/**
|
||||
* @var Support|null
|
||||
*/
|
||||
public $Support;
|
||||
|
||||
/**
|
||||
* Map of packages required by this package. The package
|
||||
* will not be installed unless those requirements can be met
|
||||
*
|
||||
* @var PackageLink[]|null
|
||||
*/
|
||||
public $Require;
|
||||
|
||||
/**
|
||||
* Map of packages required for developing this package, or running tests,
|
||||
* etc. The dev requirements of the root package are installed by default.
|
||||
* Both install or update support the --no-dev option that prevents dev
|
||||
* dependencies from being installed.
|
||||
*
|
||||
* @var PackageLink[]|null
|
||||
*/
|
||||
public $RequireDev;
|
||||
|
||||
/**
|
||||
* Map of packages that conflict with this version of this package. They will
|
||||
* not be allowed to be installed together with your package.
|
||||
*
|
||||
* @var PackageLink[]|null
|
||||
*/
|
||||
public $Conflict;
|
||||
|
||||
/**
|
||||
* Map of packages that are replaced by this package. This allows you to fork a
|
||||
* package, publish it under a different name with its own version numbers,
|
||||
* while packages requiring the original package continue to work with your fork
|
||||
* because it replaces the original package.
|
||||
*
|
||||
* @var PackageLink[]|null
|
||||
*/
|
||||
public $Replace;
|
||||
|
||||
/**
|
||||
* Map of packages that are provided by this package. This is mostly useful for
|
||||
* implementations of common interfaces. A package could depend on some virtual
|
||||
* package e.g. psr/logger-implementation, any library that implements this logger
|
||||
* interface would list it in provide. Implementors can then be found on Packagist.org.
|
||||
*
|
||||
* @var PackageLink[]|null
|
||||
*/
|
||||
public $Provide;
|
||||
|
||||
/**
|
||||
* Suggested packages that can enhance or work well with this package. These are
|
||||
* informational and are displayed after the package is installed, to give your
|
||||
* users a hint that they could add more packages, even though they are not strictly
|
||||
* required.
|
||||
*
|
||||
* @var Suggestion[]|null
|
||||
*/
|
||||
public $Suggest;
|
||||
|
||||
/**
|
||||
* Autoload mapping for a PHP autoloader.
|
||||
*
|
||||
* @var Autoloader|null
|
||||
*/
|
||||
public $Autoload;
|
||||
|
||||
/**
|
||||
* This section allows defining autoload rules for development purposes.
|
||||
*
|
||||
* @var Autoloader|null
|
||||
*/
|
||||
public $AutoloadDev;
|
||||
|
||||
/**
|
||||
* A list of paths which should get appended to PHP's include_path.
|
||||
*
|
||||
* @var string[]|null
|
||||
*/
|
||||
public $IncludePath;
|
||||
|
||||
/**
|
||||
* Defines the installation target.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $TargetDirectory;
|
||||
|
||||
/**
|
||||
* This defines the default behavior for filtering packages by
|
||||
* stability. This defaults to stable, so if you rely on a dev package,
|
||||
* you should specify it in your file to avoid surprises.
|
||||
*
|
||||
* All versions of each package are checked for stability, and those that
|
||||
* are less stable than the minimum-stability setting will be ignored when
|
||||
* resolving your project dependencies. (Note that you can also specify
|
||||
* stability requirements on a per-package basis using stability flags
|
||||
* in the version constraints that you specify in a require block
|
||||
*
|
||||
* @var ComposerPackageTypes|null
|
||||
*/
|
||||
public $MinimumStability;
|
||||
|
||||
/**
|
||||
* When this is enabled, Composer will prefer more stable packages over
|
||||
* unstable ones when finding compatible stable packages is possible.
|
||||
* If you require a dev version or only alphas are available for a package,
|
||||
* those will still be selected granted that the minimum-stability allows for it.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $PreferStable;
|
||||
|
||||
/**
|
||||
* Custom package repositories to use.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Repositories;
|
||||
|
||||
/**
|
||||
* A set of configuration options. It is only used for projects.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Configuration;
|
||||
|
||||
/**
|
||||
* Composer allows you to hook into various parts of the installation
|
||||
* process through the use of scripts.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Scripts;
|
||||
|
||||
/**
|
||||
* Arbitrary extra data for consumption by scripts.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Extra;
|
||||
|
||||
/**
|
||||
* A set of files that should be treated as binaries and made available into the bin-dir (from config).
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Bin;
|
||||
|
||||
/**
|
||||
* A set of options for creating package archives.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Archive;
|
||||
|
||||
/**
|
||||
* Indicates whether this package has been abandoned.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $Abandoned;
|
||||
|
||||
/**
|
||||
* A list of regex patterns of branch names that are
|
||||
* non-numeric (e.g. "latest" or something), that will
|
||||
* NOT be handled as feature branches. This is an array
|
||||
* of strings.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $NonFeatureBranches;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->Type = ComposerPackageTypes::Library;
|
||||
$this->MinimumStability = ComposerStabilityTypes::Stable;
|
||||
$this->PreferStable = false;
|
||||
$this->Abandoned = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$_authors = null;
|
||||
if($this->Authors !== null && count($this->Authors) > 0)
|
||||
{
|
||||
$_authors = [];
|
||||
foreach($this->Authors as $author)
|
||||
{
|
||||
$_authors[] = $author->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
$_require = null;
|
||||
if($this->Require !== null && count($this->Require) > 0)
|
||||
{
|
||||
$_require = [];
|
||||
foreach($this->Require as $require)
|
||||
{
|
||||
$_require[$require->PackageName] = $require->Version;
|
||||
}
|
||||
}
|
||||
|
||||
$_require_dev = null;
|
||||
if($this->RequireDev !== null && count($this->RequireDev) > 0)
|
||||
{
|
||||
$_require_dev = [];
|
||||
foreach($this->RequireDev as $require)
|
||||
{
|
||||
$_require_dev[$require->PackageName] = $require->Version;
|
||||
}
|
||||
}
|
||||
|
||||
$_conflict = null;
|
||||
if($this->Conflict !== null && count($this->Conflict) > 0)
|
||||
{
|
||||
$_conflict = [];
|
||||
foreach($this->Conflict as $require)
|
||||
{
|
||||
$_conflict[$require->PackageName] = $require->Version;
|
||||
}
|
||||
}
|
||||
|
||||
$_replace = null;
|
||||
if($this->Replace !== null && count($this->Replace) > 0)
|
||||
{
|
||||
$_replace = [];
|
||||
foreach($this->Replace as $require)
|
||||
{
|
||||
$_replace[$require->PackageName] = $require->Version;
|
||||
}
|
||||
}
|
||||
|
||||
$_provide = null;
|
||||
if($this->Provide !== null && count($this->Provide) > 0)
|
||||
{
|
||||
$_provide = [];
|
||||
foreach($this->Provide as $require)
|
||||
{
|
||||
$_provide[$require->PackageName] = $require->Version;
|
||||
}
|
||||
}
|
||||
|
||||
$_suggest = null;
|
||||
if($this->Suggest !== null && count($this->Suggest) > 0)
|
||||
{
|
||||
$_suggest = [];
|
||||
foreach($this->Suggest as $suggestion)
|
||||
{
|
||||
$_suggest[$suggestion->PackageName] = $suggestion->Comment;
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $this->Name,
|
||||
'description' => $this->Description,
|
||||
'version' => $this->Version,
|
||||
'type' => $this->Type,
|
||||
'keywords' => $this->Keywords,
|
||||
'homepage' => $this->Homepage,
|
||||
'readme' => $this->Readme,
|
||||
'time' => $this->Time,
|
||||
'license' => $this->License,
|
||||
'authors' => $_authors,
|
||||
'support' => $this->Support?->toArray(),
|
||||
'require' => $_require,
|
||||
'require_dev' => $_require_dev,
|
||||
'conflict' => $_conflict,
|
||||
'replace' => $_replace,
|
||||
'provide' => $_provide,
|
||||
'suggest' => $_suggest,
|
||||
'autoload' => $this->Autoload?->toArray(),
|
||||
'autoload-dev' => $this->AutoloadDev?->toArray(),
|
||||
'include-path' => $this->IncludePath,
|
||||
'target-dir' => $this->TargetDirectory,
|
||||
'minimum-stability' => $this->MinimumStability,
|
||||
'repositories' => $this->Repositories,
|
||||
'config' => $this->Configuration,
|
||||
'scripts' => $this->Scripts,
|
||||
'extra' => $this->Extra,
|
||||
'bin' => $this->Bin,
|
||||
'archive' => $this->Archive,
|
||||
'abandoned' => $this->Abandoned,
|
||||
'non-feature-branches' => $this->NonFeatureBranches
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['name']))
|
||||
$object->Name = $data['name'];
|
||||
|
||||
if(isset($data['description']))
|
||||
$object->Description = $data['description'];
|
||||
|
||||
if(isset($data['version']))
|
||||
$object->Version = $data['version'];
|
||||
|
||||
if(isset($data['type']))
|
||||
$object->Type = $data['type'];
|
||||
|
||||
if(isset($data['keywords']))
|
||||
$object->Keywords = $data['keywords'];
|
||||
|
||||
if(isset($data['homepage']))
|
||||
$object->Homepage = $data['homepage'];
|
||||
|
||||
if(isset($data['readme']))
|
||||
$object->Readme = $data['readme'];
|
||||
|
||||
if(isset($data['time']))
|
||||
$object->Time = $data['time'];
|
||||
|
||||
if(isset($data['license']))
|
||||
$object->License = $data['license'];
|
||||
|
||||
if(isset($data['authors']))
|
||||
{
|
||||
$object->Authors = [];
|
||||
foreach($data['authors'] as $author)
|
||||
{
|
||||
$object->Authors[] = Author::fromArray($author);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['support']))
|
||||
$object->Support = Support::fromArray($data['support']);
|
||||
|
||||
if(isset($data['require']))
|
||||
{
|
||||
$object->Require = [];
|
||||
foreach($data['require'] as $package => $version)
|
||||
{
|
||||
$object->Require[] = new PackageLink($package, $version);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['require_dev']))
|
||||
{
|
||||
$object->RequireDev = [];
|
||||
foreach($data['require_dev'] as $package => $version)
|
||||
{
|
||||
$object->RequireDev[] = new PackageLink($package, $version);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['conflict']))
|
||||
{
|
||||
$object->Conflict = [];
|
||||
foreach($data['conflict'] as $package => $version)
|
||||
{
|
||||
$object->Conflict[] = new PackageLink($package, $version);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['replace']))
|
||||
{
|
||||
$object->Replace = [];
|
||||
foreach($data['replace'] as $package => $version)
|
||||
{
|
||||
$object->Replace[] = new PackageLink($package, $version);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['provide']))
|
||||
{
|
||||
$object->Provide = [];
|
||||
foreach($data['provide'] as $package => $version)
|
||||
{
|
||||
$object->Provide[] = new PackageLink($package, $version);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['suggest']))
|
||||
{
|
||||
$object->Suggest = [];
|
||||
foreach($data['suggest'] as $package => $comment)
|
||||
{
|
||||
$object->Suggest[] = new Suggestion($package, $comment);
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['autoload']))
|
||||
$object->Autoload = Autoloader::fromArray($data['autoload']);
|
||||
|
||||
if(isset($data['autoload-dev']))
|
||||
$object->AutoloadDev = Autoloader::fromArray($data['autoload-dev']);
|
||||
|
||||
if(isset($data['include-path']))
|
||||
$object->IncludePath = $data['include-path'];
|
||||
|
||||
if(isset($data['target-dir']))
|
||||
$object->TargetDirectory = $data['target-dir'];
|
||||
|
||||
if(isset($data['minimum-stability']))
|
||||
$object->MinimumStability = $data['minimum-stability'];
|
||||
|
||||
if(isset($data['repositories']))
|
||||
$object->Repositories = $data['repositories'];
|
||||
|
||||
if(isset($data['config']))
|
||||
$object->Configuration = $data['config'];
|
||||
|
||||
if(isset($data['scripts']))
|
||||
$object->Scripts = $data['scripts'];
|
||||
|
||||
if(isset($data['extra']))
|
||||
$object->Extra = $data['extra'];
|
||||
|
||||
if(isset($data['bin']))
|
||||
$object->Bin = $data['bin'];
|
||||
|
||||
if(isset($data['archive']))
|
||||
$object->Archive = $data['archive'];
|
||||
|
||||
if(isset($data['abandoned']))
|
||||
$object->Abandoned = $data['abandoned'];
|
||||
|
||||
if(isset($data['non-feature-branches']))
|
||||
$object->NonFeatureBranches = $data['non-feature-branches'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
76
src/ncc/Objects/ComposerJson/Author.php
Normal file
76
src/ncc/Objects/ComposerJson/Author.php
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class Author
|
||||
{
|
||||
/**
|
||||
* The author's name. Usually their real name
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Name;
|
||||
|
||||
/**
|
||||
* The author's email address
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Email;
|
||||
|
||||
/**
|
||||
* URL to the author's website
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Homepage;
|
||||
|
||||
/**
|
||||
* The author's role in the project (eg. developer or translator)
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Role;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->Name,
|
||||
'email' => $this->Email,
|
||||
'homepage' => $this->Homepage,
|
||||
'role' => $this->Role
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return Author
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['name']))
|
||||
$object->Name = $data['name'];
|
||||
|
||||
if(isset($data['email']))
|
||||
$object->Email = $data['email'];
|
||||
|
||||
if(isset($data['homepage']))
|
||||
$object->Homepage = $data['homepage'];
|
||||
|
||||
if(isset($data['role']))
|
||||
$object->Role = $data['role'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
154
src/ncc/Objects/ComposerJson/Autoloader.php
Normal file
154
src/ncc/Objects/ComposerJson/Autoloader.php
Normal file
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class Autoloader
|
||||
{
|
||||
|
||||
/**
|
||||
* @var NamespacePointer[]|null
|
||||
*/
|
||||
public $Psr4;
|
||||
|
||||
/**
|
||||
* @var NamespacePointer[]|null
|
||||
*/
|
||||
public $Psr0;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
public $Classmap;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
public $Files;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
public $ExcludeFromClassMap;
|
||||
|
||||
/**
|
||||
* @param array $psr
|
||||
* @param mixed $pointer
|
||||
* @return array
|
||||
*/
|
||||
private static function psrRestructure(array $psr, NamespacePointer $pointer): array
|
||||
{
|
||||
if (isset($psr[(string)$pointer->Namespace]))
|
||||
{
|
||||
if (!is_array($psr[(string)$pointer->Namespace]))
|
||||
{
|
||||
$r = [
|
||||
$psr[(string)$pointer->Namespace],
|
||||
$pointer->Path
|
||||
];
|
||||
|
||||
$psr[(string)$pointer->Namespace] = $r;
|
||||
}
|
||||
elseif (!in_array($pointer->Path, $psr[(string)$pointer->Namespace]))
|
||||
{
|
||||
$psr[(string)$pointer->Namespace][] = $pointer->Path;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$psr[(string)$pointer->Namespace] = $pointer->Path;
|
||||
}
|
||||
return $psr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$_psr4 = null;
|
||||
if($this->Psr4 !== null && count($this->Psr4) > 0)
|
||||
{
|
||||
$_psr4 = [];
|
||||
foreach($this->Psr4 as $_psr)
|
||||
$_psr4 = self::psrRestructure($_psr4, $_psr);
|
||||
}
|
||||
|
||||
$_psr0 = null;
|
||||
if($this->Psr0 !== null && count($this->Psr0) > 0)
|
||||
{
|
||||
$_psr0 = [];
|
||||
foreach($this->Psr0 as $_psr)
|
||||
$_psr4 = self::psrRestructure($_psr0, $_psr);
|
||||
}
|
||||
|
||||
return [
|
||||
'psr-4' => $_psr4,
|
||||
'psr-0' => $_psr0,
|
||||
'classmap' => $this->Classmap,
|
||||
'files' => $this->Files,
|
||||
'exclude-from-classmap' => $this->ExcludeFromClassMap,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['psr-4']))
|
||||
{
|
||||
$object->Psr4 = [];
|
||||
foreach($data['psr-4'] as $namespace => $path)
|
||||
{
|
||||
if(is_array($path))
|
||||
{
|
||||
foreach($path as $datum)
|
||||
{
|
||||
$object->Psr4[] = new NamespacePointer($namespace, $datum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$object->Psr4[] = new NamespacePointer($namespace, $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['psr-0']))
|
||||
{
|
||||
$object->Psr0 = [];
|
||||
foreach($data['psr-0'] as $namespace => $path)
|
||||
{
|
||||
if(is_array($path))
|
||||
{
|
||||
foreach($path as $datum)
|
||||
{
|
||||
$object->Psr0[] = new NamespacePointer($namespace, $datum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$object->Psr0[] = new NamespacePointer($namespace, $path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($data['classmap']))
|
||||
$object->Classmap = $data['classmap'];
|
||||
|
||||
if(isset($data['files']))
|
||||
$object->Files = $data['files'];
|
||||
|
||||
if(isset($data['exclude-from-classmap']))
|
||||
$object->ExcludeFromClassMap = $data['exclude-from-classmap'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
55
src/ncc/Objects/ComposerJson/Funding.php
Normal file
55
src/ncc/Objects/ComposerJson/Funding.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class Funding
|
||||
{
|
||||
/**
|
||||
* The type of funding, or the platform through which
|
||||
* funding can be provided. eg, patreon, opencollective,
|
||||
* tidelift or GitHub
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Type;
|
||||
|
||||
/**
|
||||
* URL to a website with details, and a way to fund
|
||||
* the package
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $URL;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'type' => $this->Type,
|
||||
'url' => $this->URL
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['type']))
|
||||
$object->Type = $data['type'];
|
||||
|
||||
if(isset($data['url']))
|
||||
$object->URL = $data['url'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
64
src/ncc/Objects/ComposerJson/NamespacePointer.php
Normal file
64
src/ncc/Objects/ComposerJson/NamespacePointer.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class NamespacePointer
|
||||
{
|
||||
/**
|
||||
* Namespace name that maps to the path route
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Namespace;
|
||||
|
||||
/**
|
||||
* The relative path to the source code to index
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Path;
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* @param string|null $name
|
||||
* @param string|null $path
|
||||
*/
|
||||
public function __construct(?string $name=null, ?string $path=null)
|
||||
{
|
||||
$this->Namespace = $name;
|
||||
$this->Path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'namespace' => $this->Namespace,
|
||||
'path' => $this->Path
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the object from an array representation
|
||||
*
|
||||
* @param array $array
|
||||
* @return static
|
||||
*/
|
||||
public static function fromArray(array $array): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($array['namespace']))
|
||||
$object->Namespace = $array['namespace'];
|
||||
|
||||
if(isset($array['path']))
|
||||
$object->Path = $array['path'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
62
src/ncc/Objects/ComposerJson/PackageLink.php
Normal file
62
src/ncc/Objects/ComposerJson/PackageLink.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class PackageLink
|
||||
{
|
||||
/**
|
||||
* The name of the package that is required
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $PackageName;
|
||||
|
||||
/**
|
||||
* The version of the package that is required
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Version;
|
||||
|
||||
/**
|
||||
* @param string|null $packageName
|
||||
* @param string|null $version
|
||||
*/
|
||||
public function __construct(?string $packageName=null, ?string $version=null)
|
||||
{
|
||||
$this->PackageName = $packageName;
|
||||
$this->Version = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'package_name' => $this->PackageName,
|
||||
'version' => $this->Version
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return PackageLink
|
||||
*/
|
||||
public static function fromArray(array $data): PackageLink
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['package_name']))
|
||||
$object->PackageName = $data['package_name'];
|
||||
|
||||
if(isset($data['version']))
|
||||
$object->Version = $data['version'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
62
src/ncc/Objects/ComposerJson/Suggestion.php
Normal file
62
src/ncc/Objects/ComposerJson/Suggestion.php
Normal file
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class Suggestion
|
||||
{
|
||||
/**
|
||||
* The name of the package suggestion
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $PackageName;
|
||||
|
||||
/**
|
||||
* The comment for the suggestion
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $Comment;
|
||||
|
||||
/**
|
||||
* @param string|null $packageName
|
||||
* @param string|null $comment
|
||||
*/
|
||||
public function __construct(?string $packageName=null, ?string $comment=null)
|
||||
{
|
||||
$this->PackageName = $packageName;
|
||||
$this->Comment = $comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'package_name' => $this->PackageName,
|
||||
'comment' => $this->Comment,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return Suggestion
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['package_name']))
|
||||
$object->PackageName = $data['package_name'];
|
||||
|
||||
if(isset($data['comment']))
|
||||
$object->Comment = $data['comment'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
129
src/ncc/Objects/ComposerJson/Support.php
Normal file
129
src/ncc/Objects/ComposerJson/Support.php
Normal file
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects\ComposerJson;
|
||||
|
||||
class Support
|
||||
{
|
||||
/**
|
||||
* Email address for support
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Email;
|
||||
|
||||
/**
|
||||
* URL to the issue tracker
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Issues;
|
||||
|
||||
/**
|
||||
* URL to the forum
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Forum;
|
||||
|
||||
/**
|
||||
* URL to the Wiki
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Wiki;
|
||||
|
||||
/**
|
||||
* The IRC channel for support, as irc://server/channel
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $IRC;
|
||||
|
||||
/**
|
||||
* URL to browse or download the sources
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Source;
|
||||
|
||||
/**
|
||||
* URL to the documentation
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Docs;
|
||||
|
||||
/**
|
||||
* URL to the RSS feed
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $RSS;
|
||||
|
||||
/**
|
||||
* URL to the chat channel
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Chat;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return [
|
||||
'email' => $this->Email,
|
||||
'issues' => $this->Issues,
|
||||
'forum' => $this->Forum,
|
||||
'wiki' => $this->Wiki,
|
||||
'irc' => $this->IRC,
|
||||
'source' => $this->Source,
|
||||
'docs' => $this->Docs,
|
||||
'rss' => $this->RSS,
|
||||
'chat' => $this->Chat
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return Support
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$object = new self();
|
||||
|
||||
if(isset($data['email']))
|
||||
$object->Email = $data['email'];
|
||||
|
||||
if(isset($data['issues']))
|
||||
$object->Issues = $data['issues'];
|
||||
|
||||
if(isset($data['forum']))
|
||||
$object->Forum = $data['forum'];
|
||||
|
||||
if(isset($data['wiki']))
|
||||
$object->Wiki = $data['wiki'];
|
||||
|
||||
if(isset($data['irc']))
|
||||
$object->IRC = $data['irc'];
|
||||
|
||||
if(isset($data['source']))
|
||||
$object->Source = $data['source'];
|
||||
|
||||
if(isset($data['docs']))
|
||||
$object->Docs = $data['docs'];
|
||||
|
||||
if(isset($data['rss']))
|
||||
$object->RSS = $data['rss'];
|
||||
|
||||
if(isset($data['chat']))
|
||||
$object->Chat = $data['chat'];
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
145
src/ncc/Objects/ComposerLock.php
Normal file
145
src/ncc/Objects/ComposerLock.php
Normal file
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
class ComposerLock
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $Readme;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ContentHash;
|
||||
|
||||
/**
|
||||
* @var ComposerJson[]|null
|
||||
*/
|
||||
public $Packages;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
public $PackagesDev;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
public $Aliases;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $MinimumStability;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
public $StabilityFlags;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $PreferStable;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $PreferLowest;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
public $Platform;
|
||||
|
||||
/**
|
||||
* @var array|null
|
||||
*/
|
||||
public $PlatformDev;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $PluginApiVersion;
|
||||
|
||||
/**
|
||||
* Returns an existing package from the lock file
|
||||
*
|
||||
* @param string $name
|
||||
* @return ComposerJson|null
|
||||
*/
|
||||
public function getPackage(string $name): ?ComposerJson
|
||||
{
|
||||
foreach($this->Packages as $package)
|
||||
{
|
||||
if($package->Name == $name)
|
||||
{
|
||||
return $package;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$_packages = [];
|
||||
if($this->Packages != null)
|
||||
{
|
||||
foreach($this->Packages as $package)
|
||||
$_packages[] = $package->toArray();
|
||||
}
|
||||
return [
|
||||
'_readme' => $this->Readme,
|
||||
'content-hash' => $this->ContentHash,
|
||||
'packages' => $_packages,
|
||||
'packages-dev' => $this->PackagesDev,
|
||||
'aliases' => $this->Aliases,
|
||||
'minimum-stability' => $this->MinimumStability,
|
||||
'stability-flags' => $this->StabilityFlags,
|
||||
'prefer-stable' => $this->PreferStable,
|
||||
'prefer-lowest' => $this->PreferLowest,
|
||||
'platform' => $this->Platform,
|
||||
'platform-dev' => $this->PlatformDev,
|
||||
'plugin-api-version' => $this->PluginApiVersion,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs object from an array representation
|
||||
*
|
||||
* @param array $data
|
||||
* @return static
|
||||
*/
|
||||
public static function fromArray(array $data): self
|
||||
{
|
||||
$obj = new self();
|
||||
$obj->Readme = $data['_readme'];
|
||||
$obj->ContentHash = $data['content-hash'];
|
||||
$obj->Packages = [];
|
||||
if($data['packages'] != null)
|
||||
{
|
||||
foreach($data['packages'] as $package)
|
||||
$obj->Packages[] = ComposerJson::fromArray($package);
|
||||
}
|
||||
$obj->PackagesDev = $data['packages-dev'];
|
||||
$obj->Aliases = $data['aliases'];
|
||||
$obj->MinimumStability = $data['minimum-stability'];
|
||||
$obj->StabilityFlags = $data['stability-flags'];
|
||||
$obj->PreferStable = $data['prefer-stable'];
|
||||
$obj->PreferLowest = $data['prefer-lowest'];
|
||||
$obj->Platform = $data['platform'];
|
||||
$obj->PlatformDev = $data['platform-dev'];
|
||||
$obj->PluginApiVersion = $data['plugin-api-version'];
|
||||
return $obj;
|
||||
}
|
||||
}
|
|
@ -344,7 +344,7 @@
|
|||
{
|
||||
foreach($_dependencies as $dependency)
|
||||
{
|
||||
$object->Dependencies[] = Resource::fromArray($dependency);
|
||||
$object->Dependencies[] = Dependency::fromArray($dependency);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,13 @@
|
|||
*/
|
||||
public $CompilerVersion;
|
||||
|
||||
/**
|
||||
* An array of options to pass on to the extension
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $Options;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
|
@ -37,6 +44,7 @@
|
|||
{
|
||||
$this->CompilerExtension = new Compiler();
|
||||
$this->RuntimeConstants = [];
|
||||
$this->Options = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,6 +59,7 @@
|
|||
($bytecode ? Functions::cbc('compiler_extension') : 'compiler_extension') => $this->CompilerExtension->toArray($bytecode),
|
||||
($bytecode ? Functions::cbc('runtime_constants') : 'runtime_constants') => $this->RuntimeConstants,
|
||||
($bytecode ? Functions::cbc('compiler_version') : 'compiler_version') => $this->CompilerVersion,
|
||||
($bytecode ? Functions::cbc('options') : 'options') => $this->Options,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -67,6 +76,7 @@
|
|||
$object->CompilerExtension = Functions::array_bc($data, 'compiler_extension');
|
||||
$object->RuntimeConstants = Functions::array_bc($data, 'runtime_constants');
|
||||
$object->CompilerVersion = Functions::array_bc($data, 'compiler_version');
|
||||
$object->Options = Functions::array_bc($data, 'options');
|
||||
|
||||
if($object->CompilerExtension !== null)
|
||||
$object->CompilerExtension = Compiler::fromArray($object->CompilerExtension);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace ncc\Objects\PackageLock;
|
||||
|
||||
use ncc\Objects\InstallationPaths;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\Compiler;
|
||||
use ncc\Utilities\Functions;
|
||||
|
@ -59,6 +60,16 @@
|
|||
$this->ExecutionUnits = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns installation paths
|
||||
*
|
||||
* @return InstallationPaths
|
||||
*/
|
||||
public function getInstallPaths(): InstallationPaths
|
||||
{
|
||||
return new InstallationPaths($this->Location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of the object
|
||||
*
|
||||
|
|
|
@ -153,7 +153,7 @@
|
|||
foreach($this->ExecutionPolicies as $execution_policy)
|
||||
{
|
||||
$defined_polices[] = $execution_policy->Name;
|
||||
$execution_policy->validate();
|
||||
//$execution_policy->validate();
|
||||
}
|
||||
|
||||
// Check the installer by batch
|
||||
|
@ -277,17 +277,28 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
$execution_policies = [];
|
||||
foreach($this->ExecutionPolicies as $executionPolicy)
|
||||
$execution_policies = null;
|
||||
if($this->ExecutionPolicies !== null)
|
||||
{
|
||||
$execution_policies[$executionPolicy->Name] = $executionPolicy->toArray($bytecode);
|
||||
$execution_policies = [];
|
||||
foreach($this->ExecutionPolicies as $executionPolicy)
|
||||
{
|
||||
$execution_policies[$executionPolicy->Name] = $executionPolicy->toArray($bytecode);
|
||||
}
|
||||
}
|
||||
return [
|
||||
($bytecode ? Functions::cbc('project') : 'project') => $this->Project->toArray($bytecode),
|
||||
($bytecode ? Functions::cbc('assembly') : 'assembly') => $this->Assembly->toArray($bytecode),
|
||||
($bytecode ? Functions::cbc('execution_policies') : 'execution_policies') => $execution_policies,
|
||||
($bytecode ? Functions::cbc('build') : 'build') => $this->Build->toArray($bytecode),
|
||||
];
|
||||
|
||||
$results = [];
|
||||
if($this->Project !== null)
|
||||
$results[($bytecode ? Functions::cbc('project') : 'project')] = $this->Project->toArray($bytecode);
|
||||
if($this->Assembly !== null)
|
||||
$results['assembly'] = $this->Assembly->toArray($bytecode);
|
||||
if($this->Build !== null)
|
||||
$results[($bytecode ? Functions::cbc('build') : 'build')] = $this->Build->toArray($bytecode);
|
||||
if($this->Installer !== null)
|
||||
$results[($bytecode ? Functions::cbc('installer') : 'installer')] = $this->Installer->toArray($bytecode);
|
||||
if($execution_policies !== null && count($execution_policies) > 0)
|
||||
$results[($bytecode ? Functions::cbc('execution_policies') : 'execution_policies')] = $execution_policies;
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -321,27 +332,21 @@
|
|||
{
|
||||
$ProjectConfigurationObject = new ProjectConfiguration();
|
||||
|
||||
$ProjectConfigurationObject->Project = Project::fromArray(Functions::array_bc($data, 'project'));
|
||||
$ProjectConfigurationObject->Assembly = Assembly::fromArray(Functions::array_bc($data, 'assembly'));
|
||||
$ProjectConfigurationObject->ExecutionPolicies = Functions::array_bc($data, 'execution_policies');
|
||||
$ProjectConfigurationObject->Build = Build::fromArray(Functions::array_bc($data, 'build'));
|
||||
$ProjectConfigurationObject->Installer = Functions::array_bc($data, 'installer');
|
||||
|
||||
if($ProjectConfigurationObject->Installer !== null)
|
||||
$ProjectConfigurationObject->Installer = Installer::fromArray($ProjectConfigurationObject->Installer);
|
||||
|
||||
if($ProjectConfigurationObject->ExecutionPolicies == null)
|
||||
if(isset($data['project']))
|
||||
$ProjectConfigurationObject->Project = Project::fromArray($data['project']);
|
||||
if(isset($data['assembly']))
|
||||
$ProjectConfigurationObject->Assembly = Assembly::fromArray($data['assembly']);
|
||||
if(isset($data['build']))
|
||||
$ProjectConfigurationObject->Build = Build::fromArray($data['build']);
|
||||
if(isset($data['installer']))
|
||||
$ProjectConfigurationObject->Installer = Installer::fromArray($data['installer']);
|
||||
if(isset($data['execution_policies']))
|
||||
{
|
||||
$ProjectConfigurationObject->ExecutionPolicies = [];
|
||||
}
|
||||
else
|
||||
{
|
||||
$policies = [];
|
||||
foreach($ProjectConfigurationObject->ExecutionPolicies as $policy)
|
||||
foreach($data['execution_policies'] as $execution_policy)
|
||||
{
|
||||
$policies[] = ExecutionPolicy::fromArray($policy);
|
||||
$ProjectConfigurationObject->ExecutionPolicies[] = ExecutionPolicy::fromArray($execution_policy);
|
||||
}
|
||||
$ProjectConfigurationObject->ExecutionPolicies = $policies;
|
||||
}
|
||||
|
||||
return $ProjectConfigurationObject;
|
||||
|
|
|
@ -167,17 +167,36 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
return [
|
||||
($bytecode ? Functions::cbc('name') : 'name') => $this->Name,
|
||||
($bytecode ? Functions::cbc('package') : 'package') => $this->Package,
|
||||
($bytecode ? Functions::cbc('description') : 'description') => ($this->Description !== null && strlen($this->Description) > 0 ? $this->Description : null),
|
||||
($bytecode ? Functions::cbc('company') : 'company') => ($this->Company !== null && strlen($this->Company) > 0 ? $this->Company : null),
|
||||
($bytecode ? Functions::cbc('product') : 'product') => ($this->Product !== null && strlen($this->Product) > 0 ? $this->Product : null),
|
||||
($bytecode ? Functions::cbc('copyright') : 'copyright') => ($this->Copyright !== null && strlen($this->Copyright) > 0 ? $this->Copyright : null),
|
||||
($bytecode ? Functions::cbc('trademark') : 'trademark') => ($this->Trademark !== null && strlen($this->Trademark) > 0 ? $this->Trademark : null),
|
||||
($bytecode ? Functions::cbc('version') : 'version') => $this->Version,
|
||||
($bytecode ? Functions::cbc('uid') : 'uid') => $this->UUID,
|
||||
];
|
||||
$return_results = [];
|
||||
|
||||
if($this->Name !== null && strlen($this->Name) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('name') : 'name')] = $this->Name;
|
||||
|
||||
if($this->Package !== null && strlen($this->Package) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('package') : 'package')] = $this->Package;
|
||||
|
||||
if($this->Description !== null && strlen($this->Description) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('description') : 'description')] = $this->Description;
|
||||
|
||||
if($this->Company !== null && strlen($this->Company) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('company') : 'company')] = $this->Company;
|
||||
|
||||
if($this->Product !== null && strlen($this->Product) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('product') : 'product')] = $this->Product;
|
||||
|
||||
if($this->Copyright !== null && strlen($this->Copyright) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('copyright') : 'copyright')] = $this->Copyright;
|
||||
|
||||
if($this->Trademark !== null && strlen($this->Trademark) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('trademark') : 'trademark')] = $this->Trademark;
|
||||
|
||||
if($this->Version !== null && strlen($this->Version) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('version') : 'version')] = $this->Version;
|
||||
|
||||
if($this->UUID !== null && strlen($this->UUID) > 0)
|
||||
$return_results[($bytecode ? Functions::cbc('uuid') : 'uuid')] = $this->UUID;
|
||||
|
||||
return $return_results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +217,7 @@
|
|||
$AssemblyObject->Copyright = Functions::array_bc($data, 'copyright');
|
||||
$AssemblyObject->Trademark = Functions::array_bc($data, 'trademark');
|
||||
$AssemblyObject->Version = Functions::array_bc($data, 'version');
|
||||
$AssemblyObject->UUID = Functions::array_bc($data, 'uid');
|
||||
$AssemblyObject->UUID = Functions::array_bc($data, 'uuid');
|
||||
|
||||
return $AssemblyObject;
|
||||
}
|
||||
|
|
|
@ -195,28 +195,42 @@
|
|||
{
|
||||
$ReturnResults = [];
|
||||
|
||||
$ReturnResults[($bytecode ? Functions::cbc('source_path') : 'source_path')] = $this->SourcePath;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('default_configuration') : 'default_configuration')] = $this->DefaultConfiguration;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('exclude_files') : 'exclude_files')] = $this->ExcludeFiles;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('scope') : 'scope')] = $this->Scope;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('main') : 'main')] = $this->Main;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('pre_build') : 'pre_build')] = $this->PreBuild;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('post_build') : 'post_build')] = $this->PostBuild;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')] = [];
|
||||
|
||||
foreach($this->Dependencies as $dependency)
|
||||
{
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')][] = $dependency->toArray($bytecode);
|
||||
}
|
||||
|
||||
$ReturnResults[($bytecode ? Functions::cbc('configurations') : 'configurations')] = [];
|
||||
|
||||
foreach($this->Configurations as $configuration)
|
||||
{
|
||||
$ReturnResults[($bytecode ? Functions::cbc('configurations') : 'configurations')][] = $configuration->toArray($bytecode);
|
||||
}
|
||||
if($this->SourcePath !== null)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('source_path') : 'source_path')] = $this->SourcePath;
|
||||
if($this->DefaultConfiguration !== null)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('default_configuration') : 'default_configuration')] = $this->DefaultConfiguration;
|
||||
if($this->ExcludeFiles !== null && count($this->ExcludeFiles) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('exclude_files') : 'exclude_files')] = $this->ExcludeFiles;
|
||||
if($this->Options !== null && count($this->Options) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options;
|
||||
if($this->Scope !== null)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('scope') : 'scope')] = $this->Scope;
|
||||
if($this->Main !== null)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('main') : 'main')] = $this->Main;
|
||||
if($this->DefineConstants !== null && count($this->DefineConstants) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants;
|
||||
if($this->PreBuild !== null && count($this->PreBuild) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('pre_build') : 'pre_build')] = $this->PreBuild;
|
||||
if($this->PostBuild !== null && count($this->PostBuild) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('post_build') : 'post_build')] = $this->PostBuild;
|
||||
if($this->Dependencies !== null && count($this->Dependencies) > 0)
|
||||
{
|
||||
$dependencies = [];
|
||||
foreach($this->Dependencies as $dependency)
|
||||
{
|
||||
$dependencies[] = $dependency->toArray($bytecode);
|
||||
}
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')] = $dependencies;
|
||||
}
|
||||
if($this->Configurations !== null && count($this->Configurations) > 0)
|
||||
{
|
||||
$configurations = [];
|
||||
foreach($this->Configurations as $configuration)
|
||||
{
|
||||
$configurations[] = $configuration->toArray($bytecode);
|
||||
}
|
||||
$ReturnResults[($bytecode ? Functions::cbc('configurations') : 'configurations')] = $configurations;
|
||||
}
|
||||
|
||||
return $ReturnResults;
|
||||
}
|
||||
|
|
|
@ -95,17 +95,26 @@
|
|||
{
|
||||
$ReturnResults = [];
|
||||
|
||||
$ReturnResults[($bytecode ? Functions::cbc('name') : 'name')] = $this->Name;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('output_path') : 'output_path')] = $this->OutputPath;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('exclude_files') : 'exclude_files')] = $this->ExcludeFiles;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('pre_build') : 'pre_build')] = $this->PreBuild;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')] = [];
|
||||
|
||||
foreach($this->Dependencies as $dependency)
|
||||
if($this->Name !== null && strlen($this->Name) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('name') : 'name')] = $this->Name;
|
||||
if($this->Options !== null && count($this->Options) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options;
|
||||
if($this->OutputPath !== null && strlen($this->OutputPath) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('output_path') : 'output_path')] = $this->OutputPath;
|
||||
if($this->DefineConstants !== null && count($this->DefineConstants) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants;
|
||||
if($this->ExcludeFiles !== null && count($this->ExcludeFiles) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('exclude_files') : 'exclude_files')] = $this->ExcludeFiles;
|
||||
if($this->PreBuild !== null && count($this->PreBuild) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('pre_build') : 'pre_build')] = $this->PreBuild;
|
||||
if($this->Dependencies !== null && count($this->Dependencies) > 0)
|
||||
{
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')][] = $dependency->toArray();
|
||||
$Dependencies = [];
|
||||
foreach($this->Dependencies as $Dependency)
|
||||
{
|
||||
$Dependencies[] = $Dependency->toArray($bytecode);
|
||||
}
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')] = $Dependencies;
|
||||
}
|
||||
|
||||
return $ReturnResults;
|
||||
|
@ -121,26 +130,13 @@
|
|||
{
|
||||
$BuildConfigurationObject = new BuildConfiguration();
|
||||
|
||||
if(Functions::array_bc($data, 'name') !== null)
|
||||
$BuildConfigurationObject->Name = Functions::array_bc($data, 'name');
|
||||
|
||||
if(Functions::array_bc($data, 'options') !== null)
|
||||
$BuildConfigurationObject->Options = Functions::array_bc($data, 'options');
|
||||
|
||||
if(Functions::array_bc($data, 'output_path') !== null)
|
||||
$BuildConfigurationObject->OutputPath = Functions::array_bc($data, 'output_path');
|
||||
|
||||
if(Functions::array_bc($data, 'define_constants') !== null)
|
||||
$BuildConfigurationObject->DefineConstants = Functions::array_bc($data, 'define_constants');
|
||||
|
||||
if(Functions::array_bc($data, 'exclude_files') !== null)
|
||||
$BuildConfigurationObject->ExcludeFiles = Functions::array_bc($data, 'exclude_files');
|
||||
|
||||
if(Functions::array_bc($data, 'pre_build') !== null)
|
||||
$BuildConfigurationObject->PreBuild = Functions::array_bc($data, 'pre_build');
|
||||
|
||||
if(Functions::array_bc($data, 'post_build') !== null)
|
||||
$BuildConfigurationObject->PostBuild = Functions::array_bc($data, 'post_build');
|
||||
$BuildConfigurationObject->Name = Functions::array_bc($data, 'name');
|
||||
$BuildConfigurationObject->Options = Functions::array_bc($data, 'options');
|
||||
$BuildConfigurationObject->OutputPath = Functions::array_bc($data, 'output_path');
|
||||
$BuildConfigurationObject->DefineConstants = Functions::array_bc($data, 'define_constants');
|
||||
$BuildConfigurationObject->ExcludeFiles = Functions::array_bc($data, 'exclude_files');
|
||||
$BuildConfigurationObject->PreBuild = Functions::array_bc($data, 'pre_build');
|
||||
$BuildConfigurationObject->PostBuild = Functions::array_bc($data, 'post_build');
|
||||
|
||||
if(Functions::array_bc($data, 'dependencies') !== null)
|
||||
{
|
||||
|
|
|
@ -130,11 +130,17 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
return [
|
||||
($bytecode ? Functions::cbc('extension') : 'extension') => $this->Extension,
|
||||
($bytecode ? Functions::cbc('minimum_version') : 'minimum_version') => $this->MinimumVersion,
|
||||
($bytecode ? Functions::cbc('maximum_version') : 'maximum_version') => $this->MaximumVersion
|
||||
];
|
||||
$return_results = [];
|
||||
if($this->Extension !== null && strlen($this->Extension) > 0)
|
||||
$return_results['extension'] = $this->Extension;
|
||||
|
||||
if($this->MinimumVersion !== null && strlen($this->MinimumVersion) > 0)
|
||||
$return_results['minimum_version'] = $this->MinimumVersion;
|
||||
|
||||
if($this->MaximumVersion !== null && strlen($this->MaximumVersion) > 0)
|
||||
$return_results['maximum_version'] = $this->MaximumVersion;
|
||||
|
||||
return $return_results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
namespace ncc\Objects\ProjectConfiguration;
|
||||
|
||||
use ncc\Abstracts\DependencySourceType;
|
||||
use ncc\Utilities\Functions;
|
||||
|
||||
/**
|
||||
|
@ -20,10 +21,17 @@
|
|||
public $Name;
|
||||
|
||||
/**
|
||||
* Optional. The source from where ncc can fetch the dependency from
|
||||
* Optional. The type of source from where ncc can fetch the dependency from
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $SourceType;
|
||||
|
||||
/**
|
||||
* Optional. The actual source where NCC can fetch the dependency from
|
||||
*
|
||||
* @var DependencySourceType|string|null
|
||||
*/
|
||||
public $Source;
|
||||
|
||||
/**
|
||||
|
@ -47,15 +55,14 @@
|
|||
|
||||
$ReturnResults[($bytecode ? Functions::cbc('name') : 'name')] = $this->Name;
|
||||
|
||||
if($this->SourceType !== null && strlen($this->SourceType) > 0)
|
||||
$ReturnResults[($bytecode ? Functions::cbc('source_type') : 'source_type')] = $this->SourceType;
|
||||
|
||||
if($this->Source !== null && strlen($this->Source) > 0)
|
||||
{
|
||||
$ReturnResults[($bytecode ? Functions::cbc('source') : 'source')] = $this->Source;
|
||||
}
|
||||
|
||||
if($this->Version !== null && strlen($this->Version) > 0)
|
||||
{
|
||||
$ReturnResults[($bytecode ? Functions::cbc('version') : 'version')] = $this->Version;
|
||||
}
|
||||
|
||||
return $ReturnResults;
|
||||
}
|
||||
|
@ -71,6 +78,7 @@
|
|||
$DependencyObject = new Dependency();
|
||||
|
||||
$DependencyObject->Name = Functions::array_bc($data, 'name');
|
||||
$DependencyObject->SourceType = Functions::array_bc($data, 'source_type');
|
||||
$DependencyObject->Source = Functions::array_bc($data, 'source');
|
||||
$DependencyObject->Version = Functions::array_bc($data, 'version');
|
||||
|
||||
|
|
|
@ -64,13 +64,24 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
return [
|
||||
($bytecode ? Functions::cbc('name') : 'name') => $this->Name,
|
||||
($bytecode ? Functions::cbc('runner') : 'runner') => $this->Runner,
|
||||
($bytecode ? Functions::cbc('message') : 'message') => $this->Message,
|
||||
($bytecode ? Functions::cbc('exec') : 'exec') => $this->Execute?->toArray($bytecode),
|
||||
($bytecode ? Functions::cbc('exit_handlers') : 'exit_handlers') => $this->ExitHandlers?->toArray($bytecode),
|
||||
];
|
||||
$results = [];
|
||||
|
||||
if ($this->Name !== null && strlen($this->Name) > 0)
|
||||
$results[($bytecode ? Functions::cbc('name') : 'name')] = $this->Name;
|
||||
|
||||
if ($this->Runner !== null && strlen($this->Runner) > 0)
|
||||
$results[($bytecode ? Functions::cbc('runner') : 'runner')] = $this->Runner;
|
||||
|
||||
if ($this->Message !== null && strlen($this->Message) > 0)
|
||||
$results[($bytecode ? Functions::cbc('message') : 'message')] = $this->Message;
|
||||
|
||||
if ($this->Execute !== null)
|
||||
$results[($bytecode ? Functions::cbc('execute') : 'execute')] = $this->Execute->toArray($bytecode);
|
||||
|
||||
if ($this->ExitHandlers !== null)
|
||||
$results[($bytecode ? Functions::cbc('exit_handlers') : 'exit_handlers')] = $this->ExitHandlers->toArray($bytecode);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -71,14 +71,27 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
return [
|
||||
($bytecode ? Functions::cbc('target') : 'target') => $this->Target,
|
||||
($bytecode ? Functions::cbc('working_directory') : 'working_directory') => $this->WorkingDirectory,
|
||||
($bytecode ? Functions::cbc('options') : 'options') => $this->Options,
|
||||
($bytecode ? Functions::cbc('silent') : 'silent') => $this->Silent,
|
||||
($bytecode ? Functions::cbc('tty') : 'tty') => $this->Tty,
|
||||
($bytecode ? Functions::cbc('timeout') : 'timeout') => $this->Timeout
|
||||
];
|
||||
$results = [];
|
||||
|
||||
if($this->Target !== null)
|
||||
$results[($bytecode ? Functions::cbc("target") : "target")] = $this->Target;
|
||||
|
||||
if($this->WorkingDirectory !== null)
|
||||
$results[($bytecode ? Functions::cbc("working_directory") : "working_directory")] = $this->WorkingDirectory;
|
||||
|
||||
if($this->Options !== null)
|
||||
$results[($bytecode ? Functions::cbc("options") : "options")] = $this->Options;
|
||||
|
||||
if($this->Silent !== null)
|
||||
$results[($bytecode ? Functions::cbc("silent") : "silent")] = (bool)$this->Silent;
|
||||
|
||||
if($this->Tty !== null)
|
||||
$results[($bytecode ? Functions::cbc("tty") : "tty")] = (bool)$this->Tty;
|
||||
|
||||
if($this->Timeout !== null)
|
||||
$results[($bytecode ? Functions::cbc("timeout") : "timeout")] = (int)$this->Timeout;
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -48,12 +48,21 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
return [
|
||||
($bytecode ? Functions::cbc('message') : 'message') => $this->Message,
|
||||
($bytecode ? Functions::cbc('end_process') : 'end_process') => $this->EndProcess,
|
||||
($bytecode ? Functions::cbc('run') : 'run') => $this->Run,
|
||||
($bytecode ? Functions::cbc('exit_code') : 'exit_code') => $this->ExitCode,
|
||||
];
|
||||
$return_results = [];
|
||||
|
||||
if($this->Message !== null)
|
||||
$return_results[($bytecode ? Functions::cbc('message') : 'message')] = $this->Message;
|
||||
|
||||
if($this->EndProcess !== null)
|
||||
$return_results[($bytecode ? Functions::cbc('end_process') : 'end_process')] = $this->EndProcess;
|
||||
|
||||
if($this->Run !== null)
|
||||
$return_results[($bytecode ? Functions::cbc('run') : 'run')] = $this->Run;
|
||||
|
||||
/** @noinspection PhpCastIsUnnecessaryInspection */
|
||||
$return_results[($bytecode ? Functions::cbc('exit_code') : 'exit_code')] = (int)$this->ExitCode;
|
||||
|
||||
return $return_results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -58,14 +58,27 @@
|
|||
*/
|
||||
public function toArray(bool $bytecode=false): array
|
||||
{
|
||||
return [
|
||||
($bytecode ? Functions::cbc('pre_install') : 'pre_install') => $this->PreInstall,
|
||||
($bytecode? Functions::cbc('post_install') : 'post_install') => $this->PostInstall,
|
||||
($bytecode? Functions::cbc('pre_uninstall') : 'pre_uninstall') => $this->PostUninstall,
|
||||
($bytecode? Functions::cbc('post_uninstall') : 'post_uninstall') => $this->PostUninstall,
|
||||
($bytecode? Functions::cbc('pre_update') : 'pre_update') => $this->PreUpdate,
|
||||
($bytecode? Functions::cbc('post_update') : 'post_update') => $this->PostUpdate
|
||||
];
|
||||
$results = [];
|
||||
|
||||
if($this->PreInstall !== null && count($this->PreInstall) > 0)
|
||||
$results[($bytecode ? Functions::cbc('pre_install') : 'pre_install')] = $this->PreInstall;
|
||||
|
||||
if($this->PostInstall !== null && count($this->PostInstall) > 0)
|
||||
$results[($bytecode ? Functions::cbc('post_install') : 'post_install')] = $this->PostInstall;
|
||||
|
||||
if($this->PreUninstall !== null && count($this->PreUninstall) > 0)
|
||||
$results[($bytecode ? Functions::cbc('pre_uninstall') : 'pre_uninstall')] = $this->PreUninstall;
|
||||
|
||||
if($this->PostUninstall !== null && count($this->PostUninstall) > 0)
|
||||
$results[($bytecode ? Functions::cbc('post_uninstall') : 'post_uninstall')] = $this->PostUninstall;
|
||||
|
||||
if($this->PreUpdate !== null && count($this->PreUpdate) > 0)
|
||||
$results[($bytecode ? Functions::cbc('pre_update') : 'pre_update')] = $this->PreUpdate;
|
||||
|
||||
if($this->PostUpdate !== null && count($this->PostUpdate) > 0)
|
||||
$results[($bytecode ? Functions::cbc('post_update') : 'post_update')] = $this->PostUpdate;
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
8
src/ncc/Objects/ProjectConfiguration/UpdateSource.php
Normal file
8
src/ncc/Objects/ProjectConfiguration/UpdateSource.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects\ProjectConfiguration;
|
||||
|
||||
class UpdateSource
|
||||
{
|
||||
public $type;
|
||||
}
|
100
src/ncc/Objects/RemotePackageInput.php
Normal file
100
src/ncc/Objects/RemotePackageInput.php
Normal file
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
use ncc\Abstracts\RegexPatterns;
|
||||
|
||||
class RemotePackageInput
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $Vendor;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $Package;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $Version;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $Branch;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
public $Source;
|
||||
|
||||
/**
|
||||
* Public Constructor & String Parser
|
||||
*
|
||||
* @param string|null $input
|
||||
*/
|
||||
public function __construct(?string $input=null)
|
||||
{
|
||||
if($input !== null && preg_match(RegexPatterns::RemotePackage, $input, $matches))
|
||||
{
|
||||
$this->Vendor = $matches['vendor'];
|
||||
$this->Package = $matches['package'];
|
||||
$this->Version = $matches['version'];
|
||||
$this->Branch = $matches['branch'];
|
||||
$this->Source = $matches['source'];
|
||||
|
||||
if(strlen($this->Vendor) == 0)
|
||||
$this->Vendor = null;
|
||||
if(strlen($this->Package) == 0)
|
||||
$this->Package = null;
|
||||
if(strlen($this->Version) == 0)
|
||||
$this->Version = null;
|
||||
if(strlen($this->Branch) == 0)
|
||||
$this->Branch = null;
|
||||
if(strlen($this->Source) == 0)
|
||||
$this->Source = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toString(): string
|
||||
{
|
||||
if($this->Vendor == null || $this->Package == null)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$results = $this->Vendor . '/' . $this->Package;
|
||||
|
||||
if($this->Version !== null)
|
||||
$results .= '=' . $this->Version;
|
||||
if($this->Branch !== null)
|
||||
$results .= ':' . $this->Branch;
|
||||
if($this->Source !== null)
|
||||
$results .= '@' . $this->Source;
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a standard package name string representation
|
||||
*
|
||||
* @param bool $version
|
||||
* @return string
|
||||
*/
|
||||
public function toStandard(bool $version=true): string
|
||||
{
|
||||
if($version)
|
||||
return str_replace('-', '_', sprintf('com.%s.%s=%s', $this->Vendor, $this->Package, $this->Version));
|
||||
return str_replace('-', '_', sprintf('com.%s.%s', $this->Vendor, $this->Package));
|
||||
}
|
||||
}
|
|
@ -91,9 +91,8 @@
|
|||
flush();
|
||||
|
||||
// when done, send a newline
|
||||
if($value == $total) {
|
||||
echo "\n";
|
||||
}
|
||||
if($value == $total)
|
||||
Console::out((string)null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,18 +5,21 @@
|
|||
use Exception;
|
||||
use ncc\Abstracts\Runners;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Classes\PhpExtension\Runner;
|
||||
use ncc\Classes\PhpExtension\PhpRunner;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\MalformedJsonException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Managers\ConfigurationManager;
|
||||
use ncc\Managers\CredentialManager;
|
||||
use ncc\Managers\PackageLockManager;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Objects\ComposerJson;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\ThirdParty\jelix\Version\Parser;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
|
||||
/**
|
||||
|
@ -254,7 +257,7 @@
|
|||
public static function compileRunner(string $path, ExecutionPolicy $policy): ExecutionUnit
|
||||
{
|
||||
return match (strtolower($policy->Runner)) {
|
||||
Runners::php => Runner::processUnit($path, $policy),
|
||||
Runners::php => PhpRunner::processUnit($path, $policy),
|
||||
default => throw new UnsupportedRunnerException('The runner \'' . $policy->Runner . '\' is not supported'),
|
||||
};
|
||||
}
|
||||
|
@ -364,4 +367,89 @@
|
|||
Console::outError('Cannot construct Package Lock, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a composer json file and returns a ComposerJson object
|
||||
*
|
||||
* @param string $path
|
||||
* @return ComposerJson
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static function loadComposerJson(string $path): ComposerJson
|
||||
{
|
||||
$json_contents = IO::fread($path);
|
||||
return ComposerJson::fromArray(json_decode($json_contents, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to convert the value to a bool
|
||||
*
|
||||
* @param $value
|
||||
* @return bool
|
||||
*/
|
||||
public static function cbool($value): bool
|
||||
{
|
||||
if(is_null($value))
|
||||
return false;
|
||||
if(is_string($value))
|
||||
{
|
||||
switch(strtolower($value))
|
||||
{
|
||||
case 'y':
|
||||
case 'yes':
|
||||
case 't':
|
||||
case 'true':
|
||||
case '1':
|
||||
return true;
|
||||
|
||||
case 'n':
|
||||
case 'no':
|
||||
case 'f':
|
||||
case 'false':
|
||||
case '0':
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(is_int($value))
|
||||
{
|
||||
if ($value == 0)
|
||||
return false;
|
||||
if ($value == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a property value from the configuration
|
||||
*
|
||||
* @param string $property
|
||||
* @return mixed|null
|
||||
*/
|
||||
public static function getConfigurationProperty(string $property)
|
||||
{
|
||||
$config_manager = new ConfigurationManager();
|
||||
return $config_manager->getProperty($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the version and returns a valid version format
|
||||
*
|
||||
* @param string $version
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function parseVersion(string $version): string
|
||||
{
|
||||
/** @noinspection PhpStrFunctionsInspection */
|
||||
if(substr($version, 0, 1) === 'v')
|
||||
$version = substr($version, 1);
|
||||
|
||||
return Parser::parse($version)->toString();
|
||||
}
|
||||
}
|
|
@ -202,4 +202,15 @@
|
|||
{
|
||||
return self::getDataPath($scope, $win32) . DIRECTORY_SEPARATOR . 'ext';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration file path (ncc.yaml)
|
||||
*
|
||||
* @return string
|
||||
* @throws InvalidScopeException
|
||||
*/
|
||||
public static function getConfigurationFile(): string
|
||||
{
|
||||
return self::getDataPath(Scopes::System) . DIRECTORY_SEPARATOR . 'ncc.yaml';
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace ncc\Utilities;
|
||||
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
|
||||
class RuntimeCache
|
||||
{
|
||||
/**
|
||||
|
@ -11,6 +13,13 @@
|
|||
*/
|
||||
private static $cache = [];
|
||||
|
||||
/**
|
||||
* An array of files to delete when the cache is cleared
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private static $temporary_files = [];
|
||||
|
||||
/**
|
||||
* Sets a value, returns the value
|
||||
*
|
||||
|
@ -37,4 +46,49 @@
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a file as temporary, it will be deleted when the cache is cleared
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public static function setFileAsTemporary(string $path)
|
||||
{
|
||||
if(!in_array($path, self::$temporary_files))
|
||||
self::$temporary_files[] = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a file from the temporary files list
|
||||
*
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public static function removeFileAsTemporary(string $path)
|
||||
{
|
||||
if(in_array($path, self::$temporary_files))
|
||||
unset(self::$temporary_files[array_search($path, self::$temporary_files)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public static function clearCache(bool $clear_memory=true, bool $clear_files=true): void
|
||||
{
|
||||
if($clear_memory)
|
||||
{
|
||||
self::$cache = [];
|
||||
}
|
||||
|
||||
if($clear_files)
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
foreach(self::$temporary_files as $file)
|
||||
{
|
||||
if(file_exists($file))
|
||||
$filesystem->remove($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -131,7 +131,7 @@
|
|||
'NCC_INIT' => constant('NCC_INIT'),
|
||||
|
||||
// Debugging/Troubleshooting constants
|
||||
'NCC_EXEC_LOCATION' => constant('NCC_INIT'),
|
||||
'NCC_EXEC_LOCATION' => constant('NCC_EXEC_LOCATION'),
|
||||
'NCC_EXEC_IWD' => constant('NCC_EXEC_IWD'),
|
||||
|
||||
// Version Information
|
||||
|
|
103
tests/composer/json_example.json
Normal file
103
tests/composer/json_example.json
Normal file
|
@ -0,0 +1,103 @@
|
|||
{
|
||||
"name": "composer/composer",
|
||||
"type": "library",
|
||||
"description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
|
||||
"keywords": [
|
||||
"package",
|
||||
"dependency",
|
||||
"autoload"
|
||||
],
|
||||
"homepage": "https://getcomposer.org/",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "https://www.naderman.de"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "https://seld.be"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"composer/ca-bundle": "^1.0",
|
||||
"composer/class-map-generator": "^1.0",
|
||||
"composer/metadata-minifier": "^1.0",
|
||||
"composer/semver": "^3.0",
|
||||
"composer/spdx-licenses": "^1.5.7",
|
||||
"composer/xdebug-handler": "^2.0.2 || ^3.0.3",
|
||||
"justinrainbow/json-schema": "^5.2.11",
|
||||
"psr/log": "^1.0 || ^2.0 || ^3.0",
|
||||
"seld/jsonlint": "^1.4",
|
||||
"seld/phar-utils": "^1.2",
|
||||
"symfony/console": "^5.4.11 || ^6.0.11",
|
||||
"symfony/filesystem": "^5.4 || ^6.0",
|
||||
"symfony/finder": "^5.4 || ^6.0",
|
||||
"symfony/process": "^5.4 || ^6.0",
|
||||
"react/promise": "^2.8",
|
||||
"composer/pcre": "^2.1 || ^3.1",
|
||||
"symfony/polyfill-php73": "^1.24",
|
||||
"symfony/polyfill-php80": "^1.24",
|
||||
"symfony/polyfill-php81": "^1.24",
|
||||
"seld/signal-handler": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^6.0",
|
||||
"phpstan/phpstan": "^1.4.1",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpstan/phpstan-deprecation-rules": "^1",
|
||||
"phpstan/phpstan-strict-rules": "^1",
|
||||
"phpstan/phpstan-symfony": "^1.2.10"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
|
||||
"ext-zip": "Enabling the zip extension allows you to unzip archives",
|
||||
"ext-zlib": "Allow gzip compression of HTTP requests"
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.2.5"
|
||||
},
|
||||
"platform-check": false
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.5-dev"
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"phpstan/rules.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\": "src/Composer"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Composer\\Test\\": "tests/Composer/Test"
|
||||
}
|
||||
},
|
||||
"bin": [
|
||||
"bin/composer"
|
||||
],
|
||||
"scripts": {
|
||||
"compile": "@php -dphar.readonly=0 bin/compile",
|
||||
"test": "@php simple-phpunit",
|
||||
"phpstan": "@php vendor/bin/phpstan analyse --configuration=phpstan/config.neon"
|
||||
},
|
||||
"scripts-descriptions": {
|
||||
"compile": "Compile composer.phar",
|
||||
"test": "Run all tests",
|
||||
"phpstan": "Runs PHPStan"
|
||||
},
|
||||
"support": {
|
||||
"issues": "https://github.com/composer/composer/issues",
|
||||
"irc": "ircs://irc.libera.chat:6697/composer"
|
||||
}
|
||||
}
|
2416
tests/composer/lock_example.json
Normal file
2416
tests/composer/lock_example.json
Normal file
File diff suppressed because it is too large
Load diff
6
tests/composer/parse_json.php
Normal file
6
tests/composer/parse_json.php
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
require(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'autoload.php');
|
||||
|
||||
$example = \ncc\Utilities\IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'json_example.json');
|
||||
var_dump(\ncc\Objects\ComposerJson::fromArray(json_decode($example, true)));
|
Loading…
Add table
Reference in a new issue