@@ -40,6 +40,12 @@ module Util = struct
4040 module Uri = struct
4141 (* *)
4242
43+ (* * A local reference to nixpkgs, eg. {nixpkgs#...} or {pkgs#...} (which resolves to the former) *)
44+ type nixpkgs =
45+ { uri : string
46+ ; installables : string list
47+ }
48+
4349 (* * URI variants, like {/path/to/flake#drv} or {github:NixOS/nixpkgs#drv} *)
4450 type uri =
4551 (* A path with up to one attribute, eg. /path/to/resouce or /path/to/resource#... *)
@@ -48,6 +54,8 @@ module Util = struct
4854 | LocalResourceMultiAttr of string * string
4955 (* A remote resource, eg. github:NixOS/nixpkgs *)
5056 | RemoteResource of string
57+ (* A local reference to nixpkgs, eg. nixpkgs#... or pkgs#... (which resolves to the former) *)
58+ | Nixpkgs of nixpkgs
5159
5260 (* * Format a uri and attribute into a string *)
5361 let sprintf_uri_attr path attr = Printf. sprintf " %s#%s" path attr
@@ -65,17 +73,38 @@ module Util = struct
6573 | LocalResourceMaybeAttr (path , attr_opt ) -> sprintf_uri_attr_opt path attr_opt
6674 | LocalResourceMultiAttr (path , attr ) -> sprintf_uri_attr path attr
6775 | RemoteResource uri -> uri
76+ | Nixpkgs { uri; _ } -> uri
6877 ;;
6978
7079 (* * Parse target argument for optional attribute selection *)
7180 let parse_target target =
7281 let parse_uri uri attr_opt =
82+ let is_multiattr maybe_multiattr =
83+ String. starts_with ~prefix: " {" maybe_multiattr
84+ && String. ends_with ~suffix: " }" maybe_multiattr
85+ in
7386 match String. split_on_char ':' uri with
74- | [ path ] ->
75- let path = Unix. realpath path
76- and is_multiattr maybe_multiattr =
77- String. starts_with ~prefix: " {" maybe_multiattr
87+ | [ " nixpkgs" ] | [ " pkgs" ] ->
88+ let parse_installables attr_opt =
89+ match attr_opt with
90+ | Some attr ->
91+ if is_multiattr attr
92+ then (
93+ match String. split_on_char '{' attr with
94+ | [ _; rhs ] ->
95+ (match String. split_on_char '}' rhs with
96+ | [ lhs; _ ] -> String. split_on_char ',' lhs
97+ | _ -> [] )
98+ | _ -> [] )
99+ else [ attr ]
100+ | None -> []
78101 in
102+ Nixpkgs
103+ { uri = sprintf_uri_attr_opt " nixpkgs" attr_opt
104+ ; installables = parse_installables attr_opt
105+ }
106+ | [ path ] ->
107+ let path = Unix. realpath path in
79108 (match attr_opt with
80109 | Some attr ->
81110 if is_multiattr attr
@@ -91,15 +120,24 @@ module Util = struct
91120 Error. handle_ns_error " invalid uri or attribute selection syntax: %s\n %!" target
92121 ;;
93122
94- (* * Parse target arguments recursively, returning a list of strings .
123+ (* * Parse target arguments recursively, returning a list of {!type:uri} .
95124 This function is tail recursive optimized. *)
96125 let parse_targets_tr targets =
97126 let rec parse_targets acc = function
98127 | [] -> acc
99- | target :: remaining ->
100- parse_targets (uri_to_string (parse_target target) :: acc) remaining
128+ | target :: remaining -> parse_targets (parse_target target :: acc) remaining
101129 in
102130 parse_targets [] targets
103131 ;;
132+
133+ let combine_installables_tr installables =
134+ let rec combine_installables acc = function
135+ | [] -> Some acc
136+ | Nixpkgs { installables; _ } :: remaining ->
137+ combine_installables (acc @ installables) remaining
138+ | _ -> None
139+ in
140+ combine_installables [] installables
141+ ;;
104142 end
105143end
0 commit comments