Skip to content

Commit

Permalink
Update opam-file-format to 2.1.5 (#7328)
Browse files Browse the repository at this point in the history
* Update opam-file-format to 2.1.5

Signed-off-by: Marek Kubica <[email protected]>
  • Loading branch information
Leonidas-from-XIV authored Mar 16, 2023
1 parent c0c0acb commit 6490317
Show file tree
Hide file tree
Showing 17 changed files with 1,273 additions and 259 deletions.
86 changes: 56 additions & 30 deletions src/dune_engine/opam_file.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
open Import
open OpamParserTypes
open OpamParserTypes.FullPos

type t = opamfile

Expand All @@ -17,55 +17,79 @@ let parse =
let parse_value = parse_gen OpamBaseParser.value

let get_field t name =
List.find_map t.file_contents ~f:(function
| Variable (_, var, value) when name = var -> Some value
| _ -> None)
List.find_map t.file_contents ~f:(fun value ->
match value.pelem with
| Variable (var, value) when var.pelem = name -> Some value
| _ -> None)

let absolutify_positions ~file_contents t =
let open OpamParserTypes in
let bols = ref [ 0 ] in
String.iteri file_contents ~f:(fun i ch ->
if ch = '\n' then bols := (i + 1) :: !bols);
let bols = Array.of_list (List.rev !bols) in
let map_pos (fname, line, col) = (fname, line, bols.(line - 1) + col) in
let map_pos
{ filename; start = start_line, start_col; stop = stop_line, stop_col } =
let start = (start_line, bols.(start_line - 1) + start_col) in
let stop = (stop_line, bols.(stop_line - 1) + stop_col) in
{ filename; start; stop }
in
let repos pelem pos = { pelem; pos = map_pos pos } in
let rec map_value = function
| Bool (pos, x) -> Bool (map_pos pos, x)
| Int (pos, x) -> Int (map_pos pos, x)
| String (pos, x) -> String (map_pos pos, x)
| Relop (pos, x, y, z) -> Relop (map_pos pos, x, map_value y, map_value z)
| Prefix_relop (pos, x, y) -> Prefix_relop (map_pos pos, x, map_value y)
| Logop (pos, x, y, z) -> Logop (map_pos pos, x, map_value y, map_value z)
| Pfxop (pos, x, y) -> Pfxop (map_pos pos, x, map_value y)
| Ident (pos, x) -> Ident (map_pos pos, x)
| List (pos, x) -> List (map_pos pos, List.map x ~f:map_value)
| Group (pos, x) -> Group (map_pos pos, List.map x ~f:map_value)
| Option (pos, x, y) ->
Option (map_pos pos, map_value x, List.map y ~f:map_value)
| Env_binding (pos, x, y, z) ->
Env_binding (map_pos pos, map_value x, y, map_value z)
| { pelem = Bool x; pos } -> repos (Bool x) pos
| { pelem = Int x; pos } -> repos (Int x) pos
| { pelem = String x; pos } -> repos (String x) pos
| { pelem = Relop (x, y, z); pos } ->
repos (Relop (x, map_value y, map_value z)) pos
| { pelem = Prefix_relop (x, y); pos } ->
repos (Prefix_relop (x, map_value y)) pos
| { pelem = Logop (x, y, z); pos } ->
repos (Logop (x, map_value y, map_value z)) pos
| { pelem = Pfxop (x, y); pos } -> repos (Pfxop (x, map_value y)) pos
| { pelem = Ident x; pos } -> repos (Ident x) pos
| { pelem = List xs; pos } ->
let pelem = List.map xs.pelem ~f:map_value in
let xs = { pelem; pos = map_pos xs.pos } in
repos (List xs) pos
| { pelem = Group xs; pos } ->
let pelem = List.map xs.pelem ~f:map_value in
let xs = { pelem; pos = map_pos xs.pos } in
repos (Group xs) pos
| { pelem = Option (x, ys); pos } ->
let pelem = List.map ys.pelem ~f:map_value in
let ys = { pelem; pos = map_pos ys.pos } in
repos (Option (map_value x, ys)) pos
| { pelem = Env_binding (x, y, z); pos } ->
repos (Env_binding (map_value x, y, map_value z)) pos
in
let rec map_section s =
{ s with section_items = List.map s.section_items ~f:map_item }
let { pelem; pos } = s.section_items in
let pelem = List.map pelem ~f:map_item in
let pos = map_pos pos in
let section_items = { pelem; pos } in
{ s with section_items }
and map_item = function
| Section (pos, s) -> Section (map_pos pos, map_section s)
| Variable (pos, s, v) -> Variable (map_pos pos, s, map_value v)
| { pelem = Section s; pos } -> repos (Section (map_section s)) pos
| { pelem = Variable (s, v); pos } -> repos (Variable (s, map_value v)) pos
in
{ file_contents = List.map t.file_contents ~f:map_item
; file_name = t.file_name
}

let nopos : OpamParserTypes.pos = ("", 0, 0) (* Null position *)
let nopos : pos = { filename = ""; start = (0, 0); stop = (0, 0) }
(* Null position *)

let existing_variables t =
List.fold_left ~init:String.Set.empty t.file_contents ~f:(fun acc l ->
match l with
| Section (_, _) -> acc
| Variable (_, var, _) -> String.Set.add acc var)
match l.pelem with
| Section _ -> acc
| Variable (var, _) -> String.Set.add acc var.pelem)

