- Added new template PhpCliTemplate phpcli

- Added new template PhpLibraryTemplate `phplib`
 - Implemented a template engine and refactored the CLI menu for the Project Manager and added a new `template` command
This commit is contained in:
Netkas 2023-09-01 03:47:01 -04:00
parent 8ea203a0f1
commit 0e8397ec1f
No known key found for this signature in database
GPG key ID: 5DAF58535614062B
23 changed files with 814 additions and 445 deletions

1
.idea/ncc.iml generated
View file

@ -5,6 +5,7 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/tests/example_project/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests/projects/lib/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/docs" />
<excludeFolder url="file://$MODULE_DIR$/tests/example_project/ncc" />

View file

@ -24,6 +24,9 @@ features and reduced the number of exceptions down to 15 exceptions.
- 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.
- Added a new interface class `TemplateInterface` to implement template classes
- Added new template PhpCliTemplate `phpcli`
- Added new template PhpLibraryTemplate `phplib`
### Fixed
- Fixed MITM attack vector in `\ncc\Classes > HttpClient > prepareCurl()`
@ -221,6 +224,7 @@ features and reduced the number of exceptions down to 15 exceptions.
- 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.
- Implemented a template engine and refactored the CLI menu for the Project Manager and added a new `template` command
### Removed

View file

