Bug Fixes Part 1

This commit is contained in:
Netkas 2022-12-16 12:20:45 -05:00
parent f41a3a6351
commit 06e876bc03
13 changed files with 260 additions and 195 deletions

View file

@ -1,6 +1,6 @@
{
"name": "github",
"type": "github",
"host": "github.com",
"host": "api.github.com",
"ssl": true
}

View file

@ -32,7 +32,6 @@
{
try
{
Console::outException('Example Error', new Exception('test'), 1);
self::installPackage($args);
return;
}
@ -195,6 +194,9 @@
// check if authentication is provided
$entry_arg = ($args['auth'] ?? null);
$credential_manager = new CredentialManager();
if($entry_arg !== null)
{
$credential = $credential_manager->getVault()->getEntry($entry_arg);
if($credential == null)
@ -202,8 +204,13 @@
Console::outError(sprintf('Unknown credential entry \'%s\'', $entry_arg), true, 1);
return;
}
}
else
{
$credential = null;
}
if(!$credential->isCurrentlyDecrypted())
if($credential !== null && !$credential->isCurrentlyDecrypted())
{
// Try 3 times
for($i = 0; $i < 3; $i++)

View file

@ -35,6 +35,7 @@
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;
@ -47,6 +48,7 @@
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
use ncc\Utilities\RuntimeCache;
use ncc\Utilities\Validate;
use SplFileInfo;
class ComposerSourceBuiltin implements ServiceSourceInterface
@ -212,11 +214,10 @@
$built_package = $project_manager->build();
// 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.ncc', $project_configuration->Assembly->Package);
$filesystem->copy($built_package, $out_path);
$filesystem->remove($built_package);
$built_packages[$project_configuration->Assembly->Package] = $out_path;
}
return $built_packages;
@ -269,15 +270,29 @@
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);
// 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->Source = sprintf('%s@composer', str_ireplace('\\', '/', $composer_package->Name));
$project_configuration->Project->UpdateSource->Repository = null;
// Process the dependencies
if($composer_package->Require !== null && count($composer_package->Require) > 0)
{
foreach ($composer_package->Require as $item)
{
$package_name = self::toPackageName($item->PackageName);
@ -296,9 +311,10 @@
$dependency->Name = $package_name;
$dependency->SourceType = DependencySourceType::Local;
$dependency->Version = $package_version;
$dependency->Source = $package_name . '=' . $dependency->Version . '.ncc';
$dependency->Source = $package_name . '.ncc';
$project_configuration->Build->Dependencies[] = $dependency;
}
}
// Create a build configuration
$build_configuration = new ProjectConfiguration\BuildConfiguration();
@ -563,7 +579,7 @@
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'));
$composer_package = ComposerJson::fromArray(Functions::loadJsonFile($package_path . DIRECTORY_SEPARATOR . 'composer.json', Functions::FORCE_ARRAY));
$project_configuration = ComposerSourceBuiltin::generateProjectConfiguration($composer_package);
$filesystem = new Filesystem();
@ -658,9 +674,9 @@
}
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())

View file

@ -26,15 +26,8 @@
$process = new Process(["git", "clone", $url, $path]);
$process->setTimeout(3600); // 1 hour
$process->run(function ($type, $buffer)
{
if (Process::ERR === $type)
{
Console::outWarning($buffer);
}
else
{
Console::outVerbose($buffer);
}
});
if (!$process->isSuccessful())
@ -85,15 +78,8 @@
$process = new Process(["git", "fetch", '--all', '--tags'] , $path);
$process->setTimeout(3600); // 1 hour
$process->run(function ($type, $buffer)
{
if (Process::ERR === $type)
{
Console::outWarning($buffer);
}
else
{
Console::outVerbose($buffer);
}
});
if (!$process->isSuccessful())
@ -103,9 +89,7 @@
$process->run(function ($type, $buffer)
{
if (Process::ERR === $type)
Console::outWarning($buffer);
Console::outVerbose($buffer);
});
if (!$process->isSuccessful())

