Add support for non-integer revisions of entries, comparing them as integer when possible. --- builder/builder.ml | 9 ++++++++- builder/cache.ml | 2 +- builder/cache.mli | 6 +++--- builder/downloader.mli | 2 +- builder/index.ml | 4 ++-- builder/index.mli | 2 +- builder/index_parser.ml | 4 ++-- builder/utils.ml | 7 +++++++ 8 files changed, 25 insertions(+), 11 deletions(-) diff --git a/builder/builder.ml b/builder/builder.ml index d59380b..dcfd437 100644 --- a/builder/builder.ml +++ b/builder/builder.ml @@ -34,6 +34,13 @@ open Printf let () = Random.self_init () let remove_duplicates index = + let compare_revisions rev1 rev2 = + match rev1, rev2 with + | Rev_int n1, Rev_int n2 -> compare n1 n2 + | Rev_string s1, Rev_int n2 -> compare s1 (string_of_int n2) + | Rev_int n1, Rev_string s2 -> compare (string_of_int n1) s2 + | Rev_string s1, Rev_string s2 -> compare s1 s2 + in (* Fill an hash with the higher revision of the available * (name, arch) tuples, so it possible to ignore duplicates, * and versions with a lower revision. @@ -44,7 +51,7 @@ let remove_duplicates index = let id = name, arch in try let rev = Hashtbl.find nseen id in - if revision > rev then + if compare_revisions rev revision > 0 then Hashtbl.replace nseen id revision with Not_found -> Hashtbl.add nseen id revision diff --git a/builder/cache.ml b/builder/cache.ml index e73bcfd..8b63a86 100644 --- a/builder/cache.ml +++ b/builder/cache.ml @@ -40,7 +40,7 @@ let create ~directory = } let cache_of_name t name arch revision = - t.directory // sprintf "%s.%s.%d" name arch revision + t.directory // sprintf "%s.%s.%s" name arch (string_of_revision revision) let is_cached t name arch revision = let filename = cache_of_name t name arch revision in diff --git a/builder/cache.mli b/builder/cache.mli index 7edc670..1ab8ede 100644 --- a/builder/cache.mli +++ b/builder/cache.mli @@ -27,16 +27,16 @@ type t val create : directory:string -> t (** Create the abstract type. *) -val cache_of_name : t -> string -> string -> int -> string +val cache_of_name : t -> string -> string -> Utils.revision -> string (** [cache_of_name t name arch revision] return the filename of the cached file. (Note: It doesn't check if the filename exists, this is just a simple string transformation). *) -val is_cached : t -> string -> string -> int -> bool +val is_cached : t -> string -> string -> Utils.revision -> bool (** [is_cached t name arch revision] return whether the file with specified name, architecture and revision is cached. *) -val print_item_status : t -> header:bool -> (string * string * int) list -> unit +val print_item_status : t -> header:bool -> (string * string * Utils.revision) list -> unit (** [print_item_status t header items] print the status in the cache of the specified items (which are tuples of name, architecture, and revision). diff --git a/builder/downloader.mli b/builder/downloader.mli index 5e3cdaa..11ec498 100644 --- a/builder/downloader.mli +++ b/builder/downloader.mli @@ -35,7 +35,7 @@ type proxy_mode = val create : curl:string -> cache:Cache.t option -> t (** Create the abstract type. *) -val download : t -> ?template:(string*string*int) -> ?progress_bar:bool -> ?proxy:proxy_mode -> uri -> (filename * bool) +val download : t -> ?template:(string*string*Utils.revision) -> ?progress_bar:bool -> ?proxy:proxy_mode -> uri -> (filename * bool) (** Download the URI, returning the downloaded filename and a temporary file flag. The temporary file flag is [true] iff the downloaded file is temporary and should be deleted by the diff --git a/builder/index.ml b/builder/index.ml index 3e8cb85..c59d6dd 100644 --- a/builder/index.ml +++ b/builder/index.ml @@ -32,7 +32,7 @@ and entry = { arch : string; signature_uri : string option; (* deprecated, will be removed in 1.26 *) checksums : Checksums.csum_t list option; - revision : int; + revision : Utils.revision; format : string option; size : int64; compressed_size : int64 option; @@ -86,7 +86,7 @@ let print_entry chan (name, { printable_name = printable_name; (Checksums.string_of_csum_t c) (Checksums.string_of_csum c) ) checksums ); - fp "revision=%d\n" revision; + fp "revision=%s\n" (string_of_revision revision); (match format with | None -> () | Some format -> fp "format=%s\n" format diff --git a/builder/index.mli b/builder/index.mli index 10ed15a..fadcad9 100644 --- a/builder/index.mli +++ b/builder/index.mli @@ -24,7 +24,7 @@ and entry = { arch : string; signature_uri : string option; (* deprecated, will be removed in 1.26 *) checksums : Checksums.csum_t list option; - revision : int; + revision : Utils.revision; format : string option; size : int64; compressed_size : int64 option; diff --git a/builder/index_parser.ml b/builder/index_parser.ml index 845d0e9..2c78fd9 100644 --- a/builder/index_parser.ml +++ b/builder/index_parser.ml @@ -112,9 +112,9 @@ let get_index ~downloader ~sigchecker try Some (List.assoc ("checksum", None) fields) with Not_found -> None in let revision = - try int_of_string (List.assoc ("revision", None) fields) + try Rev_int (int_of_string (List.assoc ("revision", None) fields)) with - | Not_found -> 1 + | Not_found -> Rev_int 1 | Failure "int_of_string" -> eprintf (f_"%s: cannot parse 'revision' field for '%s'\n") prog n; corrupt_file () in diff --git a/builder/utils.ml b/builder/utils.ml index a6628eb..986bf68 100644 --- a/builder/utils.ml +++ b/builder/utils.ml @@ -26,5 +26,12 @@ type gpgkey_type = | No_Key | Fingerprint of string | KeyFile of string +and revision = + | Rev_int of int + | Rev_string of string let quote = Filename.quote + +let string_of_revision = function + | Rev_int n -> string_of_int n + | Rev_string s -> s -- 2.1.0