Start adding better support for multiple languages

This commit is contained in:
Oliver Davies 2024-03-14 08:00:00 +00:00
parent d289a01f3a
commit 1cbb2bd1e5
4 changed files with 305 additions and 3 deletions

View file

@ -7,6 +7,7 @@
"php": ">=8.2", "php": ">=8.2",
"ext-ctype": "*", "ext-ctype": "*",
"ext-iconv": "*", "ext-iconv": "*",
"illuminate/collections": "^11.0",
"symfony/console": "7.0.*", "symfony/console": "7.0.*",
"symfony/dotenv": "7.0.*", "symfony/dotenv": "7.0.*",
"symfony/flex": "^2", "symfony/flex": "^2",

248
composer.lock generated
View file

@ -4,8 +4,203 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "46c9b05e72deefb09397e0367bf62db6", "content-hash": "db9bab7397cd49e2e1fff83ef6f8d624",
"packages": [ "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", "name": "psr/cache",
"version": "3.0.0", "version": "3.0.0",
@ -208,6 +403,57 @@
}, },
"time": "2021-07-14T16:46:02+00:00" "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", "name": "symfony/cache",
"version": "v7.0.3", "version": "v7.0.3",

View file

@ -3,6 +3,7 @@
namespace App\Action; namespace App\Action;
use App\Enum\ProjectLanguage; use App\Enum\ProjectLanguage;
use Illuminate\Support\Collection;
use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Filesystem\Filesystem;
final class DetermineProjectLanguage implements DetermineProjectLanguageInterface final class DetermineProjectLanguage implements DetermineProjectLanguageInterface
@ -30,4 +31,25 @@ final class DetermineProjectLanguage implements DetermineProjectLanguageInterfac
return ProjectLanguage::PHP->value; return ProjectLanguage::PHP->value;
} }
/**
* Return the languages used in the project.
*
* @return Collection<int, ProjectLanguage>
*/
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;
}
} }

View file

@ -12,6 +12,8 @@ use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;
#[AsCommand( #[AsCommand(
description: 'Install the project\'s dependencies', description: 'Install the project\'s dependencies',
@ -26,10 +28,41 @@ final class InstallCommand extends AbstractCommand
$workingDir = $input->getOption('working-dir'); $workingDir = $input->getOption('working-dir');
if ($language === null) { if ($language === null) {
$language = (new DetermineProjectLanguage( $languages = (new DetermineProjectLanguage(
filesystem: $this->filesystem, filesystem: $this->filesystem,
workingDir: $workingDir, 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( assert(