title: Typo3, DEB.SURY and TFS build pipeline: problem with helhum/typo3-console and PHP version
body: <p>We are currently encountering a problem with the <em>helhum/typo3-console</em> extension that we can’t figure out.</p>
  
  <p>We are trying to set up a workflow for our <em>TYPO3</em> developments using <em>Microsoft TFS</em> (<em>Azure DevOps - On premise</em>) with a build agent installed on a <em>Debian</em> machine (<em>Debian GNU/Linux 9.12 - PHP 7.0.33</em>). However, for some reasons, our system administrators decided to use <em>DEB.SURY</em> (<a href="https://deb.sury.org/" rel="nofollow noreferrer">https://deb.sury.org/</a>) to manage multiple versions of <em>PHP</em> on the same machine. The build pipeline we are working on is dedicated to a <em>TYPO3 9.5</em> installation using <em>PHP 7.3</em>.</p>
  
  <p>We noticed the following thing: because (or at least, it seems) the file "<em>./vendor/helhum/typo3-console/typo3cms</em>" contains the shebang <code>#!/usr/bin/env php</code>, it always throws an error when we run a command like <code>typo3cms install:generatepackagestates</code> because it uses the version of PHP delivered by the OS and not the one we specified. So, if we do something like so:</p>
  
  <pre><code>php7.3 typo3cms install:generatepackagestates
  </code></pre>
  
  <p>...it will throw an error because it will not use <em>PHP 7.3</em>, but <em>PHP 7.0.33</em>.</p>
  
  <p>So, we created a copy of the file, placed it at the root of our directory, and removed the first line. In that file, we also changed the line calling the <em>typo3-console.php</em> file by <code>require __DIR__ . '/vendor/helhum/typo3-console/Scripts/typo3-console.php';</code>.</p>
  
  <p>We also set the following things on the fly in our build environment:</p>
  
  <pre><code>export TYPO3_PATH_ROOT="./public"
  export TYPO3_PATH_WEB="./public"
  </code></pre>
  
  <p>Now can do something like this in our build pipeline:</p>
  
  <pre><code>php7.3 ./typo3cms-custom.php install:generatepackagestates
  </code></pre>
  
  <p>This is almost great! However, we are now encountering the following error:</p>
  
  <pre><code>PHP Warning:  require(/opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Mvc/Cli/../../../../Configuration/ComposerPackagesCommands.php): failed to open stream: No such file or directory in /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Mvc/Cli/CommandConfiguration.php on line 169
  PHP Fatal error:  require(): Failed opening required '/opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Mvc/Cli/../../../../Configuration/ComposerPackagesCommands.php' (include_path='/opt/vstsagent/_work/5/s/vendor/nimut/testing-framework/.Build/vendor/pear/http_request2:/opt/vstsagent/_work/5/s/vendor/nimut/testing-framework/.Build/vendor/pear/net_url2:.:/usr/share/php') in /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Mvc/Cli/CommandConfiguration.php on line 169
  </code></pre>
  
  <p>We spent hours trying to understand why, but, to be honest we cannot figure it out. Can someone give us a little help on this or just a little hint? It would be much appreciated. Has anyone encountered such a problem or behaviour?</p>
  
  <p>Many thanks in advance.</p>
  
  <p>Best regards,</p>
  
  <p><strong>EDIT 1</strong></p>
  
  <p>We noticed that the file <em>Configuration/ComposerPackagesCommands.php</em> that is generated through the <em>PopulateCommandConfiguration.php</em> file is not present in the vendor directory on our build machine.</p>
  
  <p>We managed to regenerate the missing file <em>Configuration/ComposerPackagesCommands.php</em>, however, we not get other errors.</p>
  
  <p>If we run <em>install:generatepackagestates</em></p>
  
  <pre><code>    [ RuntimeException ]                                            
  Cannot set an alias map as the alias loader is not registered!  
  
  Exception code: 1439228111
  
  Exception trace:
  #0 ()
  /opt/vstsagent/_work/5/s/vendor/typo3/class-alias-loader/src/ClassAliasMap.php:60
  #1 TYPO3\ClassAliasLoader\ClassAliasMap::addAliasMap()
  typo3/sysext/core/Classes/Core/ClassLoadingInformation.php:160
  #2 TYPO3\CMS\Core\Core\ClassLoadingInformation::registerTransientClassLoadingInformationForPackage()
  typo3/sysext/core/Classes/Package/PackageManager.php:636
  #3 TYPO3\CMS\Core\Package\PackageManager-&gt;registerTransientClassLoadingInformationForPackage()
  typo3/sysext/core/Classes/Package/PackageManager.php:600
  #4 TYPO3\CMS\Core\Package\PackageManager-&gt;activatePackage()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Install/PackageStatesGenerator.php:60
  #5 Helhum\Typo3Console\Install\PackageStatesGenerator-&gt;generate()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Command/Install/InstallGeneratePackageStatesCommand.php:124
  #6 Helhum\Typo3Console\Command\Install\InstallGeneratePackageStatesCommand-&gt;execute()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Command/Command.php:255
  #7 Symfony\Component\Console\Command\Command-&gt;run()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Application.php:1001
  #8 Symfony\Component\Console\Application-&gt;doRunCommand()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Mvc/Cli/Symfony/Application.php:169
  #9 Helhum\Typo3Console\Mvc\Cli\Symfony\Application-&gt;doRunCommand()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Application.php:271
  #10 Symfony\Component\Console\Application-&gt;doRun()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Application.php:147
  #11 Symfony\Component\Console\Application-&gt;run()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Core/Kernel.php:148
  #12 Helhum\Typo3Console\Core\Kernel-&gt;handle()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Scripts/typo3-console.php:16
  #13 {closure}()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Scripts/typo3-console.php:18
  #14 require()
  /opt/vstsagent/_work/5/s/typo3cms-custom.php:17
  </code></pre>
  
  <p>If we run <em>install:fixfolderstructure</em></p>
  
  <pre><code>    [ TYPO3\CMS\Install\FolderStructure\Exception\InvalidArgumentException ]  
  Root node expects absolute path as name                                   
  
  Exception code: 1366141329
  
  Exception trace:
  #0 ()
  typo3/sysext/install/Classes/FolderStructure/RootNode.php:46
  #1 TYPO3\CMS\Install\FolderStructure\RootNode-&gt;__construct()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Install/FolderStructure/ExtensionFactory.php:59
  #2 Helhum\Typo3Console\Install\FolderStructure\ExtensionFactory-&gt;getStructure()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Command/Install/InstallFixFolderStructureCommand.php:77
  #3 Helhum\Typo3Console\Command\Install\InstallFixFolderStructureCommand-&gt;execute()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Command/Command.php:255
  #4 Symfony\Component\Console\Command\Command-&gt;run()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Application.php:1001
  #5 Symfony\Component\Console\Application-&gt;doRunCommand()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Mvc/Cli/Symfony/Application.php:169
  #6 Helhum\Typo3Console\Mvc\Cli\Symfony\Application-&gt;doRunCommand()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Application.php:271
  #7 Symfony\Component\Console\Application-&gt;doRun()
  /opt/vstsagent/_work/5/s/vendor/symfony/console/Application.php:147
  #8 Symfony\Component\Console\Application-&gt;run()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Classes/Console/Core/Kernel.php:148
  #9 Helhum\Typo3Console\Core\Kernel-&gt;handle()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Scripts/typo3-console.php:16
  #10 {closure}()
  /opt/vstsagent/_work/5/s/vendor/helhum/typo3-console/Scripts/typo3-console.php:18
  #11 require()
  /opt/vstsagent/_work/5/s/typo3cms-custom.php:17
  </code></pre>
  
  <p>As we understand it, the problem comes from the various scripts that need to be executed to finish a <em>TYPO3</em> installation (or update), because, even if we specify to execute commands with a specific version of <em>PHP</em>, at some point, the version delivred by the OS is used. For now, it seems that our various workarounds don't work very well.</p>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>We also tried the following things without success:</p>
  
  <pre><code>export PATH=/usr/bin/php7.3:$PATH
  php typo3cms install:generatepackagestates
  # FAILURE
  
  alias php='/usr/bin/php7.3'
  php typo3cms install:generatepackagestates
  # FAILURE
  
  alias php=php7.3
  php typo3cms install:generatepackagestates
  # FAILURE
  
  set PATH="/usr/bin/php7.3:$PATH"
  php typo3cms install:generatepackagestates
  # FAILURE
  
  env PATH="/usr/bin/php7.3:$PATH" php typo3cms install:generatepackagestates
  # FAILURE
  </code></pre>
  
  <p>Unfortunately, it doesn't use the version of <em>PHP</em> we specified. What is interesting, is we can do the following thing directly on the build machine:</p>
  
  <pre><code>$ alias php=php7.3
  $ alias 
  alias php='php7.3'
  $ php -v
  PHP 7.3...
  </code></pre>
  
  <p>However, it doesn't produce the same result if we do the same thing in the build pipeline. We have:</p>
  
  <pre><code>$ alias php=php7.3
  $ alias 
  alias php='php7.3'
  $ php -v
  PHP 7.0.33...
  </code></pre>
  
  <p><strong>EDIT 3 (and solution ?)</strong></p>
  
  <p>After hours, we finally managed to make things work (it seems) like so:</p>
  
  <pre><code>$ shopt -s expand_aliases
  $ alias php=php7.3
  alias php='php7.3'
  $ php -v
  PHP 7.3...
  
  $ php ./typo3cms-custom.php install:fixfolderstructure
  $ php ./typo3cms-custom.php install:generatepackagestates
  $ php ./typo3cms-custom.php cache:flush --files-only
  $ php ./composer.phar dump-autoload -o --no-scripts
  </code></pre>
  
  <p>Like so, TYPO3 scripts work and don't output any errors. However, when we do <code>composer install</code> the step before, we have to let the post scripts installation failed to get the file <em>Configuration/ComposerPackagesCommands.php</em>, otherwise, this last one is missing. This is not really clean, but we don't have a better solution for now.</p>
  
  <p>If anyone has a better suggestion...</p>