@ -190,7 +190,7 @@
*/
private static function displayVersion(): void
{
Console::out(sprintf('ncc version %s (%s)', ncc_VERSION_NUMBER, ncc_VERSION_BRANCH));
Console::out(sprintf('ncc version %s (%s)', NCC_VERSION_NUMBER, NCC_VERSION_BRANCH));
}
/**

View file

@ -23,15 +23,10 @@
namespace ncc\CLI\Management;
use Exception;
use ncc\Enums\CompilerExtensionDefaultVersions;
use ncc\Enums\CompilerExtensions;
use ncc\Enums\CompilerExtensionSupportedVersions;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Enums\ProjectTemplates;
use ncc\Managers\ProjectManager;
use ncc\Objects\CliHelpSection;
use ncc\Objects\ProjectConfiguration\Compiler;
use ncc\Objects\ProjectConfiguration;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
@ -42,185 +37,136 @@
*
* @param $args
* @return void
* @throws ConfigurationException
* @throws IOException
* @throws PathNotFoundException
*/
public static function start($args): void
public static function start(array $args): void
{
if(isset($args['create']))
{
self::createProject($args);
self::initializeProject($args);
return;
}
if(isset($args['template']))
{
self::applyTemplate($args);
return;
}
self::displayOptions();
}
/**
* Creates a new project
* Initializes a new project
*
* @param $args
* @return void
* @throws ConfigurationException
* @throws IOException
* @throws PathNotFoundException
*/
public static function createProject($args): void
private static function initializeProject(array $args): void
{
// First determine the source directory of the project
$current_directory = getcwd();
if(isset($args['src']))
if(isset($args['path']) || isset($args['p']))
{
// Make sure directory separators are corrected
$args['src'] = str_ireplace('/', DIRECTORY_SEPARATOR, $args['src']);
$args['src'] = str_ireplace('\\', DIRECTORY_SEPARATOR, $args['src']);
// Remove the trailing slash
if(substr($args['src'], -1) === DIRECTORY_SEPARATOR)
{
$args['src'] = substr($args['src'], 0, -1);
}
$full_path = getcwd() . DIRECTORY_SEPARATOR . $args['src'];
if(file_exists($full_path) && is_dir($full_path))
{
$real_src = getcwd() . DIRECTORY_SEPARATOR . $args['src'];
}
else
{
Console::outError('The selected source directory \'' . $full_path . '\' was not found or is not a directory', true, 1);
return;
}
$project_path = $args['path'] ?? $args['p'];
}
else
{
$real_src = getcwd() . DIRECTORY_SEPARATOR . 'src';
Console::outError('Missing required option: --path|-p, please specify the path to the project', true, 1);
return;
}
// Remove basename from real_src
$real_src = Functions::removeBasename($real_src, $current_directory);
// Fetch the rest of the information needed for the project
//$compiler_extension = Console::getOptionInput($args, 'ce', 'Compiler Extension (php, java): ');
$package_name = Console::getOptionInput($args, 'package', 'Package Name (com.example.foo): ');
$project_name = Console::getOptionInput($args, 'name', 'Project Name (Foo Bar Library): ');
$Compiler = new Compiler();
// Detect the specified compiler extension
if(isset($args['ext']) || isset($args['extension']))
if(isset($args['name']) || isset($args['n']))
{
$compiler_extension = strtolower(($args['extension'] ?? $args['ext']));
if(in_array($compiler_extension, CompilerExtensions::ALL))
{
$Compiler->setExtension($compiler_extension);
}
else
{
Console::outError('Unsupported extension: ' . $compiler_extension, true, 1);
return;
}
$project_name = $args['name'] ?? $args['n'];
}
else
{
// Default PHP Extension
$Compiler->setExtension(CompilerExtensions::PHP);
Console::outError('Missing required option: --name|-n, please specify the name of the project', true, 1);
return;
}
// If a minimum and maximum version is specified
if(
(isset($args['max-version']) || isset($args['max-ver'])) &&
(isset($args['min-version']) || isset($args['min-ver']))
)
if(isset($args['package']) || isset($args['pkg']))
{
$max_version = strtolower($args['max-version'] ?? $args['max-ver']);
$min_version = strtolower($args['min-version'] ?? $args['min-ver']);
switch($Compiler->getExtension())
{
case CompilerExtensions::PHP:
if(!in_array($max_version, CompilerExtensionSupportedVersions::PHP))
{
Console::outError('The extension \'' . $Compiler->getExtension() . '\' does not support version ' . $max_version, true, 1);
return;
}
if(!in_array($min_version, CompilerExtensionSupportedVersions::PHP))
{
Console::outError('The extension \'' . $Compiler->getExtension() . '\' does not support version ' . $min_version, true, 1);
return;
}
$Compiler->setMaximumVersion($max_version);
$Compiler->setMinimumVersion($min_version);
break;
default:
Console::outError('Unsupported extension: ' . $Compiler->getExtension(), true, 1);
return;
}
$package_name = $args['package'] ?? $args['pkg'];
}
// If a single version is specified
elseif(isset($args['version']) || isset($args['ver']))
{
$version = strtolower($args['version'] ?? $args['ver']);
switch($Compiler->getExtension())
{
case CompilerExtensions::PHP:
if(!in_array($version, CompilerExtensionSupportedVersions::PHP))
{
Console::outError('The extension \'' . $Compiler->getExtension() . '\' does not support version ' . $version, true, 1);
return;
}
$Compiler->setMaximumVersion($version);
$Compiler->setMinimumVersion($version);
break;
default:
Console::outError('Unsupported extension: ' . $Compiler->getExtension(), true, 1);
return;
}
}
// If no version is specified, use the default version
else
{
switch($Compiler->getExtension())
{
case CompilerExtensions::PHP:
$Compiler->setMinimumVersion(CompilerExtensionDefaultVersions::PHP[0]);
$Compiler->setMaximumVersion(CompilerExtensionDefaultVersions::PHP[1]);
break;
default:
Console::outError('Unsupported extension: ' . $Compiler->getExtension(), true, 1);
return;
}
Console::outError('Missing required option: --package|--pkg, please specify the package name of the project', true, 1);
return;
}
// Now create the project
$ProjectManager = new ProjectManager($current_directory);
if(isset($args['ext']))
{
$compiler_extension = $args['ext'];
}
else
{
Console::outError('Missing required option: --ext, please specify the compiler extension of the project', true, 1);
return;
}
try
{
$ProjectManager->initializeProject($Compiler, $project_name, $package_name, $real_src);
}
catch (ConfigurationException $e)
{
Console::outException(sprintf('The project configuration is invalid: %s', $e->getMessage()), $e, 1);
return;
$project_manager = ProjectManager::initializeProject($project_path, $project_name, $package_name, $compiler_extension);
}
catch(Exception $e)
{
Console::outException('There was an unexpected error while trying to initialize the project', $e, 1);
Console::outException('There was an error while trying to initialize the project', $e, 1);
return;
}
Console::out('Project successfully created');
exit(0);
Console::out(sprintf('Project successfully created in \'%s\'', $project_manager->getProjectPath()));
Console::out(sprintf('Modify the project configuration in \'%s\'', $project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'project.json'));
}
private static function applyTemplate(array $args): void
{
if(isset($args['path']) || isset($args['p']))
{
$project_path = $args['path'] ?? $args['p'];
}
else
{
if(is_file(getcwd() . DIRECTORY_SEPARATOR . 'project.json'))
{
$project_path = getcwd();
}
else
{
Console::outError('Missing option: --path|-p, please specify the path to the project', true, 1);
return;
}
}
if(isset($args['name']) || isset($args['n']))
{
$template_name = $args['name'] ?? $args['n'];
}
else
{
Console::outError('Missing required option: --name|-n, please specify the name of the template', true, 1);
return;
}
try
{
$project_manager = new ProjectManager($project_path);
}
catch(Exception $e)
{
Console::outException('There was an error while trying to load the project', $e, 1);
return;
}
try
{
$project_manager->applyTemplate($template_name);
}
catch(Exception $e)
{
Console::outException('There was an error while trying to apply the template', $e, 1);
return;
}
Console::out(sprintf('Template successfully applied to project in \'%s\'', $project_manager->getProjectPath()));
}
/**
@ -232,19 +178,23 @@
{
$options = [
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
new CliHelpSection(['create', '--src', '--package', '--name'], 'Creates a new NCC project'),
new CliHelpSection(['create', '--ext'], 'Specifies the compiler extension'),
new CliHelpSection(['create', '--min-version', '--min-ver', '--maximum-ver', '-max-ver'], 'Specifies the compiler extension version'),
new CliHelpSection(['create-makefile'], 'Generates a Makefile for the project'),
new CliHelpSection(['create', '--path|-p', '--name|-n', '--package|--pkg', '--ext'], 'Creates a new ncc project'),
new CliHelpSection(['template', '--path|-p', '--name|-n'], 'Applies a template to the project'),
];
$options_padding = Functions::detectParametersPadding($options) + 4;
Console::out('Usage: ncc project {command} [options]');
Console::out('Options:' . PHP_EOL);
Console::out('Options:');
foreach($options as $option)
{
Console::out(' ' . $option->toString($options_padding));
}
Console::out(PHP_EOL . 'Available Templates:');
foreach(ProjectTemplates::ALL as $template)
{
Console::out(' ' . $template);
}
}
}

View file

@ -1,37 +1,56 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\NccExtension;
namespace ncc\Classes\NccExtension;
use ncc\Enums\SpecialConstants\BuildConstants;
use ncc\Enums\SpecialConstants\DateTimeConstants;
use ncc\Enums\SpecialConstants\InstallConstants;
use ncc\Enums\SpecialConstants\AssemblyConstants;
use ncc\Enums\SpecialConstants\RuntimeConstants;
use ncc\Managers\ProjectManager;
use ncc\Objects\InstallationPaths;
use ncc\Objects\ProjectConfiguration;
use ncc\Objects\ProjectConfiguration\Assembly;
class ConstantCompiler
{
/**
* Compiles all constants (Usually used during pre-compiling time)
*
* @param ProjectConfiguration $project_configuration
* @param string|null $input
* @return string
*/
public static function compileConstants(ProjectConfiguration $project_configuration, ?string $input): string
{
$input = self::compileAssemblyConstants($input, $project_configuration->getAssembly());
$input = self::compileBuildConstants($input);
$input = self::compileDateTimeConstants($input, time());
$input = self::compileRuntimeConstants($input);
return $input;
}
/**
* Compiles assembly constants about the project (Usually used during compiling time)
*
@ -46,15 +65,19 @@ namespace ncc\Classes\NccExtension;
return null;
}
if($assembly->getName() !== null)
{
$input = str_replace(AssemblyConstants::ASSEMBLY_NAME, $assembly->getName(), $input);
}
if($assembly->getPackage() !== null)
{
$input = str_replace(AssemblyConstants::ASSEMBLY_PACKAGE, $assembly->getPackage(), $input);
}
$input = str_replace(
[
AssemblyConstants::ASSEMBLY_NAME,
AssemblyConstants::ASSEMBLY_PACKAGE,
AssemblyConstants::ASSEMBLY_VERSION,
AssemblyConstants::ASSEMBLY_UID
],
[
$assembly->getName(),
$assembly->getPackage(),
$assembly->getVersion(),
$assembly->getUuid()
], $input);
if($assembly->getDescription() !== null)
{
@ -80,17 +103,6 @@ namespace ncc\Classes\NccExtension;
{
$input =str_replace(AssemblyConstants::ASSEMBLY_TRADEMARK, $assembly->getTrademark(), $input);
}
if($assembly->getVersion() !== null)
{
$input = str_replace(AssemblyConstants::ASSEMBLY_VERSION, $assembly->getVersion(), $input);
}
if($assembly->getUuid() !== null)
{
$input = str_replace(AssemblyConstants::ASSEMBLY_UID, $assembly->getUuid(), $input);
}
return $input;
}
@ -126,10 +138,10 @@ namespace ncc\Classes\NccExtension;
* Compiles installation constants (Usually used during compiling time)
*
* @param string|null $input
* @param InstallationPaths $installationPaths
* @param InstallationPaths $installation_paths
* @return string|null
*/
public static function compileInstallConstants(?string $input, InstallationPaths $installationPaths): ?string
public static function compileInstallConstants(?string $input, InstallationPaths $installation_paths): ?string
{
if($input === null)
{
@ -144,10 +156,10 @@ namespace ncc\Classes\NccExtension;
InstallConstants::INSTALL_PATH_DATA
],
[
$installationPaths->getInstallationpath(),
$installationPaths->getBinPath(),
$installationPaths->getSourcePath(),
$installationPaths->getDataPath()
$installation_paths->getInstallationpath(),
$installation_paths->getBinPath(),
$installation_paths->getSourcePath(),
$installation_paths->getDataPath()
], $input);
}

