0

Imagine that you have a package MyPackage and it depends on another project called Library. MyPackage has extension methods in a class LibraryClass which is in the Library project.

At some point Library is changed and LibraryClass is renamed to NewLibraryClass or removed completely. You make changes in your project, for example move extension methods to NewLibraryClass or solve it in a different way, this does not matter much.

The problem arises when someone has a pre-Library-changes version of MyPackage already installed and updates it. Then Library package is loaded first, as your project depends on it. While Library is being loaded LibraryClass is removed and so MyPackage extension methods that were present in LibraryClass are deleted. This marks MyPackage as dirty, and so when it finally loads changes to MyPackage, the user is asked to resolve a merge even if there are no real conflicts.

How can this be solved? Because in the end your code is fine, but the user that updates your project will face weird merge questions.

Uko
  • 13,134
  • 6
  • 58
  • 106
  • The only way I see to cope with this properly is for every project to keep track of (i.e., remember) all classes whose names have changed and offer services that dependent projects could use to migrate themselves when loading. – Leandro Caniglia Nov 23 '15 at 16:01

1 Answers1

0

I have a hack that should not be qualified as a full solution, but helps to overcome the issue.

In the configuration of your project add a pre-load doit (section 1.10 of Managing projects with Metacello) and call this method:

cleanUpLibrary

  | myPackage |

  myPackage := (#MyPackage asPackageIfAbsent: [ ^ self ]).

  LibraryClass asClassIfPresent: [ :class |
    class protocols
      select: [ :prot | prot asLowercase beginsWith: myPackage methodCategoryPrefix ]
      thenDo: [ :prot | class removeProtocol: prot ] ].

  myPackage mcWorkingCopy modified: false

This will remove all extension protocols of MyPackage from LibraryClass and mark MyPackage as not modified (clean, not dirty…). Then when Library will be loading and will remove LibraryClass, MyPackage will not be marked as dirty, because at that moment LibraryClass will not have any extension methods of MyPackage

Uko
  • 13,134
  • 6
  • 58
  • 106