diff --git a/composer.json b/composer.json index e0374a1..5693afe 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "php": ">=8.2", "ext-ctype": "*", "ext-iconv": "*", + "illuminate/collections": "^11.0", "symfony/console": "7.0.*", "symfony/dotenv": "7.0.*", "symfony/flex": "^2", diff --git a/composer.lock b/composer.lock index 9dafa0b..bfc776c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,203 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "46c9b05e72deefb09397e0367bf62db6", + "content-hash": "db9bab7397cd49e2e1fff83ef6f8d624", "packages": [ + { + "name": "illuminate/collections", + "version": "v11.0.5", + "source": { + "type": "git", + "url": "https://github.com/illuminate/collections.git", + "reference": "1a81a4ba053807ee5602e0dd27e9d8f5e779fc06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/collections/zipball/1a81a4ba053807ee5602e0dd27e9d8f5e779fc06", + "reference": "1a81a4ba053807ee5602e0dd27e9d8f5e779fc06", + "shasum": "" + }, + "require": { + "illuminate/conditionable": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/macroable": "^11.0", + "php": "^8.2" + }, + "suggest": { + "symfony/var-dumper": "Required to use the dump method (^7.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "files": [ + "helpers.php" + ], + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Collections package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-03-12T18:40:10+00:00" + }, + { + "name": "illuminate/conditionable", + "version": "v11.0.5", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "e4c5c9b855c60c7bb16ce92ca9372684448cce47" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/e4c5c9b855c60c7bb16ce92ca9372684448cce47", + "reference": "e4c5c9b855c60c7bb16ce92ca9372684448cce47", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-02-07T10:39:14+00:00" + }, + { + "name": "illuminate/contracts", + "version": "v11.0.5", + "source": { + "type": "git", + "url": "https://github.com/illuminate/contracts.git", + "reference": "fae548ad43f569fc506f40385b2e0dcf1f4eb2c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/fae548ad43f569fc506f40385b2e0dcf1f4eb2c9", + "reference": "fae548ad43f569fc506f40385b2e0dcf1f4eb2c9", + "shasum": "" + }, + "require": { + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Contracts\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Contracts package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-02-23T15:52:10+00:00" + }, + { + "name": "illuminate/macroable", + "version": "v11.0.5", + "source": { + "type": "git", + "url": "https://github.com/illuminate/macroable.git", + "reference": "e1be58f9b2af73f242dc6a9add1f376b3ec89eef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/e1be58f9b2af73f242dc6a9add1f376b3ec89eef", + "reference": "e1be58f9b2af73f242dc6a9add1f376b3ec89eef", + "shasum": "" + }, + "require": { + "php": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Macroable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-06-08T14:08:27+00:00" + }, { "name": "psr/cache", "version": "3.0.0", @@ -208,6 +403,57 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, { "name": "symfony/cache", "version": "v7.0.3", diff --git a/src/Action/DetermineProjectLanguage.php b/src/Action/DetermineProjectLanguage.php index 58e0565..be2113d 100644 --- a/src/Action/DetermineProjectLanguage.php +++ b/src/Action/DetermineProjectLanguage.php @@ -3,6 +3,7 @@ namespace App\Action; use App\Enum\ProjectLanguage; +use Illuminate\Support\Collection; use Symfony\Component\Filesystem\Filesystem; final class DetermineProjectLanguage implements DetermineProjectLanguageInterface @@ -30,4 +31,25 @@ final class DetermineProjectLanguage implements DetermineProjectLanguageInterfac return ProjectLanguage::PHP->value; } + + /** + * Return the languages used in the project. + * + * @return Collection + */ + public function getLanguages(): Collection + { + $languages = collect(); + + + if ($this->filesystem->exists($this->workingDir.'/composer.json')) { + $languages->push(ProjectLanguage::PHP); + } + + if ($this->filesystem->exists($this->workingDir.'/package.json')) { + $languages->push(ProjectLanguage::JavaScript); + } + + return $languages; + } } diff --git a/src/Console/Command/InstallCommand.php b/src/Console/Command/InstallCommand.php index 046bc52..d95cedf 100644 --- a/src/Console/Command/InstallCommand.php +++ b/src/Console/Command/InstallCommand.php @@ -12,6 +12,8 @@ use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Style\SymfonyStyle; #[AsCommand( description: 'Install the project\'s dependencies', @@ -26,10 +28,41 @@ final class InstallCommand extends AbstractCommand $workingDir = $input->getOption('working-dir'); if ($language === null) { - $language = (new DetermineProjectLanguage( + $languages = (new DetermineProjectLanguage( filesystem: $this->filesystem, workingDir: $workingDir, - ))->getLanguage(); + ))->getLanguages(); + + // TODO: if more than one language is found, prompt to select which + // language to use. For now, always return the first language, which + // is consistent with what happens before this refactor. + $language = $languages->first()->value; + + // TODO: throw an Exception if no language is found. + + // TODO: if a project uses multiple languages, ask which language to use + // instead of using a default value? + // + // Currently, PHP will always be used over JavaScript if both are in the + // same project and an override, such as `versa install -l javascript` + // needs to be used to install the JavaScript/node dependencies. + // + // This could mean that `DetermineProjectLanguage` changes to + // `DetermineProjectLanguages` and returns a Collection of languages. + // If a single language is found, it is used. If multiple languages are + // found, the prompt is used to select which language to use. + if (false && $languages->count() > 1) { + $io = new SymfonyStyle($input, $output); + + $choices = $languages + ->mapWithKeys(fn (ProjectLanguage $language): array => [$language->value => $language->name]) + ->sort(); + + $language = $io->choice( + question: 'Which language should I install', + choices: $choices->toArray(), + ); + } } assert(