module Create = struct
let string s = String (nopos, s)
let string s = { pelem = String s; pos = nopos }

let list f xs = List (nopos, List.map ~f xs)
let list f xs =
let elems = { pelem = List.map ~f xs; pos = nopos } in
{ pelem = List elems; pos = nopos }

let string_list xs = list string xs

Expand Down Expand Up @@ -129,7 +153,9 @@ module Create = struct

let of_bindings vars ~file =
let file_contents =
List.map vars ~f:(fun (var, value) -> Variable (nopos, var, value))
List.map vars ~f:(fun (var, value) ->
let var = { pelem = var; pos = nopos } in
{ pelem = Variable (var, value); pos = nopos })
in
let file_name = Path.to_string file in
{ file_contents; file_name }
Expand Down
6 changes: 3 additions & 3 deletions src/dune_engine/opam_file.mli
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

open Import

type value := OpamParserTypes.value
type value := OpamParserTypes.FullPos.value

(** Type of opam files *)
type t = OpamParserTypes.opamfile
type t = OpamParserTypes.FullPos.opamfile

(** Extracts a field *)
val get_field : t -> string -> value option
Expand All @@ -19,7 +19,7 @@ val parse_value : Lexing.lexbuf -> value
(** Replace all [pos] value by a triplet [(fname, line, absolute_offset)] *)
val absolutify_positions : file_contents:string -> t -> t

val nopos : OpamParserTypes.pos
val nopos : OpamParserTypes.FullPos.pos

val existing_variables : t -> String.Set.t

Expand Down
80 changes: 40 additions & 40 deletions src/dune_engine/package.ml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ module Id = struct
end

module Dependency = struct
let nopos pelem = { OpamParserTypes.FullPos.pelem; pos = Opam_file.nopos }

module Op = struct
type t =
| Eq
Expand Down Expand Up @@ -99,13 +101,13 @@ module Dependency = struct
| Lt -> string "Lt"
| Neq -> string "Neq"

let to_relop : t -> OpamParserTypes.relop = function
| Eq -> `Eq
| Gte -> `Geq
| Lte -> `Leq
| Gt -> `Gt
| Lt -> `Lt
| Neq -> `Neq
let to_relop = function
| Eq -> nopos `Eq
| Gte -> nopos `Geq
| Lte -> nopos `Leq
| Gt -> nopos `Gt
| Lt -> nopos `Lt
| Neq -> nopos `Neq

let encode x =
let f (_, op) = equal x op in
Expand All @@ -128,11 +130,13 @@ module Dependency = struct
let+ s = string in
if String.is_prefix s ~prefix:":" then Var (String.drop s 1) else QVar s

