1.0.0 Alpha Release #59
13 changed files with 752 additions and 415 deletions
|
@ -323,6 +323,21 @@
|
|||
*/
|
||||
const UnsupportedProjectTypeException = -1762;
|
||||
|
||||
/**
|
||||
* @see UnsupportedArchiveException
|
||||
*/
|
||||
const UnsupportedArchiveException = -1763;
|
||||
|
||||
/**
|
||||
* @see ArchiveException
|
||||
*/
|
||||
const ArchiveException = -1764;
|
||||
|
||||
/**
|
||||
* @see PackageFetchException
|
||||
*/
|
||||
const PackageFetchException = -1765;
|
||||
|
||||
/**
|
||||
* All the exception codes from NCC
|
||||
*/
|
||||
|
@ -386,6 +401,9 @@
|
|||
self::GitTagsException,
|
||||
self::AuthenticationException,
|
||||
self::NotSupportedException,
|
||||
self::UnsupportedProjectTypeException
|
||||
self::UnsupportedProjectTypeException,
|
||||
self::UnsupportedArchiveException,
|
||||
self::ArchiveException,
|
||||
self::PackageFetchException
|
||||
];
|
||||
}
|
|
@ -47,7 +47,6 @@
|
|||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\RuntimeCache;
|
||||
use ncc\Utilities\Validate;
|
||||
use SplFileInfo;
|
||||
|
||||
class ComposerSourceBuiltin implements ServiceSourceInterface
|
||||
|
@ -277,15 +276,7 @@
|
|||
{
|
||||
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 Functions::convertToSemVer($version_map[$package_name]);
|
||||
}
|
||||
|
||||
return '1.0.0';
|
||||
|
@ -335,7 +326,7 @@
|
|||
$dependency = new ProjectConfiguration\Dependency();
|
||||
$dependency->Name = $package_name;
|
||||
$dependency->SourceType = DependencySourceType::Local;
|
||||
$dependency->Version = self::versionMap($item->PackageName, $version_map);;
|
||||
$dependency->Version = self::versionMap($item->PackageName, $version_map);
|
||||
$dependency->Source = $package_name . '.ncc';
|
||||
$project_configuration->Build->addDependency($dependency);
|
||||
}
|
||||
|
@ -359,22 +350,6 @@
|
|||
return $project_configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a version if available from the input
|
||||
*
|
||||
* @param string $input
|
||||
* @return string|null
|
||||
*/
|
||||
private static function extractVersion(string $input): ?string
|
||||
{
|
||||
if (stripos($input, ':'))
|
||||
{
|
||||
return explode(':', $input)[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the applicable options configured for composer
|
||||
*
|
||||
|
|
|
@ -2,12 +2,9 @@
|
|||
|
||||
namespace ncc\Classes\GithubExtension;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\HttpRequestType;
|
||||
use ncc\Abstracts\Versions;
|
||||
use ncc\Classes\GitClient;
|
||||
use ncc\Classes\HttpClient;
|
||||
use ncc\Classes\NccExtension\PackageCompiler;
|
||||
use ncc\Exceptions\AuthenticationException;
|
||||
use ncc\Exceptions\GithubServiceException;
|
||||
use ncc\Exceptions\GitlabServiceException;
|
||||
|
@ -18,134 +15,28 @@
|
|||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Objects\HttpRequest;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Objects\RepositoryQueryResults;
|
||||
use ncc\Objects\Vault\Entry;
|
||||
use ncc\ThirdParty\jelix\Version\VersionComparator;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\Validate;
|
||||
|
||||
class GithubService implements RepositorySourceInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Attempts to fetch the .ncc package from a remote source, optionally attempts to compile
|
||||
* the package if it cannot find a pre-compiled version.
|
||||
*
|
||||
* Priority of fetching:
|
||||
* - Pre-compiled version
|
||||
* - Source code of specified release
|
||||
* - Git repository (checkout specified release)
|
||||
* - Git repository master branch (If version is not specified or set to latest)
|
||||
*
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @throws GithubServiceException
|
||||
*/
|
||||
public static function fetch(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): string
|
||||
{
|
||||
// Check if there is a pre-compiled version of the package available
|
||||
try
|
||||
{
|
||||
Console::outVerbose(sprintf('Attempting to fetch pre-compiled package from %s', $definedRemoteSource->Host));
|
||||
$ncc_package = self::getNccPackage($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$ncc_package = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
if($ncc_package !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Functions::downloadGitServiceFile($ncc_package, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new GithubServiceException(sprintf('Failed to download pre-compiled package from %s', $definedRemoteSource->Host), $e);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the specified version is a release
|
||||
try
|
||||
{
|
||||
Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host));
|
||||
$release_url = self::getRelease($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$release_url = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
// If the specified version is a release, download the source code
|
||||
if($release_url !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$release_file = Functions::downloadGitServiceFile($release_url, $entry);
|
||||
$project_path = Functions::extractArchive($release_file);
|
||||
return PackageCompiler::tryCompile($project_path);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new GithubServiceException(sprintf('Failed to download release from %s', $definedRemoteSource->Host), $e);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console::outVerbose(sprintf('Attempting to fetch git repository from %s', $definedRemoteSource->Host));
|
||||
$git_url = self::fetchGitUri($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$git_url = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
if($git_url !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$project_path = GitClient::cloneRepository($git_url);
|
||||
|
||||
foreach(GitClient::getTags($project_path) as $tag)
|
||||
{
|
||||
$tag = str_replace('v', '', $tag);
|
||||
if(VersionComparator::compareVersion($tag, $packageInput->Version) === 0)
|
||||
{
|
||||
GitClient::checkout($project_path, $tag);
|
||||
return PackageCompiler::tryCompile($project_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new GithubServiceException(sprintf('Failed to clone git repository from %s', $definedRemoteSource->Host), $e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new GithubServiceException('Unable to fetch package from remote source');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the git repository url of the repository, versions cannot be specified.
|
||||
*
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
* @throws AuthenticationException
|
||||
* @throws GithubServiceException
|
||||
* @throws GitlabServiceException
|
||||
* @throws AuthenticationException
|
||||
* @throws HttpException
|
||||
* @throws MalformedJsonException
|
||||
*/
|
||||
public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string
|
||||
public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
|
||||
{
|
||||
$httpRequest = new HttpRequest();
|
||||
$protocol = ($definedRemoteSource->SSL ? "https" : "http");
|
||||
|
@ -153,23 +44,17 @@
|
|||
$owner_f = str_ireplace(".", "%2F", $owner_f);
|
||||
$repository = urlencode($packageInput->Package);
|
||||
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository";
|
||||
$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_decoded = self::getJsonResponse($httpRequest, $entry);
|
||||
|
||||
$response = HttpClient::request($httpRequest, true);
|
||||
$query = new RepositoryQueryResults();
|
||||
$query->Files->GitSshUrl = ($response_decoded['ssh_url'] ?? null);
|
||||
$query->Files->GitHttpUrl = ($response_decoded['clone_url'] ?? null);
|
||||
$query->Version = Functions::convertToSemVer($response_decoded['default_branch'] ?? null);
|
||||
$query->ReleaseDescription = ($response_decoded['description'] ?? null);
|
||||
$query->ReleaseName = ($response_decoded['name'] ?? null);
|
||||
|
||||
if($response->StatusCode != 200)
|
||||
throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
|
||||
|
||||
$response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY);
|
||||
|
||||
return
|
||||
$response_decoded['git_url'] ??
|
||||
$response_decoded['clone_url'] ??
|
||||
$response_decoded['ssh_url'] ??
|
||||
throw new GithubServiceException('Failed to fetch the repository URL.');
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,7 +63,7 @@
|
|||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
* @throws AuthenticationException
|
||||
* @throws GithubServiceException
|
||||
* @throws GitlabServiceException
|
||||
|
@ -186,42 +71,16 @@
|
|||
* @throws MalformedJsonException
|
||||
* @throws VersionNotFoundException
|
||||
*/
|
||||
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string
|
||||
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
|
||||
{
|
||||
$releases = self::getReleases($packageInput, $definedRemoteSource, $entry);
|
||||
|
||||
if(count($releases) === 0)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
|
||||
if($packageInput->Version == Versions::Latest)
|
||||
{
|
||||
$latest_version = null;
|
||||
foreach($releases as $version => $url)
|
||||
{
|
||||
if($latest_version == null)
|
||||
{
|
||||
$latest_version = $version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(VersionComparator::compareVersion($version, $latest_version) == 1)
|
||||
$latest_version = $version;
|
||||
}
|
||||
|
||||
return $releases[$latest_version]['url'];
|
||||
}
|
||||
|
||||
if(!isset($releases[$packageInput->Version]))
|
||||
throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version));
|
||||
|
||||
return $releases[$packageInput->Version]['url'];
|
||||
return self::processReleases($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
* @throws AuthenticationException
|
||||
* @throws GithubServiceException
|
||||
* @throws GitlabServiceException
|
||||
|
@ -229,43 +88,9 @@
|
|||
* @throws MalformedJsonException
|
||||
* @throws VersionNotFoundException
|
||||
*/
|
||||
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string
|
||||
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
|
||||
{
|
||||
$releases = self::getReleases($packageInput, $definedRemoteSource, $entry);
|
||||
|
||||
if(count($releases) === 0)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
|
||||
if($packageInput->Version == Versions::Latest)
|
||||
{
|
||||
$latest_version = null;
|
||||
foreach($releases as $version => $url)
|
||||
{
|
||||
if($latest_version == null)
|
||||
{
|
||||
$latest_version = $version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(VersionComparator::compareVersion($version, $latest_version) == 1)
|
||||
$latest_version = $version;
|
||||
}
|
||||
|
||||
$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'] ?? null;
|
||||
if($return === null)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
|
||||
return $return;
|
||||
return self::processReleases($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -289,17 +114,7 @@
|
|||
$owner_f = str_ireplace(".", "%2F", $owner_f);
|
||||
$repository = urlencode($packageInput->Package);
|
||||
$httpRequest->Url = $protocol . '://' . $definedRemoteSource->Host . "/repos/$owner_f/$repository/releases";
|
||||
$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, true);
|
||||
|
||||
if($response->StatusCode != 200)
|
||||
throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
|
||||
|
||||
$response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY);
|
||||
$response_decoded = self::getJsonResponse($httpRequest, $entry);
|
||||
|
||||
if(count($response_decoded) == 0)
|
||||
return [];
|
||||
|
@ -307,20 +122,24 @@
|
|||
$return = [];
|
||||
foreach($response_decoded as $release)
|
||||
{
|
||||
// Make the tag_name version friendly
|
||||
$release_version = str_replace('v', '', $release['tag_name']);
|
||||
$return[$release_version] = [
|
||||
'url' => ($release['zipball_url'] ?? $release['tarball_url'] ?? null)
|
||||
];
|
||||
$query_results = new RepositoryQueryResults();
|
||||
$query_results->Version = Functions::convertToSemVer($release['tag_name']);
|
||||
$query_results->ReleaseName = $release['name'];
|
||||
$query_results->ReleaseDescription = $release['body'];
|
||||
$query_results->Files->ZipballUrl = ($release['zipball_url'] ?? null);
|
||||
$query_results->Files->TarballUrl = ($release['tarball_url'] ?? null);
|
||||
|
||||
if(isset($release['assets']))
|
||||
{
|
||||
foreach($release['assets'] as $asset)
|
||||
{
|
||||
if(self::parseAsset($asset) !== null)
|
||||
$return[$release_version]['package'] = $asset['browser_download_url'];
|
||||
$parsed_asset = self::parseAsset($asset);
|
||||
if($parsed_asset !== null)
|
||||
$query_results->Files->PackageUrl = $parsed_asset;
|
||||
}
|
||||
}
|
||||
|
||||
$return[$query_results->Version] = $query_results;
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
@ -343,4 +162,98 @@
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param HttpRequest $httpRequest
|
||||
* @param Entry|null $entry
|
||||
* @return array
|
||||
* @throws AuthenticationException
|
||||
* @throws GithubServiceException
|
||||
* @throws GitlabServiceException
|
||||
* @throws HttpException
|
||||
* @throws MalformedJsonException
|
||||
*/
|
||||
private static function getJsonResponse(HttpRequest $httpRequest, ?Entry $entry): array
|
||||
{
|
||||
$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, true);
|
||||
|
||||
if ($response->StatusCode != 200)
|
||||
throw new GithubServiceException(sprintf('Failed to fetch releases for the given repository. Status code: %s', $response->StatusCode));
|
||||
|
||||
$response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY);
|
||||
return $response_decoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return mixed
|
||||
* @throws AuthenticationException
|
||||
* @throws GithubServiceException
|
||||
* @throws GitlabServiceException
|
||||
* @throws HttpException
|
||||
* @throws MalformedJsonException
|
||||
* @throws VersionNotFoundException
|
||||
*/
|
||||
private static function processReleases(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): mixed
|
||||
{
|
||||
$releases = self::getReleases($packageInput, $definedRemoteSource, $entry);
|
||||
|
||||
if (count($releases) === 0)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
|
||||
if ($packageInput->Version == Versions::Latest)
|
||||
{
|
||||
$latest_version = null;
|
||||
foreach ($releases as $release)
|
||||
{
|
||||
if ($latest_version == null)
|
||||
{
|
||||
$latest_version = $release->Version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (VersionComparator::compareVersion($release->Version, $latest_version) == 1)
|
||||
$latest_version = $release->Version;
|
||||
}
|
||||
|
||||
return $releases[$latest_version];
|
||||
}
|
||||
|
||||
// Query a specific version
|
||||
if (!isset($releases[$packageInput->Version]))
|
||||
{
|
||||
// Find the closest thing to the requested version
|
||||
$selected_version = null;
|
||||
foreach ($releases as $version => $url)
|
||||
{
|
||||
if ($selected_version == null)
|
||||
{
|
||||
$selected_version = $version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (VersionComparator::compareVersion($version, $packageInput->Version) == 1)
|
||||
$selected_version = $version;
|
||||
}
|
||||
|
||||
if ($selected_version == null)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$selected_version = $packageInput->Version;
|
||||
}
|
||||
|
||||
if (!isset($releases[$selected_version]))
|
||||
throw new VersionNotFoundException(sprintf('No releases found for the given repository. (Selected version: %s)', $selected_version));
|
||||
|
||||
return $releases[$selected_version];
|
||||
}
|
||||
}
|
|
@ -2,11 +2,8 @@
|
|||
|
||||
namespace ncc\Classes\GitlabExtension;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\Versions;
|
||||
use ncc\Classes\GitClient;
|
||||
use ncc\Classes\HttpClient;
|
||||
use ncc\Classes\NccExtension\PackageCompiler;
|
||||
use ncc\Exceptions\AuthenticationException;
|
||||
use ncc\Exceptions\GitlabServiceException;
|
||||
use ncc\Exceptions\HttpException;
|
||||
|
@ -17,88 +14,13 @@
|
|||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Objects\HttpRequest;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Objects\RepositoryQueryResults;
|
||||
use ncc\Objects\Vault\Entry;
|
||||
use ncc\ThirdParty\jelix\Version\VersionComparator;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
|
||||
class GitlabService implements RepositorySourceInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* Attempts to fetch the requested package from the Gitlab repository, and returns the pre-compiled package
|
||||
*
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @throws GitlabServiceException
|
||||
*/
|
||||
public static function fetch(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): string
|
||||
{
|
||||
// Check if the specified version is a release
|
||||
try
|
||||
{
|
||||
Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host));
|
||||
$release_url = self::getRelease($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$release_url = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
// If the specified version is a release, download the source code
|
||||
if($release_url !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$release_file = Functions::downloadGitServiceFile($release_url, $entry);
|
||||
$project_path = Functions::extractArchive($release_file);
|
||||
return PackageCompiler::tryCompile($project_path);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new GitlabServiceException(sprintf('Failed to download release from %s', $definedRemoteSource->Host), $e);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console::outVerbose(sprintf('Attempting to fetch git repository from %s', $definedRemoteSource->Host));
|
||||
$git_url = self::fetchGitUri($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$git_url = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
if($git_url !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$project_path = GitClient::cloneRepository($git_url);
|
||||
|
||||
foreach(GitClient::getTags($project_path) as $tag)
|
||||
{
|
||||
$tag = str_replace('v', '', $tag);
|
||||
if(VersionComparator::compareVersion($tag, $packageInput->Version) === 0)
|
||||
{
|
||||
GitClient::checkout($project_path, $tag);
|
||||
return PackageCompiler::tryCompile($project_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new GitlabServiceException(sprintf('Failed to clone git repository from %s', $definedRemoteSource->Host), $e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new GitlabServiceException('Unable to fetch package from remote source');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to return the gitRepositoryUrl of a release, cannot specify a version.
|
||||
* This needs to be done using git
|
||||
|
@ -106,13 +28,13 @@
|
|||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
* @throws AuthenticationException
|
||||
* @throws GitlabServiceException
|
||||
* @throws HttpException
|
||||
* @throws MalformedJsonException
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): string
|
||||
public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): RepositoryQueryResults
|
||||
{
|
||||
$httpRequest = new HttpRequest();
|
||||
$protocol = ($definedRemoteSource->SSL ? "https" : "http");
|
||||
|
@ -130,10 +52,14 @@
|
|||
|
||||
$response_decoded = Functions::loadJson($response->Body, Functions::FORCE_ARRAY);
|
||||
|
||||
return
|
||||
$response_decoded['http_url_to_repo'] ??
|
||||
$response_decoded['ssh_url_to_repo'] ??
|
||||
throw new GitlabServiceException('Failed to fetch the repository URL.');
|
||||
$query = new RepositoryQueryResults();
|
||||
$query->Files->GitSshUrl = ($response_decoded['ssh_url_to_repo'] ?? null);
|
||||
$query->Files->GitHttpUrl = ($response_decoded['http_url_to_repo'] ?? null);
|
||||
$query->Version = Functions::convertToSemVer($response_decoded['default_branch']) ?? null;
|
||||
$query->ReleaseDescription = ($response_decoded['description'] ?? null);
|
||||
$query->ReleaseName = ($response_decoded['name'] ?? null);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,52 +68,78 @@
|
|||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
* @throws AuthenticationException
|
||||
* @throws GitlabServiceException
|
||||
* @throws HttpException
|
||||
* @throws MalformedJsonException
|
||||
* @throws VersionNotFoundException
|
||||
*/
|
||||
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string
|
||||
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
|
||||
{
|
||||
$releases = self::getReleases($packageInput->Vendor, $packageInput->Package, $definedRemoteSource, $entry);
|
||||
|
||||
if(count($releases) === 0)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
|
||||
// Query the latest package only
|
||||
if($packageInput->Version == Versions::Latest)
|
||||
{
|
||||
$latest_version = null;
|
||||
foreach($releases as $version => $url)
|
||||
foreach($releases as $release)
|
||||
{
|
||||
if($latest_version == null)
|
||||
{
|
||||
$latest_version = $version;
|
||||
$latest_version = $release->Version;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(VersionComparator::compareVersion($version, $latest_version) == 1)
|
||||
$latest_version = $version;
|
||||
if(VersionComparator::compareVersion($release->Version, $latest_version) == 1)
|
||||
$latest_version = $release->Version;
|
||||
}
|
||||
|
||||
return $releases[$latest_version];
|
||||
}
|
||||
|
||||
// Query a specific version
|
||||
if(!isset($releases[$packageInput->Version]))
|
||||
throw new VersionNotFoundException(sprintf('The given version "%s" does not exist.', $packageInput->Version));
|
||||
{
|
||||
// Find the closest thing to the requested version
|
||||
$selected_version = null;
|
||||
foreach($releases as $version => $url)
|
||||
{
|
||||
if($selected_version == null)
|
||||
{
|
||||
$selected_version = $version;
|
||||
continue;
|
||||
}
|
||||
|
||||
return $releases[$packageInput->Version];
|
||||
if(VersionComparator::compareVersion($version, $packageInput->Version) == 1)
|
||||
$selected_version = $version;
|
||||
}
|
||||
|
||||
if($selected_version == null)
|
||||
throw new VersionNotFoundException('No releases found for the given repository.');
|
||||
}
|
||||
else
|
||||
{
|
||||
$selected_version = $packageInput->Version;
|
||||
}
|
||||
|
||||
if(!isset($releases[$selected_version]))
|
||||
throw new VersionNotFoundException(sprintf('No releases found for the given repository. (Selected version: %s)', $selected_version));
|
||||
|
||||
return $releases[$selected_version];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string
|
||||
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults
|
||||
{
|
||||
throw new NotSupportedException(sprintf('The given repository source "%s" does not support ncc packages.', $definedRemoteSource->Host));
|
||||
}
|
||||
|
@ -230,25 +182,39 @@
|
|||
$return = [];
|
||||
foreach($response_decoded as $release)
|
||||
{
|
||||
// Make the tag_name version friendly
|
||||
$release_version = str_replace('v', '', $release['tag_name']);
|
||||
$query_results = new RepositoryQueryResults();
|
||||
$query_results->ReleaseName = ($release['name'] ?? null);
|
||||
$query_results->ReleaseDescription = ($release['description'] ?? null);
|
||||
$query_results->Version = Functions::convertToSemVer($release['tag_name']);
|
||||
|
||||
if(isset($release['assets']) && isset($release['assets']['sources']))
|
||||
{
|
||||
if(count($release['assets']['sources']) > 0)
|
||||
{
|
||||
// Use the first source as the download url, if a tar.gz file is available, use that instead.
|
||||
$return[$release_version] = $release['assets']['sources'][0]['url'];
|
||||
foreach($release['assets']['sources'] as $source)
|
||||
{
|
||||
if($source['format'] == 'zip')
|
||||
{
|
||||
$return[$release_version] = $source['url'];
|
||||
$query_results->Files->ZipballUrl = $source['url'];
|
||||
break;
|
||||
}
|
||||
|
||||
if($source['format'] == 'tar.gz')
|
||||
{
|
||||
$query_results->Files->ZipballUrl = $source['url'];
|
||||
break;
|
||||
}
|
||||
|
||||
if($source['format'] == 'ncc')
|
||||
{
|
||||
$query_results->Files->PackageUrl = $source['url'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$return[$query_results->Version] = $query_results;
|
||||
}
|
||||
|
||||
return $return;
|
||||
|
|
|
@ -5,10 +5,14 @@
|
|||
use Exception;
|
||||
use ncc\Abstracts\CompilerExtensions;
|
||||
use ncc\Abstracts\ConstantReferences;
|
||||
use ncc\Abstracts\DefinedRemoteSourceType;
|
||||
use ncc\Abstracts\LogLevel;
|
||||
use ncc\Abstracts\Options\BuildConfigurationValues;
|
||||
use ncc\Abstracts\ProjectType;
|
||||
use ncc\Classes\ComposerExtension\ComposerSourceBuiltin;
|
||||
use ncc\Classes\GitClient;
|
||||
use ncc\Classes\GithubExtension\GithubService;
|
||||
use ncc\Classes\GitlabExtension\GitlabService;
|
||||
use ncc\Classes\PhpExtension\PhpCompiler;
|
||||
use ncc\CLI\Main;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
|
@ -17,17 +21,24 @@
|
|||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\MalformedJsonException;
|
||||
use ncc\Exceptions\PackageFetchException;
|
||||
use ncc\Exceptions\PackagePreparationFailedException;
|
||||
use ncc\Exceptions\ProjectConfigurationNotFoundException;
|
||||
use ncc\Exceptions\UnsupportedCompilerExtensionException;
|
||||
use ncc\Exceptions\UnsupportedProjectTypeException;
|
||||
use ncc\Exceptions\UnsupportedRemoteSourceTypeException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Interfaces\CompilerInterface;
|
||||
use ncc\Interfaces\RepositorySourceInterface;
|
||||
use ncc\Managers\ProjectManager;
|
||||
use ncc\ncc;
|
||||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Objects\Package;
|
||||
use ncc\Objects\ProjectConfiguration;
|
||||
use ncc\Objects\ProjectConfiguration\Assembly;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Objects\Vault\Entry;
|
||||
use ncc\ThirdParty\jelix\Version\VersionComparator;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
|
@ -96,10 +107,13 @@
|
|||
* @throws BuildException
|
||||
* @throws UnsupportedProjectTypeException
|
||||
*/
|
||||
public static function tryCompile(string $path): string
|
||||
public static function tryCompile(string $path, ?string $version=null): string
|
||||
{
|
||||
$project_type = Resolver::detectProjectType($path);
|
||||
|
||||
if($version !== null)
|
||||
$version = Functions::convertToSemVer($version);
|
||||
|
||||
try
|
||||
{
|
||||
if($project_type->ProjectType == ProjectType::Composer)
|
||||
|
@ -108,6 +122,7 @@
|
|||
if($project_type->ProjectType == ProjectType::Ncc)
|
||||
{
|
||||
$project_manager = new ProjectManager($project_type->ProjectPath);
|
||||
$project_manager->getProjectConfiguration()->Assembly->Version = $version;
|
||||
return $project_manager->build();
|
||||
}
|
||||
}
|
||||
|
@ -119,6 +134,7 @@
|
|||
throw new UnsupportedProjectTypeException('The project type \'' . $project_type->ProjectType . '\' is not supported');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compiles the execution policies of the package
|
||||
*
|
||||
|
|
15
src/ncc/Exceptions/ArchiveException.php
Normal file
15
src/ncc/Exceptions/ArchiveException.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class ArchiveException extends Exception
|
||||
{
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::ArchiveException, $previous);
|
||||
}
|
||||
}
|
14
src/ncc/Exceptions/PackageFetchException.php
Normal file
14
src/ncc/Exceptions/PackageFetchException.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class PackageFetchException extends \Exception
|
||||
{
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::PackageFetchException, $previous);
|
||||
}
|
||||
}
|
20
src/ncc/Exceptions/UnsupportedArchiveException.php
Normal file
20
src/ncc/Exceptions/UnsupportedArchiveException.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
namespace ncc\Exceptions;
|
||||
|
||||
use Exception;
|
||||
use ncc\Abstracts\ExceptionCodes;
|
||||
use Throwable;
|
||||
|
||||
class UnsupportedArchiveException extends Exception
|
||||
{
|
||||
/**
|
||||
* @param string $message
|
||||
* @param Throwable|null $previous
|
||||
*/
|
||||
public function __construct(string $message = "", ?Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, ExceptionCodes::UnsupportedArchiveException, $previous);
|
||||
$this->message = $message;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Objects\RepositoryQueryResults;
|
||||
use ncc\Objects\Vault\Entry;
|
||||
|
||||
interface RepositorySourceInterface
|
||||
|
@ -14,9 +15,9 @@
|
|||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
*/
|
||||
public static function fetchGitUri(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): string;
|
||||
public static function getGitRepository(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry=null): RepositoryQueryResults;
|
||||
|
||||
/**
|
||||
* Returns the release url of the repository, versions can be specified.
|
||||
|
@ -24,9 +25,9 @@
|
|||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
*/
|
||||
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string;
|
||||
public static function getRelease(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults;
|
||||
|
||||
/**
|
||||
* Returns the download URL of the pre-compiled .ncc package if available
|
||||
|
@ -34,7 +35,7 @@
|
|||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @return RepositoryQueryResults
|
||||
*/
|
||||
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): string;
|
||||
public static function getNccPackage(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry = null): RepositoryQueryResults;
|
||||
}
|
|
@ -8,15 +8,13 @@
|
|||
use ncc\Abstracts\BuiltinRemoteSourceType;
|
||||
use ncc\Abstracts\CompilerExtensions;
|
||||
use ncc\Abstracts\ConstantReferences;
|
||||
use ncc\Abstracts\DefinedRemoteSourceType;
|
||||
use ncc\Abstracts\DependencySourceType;
|
||||
use ncc\Abstracts\LogLevel;
|
||||
use ncc\Abstracts\RemoteSourceType;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Abstracts\Versions;
|
||||
use ncc\Classes\ComposerExtension\ComposerSourceBuiltin;
|
||||
use ncc\Classes\GithubExtension\GithubService;
|
||||
use ncc\Classes\GitlabExtension\GitlabService;
|
||||
use ncc\Classes\GitClient;
|
||||
use ncc\Classes\NccExtension\PackageCompiler;
|
||||
use ncc\Classes\PhpExtension\PhpInstaller;
|
||||
use ncc\CLI\Main;
|
||||
|
@ -28,13 +26,14 @@
|
|||
use ncc\Exceptions\MissingDependencyException;
|
||||
use ncc\Exceptions\NotImplementedException;
|
||||
use ncc\Exceptions\PackageAlreadyInstalledException;
|
||||
use ncc\Exceptions\PackageFetchException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Exceptions\PackageNotFoundException;
|
||||
use ncc\Exceptions\PackageParsingException;
|
||||
use ncc\Exceptions\UnsupportedCompilerExtensionException;
|
||||
use ncc\Exceptions\UnsupportedRemoteSourceTypeException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Exceptions\VersionNotFoundException;
|
||||
use ncc\Interfaces\RepositorySourceInterface;
|
||||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Objects\InstallationPaths;
|
||||
use ncc\Objects\Package;
|
||||
|
@ -43,9 +42,11 @@
|
|||
use ncc\Objects\ProjectConfiguration\Dependency;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Objects\Vault\Entry;
|
||||
use ncc\ThirdParty\jelix\Version\VersionComparator;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
use ncc\ThirdParty\theseer\DirectoryScanner\DirectoryScanner;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
use ncc\Utilities\PathFinder;
|
||||
use ncc\Utilities\Resolver;
|
||||
|
@ -80,6 +81,7 @@
|
|||
* Installs a local package onto the system
|
||||
*
|
||||
* @param string $package_path
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
|
@ -340,75 +342,122 @@
|
|||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param Entry|null $auth_entry
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @throws InstallationException
|
||||
* @throws NotImplementedException
|
||||
* @throws PackageFetchException
|
||||
*/
|
||||
public function fetchFromSource(string $source, ?Entry $auth_entry=null): string
|
||||
public function fetchFromSource(string $source, ?Entry $entry=null): string
|
||||
{
|
||||
$parsed_source = new RemotePackageInput($source);
|
||||
$input = new RemotePackageInput($source);
|
||||
|
||||
if($parsed_source->Source == null)
|
||||
throw new InstallationException('No source specified');
|
||||
|
||||
if($parsed_source->Package == null)
|
||||
throw new InstallationException('No package specified');
|
||||
|
||||
if($parsed_source->Version == null)
|
||||
$parsed_source->Version = Versions::Latest;
|
||||
|
||||
$remote_source_type = Resolver::detectRemoteSourceType($parsed_source->Source);
|
||||
if($input->Source == null)
|
||||
throw new PackageFetchException('No source specified');
|
||||
if($input->Package == null)
|
||||
throw new PackageFetchException('No package specified');
|
||||
if($input->Version == null)
|
||||
$input->Version = Versions::Latest;
|
||||
|
||||
$remote_source_type = Resolver::detectRemoteSourceType($input->Source);
|
||||
if($remote_source_type == RemoteSourceType::Builtin)
|
||||
{
|
||||
switch($parsed_source->Source)
|
||||
switch($input->Source)
|
||||
{
|
||||
case BuiltinRemoteSourceType::Composer:
|
||||
try
|
||||
{
|
||||
return ComposerSourceBuiltin::fetch($parsed_source);
|
||||
return ComposerSourceBuiltin::fetch($input);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new InstallationException('Cannot fetch package from composer source, ' . $e->getMessage(), $e);
|
||||
throw new PackageFetchException('Cannot fetch package from composer source, ' . $e->getMessage(), $e);
|
||||
}
|
||||
|
||||
default:
|
||||
throw new InstallationException('Builtin source type ' . $parsed_source->Source . ' is not implemented');
|
||||
throw new NotImplementedException('Builtin source type ' . $input->Source . ' is not implemented');
|
||||
}
|
||||
}
|
||||
|
||||
if($remote_source_type == RemoteSourceType::Defined)
|
||||
{
|
||||
$remote_source_manager = new RemoteSourcesManager();
|
||||
$remote_source = $remote_source_manager->getRemoteSource($parsed_source->Source);
|
||||
if($remote_source == null)
|
||||
throw new InstallationException('Remote source ' . $parsed_source->Source . ' is not defined');
|
||||
$source = $remote_source_manager->getRemoteSource($input->Source);
|
||||
if($source == null)
|
||||
throw new InstallationException('Remote source ' . $input->Source . ' is not defined');
|
||||
|
||||
/** @var RepositorySourceInterface $remote_service_client */
|
||||
$remote_service_client = match ($remote_source->Type) {
|
||||
DefinedRemoteSourceType::Gitlab => GitlabService::class,
|
||||
DefinedRemoteSourceType::Github => GithubService::class,
|
||||
default => throw new InstallationException('Remote source type ' . $remote_source->Type . ' is not implemented'),
|
||||
};
|
||||
$repositoryQueryResults = Functions::getRepositoryQueryResults($input, $source, $entry);
|
||||
|
||||
if($repositoryQueryResults->Files->ZipballUrl !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return $remote_service_client::fetch($parsed_source, $remote_source, $auth_entry);
|
||||
$archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->ZipballUrl, $entry);
|
||||
return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new InstallationException('Cannot fetch package from remote source, ' . $e->getMessage(), $e);
|
||||
unset($e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new InstallationException(sprintf('Unknown remote source type %s', $remote_source_type));
|
||||
if($repositoryQueryResults->Files->TarballUrl !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$archive = Functions::downloadGitServiceFile($repositoryQueryResults->Files->TarballUrl, $entry);
|
||||
return PackageCompiler::tryCompile(Functions::extractArchive($archive), $repositoryQueryResults->Version);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
}
|
||||
|
||||
if($repositoryQueryResults->Files->PackageUrl !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Functions::downloadGitServiceFile($repositoryQueryResults->Files->PackageUrl, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
}
|
||||
|
||||
if($repositoryQueryResults->Files->GitHttpUrl !== null || $repositoryQueryResults->Files->GitSshUrl !== null)
|
||||
{
|
||||
try
|
||||
{
|
||||
$git_repository = GitClient::cloneRepository($repositoryQueryResults->Files->GitHttpUrl ?? $repositoryQueryResults->Files->GitSshUrl);
|
||||
|
||||
foreach(GitClient::getTags($git_repository) as $tag)
|
||||
{
|
||||
if(VersionComparator::compareVersion($tag, $repositoryQueryResults->Version) === 0)
|
||||
{
|
||||
GitClient::checkout($git_repository, $tag);
|
||||
return PackageCompiler::tryCompile($git_repository, $repositoryQueryResults->Version);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
}
|
||||
}
|
||||
|
||||
throw new PackageFetchException(sprintf('Failed to fetch package \'%s\'', $input->Package));
|
||||
}
|
||||
|
||||
throw new PackageFetchException(sprintf('Unknown remote source type %s', $remote_source_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs a package from a source syntax (vendor/package=version@source)
|
||||
*
|
||||
* @param string $source
|
||||
* @param Entry|null $entry
|
||||
* @return string
|
||||
* @throws InstallationException
|
||||
*/
|
||||
|
@ -429,6 +478,7 @@
|
|||
* @param Dependency $dependency
|
||||
* @param Package $package
|
||||
* @param string $package_path
|
||||
* @param Entry|null $entry
|
||||
* @return void
|
||||
* @throws AccessDeniedException
|
||||
* @throws FileNotFoundException
|
||||
|
|
46
src/ncc/Objects/RepositoryQueryResults.php
Normal file
46
src/ncc/Objects/RepositoryQueryResults.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects;
|
||||
|
||||
use ncc\Objects\RepositoryQueryResults\Files;
|
||||
|
||||
class RepositoryQueryResults
|
||||
{
|
||||
/**
|
||||
* A collection of files that are available for download
|
||||
*
|
||||
* @var Files
|
||||
*/
|
||||
public $Files;
|
||||
|
||||
/**
|
||||
* The version of the package returned by the query
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $Version;
|
||||
|
||||
/**
|
||||
* The name of the release returned by the query
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $ReleaseName;
|
||||
|
||||
/**
|
||||
* The description of the release returned by the query
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $ReleaseDescription;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->Files = new Files();
|
||||
}
|
||||
}
|
50
src/ncc/Objects/RepositoryQueryResults/Files.php
Normal file
50
src/ncc/Objects/RepositoryQueryResults/Files.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace ncc\Objects\RepositoryQueryResults;
|
||||
|
||||
class Files
|
||||
{
|
||||
/**
|
||||
* The URL that points to a pre-compiled .ncc package
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $PackageUrl;
|
||||
|
||||
/**
|
||||
* The URL that points to a archived version of the source code
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $SourceUrl;
|
||||
|
||||
/**
|
||||
* The URL that points to a tarball archive of the repository
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $TarballUrl;
|
||||
|
||||
/**
|
||||
* The URL that points to a zip archive of the repository
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $ZipballUrl;
|
||||
|
||||
/**
|
||||
* The URL that points to the repository's source code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $GitHttpUrl;
|
||||
|
||||
/**
|
||||
* The URL that points to the repository's source code
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $GitSshUrl;
|
||||
}
|
|
@ -4,10 +4,13 @@
|
|||
|
||||
use Exception;
|
||||
use ncc\Abstracts\AuthenticationType;
|
||||
use ncc\Abstracts\DefinedRemoteSourceType;
|
||||
use ncc\Abstracts\HttpRequestType;
|
||||
use ncc\Abstracts\Runners;
|
||||
use ncc\Abstracts\Scopes;
|
||||
use ncc\Classes\BashExtension\BashRunner;
|
||||
use ncc\Classes\GithubExtension\GithubService;
|
||||
use ncc\Classes\GitlabExtension\GitlabService;
|
||||
use ncc\Classes\HttpClient;
|
||||
use ncc\Classes\LuaExtension\LuaRunner;
|
||||
use ncc\Classes\PerlExtension\PerlRunner;
|
||||
|
@ -16,6 +19,7 @@
|
|||
use ncc\Classes\PythonExtension\Python3Runner;
|
||||
use ncc\Classes\PythonExtension\PythonRunner;
|
||||
use ncc\Exceptions\AccessDeniedException;
|
||||
use ncc\Exceptions\ArchiveException;
|
||||
use ncc\Exceptions\AuthenticationException;
|
||||
use ncc\Exceptions\FileNotFoundException;
|
||||
use ncc\Exceptions\GitlabServiceException;
|
||||
|
@ -23,23 +27,29 @@
|
|||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\IOException;
|
||||
use ncc\Exceptions\MalformedJsonException;
|
||||
use ncc\Exceptions\UnsupportedArchiveException;
|
||||
use ncc\Exceptions\UnsupportedRunnerException;
|
||||
use ncc\Managers\ConfigurationManager;
|
||||
use ncc\Managers\CredentialManager;
|
||||
use ncc\Managers\PackageLockManager;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Objects\ComposerJson;
|
||||
use ncc\Objects\DefinedRemoteSource;
|
||||
use ncc\Objects\HttpRequest;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration\ExecutionPolicy;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Objects\RepositoryQueryResults;
|
||||
use ncc\Objects\RepositoryQueryResults\Files;
|
||||
use ncc\Objects\Vault\Entry;
|
||||
use ncc\ThirdParty\jelix\Version\Parser;
|
||||
use ncc\ThirdParty\jelix\Version\VersionComparator;
|
||||
use ncc\ThirdParty\Symfony\Filesystem\Filesystem;
|
||||
use PharData;
|
||||
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
|
||||
use ncc\ThirdParty\Symfony\Process\Process;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use Throwable;
|
||||
use ZipArchive;
|
||||
|
||||
/**
|
||||
* @author Zi Xing Narrakas
|
||||
|
@ -584,40 +594,96 @@
|
|||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string
|
||||
* @throws Exception
|
||||
* @return string|null
|
||||
* @throws ArchiveException
|
||||
* @throws UnsupportedArchiveException
|
||||
*/
|
||||
public static function extractArchive(string $path): ?string
|
||||
{
|
||||
$finfo = finfo_open(FILEINFO_MIME_TYPE);
|
||||
$mimeType = finfo_file($finfo, $path);
|
||||
finfo_close($finfo);
|
||||
$executable_finder = new ExecutableFinder();
|
||||
$unzip_executable = $executable_finder->find('unzip');
|
||||
$tar_executable = $executable_finder->find('tar');
|
||||
$out_path = dirname($path);
|
||||
$filesystem = new Filesystem();
|
||||
|
||||
if ($mimeType == 'application/zip')
|
||||
if(!$filesystem->exists($out_path))
|
||||
$filesystem->mkdir($out_path);
|
||||
|
||||
RuntimeCache::setFileAsTemporary($out_path);
|
||||
|
||||
$mimeType = mime_content_type($path);
|
||||
$supportedTypes = [];
|
||||
|
||||
if($unzip_executable !== null)
|
||||
{
|
||||
$zip = new ZipArchive;
|
||||
$res = $zip->open($path);
|
||||
if ($res === TRUE)
|
||||
{
|
||||
$zip->extractTo(dirname($path));
|
||||
$zip->close();
|
||||
return dirname($path);
|
||||
$supportedTypes = array_merge($supportedTypes, [
|
||||
'application/zip',
|
||||
'application/x-zip',
|
||||
'application/x-zip-compressed',
|
||||
'application/octet-stream',
|
||||
'application/x-compress',
|
||||
'application/x-compressed',
|
||||
'multipart/x-zip'
|
||||
]);
|
||||
}
|
||||
}
|
||||
if ($mimeType == 'application/x-tar' || $mimeType == 'application/tar')
|
||||
else
|
||||
{
|
||||
$phar = new PharData($path);
|
||||
$phar->extractTo(dirname($path), null, true);
|
||||
return dirname($path);
|
||||
}
|
||||
elseif ($mimeType == 'application/x-gzip' || $mimeType == 'application/gzip')
|
||||
if(RuntimeCache::get('warning_zip_shown') !== true)
|
||||
{
|
||||
$phar = new PharData($path);
|
||||
$phar->decompress();
|
||||
return dirname($path);
|
||||
Console::out('unzip executable not found. ZIP archives will not be supported.');
|
||||
RuntimeCache::set('warning_zip_shown', true);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
if($tar_executable !== null)
|
||||
{
|
||||
$supportedTypes = array_merge($supportedTypes, [
|
||||
'application/x-tar',
|
||||
'application/x-gzip',
|
||||
'application/x-bzip2',
|
||||
'application/x-xz'
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(RuntimeCache::get('warning_tar_shown') !== true)
|
||||
{
|
||||
Console::outWarning('tar executable not found. TAR archives will not be supported.');
|
||||
RuntimeCache::set('warning_tar_shown', true);
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($mimeType, $supportedTypes))
|
||||
throw new UnsupportedArchiveException("Unsupported archive type: $mimeType");
|
||||
|
||||
switch($mimeType)
|
||||
{
|
||||
case 'application/zip':
|
||||
$command = [$unzip_executable, $path, '-d', $out_path];
|
||||
break;
|
||||
case 'application/x-tar':
|
||||
$command = [$tar_executable, '--verbose', '-xf', $path, '-C', $out_path];
|
||||
break;
|
||||
case 'application/x-gzip':
|
||||
$command = [$tar_executable, '--verbose', '-xzf', $path, '-C', $out_path];
|
||||
break;
|
||||
case 'application/x-bzip2':
|
||||
$command = [$tar_executable, '--verbose', '-xjf', $path, '-C', $out_path];
|
||||
break;
|
||||
}
|
||||
|
||||
Console::out("Extracting archive $path");
|
||||
$process = new Process($command);
|
||||
|
||||
// display the output of the command
|
||||
$process->run(function ($type, $buffer) {
|
||||
Console::outVerbose($buffer);
|
||||
});
|
||||
|
||||
if (!$process->isSuccessful())
|
||||
throw new ArchiveException($process->getErrorOutput());
|
||||
|
||||
return $out_path;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -649,20 +715,207 @@
|
|||
* @param $version
|
||||
* @return string
|
||||
*/
|
||||
public static function convertToSemVer($version)
|
||||
public static function convertToSemVer($version): string
|
||||
{
|
||||
if(stripos($version, 'v') === 0)
|
||||
$version = substr($version, 1);
|
||||
if(!Validate::version($version))
|
||||
{
|
||||
$parts = explode('.', $version);
|
||||
$major = (string)null;
|
||||
$minor = (string)null;
|
||||
$patch = (string)null;
|
||||
|
||||
$buildmetadata = (string)null;
|
||||
if(count($parts) >= 1)
|
||||
$major = $parts[0];
|
||||
if(count($parts) >= 2)
|
||||
$minor = $parts[1];
|
||||
if(count($parts) >= 3)
|
||||
$patch = $parts[2];
|
||||
$buildmetadata = $parts[3];
|
||||
|
||||
// Assemble the SemVer compatible string
|
||||
$semver = "$major.$minor.$patch+$buildmetadata";
|
||||
$version = "$major.$minor.$patch";
|
||||
}
|
||||
if(!Validate::version($version))
|
||||
return '1.0.0';
|
||||
|
||||
return $semver;
|
||||
return $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a complete RepositoryQueryResults object
|
||||
*
|
||||
* @param RemotePackageInput $packageInput
|
||||
* @param DefinedRemoteSource $definedRemoteSource
|
||||
* @param Entry|null $entry
|
||||
* @return RepositoryQueryResults
|
||||
*/
|
||||
public static function getRepositoryQueryResults(RemotePackageInput $packageInput, DefinedRemoteSource $definedRemoteSource, ?Entry $entry): RepositoryQueryResults
|
||||
{
|
||||
$results = new RepositoryQueryResults();
|
||||
|
||||
switch($definedRemoteSource->Type)
|
||||
{
|
||||
case DefinedRemoteSourceType::Github:
|
||||
$source = GithubService::class;
|
||||
break;
|
||||
|
||||
case DefinedRemoteSourceType::Gitlab:
|
||||
$source = GitlabService::class;
|
||||
break;
|
||||
|
||||
default:
|
||||
return $results;
|
||||
}
|
||||
|
||||
// Check if the specified version is a release
|
||||
try
|
||||
{
|
||||
Console::outVerbose(sprintf('Attempting to fetch source code from %s', $definedRemoteSource->Host));
|
||||
$release_results = $source::getRelease($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$release_results = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
// If the specified version is a release, download the source code
|
||||
if($release_results !== null)
|
||||
{
|
||||
$results->ReleaseName = ($release_results->ReleaseName ?? null);
|
||||
$results->ReleaseDescription = ($release_results->ReleaseDescription ?? null);
|
||||
$results->Files = self::mergeFilesResults($release_results->Files, ($results->Files ?? null));
|
||||
if($release_results->Version !== null)
|
||||
$results->Version = $release_results->Version;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$git_results = $source::getGitRepository($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
$git_results = null;
|
||||
unset($e);
|
||||
}
|
||||
|
||||
if($git_results !== null)
|
||||
{
|
||||
if($results->ReleaseName == null)
|
||||
{
|
||||
$results->ReleaseName = ($git_results->ReleaseName ?? null);
|
||||
}
|
||||
elseif($git_results->ReleaseName !== null)
|
||||
{
|
||||
if(strlen($git_results->ReleaseName) > strlen($results->ReleaseName))
|
||||
$results->ReleaseName = $git_results->ReleaseName;
|
||||
}
|
||||
|
||||
if($results->ReleaseDescription == null)
|
||||
{
|
||||
$results->ReleaseDescription = ($git_results->ReleaseDescription ?? null);
|
||||
}
|
||||
elseif($git_results->ReleaseDescription !== null)
|
||||
{
|
||||
if(strlen($git_results->ReleaseDescription) > strlen($results->ReleaseDescription))
|
||||
$results->ReleaseDescription = $git_results->ReleaseDescription;
|
||||
}
|
||||
|
||||
if($results->Version == null)
|
||||
{
|
||||
$results->Version = ($git_results->Version ?? null);
|
||||
}
|
||||
elseif($git_results->Version !== null)
|
||||
{
|
||||
// Version compare
|
||||
if(VersionComparator::compareVersion($git_results->Version, $results->Version) > 0)
|
||||
$results->Version = $git_results->Version;
|
||||
}
|
||||
|
||||
$results->Files = self::mergeFilesResults($git_results->Files, ($results->Files ?? null));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$ncc_package_results = $source::getNccPackage($packageInput, $definedRemoteSource, $entry);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
unset($e);
|
||||
$ncc_package_results = null;
|
||||
}
|
||||
|
||||
if($ncc_package_results !== null)
|
||||
{
|
||||
if($results->ReleaseName == null)
|
||||
{
|
||||
$results->ReleaseName = ($ncc_package_results->ReleaseName ?? null);
|
||||
}
|
||||
elseif($ncc_package_results->ReleaseName !== null)
|
||||
{
|
||||
if(strlen($ncc_package_results->ReleaseName) > strlen($results->ReleaseName))
|
||||
$results->ReleaseName = $ncc_package_results->ReleaseName;
|
||||
}
|
||||
|
||||
if($results->ReleaseDescription == null)
|
||||
{
|
||||
$results->ReleaseDescription = ($ncc_package_results->ReleaseDescription ?? null);
|
||||
}
|
||||
elseif($ncc_package_results->ReleaseDescription !== null)
|
||||
{
|
||||
if(strlen($ncc_package_results->ReleaseDescription) > strlen($results->ReleaseDescription))
|
||||
$results->ReleaseDescription = $ncc_package_results->ReleaseDescription;
|
||||
}
|
||||
|
||||
if($results->Version == null)
|
||||
{
|
||||
$results->Version = ($ncc_package_results->Version ?? null);
|
||||
}
|
||||
elseif($ncc_package_results->Version !== null)
|
||||
{
|
||||
// Version compare
|
||||
if(VersionComparator::compareVersion($ncc_package_results->Version, $results->Version) > 0)
|
||||
$results->Version = $ncc_package_results->Version;
|
||||
}
|
||||
|
||||
$results->Files = self::mergeFilesResults($ncc_package_results->Files, ($results->Files ?? null));
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the given Files object with another Files object
|
||||
*
|
||||
* @param Files $input
|
||||
* @param Files|null $selected
|
||||
* @return Files
|
||||
*/
|
||||
private static function mergeFilesResults(RepositoryQueryResults\Files $input, ?RepositoryQueryResults\Files $selected=null): RepositoryQueryResults\Files
|
||||
{
|
||||
if($selected == null)
|
||||
$selected = new RepositoryQueryResults\Files();
|
||||
|
||||
if($input->GitSshUrl !== null)
|
||||
$selected->GitSshUrl = $input->GitSshUrl;
|
||||
|
||||
if($input->GitHttpUrl !== null)
|
||||
$selected->GitHttpUrl = $input->GitHttpUrl;
|
||||
|
||||
if($input->SourceUrl !== null)
|
||||
$selected->SourceUrl = $input->SourceUrl;
|
||||
|
||||
if($input->TarballUrl !== null)
|
||||
$selected->TarballUrl = $input->TarballUrl;
|
||||
|
||||
if($input->ZipballUrl !== null)
|
||||
$selected->ZipballUrl = $input->ZipballUrl;
|
||||
|
||||
if($input->PackageUrl !== null)
|
||||
$selected->PackageUrl = $input->PackageUrl;
|
||||
|
||||
return $selected;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue