Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Command sylius:theme:assets:install --symlink --relative sometimes remove origin files #79

Open
ajgarlag opened this issue Dec 16, 2020 · 8 comments

Comments

@ajgarlag
Copy link

ajgarlag commented Dec 16, 2020

Problem

Command sylius:theme:assets:install --symlink --relative removes some origin files when executed after executing the standard assets:install --symlink --relative command.

I think the problem is originated when $target is a symlink to $origin at:

$this->filesystem->remove($target);

Not sure how to fix.

Reproducer

#!/bin/bash
composer create-project symfony/website-skeleton foobar ^4
cd foobar
sed -i 's/assets:install/assets:install --symlink --relative/g' composer.json
sed -i 's/"allow-contrib": false/"allow-contrib": true/g' composer.json
composer require friendsofsymfony/jsrouting-bundle
composer require sylius/theme-bundle
bin/console sylius:theme:assets:install --symlink --relative

Output

user@host:/tmp$ composer create-project symfony/website-skeleton foobar ^4
Creating a "symfony/website-skeleton" project at "./foobar"
Installing symfony/website-skeleton (v4.4.99)
  - Installing symfony/website-skeleton (v4.4.99): Extracting archive
Created project in /tmp/foobar
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking symfony/flex (v1.11.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing symfony/flex (v1.11.0): Extracting archive

Symfony operations: 1 recipe (3e5a687e9de0045b7783045f10652945)
  - Configuring symfony/flex (>=1.0): From github.com/symfony/recipes:master
Loading composer repositories with package information
Updating dependencies
Restricting packages listed in "symfony/symfony" to "4.4.*"
Lock file operations: 105 installs, 0 updates, 0 removals
  - Locking composer/package-versions-deprecated (1.11.99.1)
  - Locking doctrine/annotations (1.11.1)
  - Locking doctrine/cache (1.10.2)
  - Locking doctrine/collections (1.6.7)
  - Locking doctrine/common (3.1.0)
  - Locking doctrine/dbal (2.12.1)
  - Locking doctrine/doctrine-bundle (2.2.2)
  - Locking doctrine/doctrine-migrations-bundle (3.0.1)
  - Locking doctrine/event-manager (1.1.1)
  - Locking doctrine/inflector (2.0.3)
  - Locking doctrine/instantiator (1.4.0)
  - Locking doctrine/lexer (1.2.1)
  - Locking doctrine/migrations (3.0.1)
  - Locking doctrine/orm (2.8.1)
  - Locking doctrine/persistence (2.1.0)
  - Locking doctrine/sql-formatter (1.1.1)
  - Locking egulias/email-validator (2.1.24)
  - Locking laminas/laminas-code (3.5.1)
  - Locking laminas/laminas-eventmanager (3.3.0)
  - Locking laminas/laminas-zendframework-bridge (1.1.1)
  - Locking monolog/monolog (1.26.0)
  - Locking nikic/php-parser (v4.10.3)
  - Locking ocramius/proxy-manager (2.10.0)
  - Locking phpdocumentor/reflection-common (2.2.0)
  - Locking phpdocumentor/reflection-docblock (5.2.2)
  - Locking phpdocumentor/type-resolver (1.4.0)
  - Locking psr/cache (1.0.1)
  - Locking psr/container (1.0.0)
  - Locking psr/link (1.0.0)
  - Locking psr/log (1.1.3)
  - Locking sensio/framework-extra-bundle (v5.6.1)
  - Locking symfony/asset (v4.4.17)
  - Locking symfony/browser-kit (v4.4.17)
  - Locking symfony/cache (v4.4.17)
  - Locking symfony/cache-contracts (v2.2.0)
  - Locking symfony/config (v4.4.17)
  - Locking symfony/console (v4.4.17)
  - Locking symfony/css-selector (v4.4.17)
  - Locking symfony/debug (v4.4.17)
  - Locking symfony/debug-bundle (v4.4.17)
  - Locking symfony/debug-pack (v1.0.9)
  - Locking symfony/dependency-injection (v4.4.17)
  - Locking symfony/deprecation-contracts (v2.2.0)
  - Locking symfony/doctrine-bridge (v4.4.17)
  - Locking symfony/dom-crawler (v4.4.17)
  - Locking symfony/dotenv (v4.4.17)
  - Locking symfony/error-handler (v4.4.17)
  - Locking symfony/event-dispatcher (v4.4.17)
  - Locking symfony/event-dispatcher-contracts (v1.1.9)
  - Locking symfony/expression-language (v4.4.17)
  - Locking symfony/filesystem (v4.4.17)
  - Locking symfony/finder (v4.4.17)
  - Locking symfony/form (v4.4.17)
  - Locking symfony/framework-bundle (v4.4.17)
  - Locking symfony/http-client (v4.4.17)
  - Locking symfony/http-client-contracts (v2.3.1)
  - Locking symfony/http-foundation (v4.4.17)
  - Locking symfony/http-kernel (v4.4.17)
  - Locking symfony/inflector (v4.4.17)
  - Locking symfony/intl (v4.4.17)
  - Locking symfony/mailer (v4.4.17)
  - Locking symfony/maker-bundle (v1.25.0)
  - Locking symfony/mime (v4.4.17)
  - Locking symfony/monolog-bridge (v4.4.17)
  - Locking symfony/monolog-bundle (v3.6.0)
  - Locking symfony/options-resolver (v4.4.17)
  - Locking symfony/orm-pack (v2.0.0)
  - Locking symfony/phpunit-bridge (v5.2.0)
  - Locking symfony/polyfill-intl-icu (v1.20.0)
  - Locking symfony/polyfill-intl-idn (v1.20.0)
  - Locking symfony/polyfill-intl-normalizer (v1.20.0)
  - Locking symfony/polyfill-mbstring (v1.20.0)
  - Locking symfony/polyfill-php72 (v1.20.0)
  - Locking symfony/polyfill-php73 (v1.20.0)
  - Locking symfony/polyfill-php80 (v1.20.0)
  - Locking symfony/process (v4.4.17)
  - Locking symfony/profiler-pack (v1.0.5)
  - Locking symfony/property-access (v4.4.17)
  - Locking symfony/property-info (v4.4.17)
  - Locking symfony/routing (v4.4.17)
  - Locking symfony/security-bundle (v4.4.17)
  - Locking symfony/security-core (v4.4.17)
  - Locking symfony/security-csrf (v4.4.17)
  - Locking symfony/security-guard (v4.4.17)
  - Locking symfony/security-http (v4.4.17)
  - Locking symfony/serializer (v4.4.17)
  - Locking symfony/serializer-pack (v1.0.4)
  - Locking symfony/service-contracts (v2.2.0)
  - Locking symfony/stopwatch (v4.4.17)
  - Locking symfony/test-pack (v1.0.7)
  - Locking symfony/translation (v4.4.17)
  - Locking symfony/translation-contracts (v2.3.0)
  - Locking symfony/twig-bridge (v4.4.17)
  - Locking symfony/twig-bundle (v4.4.17)
  - Locking symfony/twig-pack (v1.0.1)
  - Locking symfony/validator (v4.4.17)
  - Locking symfony/var-dumper (v4.4.17)
  - Locking symfony/var-exporter (v4.4.17)
  - Locking symfony/web-link (v4.4.17)
  - Locking symfony/web-profiler-bundle (v4.4.17)
  - Locking symfony/yaml (v4.4.17)
  - Locking twig/extra-bundle (v3.1.1)
  - Locking twig/twig (v3.1.1)
  - Locking webimpress/safe-writer (2.1.0)
  - Locking webmozart/assert (1.9.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 105 installs, 0 updates, 0 removals
  - Installing composer/package-versions-deprecated (1.11.99.1): Extracting archive
  - Installing doctrine/cache (1.10.2): Extracting archive
  - Installing doctrine/collections (1.6.7): Extracting archive
  - Installing doctrine/event-manager (1.1.1): Extracting archive
  - Installing doctrine/lexer (1.2.1): Extracting archive
  - Installing doctrine/annotations (1.11.1): Extracting archive
  - Installing doctrine/persistence (2.1.0): Extracting archive
  - Installing doctrine/common (3.1.0): Extracting archive
  - Installing doctrine/instantiator (1.4.0): Extracting archive
  - Installing psr/container (1.0.0): Extracting archive
  - Installing symfony/service-contracts (v2.2.0): Extracting archive
  - Installing symfony/stopwatch (v4.4.17): Extracting archive
  - Installing symfony/polyfill-php80 (v1.20.0): Extracting archive
  - Installing symfony/polyfill-php73 (v1.20.0): Extracting archive
  - Installing symfony/polyfill-mbstring (v1.20.0): Extracting archive
  - Installing symfony/console (v4.4.17): Extracting archive
  - Installing psr/log (1.1.3): Extracting archive
  - Installing webimpress/safe-writer (2.1.0): Extracting archive
  - Installing laminas/laminas-zendframework-bridge (1.1.1): Extracting archive
  - Installing laminas/laminas-eventmanager (3.3.0): Extracting archive
  - Installing laminas/laminas-code (3.5.1): Extracting archive
  - Installing ocramius/proxy-manager (2.10.0): Extracting archive
  - Installing doctrine/dbal (2.12.1): Extracting archive
  - Installing doctrine/migrations (3.0.1): Extracting archive
  - Installing doctrine/sql-formatter (1.1.1): Extracting archive
  - Installing phpdocumentor/reflection-common (2.2.0): Extracting archive
  - Installing phpdocumentor/type-resolver (1.4.0): Extracting archive
  - Installing symfony/polyfill-php72 (v1.20.0): Extracting archive
  - Installing symfony/polyfill-intl-normalizer (v1.20.0): Extracting archive
  - Installing symfony/polyfill-intl-idn (v1.20.0): Extracting archive
  - Installing symfony/mime (v4.4.17): Extracting archive
  - Installing symfony/http-foundation (v4.4.17): Extracting archive
  - Installing symfony/http-client-contracts (v2.3.1): Extracting archive
  - Installing symfony/event-dispatcher-contracts (v1.1.9): Extracting archive
  - Installing symfony/event-dispatcher (v4.4.17): Extracting archive
  - Installing symfony/var-dumper (v4.4.17): Extracting archive
  - Installing symfony/debug (v4.4.17): Extracting archive
  - Installing symfony/error-handler (v4.4.17): Extracting archive
  - Installing symfony/http-kernel (v4.4.17): Extracting archive
  - Installing symfony/routing (v4.4.17): Extracting archive
  - Installing symfony/finder (v4.4.17): Extracting archive
  - Installing symfony/filesystem (v4.4.17): Extracting archive
  - Installing symfony/dependency-injection (v4.4.17): Extracting archive
  - Installing symfony/config (v4.4.17): Extracting archive
  - Installing symfony/var-exporter (v4.4.17): Extracting archive
  - Installing psr/cache (1.0.1): Extracting archive
  - Installing symfony/cache-contracts (v2.2.0): Extracting archive
  - Installing symfony/cache (v4.4.17): Extracting archive
  - Installing symfony/framework-bundle (v4.4.17): Extracting archive
  - Installing sensio/framework-extra-bundle (v5.6.1): Extracting archive
  - Installing symfony/asset (v4.4.17): Extracting archive
  - Installing twig/twig (v3.1.1): Extracting archive
  - Installing symfony/translation-contracts (v2.3.0): Extracting archive
  - Installing symfony/twig-bridge (v4.4.17): Extracting archive
  - Installing symfony/twig-bundle (v4.4.17): Extracting archive
  - Installing symfony/web-profiler-bundle (v4.4.17): Extracting archive
  - Installing symfony/profiler-pack (v1.0.5): Extracting archive
  - Installing monolog/monolog (1.26.0): Extracting archive
  - Installing symfony/monolog-bridge (v4.4.17): Extracting archive
  - Installing symfony/monolog-bundle (v3.6.0): Extracting archive
  - Installing symfony/debug-bundle (v4.4.17): Extracting archive
  - Installing symfony/debug-pack (v1.0.9): Extracting archive
  - Installing symfony/doctrine-bridge (v4.4.17): Extracting archive
  - Installing symfony/dom-crawler (v4.4.17): Extracting archive
  - Installing symfony/dotenv (v4.4.17): Extracting archive
  - Installing symfony/expression-language (v4.4.17): Extracting archive
  - Installing symfony/inflector (v4.4.17): Extracting archive
  - Installing symfony/property-access (v4.4.17): Extracting archive
  - Installing symfony/options-resolver (v4.4.17): Extracting archive
  - Installing symfony/intl (v4.4.17): Extracting archive
  - Installing symfony/polyfill-intl-icu (v1.20.0): Extracting archive
  - Installing symfony/form (v4.4.17): Extracting archive
  - Installing symfony/http-client (v4.4.17): Extracting archive
  - Installing egulias/email-validator (2.1.24): Extracting archive
  - Installing symfony/mailer (v4.4.17): Extracting archive
  - Installing symfony/deprecation-contracts (v2.2.0): Extracting archive
  - Installing nikic/php-parser (v4.10.3): Extracting archive
  - Installing doctrine/inflector (2.0.3): Extracting archive
  - Installing symfony/maker-bundle (v1.25.0): Extracting archive
  - Installing doctrine/orm (2.8.1): Extracting archive
  - Installing doctrine/doctrine-bundle (2.2.2): Extracting archive
  - Installing doctrine/doctrine-migrations-bundle (3.0.1): Extracting archive
  - Installing symfony/orm-pack (v2.0.0): Extracting archive
  - Installing symfony/process (v4.4.17): Extracting archive
  - Installing symfony/security-core (v4.4.17): Extracting archive
  - Installing symfony/security-http (v4.4.17): Extracting archive
  - Installing symfony/security-guard (v4.4.17): Extracting archive
  - Installing symfony/security-csrf (v4.4.17): Extracting archive
  - Installing symfony/security-bundle (v4.4.17): Extracting archive
  - Installing symfony/serializer (v4.4.17): Extracting archive
  - Installing symfony/property-info (v4.4.17): Extracting archive
  - Installing webmozart/assert (1.9.1): Extracting archive
  - Installing phpdocumentor/reflection-docblock (5.2.2): Extracting archive
  - Installing symfony/serializer-pack (v1.0.4): Extracting archive
  - Installing symfony/phpunit-bridge (v5.2.0): Extracting archive
  - Installing symfony/css-selector (v4.4.17): Extracting archive
  - Installing symfony/browser-kit (v4.4.17): Extracting archive
  - Installing symfony/test-pack (v1.0.7): Extracting archive
  - Installing symfony/translation (v4.4.17): Extracting archive
  - Installing twig/extra-bundle (v3.1.1): Extracting archive
  - Installing symfony/twig-pack (v1.0.1): Extracting archive
  - Installing symfony/validator (v4.4.17): Extracting archive
  - Installing psr/link (1.0.0): Extracting archive
  - Installing symfony/web-link (v4.4.17): Extracting archive
  - Installing symfony/yaml (v4.4.17): Extracting archive
Generating autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
91 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Symfony operations: 18 recipes (3e5a687e9de0045b7783045f10652945)
  - Configuring symfony/framework-bundle (>=4.4): From github.com/symfony/recipes:master
  - Configuring doctrine/annotations (>=1.0): From github.com/symfony/recipes:master
  - Configuring symfony/console (>=4.4): From github.com/symfony/recipes:master
  - Configuring symfony/routing (>=4.2): From github.com/symfony/recipes:master
  - Configuring sensio/framework-extra-bundle (>=5.2): From github.com/symfony/recipes:master
  - Configuring symfony/twig-bundle (>=4.4): From github.com/symfony/recipes:master
  - Configuring symfony/web-profiler-bundle (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/monolog-bundle (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/debug-bundle (>=4.1): From github.com/symfony/recipes:master
  - Configuring symfony/mailer (>=4.3): From github.com/symfony/recipes:master
  - Configuring symfony/maker-bundle (>=1.0): From github.com/symfony/recipes:master
  - Configuring doctrine/doctrine-bundle (>=2.0): From github.com/symfony/recipes:master
  - Configuring doctrine/doctrine-migrations-bundle (>=2.2): From github.com/symfony/recipes:master
  - Configuring symfony/security-bundle (>=4.4): From github.com/symfony/recipes:master
  - Configuring symfony/phpunit-bridge (>=4.3): From github.com/symfony/recipes:master
  - Configuring symfony/translation (>=3.3): From github.com/symfony/recipes:master
  - Configuring twig/extra-bundle (>=v3.1.1): From auto-generated recipe
  - Configuring symfony/validator (>=4.3): From github.com/symfony/recipes:master
Executing script cache:clear [OK]
Executing script assets:install public [OK]

Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.

Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.

              
 What's next? 
              

  * Run your application:
    1. Go to the project directory
    2. Create your code repository with the git init command
    3. Download the Symfony CLI at https://symfony.com/download to install a development web server

  * Read the documentation at https://symfony.com/doc

              
 What's next? 
              

  * You're ready to send emails.

  * If you want to send emails via a supported email provider, install
    the corresponding bridge.
    For instance, composer require mailgun-mailer for Mailgun.

  * If you want to send emails asynchronously:

    1. Install the messenger component by running composer require messenger;
    2. Add 'Symfony\Component\Mailer\Messenger\SendEmailMessage': amqp to the
       config/packages/messenger.yaml file under framework.messenger.routing
       and replace amqp with your transport name of choice.

  * Read the documentation at https://symfony.com/doc/master/mailer.html

                        
 Database Configuration 
                        

  * Modify your DATABASE_URL config in .env

  * Configure the driver (mysql) and
    server_version (5.7) in config/packages/doctrine.yaml

              
 How to test? 
              

  * Write test cases in the tests/ folder
  * Run php bin/phpunit
user@host:/tmp$ cd foobar
user@host:/tmp/foobar$ sed -i 's/assets:install/assets:install --symlink --relative/g' composer.json
user@host:/tmp/foobar$ sed -i 's/"allow-contrib": false/"allow-contrib": true/g' composer.json
user@host:/tmp/foobar$ composer require friendsofsymfony/jsrouting-bundle
Using version ^2.7 for friendsofsymfony/jsrouting-bundle
./composer.json has been updated
Running composer update friendsofsymfony/jsrouting-bundle
Loading composer repositories with package information
Updating dependencies
Lock file operations: 2 installs, 0 updates, 0 removals
  - Locking friendsofsymfony/jsrouting-bundle (2.7.0)
  - Locking willdurand/jsonp-callback-validator (v1.1.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing willdurand/jsonp-callback-validator (v1.1.0): Extracting archive
  - Installing friendsofsymfony/jsrouting-bundle (2.7.0): Extracting archive
Generating autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
85 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Symfony operations: 1 recipe (c6f400a6717b397a7ee90754932a7e05)
  - Configuring friendsofsymfony/jsrouting-bundle (>=2.3): From github.com/symfony/recipes-contrib:master
Executing script cache:clear [OK]
Executing script assets:install --symlink --relative public [OK]

Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.

Nothing to unpack
user@host:/tmp/foobar$ composer require sylius/theme-bundle
Using version ^2.1 for sylius/theme-bundle
./composer.json has been updated
Running composer update sylius/theme-bundle
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking sylius/theme-bundle (v2.1.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing sylius/theme-bundle (v2.1.0): Extracting archive
Generating autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
85 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

Symfony operations: 1 recipe (1679ac13f95a548876bd279532f14a8d)
  - Configuring sylius/theme-bundle (>=v2.1.0): From auto-generated recipe
Executing script cache:clear [OK]
Executing script assets:install --symlink --relative public [OK]

Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.

Nothing to unpack
user@host:/tmp/foobar$ bin/console sylius:theme:assets:install --symlink --relative
Trying to install assets as symbolic links.

In Filesystem.php line 45:
                                                                                                                                    
  Failed to copy "/tmp/foobar/vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.js" because file does not exist.  
                                                                                                                                    

sylius:theme:assets:install [--symlink] [--relative] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] <command> [<target>]
@mbabker
Copy link
Contributor

mbabker commented Mar 18, 2021

I made some time to look at stuff today, and honestly, I'm a bit confused by this bundle's asset installer, especially when comparing it to the assets:install command provided by Symfony.

The FrameworkBundle's command installs by either symlinking or copying (based on the provided options) the bundle's public directory. The AssetsInstaller class here looks to be iterating over each file individually in the bundle and theme public directories and trying to perform the symlink/copy operation on those. Is there a particular reason for the handle every file individually approach used here?

@WavaExchange
Copy link

I think I have a quite same problem.

When I execute
php bin/console sylius:theme:assets:install --symlink

2021-05-10 15_16_33-DEV - 94 23 49 202 - Connexion Bureau à distance

As a matter of fact, the file was there before the command. And after, the file has been modified as a symbolic link to himself.
./public/bundles/apiplatform/es6-promise/es6-promise.auto.min.js -> ./public/bundles/apiplatform/es6-promise/es6-promise.auto.min.js

@WavaExchange
Copy link

The assets are copied twice:

  1. in the public folder (the symlinks are ok)
  2. in the theme folder (the symlinks overwrite the origin files and create a circularity)

image

@scrummer
Copy link

scrummer commented Sep 3, 2021

We also ran into this problem - specifically with the friendsofsymfony/jsrouting-bundle...

@imajim
Copy link

imajim commented May 17, 2022

same problem here after composer update

Executing script assets:install public [KO]
 [KO]
Script assets:install %PUBLIC_DIR% returned with error code 1
!!  
!!   Installing assets as hard copies.
!!  
!!   --- ------------------------ 
!!        Bundle                   Method / Error                                                                                                                                                                                                                                                                                                  
!!   --- ------------------------ 
!!    ✘   ApiPlatformBundle        Failed to create "symbolic" link from "/var/www/vhosts/xxxxx/httpdocs/vendor/api-platform/core/src/Bridge/Symfony/Bundle/Resources/public/es6-promise/es6-promise.auto.min.js" to "public/bundles/apiplatform/es6-promise/es6-promise.auto.min.js": symlink(): No such file or directory  
!!    ✔   BabDevPagerfantaBundle   copy                                                                                                                                                                                                                                                                                                            
!!    ✔   FOSCKEditorBundle        copy                                                                                                                                                                                                                                                                                                            
!!   --- ------------------------ - 
                                                                          
!!   [ERROR] Some errors occurred while installing assets.                          
!!                                                                                  
!!  
Script @auto-scripts was called via post-update-cmd

@fonpacific
Copy link

Same problem here with ckeditor-bundle (friendsofsymfony/ckeditor-bundle/src/Resources/public/adapters/jquery.js is removed) and pagerfanta-bundle (babdev/pagerfanta-bundle/public/css/pagerfanta.css is removed)

@langert
Copy link

langert commented Aug 31, 2023

same problem here with pimcore (/vendor/pimcore/admin-ui-classic-bundle/public/assets/imageEditor.js is removed)

@scrummer
Copy link

scrummer commented Sep 1, 2023

FYI for all who run into this kind of problem: We solved the issue by just not using the command provided by sylius. We implement 2 different ways in our projects which basically do the same as the command from sylius. Depending on the project we choose version 1 or 2.

Version 1

symlink via composer.json scripts

Pro: simple to set up
Con: You have to add each theme manually - can be easily forgotten if you create a new one

"scripts": {
    "post-install-cmd": [
        "@theme-scripts"
    ],
    "post-update-cmd": [
        "@theme-scripts"
    ],
    "theme-scripts": [
        "rm -rf web/_themes",
        "mkdir -p public/_themes/dachcom-digital/default && ln -s ../../../bundles public/_themes/dachcom-digital/default/bundles",
        "mkdir -p public/_themes/dachcom-digital/XY && ln -s ../../../bundles public/_themes/dachcom-digital/XY/bundles"
    ]
}

Version 2

Via EventListener - hooks into the assets:install command from symfony and install sylius assets the same way (hard copy vs symlinking)

Pro: Highly dynamic; copies all assets the same way you executed the default (symfony) assets:install command and you do not need to pay attention when adding new themes
Con: More setup

Expand Code
<?php
declare(strict_types=1);

namespace App\EventListener\Console;

use Sylius\Bundle\ThemeBundle\Repository\ThemeRepositoryInterface;
use Symfony\Bundle\FrameworkBundle\Command\AssetsInstallCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleTerminateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Finder\Finder;

class CommandExecutionListener implements EventSubscriberInterface
{
    public function __construct(
        private string $projectDir,
        private Filesystem $filesystem,
        private ThemeRepositoryInterface $themeRepository
    ) { }

    public static function getSubscribedEvents(): array
    {
        return [
            ConsoleEvents::TERMINATE => 'installThemeAssets'
        ];
    }

    public function installThemeAssets(ConsoleTerminateEvent $event): void
    {
        $command = $event->getCommand();
        $input = $event->getInput();
        $output = $event->getOutput();
        $bundlesDir = $this->projectDir . '/public/bundles';
        $destDirTpl = $this->projectDir . '/public/_themes/%s/default/bundles';

        if ($command::class !== AssetsInstallCommand::class) {
            return;
        }

        if ($event->getExitCode() !== Command::SUCCESS) {
            $output->writeln('<info>[THEME] Skipping Sylius asset installation due to failure of "assets:install" command.</info>');
        }

        $output->writeln('<info>[THEME] Installing assets for SyliusThemeBundle...</info>');
        $symlink = $input->getOption('symlink');

        foreach ($this->themeRepository->findAll() as $theme) {
            $pathParts = explode('/', $theme->getPath());
            $themeDirName = $pathParts[array_key_last($pathParts)];
            $destDir = sprintf($destDirTpl, $themeDirName);

            if ($symlink) {
                $this->symlink($bundlesDir, $destDir, true);
            } else {
                $this->hardCopy($bundlesDir, $destDir);
            }

            $output->writeln(sprintf('<info>[THEME] Installed assets for theme "%s" as %s.</info>', $theme->getName(), $symlink ? 'symlink' : 'hard copy'));
        }
    }

    /**
     * @throws IOException
     */
    private function symlink(string $originDir, string $targetDir, bool $relative = false): void
    {
        if ($relative) {
            $this->filesystem->mkdir(\dirname($targetDir));
            $originDir = $this->filesystem->makePathRelative($originDir, realpath(\dirname($targetDir)));
        }
        $this->filesystem->symlink($originDir, $targetDir);
        if (!file_exists($targetDir)) {
            throw new IOException(sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), 0, null, $targetDir);
        }
    }

    private function hardCopy(string $originDir, string $targetDir): void
    {
        $this->filesystem->mkdir($targetDir, 0777);
        $this->filesystem->mirror($originDir, $targetDir, Finder::create()->ignoreDotFiles(false)->in($originDir));
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants