[Pkg-ocaml-maint-commits] [SCM] ocaml-debian-formats packaging branch, master, updated. c558195600c4cb91793dc10dcdfe8f321b92482c
Sylvain Le Gall
gildor at debian.org
Thu Aug 4 09:19:35 UTC 2011
The following commit has been merged in the master branch:
commit c558195600c4cb91793dc10dcdfe8f321b92482c
Author: Sylvain Le Gall <gildor at debian.org>
Date: Thu Aug 4 09:19:00 2011 +0000
Add debian/watch parser and a prototype for oasis-db
diff --git a/.gitignore b/.gitignore
index d928205..976b27d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@ _build
setup.data
setup.log
test.byte
+proto_oasis.native
+tmp
diff --git a/_oasis b/_oasis
index f461aa0..433111b 100644
--- a/_oasis
+++ b/_oasis
@@ -5,6 +5,7 @@ Synopsis: Parse debian files
Authors: Sylvain Le Gall
License: LGPL-2.1 with OCaml linking exception
Plugins: DevFiles (0.2), META (0.2), StdFiles (0.2)
+BuildTools: ocamlbuild
Library "debian-formats"
Path: src
@@ -14,12 +15,19 @@ Library "debian-formats"
DF822_parser,
DF822,
DFUtils,
- DFChangelog
+ DFChangelog,
+ DFWatch
BuildDepends: extlib, str, mikmatch_pcre
+Document "api-debian-formats"
+ Title: API reference for DebianFormats
+ InstallDir: $htmldir/debian-formats
+ XOCamlbuildPath: src/
+ XOCamlbuildLibraries: debian-formats
+ BuildTools+: ocamldoc
+
Executable test
Path: test
- BuildTools: ocamlbuild
MainIs: test.ml
Install: false
BuildDepends: debian-formats, oUnit
@@ -29,3 +37,20 @@ Test main
TestTools: test
WorkingDirectory: test/data
+Flag "examples"
+ Description: Build and test examples
+ Default: false
+
+Executable "proto_oasis"
+ Path: examples/proto_oasis
+ MainIs: proto_oasis.ml
+ BuildDepends: debian-formats, curl, pcre, fileutils, archive.lwt, oasis, bz2, lwt.preemptive, threads
+ Install: false
+ Build$: flag(examples)
+ CompiledObject: best
+
+Test "proto_oasis"
+ Command: $proto_oasis
+ TestTools: proto_oasis
+# Run$: flag(examples)
+ Run: false
diff --git a/_tags b/_tags
index 5d64689..6d0c1a0 100644
--- a/_tags
+++ b/_tags
@@ -19,3 +19,4 @@
# OASIS_STOP
"src/DFChangelog.ml": syntax_camlp4o
+"src/DFWatch.ml": syntax_camlp4o
diff --git a/examples/proto_oasis/proto_oasis.ml b/examples/proto_oasis/proto_oasis.ml
new file mode 100644
index 0000000..0539fce
--- /dev/null
+++ b/examples/proto_oasis/proto_oasis.ml
@@ -0,0 +1,493 @@
+
+open Curl
+open Lwt
+
+let with_fn_out fn f =
+ let chn = open_out fn in
+ try
+ let res = f chn in
+ close_out chn;
+ res
+ with e ->
+ close_out chn;
+ raise e
+
+let with_fn_in fn f =
+ let chn = open_in fn in
+ try
+ let res = f chn in
+ close_in chn;
+ res
+ with e ->
+ close_in chn;
+ raise e
+
+let with_curl f =
+ let c = Curl.init () in
+ try
+ let res = f c in
+ Curl.cleanup c;
+ res
+ with e ->
+ Curl.cleanup c;
+ raise e
+
+
+module ODBMessage =
+struct
+ let info ~ctxt fmt =
+ Printf.ksprintf
+ (fun str -> return (prerr_endline ("I: "^str)))
+ fmt
+
+ let debug ~ctxt fmt =
+ Printf.ksprintf
+ (fun str -> return (prerr_endline ("D: "^str)))
+ fmt
+
+ let warning ~ctxt fmt =
+ Printf.ksprintf
+ (fun str -> return (prerr_endline ("W: "^str)))
+ fmt
+end
+
+module S =
+struct
+ let use sqle f =
+ f ()
+
+ let execute () fmt =
+ Printf.ksprintf
+ (fun str ->
+ Printf.eprintf "SQL: %s\n" str;
+ return ())
+ fmt
+
+ let transaction () f =
+ f ()
+end
+
+module ODBOASIS =
+struct
+
+ let from_string ~ctxt ?fn str =
+ let ctxt =
+ {!OASISContext.default with
+ OASISContext.
+ ignore_plugins = true;
+ ignore_unknown_fields = true}
+ in
+ OASISParse.from_string ~ctxt ?fn str
+end
+
+module Context =
+struct
+ type t =
+ {
+ sqle : unit;
+ }
+
+ let default =
+ {
+ sqle = ();
+ }
+end
+
+module ODBCurl =
+struct
+ let download_if_new url fn =
+
+ let fn_etag = fn^".etag" in
+
+ let cur_etag =
+ if Sys.file_exists fn then
+ begin
+ try
+ let chn =
+ open_in fn_etag
+ in
+ let res =
+ String.make (in_channel_length chn) '\000'
+ in
+ really_input chn res 0 (String.length res);
+ close_in chn;
+ Some res
+ with _ ->
+ None
+ end
+ else
+ None
+ in
+
+ let etag_regex =
+ ignore "(*";
+ Pcre.regexp "ETag: \"(.*)\""
+ in
+
+ let write_fun chn str =
+ output_string chn str;
+ String.length str
+ in
+
+ let header_fun str =
+ let () =
+ try
+ let substr =
+ Pcre.exec ~rex:etag_regex str
+ in
+ let etag =
+ Pcre.get_substring substr 1
+ in
+ with_fn_out fn_etag
+ (fun chn ->
+ output_string chn etag)
+
+ with Not_found ->
+ ()
+ in
+ String.length str
+ in
+
+ let fn_tmp =
+ fn^".tmp"
+ in
+ catch
+ (fun () ->
+ with_fn_out fn_tmp
+ (fun chn ->
+ with_curl
+ (fun c ->
+ Curl.set_url c url;
+ Curl.set_followlocation c true;
+ begin
+ match cur_etag with
+ | Some etag ->
+ Curl.set_httpheader c
+ [Printf.sprintf
+ "If-None-Match: \"%s\""
+ etag]
+ | None ->
+ ()
+ end;
+ Curl.set_headerfunction c header_fun;
+ Curl.set_writefunction c (write_fun chn);
+ Curl.perform c;
+ match Curl.get_httpcode c with
+ | 200 ->
+ return true
+ | 304 ->
+ return false
+ | n ->
+ fail
+ (Failure
+ (Printf.sprintf "Unexpected HTTP code %d" n))))
+ >|= fun is_new ->
+ begin
+ if is_new then
+ begin
+ (* TODO: lwt version of this *)
+ FileUtil.rm [fn];
+ FileUtil.mv fn_tmp fn;
+ end
+ else
+ begin
+ FileUtil.rm [fn_tmp]
+ end;
+ is_new
+ end)
+
+ (fun e ->
+ FileUtil.rm [fn; fn_tmp; fn_etag];
+ fail e)
+end
+
+open ExtLib
+open DebianFormats
+
+type uri = string
+type filename = string
+
+type t =
+ {
+ deb_force: bool;
+ deb_mirror: uri;
+ deb_dist: string;
+ deb_distro: string;
+ deb_tmpdir: filename;
+ }
+
+module SetString = Set.Make(String)
+
+let download_uri ~ctxt uri fn =
+ ODBMessage.info ~ctxt "Start downloading '%s'" uri
+ >>= fun () ->
+ ODBCurl.download_if_new uri fn
+ >>= fun res ->
+ ODBMessage.info ~ctxt "End downloading '%s'" uri
+ >|= fun () ->
+ res
+
+let download_uri_exists ~ctxt uri fn =
+ if Sys.file_exists fn then
+ return ()
+ else
+ begin
+ download_uri ~ctxt uri fn
+ >>= fun (is_new : bool) ->
+ return ()
+ end
+
+let find_fn bn fn =
+ ArchiveLwt.Read.create (`Filename fn)
+ >>= fun arch ->
+ begin
+ let rec find lst =
+ try
+ List.find
+ (fun fn ->
+ not (ArchiveLwt.Read.is_directory arch fn) &&
+ FilePath.basename fn = bn)
+ lst
+ with
+ | Not_found when lst <> [] ->
+ let lst =
+ List.fold_left
+ (fun acc fn ->
+ if ArchiveLwt.Read.is_directory arch fn then
+ begin
+ let lst' =
+ List.rev_map
+ (FilePath.concat fn)
+ (Array.to_list (ArchiveLwt.Read.readdir arch fn))
+ in
+ List.rev_append lst' acc
+ end
+ else
+ acc)
+ []
+ lst
+ in
+ find lst
+ | e ->
+ raise e
+ in
+ try
+ begin
+ let fn =
+ find (Array.to_list (ArchiveLwt.Read.readdir arch ""))
+ in
+ ArchiveLwt.Read.content arch fn
+ >|= fun ctnt ->
+ Some ctnt
+ end
+
+ with Not_found ->
+ begin
+ return None
+ end
+ end
+
+(* Update available package list *)
+let update_packages ~ctxt t pkg_lst =
+ Lwt_list.fold_left_s
+ (fun acc e ->
+ try
+ let fn, _, _ =
+ Source.filename e `Tarball
+ in
+ let uri = URI.pool t.deb_mirror e fn in
+ let tarball_fn =
+ FilePath.make_filename
+ [t.deb_tmpdir;
+ "pool";
+ FilePath.add_extension
+ (e.Source.name ^"-"^ (Version.upstream e.Source.version) ^ ".tar")
+ (FilePath.get_extension fn)]
+ in
+ download_uri_exists ~ctxt uri tarball_fn
+ >>= fun () ->
+ find_fn "_oasis" tarball_fn
+ >|=
+ function
+ | Some oasis_ctnt ->
+ let oasis =
+ ODBOASIS.from_string ~ctxt oasis_ctnt
+ in
+ (`Sure (oasis, e)) :: acc
+ | None ->
+ (`Unsure e) :: acc
+
+ with Not_found ->
+ ODBMessage.warning ~ctxt
+ "No tarball found for %s"
+ e.Source.name
+ >|= fun () ->
+ acc)
+ []
+ pkg_lst
+ >>= fun inject_pkg ->
+ (* TODO: fix unsure packages when they have already been dealt with *)
+ S.use ctxt.Context.sqle
+ (fun db ->
+ S.transaction db
+ (fun () ->
+ S.execute db
+ "DELETE FROM distro_pkg WHERE distro = %s" t.deb_distro
+ >>= fun () ->
+ S.execute db
+ "DELETE FROM distro_pkg_unsure WHERE distro = %s" t.deb_distro
+ >>= fun () ->
+ Lwt_list.iter_s
+ (function
+ | `Sure (oasis, e) ->
+ Lwt_list.iter_s
+ (fun (bin, _) ->
+ S.execute db
+ "INSERT INTO distro_pkg(distro, distro_src, distro_bin, pkg, ver) \
+ VALUES (%s, %s, %s, %s, %s)"
+ t.deb_distro
+ e.Source.name
+ bin
+ (oasis.OASISTypes.name)
+ (OASISVersion.string_of_version
+ oasis.OASISTypes.version))
+ e.Source.binary
+ | `Unsure e ->
+ Lwt_list.iter_s
+ (fun (bin, _) ->
+ S.execute db
+ "INSERT INTO distro_pkg_unsure(distro, distro_src, distro_bin, ver) \
+ VALUES (%s, %s, %s, %s)"
+ t.deb_distro
+ e.Source.name
+ bin
+ (Version.upstream e.Source.version))
+ e.Source.binary)
+ inject_pkg))
+
+(** Update watch files *)
+let update_watches ~ctxt t pkg_lst =
+ Lwt_list.iter_s
+ (fun e ->
+ try
+ let fn, _, _ =
+ Source.filename e `Diff
+ in
+ if String.ends_with fn ".debian.tar.gz" then
+ begin
+ let uri = URI.pool t.deb_mirror e fn in
+ let diff_fn =
+ FilePath.make_filename
+ [t.deb_tmpdir;
+ "pool";
+ e.Source.name ^"-"^ (Version.noepoch e.Source.version) ^ ".debian.tar.gz"]
+ in
+ download_uri_exists ~ctxt uri diff_fn
+ >>= fun () ->
+ find_fn "watch" diff_fn
+ >|=
+ function
+ | Some watch_ctnt ->
+ (* TODO: inject *)
+ prerr_endline watch_ctnt
+ | None ->
+ ()
+ end
+ else
+ return ()
+
+ with Not_found ->
+ ODBMessage.debug ~ctxt "No diff found for %s" e.Source.name)
+ pkg_lst
+
+let update ~ctxt t =
+ let fn =
+ Filename.concat t.deb_tmpdir (t.deb_distro^"-sources")
+ in
+ let fn_bz2 =
+ fn^".bz2"
+ in
+
+ download_uri ~ctxt (URI.sources t.deb_mirror t.deb_dist `Main) fn_bz2
+ >>= fun is_new ->
+ (* TODO: build a list of extra packages *)
+ return SetString.empty
+ >>= fun extra_set ->
+ (* TODO: build a package of ignored packages *)
+ return SetString.empty
+ >>= fun ignore_set ->
+ begin
+ if is_new || t.deb_force then
+ begin
+ ODBMessage.info ~ctxt "File '%s' is new" fn_bz2
+ >>= fun () ->
+ (* Decompress Source.bz2 *)
+ Lwt_preemptive.detach
+ (fun () ->
+ with_fn_in fn_bz2
+ (fun chn_bz2 ->
+ with_fn_out fn
+ (fun chn_out ->
+ let chn_bz2' = Bz2.open_in chn_bz2 in
+ try
+ let len = 4096 in
+ let buf = String.make len '\000' in
+ let read () = Bz2.read chn_bz2' buf 0 len in
+ let byte_read = ref (read ()) in
+ while !byte_read = len do
+ output_string chn_out buf;
+ byte_read := read ()
+ done;
+ output chn_out buf 0 !byte_read;
+ Bz2.close_in chn_bz2'
+ with e ->
+ Bz2.close_in chn_bz2';
+ raise e)))
+ ()
+ >>= fun () ->
+ (* Extract ocaml packages from Sources *)
+ Lwt_preemptive.detach
+ (fun () ->
+ with_fn_in
+ fn
+ (fun chn ->
+ let rlst =
+ ref []
+ in
+ let _i: unit list =
+ Source.parse
+ (fun e ->
+ if (e.Source.section = "ocaml" ||
+ SetString.mem e.Source.name extra_set) &&
+ not (SetString.mem e.Source.name ignore_set) then
+ rlst := e :: !rlst)
+ (IO.input_channel chn)
+ in
+ !rlst))
+ ()
+ >>= fun lst ->
+ update_packages ~ctxt t lst
+ >>= fun () ->
+ update_watches ~ctxt t lst
+ end
+ else
+ ODBMessage.info ~ctxt "File '%s' has not changed" fn_bz2
+ end
+
+let () =
+ let () =
+ Curl.global_init CURLINIT_GLOBALNOTHING
+ in
+
+ let default =
+ {
+ deb_force = true;
+ deb_mirror = "http://ftp.debian.org/debian";
+ deb_dist = "unstable";
+ deb_distro = "debian-unstable";
+ deb_tmpdir = "tmp/";
+ }
+ in
+ Lwt_main.run
+ (update ~ctxt:Context.default default);
+ Curl.global_cleanup ()
diff --git a/src/DFWatch.ml b/src/DFWatch.ml
new file mode 100644
index 0000000..850089f
--- /dev/null
+++ b/src/DFWatch.ml
@@ -0,0 +1,37 @@
+
+open DFUtils
+open ExtLib
+
+let parse ch =
+ let rec parse () =
+ try
+ match IO.read_line ch with
+ | RE bol space* "#" ->
+ parse ()
+ | RE bol space* "$" ->
+ parse ()
+ | RE bol space* (_* as str) ->
+ begin
+ let rec cont_line str =
+ if String.ends_with str "\\" then
+ begin
+ (String.rchop str) ^
+ (try
+ cont_line (IO.read_line ch)
+ with IO.No_more_input ->
+ "")
+ end
+ else
+ str
+ in
+ let full_line =
+ cont_line str
+ in
+ full_line :: parse ()
+ end
+ | _ ->
+ assert false
+ with IO.No_more_input ->
+ []
+ in
+ parse ()
diff --git a/src/DebianFormats.ml b/src/DebianFormats.ml
index 547f70c..fe0e9cf 100644
--- a/src/DebianFormats.ml
+++ b/src/DebianFormats.ml
@@ -19,6 +19,11 @@ type version = string
type vpkg = (string * (string * string) option)
type veqpkg = (string * (string * string) option)
type architecture = string
+type md5sum = Digest.t
+type sha1 = string
+type sha256 = string
+type file_size = int64
+type filename = string
(**/**)
let default dflt f1 f2 fld =
@@ -29,6 +34,26 @@ let default dflt f1 f2 fld =
(**/**)
+module Version =
+struct
+
+ let noepoch ver =
+ try
+ snd (String.split ver ":")
+ with Invalid_string ->
+ ver
+
+ let upstream ver =
+ try
+ fst (String.split (noepoch ver) "-")
+ with Invalid_string ->
+ ver
+
+ let is_native ver =
+ String.contains ver '-'
+
+end
+
module Release =
struct
type t =
@@ -42,9 +67,9 @@ struct
architecture: string;
component : string;
description: string;
- md5sums: (string * string * string) list;
- sha1: (string * string * string) list;
- sha256: (string * string * string) list
+ md5sums: (md5sum * file_size * string) list;
+ sha1: (sha1 * file_size * string) list;
+ sha256: (sha256 * file_size * string) list;
}
let parse ch =
@@ -80,22 +105,40 @@ struct
type t =
{
name : name;
- version : version;
- binary : vpkg list;
- build_depends : (vpkg * (bool * architecture) list) list list;
- build_depends_indep : (vpkg * (bool * architecture) list) list list;
- build_conflicts : (vpkg * (bool * architecture) list) list;
+ version : version;
+ binary : vpkg list;
+ build_depends : (vpkg * (bool * architecture) list) list list;
+ build_depends_indep : (vpkg * (bool * architecture) list) list list;
+ build_conflicts : (vpkg * (bool * architecture) list) list;
build_conflicts_indep : (vpkg * (bool * architecture) list) list;
- architecture : architecture list
+ architecture : architecture list;
+ md5sums: (md5sum * file_size * filename) list;
+ sha1: (sha1 * file_size * filename) list;
+ sha256: (sha256 * file_size * filename) list;
+ directory: filename;
+ section: string;
}
let parse_name = parse_package
- let parse_arch s = Str.split (Str.regexp " ") s
+ let parse_arch s = List.filter (( <> ) "") (String.nsplit s " ")
let parse_version s = parse_version s
let parse_binary s = parse_vpkglist parse_constr s
let parse_cnf s = parse_vpkgformula parse_builddeps s
let parse_conj s = parse_vpkglist parse_builddeps s
+ let parse_cksum lst =
+ List.fold_left
+ (fun acc line ->
+ match List.filter ((<>) "") (String.nsplit line " ") with
+ | cksum :: sz :: tl ->
+ (cksum, Int64.of_string sz, (String.concat " " tl))
+ :: acc
+ | _ ->
+ acc)
+ []
+ (List.rev lst)
+
+
(* Relationships between source and binary packages
* http://www.debian.org/doc/debian-policy/ch-relationships.html
* Build-Depends, Build-Depends-Indep, Build-Conflicts, Build-Conflicts-Indep
@@ -103,6 +146,7 @@ struct
let parse_sources_fields par =
let parse_s f field = f (single_line field (List.assoc field par)) in
let parse_m f field = f (String.concat " " (List.assoc field par)) in
+ let parse_l f field = f (List.assoc field par) in
let exec () =
{
name = parse_s parse_name "package";
@@ -113,6 +157,11 @@ struct
build_depends_indep = default [] parse_m parse_cnf "build-depends-indep";
build_conflicts = default [] parse_m parse_conj "build-conflicts";
build_conflicts_indep = default [] parse_m parse_conj "build-conflicts-indep";
+ md5sums = default [] parse_l parse_cksum "files";
+ sha1 = default [] parse_l parse_cksum "checksums-sha1";
+ sha256 = default [] parse_l parse_cksum "checksums-sha256";
+ directory = parse_s String.strip "directory";
+ section = parse_s String.strip "section";
}
in
try
@@ -121,13 +170,56 @@ struct
None (* this package doesn't either have version, arch or name *)
(** parse a debian Sources file from channel *)
- let parse ch =
+ let parse f ch =
let parse_packages =
parse_822_iter parse_sources_fields
in
parse_packages
- (fun i -> i)
+ f
(start_from_channel ch)
+
+ let filename t ft =
+ let test =
+ match ft with
+ | `Dsc ->
+ fun s ->
+ String.ends_with s ".dsc"
+
+ | `Tarball ->
+ fun s ->
+ (not
+ (String.ends_with s ".debian.tar.gz" ||
+ String.ends_with s ".debian.tar.bz2"))
+ &&
+ (String.ends_with s ".tar.gz" ||
+ String.ends_with s ".tar.bz2")
+
+ | `Diff ->
+ fun s ->
+ String.ends_with s ".diff.gz" ||
+ String.ends_with s ".debian.tar.gz" ||
+ String.ends_with s ".debian.tar.bz2"
+
+ | `Other fn ->
+ ( = ) fn
+ in
+ let md5sum, sz, fn =
+ List.find (fun (_, _, fn) -> test fn) t.md5sums
+ in
+ let find acc f fld =
+ try
+ let digest, _, _ =
+ List.find (fun (_, _, fn') -> fn = fn') fld
+ in
+ (f digest) :: acc
+ with Not_found ->
+ acc
+ in
+ let digests = [`MD5Sum md5sum] in
+ let digests = find digests (fun d -> `Sha1 d) t.sha1 in
+ let digests = find digests (fun d -> `Sha256 d) t.sha256 in
+ fn, sz, digests
+
end
module Binary =
@@ -364,3 +456,60 @@ end
module Changelog = DFChangelog
+module Watch = DFWatch
+
+module URI =
+struct
+ type uri = string
+ type mirror = uri
+ type dist = string
+ type section = [`Main | `Contrib | `NonFree]
+
+ (**/**)
+ let concat uri1 uri2 =
+ match String.ends_with uri1 "/", String.starts_with uri2 "/" with
+ | true, true ->
+ uri1 ^ (String.lchop uri2)
+ | false, true
+ | true, false ->
+ uri1 ^ uri2
+ | false, false ->
+ uri1 ^ "/" ^ uri2
+
+ let rec concat_lst =
+ function
+ | uri1 :: uri2 :: tl ->
+ concat_lst ((concat uri1 uri2) :: tl)
+ | [uri] ->
+ uri
+ | [] ->
+ ""
+
+ let string_of_section =
+ function
+ | `Main -> "main"
+ | `Contrib -> "contrib"
+ | `NonFree -> "non-free"
+ (**/**)
+
+
+ let sources mirror dist section =
+ concat_lst
+ [
+ mirror;
+ "dists";
+ dist;
+ string_of_section section;
+ "source/Sources.bz2"
+ ]
+
+ let pool mirror src fn =
+ concat_lst
+ [
+ mirror;
+ src.Source.directory;
+ fn;
+ ]
+
+
+end
diff --git a/test/data/watch.oasis b/test/data/watch.oasis
new file mode 100644
index 0000000..5943512
--- /dev/null
+++ b/test/data/watch.oasis
@@ -0,0 +1,5 @@
+version=3
+http://forge.ocamlcore.org/frs/?group_id=54 .*/oasis-(\d.*)\.tar\.gz
+# Upstream darcs repository:
+# http://forge.ocamlcore.org/anonscm/darcs/oasis/oasis
+# http://forge.ocamlcore.org/scm/browser.php?group_id=54&repo_name=oasis
diff --git a/test/data/watch.obus b/test/data/watch.obus
new file mode 100644
index 0000000..a1a952c
--- /dev/null
+++ b/test/data/watch.obus
@@ -0,0 +1,6 @@
+version=3
+opts="uversionmangle=s/rc/~rc/" \
+http://forge.ocamlcore.org/frs/?group_id=26 .*/obus-(.*)\.tar\.gz
+# Upstream darcs repository:
+# http://darcs.ocamlcore.org/repos/obus
+# http://darcs.ocamlcore.org/cgi-bin/darcsweb.cgi?r=obus
diff --git a/test/test.ml b/test/test.ml
index a7b4228..4708284 100644
--- a/test/test.ml
+++ b/test/test.ml
@@ -50,6 +50,22 @@ let tests =
"0.0.3-1"
e.Changelog.version);
]);
+
+ "Watch">:::
+ (List.map
+ (fun (fn, f) ->
+ fn >::
+ with_fn fn
+ (fun ch ->
+ f (Watch.parse ch)))
+ [
+ "watch.oasis",
+ (fun lst ->
+ List.iter prerr_endline lst);
+ "watch.obus",
+ (fun lst ->
+ List.iter prerr_endline lst);
+ ]);
]
--
ocaml-debian-formats packaging
More information about the Pkg-ocaml-maint-commits
mailing list