diff --git a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php index e97d4b4..eee3abe 100644 --- a/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php +++ b/src/ncc/Classes/ComposerExtension/ComposerSourceBuiltin.php @@ -35,7 +35,6 @@ use ncc\ncc; use ncc\Objects\ComposerJson; use ncc\Objects\ComposerLock; - use ncc\Objects\Package; use ncc\Objects\ProjectConfiguration; use ncc\Objects\RemotePackageInput; use ncc\ThirdParty\Symfony\Filesystem\Filesystem; @@ -151,8 +150,11 @@ // Compile dependencies self::compilePackages($path . DIRECTORY_SEPARATOR . 'composer.lock'); + $composer_lock = Functions::loadJson(IO::fread($path . DIRECTORY_SEPARATOR . 'composer.lock'), Functions::FORCE_ARRAY); + $version_map = self::getVersionMap(ComposerLock::fromArray($composer_lock)); + // Finally convert the main package's composer.json to package.json and compile it - ComposerSourceBuiltin::convertProject($path); + ComposerSourceBuiltin::convertProject($path, $version_map); $project_manager = new ProjectManager($path); $project_manager->load(); $built_package = $project_manager->build(); @@ -195,6 +197,7 @@ } $filesystem->mkdir($base_dir . DIRECTORY_SEPARATOR . 'build'); + $version_map = self::getVersionMap($composer_lock); foreach ($composer_lock->Packages as $package) { @@ -206,7 +209,7 @@ throw new PackageNotFoundException(sprintf('Package "%s" not found in composer lock file', $package->Name)); // Convert it to a NCC project configuration - $project_configuration = self::convertProject($package_path, $composer_package); + $project_configuration = self::convertProject($package_path, $version_map, $composer_package); // Load the project $project_manager = new ProjectManager($package_path); @@ -223,6 +226,22 @@ return $built_packages; } + /** + * Returns array of versions from the ComposerLock file + * + * @param ComposerLock $composerLock + * @return array + */ + private static function getVersionMap(ComposerLock $composerLock): array + { + $version_map = []; + foreach($composerLock->Packages as $package) + { + $version_map[$package->Name] = $package->Version; + } + return $version_map; + } + /** * Converts a composer package name to a valid package name * @@ -247,15 +266,40 @@ return null; } + /** + * Returns a valid version from a version map + * + * @param string $package_name + * @param array $version_map + * @return string + */ + private static function versionMap(string $package_name, array $version_map): string + { + if (array_key_exists($package_name, $version_map)) + { + $version = $version_map[$package_name]; + if(stripos($version, 'v') === 0) + $version = substr($version, 1); + if(!Validate::version($version)) + $version = Functions::convertToSemVer($version); + if(!Validate::version($version)) + return '1.0.0'; + + return $version; + } + + return '1.0.0'; + } + /** * Generates a project configuration from a package selection * from the composer.lock file * * @param ComposerJson $composer_package + * @param array $version_map * @return ProjectConfiguration - * @throws Exception */ - private static function generateProjectConfiguration(ComposerJson $composer_package): ProjectConfiguration + private static function generateProjectConfiguration(ComposerJson $composer_package, array $version_map): ProjectConfiguration { // Generate a new project configuration object $project_configuration = new ProjectConfiguration(); @@ -264,23 +308,12 @@ $project_configuration->Assembly->Name = $composer_package->Name; if (isset($composer_package->Description)) $project_configuration->Assembly->Description = $composer_package->Description; - if (isset($composer_package->Version)) - $project_configuration->Assembly->Version = Functions::parseVersion($composer_package->Version); + if(isset($version_map[$composer_package->Name])) + $project_configuration->Assembly->Version = self::versionMap($composer_package->Name, $version_map); if($project_configuration->Assembly->Version == null || $project_configuration->Assembly->Version == '') $project_configuration->Assembly->Version = '1.0.0'; - if(!Validate::version($project_configuration->Assembly->Version)) - $project_configuration->Assembly->Version = Functions::convertToSemVer($project_configuration->Assembly->Version); - - if(!Validate::version($project_configuration->Assembly->Version)) - { - Console::outWarning(sprintf('Invalid version "%s" for package "%s", using "1.0.0" instead', $project_configuration->Assembly->Version, $project_configuration->Assembly->Name)); - $project_configuration->Assembly->Version = '1.0.0'; - } - - RuntimeCache::set(sprintf('composer_version_%s', $project_configuration->Assembly->Package), $project_configuration->Assembly->Version); - $project_configuration->Assembly->UUID = Uuid::v1()->toRfc4122(); $project_configuration->Assembly->Package = self::toPackageName($composer_package->Name); @@ -295,24 +328,16 @@ { foreach ($composer_package->Require as $item) { + // Check if the dependency is already in the project configuration $package_name = self::toPackageName($item->PackageName); - $package_version = $composer_package->Version; - if ($package_version == null) - { - $package_version = '1.0.0'; - } - else - { - $package_version = Functions::parseVersion($package_version); - } if ($package_name == null) continue; $dependency = new ProjectConfiguration\Dependency(); $dependency->Name = $package_name; $dependency->SourceType = DependencySourceType::Local; - $dependency->Version = $package_version; + $dependency->Version = self::versionMap($item->PackageName, $version_map);; $dependency->Source = $package_name . '.ncc'; - $project_configuration->Build->Dependencies[] = $dependency; + $project_configuration->Build->addDependency($dependency); } } @@ -448,6 +473,8 @@ if ($version == null) $version = '*'; + if($version == 'latest') + $version = '*'; $tpl_file = __DIR__ . DIRECTORY_SEPARATOR . 'composer.jtpl'; if (!file_exists($tpl_file)) @@ -566,22 +593,22 @@ /** * Converts a composer project to a NCC project * - * @param mixed $composer_package * @param string $package_path + * @param array $version_map + * @param mixed $composer_package * @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 + private static function convertProject(string $package_path, array $version_map, ?ComposerJson $composer_package=null): ProjectConfiguration { if($composer_package == null) $composer_package = ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json', Functions::FORCE_ARRAY)); - $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package); + $project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package, $version_map); $filesystem = new Filesystem(); // Process the source files diff --git a/src/ncc/Classes/PhpExtension/PhpInstaller.php b/src/ncc/Classes/PhpExtension/PhpInstaller.php index 611f21e..490d739 100644 --- a/src/ncc/Classes/PhpExtension/PhpInstaller.php +++ b/src/ncc/Classes/PhpExtension/PhpInstaller.php @@ -115,24 +115,8 @@ */ public function postInstall(InstallationPaths $installationPaths): void { - $static_files_exists = false; - if($this->package->Header->Options !== null && isset($this->package->Header->Options['static_files'])) - { - $static_files = $this->package->Header->Options['static_files']; - $static_files_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'static_autoload.bin'; - - foreach($static_files as $file) - { - if(!file_exists($file)) - throw new InstallationException(sprintf('Static file %s does not exist', $file)); - } - - $static_files_exists = true; - IO::fwrite($static_files_path, ZiProto::encode($static_files)); - } - $autoload_path = $installationPaths->getBinPath() . DIRECTORY_SEPARATOR . 'autoload.php'; - $autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path, $static_files_exists); + $autoload_src = $this->generateAutoload($installationPaths->getSourcePath(), $autoload_path); IO::fwrite($autoload_path, $autoload_src); } @@ -294,7 +278,7 @@ * @throws IOException * @throws NoUnitsFoundException */ - private function generateAutoload(string $src, string $output, bool $ignore_units=false): string + private function generateAutoload(string $src, string $output, bool $ignore_units=true): string { // Construct configuration $configuration = new Config([$src]); diff --git a/src/ncc/Objects/ProjectConfiguration/Build.php b/src/ncc/Objects/ProjectConfiguration/Build.php index 938288e..75cb315 100644 --- a/src/ncc/Objects/ProjectConfiguration/Build.php +++ b/src/ncc/Objects/ProjectConfiguration/Build.php @@ -106,6 +106,44 @@ $this->Configurations = []; } + /** + * Adds a new dependency to the build, if it doesn't already exist + * + * @param Dependency $dependency + * @return void + */ + public function addDependency(Dependency $dependency) + { + foreach($this->Dependencies as $dep) + { + if($dep->Name == $dependency->Name) + { + $this->removeDependency($dep); + break; + } + } + + $this->Dependencies[] = $dependency; + } + + /** + * Removes a dependency from the build + * + * @param string $name + * @return void + */ + private function removeDependency(string $name) + { + foreach($this->Dependencies as $key => $dep) + { + if($dep->Name == $name) + { + unset($this->Dependencies[$key]); + return; + } + } + } + /** * Validates the build configuration object *