Problem/Motivation

On February 1, 2026, the pear/console_getopt package was marked as archived on GitHub and Packagist. Maintaining abandoned dependencies in drupal/core-recommended poses a potential long-term security and maintainability risk.

Eventually the package was un-abandoned but Drupal should take the opportunity to reduce its dependencies as we worked out we could replace the usage with the builtin \PharData class.

Proposed resolution

Deprecate \Drupal\Core\Archiver\ArchiveTar and use \PharData instead

Remaining tasks

Fix MR to deprecate \Drupal\Core\Archiver\ArchiveTar

User interface changes

None

Introduced terminology

None

API changes

\Drupal\Core\Archiver\ArchiveTar is deprecated without replacement.

Data model changes

None

Release notes snippet

TBD

Issue fork drupal-3571185

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nicrodgers’s picture

Also noticed this today.

drupal/core 11.3.2 requires pear/archive_tar
pear/archive_tar 1.6.0 requires pear/pear-core-minimal
pear/pear-core-minimal v1.10.18 requires pear/console_getopt

longwave’s picture

We are asking if this can be fixed upstream: https://github.com/pear/pear-core-minimal/issues/21

eduardo morales alberti’s picture

The long term solution would be to replace pear/archive_tar by https://www.php.net/manual/en/class.phardata.php

eduardo morales alberti’s picture

The change record removed most of the dependencies https://www.drupal.org/node/3556927
Except \Drupal\Core\Archiver\ArchiveTar that is used on \Drupal\config\Controller\ConfigController::downloadExport

    $archiver = new ArchiveTar($this->fileSystem->getTempDirectory() . '/config.tar.gz', 'gz');
    // Add all contents of the export storage to the archive.
    foreach ($this->exportStorage->listAll() as $name) {
      $archiver->addString("$name.yml", Yaml::encode($this->exportStorage->read($name)));
    }
    // Get all  data from the remaining collections.
    foreach ($this->exportStorage->getAllCollectionNames() as $collection) {
      $collection_storage = $this->exportStorage->createCollection($collection);
      foreach ($collection_storage->listAll() as $name) {
        $archiver->addString(str_replace('.', '/', $collection) . "/$name.yml", Yaml::encode($collection_storage->read($name)));
      }
    }

But could be easily replaced by https://www.php.net/manual/en/class.phardata.php

New way:

// PharData creates .tar first, then we compress to .gz
$tarFile = $this->fileSystem->getTempDirectory() . '/config.tar';
$gzFile = $tarFile . '.gz';

// Clean up any previous files to avoid PharData errors.
if (file_exists($gzFile)) {
  @unlink($gzFile);
}
if (file_exists($tarFile)) {
  @unlink($tarFile);
}

$archiver = new \PharData($tarFile);

// Add all contents of the export storage to the archive.
foreach ($this->exportStorage->listAll() as $name) {
  $archiver->addFromString("$name.yml", Yaml::encode($this->exportStorage->read($name)));
}

// Get all data from the remaining collections.
foreach ($this->exportStorage->getAllCollectionNames() as $collection) {
  $collection_storage = $this->exportStorage->createCollection($collection);
  foreach ($collection_storage->listAll() as $name) {
    $archiver->addFromString(
      str_replace('.', '/', $collection) . "/$name.yml",
      Yaml::encode($collection_storage->read($name))
    );
  }
}

// Compress to .gz and remove the intermediate .tar file.
$archiver->compress(\Phar::GZ);
unset($archiver);
@unlink($tarFile);
eduardo morales alberti’s picture

andypost’s picture

+1 to get rid of pear

eduardo morales alberti’s picture

Summary:

Composer/config (4 files)

  • core/composer.json - Removed pear/archive_tar requirement
  • composer/Metapackage/CoreRecommended/composer.json - Removed all pear packages (archive_tar, console_getopt, pear-core-minimal, pear_exception)
  • composer/Plugin/VendorHardening/Config.php - Removed pear vendor hardening entries
  • core/.phpstan-baseline.php - Removed stale baseline entries for ArchiveTar::_error/_warning

Runtime code (3 files)

  • core/lib/Drupal/Core/Archiver/ArchiveTar.php - Replaced with a deprecated stub (no longer extends \Archive_Tar)
  • core/modules/config/src/Controller/ConfigController.php - ArchiveTar > \PharData, addString > addFromString, added compress(\Phar::GZ) step
  • core/modules/config/src/Form/ConfigImportForm.php - ArchiveTar > \PharData, listContent > iterator, extractList > extractTo

Test code (3 files)

  • ConfigExportImportUITest.php - ArchiveTar > \PharData with RecursiveIteratorIterator
  • ConfigExportUITest.php - ArchiveTar > \PharData with iterator
  • InstallerExistingConfigTestBase.php - ArchiveTar > \PharData, extractInString > getContent()

longwave’s picture

Status: Active » Needs work

Thanks, if this works it looks like a good approach, but coding standards and tests are failing.

eduardo morales alberti’s picture

Failed https://git.drupalcode.org/issue/drupal-3571185/-/jobs/8887753 but seems not related

84.630s …Tests\demo_umami\FunctionalJavascript\AssetAggregationAcrossPagesTest    0 passed, 1 failed, exit code 1
eduardo morales alberti’s picture

