@@ -8,6 +8,7 @@ import 'package:clock/clock.dart';
88import 'package:json_annotation/json_annotation.dart' ;
99import 'package:pub_dev/admin/actions/actions.dart' ;
1010import 'package:pub_dev/shared/utils.dart' ;
11+ import 'package:pub_semver/pub_semver.dart' ;
1112
1213import '../shared/datastore.dart' as db;
1314import '../shared/versions.dart' as shared_versions;
@@ -167,7 +168,7 @@ class PackageState extends db.ExpandoModel<String> {
167168 final at_ = at ?? clock.now ();
168169 Duration timeSince (DateTime past) => at_.difference (past);
169170
170- return versions! .entries
171+ final list = versions! .entries
171172 .where (
172173 // NOTE: Any changes here must be reflected in [derivePendingAt]
173174 (e) =>
@@ -185,7 +186,40 @@ class PackageState extends db.ExpandoModel<String> {
185186 taskRetryDelay (e.value.attempts)),
186187 )
187188 .map ((e) => e.key)
189+ .map (Version .parse)
188190 .toList ();
191+
192+ // Prioritize stable versions first, prereleases after them (in decreasing order), e.g.
193+ // - 2.5.0
194+ // - 2.4.0
195+ // - 2.0.0
196+ // - 1.2.0
197+ // - 3.0.0-dev2
198+ // - 3.0.0-dev1
199+ // - 2.7.0-beta
200+ // - 1.0.0-dev
201+ list.sort ((a, b) => compareSemanticVersionsDesc (a, b, true , true ));
202+
203+ // Promote the first prerelease version to the second position, e.g.
204+ // - 2.5.0
205+ // - 3.0.0-dev2
206+ // - 2.4.0
207+ // - 2.0.0
208+ // - 1.2.0
209+ // - 3.0.0-dev1
210+ // - 2.7.0-beta
211+ // - 1.0.0-dev
212+ //
213+ // (applicable only when the second position is a stable version)
214+ if (list.length > 2 && ! list[1 ].isPreRelease) {
215+ final firstPrereleaseIndex = list.indexWhere ((v) => v.isPreRelease);
216+ if (firstPrereleaseIndex > 1 ) {
217+ final v = list.removeAt (firstPrereleaseIndex);
218+ list.insert (1 , v);
219+ }
220+ }
221+
222+ return list.map ((s) => s.toString ()).toList ();
189223 }
190224
191225 /// Returns true if the current [PackageState] instance is new, no version analysis
0 commit comments