View file

@ -0,0 +1,114 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Enums\Options\ProjectOptions;
use ncc\Enums\Runners;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\TemplateInterface;
use ncc\Managers\ProjectManager;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
use ncc\Utilities\IO;
class PhpCliTemplate implements TemplateInterface
{
/**
* @inheritDoc
* @param ProjectManager $project_manager
* @throws IOException
* @throws PathNotFoundException
* @throws ConfigurationException
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
$project_manager->getProjectConfiguration()->addExecutionPolicy(
new ExecutionPolicy('main_policy', Runners::PHP, new ExecutionPolicy\Execute('main'))
);
$project_manager->getProjectConfiguration()->getBuild()->setMain('main_policy');
$project_manager->getProjectConfiguration()->getProject()->addOption(ProjectOptions::CREATE_SYMLINK, true);
self::writeProgramTemplate($project_manager);
self::writeMainEntryTemplate($project_manager);
self::writeMakefileTemplate($project_manager);
$project_manager->save();
}
/**
* Writes the Program.php file to the project source directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeProgramTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectSourcePath() . DIRECTORY_SEPARATOR . 'Program.php',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Program.php.tpl')
)
);
}
/**
* Writes the main.php file to the project directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeMainEntryTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'main',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'main.php.tpl')
)
);
}
/**
* Writes the Makefile to the project directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeMakefileTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'Makefile',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Makefile.tpl')
)
);
}
}

View file

@ -0,0 +1,76 @@
<?php
/*
* Copyright (c) Nosial 2022-2023, all rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including without
* limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
namespace ncc\Classes\PhpExtension;
use ncc\Classes\NccExtension\ConstantCompiler;
use ncc\Exceptions\IOException;
use ncc\Exceptions\PathNotFoundException;
use ncc\Interfaces\TemplateInterface;
use ncc\Managers\ProjectManager;
use ncc\Utilities\IO;
class PhpLibraryTemplate implements TemplateInterface
{
/**
* @inheritDoc
*/
public static function applyTemplate(ProjectManager $project_manager): void
{
self::createClassTemplate($project_manager);
self::writeMakefileTemplate($project_manager);
}
/**
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function createClassTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectSourcePath() . DIRECTORY_SEPARATOR . $project_manager->getProjectConfiguration()->getAssembly()->getName() . '.php',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'class.php.tpl')
)
);
}
/**
* Writes the Makefile to the project directory
*
* @param ProjectManager $project_manager
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
private static function writeMakefileTemplate(ProjectManager $project_manager): void
{
IO::fwrite(
$project_manager->getProjectPath() . DIRECTORY_SEPARATOR . 'Makefile',
ConstantCompiler::compileConstants($project_manager->getProjectConfiguration(),
IO::fread(__DIR__ . DIRECTORY_SEPARATOR . 'TemplateFiles' . DIRECTORY_SEPARATOR . 'Makefile.tpl')
)
);
}
}

View file

@ -0,0 +1,20 @@
# Variables
CONFIG ?= release
LOG_LEVEL = debug
OUTDIR = build/$(CONFIG)
PACKAGE = $(OUTDIR)/%ASSEMBLY.PACKAGE%.ncc
# Default Target
all: build
# Build Steps
build:
ncc build --config=$(CONFIG) --log-level $(LOG_LEVEL)
install:
ncc package install --package=$(PACKAGE) --skip-dependencies --reinstall -y --log-level $(LOG_LEVEL)
clean:
rm -rf build
.PHONY: all build install clean

View file

@ -0,0 +1,17 @@
<?php
namespace %ASSEMBLY.NAME%;
class Program
{
/**
* %ASSEMBLY.NAME% main entry point
*
* @param string[] $args
* @return void
*/
public static function main(array $args): void
{
print("Hello World from %ASSEMBLY.PACKAGE%!" . PHP_EOL);
}
}