View file

@ -153,10 +153,12 @@
$owner_f = str_ireplace(".", "%2F", $owner_f);
$repository = urlencode($packageInput->Package);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository";
$httpRequest->Type = HttpRequestType::POST;
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
$httpRequest->Type = HttpRequestType::GET;
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false);
$httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28';
$httpRequest->Headers[] = 'Accept: application/vnd.github+json';
$response = HttpClient::request($httpRequest);
$response = HttpClient::request($httpRequest, true);
if($response->StatusCode != 200)
throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
@ -249,13 +251,21 @@
$latest_version = $version;
}
return $releases[$latest_version]['package'];
$return = $releases[$latest_version]['package'] ?? null;
if($return === null)
throw new VersionNotFoundException('No releases found for the given repository.');
return $return;
}
if(!isset($releases[$packageInput->Version]))
throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version));
return $releases[$packageInput->Version]['package'];
$return = $releases[$packageInput->Version]['package'] ?? null;
if($return === null)
throw new VersionNotFoundException('No releases found for the given repository.');
return $return;
}
/**
@ -279,10 +289,12 @@
$owner_f = str_ireplace(".", "%2F", $owner_f);
$repository = urlencode($packageInput->Package);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases";
$httpRequest->Type = HttpRequestType::POST;
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
$httpRequest->Type = HttpRequestType::GET;
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry, false);
$httpRequest->Headers[] = 'X-GitHub-Api-Version: 2022-11-28';
$httpRequest->Headers[] = 'Accept: application/vnd.github+json';
$response = HttpClient::request($httpRequest);
$response = HttpClient::request($httpRequest, true);
if($response->StatusCode != 200)
throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
@ -298,7 +310,7 @@
// Make the tag_name version friendly
$release_version = str_replace('v', '', $release['tag_name']);
$return[$release_version] = [
'url' => ($release['tarball_url'] ?? $release['zipball_url'] ?? null)
'url' => ($release['zipball_url'] ?? $release['tarball_url'] ?? null)
];
if(isset($release['assets']))

View file

@ -118,11 +118,12 @@
$protocol = ($definedRemoteSource->SSL ? "https" : "http");
$owner_f = str_ireplace("/", "%2F", $packageInput->Vendor);
$owner_f = str_ireplace(".", "%2F", $owner_f);
$repository = urlencode($packageInput->Package);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository";
$project_f = str_ireplace("/", "%2F", $packageInput->Package);
$project_f = str_ireplace(".", "%2F", $project_f);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$project_f";
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
$response = HttpClient::request($httpRequest);
$response = HttpClient::request($httpRequest, true);
if($response->StatusCode != 200)
throw new GitlabServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
@ -210,10 +211,13 @@
$protocol = ($definedRemoteSource->SSL ? "https" : "http");
$owner_f = str_ireplace("/", "%2F", $owner);
$owner_f = str_ireplace(".", "%2F", $owner_f);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository/releases";
$repository_f = str_ireplace("/", "%2F", $repository);
$repository_f = str_ireplace(".", "%2F", $repository_f);
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/api/v4/projects/$owner_f%2F$repository_f/releases";
$httpRequest = Functions::prepareGitServiceRequest($httpRequest, $entry);
$response = HttpClient::request($httpRequest);
$response = HttpClient::request($httpRequest, true);
if($response->StatusCode != 200)
throw new GitlabServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
@ -237,7 +241,7 @@
$return[$release_version] = $release['assets']['sources'][0]['url'];
foreach($release['assets']['sources'] as $source)
{
if($source['format'] == 'tar.gz')
if($source['format'] == 'zip')
{
$return[$release_version] = $source['url'];
break;

View file

@ -206,19 +206,19 @@
* @param string $headers
* @return array
*/
private static function parseHeaders(string $headers): array
private static function parseHeaders(string $input): array
{
$headers = explode("\r", $headers);
$headers = array_filter($headers, function ($header)
{
return !empty($header);
});
$headers = array_map(function ($header) {
return explode(':', $header, 2);
}, $headers);
$headers = array();
$lines = explode("\n", $input);
$headers['HTTP'] = array_shift($lines);
return array_combine(array_map(function ($header) { return strtolower($header[0]); }, $headers),
array_map(function ($header) { return trim($header[1]); }, $headers)
);
foreach ($lines as $line) {
$header = explode(':', $line, 2);
if (count($header) == 2) {
$headers[trim($header[0])] = trim($header[1]);
}
}
return $headers;
}
}