let to_opam : t -> OpamParserTypes.value =
let nopos = Opam_file.nopos in
function
| QVar x -> String (nopos, x)
| Var x -> Ident (nopos, x)
let to_opam v =
let value_kind : OpamParserTypes.FullPos.value_kind =
match v with
| QVar x -> String x
| Var x -> Ident x
in
nopos value_kind

let to_dyn = function
| QVar v -> Dyn.String v
Expand Down Expand Up @@ -227,34 +231,30 @@ module Dependency = struct
<|> let+ name = Name.decode in
{ name; constraint_ = None }

let rec opam_constraint : Constraint.t -> OpamParserTypes.value =
let nopos = Opam_file.nopos in
let rec opam_constraint : Constraint.t -> OpamParserTypes.FullPos.value =
let open OpamParserTypes.FullPos in
function
| Bvar v -> Constraint.Var.to_opam v
| Uop (op, x) ->
Prefix_relop (nopos, Op.to_relop op, Constraint.Var.to_opam x)
nopos (Prefix_relop (Op.to_relop op, Constraint.Var.to_opam x))
| Bop (op, x, y) ->
Relop
( nopos
, Op.to_relop op
, Constraint.Var.to_opam x
, Constraint.Var.to_opam y )
nopos
(Relop
(Op.to_relop op, Constraint.Var.to_opam x, Constraint.Var.to_opam y))
| And [ c ] -> opam_constraint c
| And (c :: cs) ->
Logop (nopos, `And, opam_constraint c, opam_constraint (And cs))
nopos (Logop (nopos `And, opam_constraint c, opam_constraint (And cs)))
| Or [ c ] -> opam_constraint c
| Or (c :: cs) ->
Logop (nopos, `Or, opam_constraint c, opam_constraint (And cs))
nopos (Logop (nopos `Or, opam_constraint c, opam_constraint (And cs)))
| And [] | Or [] -> Code_error.raise "opam_constraint" []

let opam_depend : t -> OpamParserTypes.value =
let nopos = Opam_file.nopos in
fun { name; constraint_ } ->
let constraint_ = Option.map ~f:opam_constraint constraint_ in
let pkg : OpamParserTypes.value = String (nopos, Name.to_string name) in
match constraint_ with
| None -> pkg
| Some c -> Option (nopos, pkg, [ c ])
let opam_depend { name; constraint_ } =
let constraint_ = Option.map ~f:opam_constraint constraint_ in
let pkg = nopos (OpamParserTypes.FullPos.String (Name.to_string name)) in
match constraint_ with
| None -> pkg
| Some c -> nopos (OpamParserTypes.FullPos.Option (pkg, nopos [ c ]))

let to_dyn { name; constraint_ } =
let open Dyn in
Expand Down Expand Up @@ -711,8 +711,7 @@ let deprecated_meta_file t name =

let default name dir =
let depends =
let open Dependency in
[ { name = Name.of_string "ocaml"; constraint_ = None }
[ { Dependency.name = Name.of_string "ocaml"; constraint_ = None }
; { name = Name.of_string "dune"; constraint_ = None }
]
in
Expand Down Expand Up @@ -756,21 +755,22 @@ let load_opam_file file name =
let get_one name =
let* opam = opam in
let* value = Opam_file.get_field opam name in
match value with
| String (_, s) -> Some s
match value.pelem with
| String s -> Some s
| _ -> None
in
let get_many name =
let* opam = opam in
let* value = Opam_file.get_field opam name in
match value with
| String (_, s) -> Some [ s ]
| List (_, l) ->
match value.pelem with
| String s -> Some [ s ]
| List l ->
let+ l =
List.fold_left l ~init:(Some []) ~f:(fun acc v ->
List.fold_left l.pelem ~init:(Some [])
~f:(fun acc (v : OpamParserTypes.FullPos.value) ->
let* acc = acc in
match v with
| OpamParserTypes.String (_, s) -> Some (s :: acc)
match v.pelem with
| String s -> Some (s :: acc)
| _ -> None)
in
List.rev l
Expand Down
2 changes: 1 addition & 1 deletion src/dune_engine/package.mli
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ module Dependency : sig
; constraint_ : Constraint.t option
}

val opam_depend : t -> OpamParserTypes.value
val opam_depend : t -> OpamParserTypes.FullPos.value

val to_dyn : t -> Dyn.t

Expand Down
51 changes: 22 additions & 29 deletions src/dune_rules/install.ml
Original file line number Diff line number Diff line change
Expand Up @@ -429,44 +429,37 @@ let gen_install_file entries =
pr "]");
Buffer.contents buf

