784
786
def __repr__(self):
785
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()
788
803
class BzrDirMeta1(BzrDir):
789
804
"""A .bzr meta version 1 control object.
1111
1126
(i.e. different from .bzr/branch-format) derive from this class,
1112
1127
as well as the relevant base class for their kind
1113
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)
1117
1178
def get_format_string(cls):
1118
1179
"""Return the ASCII format string that identifies this format."""
1119
1180
raise NotImplementedError(cls.get_format_string)
1122
def from_string(cls, format_string):
1123
if format_string != cls.get_format_string():
1124
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)
1128
1207
def _find_format(klass, registry, kind, format_string):
1130
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)
1131
1214
except KeyError:
1132
raise errors.UnknownFormatError(format=format_string, kind=kind)
1215
raise errors.UnknownFormatError(format=first_line, kind=kind)
1216
return cls.from_string(format_string)
1135
1218
def network_name(self):
1136
1219
"""A simple byte string uniquely identifying this format for RPC calls.
1138
1221
Metadir branch formats use their format string.
1140
return self.get_format_string()
1223
return self.as_string()
1142
1225
def __eq__(self, other):
1143
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
1146
1244
class BzrProber(controldir.Prober):
1431
1528
compatible with whatever sub formats are supported by self.
1531
other_format.features = dict(self.features)
1435
1533
def supports_transport(self, transport):
1436
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)
1440
1546
class BzrDirMetaFormat1(BzrDirFormat):
1441
1547
"""Bzr meta control format 1