- 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:
parent
8ea203a0f1
commit
0e8397ec1f
23 changed files with 814 additions and 445 deletions
1
.idea/ncc.iml
generated
1
.idea/ncc.iml
generated
|
@ -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" />
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
114
src/ncc/Classes/PhpExtension/PhpCliTemplate.php
Normal file
114
src/ncc/Classes/PhpExtension/PhpCliTemplate.php
Normal 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')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
76
src/ncc/Classes/PhpExtension/PhpLibraryTemplate.php
Normal file
76
src/ncc/Classes/PhpExtension/PhpLibraryTemplate.php
Normal 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')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
20
src/ncc/Classes/PhpExtension/TemplateFiles/Makefile.tpl
Normal file
20
src/ncc/Classes/PhpExtension/TemplateFiles/Makefile.tpl
Normal 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
|
17
src/ncc/Classes/PhpExtension/TemplateFiles/Program.php.tpl
Normal file
17
src/ncc/Classes/PhpExtension/TemplateFiles/Program.php.tpl
Normal 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);
|
||||
}
|
||||
}
|
8
src/ncc/Classes/PhpExtension/TemplateFiles/class.php.tpl
Normal file
8
src/ncc/Classes/PhpExtension/TemplateFiles/class.php.tpl
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace %ASSEMBLY.NAME%;
|
||||
|
||||
class %ASSEMBLY.NAME%
|
||||
{
|
||||
|
||||
}
|
17
src/ncc/Classes/PhpExtension/TemplateFiles/main.php.tpl
Normal file
17
src/ncc/Classes/PhpExtension/TemplateFiles/main.php.tpl
Normal 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);
|
|
@ -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';
|
||||
}
|
28
src/ncc/Enums/Options/ProjectOptions.php
Normal file
28
src/ncc/Enums/Options/ProjectOptions.php
Normal 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';
|
||||
}
|
44
src/ncc/Enums/ProjectTemplates.php
Normal file
44
src/ncc/Enums/ProjectTemplates.php
Normal 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
|
||||
];
|
||||
}
|
36
src/ncc/Interfaces/TemplateInterface.php
Normal file
36
src/ncc/Interfaces/TemplateInterface.php
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = [];
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"project": {
|
||||
"compiler": {
|
||||
"extension": "php",
|
||||
"minimum_version": "8.0"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue