786
786
def __repr__(self):
787
787
return "<%s at %r>" % (self.__class__.__name__, self.user_url)
789
def update_feature_flags(self, updated_flags):
790
"""Update the features required by this bzrdir.
792
:param updated_flags: Dictionary mapping feature names to necessities
793
A necessity can be None to indicate the feature should be removed
795
self.control_files.lock_write()
797
self._format._update_feature_flags(updated_flags)
798
self.transport.put_bytes('branch-format', self._format.as_string())
800
self.control_files.unlock()
790
803
class BzrDirMeta1(BzrDir):
791
804
"""A .bzr meta version 1 control object.
1113
1126
(i.e. different from .bzr/branch-format) derive from this class,
1114
1127
as well as the relevant base class for their kind
1115
1128
(BranchFormat, WorkingTreeFormat, RepositoryFormat).
1130
Each format is identified by a "format" or "branch-format" file with a
1131
single line containing the base format name and then an optional list of
1134
Feature flags are supported as of bzr 2.5. Setting feature flags on formats
1135
will render them inaccessible to older versions of bzr.
1137
:ivar features: Dictionary mapping feature names to their necessity
1140
_present_features = set()
1146
def register_feature(cls, name):
1147
"""Register a feature as being present.
1149
:param name: Name of the feature
1152
raise ValueError("spaces are not allowed in feature names")
1153
if name in cls._present_features:
1154
raise errors.FeatureAlreadyRegistered(name)
1155
cls._present_features.add(name)
1158
def unregister_feature(cls, name):
1159
"""Unregister a feature."""
1160
cls._present_features.remove(name)
1162
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1164
for name, necessity in self.features.iteritems():
1165
if name in self._present_features:
1167
if necessity == "optional":
1168
mutter("ignoring optional missing feature %s", name)
1170
elif necessity == "required":
1171
raise errors.MissingFeature(name)
1173
mutter("treating unknown necessity as require for %s",
1175
raise errors.MissingFeature(name)
1119
1178
def get_format_string(cls):
1120
1179
"""Return the ASCII format string that identifies this format."""
1121
1180
raise NotImplementedError(cls.get_format_string)
1124
def from_string(cls, format_string):
1125
if format_string != cls.get_format_string():
1126
raise ValueError("Invalid format header %r" % format_string)
1183
def from_string(cls, text):
1184
format_string = cls.get_format_string()
1185
if not text.startswith(format_string):
1186
raise AssertionError("Invalid format header %r for %r" % (text, cls))
1187
lines = text[len(format_string):].splitlines()
1189
for lineno, line in enumerate(lines):
1191
(necessity, feature) = line.split(" ", 1)
1193
raise errors.ParseFormatError(format=cls, lineno=lineno+2,
1194
line=line, text=text)
1195
ret.features[feature] = necessity
1198
def as_string(self):
1199
"""Return the string representation of this format.
1201
lines = [self.get_format_string()]
1202
lines.extend([("%s %s\n" % (item[1], item[0])) for item in
1203
self.features.iteritems()])
1204
return "".join(lines)
1130
1207
def _find_format(klass, registry, kind, format_string):
1132
cls = registry.get(format_string)
1209
first_line = format_string[:format_string.index("\n")+1]
1211
first_line = format_string
1213
cls = registry.get(first_line)
1133
1214
except KeyError:
1134
raise errors.UnknownFormatError(format=format_string, kind=kind)
1215
raise errors.UnknownFormatError(format=first_line, kind=kind)
1216
return cls.from_string(format_string)
1137
1218
def network_name(self):
1138
1219
"""A simple byte string uniquely identifying this format for RPC calls.
1140
1221
Metadir branch formats use their format string.
1142
return self.get_format_string()
1223
return self.as_string()
1144
1225
def __eq__(self, other):
1145
return (self.__class__ is other.__class__)
1226
return (self.__class__ is other.__class__ and
1227
self.features == other.features)
1229
def _update_feature_flags(self, updated_flags):
1230
"""Update the feature flags in this format.
1232
:param updated_flags: Updated feature flags
1234
for name, necessity in updated_flags.iteritems():
1235
if necessity is None:
1237
del self.features[name]
1241
self.features[name] = necessity
1148
1244
class BzrProber(controldir.Prober):
1433
1528
compatible with whatever sub formats are supported by self.
1531
other_format.features = dict(self.features)
1437
1533
def supports_transport(self, transport):
1438
1534
# bzr formats can be opened over all known transports
1537
def check_support_status(self, allow_unsupported, recommend_upgrade=True,
1539
controldir.ControlDirFormat.check_support_status(self,
1540
allow_unsupported=allow_unsupported, recommend_upgrade=recommend_upgrade,
1542
BzrFormat.check_support_status(self, allow_unsupported=allow_unsupported,
1543
recommend_upgrade=recommend_upgrade, basedir=basedir)
1442
1546
class BzrDirMetaFormat1(BzrDirFormat):
1443
1547
"""Bzr meta control format 1