Mercurial > hg-stable
changeset 47327:e985a36c2aa3
upgrade: Use `improvement` subclasses everywhere, not instances
This changes the source definition of optimizations to match that of formats:
a subclass with a decorator, instead of an instance passed to a function call.
Not having any instance removes the confusion between class attributes and
instance attributes, which were used interchangeably.
Differential Revision: https://phab.mercurial-scm.org/D10768
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 21 May 2021 17:12:47 +0200 |
parents | 825d5a5907b4 |
children | a43d256c041a |
files | mercurial/upgrade_utils/actions.py |
diffstat | 1 files changed, 116 insertions(+), 160 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/upgrade_utils/actions.py Tue May 11 01:05:38 2021 -0400 +++ b/mercurial/upgrade_utils/actions.py Fri May 21 17:12:47 2021 +0200 @@ -44,92 +44,16 @@ class improvement(object): - """Represents an improvement that can be made as part of an upgrade. - - The following attributes are defined on each instance: - - name - Machine-readable string uniquely identifying this improvement. It - will be mapped to an action later in the upgrade process. - - type - Either ``FORMAT_VARIANT`` or ``OPTIMISATION``. - A format variant is where we change the storage format. Not all format - variant changes are an obvious problem. - An optimization is an action (sometimes optional) that - can be taken to further improve the state of the repository. - - description - Message intended for humans explaining the improvement in more detail, - including the implications of it. For ``FORMAT_VARIANT`` types, should be - worded in the present tense. For ``OPTIMISATION`` types, should be - worded in the future tense. + """Represents an improvement that can be made as part of an upgrade.""" - upgrademessage - Message intended for humans explaining what an upgrade addressing this - issue will do. Should be worded in the future tense. - - postupgrademessage - Message intended for humans which will be shown post an upgrade - operation when the improvement will be added - - postdowngrademessage - Message intended for humans which will be shown post an upgrade - operation in which this improvement was removed - - touches_filelogs (bool) - Whether this improvement touches filelogs - - touches_manifests (bool) - Whether this improvement touches manifests - - touches_changelog (bool) - Whether this improvement touches changelog + ### The following attributes should be defined for each subclass: - touches_requirements (bool) - Whether this improvement changes repository requirements - """ - - def __init__(self, name, type, description, upgrademessage): - self.name = name - self.type = type - self.description = description - self.upgrademessage = upgrademessage - self.postupgrademessage = None - self.postdowngrademessage = None - # By default for now, we assume every improvement touches - # all the things - self.touches_filelogs = True - self.touches_manifests = True - self.touches_changelog = True - self.touches_requirements = True - - def __eq__(self, other): - if not isinstance(other, improvement): - # This is what python tell use to do - return NotImplemented - return self.name == other.name - - def __ne__(self, other): - return not (self == other) - - def __hash__(self): - return hash(self.name) - - -allformatvariant = [] # type: List[Type['formatvariant']] - - -def registerformatvariant(cls): - allformatvariant.append(cls) - return cls - - -class formatvariant(improvement): - """an improvement subclass dedicated to repository format""" - - type = FORMAT_VARIANT - ### The following attributes should be defined for each class: + # Either ``FORMAT_VARIANT`` or ``OPTIMISATION``. + # A format variant is where we change the storage format. Not all format + # variant changes are an obvious problem. + # An optimization is an action (sometimes optional) that + # can be taken to further improve the state of the repository. + type = None # machine-readable string uniquely identifying this improvement. it will be # mapped to an action later in the upgrade process. @@ -157,13 +81,32 @@ postdowngrademessage = None # By default for now, we assume every improvement touches all the things + + # Whether this improvement touches filelogs touches_filelogs = True + + # Whether this improvement touches manifests touches_manifests = True + + # Whether this improvement touches changelog touches_changelog = True + + # Whether this improvement changes repository requirements touches_requirements = True - def __init__(self): - raise NotImplementedError() + +allformatvariant = [] # type: List[Type['formatvariant']] + + +def registerformatvariant(cls): + allformatvariant.append(cls) + return cls + + +class formatvariant(improvement): + """an improvement subclass dedicated to repository format""" + + type = FORMAT_VARIANT @staticmethod def fromrepo(repo): @@ -545,87 +488,100 @@ return obj -register_optimization( - improvement( - name=b're-delta-parent', - type=OPTIMISATION, - description=_( - b'deltas within internal storage will be recalculated to ' - b'choose an optimal base revision where this was not ' - b'already done; the size of the repository may shrink and ' - b'various operations may become faster; the first time ' - b'this optimization is performed could slow down upgrade ' - b'execution considerably; subsequent invocations should ' - b'not run noticeably slower' - ), - upgrademessage=_( - b'deltas within internal storage will choose a new ' - b'base revision if needed' - ), +class optimization(improvement): + """an improvement subclass dedicated to optimizations""" + + type = OPTIMISATION + + +@register_optimization +class redeltaparents(optimization): + name = b're-delta-parent' + + type = OPTIMISATION + + description = _( + b'deltas within internal storage will be recalculated to ' + b'choose an optimal base revision where this was not ' + b'already done; the size of the repository may shrink and ' + b'various operations may become faster; the first time ' + b'this optimization is performed could slow down upgrade ' + b'execution considerably; subsequent invocations should ' + b'not run noticeably slower' ) -) + + upgrademessage = _( + b'deltas within internal storage will choose a new ' + b'base revision if needed' + ) + + +@register_optimization +class redeltamultibase(optimization): + name = b're-delta-multibase' + + type = OPTIMISATION + + description = _( + b'deltas within internal storage will be recalculated ' + b'against multiple base revision and the smallest ' + b'difference will be used; the size of the repository may ' + b'shrink significantly when there are many merges; this ' + b'optimization will slow down execution in proportion to ' + b'the number of merges in the repository and the amount ' + b'of files in the repository; this slow down should not ' + b'be significant unless there are tens of thousands of ' + b'files and thousands of merges' + ) -register_optimization( - improvement( - name=b're-delta-multibase', - type=OPTIMISATION, - description=_( - b'deltas within internal storage will be recalculated ' - b'against multiple base revision and the smallest ' - b'difference will be used; the size of the repository may ' - b'shrink significantly when there are many merges; this ' - b'optimization will slow down execution in proportion to ' - b'the number of merges in the repository and the amount ' - b'of files in the repository; this slow down should not ' - b'be significant unless there are tens of thousands of ' - b'files and thousands of merges' - ), - upgrademessage=_( - b'deltas within internal storage will choose an ' - b'optimal delta by computing deltas against multiple ' - b'parents; may slow down execution time ' - b'significantly' - ), + upgrademessage = _( + b'deltas within internal storage will choose an ' + b'optimal delta by computing deltas against multiple ' + b'parents; may slow down execution time ' + b'significantly' ) -) + + +@register_optimization +class redeltaall(optimization): + name = b're-delta-all' + + type = OPTIMISATION + + description = _( + b'deltas within internal storage will always be ' + b'recalculated without reusing prior deltas; this will ' + b'likely make execution run several times slower; this ' + b'optimization is typically not needed' + ) -register_optimization( - improvement( - name=b're-delta-all', - type=OPTIMISATION, - description=_( - b'deltas within internal storage will always be ' - b'recalculated without reusing prior deltas; this will ' - b'likely make execution run several times slower; this ' - b'optimization is typically not needed' - ), - upgrademessage=_( - b'deltas within internal storage will be fully ' - b'recomputed; this will likely drastically slow down ' - b'execution time' - ), + upgrademessage = _( + b'deltas within internal storage will be fully ' + b'recomputed; this will likely drastically slow down ' + b'execution time' ) -) + + +@register_optimization +class redeltafulladd(optimization): + name = b're-delta-fulladd' + + type = OPTIMISATION -register_optimization( - improvement( - name=b're-delta-fulladd', - type=OPTIMISATION, - description=_( - b'every revision will be re-added as if it was new ' - b'content. It will go through the full storage ' - b'mechanism giving extensions a chance to process it ' - b'(eg. lfs). This is similar to "re-delta-all" but even ' - b'slower since more logic is involved.' - ), - upgrademessage=_( - b'each revision will be added as new content to the ' - b'internal storage; this will likely drastically slow ' - b'down execution time, but some extensions might need ' - b'it' - ), + description = _( + b'every revision will be re-added as if it was new ' + b'content. It will go through the full storage ' + b'mechanism giving extensions a chance to process it ' + b'(eg. lfs). This is similar to "re-delta-all" but even ' + b'slower since more logic is involved.' ) -) + + upgrademessage = _( + b'each revision will be added as new content to the ' + b'internal storage; this will likely drastically slow ' + b'down execution time, but some extensions might need ' + b'it' + ) def findoptimizations(repo):