Added the ability to initialize a project
This commit is contained in:
parent
7926ef4077
commit
265cfce65b
10 changed files with 350 additions and 53 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\ComponentVersionNotFoundException;
|
||||
use ncc\Exceptions\ConstantReadonlyException;
|
||||
use ncc\Exceptions\DirectoryNotFoundException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\InvalidCredentialsEntryException;
|
||||
|
@ -62,4 +63,9 @@
|
|||
* @see ComponentVersionNotFoundException
|
||||
*/
|
||||
const ComponentVersionNotFoundException = -1708;
|
||||
|
||||
/**
|
||||
* @see ConstantReadonlyException
|
||||
*/
|
||||
const ConstantReadonlyException = -1709;
|
||||
}
|
8
src/ncc/Abstracts/Options/InitializeProjectOptions.php
Normal file
8
src/ncc/Abstracts/Options/InitializeProjectOptions.php
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Abstracts\Options;
|
||||
|
||||
abstract class InitializeProjectOptions
|
||||
{
|
||||
const CREATE_SOURCE_DIRECTORY = 1;
|
||||
}
|
20
src/ncc/Exceptions/ConstantReadonlyException.php
Normal file
20
src/ncc/Exceptions/ConstantReadonlyException.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class ConstantReadonlyException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::ConstantReadonlyException, $previous);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,11 @@
|
|||
|
||||
namespace ncc\Managers;
|
||||
|
||||
use ncc\Abstracts\Options\InitializeProjectOptions;
|
||||
use ncc\Exceptions\MalformedJsonException;
|
||||
use ncc\Objects\ProjectConfiguration;
|
||||
use ncc\Objects\ProjectConfiguration\Compiler;
|
||||
use ncc\Symfony\Component\Uid\Uuid;
|
||||
|
||||
class ProjectManager
|
||||
{
|
||||
|
@ -18,6 +22,13 @@
|
|||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private string $ProjectFilePath;
|
||||
|
||||
/**
|
||||
* The path that points the project's main directory
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private string $ProjectPath;
|
||||
|
||||
/**
|
||||
|
@ -28,6 +39,9 @@
|
|||
public function __construct(string $selected_directory)
|
||||
{
|
||||
$this->SelectedDirectory = $selected_directory;
|
||||
$this->ProjectFilePath = null;
|
||||
$this->ProjectPath = null;
|
||||
|
||||
$this->detectProjectPath();
|
||||
}
|
||||
|
||||
|
@ -42,6 +56,7 @@
|
|||
$selected_directory = $this->SelectedDirectory;
|
||||
|
||||
// Auto-resolve the trailing slash
|
||||
/** @noinspection PhpStrFunctionsInspection */
|
||||
if(substr($selected_directory, -1) !== '/')
|
||||
{
|
||||
$selected_directory .= $selected_directory . DIRECTORY_SEPARATOR;
|
||||
|
@ -56,37 +71,81 @@
|
|||
// Detect if project.json exists in the directory
|
||||
if(file_exists($selected_directory . 'project.json') == true)
|
||||
{
|
||||
$this->ProjectPath = $selected_directory . 'project.json';
|
||||
$this->ProjectPath = $selected_directory;
|
||||
$this->ProjectFilePath = $selected_directory . 'project.json';
|
||||
return true;
|
||||
}
|
||||
|
||||
// If not, check for pointer files
|
||||
$pointer_files = [
|
||||
'.ppm_package', // Backwards Compatibility
|
||||
'.ncc_project'
|
||||
];
|
||||
|
||||
foreach($pointer_files as $pointer_file)
|
||||
{
|
||||
if(file_exists($selected_directory . $pointer_file) && is_file($selected_directory . $pointer_file))
|
||||
{
|
||||
// TODO: Complete this
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the project sturcture
|
||||
*
|
||||
* @param Compiler $compiler
|
||||
* @param string $source
|
||||
* @param string $name
|
||||
* @param string $package
|
||||
* @return bool
|
||||
* @param array $options
|
||||
* @throws MalformedJsonException
|
||||
*/
|
||||
public function initializeProject(Compiler $compiler, string $name, string $package): bool
|
||||
public function initializeProject(Compiler $compiler, string $source, string $name, string $package, array $options=[])
|
||||
{
|
||||
$Project = new ProjectConfiguration();
|
||||
|
||||
// Set the compiler information
|
||||
$Project->Project->Compiler = $compiler;
|
||||
|
||||
// Set the assembly information
|
||||
$Project->Assembly->Name = $name;
|
||||
$Project->Assembly->Package = $package;
|
||||
$Project->Assembly->UUID = Uuid::v1()->toRfc4122();
|
||||
|
||||
// Set the build information
|
||||
$Project->Build->SourcePath = $source;
|
||||
$Project->Build->DefaultConfiguration = 'debug';
|
||||
|
||||
// Assembly constants if the program wishes to check for this
|
||||
$Project->Build->DefineConstants['ASSEMBLY_NAME'] = '%ASSEMBLY.NAME%';
|
||||
$Project->Build->DefineConstants['ASSEMBLY_PACKAGE'] = '%ASSEMBLY.PACKAGE%';
|
||||
$Project->Build->DefineConstants['ASSEMBLY_VERSION'] = '%ASSEMBLY.VERSION%';
|
||||
$Project->Build->DefineConstants['ASSEMBLY_UID'] = '%ASSEMBLY.UID%';
|
||||
|
||||
// Generate configurations
|
||||
$DebugConfiguration = new ProjectConfiguration\BuildConfiguration();
|
||||
$DebugConfiguration->Name = 'debug';
|
||||
$DebugConfiguration->OutputPath = 'build/debug';
|
||||
$DebugConfiguration->DefineConstants["DEBUG"] = '1'; // Debugging constant if the program wishes to check for this
|
||||
$Project->Build->Configurations[] = $DebugConfiguration;
|
||||
$ReleaseConfiguration = new ProjectConfiguration\BuildConfiguration();
|
||||
$ReleaseConfiguration->Name = 'release';
|
||||
$ReleaseConfiguration->OutputPath = 'build/release';
|
||||
$ReleaseConfiguration->DefineConstants["DEBUG"] = '0'; // Debugging constant if the program wishes to check for this
|
||||
$Project->Build->Configurations[] = $ReleaseConfiguration;
|
||||
|
||||
// Finally create project.json
|
||||
$Project->toFile($this->ProjectPath . DIRECTORY_SEPARATOR . 'project.json');
|
||||
|
||||
// Process options
|
||||
foreach($options as $option)
|
||||
{
|
||||
switch($option)
|
||||
{
|
||||
case InitializeProjectOptions::CREATE_SOURCE_DIRECTORY:
|
||||
if(file_exists($source) == false)
|
||||
{
|
||||
mkdir($source);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getProjectFilePath(): ?string
|
||||
{
|
||||
return $this->ProjectFilePath;
|
||||
}
|
||||
}
|
137
src/ncc/Objects/Constant.php
Normal file
137
src/ncc/Objects/Constant.php
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
use ncc\Exceptions\ConstantReadonlyException;
|
||||
use ncc\Symfony\Component\Uid\Uuid;
|
||||
use ncc\Utilities\Resolver;
|
||||
|
||||
class Constant
|
||||
{
|
||||
/**
|
||||
* The unique hash of the constant
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Hash;
|
||||
|
||||
/**
|
||||
* The package that manages this constant
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Scope;
|
||||
|
||||
/**
|
||||
* The name of the constant
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Name;
|
||||
|
||||
/**
|
||||
* The value of the constant
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $Value;
|
||||
|
||||
/**
|
||||
* Indicates if the constant is readonly or not
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $Readonly;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*
|
||||
* @param string $scope
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param bool $readonly
|
||||
*/
|
||||
public function __construct(string $scope, string $name, string $value, bool $readonly=false)
|
||||
{
|
||||
$this->Scope = $scope;
|
||||
$this->Name = $name;
|
||||
$this->Value = $value;
|
||||
$this->Readonly = $readonly;
|
||||
$this->Hash = Resolver::resolveConstantHash($this->Scope, $this->Name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the constant value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue(): string
|
||||
{
|
||||
return $this->Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the full name of the constant
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFullName(): string
|
||||
{
|
||||
return Resolver::resolveFullConstantName($this->Scope, $this->Name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value
|
||||
* @throws ConstantReadonlyException
|
||||
*/
|
||||
public function setValue(string $value, bool $readonly=false): void
|
||||
{
|
||||
if($this->Readonly == true)
|
||||
{
|
||||
throw new ConstantReadonlyException('Cannot set value to the constant \'' . $this->getFullName() . '\', constant is readonly');
|
||||
}
|
||||
|
||||
$this->Value = $value;
|
||||
$this->Readonly = $readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isReadonly(): bool
|
||||
{
|
||||
return $this->Readonly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHash(): string
|
||||
{
|
||||
return $this->Hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getScope(): string
|
||||
{
|
||||
return $this->Scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->Name;
|
||||
}
|
||||
}
|
|
@ -89,6 +89,12 @@
|
|||
*/
|
||||
public function toFile(string $path, bool $bytecode=false)
|
||||
{
|
||||
if(!$bytecode)
|
||||
{
|
||||
Functions::encodeJsonFile($this->toArray($bytecode), $path, Functions::FORCE_ARRAY | Functions::PRETTY | Functions::ESCAPE_UNICODE);
|
||||
return;
|
||||
}
|
||||
|
||||
Functions::encodeJsonFile($this->toArray($bytecode), $path, Functions::FORCE_ARRAY);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,13 +26,6 @@
|
|||
*/
|
||||
public $Options;
|
||||
|
||||
/**
|
||||
* Indicates if the libraries and resources for the build configuration are statically linked
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $StaticLinking;
|
||||
|
||||
/**
|
||||
* The build output path for the build configuration, eg; build/%BUILD.NAME%
|
||||
*
|
||||
|
@ -47,13 +40,6 @@
|
|||
*/
|
||||
public $DefineConstants;
|
||||
|
||||
/**
|
||||
* Indicates if one or more constants cannot be defined, it should result in a runtime error.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $StrictConstants;
|
||||
|
||||
/**
|
||||
* An array of files to exclude in this build configuration
|
||||
*
|
||||
|
@ -75,10 +61,8 @@
|
|||
public function __construct()
|
||||
{
|
||||
$this->Options = [];
|
||||
$this->StaticLinking = false;
|
||||
$this->OutputPath = 'build';
|
||||
$this->DefineConstants = [];
|
||||
$this->StrictConstants = false;
|
||||
$this->ExcludeFiles = [];
|
||||
$this->Dependencies = [];
|
||||
}
|
||||
|
@ -97,10 +81,8 @@
|
|||
|
||||
$ReturnResults[($bytecode ? Functions::cbc('name') : 'name')] = $this->Name;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('options') : 'options')] = $this->Options;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('static_linking') : 'static_linking')] = $this->StaticLinking;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('output_path') : 'output_path')] = $this->OutputPath;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('define_constants') : 'define_constants')] = $this->DefineConstants;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('strict_constants') : 'strict_constants')] = $this->StrictConstants;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('exclude_files') : 'exclude_files')] = $this->ExcludeFiles;
|
||||
$ReturnResults[($bytecode ? Functions::cbc('dependencies') : 'dependencies')] = [];
|
||||
|
||||
|
@ -132,11 +114,6 @@
|
|||
$BuildConfigurationObject->Options = Functions::array_bc($data, 'options');
|
||||
}
|
||||
|
||||
if(Functions::array_bc($data, 'static_linking') !== null)
|
||||
{
|
||||
$BuildConfigurationObject->StaticLinking = Functions::array_bc($data, 'static_linking');
|
||||
}
|
||||
|
||||
if(Functions::array_bc($data, 'output_path') !== null)
|
||||
{
|
||||
$BuildConfigurationObject->OutputPath = Functions::array_bc($data, 'output_path');
|
||||
|
@ -147,11 +124,6 @@
|
|||
$BuildConfigurationObject->DefineConstants = Functions::array_bc($data, 'define_constants');
|
||||
}
|
||||
|
||||
if(Functions::array_bc($data, 'strict_constants') !== null)
|
||||
{
|
||||
$BuildConfigurationObject->StrictConstants = Functions::array_bc($data, 'strict_constants');
|
||||
}
|
||||
|
||||
if(Functions::array_bc($data, 'exclude_files') !== null)
|
||||
{
|
||||
$BuildConfigurationObject->ExcludeFiles = Functions::array_bc($data, 'exclude_files');
|
||||
|
|
61
src/ncc/Runtime/Constants.php
Normal file
61
src/ncc/Runtime/Constants.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Runtime;
|
||||
|
||||
use ncc\Exceptions\ConstantReadonlyException;
|
||||
use ncc\Objects\Constant;
|
||||
use ncc\Utilities\Resolver;
|
||||
|
||||
class Constants
|
||||
{
|
||||
/**
|
||||
* The registered constants in memory
|
||||
*
|
||||
* @var Constant[]
|
||||
*/
|
||||
private static $Constants;
|
||||
|
||||
/**
|
||||
* Registers a new constant
|
||||
*
|
||||
* @param string $scope The package name that owns this constant
|
||||
* @param string $name The name of the constant
|
||||
* @param string $value The value of the constant
|
||||
* @param bool $readonly Indicates if the constant cannot be changed with the registerConstant function once it's registered
|
||||
* @return void
|
||||
* @throws ConstantReadonlyException
|
||||
*/
|
||||
public static function register(string $scope, string $name, string $value, bool $readonly=false)
|
||||
{
|
||||
// TODO: Add functionality to convert the constant name to be more memory-friendly with a size limit
|
||||
$constant_hash = Resolver::resolveConstantHash($scope, $name);
|
||||
|
||||
if(isset(self::$Constants[$constant_hash]))
|
||||
{
|
||||
self::$Constants[$constant_hash]->setValue($value, $readonly);
|
||||
return;
|
||||
}
|
||||
|
||||
self::$Constants[$constant_hash] = new Constant($scope, $name, $value, $readonly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the constant
|
||||
*
|
||||
* @param string $scope
|
||||
* @param string $name
|
||||
* @return void
|
||||
* @throws ConstantReadonlyException
|
||||
*/
|
||||
public static function delete(string $scope, string $name)
|
||||
{
|
||||
$constant_hash = Resolver::resolveConstantHash($scope, $name);
|
||||
|
||||
if(isset(self::$Constants[$constant_hash]) && self::$Constants[$constant_hash]->isReadonly())
|
||||
{
|
||||
throw new ConstantReadonlyException('Cannot delete the constant \'' . self::$Constants[$constant_hash]->getFullName() . '\', constant is readonly');
|
||||
}
|
||||
|
||||
unset(self::$Constants[$constant_hash]);
|
||||
}
|
||||
}
|
|
@ -112,4 +112,27 @@
|
|||
return $configs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the constant's full name
|
||||
*
|
||||
* @param string $scope
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public static function resolveFullConstantName(string $scope, string $name): string
|
||||
{
|
||||
return $scope . '.(' . $name . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the constant's unique hash
|
||||
*
|
||||
* @param string $scope
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public static function resolveConstantHash(string $scope, string $name): string
|
||||
{
|
||||
return hash('haval128,3', self::resolveFullConstantName($scope, $name));
|
||||
}
|
||||
}
|
|
@ -26,7 +26,12 @@
|
|||
],
|
||||
"options": {},
|
||||
"scope": "user",
|
||||
"define_constants": {"%ASSEMBLY.NAME%_HELLO": "Hello World!"},
|
||||
"define_constants": {
|
||||
"ASSEMBLY_NAME": "%ASSEMBLY.NAME%",
|
||||
"ASSEMBLY_PACKAGE": "%ASSEMBLY.PACKAGE%",
|
||||
"ASSEMBLY_VERSION": "%ASSEMBLY.VERSION%",
|
||||
"ASSEMBLY_UID": "%ASSEMBLY.UID%"
|
||||
},
|
||||
"dependencies": [
|
||||
{"name": "mbstring", "source": "extension", "version": "latest"},
|
||||
{"name": "com.example.dependency", "source": "default@github/example/ncc_dependency", "version": "latest"},
|
||||
|
@ -36,10 +41,10 @@
|
|||
{
|
||||
"name": "debug",
|
||||
"options": {},
|
||||
"static_linking": true,
|
||||
"output_path": "build/debug",
|
||||
"define_constants": {"%ASSEMBLY.NAME%_DEBUG": "1"},
|
||||
"strict_constants": false,
|
||||
"define_constants": {
|
||||
"DEBUG": "1"
|
||||
},
|
||||
"exclude_files": [],
|
||||
"dependencies": [
|
||||
{"name": "x-debug", "source": "extension", "version": "latest"}
|
||||
|
@ -48,10 +53,10 @@
|
|||
{
|
||||
"name": "release",
|
||||
"options": {},
|
||||
"static_linking": true,
|
||||
"output_path": "build/release",
|
||||
"define_constants": {},
|
||||
"strict_constants": false,
|
||||
"define_constants": {
|
||||
"DEBUG": "0"
|
||||
},
|
||||
"exclude_files": [],
|
||||
"dependencies": []
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue