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

Preserve paths can fail if misconfigured #42

Open
driskell opened this issue Jan 24, 2023 · 2 comments
Open

Preserve paths can fail if misconfigured #42

driskell opened this issue Jan 24, 2023 · 2 comments

Comments

@driskell
Copy link

It's easy to misconfigure preserve paths.

If you preserve a path that, perhaps, receives a single file like a .gitkeep (for Drupal 7 for example the sites/all/themes folder would receive this), then you can hit issues where you lose the data.

  • Package drupal/drupal installs (web/)
  • Preserve of (web/sites/all/themes/) occurs
  • Install creates web/sites/all/themes/.htaccess
  • Package drupal/date_api installs (metapackage with no install-path so it calculates the root: /)
  • Preserve of (web/sites/all/themes/) occurs again because it exists again
  • End of install, restore the original, but then we overwrite again with just a .htaccess file

I think part of the issue is metapackages, as those cause a preserved path to be encountered twice. So packages like date_api, migrate_ui, and field_object can all cause secondary backups if the backup path overlaps.

Other part of the issue is the overlapping configuration - if you do have a preserve path which has its folder or some contents existing in some packages, even if you don't want them and did want to just overwrite it, then all it takes is a metapackage and it will mess up.

Perhaps the fix is metapackage exclusion, but I worry there is some cases still where paths overlap (drupal/drupal for example overlaps everything - there's nothing to say there would be a drupal/parent-module package that installs to modules/contrib/parent and then a drupal/parent-module-child-module package that installs to modules/contrib/parent/modules/child... and this would also cause the issue above if you configured an overlapping path such as modules/contrib/parent/modules)

Perhaps also need to count the number of times preserve is hit on a path and only preserve once, and then at the end once all packages affecting it are installed it is only then restored?

@driskell
Copy link
Author

I can't make a good reproduction case as it seems Composer 2 extracts asynchronously in background, so you have this issue where sometimes it extracts in time before the preserve checks for the path and thus backup again, but then you can have scenario where it doesn't extract before the next package begins processing and so the preserve-paths doesn't detect it and everything then works fine

@driskell
Copy link
Author

driskell commented Jan 24, 2023

{
  "repositories": [
    {
      "type": "composer",
      "url": "https://packages.drupal.org/7"
    },
    {
        "type": "path",
        "url": "../a-sync-copy"
    }
  ],
  "require": {
    "composer/installers": "^1.2",
    "drupal-composer/preserve-paths": "@dev",
    "drupal/drupal": "7.52",
    "drupal/a-sync-copy": "^1",
    "drupal/date_api": "^2",
    "drupal/views": "3.*"
  },
  "config": {
    "vendor-dir": "vendor",
    "allow-plugins": {
      "composer/installers": true,
      "drupal-composer/preserve-paths": true,
      "oomphinc/composer-installers-extender": true
    }
  },
  "extra": {
    "installer-paths": {
      "web/": ["type:drupal-core"],
      "web/sites/all/modules/contrib/{$name}/": ["type:drupal-module"],
      "web/sites/all/themes/contrib/{$name}/": ["type:drupal-theme"],
      "web/sites/all/libraries/{$name}/": ["type:drupal-library"],
      "web/sites/all/drush/{$name}/": ["type:drupal-drush"],
      "web/profiles/{$name}/": ["type:drupal-profile"]
    },
    "preserve-paths": [
      "web/sites/all/modules/contrib",
      "web/sites/all/themes",
      "web/sites/all/libraries",
      "web/sites/all/drush",
      "web/sites/default/settings.php",
      "web/sites/default/files"
    ]
  }
}

With the following in the path location:

{
    "name": "drupal/a-sync-copy",
    "version": "1.0",
    "description": "Drupal theme",
    "type": "drupal-theme",
    "require": {
      "drupal/drupal": "*"
    },
    "require-dev": {}
  }

This reproduces it. Create a module folder in web/sites/all/themes/TEST. After a composer install, it's gone.

Workaround is to preserve web/sites/all/themes/TEST directly. But there's no warning what's happening and due to the async nature of extracting stuff it is random a bit. (Using path VCS is synchronous so reproduces every time)

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

1 participant