- \ncc\Objects\ProjectConfiguration > Dependency > __construct() now requires the parameters $name, $source_type,

`$source` and `$version`
 - `\ncc\Objects\ProjectConfiguration > Dependency > fromArray()` Throws an `ConfigurationException` if the property
   `name` is missing in the dependency configuration
 - Also updated a bunch of objects in a similar fashion to the ones above, (BuildConfiguration, Execute, ExitHandle,
   ExitHandler, Repository, Assembly, Build, Dependency, ExecutionPolicy, Installer, Project, UpdateSource) I'm not
   going to list them all here, but you can find them in the commit history.
 - Added a new interface class `ValidatableObjectInterface` to implement validatable objects, this method will throw a
   `ConfigurationException` if the object is not valid or a `NotSupportedException` if the object contains methods that
   are not supported by the current version of ncc or project.
This commit is contained in:
Netkas 2023-08-31 18:25:37 -04:00
parent 230675c586
commit 01cda99139
No known key found for this signature in database
GPG key ID: 5DAF58535614062B
16 changed files with 415 additions and 457 deletions

View file

@ -21,6 +21,9 @@ features and reduced the number of exceptions down to 15 exceptions.
- Added new exception `OperationException` in `\ncc\Exceptions` to replace all generic related exceptions
- Added a new interface class `SerializableObjectInterface` to implement serializable objects, `BytecodeObjectInterface`
extends this interface to allow for serialization of compiled assets
- Added a new interface class `ValidatableObjectInterface` to implement validatable objects, this method will throw a
`ConfigurationException` if the object is not valid or a `NotSupportedException` if the object contains methods that
are not supported by the current version of ncc or project.
### Fixed
- Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()`
@ -211,6 +214,13 @@ features and reduced the number of exceptions down to 15 exceptions.
- `\ncc\Objects > ProjectConfiguration > fromArray()` Throws an `ConfigurationException` if the property 'project' is
missing in the root configuration
- `\ncc\Objects\ProjectConfiguration > Project > __construct()` now requires the parameter `$compiler`
- `\ncc\Objects\ProjectConfiguration > Dependency > __construct()` now requires the parameters `$name`, `$source_type`,
`$source` and `$version`
- `\ncc\Objects\ProjectConfiguration > Dependency > fromArray()` Throws an `ConfigurationException` if the property
`name` is missing in the dependency configuration
- Also updated a bunch of objects in a similar fashion to the ones above, (BuildConfiguration, Execute, ExitHandle,
ExitHandler, Repository, Assembly, Build, Dependency, ExecutionPolicy, Installer, Project, UpdateSource) I'm not
going to list them all here, but you can find them in the commit history.
### Removed

View file

@ -42,9 +42,15 @@ namespace ncc\Enums;
*/
public const UNKNOWN = 'unknown';
/**
* No remote source type
*/
public const NONE = 'none';
public const All = [
self::BUILTIN,
self::DEFINED,
self::UNKNOWN
self::UNKNOWN,
self::NONE
];
}

View file

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

View file

@ -31,6 +31,7 @@
use ncc\Exceptions\NotSupportedException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Interfaces\ValidatableObjectInterface;
use ncc\Objects\ProjectConfiguration\Assembly;
use ncc\Objects\ProjectConfiguration\Build;
use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
@ -43,7 +44,7 @@
* @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved.
*/
class ProjectConfiguration implements BytecodeObjectInterface
class ProjectConfiguration implements BytecodeObjectInterface, ValidatableObjectInterface
{
/**
* The project configuration
@ -59,6 +60,13 @@
*/
private $assembly;
/**
* Build configuration for the project
*
* @var Build
*/
private $build;
/**
* An array of execution policies
*
@ -73,22 +81,15 @@
*/
private $installer;
/**
* Build configuration for the project
*
* @var Build
*/
private $build;
/**
* Public Constructor
*/
public function __construct()
public function __construct(Project $project, Assembly $assembly, Build $build)
{
$this->project = new Project();
$this->assembly = new Assembly();
$this->project = $project;
$this->assembly = $assembly;
$this->build = $build;
$this->execution_policies = [];
$this->build = new Build();
}
/**
@ -172,55 +173,19 @@
}
/**
* Validates the object for any errors
*
* @param bool $throw_exception
* @return bool
* @throws ConfigurationException
* @throws NotSupportedException
* @inheritDoc
*/
public function validate(bool $throw_exception=True): bool
public function validate(): void
{
if(!$this->project->validate($throw_exception))
{
return false;
}
if(!$this->assembly->validate($throw_exception))
{
return false;
}
if(!$this->build->validate($throw_exception))
{
return false;
}
try
{
$this->getRequiredExecutionPolicies(BuildConfigurationValues::ALL);
}
catch(Exception $e)
{
if($throw_exception)
{
throw $e;
}
return false;
}
$this->project->validate();
$this->assembly->validate();
$this->build->validate();
if($this->build->getMain() !== null)
{
if($this->execution_policies === null || count($this->execution_policies) === 0)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Build configuration build.main uses an execution policy "%s" but no policies are defined', $this->build->getMain()));
}
return false;
throw new ConfigurationException(sprintf('Build configuration build.main uses an execution policy "%s" but no policies are defined', $this->build->getMain()));
}
@ -236,25 +201,14 @@
if(!$found)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Build configuration build.main points to a undefined execution policy "%s"', $this->build->getMain()));
}
return false;
throw new ConfigurationException(sprintf('Build configuration build.main points to a undefined execution policy "%s"', $this->build->getMain()));
}
if($this->build->getMain() === BuildConfigurationValues::ALL)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Build configuration build.main cannot be set to "%s"', BuildConfigurationValues::ALL));
}
return false;
throw new ConfigurationException(sprintf('Build configuration build.main cannot be set to "%s"', BuildConfigurationValues::ALL));
}
}
return true;
}
/**
@ -301,9 +255,8 @@
// Check the installer by batch
if($this->installer !== null)
{
$array_rep = $this->installer->toArray();
/** @var string[] $value */
foreach($array_rep as $key => $value)
foreach($this->installer->toArray() as $key => $value)
{
if($value === null || count($value) === 0)
{
@ -510,17 +463,8 @@
*/
public function toArray(bool $bytecode=false): array
{
$execution_policies = null;
if($this->execution_policies !== null)
{
$execution_policies = [];
foreach($this->execution_policies as $executionPolicy)
{
$execution_policies[$executionPolicy->getName()] = $executionPolicy->toArray($bytecode);
}
}
$results = [];
if($this->project !== null)
{
$results[($bytecode ? Functions::cbc('project') : 'project')] = $this->project->toArray($bytecode);
@ -541,8 +485,15 @@
$results[($bytecode ? Functions::cbc('installer') : 'installer')] = $this->installer->toArray($bytecode);
}
if($execution_policies !== null && count($execution_policies) > 0)
if(count($this->execution_policies) > 0)
{
$execution_policies = [];
foreach($this->execution_policies as $executionPolicy)
{
$execution_policies[$executionPolicy->getName()] = $executionPolicy->toArray($bytecode);
}
$results[($bytecode ? Functions::cbc('execution_policies') : 'execution_policies')] = $execution_policies;
}
@ -558,30 +509,37 @@
*/
public static function fromArray(array $data): ProjectConfiguration
{
$object = new self();
$object->project = Functions::array_bc($data, 'project');
if($object->project !== null)
$project = Functions::array_bc($data, 'project');
if($project !== null)
{
$object->project = Project::fromArray($object->project);
$project = Project::fromArray($project);
}
else
{
throw new ConfigurationException('The project configuration is missing the required property "project" in the root of the configuration');
}
$object->assembly = Functions::array_bc($data, 'assembly');
if($object->assembly !== null)
$assembly = Functions::array_bc($data, 'assembly');
if($assembly !== null)
{
$object->assembly = Assembly::fromArray($object->assembly);
$assembly = Assembly::fromArray($assembly);
}
else
{
throw new ConfigurationException('The project configuration is missing the required property "assembly" in the root of the configuration');
}
$object->build = Functions::array_bc($data, 'build');
if($object->build !== null)
$build = Functions::array_bc($data, 'build');
if($build !== null)
{
$object->build = Build::fromArray($object->build);
$build = Build::fromArray($build);
}
else
{
throw new ConfigurationException('The project configuration is missing the required property "build" in the root of the configuration');
}
$object = new self($project, $assembly, $build);
$object->installer = Functions::array_bc($data, 'installer');
if($object->installer !== null)
@ -592,11 +550,9 @@
$execution_policies = Functions::array_bc($data, 'execution_policies');
if(!is_null($execution_policies))
{
$object->execution_policies = [];
foreach(Functions::array_bc($data, 'execution_policies') as $execution_policy)
{
$object->execution_policies[] = ExecutionPolicy::fromArray($execution_policy);
}
$object->execution_policies = array_map(static function($policy) {
return ExecutionPolicy::fromArray($policy);
}, $execution_policies);
}
return $object;

View file

@ -27,6 +27,9 @@
use ncc\Enums\RegexPatterns;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Interfaces\ValidatableObjectInterface;
use ncc\ThirdParty\Symfony\Uid\Uuid;
use ncc\ThirdParty\Symfony\Uid\UuidV4;
use ncc\Utilities\Functions;
use ncc\Utilities\Validate;
@ -34,7 +37,7 @@
* @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved.
*/
class Assembly implements BytecodeObjectInterface
class Assembly implements BytecodeObjectInterface, ValidatableObjectInterface
{
/**
* The software name
@ -97,6 +100,25 @@
*/
private $uuid;
/**
* Assembly constructor.
*/
public function __construct(string $name, string $package, string $version='1.0.0', ?string $uuid=null)
{
$this->name = $name;
$this->package = $package;
$this->version = $version;
if($uuid === null)
{
$this->uuid = Uuid::v4()->toRfc4122();
}
else
{
$this->uuid = $uuid;
}
}
/**
* @return string
*/
@ -242,105 +264,54 @@
}
/**
* Validates the object information to detect possible errors
*
* @param bool $throw_exception
* @return bool
* @throws ConfigurationException
* @inheritDoc
*/
public function validate(bool $throw_exception=True): bool
public function validate(): void
{
if(!preg_match(RegexPatterns::UUID, $this->uuid))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The UUID is not a valid v4 UUID: %s, in property Assembly.UUID', $this->uuid));
}
return false;
throw new ConfigurationException(sprintf('The UUID is not a valid v4 UUID: %s, in property assembly.uuid', $this->uuid));
}
if($this->version !== null && !Validate::version($this->version))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The version number is invalid: %s, in property Assembly.Version', $this->version));
}
return false;
throw new ConfigurationException(sprintf('The version number is invalid: %s, in property assembly.version', $this->version));
}
if($this->package !== null && !preg_match(RegexPatterns::PACKAGE_NAME_FORMAT, $this->package))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The package name is invalid: %s, in property Assembly.Package', $this->package));
}
return false;
throw new ConfigurationException(sprintf('The package name is invalid: %s, in property assembly.package', $this->package));
}
if($this->name !== null && strlen($this->name) > 126)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The name cannot be larger than 126 characters: %s, in property Assembly.Name', $this->name));
}
return false;
throw new ConfigurationException(sprintf('The name cannot be larger than 126 characters: %s, in property assembly.name', $this->name));
}
if($this->description !== null && strlen($this->description) > 512)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The description cannot be larger than 512 characters: %s, in property Assembly.Description', $this->description));
}
return false;
throw new ConfigurationException(sprintf('The description cannot be larger than 512 characters: %s, in property assembly.description', $this->description));
}
if($this->company !== null && strlen($this->company) > 126)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The company cannot be larger than 126 characters: %s, in property Assembly.Company', $this->company));
}
return false;
throw new ConfigurationException(sprintf('The company cannot be larger than 126 characters: %s, in property assembly.company', $this->company));
}
if($this->product !== null && strlen($this->product) > 256)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The product cannot be larger than 256 characters: %s, in property Assembly.Product', $this->product));
}
return false;
throw new ConfigurationException(sprintf('The product cannot be larger than 256 characters: %s, in property assembly.product', $this->product));
}
if($this->copyright !== null && strlen($this->copyright) > 256)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The copyright cannot be larger than 256 characters: %s, in property Assembly.Copyright', $this->company));
}
return false;
throw new ConfigurationException(sprintf('The copyright cannot be larger than 256 characters: %s, in property assembly.copyright', $this->company));
}
if($this->trademark !== null && strlen($this->trademark) > 256)
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The trademark cannot be larger than 256 characters: %s, in property Assembly.Trademark', $this->trademark));
}
return false;
throw new ConfigurationException(sprintf('The trademark cannot be larger than 256 characters: %s, in property assembly.trademark', $this->trademark));
}
return true;
}
/**
@ -400,20 +371,30 @@
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): Assembly
{
$object = new self();
$name = Functions::array_bc($data, 'name');
$package = Functions::array_bc($data, 'package');
if($name === null)
{
throw new ConfigurationException('The property \'assembly.name\' must not be null.');
}
if($package === null)
{
throw new ConfigurationException('The property \'assembly.package\' must not be null.');
}
$object = new self($name, $package, Functions::array_bc($data, 'version'), Functions::array_bc($data, 'uuid'));
$object->name = Functions::array_bc($data, 'name');
$object->package = Functions::array_bc($data, 'package');
$object->description = Functions::array_bc($data, 'description');
$object->company = Functions::array_bc($data, 'company');
$object->product = Functions::array_bc($data, 'product');
$object->copyright = Functions::array_bc($data, 'copyright');
$object->trademark = Functions::array_bc($data, 'trademark');
$object->version = Functions::array_bc($data, 'version');
$object->uuid = Functions::array_bc($data, 'uuid');
return $object;
}

View file

@ -27,6 +27,7 @@
use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Interfaces\ValidatableObjectInterface;
use ncc\Objects\ProjectConfiguration\Build\BuildConfiguration;
use ncc\Utilities\Functions;
use ncc\Utilities\Validate;
@ -35,7 +36,7 @@
* @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved.
*/
class Build implements BytecodeObjectInterface
class Build implements BytecodeObjectInterface, ValidatableObjectInterface
{
/**
* The source directory that the compiler will target to generate a build
@ -110,8 +111,10 @@
/**
* Public Constructor
*/
public function __construct()
public function __construct(string $source_path, ?string $default_configuration=null)
{
$this->source_path = $source_path;
$this->default_configuration = $default_configuration ?? BuildConfigurationValues::DEFAULT;
$this->exclude_files = [];
$this->options = [];
$this->define_constants = [];
@ -365,7 +368,7 @@
}
/**
* Adds a new pre build policy to the build
* Adds a new pre-build policy to the build
*
* @param string $policy
* @return void
@ -496,13 +499,9 @@
}
/**
* Validates the build configuration object
*
* @param bool $throw_exception
* @return bool
* @throws ConfigurationException
* @inheritDoc
*/
public function validate(bool $throw_exception=True): bool
public function validate(): void
{
// Check the defined constants
foreach($this->define_constants as $name => $value)
@ -519,46 +518,24 @@
{
if(in_array($configuration->getName(), $build_configurations, true))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $configuration->getName()));
}
return false;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $configuration->getName()));
}
}
foreach($this->build_configurations as $configuration)
{
if (!$configuration->validate($throw_exception))
{
return false;
}
$configuration->validate();
}
if($this->default_configuration === null)
{
if($throw_exception)
{
throw new ConfigurationException('The default build configuration is not set');
}
return false;
throw new ConfigurationException('The default build configuration is not set');
}
if(!Validate::nameFriendly($this->default_configuration))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('The default build configuration name "%s" is not valid', $this->default_configuration));
}
return false;
throw new ConfigurationException(sprintf('The default build configuration name "%s" is not valid', $this->default_configuration));
}
$this->getBuildConfiguration($this->default_configuration);
return true;
}
/**
@ -621,10 +598,12 @@
if($this->build_configurations !== null && count($this->build_configurations) > 0)
{
$configurations = [];
foreach($this->build_configurations as $configuration)
{
$configurations[] = $configuration->toArray($bytecode);
}
$results[($bytecode ? Functions::cbc('configurations') : 'configurations')] = $configurations;
}
@ -636,31 +615,38 @@
*
* @param array $data
* @return Build
* @throws ConfigurationException
*/
public static function fromArray(array $data): Build
{
$object = new self();
$source_path = Functions::array_bc($data, 'source_path');
if($source_path === null)
{
throw new ConfigurationException('The property \'project.build.source_path\' must not be null.');
}
$object = new self($source_path, Functions::array_bc($data, 'default_configuration'));
$object->source_path = Functions::array_bc($data, 'source_path');
$object->default_configuration = Functions::array_bc($data, 'default_configuration');
$object->exclude_files = (Functions::array_bc($data, 'exclude_files') ?? []);
$object->options = (Functions::array_bc($data, 'options') ?? []);
$object->main = Functions::array_bc($data, 'main');
$object->define_constants = (Functions::array_bc($data, 'define_constants') ?? []);
$object->pre_build = (Functions::array_bc($data, 'pre_build') ?? []);
$object->post_build = (Functions::array_bc($data, 'post_build') ?? []);
$object->main = Functions::array_bc($data, 'main');
if(Functions::array_bc($data, 'dependencies') !== null)
$dependencies = Functions::array_bc($data, 'dependencies');
if($dependencies !== null)
{
foreach(Functions::array_bc($data, 'dependencies') as $dependency)
foreach($dependencies as $dependency)
{
$object->dependencies[] = Dependency::fromArray($dependency);
}
}
if(Functions::array_bc($data, 'configurations') !== null)
$configurations = Functions::array_bc($data, 'configurations');
if($configurations !== null)
{
foreach(Functions::array_bc($data, 'configurations') as $configuration)
foreach($configurations as $configuration)
{
$object->build_configurations[] = BuildConfiguration::fromArray($configuration);
}

View file

@ -96,10 +96,11 @@
/**
* Public Constructor
*/
public function __construct()
public function __construct(string $name, string $output_path)
{
$this->name = $name;
$this->output_path = $output_path;
$this->options = [];
$this->output_path = 'build';
$this->define_constants = [];
$this->exclude_files = [];
$this->pre_build = [];
@ -114,97 +115,47 @@
* @return bool
* @throws ConfigurationException
*/
public function validate(bool $throw_exception=True): bool
public function validate(): bool
{
if(!Validate::nameFriendly($this->name))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
if(!Validate::pathName($this->output_path))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
if($this->define_constants !== null && !is_array($this->define_constants))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
if($this->exclude_files !== null && !is_array($this->exclude_files))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
if($this->pre_build !== null && !is_array($this->pre_build))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
if($this->post_build !== null && !is_array($this->post_build))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
if($this->dependencies !== null && !is_array($this->dependencies))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
return False;
throw new ConfigurationException(sprintf('Invalid build configuration name "%s"', $this->name));
}
/** @var Dependency $dependency */
foreach($this->dependencies as $dependency)
{
try
{
if (!$dependency->validate($throw_exception))
{
return False;
}
}
catch (ConfigurationException $e)
{
if($throw_exception)
{
throw $e;
}
return False;
}
$dependency->validate();
}
return True;
@ -418,37 +369,30 @@
{
$results = [];
if($this->name !== null && $this->name !== '')
{
$results[($bytecode ? Functions::cbc('name') : 'name')] = $this->name;
}
$results[($bytecode ? Functions::cbc('name') : 'name')] = $this->name;
$results[($bytecode ? Functions::cbc('output_path') : 'output_path')] = $this->output_path;
if($this->options !== null && count($this->options) > 0)
if(count($this->options) > 0)
{
$results[($bytecode ? Functions::cbc('options') : 'options')] = $this->options;
}
if($this->output_path !== null && $this->output_path !== '')
{
$results[($bytecode ? Functions::cbc('output_path') : 'output_path')] = $this->output_path;
}
if($this->define_constants !== null && count($this->define_constants) > 0)
if(count($this->define_constants) > 0)
{
$results[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->define_constants;
}
if($this->exclude_files !== null && count($this->exclude_files) > 0)
if(count($this->exclude_files) > 0)
{
$results[($bytecode ? Functions::cbc('exclude_files') : 'exclude_files')] = $this->exclude_files;
}
if($this->pre_build !== null && count($this->pre_build) > 0)
if(count($this->pre_build) > 0)
{
$results[($bytecode ? Functions::cbc('pre_build') : 'pre_build')] = $this->pre_build;
}
if($this->dependencies !== null && count($this->dependencies) > 0)
if(count($this->dependencies) > 0)
{
$dependencies = array_map(static function(Dependency $Dependency) use ($bytecode)
{
@ -463,22 +407,35 @@
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): BuildConfiguration
{
$object = new BuildConfiguration();
$name = Functions::array_bc($data, 'name');
$output_path = Functions::array_bc($data, 'output_path');
if($name === null)
{
throw new ConfigurationException('Build configuration "name" property is required');
}
if($output_path === null)
{
throw new ConfigurationException('Build configuration "output_path" property is required');
}
$object = new BuildConfiguration($name, $output_path);
$object->name = Functions::array_bc($data, 'name');
$object->options = Functions::array_bc($data, 'options') ?? [];
$object->output_path = Functions::array_bc($data, 'output_path');
$object->define_constants = Functions::array_bc($data, 'define_constants') ?? [];
$object->exclude_files = Functions::array_bc($data, 'exclude_files') ?? [];
$object->pre_build = Functions::array_bc($data, 'pre_build') ?? [];
$object->post_build = Functions::array_bc($data, 'post_build') ?? [];
if(Functions::array_bc($data, 'dependencies') !== null)
$dependencies = Functions::array_bc($data, 'dependencies');
if($dependencies !== null)
{
foreach(Functions::array_bc($data, 'dependencies') as $item)
foreach($dependencies as $item)
{
$object->dependencies[] = Dependency::fromArray($item);
}

View file

@ -24,8 +24,11 @@
namespace ncc\Objects\ProjectConfiguration;
use ncc\Enums\RemoteSourceType;
use ncc\Enums\Versions;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Interfaces\ValidatableObjectInterface;
use ncc\Utilities\Functions;
use ncc\Utilities\Validate;
@ -33,7 +36,7 @@
* @author Zi Xing Narrakas
* @copyright Copyright (C) 2022-2023. Nosial - All Rights Reserved.
*/
class Dependency implements BytecodeObjectInterface
class Dependency implements BytecodeObjectInterface, ValidatableObjectInterface
{
/**
* @var string
@ -41,19 +44,35 @@
private $name;
/**
* @var string|null
* @var string
*/
private $source_type;
/**
* @var string
*/
private $version;
/**
* @var string|null
*/
private $source;
/**
* @var string|null
* Dependency constructor.
*
* @param string $name
* @param string|null $source_type
* @param string|null $source
* @param string|null $version
*/
private $version;
public function __construct(string $name, ?string $source_type=null, ?string $source=null, ?string $version=null)
{
$this->name = $name;
$this->source_type = $source_type ?? RemoteSourceType::NONE;
$this->version = $version ?? Versions::LATEST;
$this->source = $source;
}
/**
* Returns the name of the dependency
@ -79,22 +98,23 @@
/**
* Optional. Returns the type of source from where ncc can fetch the dependency from
*
* @return string|null
* @return string
*/
public function getSourceType(): ?string
public function getSourceType(): string
{
return $this->source_type;
}
/**
* Sets the type of source from where ncc can fetch the dependency from
* Sets the type of source from where ncc can fetch the dependency from,
* if the source type is not defined, it will be set to RemoteSourceType::NONE
*
* @param string|null $source_type
* @return void
*/
public function setSourceType(?string $source_type): void
{
$this->source_type = $source_type;
$this->source_type = ($source_type ?? RemoteSourceType::NONE);
}
/**
@ -125,50 +145,35 @@
*/
public function getVersion(): string
{
return $this->version ?? 'latest';
return $this->version ?? Versions::LATEST;
}
/**
* Returns the required version of the dependency or null if no version is required
* if the version is not defined, it will be set to Versions::LATEST
*
* @param string|null $version
* @return void
*/
public function setVersion(?string $version): void
{
$this->version = $version;
$this->version = ($version ?? Versions::LATEST);
}
/**
* Validates the dependency configuration
*
* @param bool $throw_exception
* @return bool
* @throws ConfigurationException
* @inheritDoc
*/
public function validate(bool $throw_exception): bool
public function validate(): void
{
if(!Validate::packageName($this->name))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid dependency name "%s"', $this->name));
}
return false;
throw new ConfigurationException(sprintf('Invalid dependency name "%s"', $this->name));
}
if($this->version !== null && !Validate::version($this->version))
if($this->version !== Versions::LATEST && !Validate::version($this->version))
{
if($throw_exception)
{
throw new ConfigurationException(sprintf('Invalid dependency version "%s"', $this->version));
}
return false;
throw new ConfigurationException(sprintf('Invalid dependency version "%s"', $this->version));
}
return true;
}
/**
@ -179,37 +184,34 @@
$results = [];
$results[($bytecode ? Functions::cbc('name') : 'name')] = $this->name;
if($this->source_type !== null && $this->source_type !== '')
{
$results[($bytecode ? Functions::cbc('source_type') : 'source_type')] = $this->source_type;
}
$results[($bytecode ? Functions::cbc('source_type') : 'source_type')] = $this->source_type;
$results[($bytecode ? Functions::cbc('version') : 'version')] = $this->version;
if($this->source !== null && $this->source !== '')
{
$results[($bytecode ? Functions::cbc('source') : 'source')] = $this->source;
}
if($this->version !== null && $this->version !== '')
{
$results[($bytecode ? Functions::cbc('version') : 'version')] = $this->version;
}
return $results;
}
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): Dependency
{
$object = new self();
$name = Functions::array_bc($data, 'name');
$object->name = Functions::array_bc($data, 'name');
$object->source_type = Functions::array_bc($data, 'source_type');
$object->source = Functions::array_bc($data, 'source');
$object->version = Functions::array_bc($data, 'version');
if($name === null)
{
throw new ConfigurationException('Dependency name is required');
}
return $object;
return new self($name,
Functions::array_bc($data, 'source_type'),
Functions::array_bc($data, 'source'),
Functions::array_bc($data, 'version')
);
}
}

View file

@ -45,13 +45,6 @@
*/
private $runner;
/**
* The message to display when the policy is invoked
*
* @var string|null
*/
private $message;
/**
* The execution process of the policy
*
@ -62,10 +55,17 @@
/**
* The configuration for exit handling
*
* @var ExitHandlers
* @var ExitHandlers|null
*/
private $exit_handlers;
/**
* The message to display when the policy is invoked
*
* @var string|null
*/
private $message;
/**
* @return string
*/

View file

@ -25,6 +25,7 @@
namespace ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Enums\SpecialConstants\RuntimeConstants;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Utilities\Functions;
@ -41,7 +42,7 @@
* The working directory to execute the policy in, if not specified the
* value "%CWD%" will be used as the default
*
* @var string|null
* @var string
*/
private $working_directory;
@ -89,11 +90,14 @@
/**
* Public Constructor
*/
public function __construct()
public function __construct(string $target, ?string $working_directory)
{
$this->tty = false;
$this->target = $target;
$this->working_directory = $working_directory ?? RuntimeConstants::CWD;
$this->options = [];
$this->environment_variables = [];
$this->silent = false;
$this->working_directory = "%CWD%";
$this->tty = true;
}
/**
@ -135,7 +139,7 @@
*/
public function setWorkingDirectory(?string $working_directory): void
{
$this->working_directory = $working_directory;
$this->working_directory = $working_directory ?? RuntimeConstants::CWD;
}
/**
@ -175,7 +179,7 @@
*/
public function isSilent(): bool
{
return $this->silent ?? false;
return $this->silent;
}
/**
@ -191,7 +195,7 @@
*/
public function isTty(): bool
{
return $this->tty ?? true;
return $this->tty;
}
/**
@ -234,8 +238,6 @@
$this->idle_timeout = $idle_timeout;
}
/**
* @inheritDoc
*/
@ -243,58 +245,37 @@
{
$results = [];
$results[($bytecode ? Functions::cbc('working_directory') : 'working_directory')] = $this->working_directory;
$results[($bytecode ? Functions::cbc('options') : 'options')] = $this->options;
$results[($bytecode ? Functions::cbc('environment_variables') : 'environment_variables')] = $this->environment_variables;
$results[($bytecode ? Functions::cbc('silent') : 'silent')] = (bool)$this->silent;
$results[($bytecode ? Functions::cbc('tty') : 'tty')] = (bool)$this->tty;
$results[($bytecode ? Functions::cbc('timeout') : 'timeout')] = (int)$this->timeout;
$results[($bytecode ? Functions::cbc('idle_timeout') : 'idle_timeout')] = (int)$this->idle_timeout;
if($this->target !== null)
{
$results[($bytecode ? Functions::cbc('target') : 'target')] = $this->target;
}
if($this->working_directory !== null)
{
$results[($bytecode ? Functions::cbc('working_directory') : 'working_directory')] = $this->working_directory;
}
if($this->options !== null)
{
$results[($bytecode ? Functions::cbc('options') : 'options')] = $this->options;
}
if($this->environment_variables !== null)
{
$results[($bytecode ? Functions::cbc('environment_variables') : 'environment_variables')] = $this->environment_variables;
}
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;
}
if($this->idle_timeout !== null)
{
$results[($bytecode ? Functions::cbc('idle_timeout') : 'idle_timeout')] = (int)$this->idle_timeout;
}
return $results;
}
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): Execute
{
$object = new self();
$target = Functions::array_bc($data, 'target');
if($target === null)
{
throw new ConfigurationException("The ExecutionPolicy's Execute target is required");
}
$object = new self($target, Functions::array_bc($data, 'working_directory'));
$object->target = Functions::array_bc($data, 'target');
$object->working_directory = Functions::array_bc($data, 'working_directory');
$object->options = Functions::array_bc($data, 'options') ?? [];
$object->environment_variables = Functions::array_bc($data, 'environment_variables') ?? [];
$object->silent = Functions::array_bc($data, 'silent') ?? false;

View file

@ -24,11 +24,26 @@
namespace ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Utilities\Functions;
class ExitHandle implements BytecodeObjectInterface
{
/**
* The name of another execution policy to execute (optionally) when this exit handle is triggered
*
* @var string
*/
private $run;
/**
* The exit code that needs to be returned from the process to trigger this handle
*
* @var int
*/
private $exit_code;
/**
* The message to display when the handle is triggered
*
@ -47,24 +62,11 @@
*/
private $end_process;
/**
* The name of another execution policy to execute (optionally) when this exit handle is triggered
*
* @var string|null
*/
private $run;
/**
* The exit code that needs to be returned from the process to trigger this handle
*
* @var int
*/
private $exit_code;
public function __construct()
public function __construct(string $run, int $exit_code=0)
{
$this->run = $run;
$this->exit_code = $exit_code;
$this->end_process = false;
$this->exit_code = 0;
}
/**
@ -161,15 +163,21 @@
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): ExitHandle
{
$object = new self();
$run = Functions::array_bc($data, 'run');
if($run === null)
{
throw new ConfigurationException('Exit handle "run" property is required');
}
$object = new self($run, (Functions::array_bc($data, 'exit_code') ?? 0));
$object->message = Functions::array_bc($data, 'message');
$object->end_process = Functions::array_bc($data, 'end_process') ?? false;
$object->message = Functions::array_bc($data, 'message');
$object->run = Functions::array_bc($data, 'run');
$object->exit_code = Functions::array_bc($data, 'exit_code') ?? 0;
return $object;
}

View file

@ -24,6 +24,7 @@
namespace ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Utilities\Functions;
@ -112,6 +113,7 @@
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): ExitHandlers
{

View file

@ -32,45 +32,58 @@
/**
* An array of execution policies to execute pre-installation
*
* @var string[]|null
* @var string[]
*/
private $pre_install;
/**
* An array of execution policies to execute post-installation
*
* @var string[]|null
* @var string[]
*/
private $post_install;
/**
* An array of execution policies to execute pre-uninstallation
*
* @var string[]|null
* @var string[]
*/
private $pre_uninstall;
/**
* An array of execution policies to execute post-uninstallation
*
* @var string[]|null
* @var string[]
*/
private $post_uninstall;
/**
* An array of execution policies to execute pre-update
*
* @var string[]|null
* @var string[]
*/
private $pre_update;
/**
* An array of execution policies to execute post-update
*
* @var string[]|null
* @var string[]
*/
private $post_update;
/**
* Installer constructor.
*/
public function __construct()
{
$this->pre_install = [];
$this->post_install = [];
$this->pre_uninstall = [];
$this->post_uninstall = [];
$this->pre_update = [];
$this->post_update = [];
}
/**
* @inheritDoc
*/
@ -78,32 +91,32 @@
{
$results = [];
if($this->pre_install !== null && count($this->pre_install) > 0)
if(count($this->pre_install) > 0)
{
$results[($bytecode ? Functions::cbc('pre_install') : 'pre_install')] = $this->pre_install;
}
if($this->post_install !== null && count($this->post_install) > 0)
if(count($this->post_install) > 0)
{
$results[($bytecode ? Functions::cbc('post_install') : 'post_install')] = $this->post_install;
}
if($this->pre_uninstall !== null && count($this->pre_uninstall) > 0)
if(count($this->pre_uninstall) > 0)
{
$results[($bytecode ? Functions::cbc('pre_uninstall') : 'pre_uninstall')] = $this->pre_uninstall;
}
if($this->post_uninstall !== null && count($this->post_uninstall) > 0)
if(count($this->post_uninstall) > 0)
{
$results[($bytecode ? Functions::cbc('post_uninstall') : 'post_uninstall')] = $this->post_uninstall;
}
if($this->pre_update !== null && count($this->pre_update) > 0)
if(count($this->pre_update) > 0)
{
$results[($bytecode ? Functions::cbc('pre_update') : 'pre_update')] = $this->pre_update;
}
if($this->post_update !== null && count($this->post_update) > 0)
if(count($this->post_update) > 0)
{
$results[($bytecode ? Functions::cbc('post_update') : 'post_update')] = $this->post_update;
}
@ -118,12 +131,12 @@
{
$object = new self();
$object->pre_install = Functions::array_bc($data, 'pre_install');
$object->post_install = Functions::array_bc($data, 'post_install');
$object->pre_uninstall = Functions::array_bc($data, 'pre_uninstall');
$object->post_uninstall = Functions::array_bc($data, 'post_uninstall');
$object->pre_update = Functions::array_bc($data, 'pre_update');
$object->post_update = Functions::array_bc($data, 'post_update');
$object->pre_install = Functions::array_bc($data, 'pre_install') ?? [];
$object->post_install = Functions::array_bc($data, 'post_install') ?? [];
$object->pre_uninstall = Functions::array_bc($data, 'pre_uninstall') ?? [];
$object->post_uninstall = Functions::array_bc($data, 'post_uninstall') ?? [];
$object->pre_update = Functions::array_bc($data, 'pre_update') ?? [];
$object->post_update = Functions::array_bc($data, 'post_update') ?? [];
return $object;
}

View file

@ -180,12 +180,7 @@
throw new ConfigurationException('The project configuration is missing the required property "compiler" in the project section.');
}
$object->options = Functions::array_bc($data, 'options');
if($object->options === null)
{
$object->options = [];
}
$object->options = Functions::array_bc($data, 'options') ?? [];
$object->update_source = Functions::array_bc($data, 'update_source');
if($object->update_source !== null)
{

View file

@ -24,6 +24,7 @@
namespace ncc\Objects\ProjectConfiguration;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Objects\ProjectConfiguration\UpdateSource\Repository;
use ncc\Utilities\Functions;
@ -44,6 +45,16 @@
*/
private $repository;
/**
* @param string $source
* @param Repository|null $repository
*/
public function __construct(string $source, ?Repository $repository=null)
{
$this->source = $source;
$this->repository = $repository;
}
/**
* @return string
*/
@ -77,10 +88,7 @@
}
/**
* Returns an array representation of the object
*
* @param bool $bytecode
* @return array
* @inheritDoc
*/
public function toArray(bool $bytecode=false): array
{
@ -90,25 +98,17 @@
];
}
/**
* Constructs object from an array representation
*
* @param array $data
* @return UpdateSource
* @inheritDoc
*/
public static function fromArray(array $data): UpdateSource
{
$object = new self();
$object->source = Functions::array_bc($data, 'source');
$object->repository = Functions::array_bc($data, 'repository');
if($object->repository !== null)
$source = Functions::array_bc($data, 'source');
if($source === null)
{
$object->repository = Repository::fromArray($object->repository);
throw new ConfigurationException('The UpdateSource requires the "source" property');
}
return $object;
return new self($source, Functions::array_bc($data, 'repository'));
}
}

View file

@ -25,6 +25,7 @@
namespace ncc\Objects\ProjectConfiguration\UpdateSource;
use ncc\Enums\RemoteSourceType;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Utilities\Functions;
@ -58,6 +59,14 @@
*/
private $ssl;
public function __construct(string $name, string $host, ?string $type=null, bool $ssl=false)
{
$this->name = $name;
$this->host = $host;
$this->type = $type;
$this->ssl = $ssl;
}
/**
* @return string
*/
@ -137,16 +146,30 @@
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): Repository
{
$object = new self();
$name = Functions::array_bc($data, 'name');
$type = Functions::array_bc($data, 'type');
$host = Functions::array_bc($data, 'host');
$ssl = Functions::array_bc($data, 'ssl') ?? false;
$object->name = Functions::array_bc($data, 'name');
$object->type = Functions::array_bc($data, 'type') ?? RemoteSourceType::UNKNOWN;
$object->host = Functions::array_bc($data, 'host');
$object->ssl = Functions::array_bc($data, 'ssl') ?? false;
if($name === null)
{
throw new ConfigurationException("The UpdateSource's Repository property requires 'main'");
}
return $object;
if($type === null)
{
throw new ConfigurationException("The UpdateSource's Repository property requires 'type'");
}
if($host === null)
{
throw new ConfigurationException("The UpdateSource's Repository property requires 'host'");
}
return new self($name, $host, $type, $ssl);
}
}