let pos_of_opam_value : OpamParserTypes.value -> OpamParserTypes.pos = function
| Bool (pos, _) -> pos
| Int (pos, _) -> pos
| String (pos, _) -> pos
| Relop (pos, _, _, _) -> pos
| Prefix_relop (pos, _, _) -> pos
| Logop (pos, _, _, _) -> pos
| Pfxop (pos, _, _) -> pos
| Ident (pos, _) -> pos
| List (pos, _) -> pos
| Group (pos, _) -> pos
| Option (pos, _, _) -> pos
| Env_binding (pos, _, _, _) -> pos

let load_install_file path =
let open OpamParserTypes in
let open OpamParserTypes.FullPos in
let file = Io.Untracked.with_lexbuf_from_file path ~f:Opam_file.parse in
let fail (fname, line, col) msg =
let pos : Lexing.position =
{ pos_fname = fname; pos_lnum = line; pos_bol = 0; pos_cnum = col }
let fail { filename = pos_fname; start; stop } msg =
let position_of_loc (pos_lnum, pos_cnum) =
{ Lexing.pos_fname; pos_lnum; pos_bol = 0; pos_cnum }
in
User_error.raise ~loc:{ start = pos; stop = pos } [ Pp.text msg ]
let start = position_of_loc start in
let stop = position_of_loc stop in
User_error.raise ~loc:{ start; stop } [ Pp.text msg ]
in
List.concat_map file.file_contents ~f:(function
| Variable (pos, section, files) -> (
match Section.of_string section with
| { pelem = Variable (section, files); pos } -> (
match Section.of_string section.pelem with
| None -> fail pos "Unknown install section"
| Some section -> (
match files with
| List (_, l) ->
| { pelem = List l; _ } ->
let install_file src dst =
let src = Path.of_string src in
Entry.of_install_file ~src ~dst ~section
in
List.map l ~f:(function
| String (_, src) -> install_file src None
| Option (_, String (_, src), [ String (_, dst) ]) ->
install_file src (Some dst)
| v -> fail (pos_of_opam_value v) "Invalid value in .install file")
| v -> fail (pos_of_opam_value v) "Invalid value for install section"))
| Section (pos, _) -> fail pos "Sections are not allowed in .install file")
List.map l.pelem ~f:(function
| { pelem = String src; _ } -> install_file src None
| { pelem =
Option
( { pelem = String src; _ }
, { pelem = [ { pelem = String dst; _ } ]; _ } )
; _
} -> install_file src (Some dst)
| { pelem = _; pos } -> fail pos "Invalid value in .install file")
| { pelem = _; pos } -> fail pos "Invalid value for install section"))
| { pelem = Section _; pos } ->
fail pos "Sections are not allowed in .install file")
2 changes: 1 addition & 1 deletion src/dune_rules/opam_create.ml
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ let generate project pkg ~template =
|> Opam_file.Create.of_bindings ~file:(Path.source opam_fname)
in
sprintf "# This file is generated by dune, edit dune-project instead\n%s\n%s"
(OpamPrinter.opamfile generated_fields)
(OpamPrinter.FullPos.opamfile generated_fields)
(match template with
| None -> ""
| Some (_, s) -> s)
Expand Down
1 change: 0 additions & 1 deletion vendor/opam-file-format/src/dune
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
(library
(name opam_file_format)
(modules_without_implementation opamParserTypes)
(wrapped false))

(ocamllex opamLexer)
Expand Down
Loading

0 comments on commit 6490317

Please sign in to comment.