Skip to content

Commit c24906f

Browse files
feature #51351 [AssetMapper] Add command to download missing downloaded packages (jmsche)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [AssetMapper] Add command to download missing downloaded packages | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | N/A | License | MIT | Doc PR | None yet Hi, this PR adds a `importmap:install` command to download all packages marked as downloaded in the `impormap.php` file that are missing on filesystem. To quote `@weaverryan`: > the intention is to allow devs to not commit `assets/vendor/`, which means that this is a command you’ll run during deploy and your teammates will run Commits ------- a82a429 [AssetMapper] Add command to download missing downloaded packages
2 parents ccd6a30 + a82a429 commit c24906f

File tree

8 files changed

+142
-1
lines changed

8 files changed

+142
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/asset_mapper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\AssetMapper\Command\AssetMapperCompileCommand;
2020
use Symfony\Component\AssetMapper\Command\DebugAssetMapperCommand;
2121
use Symfony\Component\AssetMapper\Command\ImportMapExportCommand;
22+
use Symfony\Component\AssetMapper\Command\ImportMapInstallCommand;
2223
use Symfony\Component\AssetMapper\Command\ImportMapRemoveCommand;
2324
use Symfony\Component\AssetMapper\Command\ImportMapRequireCommand;
2425
use Symfony\Component\AssetMapper\Command\ImportMapUpdateCommand;
@@ -202,5 +203,9 @@
202203
->set('asset_mapper.importmap.command.export', ImportMapExportCommand::class)
203204
->args([service('asset_mapper.importmap.manager')])
204205
->tag('console.command')
206+
207+
->set('asset_mapper.importmap.command.install', ImportMapInstallCommand::class)
208+
->args([service('asset_mapper.importmap.manager')])
209+
->tag('console.command')
205210
;
206211
};

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"doctrine/persistence": "^1.3|^2|^3",
3838
"seld/jsonlint": "^1.10",
3939
"symfony/asset": "^5.4|^6.0|^7.0",
40-
"symfony/asset-mapper": "^6.3|^7.0",
40+
"symfony/asset-mapper": "^6.4|^7.0",
4141
"symfony/browser-kit": "^5.4|^6.0|^7.0",
4242
"symfony/console": "^5.4.9|^6.0.9|^7.0",
4343
"symfony/clock": "^6.2|^7.0",
@@ -79,6 +79,7 @@
7979
"phpdocumentor/reflection-docblock": "<3.2.2",
8080
"phpdocumentor/type-resolver": "<1.4.0",
8181
"symfony/asset": "<5.4",
82+
"symfony/asset-mapper": "<6.4",
8283
"symfony/clock": "<6.3",
8384
"symfony/console": "<5.4",
8485
"symfony/dotenv": "<5.4",

src/Symfony/Component/AssetMapper/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Mark the component as non experimental
8+
* Add a `importmap:install` command to download all missing downloaded packages
89

910
6.3
1011
---
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\AssetMapper\Command;
13+
14+
use Symfony\Component\AssetMapper\ImportMap\ImportMapManager;
15+
use Symfony\Component\Console\Attribute\AsCommand;
16+
use Symfony\Component\Console\Command\Command;
17+
use Symfony\Component\Console\Input\InputInterface;
18+
use Symfony\Component\Console\Output\OutputInterface;
19+
use Symfony\Component\Console\Style\SymfonyStyle;
20+
21+
/**
22+
* Downloads all assets that should be downloaded.
23+
*
24+
* @author Jonathan Scheiber <contact@jmsche.fr>
25+
*/
26+
#[AsCommand(name: 'importmap:install', description: 'Downloads all assets that should be downloaded.')]
27+
final class ImportMapInstallCommand extends Command
28+
{
29+
public function __construct(
30+
private readonly ImportMapManager $importMapManager,
31+
) {
32+
parent::__construct();
33+
}
34+
35+
protected function execute(InputInterface $input, OutputInterface $output): int
36+
{
37+
$io = new SymfonyStyle($input, $output);
38+
39+
$downloadedPackages = $this->importMapManager->downloadMissingPackages();
40+
$io->success(sprintf('Downloaded %d assets.', \count($downloadedPackages)));
41+
42+
return Command::SUCCESS;
43+
}
44+
}

