Add functionality to install project dependencies
Added a new feature in `ProjectManager.php` that allows automatic installation of a project's dependencies. The `installDependencies` function eases the task of separately installing each dependency. Now, both public and private dependencies can be installed collectively using the 'install' command added in `ProjectMenu.php`. This functionality is further documented in `DOCUMENTATION.md`.
This commit is contained in:
parent
c82bc7195a
commit
35981115eb
4 changed files with 173 additions and 1 deletions
|
@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [2.0.1] - Unreleased
|
||||
|
||||
This update introduces minor bug fixes and changes
|
||||
Added a new feature in `ProjectManager.php` that allows automatic installation of a project's dependencies. The
|
||||
`installDependencies` function eases the task of separately installing each dependency. Now, both public and private
|
||||
dependencies can be installed collectively using the 'install' command added in `ProjectMenu.php`. This functionality
|
||||
is further documented in `DOCUMENTATION.md`
|
||||
|
||||
### Added
|
||||
- Add functionality to install project dependencies
|
||||
|
||||
### Fixed
|
||||
- Correct exception message for configuration property in `\ncc\Objects\ProjectConfiguration\Build > BuildConfiguration > fromArray()`
|
||||
|
|
|
@ -41,6 +41,7 @@ basic usage, standards, and much more.
|
|||
* [Applying Templates (template)](#applying-templates-template)
|
||||
* [phpcli template](#phpcli-template)
|
||||
* [phplib template](#phplib-template)
|
||||
* [Install Dependencies (install)](#install-dependencies-install)
|
||||
* [Package Management (package or pkg)](#package-management-package-or-pkg)
|
||||
* [Listing Installed Packages (list)](#listing-installed-packages-list)
|
||||
* [Installing Packages (install)](#installing-packages-install)
|
||||
|
@ -1083,6 +1084,20 @@ about autoloaders or anything like that, ncc will take care of that for you. Thi
|
|||
can only install packages onto your project directory, but it cannot bundle them into your programs if you wish to
|
||||
have an easy way to distribute your project to other people, this is where ncc shines.
|
||||
|
||||
### Install Dependencies (install)
|
||||
|
||||
The `install` command satisfies the dependencies of a project by installing the required packages. This command is
|
||||
not the same as `package install`, this command will install the dependencies of a project, while `package install`
|
||||
only handles your dependencies, including dependencies defined in build configurations.
|
||||
|
||||
| Option | Required | Example | Description |
|
||||
|--------------------------|----------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `--path`, `-p` | No | example_project | The project directory to use to install the dependencies, if not provided then the current working directory would be used instead |
|
||||
| `--authentication`, `-a` | No | johndoe | The authentication credential to use when pulling from private repositories, see [Credentials Management (cred)](#credentials-management-cred) for more information |
|
||||
|
||||
|
||||
|
||||
|
||||
## Package Management (package or pkg)
|
||||
|
||||
The command `package` provides a set of commands for managing packages, such as installing packages and uninstalling
|
||||
|
|
|
@ -24,10 +24,13 @@
|
|||
|
||||
use Exception;
|
||||
use ncc\Enums\ProjectTemplates;
|
||||
use ncc\Enums\Scopes;
|
||||
use ncc\Managers\CredentialManager;
|
||||
use ncc\Managers\ProjectManager;
|
||||
use ncc\Objects\CliHelpSection;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\Resolver;
|
||||
use ncc\Utilities\Security;
|
||||
|
||||
class ProjectMenu
|
||||
|
@ -37,6 +40,7 @@
|
|||
*
|
||||
* @param array $args
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function start(array $args): int
|
||||
{
|
||||
|
@ -50,6 +54,11 @@
|
|||
return self::applyTemplate($args);
|
||||
}
|
||||
|
||||
if(isset($args['install']))
|
||||
{
|
||||
return self::installProject($args);
|
||||
}
|
||||
|
||||
return self::displayOptions();
|
||||
}
|
||||
|
||||
|
@ -116,6 +125,93 @@
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the project dependencies
|
||||
*
|
||||
* @param array $args
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
private static function installProject(array $args): int
|
||||
{
|
||||
if(Resolver::resolveScope() !== Scopes::SYSTEM)
|
||||
{
|
||||
Console::outError('You cannot install packages in a user scope, please run this command as root', true, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(isset($args['path']) || isset($args['p']))
|
||||
{
|
||||
$project_path = $args['path'] ?? $args['p'];
|
||||
}
|
||||
elseif(is_file(getcwd() . DIRECTORY_SEPARATOR . 'project.json'))
|
||||
{
|
||||
$project_path = getcwd();
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::outError('Missing option: --path|-p, please specify the path to the project', true, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
$authentication = $args['authentication'] ?? $args['a'] ?? null;
|
||||
$authentication_entry = null;
|
||||
|
||||
if($authentication !== null)
|
||||
{
|
||||
$entry = (new CredentialManager())->getVault()?->getEntry($authentication);
|
||||
|
||||
if($entry->isEncrypted())
|
||||
{
|
||||
$tries = 0;
|
||||
while(true)
|
||||
{
|
||||
if (!$entry->unlock(Console::passwordInput('Password/Secret: ')))
|
||||
{
|
||||
$tries++;
|
||||
if ($tries >= 3)
|
||||
{
|
||||
Console::outError('Too many failed attempts.', true, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console::outError(sprintf('Incorrect password/secret, %d attempts remaining', 3 - $tries));
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::out('Authentication successful.');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$authentication_entry = $entry->getPassword();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$project_manager = new ProjectManager($project_path);
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException('There was an error while trying to load the project', $e, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console::out(sprintf('Installed %s packages', count($project_manager->installDependencies($authentication_entry))));
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
Console::outException('There was an error while trying to install the project dependencies', $e, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Console::out(sprintf('Project dependencies successfully installed in \'%s\'', $project_manager->getProjectPath()));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a template to the project
|
||||
*
|
||||
|
@ -183,6 +279,7 @@
|
|||
new CliHelpSection(['help'], 'Displays this help menu about the value command'),
|
||||
new CliHelpSection(['create', '--path|-p', '--name|-n', '--package|--pkg', '--ext'], 'Creates a new ncc project'),
|
||||
new CliHelpSection(['template', '--path|-p', '--name|-n'], 'Applies a template to the project'),
|
||||
new CliHelpSection(['install', '--path|-p', '--authentication|-a'], 'Installs the project dependencies'),
|
||||
];
|
||||
|
||||
$options_padding = Functions::detectParametersPadding($options) + 4;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
use ncc\Enums\Options\BuildConfigurationValues;
|
||||
use ncc\Enums\Options\InitializeProjectOptions;
|
||||
use ncc\Enums\ProjectTemplates;
|
||||
use ncc\Enums\Scopes;
|
||||
use ncc\Enums\SpecialConstants\AssemblyConstants;
|
||||
use ncc\Enums\Types\BuildOutputType;
|
||||
use ncc\Exceptions\BuildException;
|
||||
|
@ -44,9 +45,11 @@
|
|||
use ncc\Exceptions\NotSupportedException;
|
||||
use ncc\Exceptions\OperationException;
|
||||
use ncc\Exceptions\PathNotFoundException;
|
||||
use ncc\Interfaces\AuthenticationInterface;
|
||||
use ncc\Objects\ComposerJson;
|
||||
use ncc\Objects\Package\ExecutionUnit;
|
||||
use ncc\Objects\ProjectConfiguration;
|
||||
use ncc\Objects\RemotePackageInput;
|
||||
use ncc\Utilities\Console;
|
||||
use ncc\Utilities\Functions;
|
||||
use ncc\Utilities\IO;
|
||||
|
@ -195,6 +198,56 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install dependencies for the project
|
||||
*
|
||||
* @param AuthenticationInterface|null $authentication
|
||||
* @return array Array of installed packages
|
||||
* @throws OperationException
|
||||
* @throws IOException
|
||||
* @throws ConfigurationException
|
||||
* @throws PathNotFoundException
|
||||
* @throws NotSupportedException
|
||||
*/
|
||||
public function installDependencies(?AuthenticationInterface $authentication=null): array
|
||||
{
|
||||
if(Resolver::resolveScope() !== Scopes::SYSTEM)
|
||||
{
|
||||
throw new OperationException('Unable to install dependencies, you must be running as root');
|
||||
}
|
||||
|
||||
$installed_packages = [];
|
||||
$dependencies = $this->project_configuration->getBuild()->getDependencies();
|
||||
$package_manager = new PackageManager();
|
||||
|
||||
foreach($this->project_configuration->getBuild()->getBuildConfigurations() as $configuration)
|
||||
{
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$dependencies = array_merge(
|
||||
$dependencies,
|
||||
$this->project_configuration->getBuild()->getBuildConfiguration($configuration)->getDependencies()
|
||||
);
|
||||
}
|
||||
|
||||
foreach($dependencies as $dependency)
|
||||
{
|
||||
if($dependency->getSource() === null)
|
||||
{
|
||||
Console::outVerbose('Skipping dependency \'' . $dependency->getName() . '\' because there is no source available');
|
||||
}
|
||||
elseif($package_manager->getPackageLock()->entryExists($dependency->getName(), $dependency->getVersion()))
|
||||
{
|
||||
Console::outVerbose('Skipping dependency \'' . $dependency->getName() . '\' because it is already installed');
|
||||
}
|
||||
else
|
||||
{
|
||||
$installed_packages[] = $package_manager->install(RemotePackageInput::fromString($dependency->getSource()), $authentication);
|
||||
}
|
||||
}
|
||||
|
||||
return $installed_packages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of file extensions for the components that are part of this project
|
||||
*
|
||||
|
@ -549,6 +602,7 @@
|
|||
|
||||
foreach($composer_json->getAutoload()?->getFiles() as $path)
|
||||
{
|
||||
/** @noinspection SlowArrayOperationsInLoopInspection */
|
||||
$required_files = array_merge($required_files, self::copyContents($project_path, $project_src, $path));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue