Completed installation script

This commit is contained in:
Netkas 2022-08-12 20:32:59 -04:00
parent bcb9d6c1c2
commit 41fc5604fc
33 changed files with 908 additions and 370 deletions

View file

@ -35,7 +35,9 @@
'generate_build_files.php',
'installer',
'checksum.bin'.
'build_files'
'build_files',
'ncc.sh',
'extension'
];
ncc\Utilities\Console::out('Creating build_files ...');

View file

@ -0,0 +1,503 @@
#!/bin/php
# ------------------------------------------------------------------
# Nosial Code Compiler (NCC) Installation Script
#
# Nosial Code Compiler is a program written in PHP designed
# to be a multipurpose compiler, package manager and toolkit.
#
# Dependency:
# PHP 8.0+
# ------------------------------------------------------------------
<?PHP
use ncc\Abstracts\Scopes;
use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\ComponentVersionNotFoundException;
use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InvalidScopeException;
use ncc\Managers\CredentialManager;
use ncc\ncc;
use ncc\Objects\CliHelpSection;
use ncc\ThirdParty\Symfony\Filesystem\Exception\IOException;
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
use ncc\ThirdParty\Symfony\Process\Exception\ProcessFailedException;
use ncc\ThirdParty\Symfony\process\PhpExecutableFinder;
use ncc\ThirdParty\Symfony\Process\Process;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
use ncc\Utilities\Validate;
use ncc\ZiProto\ZiProto;
# Global Variables
$NCC_INSTALL_PATH=DIRECTORY_SEPARATOR . 'etc' . DIRECTORY_SEPARATOR . 'ncc';
$NCC_DATA_PATH=DIRECTORY_SEPARATOR . 'var' . DIRECTORY_SEPARATOR . 'ncc';
$NCC_UPDATE_SOURCE='https://updates.nosial.com/ncc/check_updates?current_version=$VERSION'; # Unused
$NCC_CHECKSUM=__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin';
$NCC_AUTOLOAD=__DIR__ . DIRECTORY_SEPARATOR . 'autoload.php';
$NCC_PHP_EXECUTABLE=null;
$NCC_FILESYSTEM=null;
// Require NCC
if(!file_exists($NCC_AUTOLOAD))
{
print('The file \'autoload.php\' was not found, installation cannot proceed.' . PHP_EOL);
exit(1);
}
require($NCC_AUTOLOAD);
// Initialize NCC
try
{
ncc::initialize();
}
catch (FileNotFoundException|\ncc\Exceptions\RuntimeException $e)
{
Console::outError('Cannot initialize NCC, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')');
exit(1);
}
$NCC_ARGS = null;
$NCC_FILESYSTEM = new Filesystem();
// Options Parser
if(isset($argv))
{
$NCC_ARGS = Resolver::parseArguments(implode(' ', $argv));
}
if(isset($NCC_ARGS['help']))
{
$options = [
new CliHelpSection(['--help'], 'Displays this help menu about the installer'),
new CliHelpSection(['--auto'], 'Automates the installation process'),
new CliHelpSection(['--install-composer'], 'Require composer to be installed alongside NCC'),
new CliHelpSection(['--install-dir'], 'Specifies the installation directory for NCC'),
];
$options_padding = Functions::detectParametersPadding($options) + 4;
Console::out('Usage: ' . __FILE__ . ' [options]');
Console::out('Options:' . PHP_EOL);
foreach($options as $option)
{
Console::out(' ' . $option->toString($options_padding));
}
exit(0);
}
// Detect if running in Windows
if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
{
print('This installer can only run on Linux based machines' . PHP_EOL);
}
// Detect the server API
if(defined('PHP_SAPI'))
{
if(strtolower(PHP_SAPI) !== 'cli')
{
print('This installation script is meant to be running in your terminal' . PHP_EOL);
}
}
elseif(function_exists('php_sapi_name') && strtolower(php_sapi_name()) !== 'cli')
{
print('This installation script is meant to be running in your terminal' . PHP_EOL);
}
else
{
Console::outWarning(
'The installer cannot determine the Server API (SAPI), the installer will continue but it is ' .
'recommended to be running this installer in a terminal'
);
}
// Check if running in a TTY
if(stream_isatty(STDERR))
{
Console::outWarning('Your terminal may have some issues rendering the output of this installer');
}
// Check if running as root
if (posix_getuid() !== 0)
{
Console::outError('You must be running as root');
exit(1);
}
// Find the PHP executable
$executable_finder = new PhpExecutableFinder();
$NCC_PHP_EXECUTABLE = $executable_finder->find();
if(!$NCC_PHP_EXECUTABLE)
{
Console::outError('Cannot find PHP executable path');
exit(1);
}
// Check for the required files
$required_files = [
__DIR__ . DIRECTORY_SEPARATOR . 'LICENSE',
__DIR__ . DIRECTORY_SEPARATOR . 'build_files',
__DIR__ . DIRECTORY_SEPARATOR . 'ncc.sh',
];
foreach($required_files as $path)
{
if(!file_exists($path))
{
Console::outError('Missing file \'' . $path . '\', installation failed.', true, 1);
exit(1);
}
}
// Preform the checksum validation
if(!file_exists($NCC_CHECKSUM))
{
Console::outWarning('The file \'checksum.bin\' was not found, the contents of the program cannot be verified to be safe');
}
else
{
Console::out('Running checksum');
$checksum = ZiProto::decode(file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'checksum.bin'));
$checksum_failed = false;
foreach($checksum as $path => $hash)
{
if(!file_exists(__DIR__ . DIRECTORY_SEPARATOR . $path))
{
Console::outError('Cannot check file, \'' . $path . '\' not found.');
$checksum_failed = true;
}
elseif(hash_file('sha256', __DIR__ . DIRECTORY_SEPARATOR . $path) !== $hash)
{
Console::outWarning('The file \'' . $path . '\' does not match the original checksum');
$checksum_failed = true;
}
}
if($checksum_failed)
{
Console::outError('Checksum failed, the contents of the program cannot be verified to be safe');
exit(1);
}
else
{
Console::out('Checksum passed');
}
}
// Check for required extensions
$curl_available = true;
foreach(Validate::requiredExtensions() as $ext => $installed)
{
if(!$installed)
{
switch($ext)
{
case 'curl':
Console::outWarning('This installer requires the \'curl\' extension to install composer');
$curl_available = false;
break;
default:
Console::outWarning('The extension \'' . $ext . '\' is not installed, compatibility without it is not guaranteed');
break;
}
}
}
// Attempt to load version information
try
{
$VersionInformation = ncc::getVersionInformation();
}
catch (FileNotFoundException|\ncc\Exceptions\RuntimeException $e)
{
Console::outError('Cannot get version information, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')');
exit(1);
}
// Start of installer
Console::out('Started NCC installer');
// Display version information
Console::out('NCC Version: ' . NCC_VERSION_NUMBER . ' (' . NCC_VERSION_BRANCH . ')');
Console::out('Build Flags: ' . implode(',', NCC_VERSION_FLAGS));
foreach($VersionInformation->Components as $component)
{
$full_name = $component->Vendor . '/' . $component->PackageName;
try
{
Console::out($full_name . ' Version: ' . $component->getVersion());
}
catch (ComponentVersionNotFoundException $e)
{
Console::outWarning('Cannot determine component version of ' . $full_name);
}
}
// Determine the installation path
// TODO: Add the ability to change the data path as well
if($NCC_ARGS == null && !isset($NCC_ARGS['auto']))
{
while(true)
{
$user_input = null;
$user_input = Console::getInput("Installation Path (Default: $NCC_INSTALL_PATH): ");
if(strlen($user_input) > 0)
{
if(file_exists($user_input))
{
if(file_exists($user_input . DIRECTORY_SEPARATOR . 'ncc'))
{
Console::out('NCC Seems to already be installed, the installer will repair/upgrade your current install');
break;
}
else
{
Console::outError('The given directory already exists, it must be deleted before proceeding');
}
}
else
{
break;
}
}
else
{
break;
}
}
}
else
{
if(strlen($NCC_ARGS['install-dir']) > 0)
{
if(file_exists($NCC_ARGS['install-dir']))
{
if(file_exists($NCC_ARGS['install-dir'] . DIRECTORY_SEPARATOR . 'ncc'))
{
Console::out('NCC Seems to already be installed, the installer will repair/upgrade your current install');
}
else
{
Console::outError('The given directory already exists, it must be deleted before proceeding');
exit(1);
}
}
}
}
// Ask to install composer if curl is available
if($curl_available)
{
if($NCC_ARGS !== null && isset($NCC_ARGS['auto']) && isset($NCC_ARGS['install-composer']))
{
$update_composer = true;
}
elseif(isset($NCC_ARGS['install-composer']))
{
$update_composer = true;
}
else
{
Console::out("Note: This doesn't affect your current install of composer (if you have composer installed)");
$update_composer = Console::getBooleanInput('Do you want to install composer for NCC? (Recommended)');
}
}
if($NCC_ARGS == null && !isset($NCC_ARGS['auto']))
{
if(!Console::getBooleanInput('Do you want install NCC?'))
{
Console::outError('Installation cancelled by user');
exit(1);
}
}
// Prepare installation
if(file_exists($NCC_INSTALL_PATH))
{
try
{
$NCC_FILESYSTEM->remove([$NCC_INSTALL_PATH]);
}
catch(IOException $e)
{
Console::outError('Cannot delete directory \'' . $NCC_INSTALL_PATH . '\', ' . $e->getMessage());
exit(1);
}
}
// Create the required directories
$required_dirs = [
$NCC_INSTALL_PATH,
$NCC_DATA_PATH,
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'packages',
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'cache',
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'repos',
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'downloads',
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'config',
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'data',
$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'ext',
];
$NCC_FILESYSTEM->mkdir($required_dirs);
foreach($required_dirs as $dir)
{
$NCC_FILESYSTEM->chmod([$dir], 0755);
}
$NCC_FILESYSTEM->chmod([$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'config'], 0755);
$NCC_FILESYSTEM->chmod([$NCC_DATA_PATH . DIRECTORY_SEPARATOR . 'cache'], 0755);
// Install composer
if($curl_available && $update_composer)
{
Console::out('Installing composer for NCC');
$fp = fopen($NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer-setup.php', 'w+');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://getcomposer.org/installer');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 600);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_USERAGENT, 'ncc/' . NCC_VERSION_NUMBER . ' (' . NCC_VERSION_BRANCH . ')');
curl_exec($ch);
curl_close($ch);
fclose($fp);
Console::out('Running composer installer');
// TODO: Unescaped shell arguments are a security issue
$Process = Process::fromShellCommandline(implode(' ', [
$NCC_PHP_EXECUTABLE,
$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer-setup.php',
'--install-dir=' . $NCC_INSTALL_PATH,
'--filename=composer.phar'
]));
$Process->setWorkingDirectory($NCC_INSTALL_PATH);
$Process->setTty(true);
try
{
$Process->mustRun();
}
catch(ProcessFailedException $e)
{
Console::outError('Cannot install composer, ' . $e->getMessage());
exit(1);
}
$NCC_FILESYSTEM->remove([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer-setup.php']);
$NCC_FILESYSTEM->chmod([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'composer.phar'], 0755);
Console::out('Installed composer successfully');
}
// Install NCC
Console::out('Copying files to \'' . $NCC_INSTALL_PATH . '\'');
$build_files = explode("\n", file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'build_files'));
$total_items = count($build_files);
$processed_items = 0;
// Create all the directories first
foreach($build_files as $path)
{
if(is_dir(__DIR__ . DIRECTORY_SEPARATOR . $path))
{
$NCC_FILESYSTEM->mkdir([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $path]);
$NCC_FILESYSTEM->chmod([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $path], 0755);
$processed_items += 1;
}
Console::inlineProgressBar($processed_items, $total_items);
}
// Copy over all the files
foreach($build_files as $file)
{
if(is_file(__DIR__ . DIRECTORY_SEPARATOR . $file))
{
$NCC_FILESYSTEM->copy(__DIR__ . DIRECTORY_SEPARATOR . $file, $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $file);
$NCC_FILESYSTEM->chmod([$NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . $file], 0755);
$processed_items += 1;
}
Console::inlineProgressBar($processed_items, $total_items);
}
// Create credential store if needed
Console::out('Processing Credential Store');
$credential_manager = new CredentialManager();
try
{
$credential_manager->constructStore();
}
catch (AccessDeniedException|\ncc\Exceptions\RuntimeException $e)
{
Console::outError('Cannot construct credential store, ' . $e->getMessage() . ' (Error Code: ' . $e->getCode() . ')');
}
try
{
$NCC_FILESYSTEM->touch([PathFinder::getPackageLock(Scopes::System)]);
}
catch (InvalidScopeException $e)
{
Console::outError('Cannot create package lock, ' . $e->getMessage());
exit(0);
}
// Generate executable shortcut
Console::out('Creating shortcut');
$executable_shortcut = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'ncc.sh');
$executable_shortcut = str_ireplace('%php_exec', $NCC_PHP_EXECUTABLE, $executable_shortcut);
$executable_shortcut = str_ireplace('%ncc_exec', $NCC_INSTALL_PATH . DIRECTORY_SEPARATOR . 'ncc', $executable_shortcut);
$bin_paths = [
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'bin',
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'local' . DIRECTORY_SEPARATOR . 'bin',
DIRECTORY_SEPARATOR . 'usr' . DIRECTORY_SEPARATOR . 'share'
];
foreach($bin_paths as $path)
{
if($NCC_FILESYSTEM->exists([$path]))
{
file_put_contents($path . DIRECTORY_SEPARATOR . 'ncc', $executable_shortcut);
$NCC_FILESYSTEM->chmod([$path . DIRECTORY_SEPARATOR . 'ncc'], 0755);
}
}
// Register the ncc extension
Console::out('Registering extension');
$extension_shortcut = file_get_contents(__DIR__ . DIRECTORY_SEPARATOR . 'extension');
$extension_shortcut = str_ireplace('%ncc_install', $NCC_INSTALL_PATH, $extension_shortcut);
if(function_exists('get_include_path'))
{
foreach(explode(':', get_include_path()) as $path)
{
switch($path)
{
case '.':
case '..':
break;
default:
file_put_contents($path . DIRECTORY_SEPARATOR . 'ncc', $extension_shortcut);
$NCC_FILESYSTEM->chmod([$path . DIRECTORY_SEPARATOR . 'ncc'], 0755);
break;
}
}
}
Console::out('NCC has been successfully installed');
exit(0);