Status: Needs work » Needs review
eduardo morales alberti’s picture

Seems like the aggregation test is fixed on main branch, merging

eduardo morales alberti’s picture

MR stabilized, ready to review

alexpott’s picture

Status: Needs review » Needs work

The current approach is completely breaking \Drupal\Core\Archiver\ArchiveTar. I don't think this is a viable approach for Drupal 11. It will break contrib modules see https://search.tresbien.tech/search?q=ArchiveTar%20-f%3Acore&num=50&ctx=0

I think the way to go here is to deprecate it in Drupal 11 and remove in Drupal 12. Yes we have to act quick but because the replacement is using \PharData - available in PHP since 5.3 I think this is okay.

So this MR should remove all usages of ArchiveTar from core but leave the dependencies in and deprecate the class to be removed in Drupal 12. The CR should give clear instructions of how to update. Then we should open a new issue to remove the ArchiveTar and it's composer dependencies from Drupal 12. We can't fix the abandoned package issue in Drupal 11 and maintain BC as far as I can see.

eduardo morales alberti’s picture

Ok, @alexpott, we will add the dependencies then, and deprecate the class, and remove it on D12

eduardo morales alberti’s picture

One question, should we create two MRs? one to 11.x and the other to main? Main goes against D12?

alexpott’s picture

@eduardo morales alberti let's first do the deprecation for Drupal 12... on both main and 11.x which will remove all the core usages too. And then we can open a new issue to remove the class and dependencies on main and leave 11.x alone.

longwave’s picture

I don't know if it's possible to shim all the methods that ArchiveTar provides and keep backward compatibility by using PharData under the hood? The different way that it appears to handle compression might not mean this is possible.

eduardo morales alberti’s picture

We keep the archive tar with a deprecated message to avoid losing backward compatibility. MR https://git.drupalcode.org/project/drupal/-/merge_requests/15074

eduardo morales alberti changed the visibility of the branch 3571185-remove-abandoned-pearconsolegetopt to hidden.

eduardo morales alberti’s picture

@logwave \PharData cannot replace \Archive_Tar on core/lib/Drupal/Core/Archiver/ArchiveTar.php because they are similar but do not share the same methods.

longwave’s picture

MR!15076 is a backward compatible implementation that removes Archive_Tar and handles everything internally with PharData.

Disclaimer: this MR was assisted by Claude Code.

longwave’s picture

Status: Needs work » Needs review

eduardo morales alberti changed the visibility of the branch 3571185-remove-archive-tar-dependency to hidden.

eduardo morales alberti’s picture

@longwave approximation is a cleaner option and allows for removing the dependency directly without breaking backwards compatibility.

longwave’s picture

Discussed with @alexpott, we still want to remove this and encourage direct use of PharData instead, but this removes the urgency; we can deprecate it for removal in Drupal 13.

alexpott’s picture

So I've cloned https://github.com/pear/Archive_Tar.git and replaced the Archive_Tar class with our PharData backed class and we've got quite a way to go make it pass all the tests.

alexpott’s picture

So I've tried to get as many of the tests from the PEAR package passing as possible. Unfortunately the reality is that there are somethings the PEAR package supports that PharData cannot. There are:

  • symlinks
  • long filenames
  • directory permissions

Also there are differences due to error handling - obviously the of PEAR errors and this not problematic because we already override that - but also the PharData approach gets out-of-memory errors where the PEAR package does not.

So tldr; while I wish @longwave's MR was an option I'm not sure it is because it's not possible to be API equivalent enough.

I wish this problem would just be fixed by PEAR. I'm not sure of the impact of the long filename issue... and who knows what contrib and custom are relying on.

Not sure of the best way forward but maybe the place from #16 will work for core. I guess in an ideal world this would be fixed upstream.

eduardo morales alberti’s picture

longwave’s picture

Upstream has un-abandoned the package, so the original problem is gone: https://github.com/pear/pear-core-minimal/issues/21

We could still repurpose this issue to replace ArchiveTar with PharData and eventually drop the dependency on pear/archive_tar.

longwave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue rescope
jamesoakley’s picture

IMO, this buys us time, but the direction of travel is clearly away from pear/console_getopt remaining maintained. So it would be prudent to removing our dependency on it.

alexpott changed the visibility of the branch 3571185-remove-abandoned-pearconsolegetopt to active.

alexpott changed the visibility of the branch 3571185-archivetar-phardata-shim to hidden.

alexpott’s picture

I've unhidden the branch that only needs a few updates in order to remove the dependency. We need to stop removing the dependency in this MR and deprecate core's ArchiveTar class to be removed in Drupal 13. And then we can file a follow-up issue against main to remove the dependency once 12.x has been branched from main.

alexpott’s picture

Title: Remove abandoned pear/console_getopt from drupal/core-recommended » Replace usage of \Drupal\Core\Archiver\ArchiveTar with \PharData and deprecate it
Category: Bug report » Task
Issue summary: View changes
Issue tags: -Needs issue rescope +Needs change record

I've updated the issue summary and title to fit the rescoped purpose.

alexpott’s picture

Status: Needs work » Needs review
alexpott’s picture

For me the big question about this change is do we open new security issues by using \PharData like this that have been closed off by using the old and well-tested code from PEAR. That's going to be a hard call to make...

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.