Skip to content

Commit fbd2a14

Browse files
committed
handle "Exchange Server SE" - shares build number tree 15.2 with "Exchange Server 2019"
for whatever fucked up reason... It's basically a "CU" with a completely new name. Treat it as a different tree in internal representation, which means the "root" trees for the main exchange version don't use the build number prefix as primary key anymore; they might also need to check the version name if the prefix isn't unique.
1 parent f7945f6 commit fbd2a14

File tree

1 file changed

+55
-30
lines changed

1 file changed

+55
-30
lines changed

check_stbuehler_exchange_version

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -336,25 +336,14 @@ class TreeBuilder(yaml.YAMLObject):
336336
self.children[key] = node
337337
return node
338338

339-
def _insert_root(self, path: typing.Sequence[int], name: str) -> TreeBuilder:
339+
def _insert(self, path: typing.Sequence[int], version: Version):
340340
if len(path) == 0:
341-
self.name = name
342-
self.is_root = True
343-
return self
344-
key = path[0]
345-
path = path[1:]
346-
return self._subnode(key)._insert_root(path, name)
347-
348-
def _insert(self, path: typing.Sequence[int], version: Version, *, found_root: bool = False):
349-
if len(path) == 0:
350-
assert found_root, f'Version inserted above roots'
351341
assert self.version is None, f'Version already in tree: {version} ({self.version})'
352342
self.version = version
353343
return
354-
found_root = found_root or self.is_root
355344
key = path[0]
356345
path = path[1:]
357-
self._subnode(key)._insert(path, version, found_root=found_root)
346+
self._subnode(key)._insert(path, version)
358347

359348
def _build_root_trees(self) -> typing.Iterable[Tree]:
360349
if self.is_root:
@@ -380,25 +369,61 @@ class TreeBuilder(yaml.YAMLObject):
380369
tree._fix_tree()
381370
return tree
382371

372+
373+
@dataclasses.dataclass
374+
class RootTrees(yaml.YAMLObject):
375+
@staticmethod
376+
def _default_roots() -> dict[tuple[int, ...], list[tuple[str, TreeBuilder]]]:
377+
CONFIG = {
378+
(15, 2): ['Exchange Server SE', 'Exchange Server 2019'],
379+
(15, 1): ['Exchange Server 2016'],
380+
(15, 0): ['Exchange Server 2013'],
381+
(14,): ['Exchange Server 2010'],
382+
(8,): ['Exchange Server 2007'],
383+
(6, 5): ['Exchange Server 2003'],
384+
(6, 0): ['Exchange 2000 Server'],
385+
(5, 5): ['Exchange Server 5.5'],
386+
(5, 0): ['Exchange Server 5.0'],
387+
(4, 0): ['Exchange Server 4.0'],
388+
(): ['Unknown version'],
389+
}
390+
return {
391+
version: [
392+
(name, TreeBuilder(path=version, name=name, is_root=True))
393+
for name in names
394+
]
395+
for version, names in CONFIG.items()
396+
}
397+
398+
roots: dict[tuple[int, ...], tuple[str, TreeBuilder]] = dataclasses.field(default_factory=_default_roots)
399+
400+
def _insert(self, path: typing.Sequence[int], version: Version):
401+
for num in reversed(range(len(path))):
402+
tbs = self.roots.get(tuple(path[:num]))
403+
if tbs is None:
404+
continue
405+
if len(tbs) == 1:
406+
tbs[0][1]._insert(path[num:], version)
407+
return
408+
# multiple versions in same "tree" - match using the name
409+
for name, tb in tbs:
410+
if version.name.startswith(name):
411+
tb._insert(path[num:], version)
412+
return
413+
414+
raise RuntimeError("unknown version should have been caught by config")
415+
416+
def _build_root_trees(self) -> typing.Iterable[Tree]:
417+
for tbs in self.roots.values():
418+
for _, tb in tbs:
419+
yield from tb._build_root_trees()
420+
383421
@staticmethod
384422
def from_versions(versions: typing.Iterable[Version]) -> 'Tree':
385-
root = TreeBuilder(path=())
386-
for (path, name) in (
387-
((15, 2), 'Exchange Server 2019'),
388-
((15, 1), 'Exchange Server 2016'),
389-
((15, 0), 'Exchange Server 2013'),
390-
((14,), 'Exchange Server 2010'),
391-
((8,), 'Exchange Server 2007'),
392-
((6, 5), 'Exchange Server 2003'),
393-
((6, 0), 'Exchange 2000 Server'),
394-
((5, 5), 'Exchange Server 5.5'),
395-
((5, 0), 'Exchange Server 5.0'),
396-
((4, 0), 'Exchange Server 4.0'),
397-
):
398-
root._insert_root(path, name)
423+
root_tress = RootTrees()
399424
for version in versions:
400-
root._insert(version.num_code, version)
401-
children = list(root._build_root_trees())
425+
root_tress._insert(version.num_code, version)
426+
children = list(root_tress._build_root_trees())
402427
root = Tree(path=(), name='', html_name=None, version=None, children=children)
403428
for c in children:
404429
c.parent = root
@@ -482,7 +507,7 @@ class Trees:
482507
# assume content is utf-8 (html meta), although not specified in http content-type:
483508
versions = list(Version.scan(ms_release_list.content.decode('utf-8')))
484509

485-
root = TreeBuilder.from_versions(versions)
510+
root = RootTrees.from_versions(versions)
486511
trees = Trees(trees=root.children, versions={v.short_code: v for v in versions})
487512
if supported_cus:
488513
trees.calc_alive_supported_cus(supported_cus)

0 commit comments

Comments
 (0)