View file

@ -0,0 +1,8 @@
<?php
namespace %ASSEMBLY.NAME%;
class %ASSEMBLY.NAME%
{
}

View file

@ -0,0 +1,17 @@
<?php
if (PHP_SAPI !== 'cli')
{
print('%ASSEMBLY.PACKAGE% must be run from the command line.' . PHP_EOL);
exit(1);
}
if(!isset($argv))
{
trigger_error('No $argv found, maybe you are using php-cgi?', E_USER_ERROR);
}
require('ncc');
import('%ASSEMBLY.PACKAGE%', 'latest');
\%ASSEMBLY.NAME%\Program::main($argv);

View file

@ -24,5 +24,13 @@
final class InitializeProjectOptions
{
public const CREATE_SOURCE_DIRECTORY = 1;
/**
* A custom path to the project's source directory
*/
public const PROJECT_SRC_PATH = 'PROJECT_SRC_PATH';
/**
* A boolean option that indicates whether to overwrite the project file if it already exists
*/
public const OVERWRITE_PROJECT_FILE = 'OVERWRITE_PROJECT_FILE';
}

View file

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

View file

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

View file

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

View file

@ -502,9 +502,9 @@
}
else
{
$this->handleExit($package, $version, $unit->getExecutionPolicy()->getExitHandlers()->getSuccess(), $process);
$this->handleExit($package, $version, $unit->getExecutionPolicy()->getExitHandlers()->getWarning(), $process);
$this->handleExit($package, $version, $unit->executigetExecutionPolicy()on_policy->getExitHandlers()->getError(), $process);
$this->handleExit($package, $version, $unit->getExecutionPolicy()->getExitHandlers()?->getSuccess(), $process);
$this->handleExit($package, $version, $unit->getExecutionPolicy()->getExitHandlers()?->getWarning(), $process);
$this->handleExit($package, $version, $unit->getExecutionPolicy()->getExitHandlers()?->getError(), $process);
}
}