src/Symfony/Component/AssetMapper/ImportMap/ImportMapManager.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\AssetMapper\AssetDependency;
1515
use Symfony\Component\AssetMapper\AssetMapperInterface;
16+
use Symfony\Component\AssetMapper\Exception\RuntimeException;
1617
use Symfony\Component\AssetMapper\ImportMap\Resolver\PackageResolverInterface;
1718
use Symfony\Component\AssetMapper\Path\PublicAssetsPathResolverInterface;
1819
use Symfony\Component\VarExporter\VarExporter;
@@ -108,6 +109,36 @@ public function update(): array
108109
return $this->updateImportMapConfig(true, [], []);
109110
}
110111

112+
/**
113+
* Downloads all missing downloaded packages.
114+
*
115+
* @return ImportMapEntry[] The downloaded packages
116+
*/
117+
public function downloadMissingPackages(): array
118+
{
119+
$entries = $this->loadImportMapEntries();
120+
$packagesToDownload = [];
121+
122+
foreach ($entries as $entry) {
123+
if (!$entry->isDownloaded || $this->assetMapper->getAsset($entry->path)) {
124+
continue;
125+
}
126+
127+
$parts = self::parsePackageName($entry->url);
128+
129+
$packagesToDownload[] = new PackageRequireOptions(
130+
$parts['package'],
131+
$parts['version'] ?? throw new RuntimeException(sprintf('Cannot get a version for the "%s" package.', $parts['package'])),
132+
true,
133+
$entry->preload,
134+
$parts['alias'] ?? $parts['package'],
135+
isset($parts['registry']) && $parts['registry'] ? $parts['registry'] : null,
136+
);
137+
}
138+
139+
return $this->require($packagesToDownload);
140+
}
141+
111142
/**
112143
* @internal
113144
*/

src/Symfony/Component/AssetMapper/Tests/ImportMap/ImportMapManagerTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,43 @@ public function testUpdate()
373373
$this->assertSame('contents of cowsay.js', $actualContents);
374374
}
375375

376+
public function testDownloadMissingPackages()
377+
{
378+
$rootDir = __DIR__.'/../fixtures/download';
379+
$manager = $this->createImportMapManager(['assets' => ''], $rootDir);
380+
381+
$this->packageResolver->expects($this->once())
382+
->method('resolvePackages')
383+
->willReturn([
384+
self::resolvedPackage('@hotwired/stimulus', 'https://cdn.jsdelivr.net/npm/stimulus@3.2.1/+esm', true, content: 'contents of stimulus.js'),
385+
])
386+
;
387+
388+
$downloadedPackages = $manager->downloadMissingPackages();
389+
$actualImportMap = require $rootDir.'/importmap.php';
390+
$expectedImportMap = [
391+
'@hotwired/stimulus' => [
392+
'downloaded_to' => 'vendor/@hotwired/stimulus.js',
393+
'url' => 'https://cdn.jsdelivr.net/npm/stimulus@3.2.1/+esm',
394+
],
395+
'lodash' => [
396+
'downloaded_to' => 'vendor/lodash.js',
397+
'url' => 'https://ga.jspm.io/npm:lodash@4.17.21/lodash.js',
398+
],
399+
];
400+
$this->assertEquals($expectedImportMap, $actualImportMap);
401+
402+
$expectedDownloadedFiles = [
403+
'assets/vendor/@hotwired/stimulus.js' => 'contents of stimulus.js',
404+
];
405+
foreach ($expectedDownloadedFiles as $file => $expectedContents) {
406+
$this->assertFileExists($rootDir.'/'.$file);
407+
$actualContents = file_get_contents($rootDir.'/'.$file);
408+
$this->assertSame($expectedContents, $actualContents);
409+
unlink($rootDir.'/'.$file);
410+
}
411+
}
412+
376413
/**
377414
* @dataProvider getPackageNameTests
378415
*/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log('fake downloaded lodash.js');
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
return [
13+
'@hotwired/stimulus' => [
14+
'downloaded_to' => 'vendor/@hotwired/stimulus.js',
15+
'url' => 'https://cdn.jsdelivr.net/npm/stimulus@3.2.1/+esm',
16+
],
17+
'lodash' => [
18+
'downloaded_to' => 'vendor/lodash.js',
19+
'url' => 'https://ga.jspm.io/npm:lodash@4.17.21/lodash.js',
20+
],
21+
];

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy