Refactored \ncc\Classes\ComposerExtension > ComposerSourceBuiltin to allow for building from local packages
This commit is contained in:
parent
fecc7e0465
commit
150ff9dee3
1 changed files with 288 additions and 177 deletions
|
@ -32,6 +32,8 @@
|
||||||
use ncc\Exceptions\UserAbortedOperationException;
|
use ncc\Exceptions\UserAbortedOperationException;
|
||||||
use ncc\Interfaces\ServiceSourceInterface;
|
use ncc\Interfaces\ServiceSourceInterface;
|
||||||
use ncc\Managers\ProjectManager;
|
use ncc\Managers\ProjectManager;
|
||||||
|
use ncc\ncc;
|
||||||
|
use ncc\Objects\ComposerJson;
|
||||||
use ncc\Objects\ComposerLock;
|
use ncc\Objects\ComposerLock;
|
||||||
use ncc\Objects\ProjectConfiguration;
|
use ncc\Objects\ProjectConfiguration;
|
||||||
use ncc\Objects\RemotePackageInput;
|
use ncc\Objects\RemotePackageInput;
|
||||||
|
@ -95,6 +97,68 @@
|
||||||
throw new RuntimeException(sprintf('Could not find package %s in the compiled packages', $packageInput->toStandard()));
|
throw new RuntimeException(sprintf('Could not find package %s in the compiled packages', $packageInput->toStandard()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Works with a local composer.json file and attempts to compile the required packages
|
||||||
|
* and their dependencies, returns the path to the compiled package.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* @throws BuildConfigurationNotFoundException
|
||||||
|
* @throws BuildException
|
||||||
|
* @throws ComposerDisabledException
|
||||||
|
* @throws ComposerException
|
||||||
|
* @throws ComposerNotAvailableException
|
||||||
|
* @throws DirectoryNotFoundException
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws InternalComposerNotAvailableException
|
||||||
|
* @throws MalformedJsonException
|
||||||
|
* @throws PackageNotFoundException
|
||||||
|
* @throws PackagePreparationFailedException
|
||||||
|
* @throws ProjectConfigurationNotFoundException
|
||||||
|
* @throws UnsupportedCompilerExtensionException
|
||||||
|
* @throws UnsupportedRunnerException
|
||||||
|
* @throws UserAbortedOperationException
|
||||||
|
*/
|
||||||
|
public static function fromLocal(string $path): string
|
||||||
|
{
|
||||||
|
// Check if the file composer.json exists
|
||||||
|
if (!file_exists($path . DIRECTORY_SEPARATOR . 'composer.json'))
|
||||||
|
throw new FileNotFoundException(sprintf('File "%s" not found', $path . DIRECTORY_SEPARATOR . 'composer.json'));
|
||||||
|
|
||||||
|
// Execute composer with options
|
||||||
|
$options = self::getOptions();
|
||||||
|
$composer_exec = self::getComposerPath();
|
||||||
|
$process = new Process([$composer_exec, 'install']);
|
||||||
|
self::prepareProcess($process, $path, $options);
|
||||||
|
|
||||||
|
Console::outDebug(sprintf('executing %s', $process->getCommandLine()));
|
||||||
|
$process->run(function ($type, $buffer) {
|
||||||
|
Console::out($buffer, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!$process->isSuccessful())
|
||||||
|
throw new ComposerException($process->getErrorOutput());
|
||||||
|
|
||||||
|
$filesystem = new Filesystem();
|
||||||
|
if($filesystem->exists($path . DIRECTORY_SEPARATOR . 'build'))
|
||||||
|
$filesystem->remove($path . DIRECTORY_SEPARATOR . 'build');
|
||||||
|
$filesystem->mkdir($path . DIRECTORY_SEPARATOR . 'build');
|
||||||
|
|
||||||
|
// Compile dependencies
|
||||||
|
self::compilePackages($path . DIRECTORY_SEPARATOR . 'composer.lock');
|
||||||
|
|
||||||
|
// Finally convert the main package's composer.json to package.json and compile it
|
||||||
|
ComposerSourceBuiltin::convertProject($path);
|
||||||
|
$project_manager = new ProjectManager($path);
|
||||||
|
$project_manager->load();
|
||||||
|
$built_package = $project_manager->build();
|
||||||
|
|
||||||
|
RuntimeCache::setFileAsTemporary($built_package);
|
||||||
|
return $built_package;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $composer_lock_path
|
* @param string $composer_lock_path
|
||||||
* @return array
|
* @return array
|
||||||
|
@ -133,154 +197,16 @@
|
||||||
foreach ($composer_lock->Packages as $package)
|
foreach ($composer_lock->Packages as $package)
|
||||||
{
|
{
|
||||||
$package_path = $base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->Name;
|
$package_path = $base_dir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . $package->Name;
|
||||||
// Generate the package configuration
|
|
||||||
$project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($package->Name, $composer_lock);
|
|
||||||
|
|
||||||
// Process the source files
|
// Load the composer lock file
|
||||||
if ($package->Autoload !== null)
|
$composer_package = $composer_lock->getPackage($package->Name);
|
||||||
{
|
if ($composer_package == null)
|
||||||
$source_directory = $package_path . DIRECTORY_SEPARATOR . '.src';
|
throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package->Name));
|
||||||
if ($filesystem->exists($source_directory))
|
|
||||||
{
|
|
||||||
$filesystem->remove($source_directory);
|
|
||||||
}
|
|
||||||
$filesystem->mkdir($source_directory);
|
|
||||||
$source_directories = [];
|
|
||||||
$static_files = [];
|
|
||||||
|
|
||||||
// Extract all the source directories
|
// Convert it to a NCC project configuration
|
||||||
if ($package->Autoload->Psr4 !== null && count($package->Autoload->Psr4) > 0)
|
$project_configuration = self::convertProject($package_path, $composer_package);
|
||||||
{
|
|
||||||
Console::outVerbose('Extracting PSR-4 source directories');
|
|
||||||
foreach ($package->Autoload->Psr4 as $namespace_pointer)
|
|
||||||
{
|
|
||||||
if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories))
|
|
||||||
{
|
|
||||||
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($package->Autoload->Psr0 !== null && count($package->Autoload->Psr0) > 0)
|
|
||||||
{
|
|
||||||
Console::outVerbose('Extracting PSR-0 source directories');
|
|
||||||
foreach ($package->Autoload->Psr0 as $namespace_pointer)
|
|
||||||
{
|
|
||||||
if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories))
|
|
||||||
{
|
|
||||||
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($package->Autoload->Files !== null && count($package->Autoload->Files) > 0)
|
|
||||||
{
|
|
||||||
Console::outVerbose('Extracting static files');
|
|
||||||
foreach ($package->Autoload->Files as $file)
|
|
||||||
{
|
|
||||||
$static_files[] = $package_path . DIRECTORY_SEPARATOR . $file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Console::outDebug(sprintf('source directories: %s', implode(', ', $source_directories)));
|
|
||||||
|
|
||||||
// First scan the project files and create a file struct.
|
|
||||||
$DirectoryScanner = new DirectoryScanner();
|
|
||||||
|
|
||||||
// TODO: Implement exclude-class handling
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$DirectoryScanner->unsetFlag(FilesystemIterator::FOLLOW_SYMLINKS);
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
throw new PackagePreparationFailedException('Cannot unset flag \'FOLLOW_SYMLINKS\' in DirectoryScanner, ' . $e->getMessage(), $e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include file components that can be compiled
|
|
||||||
$DirectoryScanner->setIncludes(ComponentFileExtensions::Php);
|
|
||||||
|
|
||||||
foreach ($source_directories as $directory)
|
|
||||||
{
|
|
||||||
/** @var SplFileInfo $item */
|
|
||||||
/** @noinspection PhpRedundantOptionalArgumentInspection */
|
|
||||||
foreach ($DirectoryScanner($directory, True) as $item)
|
|
||||||
{
|
|
||||||
if (is_dir($item->getPathName()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName());
|
|
||||||
|
|
||||||
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name));
|
|
||||||
$filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count($static_files) > 0)
|
|
||||||
{
|
|
||||||
$project_configuration->Project->Options['static_files'] = $static_files;
|
|
||||||
|
|
||||||
foreach ($static_files as $file)
|
|
||||||
{
|
|
||||||
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $file);
|
|
||||||
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $package->Name));
|
|
||||||
$filesystem->copy($file, $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
|
|
||||||
}
|
|
||||||
unset($file);
|
|
||||||
}
|
|
||||||
|
|
||||||
$project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the project
|
// Load the project
|
||||||
$license_files = [
|
|
||||||
'LICENSE',
|
|
||||||
'license',
|
|
||||||
'LICENSE.txt',
|
|
||||||
'license.txt'
|
|
||||||
];
|
|
||||||
|
|
||||||
foreach($license_files as $license_file)
|
|
||||||
{
|
|
||||||
if($filesystem->exists($package_path . DIRECTORY_SEPARATOR . $license_file))
|
|
||||||
{
|
|
||||||
// Check configuration if composer.extension.display_licenses is set
|
|
||||||
if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_licenses')))
|
|
||||||
{
|
|
||||||
Console::out(sprintf('License for package %s:', $package->Name));
|
|
||||||
Console::out(IO::fread($package_path . DIRECTORY_SEPARATOR . $license_file));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_authors')))
|
|
||||||
{
|
|
||||||
if($package->Authors !== null && count($package->Authors) > 0)
|
|
||||||
{
|
|
||||||
Console::out(sprintf('Authors for package %s:', $package->Name));
|
|
||||||
foreach($package->Authors as $author)
|
|
||||||
{
|
|
||||||
Console::out(sprintf(' - %s', $author->Name));
|
|
||||||
|
|
||||||
if($author->Email !== null)
|
|
||||||
{
|
|
||||||
Console::out(sprintf(' %s', $author->Email));
|
|
||||||
}
|
|
||||||
|
|
||||||
if($author->Homepage !== null)
|
|
||||||
{
|
|
||||||
Console::out(sprintf(' %s', $author->Homepage));
|
|
||||||
}
|
|
||||||
|
|
||||||
if($author->Role !== null)
|
|
||||||
{
|
|
||||||
Console::out(sprintf(' %s', $author->Role));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$project_manager = new ProjectManager($package_path);
|
$project_manager = new ProjectManager($package_path);
|
||||||
$project_manager->load();
|
$project_manager->load();
|
||||||
$built_package = $project_manager->build();
|
$built_package = $project_manager->build();
|
||||||
|
@ -288,6 +214,7 @@
|
||||||
// Copy the project to the build directory
|
// Copy the project to the build directory
|
||||||
$out_path = $base_dir . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . sprintf('%s=%s.ncc', $project_configuration->Assembly->Package, $project_configuration->Assembly->Version);
|
$out_path = $base_dir . DIRECTORY_SEPARATOR . 'build' . DIRECTORY_SEPARATOR . sprintf('%s=%s.ncc', $project_configuration->Assembly->Package, $project_configuration->Assembly->Version);
|
||||||
$filesystem->copy($built_package, $out_path);
|
$filesystem->copy($built_package, $out_path);
|
||||||
|
$filesystem->remove($built_package);
|
||||||
$built_packages[$project_configuration->Assembly->Package] = $out_path;
|
$built_packages[$project_configuration->Assembly->Package] = $out_path;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -323,18 +250,12 @@
|
||||||
* Generates a project configuration from a package selection
|
* Generates a project configuration from a package selection
|
||||||
* from the composer.lock file
|
* from the composer.lock file
|
||||||
*
|
*
|
||||||
* @param string $package_name
|
* @param ComposerJson $composer_package
|
||||||
* @param ComposerLock $composer_lock
|
|
||||||
* @return ProjectConfiguration
|
* @return ProjectConfiguration
|
||||||
* @throws PackageNotFoundException
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private static function generateProjectConfiguration(string $package_name, ComposerLock $composer_lock): ProjectConfiguration
|
private static function generateProjectConfiguration(ComposerJson $composer_package): ProjectConfiguration
|
||||||
{
|
{
|
||||||
// Load the composer lock file
|
|
||||||
$composer_package = $composer_lock->getPackage($package_name);
|
|
||||||
if ($composer_package == null)
|
|
||||||
throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package_name));
|
|
||||||
|
|
||||||
// Generate a new project configuration object
|
// Generate a new project configuration object
|
||||||
$project_configuration = new ProjectConfiguration();
|
$project_configuration = new ProjectConfiguration();
|
||||||
|
|
||||||
|
@ -345,14 +266,22 @@
|
||||||
if (isset($composer_package->Version))
|
if (isset($composer_package->Version))
|
||||||
$project_configuration->Assembly->Version = Functions::parseVersion($composer_package->Version);
|
$project_configuration->Assembly->Version = Functions::parseVersion($composer_package->Version);
|
||||||
|
|
||||||
|
if($project_configuration->Assembly->Version == null || $project_configuration->Assembly->Version == '')
|
||||||
|
$project_configuration->Assembly->Version = '1.0.0';
|
||||||
|
|
||||||
$project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122();
|
$project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122();
|
||||||
$project_configuration->Assembly->Package = self::toPackageName($package_name);
|
$project_configuration->Assembly->Package = self::toPackageName($composer_package->Name);
|
||||||
|
|
||||||
|
// Add the update source
|
||||||
|
$project_configuration->Project->UpdateSource = new ProjectConfiguration\UpdateSource();
|
||||||
|
$project_configuration->Project->UpdateSource->Source = sprintf('%s=%s@composer', str_ireplace('\\', '/', $composer_package->Name), $composer_package->Version);
|
||||||
|
$project_configuration->Project->UpdateSource->Repository = null;
|
||||||
|
|
||||||
// Process the dependencies
|
// Process the dependencies
|
||||||
foreach ($composer_package->Require as $item)
|
foreach ($composer_package->Require as $item)
|
||||||
{
|
{
|
||||||
$package_name = self::toPackageName($item->PackageName);
|
$package_name = self::toPackageName($item->PackageName);
|
||||||
$package_version = $composer_lock->getPackage($item->PackageName)?->Version;
|
$package_version = $composer_package->Version;
|
||||||
if ($package_version == null)
|
if ($package_version == null)
|
||||||
{
|
{
|
||||||
$package_version = '1.0.0';
|
$package_version = '1.0.0';
|
||||||
|
@ -485,7 +414,6 @@
|
||||||
* @param string $vendor
|
* @param string $vendor
|
||||||
* @param string $package
|
* @param string $package
|
||||||
* @param string|null $version
|
* @param string|null $version
|
||||||
* @param array $options
|
|
||||||
* @return string
|
* @return string
|
||||||
* @throws AccessDeniedException
|
* @throws AccessDeniedException
|
||||||
* @throws ComposerDisabledException
|
* @throws ComposerDisabledException
|
||||||
|
@ -497,7 +425,7 @@
|
||||||
* @throws InvalidScopeException
|
* @throws InvalidScopeException
|
||||||
* @throws UserAbortedOperationException
|
* @throws UserAbortedOperationException
|
||||||
*/
|
*/
|
||||||
private static function require(string $vendor, string $package, ?string $version = null, array $options = []): string
|
private static function require(string $vendor, string $package, ?string $version = null): string
|
||||||
{
|
{
|
||||||
if (Resolver::resolveScope() !== Scopes::System)
|
if (Resolver::resolveScope() !== Scopes::System)
|
||||||
throw new AccessDeniedException('Insufficient permissions to require');
|
throw new AccessDeniedException('Insufficient permissions to require');
|
||||||
|
@ -530,26 +458,7 @@
|
||||||
// Execute composer with options
|
// Execute composer with options
|
||||||
$options = self::getOptions();
|
$options = self::getOptions();
|
||||||
$process = new Process(array_merge([$composer_exec, 'require'], $options));
|
$process = new Process(array_merge([$composer_exec, 'require'], $options));
|
||||||
$process->setWorkingDirectory($tmp_dir);
|
self::prepareProcess($process, $tmp_dir, $options);
|
||||||
|
|
||||||
// Check if scripts are enabled while running as root
|
|
||||||
if (!in_array('--no-scripts', $options) && Resolver::resolveScope() == Scopes::System)
|
|
||||||
{
|
|
||||||
Console::outWarning('composer scripts are enabled while running as root, this can allow malicious scripts to run as root');
|
|
||||||
if (!isset($options['--no-interaction']))
|
|
||||||
{
|
|
||||||
if (!Console::getBooleanInput('Do you want to continue?'))
|
|
||||||
throw new UserAbortedOperationException('The operation was aborted by the user');
|
|
||||||
|
|
||||||
// The user understands the risks and wants to continue
|
|
||||||
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Composer is running "safely". We can disable the superuser check
|
|
||||||
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Console::outDebug(sprintf('executing %s', $process->getCommandLine()));
|
Console::outDebug(sprintf('executing %s', $process->getCommandLine()));
|
||||||
$process->run(function ($type, $buffer) {
|
$process->run(function ($type, $buffer) {
|
||||||
|
@ -606,4 +515,206 @@
|
||||||
|
|
||||||
throw new ComposerNotAvailableException('No composer executable path is configured');
|
throw new ComposerNotAvailableException('No composer executable path is configured');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Process $process
|
||||||
|
* @param string $path
|
||||||
|
* @param array $options
|
||||||
|
* @return void
|
||||||
|
* @throws UserAbortedOperationException
|
||||||
|
*/
|
||||||
|
private static function prepareProcess(Process $process, string $path, array $options): void
|
||||||
|
{
|
||||||
|
$process->setWorkingDirectory($path);
|
||||||
|
|
||||||
|
// Check if scripts are enabled while running as root
|
||||||
|
if (!in_array('--no-scripts', $options) && Resolver::resolveScope() == Scopes::System)
|
||||||
|
{
|
||||||
|
Console::outWarning('composer scripts are enabled while running as root, this can allow malicious scripts to run as root');
|
||||||
|
if (!isset($options['--no-interaction']))
|
||||||
|
{
|
||||||
|
if (!Console::getBooleanInput('Do you want to continue?'))
|
||||||
|
throw new UserAbortedOperationException('The operation was aborted by the user');
|
||||||
|
|
||||||
|
// The user understands the risks and wants to continue
|
||||||
|
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Composer is running "safely". We can disable the superuser check
|
||||||
|
$process->setEnv(['COMPOSER_ALLOW_SUPERUSER' => 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a composer project to a NCC project
|
||||||
|
*
|
||||||
|
* @param mixed $composer_package
|
||||||
|
* @param string $package_path
|
||||||
|
* @return ProjectConfiguration
|
||||||
|
* @throws AccessDeniedException
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws MalformedJsonException
|
||||||
|
* @throws PackagePreparationFailedException
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private static function convertProject(string $package_path, ?ComposerJson $composer_package=null): ProjectConfiguration
|
||||||
|
{
|
||||||
|
if($composer_package == null)
|
||||||
|
ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json'));
|
||||||
|
|
||||||
|
$project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package);
|
||||||
|
$filesystem = new Filesystem();
|
||||||
|
|
||||||
|
// Process the source files
|
||||||
|
if ($composer_package->Autoload !== null)
|
||||||
|
{
|
||||||
|
$source_directory = $package_path . DIRECTORY_SEPARATOR . '.src';
|
||||||
|
if ($filesystem->exists($source_directory))
|
||||||
|
$filesystem->remove($source_directory);
|
||||||
|
$filesystem->mkdir($source_directory);
|
||||||
|
$source_directories = [];
|
||||||
|
$static_files = [];
|
||||||
|
|
||||||
|
// Extract all the source directories
|
||||||
|
if ($composer_package->Autoload->Psr4 !== null && count($composer_package->Autoload->Psr4) > 0)
|
||||||
|
{
|
||||||
|
Console::outVerbose('Extracting PSR-4 source directories');
|
||||||
|
foreach ($composer_package->Autoload->Psr4 as $namespace_pointer)
|
||||||
|
{
|
||||||
|
if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories))
|
||||||
|
{
|
||||||
|
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($composer_package->Autoload->Psr0 !== null && count($composer_package->Autoload->Psr0) > 0)
|
||||||
|
{
|
||||||
|
Console::outVerbose('Extracting PSR-0 source directories');
|
||||||
|
foreach ($composer_package->Autoload->Psr0 as $namespace_pointer)
|
||||||
|
{
|
||||||
|
if ($namespace_pointer->Path !== null && !in_array($namespace_pointer->Path, $source_directories))
|
||||||
|
{
|
||||||
|
$source_directories[] = $package_path . DIRECTORY_SEPARATOR . $namespace_pointer->Path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($composer_package->Autoload->Files !== null && count($composer_package->Autoload->Files) > 0)
|
||||||
|
{
|
||||||
|
Console::outVerbose('Extracting static files');
|
||||||
|
foreach ($composer_package->Autoload->Files as $file)
|
||||||
|
{
|
||||||
|
$static_files[] = $package_path . DIRECTORY_SEPARATOR . $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Console::outDebug(sprintf('source directories: %s', implode(', ', $source_directories)));
|
||||||
|
|
||||||
|
// First scan the project files and create a file struct.
|
||||||
|
$DirectoryScanner = new DirectoryScanner();
|
||||||
|
|
||||||
|
// TODO: Implement exclude-class handling
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$DirectoryScanner->unsetFlag(FilesystemIterator::FOLLOW_SYMLINKS);
|
||||||
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
|
throw new PackagePreparationFailedException('Cannot unset flag \'FOLLOW_SYMLINKS\' in DirectoryScanner, ' . $e->getMessage(), $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Include file components that can be compiled
|
||||||
|
$DirectoryScanner->setIncludes(ComponentFileExtensions::Php);
|
||||||
|
|
||||||
|
foreach ($source_directories as $directory)
|
||||||
|
{
|
||||||
|
/** @var SplFileInfo $item */
|
||||||
|
/** @noinspection PhpRedundantOptionalArgumentInspection */
|
||||||
|
foreach ($DirectoryScanner($directory, True) as $item)
|
||||||
|
{
|
||||||
|
if (is_dir($item->getPathName()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $item->getPathName());
|
||||||
|
|
||||||
|
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $composer_package->Name));
|
||||||
|
$filesystem->copy($item->getPathName(), $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($static_files) > 0)
|
||||||
|
{
|
||||||
|
$project_configuration->Project->Options['static_files'] = $static_files;
|
||||||
|
|
||||||
|
foreach ($static_files as $file)
|
||||||
|
{
|
||||||
|
$parsed_path = str_ireplace($package_path . DIRECTORY_SEPARATOR, '', $file);
|
||||||
|
Console::outDebug(sprintf('copying file %s for package %s', $parsed_path, $composer_package->Name));
|
||||||
|
$filesystem->copy($file, $source_directory . DIRECTORY_SEPARATOR . $parsed_path);
|
||||||
|
}
|
||||||
|
unset($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$project_configuration->toFile($package_path . DIRECTORY_SEPARATOR . 'project.json');
|
||||||
|
}
|
||||||
|
|
||||||
|
// This part simply displays the package information to the command-line interface
|
||||||
|
if(ncc::cliMode())
|
||||||
|
{
|
||||||
|
$license_files = [
|
||||||
|
'LICENSE',
|
||||||
|
'license',
|
||||||
|
'LICENSE.txt',
|
||||||
|
'license.txt'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach($license_files as $license_file)
|
||||||
|
{
|
||||||
|
if($filesystem->exists($package_path . DIRECTORY_SEPARATOR . $license_file))
|
||||||
|
{
|
||||||
|
// Check configuration if composer.extension.display_licenses is set
|
||||||
|
if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_licenses')))
|
||||||
|
{
|
||||||
|
Console::out(sprintf('License for package %s:', $composer_package->Name));
|
||||||
|
Console::out(IO::fread($package_path . DIRECTORY_SEPARATOR . $license_file));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Functions::cbool(Functions::getConfigurationProperty('composer.extension.display_authors')))
|
||||||
|
{
|
||||||
|
if($composer_package->Authors !== null && count($composer_package->Authors) > 0)
|
||||||
|
{
|
||||||
|
Console::out(sprintf('Authors for package %s:', $composer_package->Name));
|
||||||
|
foreach($composer_package->Authors as $author)
|
||||||
|
{
|
||||||
|
Console::out(sprintf(' - %s', $author->Name));
|
||||||
|
|
||||||
|
if($author->Email !== null)
|
||||||
|
{
|
||||||
|
Console::out(sprintf(' %s', $author->Email));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($author->Homepage !== null)
|
||||||
|
{
|
||||||
|
Console::out(sprintf(' %s', $author->Homepage));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($author->Role !== null)
|
||||||
|
{
|
||||||
|
Console::out(sprintf(' %s', $author->Role));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $project_configuration;
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue