1# Contains the ruby version heuristics
2{ lib }:
3
4let
5 # The returned set should be immutable
6 rubyVersion = major: minor: tiny: tail:
7 rec {
8 inherit major minor tiny tail;
9
10 # Contains the patch number "223" if tail is "p223" or null
11 patchLevel =
12 let
13 p = lib.removePrefix "p" tail;
14 isPosInt = num:
15 0 == lib.stringLength
16 (lib.replaceStrings
17 ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"]
18 ["" "" "" "" "" "" "" "" "" "" ]
19 num);
20 in
21 if lib.hasPrefix "p" tail && isPosInt p then p
22 else null;
23
24 # Shortcuts
25 majMin = "${major}.${minor}";
26 majMinTiny = "${major}.${minor}.${tiny}";
27
28 # Ruby separates lib and gem folders by ABI version which isn't very
29 # consistent.
30 libDir =
31 if lib.versionAtLeast majMinTiny "2.1.0" then
32 "${majMin}.0"
33 else if lib.versionAtLeast majMinTiny "2.0.0" then
34 "2.0.0"
35 else if lib.versionAtLeast majMinTiny "1.9.1" then
36 "1.9.1"
37 else
38 throw "version ${majMinTiny} is not supported";
39
40 # How ruby releases are tagged on github.com/ruby/ruby
41 gitTag =
42 let
43 base = "v${major}_${minor}_${tiny}";
44 in
45 if patchLevel != null then
46 "${base}_${patchLevel}"
47 else
48 if tail != "" then
49 "${base}_${tail}"
50 else
51 base;
52
53 # Implements the builtins.toString interface.
54 __toString = self:
55 self.majMinTiny + (
56 if self.patchLevel != null then
57 "-p${self.patchLevel}"
58 else
59 lib.optionalString (self.tail != "") "-${self.tail}"
60 );
61 };
62in
63 rubyVersion