Add a Sorting function.
Currently we're reverse sorting with a simple sort, this sadly puts newer released (antalope, bobcat) at the end of the list. Add a key function that has context around our release names and release ids to sort "2024.1/cantaloupe"[1] at the top. [1] As of now the c name isn't selected cantaloupe is my placeholder Change-Id: I4b021d99bd4ecc232838a3639dd8d5ef075e1a24
This commit is contained in:
@@ -27,6 +27,7 @@ from sphinx.util.nodes import nested_parse_with_titles
|
|||||||
|
|
||||||
from openstack_releases import deliverable
|
from openstack_releases import deliverable
|
||||||
from openstack_releases import links
|
from openstack_releases import links
|
||||||
|
from openstack_releases import series_sorting
|
||||||
from openstack_releases import series_status
|
from openstack_releases import series_status
|
||||||
from openstack_releases._redirections import generate_constraints_redirections
|
from openstack_releases._redirections import generate_constraints_redirections
|
||||||
|
|
||||||
@@ -384,7 +385,8 @@ class TeamDirective(rst.Directive):
|
|||||||
)
|
)
|
||||||
|
|
||||||
all_series = reversed(sorted(
|
all_series = reversed(sorted(
|
||||||
_deliverables.get_team_series(self.team_name)
|
_deliverables.get_team_series(self.team_name),
|
||||||
|
key=series_sorting.keyfunc
|
||||||
))
|
))
|
||||||
# If independent is in the list, it should be sorted last
|
# If independent is in the list, it should be sorted last
|
||||||
all_series = sorted(all_series, key='independent'.__eq__)
|
all_series = sorted(all_series, key='independent'.__eq__)
|
||||||
|
55
openstack_releases/series_sorting.py
Normal file
55
openstack_releases/series_sorting.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
_series_data = [
|
||||||
|
["austin", "bexar", "cactus", "diablo", "essex", "folsom", "grizzly",
|
||||||
|
"havana", "icehouse", "juno", "kilo", "liberty", "mitaka", "newton",
|
||||||
|
"ocata", "pike", "queens", "rocky", "stein", "train", "ussuri",
|
||||||
|
"victoria", "wallaby", "xena", "yoga", "zed"],
|
||||||
|
# ["antelope", bobcat, etc etc etc],`
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def keyfunc(series_name):
|
||||||
|
assert series_name.isascii()
|
||||||
|
|
||||||
|
# NOTE(tonyb): Create a private copy to avoid mutating input variable
|
||||||
|
_series_name = series_name.lower()
|
||||||
|
# This for/else statement looks for a series_name in series_data. If it
|
||||||
|
# is found stop looking (via break), because we have all the information
|
||||||
|
# we need. If the series name isn't found, i.e a run through the entire
|
||||||
|
# series_data list-of-lists, the 'else' clause will be executed to do our
|
||||||
|
# best to deduce the sort key from there.
|
||||||
|
for series_nr, series_names in enumerate(_series_data):
|
||||||
|
if _series_name in series_names:
|
||||||
|
series_idx = series_names.index(_series_name)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if _series_name[0].isalpha():
|
||||||
|
series_nr += 1
|
||||||
|
series_idx = ord(_series_name[0]) - ord("a")
|
||||||
|
elif _series_name[0].isdigit():
|
||||||
|
(year, release) = map(int, _series_name.split("."))
|
||||||
|
# This arithmetic comes from the fact that we started using
|
||||||
|
# year.release naming scheme, after we completed a full list
|
||||||
|
# of the alphabet.
|
||||||
|
# This happened with the 2023.1 release. To date it's two
|
||||||
|
# releases per year. If that changes this code will need to
|
||||||
|
# be updated.
|
||||||
|
# Releases "austin" -> "zed" are 0 -> 25 so 2023.1 is the 26th
|
||||||
|
# OpenStack release
|
||||||
|
(series_nr, series_idx) = \
|
||||||
|
divmod(26 + ((year - 2023) * 2 + (release - 1)), 26)
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
# TODO(tonyb): Do we want to switch this to aa_austin, ba_2023.1 to force
|
||||||
|
# a stable sort order
|
||||||
|
return series_nr * 26 + series_idx
|
71
openstack_releases/tests/test_sorting.py
Normal file
71
openstack_releases/tests/test_sorting.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
|
from oslotest import base
|
||||||
|
|
||||||
|
from openstack_releases import series_sorting
|
||||||
|
|
||||||
|
|
||||||
|
class TestSeries_Sorting(base.BaseTestCase):
|
||||||
|
FAKE_SERIES_DATA = [
|
||||||
|
series_sorting._series_data[0],
|
||||||
|
["antelope", "bobcat", "camel", "duck", "elephant", "fox", "gorilla",
|
||||||
|
"hamster", "ibex", "jellyfish", "kudu", "lion", "meerkat", "narwhal",
|
||||||
|
"otter", "pony", "quail", "raccoon", "salmon", "termite", "uakari",
|
||||||
|
"viperfish", "whale", "xerus", "yak", "zebra"]
|
||||||
|
]
|
||||||
|
|
||||||
|
def test_assert_nonascii(self):
|
||||||
|
self.assertRaises(AssertionError, series_sorting.keyfunc, "ハロー")
|
||||||
|
|
||||||
|
def test_assert_nonaplphanumeric(self):
|
||||||
|
self.assertRaises(AssertionError, series_sorting.keyfunc, "__austin")
|
||||||
|
|
||||||
|
def test_simple(self):
|
||||||
|
test_series_list = ["antelope", "victoria", "2023.1", "zed",
|
||||||
|
"c-release-not-cactus"]
|
||||||
|
sorted_series_list = ["victoria", "zed", "antelope", "2023.1",
|
||||||
|
"c-release-not-cactus"]
|
||||||
|
self.assertEqual(sorted(test_series_list, key=series_sorting.keyfunc),
|
||||||
|
sorted_series_list)
|
||||||
|
|
||||||
|
def test_simple_with_case(self):
|
||||||
|
test_series_list = ["Antelope", "victoria", "2023.1", "zed",
|
||||||
|
"C-release-not-cactus"]
|
||||||
|
sorted_series_list = ["victoria", "zed", "Antelope", "2023.1",
|
||||||
|
"C-release-not-cactus"]
|
||||||
|
self.assertEqual(sorted(test_series_list, key=series_sorting.keyfunc),
|
||||||
|
sorted_series_list)
|
||||||
|
|
||||||
|
@mock.patch.object(series_sorting, "_series_data", FAKE_SERIES_DATA)
|
||||||
|
def test_with_series_2(self):
|
||||||
|
test_series_list = ["antelope", "austin", "aardvark"]
|
||||||
|
sorted_series_list = ["austin", "antelope", "aardvark"]
|
||||||
|
self.assertEqual(sorted(test_series_list, key=series_sorting.keyfunc),
|
||||||
|
sorted_series_list)
|
||||||
|
|
||||||
|
@mock.patch.object(series_sorting, "_series_data", FAKE_SERIES_DATA)
|
||||||
|
def test_with_series_2_rollover(self):
|
||||||
|
test_series_list = ["antelope", "austin", "zebra", "yak", "aardvark"]
|
||||||
|
sorted_series_list = ["austin", "antelope", "yak", "zebra", "aardvark"]
|
||||||
|
self.assertEqual(sorted(test_series_list, key=series_sorting.keyfunc),
|
||||||
|
sorted_series_list)
|
||||||
|
|
||||||
|
@mock.patch.object(series_sorting, "_series_data", FAKE_SERIES_DATA)
|
||||||
|
def test_with_series_2_mixed_styles(self):
|
||||||
|
test_series_list = ["elephant", "2023.1", "duck", "2024.2",
|
||||||
|
"aardvark", "2024.1"]
|
||||||
|
sorted_series_list = ["2023.1", "2024.1", "duck", "2024.2",
|
||||||
|
"elephant", "aardvark"]
|
||||||
|
self.assertEqual(sorted(test_series_list, key=series_sorting.keyfunc),
|
||||||
|
sorted_series_list)
|
Reference in New Issue
Block a user