View file

@ -116,7 +116,6 @@
throw new BuildException('Failed to build project', $e);
}
throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported');
}
@ -168,7 +167,6 @@
* @param string $build_configuration
* @return string
* @throws BuildConfigurationNotFoundException
* @throws BuildException
* @throws IOException
*/
public static function writePackage(string $path, Package $package, ProjectConfiguration $configuration, string $build_configuration=BuildConfigurationValues::DefaultConfiguration): string
@ -176,21 +174,14 @@
// Write the package to disk
$FileSystem = new Filesystem();
$BuildConfiguration = $configuration->Build->getBuildConfiguration($build_configuration);
if($FileSystem->exists($path . $BuildConfiguration->OutputPath))
{
try
{
$FileSystem->remove($path . $BuildConfiguration->OutputPath);
}
catch(\ncc\ThirdParty\Symfony\Filesystem\Exception\IOException $e)
{
throw new BuildException('Cannot delete directory \'' . $path . $BuildConfiguration->OutputPath . '\', ' . $e->getMessage(), $e);
}
}
if(!$FileSystem->exists($path . $BuildConfiguration->OutputPath))
$FileSystem->mkdir($path . $BuildConfiguration->OutputPath);
// Finally write the package to the disk
$FileSystem->mkdir($path . $BuildConfiguration->OutputPath);
$output_file = $path . $BuildConfiguration->OutputPath . DIRECTORY_SEPARATOR . $package->Assembly->Package . '.ncc';
if($FileSystem->exists($output_file))
$FileSystem->remove($output_file);
$FileSystem->touch($output_file);
try

View file

@ -128,6 +128,9 @@
// TODO: Re-implement the scanning process outside the compiler, as this is will be redundant
// Scan for components first.
if(file_exists($source_path))
{
Console::outVerbose('Scanning for components... ');
/** @var SplFileInfo $item */
/** @noinspection PhpRedundantOptionalArgumentInspection */
@ -190,6 +193,11 @@
{
Console::outVerbose('No resources found');
}
}
else
{
Console::outWarning('Source path does not exist, skipping resource and component scanning');
}
$selected_dependencies = [];
if($this->project->Build->Dependencies !== null && count($this->project->Build->Dependencies) > 0)

View file

@ -149,7 +149,6 @@
return false;
$this->Password = $this->encrypt();
var_dump($this->Password);
return true;
}

View file

