summaryrefslogtreecommitdiff
path: root/pkgs/development/interpreters/ruby/ruby-version.nix
blob: 8b8bebc9ec42dafd235536bbd2bb1d14681f35a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# Contains the ruby version heuristics
{ lib }:

let
  # The returned set should be immutable
  rubyVersion = major: minor: tiny: tail: rec {
    inherit
      major
      minor
      tiny
      tail
      ;

    # Contains the patch number "223" if tail is "p223" or null
    patchLevel =
      let
        p = lib.removePrefix "p" tail;
        isPosInt =
          num:
          0 == lib.stringLength (
            lib.replaceStrings
              [
                "0"
                "1"
                "2"
                "3"
                "4"
                "5"
                "6"
                "7"
                "8"
                "9"
              ]
              [
                ""
                ""
                ""
                ""
                ""
                ""
                ""
                ""
                ""
                ""
              ]
              num
          );
      in
      if lib.hasPrefix "p" tail && isPosInt p then p else null;

    # Shortcuts
    majMin = "${major}.${minor}";
    majMinTiny = "${major}.${minor}.${tiny}";

    # Ruby separates lib and gem folders by ABI version which isn't very
    # consistent.
    libDir =
      if lib.versionAtLeast majMinTiny "2.1.0" then
        "${majMin}.0"
      else if lib.versionAtLeast majMinTiny "2.0.0" then
        "2.0.0"
      else if lib.versionAtLeast majMinTiny "1.9.1" then
        "1.9.1"
      else
        throw "version ${majMinTiny} is not supported";

    # How ruby releases are tagged on github.com/ruby/ruby
    gitTag =
      let
        base = "v${major}_${minor}_${tiny}";
      in
      if patchLevel != null then
        "${base}_${patchLevel}"
      else if tail != "" then
        "${base}_${tail}"
      else
        base;

    # Implements the builtins.toString interface.
    __toString =
      self:
      self.majMinTiny
      + (
        if self.patchLevel != null then
          "-p${self.patchLevel}"
        else
          lib.optionalString (self.tail != "") "-${self.tail}"
      );
  };
in
rubyVersion