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