View file

@ -25,9 +25,13 @@
namespace ncc\Managers;
use JetBrains\PhpStorm\NoReturn;
use ncc\Classes\PhpExtension\PhpCliTemplate;
use ncc\Classes\PhpExtension\PhpLibraryTemplate;
use ncc\Enums\Options\BuildConfigurationValues;
use ncc\Enums\Options\InitializeProjectOptions;
use ncc\Classes\NccExtension\PackageCompiler;
use ncc\Enums\ProjectTemplates;
use ncc\Exceptions\BuildException;
use ncc\Exceptions\ConfigurationException;
use ncc\Exceptions\IOException;
@ -35,9 +39,8 @@
use ncc\Exceptions\PathNotFoundException;
use ncc\Objects\ProjectConfiguration;
use ncc\Objects\ProjectConfiguration\Compiler;
use ncc\ThirdParty\Symfony\Uid\Uuid;
use ncc\Utilities\Console;
use ncc\Utilities\Validate;
use RuntimeException;
class ProjectManager
{
@ -58,7 +61,7 @@
/**
* The loaded project configuration, null if no project file is loaded
*
* @var ProjectConfiguration|null
* @var ProjectConfiguration
*/
private $project_configuration;
@ -69,13 +72,14 @@
* @throws ConfigurationException
* @throws IOException
* @throws PathNotFoundException
* @throws NotSupportedException
*/
public function __construct(string $path)
{
// Auto-resolve the trailing slash
if(!str_ends_with($path, '/'))
if(str_ends_with($path, '/'))
{
$path .= DIRECTORY_SEPARATOR;
$path = substr($path, 0, -1);
}
// Detect if the folder exists or not
@ -85,139 +89,7 @@
}
$this->project_path = $path;
$this->project_file_path = $path . 'project.json';
if(file_exists($this->project_file_path))
{
$this->load();
}
}
/**
* Initializes the project structure
*
* @param Compiler $compiler
* @param string $name
* @param string $package
* @param string|null $src
* @param array $options
* @throws ConfigurationException
* @throws IOException
*/
public function initializeProject(Compiler $compiler, string $name, string $package, ?string $src=null, array $options=[]): void
{
// Validate the project information first
if(!Validate::packageName($package))
{
throw new ConfigurationException('The given package name \'' . $package . '\' is not a valid package name');
}
if(!Validate::projectName($name))
{
throw new ConfigurationException('The given project name \'' . $name . '\' is not valid');
}
if(file_exists($this->project_path . DIRECTORY_SEPARATOR . 'project.json'))
{
throw new IOException('A project has already been initialized in \'' . $this->project_path . DIRECTORY_SEPARATOR . 'project.json' . '\'');
}
$this->project_configuration = new ProjectConfiguration();
// Set the compiler information
$this->project_configuration->getProject()->setCompiler($compiler);
// Set the assembly information
$this->project_configuration->getAssembly()->setName($name);
$this->project_configuration->getAssembly()->setPackage($package);
$this->project_configuration->getAssembly()->setVersion('1.0.0');
$this->project_configuration->getAssembly()->setUuid(Uuid::v1()->toRfc4122());
// Set the build information
$this->project_configuration->getBuild()->setSourcePath($src);
if($this->project_configuration->getBuild()->getSourcePath() === null)
{
$this->project_configuration->getBuild()->setSourcePath($this->project_path);
}
$this->project_configuration->getBuild()->setDefaultConfiguration('debug');
// Assembly constants if the program wishes to check for this
$this->project_configuration->getBuild()->addDefineConstant('ASSEMBLY_PACKAGE', '%ASSEMBLY.PACKAGE%');
$this->project_configuration->getBuild()->addDefineConstant('ASSEMBLY_VERSION', '%ASSEMBLY.VERSION%');
$this->project_configuration->getBuild()->addDefineConstant('ASSEMBLY_UID', '%ASSEMBLY.UID%');
// Generate configurations
$debug_configuration = new ProjectConfiguration\Build\BuildConfiguration();
$debug_configuration->setName('debug');
$debug_configuration->setOutputPath('build/debug');
$debug_configuration->setDefinedConstant('DEBUG', '1'); // Debugging constant if the program wishes to check for this
$this->project_configuration->getBuild()->addBuildConfiguration($debug_configuration);
$release_configuration = new ProjectConfiguration\Build\BuildConfiguration();
$release_configuration->setName('release');
$release_configuration->setOutputPath('build/release');
$release_configuration->setDefinedConstant('DEBUG', '0'); // Debugging constant if the program wishes to check for this
$this->project_configuration->getBuild()->addBuildConfiguration($release_configuration);
// Finally, create project.json
$this->project_configuration->toFile($this->project_path . DIRECTORY_SEPARATOR . 'project.json');
// And create the project directory for additional assets/resources
$Folders = [
$this->project_path . DIRECTORY_SEPARATOR . 'ncc',
$this->project_path . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'cache',
$this->project_path . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'config',
];
foreach($Folders as $folder)
{
if(!file_exists($folder) && !mkdir($folder) && !is_dir($folder))
{
throw new RuntimeException(sprintf('Directory "%s" was not created', $folder));
}
}
// Process options
foreach($options as $option)
{
if (
$option === InitializeProjectOptions::CREATE_SOURCE_DIRECTORY &&
!file_exists($this->project_configuration->getBuild()->getSourcePath()) &&
!mkdir($concurrentDirectory = $this->project_configuration->getBuild()->getSourcePath()) &&
!is_dir($concurrentDirectory)
)
{
throw new RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
}
}
}
/**
* Determines if a project configuration is loaded or not
*
* @return bool
*/
public function projectLoaded(): bool
{
return $this->project_configuration !== null;
}
/**
* Attempts to load the project configuration
*
* @return void
* @throws IOException
* @throws PathNotFoundException
*/
public function load(): void
{
if(!is_file($this->project_file_path))
{
throw new PathNotFoundException($this->project_file_path);
}
$this->project_file_path = $this->project_path . DIRECTORY_SEPARATOR . 'project.json';
$this->project_configuration = ProjectConfiguration::fromFile($this->project_file_path);
}
@ -229,11 +101,6 @@
*/
public function save(): void
{
if(!$this->projectLoaded())
{
return;
}
$this->project_configuration->toFile($this->project_file_path);
}
@ -241,17 +108,9 @@
* Returns the ProjectConfiguration object
*
* @return ProjectConfiguration
* @throws ConfigurationException
* @throws IOException
* @throws PathNotFoundException
*/
public function getProjectConfiguration(): ProjectConfiguration
{
if($this->project_configuration === null)
{
$this->load();
}
return $this->project_configuration;
}
@ -265,6 +124,15 @@
return $this->project_path;
}
/**
* Returns the project's source path
*
* @return string|null
*/
public function getProjectSourcePath(): ?string
{
return $this->project_path . DIRECTORY_SEPARATOR . $this->project_configuration->getBuild()->getSourcePath();
}
/**
* Compiles the project into a package
@ -281,4 +149,103 @@
{
return PackageCompiler::compile($this, $build_configuration);
}
/**
* Applies the given template to the project
*
* @param string $template_name
* @return void
* @throws ConfigurationException
* @throws IOException
* @throws NotSupportedException
* @throws PathNotFoundException
*/
public function applyTemplate(string $template_name): void
{
switch(strtolower($template_name))
{
case ProjectTemplates::PHP_CLI:
PhpCliTemplate::applyTemplate($this);
break;
case ProjectTemplates::PHP_LIBRARY:
PhpLibraryTemplate::applyTemplate($this);
break;
default:
throw new NotSupportedException('The given template \'' . $template_name . '\' is not supported');
}
}
/**
* Initializes the project structure
*
* @param string $project_path The directory for the project to be initialized in
* @param string $name The name of the project eg; ProjectLib
* @param string $package The standard package name eg; com.example.project
* @param Compiler $compiler The compiler to use for this project
* @param array $options An array of options to use when initializing the project
* @return ProjectManager
* @throws ConfigurationException
* @throws IOException
* @throws NotSupportedException
* @throws PathNotFoundException
*/
public static function initializeProject(string $project_path, string $name, string $package, string $compiler, array $options=[]): ProjectManager
{
if(str_ends_with($project_path, DIRECTORY_SEPARATOR))
{
$project_path = substr($project_path, 0, -1);
}
if(is_file($project_path . DIRECTORY_SEPARATOR . 'project.json'))
{
if(!isset($options[InitializeProjectOptions::OVERWRITE_PROJECT_FILE]))
{
throw new IOException('A project has already been initialized in \'' . $project_path . DIRECTORY_SEPARATOR . 'project.json' . '\'');
}
Console::out(sprintf('Overwriting project.json in \'%s\'', $project_path));
unlink($project_path . DIRECTORY_SEPARATOR . 'project.json');
}
$project_src = $options[InitializeProjectOptions::PROJECT_SRC_PATH] ?? ('src' . DIRECTORY_SEPARATOR . $name);
if(str_ends_with($project_src, DIRECTORY_SEPARATOR))
{
$project_src = substr($project_src, 0, -1);
}
if(!mkdir($project_path, 0777, true) && !is_dir($project_path))
{
throw new IOException(sprintf('Project directory "%s" was not created', $project_path));
}
if(!mkdir($project_path . DIRECTORY_SEPARATOR . $project_src, 0777, true) && !is_dir($project_path . DIRECTORY_SEPARATOR . $project_src))
{
throw new IOException(sprintf('Project source directory "%s" was not created', $project_path . DIRECTORY_SEPARATOR . $project_src));
}
// Create the build configuration
$build = new ProjectConfiguration\Build($project_src);
$build->addDefineConstant('ASSEMBLY_PACKAGE', '%ASSEMBLY.PACKAGE%');
$build->addDefineConstant('ASSEMBLY_VERSION', '%ASSEMBLY.VERSION%');
$build->addDefineConstant('ASSEMBLY_UID', '%ASSEMBLY.UID%');
// Generate the Debug & Release build configurations
$debug_configuration = new ProjectConfiguration\Build\BuildConfiguration('debug', 'build' . DIRECTORY_SEPARATOR . 'debug');
$debug_configuration->setDefinedConstant('DEBUG', '1');
$build->addBuildConfiguration(new ProjectConfiguration\Build\BuildConfiguration('release', 'build' . DIRECTORY_SEPARATOR . 'release'));
$build->addBuildConfiguration($debug_configuration);
$build->setDefaultConfiguration('release');
$project_configuration = new ProjectConfiguration(
new ProjectConfiguration\Project($compiler),
new ProjectConfiguration\Assembly($name, $package),
$build
);
// Finally, create project.json and return a new ProjectManager
$project_configuration->toFile($project_path . DIRECTORY_SEPARATOR . 'project.json');
return new ProjectManager($project_path);
}
}