View file

@ -1 +1 @@
php ncc --ncc-cli "$@"
%php_exec %ncc_exec --ncc-cli "$@"

View file

@ -55,7 +55,7 @@
*/
public function constructStore(): void
{
// Do not continue the function if the file already exists, if the file is damaged a seperate function
// Do not continue the function if the file already exists, if the file is damaged a separate function
// is to be executed to fix the damaged file.
if(file_exists($this->CredentialsPath))
return;
@ -68,11 +68,12 @@
$VaultObject = new Vault();
$VaultObject->Version = Versions::CredentialsStoreVersion;
// TODO: Set proper permissions for root access only for the file
if(!@file_put_contents($this->CredentialsPath, ZiProto::encode($VaultObject->toArray())))
{
throw new RuntimeException('Cannot create file \'' . $this->CredentialsPath . '\'');
}
chmod($this->CredentialsPath, 0600);
}
/**

View file

@ -23,7 +23,7 @@
/**
* Flags for the current build
*
* @var string|null
* @var array|null
*/
public $Flags;

View file

@ -23,19 +23,12 @@
/**
* Attempts to resolve the component's build version
*
* @param string $ncc_installation_path
* @return string
* @throws ComponentVersionNotFoundException
*/
public function getVersion(string $ncc_installation_path): string
public function getVersion(): string
{
// Auto-resolve the trailing slash
if(substr($ncc_installation_path, -1) !== '/')
{
$ncc_installation_path .= $ncc_installation_path . DIRECTORY_SEPARATOR;
}
$third_party_path = $ncc_installation_path . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR;
$third_party_path = NCC_EXEC_LOCATION . DIRECTORY_SEPARATOR . 'ThirdParty' . DIRECTORY_SEPARATOR;
$component_path = $third_party_path . $this->Vendor . DIRECTORY_SEPARATOR . $this->PackageName . DIRECTORY_SEPARATOR;
if(file_exists($component_path . 'VERSION') == false)

View file

@ -4,74 +4,74 @@ CHANGELOG
5.2.0
-----
* added `process::setOptions()` to set `process` specific options
* added option `create_new_console` to allow a subprocess to continue
* added `Process::setOptions()` to set `Process` specific options
* added option `create_new_console` to allow a subProcess to continue
to run after the main script exited, both on Linux and on Windows
5.1.0
-----
* added `process::getStartTime()` to retrieve the start time of the process as float
* added `Process::getStartTime()` to retrieve the start time of the Process as float
5.0.0
-----
* removed `process::inheritEnvironmentVariables()`
* removed `Phpprocess::setPhpBinary()`
* `process` must be instantiated with a command array, use `process::fromShellCommandline()` when the command should be parsed by the shell
* removed `process::setCommandLine()`
* removed `Process::inheritEnvironmentVariables()`
* removed `PhpProcess::setPhpBinary()`
* `Process` must be instantiated with a command array, use `Process::fromShellCommandline()` when the command should be parsed by the shell
* removed `Process::setCommandLine()`
4.4.0
-----
* deprecated `process::inheritEnvironmentVariables()`: env variables are always inherited.
* added `process::getLastOutputTime()` method
* deprecated `Process::inheritEnvironmentVariables()`: env variables are always inherited.
* added `Process::getLastOutputTime()` method
4.2.0
-----
* added the `process::fromShellCommandline()` to run commands in a shell wrapper
* deprecated passing a command as string when creating a `process` instance
* deprecated the `process::setCommandline()` and the `Phpprocess::setPhpBinary()` methods
* added the `process::waitUntil()` method to wait for the process only for a
* added the `Process::fromShellCommandline()` to run commands in a shell wrapper
* deprecated passing a command as string when creating a `Process` instance
* deprecated the `Process::setCommandline()` and the `PhpProcess::setPhpBinary()` methods
* added the `Process::waitUntil()` method to wait for the Process only for a
specific output, then continue the normal execution of your application
4.1.0
-----
* added the `process::isTtySupported()` method that allows to check for TTY support
* added the `Process::isTtySupported()` method that allows to check for TTY support
* made `PhpExecutableFinder` look for the `PHP_BINARY` env var when searching the php binary
* added the `processSignaledException` class to properly catch signaled process errors
* added the `ProcessSignaledException` class to properly catch signaled Process errors
4.0.0
-----
* environment variables will always be inherited
* added a second `array $env = []` argument to the `start()`, `run()`,
`mustRun()`, and `restart()` methods of the `process` class
`mustRun()`, and `restart()` methods of the `Process` class
* added a second `array $env = []` argument to the `start()` method of the
`Phpprocess` class
* the `processUtils::escapeArgument()` method has been removed
`PhpProcess` class
* the `ProcessUtils::escapeArgument()` method has been removed
* the `areEnvironmentVariablesInherited()`, `getOptions()`, and `setOptions()`
methods of the `process` class have been removed
methods of the `Process` class have been removed
* support for passing `proc_open()` options has been removed
* removed the `processBuilder` class, use the `process` class instead
* removed the `getEnhanceWindowsCompatibility()` and `setEnhanceWindowsCompatibility()` methods of the `process` class
* passing a not existing working directory to the constructor of the `Symfony\Component\process\process` class is not
* removed the `ProcessBuilder` class, use the `Process` class instead
* removed the `getEnhanceWindowsCompatibility()` and `setEnhanceWindowsCompatibility()` methods of the `Process` class
* passing a not existing working directory to the constructor of the `Symfony\Component\Process\Process` class is not
supported anymore
3.4.0
-----
* deprecated the processBuilder class
* deprecated calling `process::start()` without setting a valid working directory beforehand (via `setWorkingDirectory()` or constructor)
* deprecated the ProcessBuilder class
* deprecated calling `Process::start()` without setting a valid working directory beforehand (via `setWorkingDirectory()` or constructor)
3.3.0
-----
* added command line arrays in the `process` class
* added `$env` argument to `process::start()`, `run()`, `mustRun()` and `restart()` methods
* deprecated the `processUtils::escapeArgument()` method
* added command line arrays in the `Process` class
* added `$env` argument to `Process::start()`, `run()`, `mustRun()` and `restart()` methods
* deprecated the `ProcessUtils::escapeArgument()` method
* deprecated not inheriting environment variables
* deprecated configuring `proc_open()` options
* deprecated configuring enhanced Windows compatibility
@ -82,9 +82,9 @@ CHANGELOG
* added support for PTY mode
* added the convenience method "mustRun"
* deprecation: process::setStdin() is deprecated in favor of process::setInput()
* deprecation: process::getStdin() is deprecated in favor of process::getInput()
* deprecation: process::setInput() and processBuilder::setInput() do not accept non-scalar types
* deprecation: Process::setStdin() is deprecated in favor of Process::setInput()
* deprecation: Process::getStdin() is deprecated in favor of Process::getInput()
* deprecation: Process::setInput() and ProcessBuilder::setInput() do not accept non-scalar types
2.4.0
-----
@ -94,23 +94,23 @@ CHANGELOG
2.3.0
-----
* added processUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows
* added process::signal()
* added process::getPid()
* added ProcessUtils::escapeArgument() to fix the bug in escapeshellarg() function on Windows
* added Process::signal()
* added Process::getPid()
* added support for a TTY mode
2.2.0
-----
* added processBuilder::setArguments() to reset the arguments on a builder
* added ProcessBuilder::setArguments() to reset the arguments on a builder
* added a way to retrieve the standard and error output incrementally
* added process:restart()
* added Process:restart()
2.1.0
-----
* added support for non-blocking processes (start(), wait(), isRunning(), stop())
* added support for non-blocking Processes (start(), wait(), isRunning(), stop())
* enhanced Windows compatibility
* added process::getExitCodeText() that returns a string representation for
the exit code returned by the process
* added processBuilder
* added Process::getExitCodeText() that returns a string representation for
the exit code returned by the Process
* added ProcessBuilder

View file

@ -9,10 +9,10 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
/**
* Marker Interface for the process Component.
* Marker Interface for the Process Component.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/

View file

@ -9,10 +9,10 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
/**
* InvalidArgumentException for the process Component.
* InvalidArgumentException for the Process Component.
*
* @author Romain Neutron <imprec@gmail.com>
*/

View file

@ -9,10 +9,10 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
/**
* LogicException for the process Component.
* LogicException for the Process Component.
*
* @author Romain Neutron <imprec@gmail.com>
*/

View file

@ -9,46 +9,46 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
use ncc\ThirdParty\Symfony\process\process;
use ncc\ThirdParty\Symfony\Process\Process;
/**
* Exception for failed processes.
* Exception for failed Processes.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class processFailedException extends RuntimeException
class ProcessFailedException extends RuntimeException
{
private $process;
private $Process;
public function __construct(process $process)
public function __construct(Process $Process)
{
if ($process->isSuccessful()) {
throw new InvalidArgumentException('Expected a failed process, but the given process was successful.');
if ($Process->isSuccessful()) {
throw new InvalidArgumentException('Expected a failed Process, but the given Process was successful.');
}
$error = sprintf('The command "%s" failed.'."\n\nExit Code: %s(%s)\n\nWorking directory: %s",
$process->getCommandLine(),
$process->getExitCode(),
$process->getExitCodeText(),
$process->getWorkingDirectory()
$Process->getCommandLine(),
$Process->getExitCode(),
$Process->getExitCodeText(),
$Process->getWorkingDirectory()
);
if (!$process->isOutputDisabled()) {
if (!$Process->isOutputDisabled()) {
$error .= sprintf("\n\nOutput:\n================\n%s\n\nError Output:\n================\n%s",
$process->getOutput(),
$process->getErrorOutput()
$Process->getOutput(),
$Process->getErrorOutput()
);
}
parent::__construct($error);
$this->process = $process;
$this->Process = $Process;
}
public function getprocess()
public function getProcess()
{
return $this->process;
return $this->Process;
}
}

View file

@ -9,33 +9,33 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
use ncc\ThirdParty\Symfony\process\process;
use ncc\ThirdParty\Symfony\Process\Process;
/**
* Exception that is thrown when a process has been signaled.
* Exception that is thrown when a Process has been signaled.
*
* @author Sullivan Senechal <soullivaneuh@gmail.com>
*/
final class processSignaledException extends RuntimeException
final class ProcessSignaledException extends RuntimeException
{
private $process;
private $Process;
public function __construct(process $process)
public function __construct(Process $Process)
{
$this->process = $process;
$this->Process = $Process;
parent::__construct(sprintf('The process has been signaled with signal "%s".', $process->getTermSignal()));
parent::__construct(sprintf('The Process has been signaled with signal "%s".', $Process->getTermSignal()));
}
public function getprocess(): process
public function getProcess(): Process
{
return $this->process;
return $this->Process;
}
public function getSignal(): int
{
return $this->getprocess()->getTermSignal();
return $this->getProcess()->getTermSignal();
}
}

View file

@ -9,38 +9,38 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
use ncc\ThirdParty\Symfony\process\process;
use ncc\ThirdParty\Symfony\Process\Process;
/**
* Exception that is thrown when a process times out.
* Exception that is thrown when a Process times out.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/
class processTimedOutException extends RuntimeException
class ProcessTimedOutException extends RuntimeException
{
public const TYPE_GENERAL = 1;
public const TYPE_IDLE = 2;
private $process;
private $Process;
private $timeoutType;
public function __construct(process $process, int $timeoutType)
public function __construct(Process $Process, int $timeoutType)
{
$this->process = $process;
$this->Process = $Process;
$this->timeoutType = $timeoutType;
parent::__construct(sprintf(
'The process "%s" exceeded the timeout of %s seconds.',
$process->getCommandLine(),
'The Process "%s" exceeded the timeout of %s seconds.',
$Process->getCommandLine(),
$this->getExceededTimeout()
));
}
public function getprocess()
public function getProcess()
{
return $this->process;
return $this->Process;
}
public function isGeneralTimeout()
@ -56,8 +56,8 @@ class processTimedOutException extends RuntimeException
public function getExceededTimeout()
{
return match ($this->timeoutType) {
self::TYPE_GENERAL => $this->process->getTimeout(),
self::TYPE_IDLE => $this->process->getIdleTimeout(),
self::TYPE_GENERAL => $this->Process->getTimeout(),
self::TYPE_IDLE => $this->Process->getIdleTimeout(),
default => throw new \LogicException(sprintf('Unknown timeout type "%d".', $this->timeoutType)),
};
}

View file

@ -9,10 +9,10 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Exception;
namespace ncc\ThirdParty\Symfony\Process\Exception;
/**
* RuntimeException for the process Component.
* RuntimeException for the Process Component.
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
*/

View file

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process;
namespace ncc\ThirdParty\Symfony\Process;
/**
* Generic executable finder.

View file

@ -9,12 +9,12 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process;
namespace ncc\ThirdParty\Symfony\Process;
use ncc\ThirdParty\Symfony\process\Exception\RuntimeException;
use ncc\ThirdParty\Symfony\Process\Exception\RuntimeException;
/**
* Provides a way to continuously write to the input of a process until the InputStream is closed.
* Provides a way to continuously write to the input of a Process until the InputStream is closed.
*
* @author Nicolas Grekas <p@tchwork.com>
*
@ -49,7 +49,7 @@ class InputStream implements \IteratorAggregate
if ($this->isClosed()) {
throw new RuntimeException(sprintf('"%s" is closed.', static::class));
}
$this->input[] = processUtils::validateInput(__METHOD__, $input);
$this->input[] = ProcessUtils::validateInput(__METHOD__, $input);
}
/**

View file

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process;
namespace ncc\ThirdParty\Symfony\Process;
/**
* An executable finder specifically designed for the PHP executable.

View file

@ -9,26 +9,26 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process;
namespace ncc\ThirdParty\Symfony\Process;
use ncc\ThirdParty\Symfony\process\Exception\LogicException;
use ncc\ThirdParty\Symfony\process\Exception\RuntimeException;
use ncc\ThirdParty\Symfony\Process\Exception\LogicException;
use ncc\ThirdParty\Symfony\Process\Exception\RuntimeException;
/**
* Phpprocess runs a PHP script in an independent process.
* PhpProcess runs a PHP script in an independent Process.
*
* $p = new Phpprocess('<?php echo "foo"; ?>');
* $p = new PhpProcess('<?php echo "foo"; ?>');
* $p->run();
* print $p->getOutput()."\n";
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Phpprocess extends process
class PhpProcess extends Process
{
/**
* @param string $script The PHP script to run (as a string)
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process
* @param array|null $env The environment variables or null to use the same environment as the current PHP process
* @param string|null $cwd The working directory or null to use the working dir of the current PHP Process
* @param array|null $env The environment variables or null to use the same environment as the current PHP Process
* @param int $timeout The timeout in seconds
* @param array|null $php Path to the PHP binary to use with any additional arguments
*/

View file

@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Pipes;
namespace ncc\ThirdParty\Symfony\Process\Pipes;
use ncc\ThirdParty\Symfony\process\Exception\InvalidArgumentException;
use ncc\ThirdParty\Symfony\Process\Exception\InvalidArgumentException;
/**
* @author Romain Neutron <imprec@gmail.com>

View file

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Pipes;
namespace ncc\ThirdParty\Symfony\Process\Pipes;
/**
* PipesInterface manages descriptors and pipes for the use of proc_open.

View file

@ -9,9 +9,9 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Pipes;
namespace ncc\ThirdParty\Symfony\Process\Pipes;
use ncc\ThirdParty\Symfony\process\process;
use ncc\ThirdParty\Symfony\Process\Process;
/**
* UnixPipes implementation uses unix pipes as handles.
@ -73,7 +73,7 @@ class UnixPipes extends AbstractPipes
];
}
if ($this->ptyMode && process::isPtySupported()) {
if ($this->ptyMode && Process::isPtySupported()) {
return [
['pty'],
['pty'],
@ -110,7 +110,7 @@ class UnixPipes extends AbstractPipes
// let's have a look if something changed in streams
set_error_handler($this->handleError(...));
if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? process::TIMEOUT_PRECISION * 1E6 : 0)) {
if (($r || $w) && false === stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {
restore_error_handler();
// if a system call has been interrupted, forget about it, let's try again
// otherwise, an error occurred, let's reset pipes

View file

@ -9,10 +9,10 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process\Pipes;
namespace ncc\ThirdParty\Symfony\Process\Pipes;
use ncc\ThirdParty\Symfony\process\Exception\RuntimeException;
use ncc\ThirdParty\Symfony\process\process;
use ncc\ThirdParty\Symfony\Process\Exception\RuntimeException;
use ncc\ThirdParty\Symfony\Process\Process;
/**
* WindowsPipes implementation uses temporary files as handles.
@ -30,8 +30,8 @@ class WindowsPipes extends AbstractPipes
private $fileHandles = [];
private $lockHandles = [];
private $readBytes = [
process::STDOUT => 0,
process::STDERR => 0,
Process::STDOUT => 0,
Process::STDERR => 0,
];
private $haveReadSupport;
@ -45,8 +45,8 @@ class WindowsPipes extends AbstractPipes
//
// @see https://bugs.php.net/51800
$pipes = [
process::STDOUT => process::OUT,
process::STDERR => process::ERR,
Process::STDOUT => Process::OUT,
Process::STDERR => Process::ERR,
];
$tmpDir = sys_get_temp_dir();
$lastError = 'unknown reason';
@ -60,7 +60,7 @@ class WindowsPipes extends AbstractPipes
continue 2;
}
restore_error_handler();
throw new RuntimeException('A temporary file could not be opened to write the process output: '.$lastError);
throw new RuntimeException('A temporary file could not be opened to write the Process output: '.$lastError);
}
if (!flock($h, \LOCK_EX | \LOCK_NB)) {
continue 2;
@ -120,7 +120,7 @@ class WindowsPipes extends AbstractPipes
// We're not using pipe on Windows platform as it hangs (https://bugs.php.net/51800)
// We're not using file handles as it can produce corrupted output https://bugs.php.net/65650
// So we redirect output within the commandline and pass the nul device to the process
// So we redirect output within the commandline and pass the nul device to the Process
return [
['pipe', 'r'],
['file', 'NUL', 'w'],
@ -147,9 +147,9 @@ class WindowsPipes extends AbstractPipes
if ($blocking) {
if ($w) {
@stream_select($r, $w, $e, 0, process::TIMEOUT_PRECISION * 1E6);
@stream_select($r, $w, $e, 0, Process::TIMEOUT_PRECISION * 1E6);
} elseif ($this->fileHandles) {
usleep(process::TIMEOUT_PRECISION * 1E6);
usleep(Process::TIMEOUT_PRECISION * 1E6);
}
}
foreach ($this->fileHandles as $type => $fileHandle) {

File diff suppressed because it is too large Load diff

View file

@ -9,18 +9,18 @@
* file that was distributed with this source code.
*/
namespace ncc\ThirdParty\Symfony\process;
namespace ncc\ThirdParty\Symfony\Process;
use ncc\ThirdParty\Symfony\process\Exception\InvalidArgumentException;
use ncc\ThirdParty\Symfony\Process\Exception\InvalidArgumentException;
/**
* processUtils is a bunch of utility methods.
* ProcessUtils is a bunch of utility methods.
*
* This class contains static methods only and is not meant to be instantiated.
*
* @author Martin Hasoň <martin.hason@gmail.com>
*/
class processUtils
class ProcessUtils
{
/**
* This class should not be instantiated.
@ -30,7 +30,7 @@ class processUtils
}
/**
* Validates and normalizes a process input.
* Validates and normalizes a Process input.
*
* @param string $caller The name of method call that validates the input
* @param mixed $input The input to validate
@ -49,7 +49,7 @@ class processUtils
if (\is_scalar($input)) {
return (string) $input;
}
if ($input instanceof process) {
if ($input instanceof Process) {
return $input->getIterator($input::ITER_SKIP_ERR);
}
if ($input instanceof \Iterator) {

View file

@ -1,12 +1,12 @@
process Component
Process Component
=================
The process component executes commands in sub-processes.
The Process component executes commands in sub-Processes.
Sponsor
-------
The process component for Symfony 6.1 is [backed][1] by [SensioLabs][2].
The Process component for Symfony 6.1 is [backed][1] by [SensioLabs][2].
As the creator of Symfony, SensioLabs supports companies using Symfony, with an
offering encompassing consultancy, expertise, services, training, and technical
@ -17,7 +17,7 @@ Help Symfony by [sponsoring][3] its development!
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/process.html)
* [Documentation](https://symfony.com/doc/current/components/Process.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)

View file

@ -11,14 +11,14 @@
* Inline Progress bar, created by dealnews.com.
*
* // TODO: Add non-inline option
* @copyright Copyright (c) 2010, dealnews.com, Inc. All rights reserved.
* @param int $value
* @param int $total
* @param int $size
* @param array $flags
* @param array $options
* @return void
*@copyright Copyright (c) 2010, dealnews.com, Inc. All rights reserved.
*/
public static function inlineProgressBar(int $value, int $total, int $size=38, array $flags=[])
public static function inlineProgressBar(int $value, int $total, int $size=38, array $options=[])
{
static $start_time;
@ -48,10 +48,15 @@
$rate = ($now-$start_time)/$value;
$left = $total - $value;
$eta = round($rate * $left, 2);
$elapsed = $now - $start_time;
$status_bar.= " remaining: ".number_format($eta)." sec. elapsed: ".number_format($elapsed)." sec.";
$remaining_text = 'remaining: ';
if(isset($options['remaining_text']))
{
$remaining_text = $options['remaining_text'];
}
$status_bar.= " $remaining_text ".number_format($eta)." sec. elapsed: ".number_format($elapsed)." sec.";
echo "$status_bar ";
@ -217,7 +222,6 @@
if(strlen($r) > 0)
{
print($r);
switch(strtoupper($r))
{
case '1':

View file

@ -21,6 +21,7 @@
$requirements = [
'zlib',
'libxml',
'curl',
'ctype',
'json',
'mbstring',

View file

@ -20,6 +20,7 @@
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'polyfill-mbstring' . DIRECTORY_SEPARATOR . 'bootstrap.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Process' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Uid' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
$third_party_path . 'Symfony' . DIRECTORY_SEPARATOR . 'Filesystem' . DIRECTORY_SEPARATOR . 'autoload_spl.php',
];
foreach($target_files as $file)

View file

@ -1,5 +1,4 @@
<?php
require('autoload.php');
\ncc\CLI\Main::start($argv);

View file

@ -92,6 +92,7 @@
define('NCC_VERSION_UPDATE_SOURCE', $VersionInformation->UpdateSource);
define('NCC_VERSION_FLAGS', $VersionInformation->Flags);
define('NCC_INIT', 1);
return true;
}

View file

@ -17,11 +17,11 @@
},
{
"vendor": "Symfony",
"package_name": "polyfill-Process"
"package_name": "Process"
},
{
"vendor": "Symfony",
"package_name": "polyfill-uid"
"package_name": "Uid"
},
{
"vendor": "Symfony",