about summary refs log tree commit diff
path: root/parse.nix
blob: 6244b6954fbe3a2953f50bfa77634e9af2ee7dec (plain) (blame)
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
{ lib }:
let
  isStrEmpty = s: (builtins.replaceStrings [ " " ] [ "" ] s) == "";

  splitString = _sep: _s: builtins.filter
    (x: builtins.typeOf x == "string")
    (builtins.split _sep _s);

  parsePackagesFromPackageRequires = packageFile:
    let
      lines = splitString "\r?\n" packageFile;
      requires =
        lib.concatMapStrings
          (line:
            let match = builtins.match ";;;* *[pP]ackage-[rR]equires *: *\\((.*)\\) *" line;
            in if match == null then "" else builtins.head match)
          lines;
      parseReqList = s:
        let matchAndRest = builtins.match " *\\(? *([^ \"\\)]+)( +\"[^\"]+\" *\\)| *\\))?(.*)" s;
        in
        if isStrEmpty s then
          [ ]
        else
          if matchAndRest == null then
            throw "Failed to parse package requirements list: ${s}"
          else
            [ (builtins.head matchAndRest) ] ++ (parseReqList (builtins.elemAt matchAndRest 2));
    in
    parseReqList requires;

  stripComments = dotEmacs:
    let
      lines = splitString "\n" dotEmacs;
      stripped = builtins.map
        (l:
          builtins.elemAt (splitString ";;" l) 0)
        lines;
    in
    builtins.concatStringsSep " " stripped;

  parsePackagesFromUsePackage = dotEmacs:
    let
      strippedComments = stripComments dotEmacs;
      tokens = builtins.filter (t: !(isStrEmpty t)) (builtins.map
        (t: if builtins.typeOf t == "list" then builtins.elemAt t 0 else t)
        (builtins.split "([\(\)])" strippedComments)
      );
      matches = builtins.map
        (t:
          builtins.match "^use-package[[:space:]]+([A-Za-z0-9_-]+).*" t)
        tokens;
    in
    builtins.map
      (m: builtins.elemAt m 0)
      (builtins.filter (m: m != null) matches);

in
{
  inherit parsePackagesFromPackageRequires;
  inherit parsePackagesFromUsePackage;
}