View file

@ -140,77 +140,6 @@
$this->execution_policies = $execution_policies;
}
/**
* @return Installer|null
*/
public function getInstaller(): ?Installer
{
return $this->installer;
}
/**
* @param Installer|null $installer
*/
public function setInstaller(?Installer $installer): void
{
$this->installer = $installer;
}
/**
* @return Build
*/
public function getBuild(): Build
{
return $this->build;
}
/**
* @param Build $build
*/
public function setBuild(Build $build): void
{
$this->build = $build;
}
/**
* @inheritDoc
*/
public function validate(): void
{
$this->project->validate();
$this->assembly->validate();
$this->build->validate();
if($this->build->getMain() !== null)
{
if($this->execution_policies === null || count($this->execution_policies) === 0)
{
throw new ConfigurationException(sprintf('Build configuration build.main uses an execution policy "%s" but no policies are defined', $this->build->getMain()));
}
$found = false;
foreach($this->execution_policies as $policy)
{
if($policy->getName() === $this->build->getMain())
{
$found = true;
break;
}
}
if(!$found)
{
throw new ConfigurationException(sprintf('Build configuration build.main points to a undefined execution policy "%s"', $this->build->getMain()));
}
if($this->build->getMain() === BuildConfigurationValues::ALL)
{
throw new ConfigurationException(sprintf('Build configuration build.main cannot be set to "%s"', BuildConfigurationValues::ALL));
}
}
}
/**
* @param string $name
* @return ExecutionPolicy|null
@ -228,6 +157,44 @@
return null;
}
/**
* @param ExecutionPolicy $policy
* @param bool $overwrite
* @return void
* @throws ConfigurationException
*/
public function addExecutionPolicy(ExecutionPolicy $policy, bool $overwrite=true): void
{
if(!$overwrite)
{
foreach($this->execution_policies as $executionPolicy)
{
if($executionPolicy->getName() === $policy->getName())
{
throw new ConfigurationException('An execution policy with the name \'' . $policy->getName() . '\' already exists');
}
}
}
$this->execution_policies[] = $policy;
}
/**
* @param string $name
* @return void
*/
public function removeExecutionPolicy(string $name): void
{
foreach($this->execution_policies as $key => $executionPolicy)
{
if($executionPolicy->getName() === $name)
{
unset($this->execution_policies[$key]);
return;
}
}
}
/**
* Runs a check on the project configuration and determines what policies are required
*
@ -387,6 +354,77 @@
return $required_policies;
}
/**
* @return Installer|null
*/
public function getInstaller(): ?Installer
{
return $this->installer;
}
/**
* @param Installer|null $installer
*/
public function setInstaller(?Installer $installer): void
{
$this->installer = $installer;
}
/**
* @return Build
*/
public function getBuild(): Build
{
return $this->build;
}
/**
* @param Build $build
*/
public function setBuild(Build $build): void
{
$this->build = $build;
}
/**
* @inheritDoc
*/
public function validate(): void
{
$this->project->validate();
$this->assembly->validate();
$this->build->validate();
if($this->build->getMain() !== null)
{
if($this->execution_policies === null || count($this->execution_policies) === 0)
{
throw new ConfigurationException(sprintf('Build configuration build.main uses an execution policy "%s" but no policies are defined', $this->build->getMain()));
}
$found = false;
foreach($this->execution_policies as $policy)
{
if($policy->getName() === $this->build->getMain())
{
$found = true;
break;
}
}
if(!$found)
{
throw new ConfigurationException(sprintf('Build configuration build.main points to a undefined execution policy "%s"', $this->build->getMain()));
}
if($this->build->getMain() === BuildConfigurationValues::ALL)
{
throw new ConfigurationException(sprintf('Build configuration build.main cannot be set to "%s"', BuildConfigurationValues::ALL));
}
}
}
/**
* Writes a json representation of the object to a file
*
@ -493,7 +531,7 @@
foreach($this->execution_policies as $executionPolicy)
{
$execution_policies[$executionPolicy->getName()] = $executionPolicy->toArray($bytecode);
$execution_policies[] = $executionPolicy->toArray($bytecode);
}
$results[($bytecode ? Functions::cbc('execution_policies') : 'execution_policies')] = $execution_policies;

View file

@ -24,6 +24,7 @@
namespace ncc\Objects\ProjectConfiguration;
use ncc\Exceptions\ConfigurationException;
use ncc\Interfaces\BytecodeObjectInterface;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy\Execute;
use ncc\Objects\ProjectConfiguration\ExecutionPolicy\ExitHandlers;
@ -66,6 +67,20 @@
*/
private $message;
/**
* ExecutionPolicy constructor.
*
* @param string $name
* @param string $runner
* @param Execute $execute
*/
public function __construct(string $name, string $runner, Execute $execute)
{
$this->name = $name;
$this->runner = $runner;
$this->execute = $execute;
}
/**
* @return string
*/
@ -192,22 +207,34 @@
/**
* @inheritDoc
* @throws ConfigurationException
*/
public static function fromArray(array $data): ExecutionPolicy
{
$object = new self();
$name = Functions::array_bc($data, 'name');
$runner = Functions::array_bc($data, 'runner');
$execute = Functions::array_bc($data, 'execute');
$object->name = Functions::array_bc($data, 'name');
$object->runner = Functions::array_bc($data, 'runner');
$object->message = Functions::array_bc($data, 'message');
$object->execute = Functions::array_bc($data, 'execute');
$object->exit_handlers = Functions::array_bc($data, 'exit_handlers');
if($object->execute !== null)
if($name === null || $name === '')
{
$object->execute = Execute::fromArray($object->execute);
throw new ConfigurationException('ExecutionPolicy name cannot be null or empty');
}
if($runner === null || $runner === '')
{
throw new ConfigurationException('ExecutionPolicy runner cannot be null or empty');
}
if($execute === null)
{
throw new ConfigurationException('ExecutionPolicy execute cannot be null');
}
$object = new self($name, $runner, Execute::fromArray($execute));
$object->message = Functions::array_bc($data, 'message');
$object->exit_handlers = Functions::array_bc($data, 'exit_handlers');
if($object->exit_handlers !== null)
{
$object->exit_handlers = ExitHandlers::fromArray($object->exit_handlers);

View file

@ -88,9 +88,12 @@
private $idle_timeout;
/**
* Public Constructor
* Execute constructor.
*
* @param string $target
* @param string|null $working_directory
*/
public function __construct(string $target, ?string $working_directory)
public function __construct(string $target, ?string $working_directory=null)
{
$this->target = $target;
$this->working_directory = $working_directory ?? RuntimeConstants::CWD;

View file

@ -52,9 +52,16 @@
/**
* Public Constructor
* @param string|Compiler $compiler
* @throws NotSupportedException
*/
public function __construct(Compiler $compiler)
public function __construct(string|Compiler $compiler)
{
if(is_string($compiler))
{
$compiler = new Compiler($compiler);
}
$this->compiler = $compiler;
$this->options = [];
}

View file

@ -20,7 +20,7 @@
*
*/
$build_directory = __DIR__ . DIRECTORY_SEPARATOR . 'ncc' . DIRECTORY_SEPARATOR . 'build';
$build_directory = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'build';
$autoload_path = $build_directory . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'autoload.php';
if(!is_dir($build_directory))

View file

@ -1,8 +0,0 @@
{
"project": {
"compiler": {
"extension": "php",
"minimum_version": "8.0"
}
}
}