@ -126,7 +126,7 @@
/** @noinspection PhpRedundantOptionalArgumentInspection */
$tick_time = str_pad($tick_time, (strlen($tick_time) + (self::$largestTickLength - strlen($tick_time))), ' ', STR_PAD_RIGHT);
return '[' . $tick_time . ' - ' . date('TH:i:sP') . '] ' . $input;
return '[' . $tick_time . '] ' . $input;
}
/**

View file

@ -36,6 +36,8 @@
use ncc\ThirdParty\jelix\Version\Parser;
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
use PharData;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use Throwable;
use ZipArchive;
@ -585,36 +587,82 @@
* @return string
* @throws Exception
*/
public static function extractArchive(string $path): string
public static function extractArchive(string $path): ?string
{
$filesystem = new Filesystem();
if(!$filesystem->exists(dirname($path)))
$filesystem->mkdir(dirname($path));
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $path);
finfo_close($finfo);
switch(pathinfo($path, PATHINFO_EXTENSION))
if ($mimeType == 'application/zip')
{
$zip = new ZipArchive;
$res = $zip->open($path);
if ($res === TRUE)
{
case 'zip':
$zip = new ZipArchive();
$zip->open($path);
$zip->extractTo(dirname($path));
$zip->close();
break;
case 'tar':
return dirname($path);
}
}
if ($mimeType == 'application/x-tar' || $mimeType == 'application/tar')
{
$phar = new PharData($path);
$phar->extractTo(dirname($path));
break;
case 'gz':
$phar->extractTo(dirname($path), null, true);
return dirname($path);
}
elseif ($mimeType == 'application/x-gzip' || $mimeType == 'application/gzip')
{
$phar = new PharData($path);
$phar->decompress();
break;
default:
throw new Exception('Unsupported archive type');
}
return dirname($path);
}
return null;
}
/**
* Scans the given directory for files and returns the found file
*
* @param string $path
* @param array $files
* @return string|null
*/
public static function searchDirectory(string $path, array $files): ?string
{
if (!is_dir($path))
return null;
// Search files in the given directory recursively
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
foreach ($iterator as $file)
{
if (in_array($file->getFilename(), $files))
return $file->getPathname();
}
return null;
}
/**
* Attempts to convert a weird version number to a standard version number
*
* @param $version
* @return string
*/
public static function convertToSemVer($version)
{
$parts = explode('.', $version);
$major = $parts[0];
$minor = $parts[1];
$patch = $parts[2];
$buildmetadata = $parts[3];
// Assemble the SemVer compatible string
$semver = "$major.$minor.$patch+$buildmetadata";
return $semver;
}
}

View file

@ -5,14 +5,12 @@
namespace ncc\Utilities;
use ncc\Abstracts\BuiltinRemoteSourceType;
use ncc\Abstracts\DefinedRemoteSourceType;
use ncc\Abstracts\LogLevel;
use ncc\Abstracts\ProjectType;
use ncc\Abstracts\RemoteSourceType;
use ncc\Abstracts\Scopes;
use ncc\Managers\RemoteSourcesManager;
use ncc\Objects\ProjectDetectionResults;
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
class Resolver
{
@ -267,7 +265,7 @@
if($defined_source == null)
return RemoteSourceType::Unknown;
return $defined_source->Type;
return RemoteSourceType::Defined;
}
/**
@ -277,38 +275,36 @@
* @param array $exlucde
* @return ProjectDetectionResults
*/
public static function detectProjectType(string $path, array $exlucde=[]): ProjectDetectionResults
public static function detectProjectType(string $path): ProjectDetectionResults
{
$Scanner = new DirectoryScanner();
$Scanner->setExcludes($exlucde);
$project_files = [
'composer.json',
'package.json',
'project.json',
'composer.json'
];
$project_file = Functions::searchDirectory($path, $project_files);
$project_detection_results = new ProjectDetectionResults();
$project_detection_results->ProjectType = ProjectType::Unknown;
/** @var \SplFileInfo $item */
foreach($Scanner($path, true) as $item)
if($project_file == null)
{
if(in_array($item->getFilename(), $project_files))
{
switch($item->getFilename())
{
case 'composer.json':
$project_detection_results->ProjectType = ProjectType::Composer;
$project_detection_results->ProjectPath = dirname($item->getPathname());
break;
return $project_detection_results;
}
// Get filename of the project file
switch(basename($project_file))
{
case 'project.json':
$project_detection_results->ProjectType = ProjectType::Ncc;
$project_detection_results->ProjectPath = dirname($item->getPathname());
break;
case 'composer.json':
$project_detection_results->ProjectType = ProjectType::Composer;
break;
}
}
}
$project_detection_results->ProjectPath = dirname($project_file);
return $project_detection_results;
}
}