Improve opam parsing errors & use opam-file-format to extract the version

This commit is contained in:
Jeremie Dimino 2017-05-16 14:47:52 +01:00
parent f2a857f406
commit 60ad83c522
6 changed files with 60 additions and 30 deletions

View File

@ -281,14 +281,18 @@ module Jbuilder_opam_file_format = struct
; file_name : string
}
end
module OpamParser = struct
module OpamBaseParser = struct
open OpamParserTypes
let file fn =
let main _lex _lexbuf fn =
assert (fn = "jbuilder.opam");
{ file_contents = []
; file_name = fn
}
end
module OpamLexer = struct
exception Error of string
let token _ = assert false
end
end
module Glob_lexer = struct

View File

@ -407,14 +407,14 @@ let with_file_out ?(binary=true)fn ~f =
let with_lexbuf_from_file fn ~f =
with_file_in fn ~f:(fun ic ->
let lb = Lexing.from_channel ic in
lb.lex_curr_p <-
{ pos_fname = fn
; pos_lnum = 1
; pos_bol = 0
; pos_cnum = 0
};
f lb)
let lb = Lexing.from_channel ic in
lb.lex_curr_p <-
{ pos_fname = fn
; pos_lnum = 1
; pos_bol = 0
; pos_cnum = 0
};
f lb)
let input_lines =
let rec loop ic acc =

View File

@ -149,18 +149,16 @@ let load ?(extra_ignored_subtrees=Path.Set.empty) () =
match Filename.split_extension fn with
| (pkg, ".opam") when pkg <> "" ->
let version_from_opam_file =
let lines = lines_of_file (Path.relative path fn |> Path.to_string) in
List.find_map lines ~f:(fun s ->
try
Scanf.sscanf s "version: %S" (fun x -> Some x)
with _ ->
None)
in
(pkg,
{ Package. name = pkg
; path
; version_from_opam_file
}) :: acc
let opam = Opam_file.load (Path.relative path fn |> Path.to_string) in
match Opam_file.get_field opam "version" with
| Some (String (_, s)) -> Some s
| _ -> None
in
(pkg,
{ Package. name = pkg
; path
; version_from_opam_file
}) :: acc
| _ -> acc)
in
if String_set.mem "jbuild-ignore" files then

22
src/opam_file.ml Normal file
View File

@ -0,0 +1,22 @@
open Import
open Jbuilder_opam_file_format
open OpamParserTypes
type t = opamfile
let load fn =
with_lexbuf_from_file fn ~f:(fun lb ->
try
OpamBaseParser.main OpamLexer.token lb fn
with
| OpamLexer.Error msg ->
Loc.fail_lex lb "%s" msg
| Parsing.Parse_error ->
Loc.fail_lex lb "Parse error")
let get_field t name =
List.find_map t.file_contents
~f:(function
| Variable (_, var, value) when name = var ->
Some value
| _ -> None)

12
src/opam_file.mli Normal file
View File

@ -0,0 +1,12 @@
(** Parsing and interpretation of opam files *)
open Jbuilder_opam_file_format.OpamParserTypes
(** Type of opam files *)
type t = opamfile
(** Load a file *)
val load : string -> t
(** Extracts a field *)
val get_field : t -> string -> value option

View File

@ -21,7 +21,7 @@ let is_a_source_file fn =
| _ -> true
let make_watermark_map ~name ~version ~commit =
let opam_file = OpamParser.file (name ^ ".opam") in
let opam_file = Opam_file.load (name ^ ".opam") in
let version_num =
if String.is_prefix version ~prefix:"v" then
String.sub version ~pos:1 ~len:(String.length version - 1)
@ -29,13 +29,7 @@ let make_watermark_map ~name ~version ~commit =
version
in
let opam_var name sep =
match
List.find_map opam_file.file_contents
~f:(function
| Variable (_, var, value) when name = var ->
Some value
| _ -> None)
with
match Opam_file.get_field opam_file name with
| None -> Error (sprintf "variable %S not found in opam file" name)
| Some value ->
let err = Error (sprintf "invalid value for variable %S in opam file" name) in