1# Contains the ruby version heuristics
2{ lib }:
3with lib;
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 = removePrefix "p" tail;
14 isPosInt = num:
15 0 == stringLength
16 (replaceStrings
17 ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"]
18 ["" "" "" "" "" "" "" "" "" "" ]
19 num);
20 in
21 if 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 versionAtLeast majMinTiny "2.1.0" then
32 "${majMin}.0"
33 else if versionAtLeast majMinTiny "2.0.0" then
34 "2.0.0"
35 else if 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 if self.tail != "" then
59 "-${self.tail}"
60 else "");
61 };
62in
63 rubyVersion