@@ -2,6 +2,7 @@ open Stdune
2
2
open Dune_sexp
3
3
open Dune_util.Action
4
4
open Pform.Macro
5
+ open Pform
5
6
6
7
module Named_targets = struct
7
8
type t = (string * String_with_vars .t ) list
@@ -25,7 +26,7 @@ module Pform = struct
25
26
| C_flags
26
27
| Cxx_flags
27
28
| Cpp_flags
28
- | Target of string (* New variant for named targets *)
29
+ | Target of string (* New variant for named targets *)
29
30
| Ocaml
30
31
| Ocamlc
31
32
| Ocamlopt
@@ -62,8 +63,8 @@ module Pform = struct
62
63
63
64
let compare = compare
64
65
end
65
- type t =
66
- | Var of Var .t
66
+
67
+ type t = Var of Var .t
67
68
end
68
69
69
70
module Diff = struct
@@ -162,7 +163,7 @@ module Env_update = struct
162
163
163
164
type 'a t =
164
165
{ op : Op .t
165
- ; var : Env. Var.t
166
+ ; var : Var .t
166
167
; value : 'a
167
168
}
168
169
@@ -174,28 +175,36 @@ module Env_update = struct
174
175
{ op = other_op ; var = other_var ; value = other_value }
175
176
=
176
177
Op. equal op other_op
177
- && Ordering. is_eq ( Env. Var. compare var other_var)
178
+ && Var. compare var other_var = Ordering. Eq
178
179
&& value_equal value other_value
179
180
;;
180
181
181
182
let to_dyn value_to_dyn { op; var; value } =
182
- Dyn. record
183
- [ " op" , Op. to_dyn op; " var" , Env.Var. to_dyn var; " value" , value_to_dyn value ]
183
+ Dyn. record [ " op" , Op. to_dyn op; " var" , Var. to_dyn var; " value" , value_to_dyn value ]
184
184
;;
185
185
186
186
let decode =
187
187
let open Decoder in
188
188
let env_update_op = enum Op. all in
189
189
let + op, var, value = triple env_update_op string String_with_vars. decode in
190
- { op; var; value }
190
+ { op; var = Var. User_var var ; value }
191
191
;;
192
192
193
193
let encode { op; var; value } =
194
- let op =
194
+ let op_str =
195
195
List. find_map Op. all ~f: (fun (k , v ) -> if Poly. equal v op then Some k else None )
196
196
|> Option. value_exn
197
197
in
198
- List [ atom op; atom var; String_with_vars. encode value ]
198
+ let var_str =
199
+ match var with
200
+ | Var. User_var s -> s
201
+ | Var. Target -> " target"
202
+ | _ ->
203
+ (* Handle other cases or raise an error *)
204
+ Code_error. raise " Action.encode: unsupported variable" []
205
+ in
206
+ Dune_sexp. List
207
+ [ Dune_sexp. atom op_str; Dune_sexp. atom var_str; String_with_vars. encode value ]
199
208
;;
200
209
end
201
210
@@ -232,63 +241,73 @@ type t =
232
241
| When of Slang .blang * t
233
242
| Format_dune_file of String_with_vars .t * String_with_vars .t
234
243
235
- type expansion_context = {
236
- dir : Path .t ;
237
- (* ... other fields ... *)
238
- named_targets : Named_targets .t ;
239
- }
244
+ type expansion_context =
245
+ { dir : Path .t
246
+ ; named_targets : (string * String_with_vars .t ) list
247
+ ; named_deps : (string * Dep_conf .t ) list
248
+ }
249
+
240
250
let is_dev_null t = String_with_vars. is_pform t (Var Dev_null )
241
251
242
252
let translate_to_ignore fn output action =
243
253
if is_dev_null fn
244
254
then Ignore (output, action)
245
255
else Redirect_out (output, fn, Normal , action)
246
256
;;
247
- let expand_target_var ~loc ~named_targets name =
248
- match List. assoc_opt name named_targets with
249
- | Some target ->
250
- (match String_with_vars. text_only target with
251
- | Some text -> text
252
- | None ->
253
- User_error. raise ~loc [
254
- Pp. textf " Named target '%s' contains variables and cannot be expanded here" name
255
- ])
256
- | None ->
257
- User_error. raise ~loc [
258
- Pp. textf " Undefined named target: %s" name;
259
- Pp. text " Available named targets:" ;
260
- Pp. enumerate named_targets ~f: (fun (name , _ ) -> Pp. text name)
261
- ]
262
- ;;
257
+
263
258
let expand_str ~context sw =
264
259
let module S = String_with_vars in
265
-
266
260
match S. text_only sw with
267
261
| Some s -> s
268
262
| None ->
269
263
let expand_var = function
270
- | Pform. Var var ->
271
- if String. equal (Pform.Var. to_string var) " target" then
272
- (match context.named_targets with
273
- | (name , target ) :: _ -> S. to_string target
274
- | [] -> " %{target}" )
275
- else
276
- S. to_string (S. make_var (S. loc sw) (Pform. Var var))
264
+ | Pform. Var (Var. User_var name ) ->
265
+ (* Fixed pattern *)
266
+ (match List. assoc_opt name context.named_targets with
267
+ | Some target -> S. to_string target
268
+ | None ->
269
+ (match List. assoc_opt name context.named_deps with
270
+ | Some dep -> Dep_conf. to_string dep
271
+ | None ->
272
+ User_error. raise
273
+ ~loc: (S. loc sw)
274
+ [ Pp. textf " Undefined variable %%{%s}" name
275
+ ; Pp. text " Available variables:"
276
+ ; Pp. enumerate
277
+ (List. map
278
+ (context.named_targets @ context.named_deps)
279
+ ~f: (fun (n , _ ) -> n))
280
+ ]))
281
+ | Pform. Var Var. Target ->
282
+ (* Correct pattern *)
283
+ (match List. assoc_opt " target" context.named_targets with
284
+ | Some target -> S. to_string target
285
+ | None ->
286
+ User_error. raise ~loc: (S. loc sw) [ Pp. text " Undefined target %{target}" ])
287
+ | Pform. Var other_var ->
288
+ (* Handle other built-in variables *)
289
+ S. to_string (S. make_var (S. loc sw) (Pform. Var other_var))
290
+ | Pform. Macro macro ->
291
+ (* Handle macros *)
292
+ S. to_string (S. make_var (S. loc sw) (Pform. Macro macro))
277
293
in
278
294
S. expand sw ~f: expand_var
279
- ;;
295
+ ;;
280
296
281
297
let create_action targets action =
282
- let named_targets =
298
+ let named_targets =
283
299
List. filter_map targets ~f: (fun (target , _ , name ) ->
284
- Option. map name ~f: (fun n -> ( n, target) ))
300
+ Option. map name ~f: (fun n -> n, target))
285
301
in
286
- { action with
287
- expansion_context = {
288
- dir = Path. root;
289
- named_targets
290
- }
302
+ { action with
303
+ expansion_context =
304
+ { dir = Path. root
305
+ ; named_targets
306
+ ; named_deps = [] (* Will be populated from rule.deps later *)
307
+ }
291
308
}
309
+ ;;
310
+
292
311
let two_or_more decode =
293
312
let open Decoder in
294
313
let + n1 = decode
@@ -360,15 +379,17 @@ let decode_with_accepted_exit_codes =
360
379
361
380
let decode_rule =
362
381
let open Decoder in
363
- let * targets =
364
- repeat (
365
- let * target = String_with_vars. decode in
366
- let * name = optional string in
367
- return (target, () , name)
368
- )
369
- in
370
- let * action = decode_dune_file in
371
- return (create_action targets action)
382
+ let + targets =
383
+ repeat
384
+ (let * target = String_with_vars. decode in
385
+ let * name = optional string in
386
+ return (target, () , name))
387
+ and + deps = field " deps" (Bindings. decode Dep_conf. decode) ~default: Bindings. empty
388
+ and + action = decode_dune_file in
389
+ let rule = create_action targets action in
390
+ { rule with
391
+ expansion_context = { rule.expansion_context with named_deps = Bindings. to_list deps }
392
+ }
372
393
;;
373
394
374
395
let sw = String_with_vars. decode
0 commit comments