diff --git a/CHANGES.md b/CHANGES.md index 14687b4..5ce55b4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ ### Added +- Add new `vcs-base` package meant to extend `vcs` with base-style functionality. - Add `Vcs.find_enclosing_repo_root` helper (#28, @mbarbin). - Add `Vcs.read_dir` helper (#28, @mbarbin). diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..a34ede3 --- /dev/null +++ b/TODO.md @@ -0,0 +1,57 @@ +# Vcs_base + +In this file we document a multi-stages refactoring that is currently in progress in the repository. + +## Targeted end result + +The aim of this refactoring is to remove the base dependency of the `Vcs` library. To achieve this, we will offer two distinct libraries: + +- `Vcs` - a kernel library that can be used with very little dependencies; +- `Vcs_base` - an extension of `Vcs` which will add some functionality related to working with `Base`. + +## Stages + +### Stage 1 - Introducing `Vcs_base` + +- [x] Completed: Oct. 2024 + +In this stage, we create the library `Vcs_base` and setup the way in which this library extends `Vcs`. It exposes the same modules, plus extra functionality, such as: + +- Base style `hash` signatures +- `Comparable.S` signatures for use with Base style containers +- Make some functions return sets instead of lists. + +### Stage 2 - Reducing ppx dependencies in `Vcs` + +- [x] Completed: Oct. 2024 + +Only keep sexp related ppx that have no runtime dependency on `base`, such as `sexplib0` only. + +- Remove `ppx_compare`, `ppx_here`, `ppx_let` dependencies. + +### Stage 3 - Refactor non-raising APIs + +- [ ] Pending + +- Rename `Result` => `Rresult`, introduce a new `Result` one. + +### Stage 4 - Trait implementation use `Result` + +- [ ] Pending + +### Stage 5 - Move `Or_error` module into `Vcs_base`. + +- [ ] Pending + +### Stage 6 - Remove base dependency from `Vcs` + +- [ ] Pending + +Use `vcs/src/import` to make a local mini-stdlib with utils required to remove `base` dependency. + +Do this for the other libraries: + +- [ ] vcs +- [ ] vcs_git_eio +- [ ] vcs_git_provider +- [ ] vcs_git_blocking diff --git a/example/hello_blocking.ml b/example/hello_blocking.ml index 13fa597..da086eb 100644 --- a/example/hello_blocking.ml +++ b/example/hello_blocking.ml @@ -34,7 +34,7 @@ let%expect_test "hello commit" = GitHub Actions environment, where no default user config exists. *) let repo_root = let path = Stdlib.Filename.temp_dir ~temp_dir:(Unix.getcwd ()) "vcs" "test" in - Vcs.For_test.init vcs ~path:(Absolute_path.v path) |> Or_error.ok_exn + Vcs.For_test.init vcs ~path:(Absolute_path.v path) in (* Ok, we are all set, we are now inside a Git repo and we can start using [Vcs]. What we do in this example is simply create a new file and commit it diff --git a/headache.sh b/headache.sh index fa144ae..02e4fdf 100755 --- a/headache.sh +++ b/headache.sh @@ -5,6 +5,8 @@ dirs=( "example" "lib/vcs/src" "lib/vcs/test" + "lib/vcs_base/src" + "lib/vcs_base/test" "lib/vcs_command/src" "lib/vcs_command/test" "lib/vcs_git_blocking/src" diff --git a/lib/vcs/src/author.ml b/lib/vcs/src/author.ml index f5c4dd8..01ff021 100644 --- a/lib/vcs/src/author.ml +++ b/lib/vcs/src/author.ml @@ -20,14 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, equal, hash, sexp_of] -end - -include T +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/author.mli b/lib/vcs/src/author.mli index ca7fcfd..3c92e91 100644 --- a/lib/vcs/src/author.mli +++ b/lib/vcs/src/author.mli @@ -26,8 +26,9 @@ For example: [Author.v "John Doe "]. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t +include Container_key.S with type t := t include Validated_string.S with type t := t val of_user_config : user_name:User_name.t -> user_email:User_email.t -> t diff --git a/lib/vcs/src/branch_name.ml b/lib/vcs/src/branch_name.ml index 6399c33..b3bb763 100644 --- a/lib/vcs/src/branch_name.ml +++ b/lib/vcs/src/branch_name.ml @@ -20,15 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/branch_name.mli b/lib/vcs/src/branch_name.mli index fbc95dd..9d8e161 100644 --- a/lib/vcs/src/branch_name.mli +++ b/lib/vcs/src/branch_name.mli @@ -19,9 +19,9 @@ (*_ and , respectively. *) (*_******************************************************************************) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t (** {1 Some standard names} *) diff --git a/lib/vcs/src/commit_message.ml b/lib/vcs/src/commit_message.ml index 2dd1426..9e58ffa 100644 --- a/lib/vcs/src/commit_message.ml +++ b/lib/vcs/src/commit_message.ml @@ -20,14 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, equal, hash, sexp_of] -end - -include T +include Container_key.String_impl let invariant t = (not (String.is_empty t)) && String.length t <= 512 diff --git a/lib/vcs/src/commit_message.mli b/lib/vcs/src/commit_message.mli index 46e6566..db096a7 100644 --- a/lib/vcs/src/commit_message.mli +++ b/lib/vcs/src/commit_message.mli @@ -25,6 +25,7 @@ sets some arbitrary limits on the length of the message, and mustn't be empty. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/container_key.ml b/lib/vcs/src/container_key.ml new file mode 100644 index 0000000..c80284c --- /dev/null +++ b/lib/vcs/src/container_key.ml @@ -0,0 +1,42 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +open! Import + +module type S = sig + type t + + val compare : t -> t -> int + val equal : t -> t -> bool + val hash : t -> int + val seeded_hash : int -> t -> int + val sexp_of_t : t -> Sexp.t +end + +module String_impl = struct + type t = string + + let compare = compare_string + let equal = equal_string + let hash = hash_string + let seeded_hash = Stdlib.String.seeded_hash + let sexp_of_t = sexp_of_string +end diff --git a/lib/vcs/src/container_key.mli b/lib/vcs/src/container_key.mli new file mode 100644 index 0000000..c98c361 --- /dev/null +++ b/lib/vcs/src/container_key.mli @@ -0,0 +1,32 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +module type S = sig + type t + + val compare : t -> t -> int + val equal : t -> t -> bool + val hash : t -> int + val seeded_hash : int -> t -> int + val sexp_of_t : t -> Sexp.t +end + +module String_impl : S with type t = string diff --git a/lib/vcs/src/dune b/lib/vcs/src/dune index da028f6..3ce729f 100644 --- a/lib/vcs/src/dune +++ b/lib/vcs/src/dune @@ -15,7 +15,7 @@ (instrumentation (backend bisect_ppx)) (lint - (pps ppx_js_style -check-doc-comments)) + (pps ppx_js_style -allow-let-operators -check-doc-comments)) (modules_without_implementation trait_add trait_branch @@ -36,10 +36,6 @@ (preprocess (pps -unused-code-warnings=force - ppx_compare ppx_enumerate - ppx_hash - ppx_here - ppx_let ppx_sexp_conv ppx_sexp_value))) diff --git a/lib/vcs/src/file_contents.ml b/lib/vcs/src/file_contents.ml index 5174673..17a662e 100644 --- a/lib/vcs/src/file_contents.ml +++ b/lib/vcs/src/file_contents.ml @@ -20,14 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, equal, hash, sexp_of] -end - -include T +include Container_key.String_impl let create t = t let to_string t = t diff --git a/lib/vcs/src/file_contents.mli b/lib/vcs/src/file_contents.mli index ba3afd2..cb696cb 100644 --- a/lib/vcs/src/file_contents.mli +++ b/lib/vcs/src/file_contents.mli @@ -22,7 +22,9 @@ (** Representing the raw contents of files on disk. *) (** This is a simple wrapper for the type string, used to increase type safety. *) -type t = private string [@@deriving compare, equal, hash, sexp_of] +type t = private string + +include Container_key.S with type t := t (** [create file_contents] returns a [t] representing the given file contents. *) val create : string -> t diff --git a/lib/vcs/src/for_test.ml b/lib/vcs/src/for_test.ml index e6d2262..1227ecc 100644 --- a/lib/vcs/src/for_test.ml +++ b/lib/vcs/src/for_test.ml @@ -20,16 +20,8 @@ (*******************************************************************************) let init vcs ~path = - let open Or_error.Let_syntax in - let%bind repo_root = Vcs_or_error.init vcs ~path in - let%bind () = - Vcs_or_error.set_user_name vcs ~repo_root ~user_name:(User_name.v "Test User") - in - let%bind () = - Vcs_or_error.set_user_email - vcs - ~repo_root - ~user_email:(User_email.v "test@example.com") - in - return repo_root + let repo_root = Vcs0.init vcs ~path in + Vcs0.set_user_name vcs ~repo_root ~user_name:(User_name.v "Test User"); + Vcs0.set_user_email vcs ~repo_root ~user_email:(User_email.v "test@example.com"); + repo_root ;; diff --git a/lib/vcs/src/for_test.mli b/lib/vcs/src/for_test.mli index 9a9f2a5..71eab67 100644 --- a/lib/vcs/src/for_test.mli +++ b/lib/vcs/src/for_test.mli @@ -26,7 +26,4 @@ your machine. This isolates the test from your local settings, and also makes things work when running in the GitHub Actions environment, where no default user config exists. *) -val init - : [> Trait.config | Trait.init ] Vcs0.t - -> path:Absolute_path.t - -> Repo_root.t Or_error.t +val init : [> Trait.config | Trait.init ] Vcs0.t -> path:Absolute_path.t -> Repo_root.t diff --git a/lib/vcs/src/graph.ml b/lib/vcs/src/graph.ml index ddf8470..648674a 100644 --- a/lib/vcs/src/graph.ml +++ b/lib/vcs/src/graph.ml @@ -22,18 +22,13 @@ open! Import module Node = struct - module T0 = struct - [@@@coverage off] - - type t = int [@@deriving compare, hash] - - [@@@coverage on] - - let sexp_of_t i = Sexp.Atom ("#" ^ Int.to_string_hum i) - end + type t = int - include T0 - include Comparable.Make (T0) + let compare = Int.compare + let equal = Int.equal + let hash = Int.hash + let seeded_hash = Stdlib.Int.seeded_hash + let sexp_of_t i = Sexp.Atom ("#" ^ Int.to_string_hum i) end module Node_kind = struct @@ -51,7 +46,31 @@ module Node_kind = struct ; parent1 : Node.t ; parent2 : Node.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + let equal = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then true + else ( + match a__001_, b__002_ with + | Root _a__003_, Root _b__004_ -> Rev.equal _a__003_.rev _b__004_.rev + | Root _, _ -> false + | _, Root _ -> false + | Commit _a__005_, Commit _b__006_ -> + Stdlib.( && ) + (Rev.equal _a__005_.rev _b__006_.rev) + (Node.equal _a__005_.parent _b__006_.parent) + | Commit _, _ -> false + | _, Commit _ -> false + | Merge _a__007_, Merge _b__008_ -> + Stdlib.( && ) + (Rev.equal _a__007_.rev _b__008_.rev) + (Stdlib.( && ) + (Node.equal _a__007_.parent1 _b__008_.parent1) + (Node.equal _a__007_.parent2 _b__008_.parent2))) + : t -> t -> bool) + ;; end include T @@ -337,7 +356,12 @@ module Descendance = struct | Strict_ancestor | Strict_descendant | Other - [@@deriving equal, enumerate, hash, sexp_of] + [@@deriving enumerate, sexp_of] + + let compare = (Stdlib.compare : t -> t -> int) + let equal = (Stdlib.( = ) : t -> t -> bool) + let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) + let hash = (Stdlib.Hashtbl.hash : t -> int) end let descendance t a b : Descendance.t = @@ -481,4 +505,4 @@ let get_node_exn t ~index = (index :> Node.t) ;; -let node_index _ (node : Node.t) = (node :> int) +let node_index (node : Node.t) = (node :> int) diff --git a/lib/vcs/src/graph.mli b/lib/vcs/src/graph.mli index 79827a9..0a91f5d 100644 --- a/lib/vcs/src/graph.mli +++ b/lib/vcs/src/graph.mli @@ -77,9 +77,9 @@ val set_ref : t -> rev:Rev.t -> ref_kind:Ref_kind.t -> unit function) then you can be certain that [n1] is not a parent of [n2]. *) module Node : sig - type t [@@deriving compare, equal, hash, sexp_of] + type t - include Comparable.S with type t := t + include Container_key.S with type t := t end module Node_kind : sig @@ -94,7 +94,9 @@ module Node_kind : sig ; parent1 : Node.t ; parent2 : Node.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + val equal : t -> t -> bool (** A helper to access the revision of the node itself. This simply returns the first argument of each constructor. *) @@ -190,7 +192,10 @@ module Descendance : sig | Strict_ancestor | Strict_descendant | Other - [@@deriving equal, enumerate, hash, sexp_of] + + val all : t list + + include Container_key.S with type t := t end (** [descendance graph a b] characterizes the descendance relationship between @@ -285,4 +290,4 @@ val summary : t -> Summary.t exposed API isn't enough for your use case. *) val get_node_exn : t -> index:int -> Node.t -val node_index : t -> Node.t -> int +val node_index : Node.t -> int diff --git a/lib/vcs/src/log.ml b/lib/vcs/src/log.ml index 04bccb0..b8d0c1c 100644 --- a/lib/vcs/src/log.ml +++ b/lib/vcs/src/log.ml @@ -35,7 +35,31 @@ module Line = struct ; parent1 : Rev.t ; parent2 : Rev.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + let equal = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then true + else ( + match a__001_, b__002_ with + | Root _a__003_, Root _b__004_ -> Rev.equal _a__003_.rev _b__004_.rev + | Root _, _ -> false + | _, Root _ -> false + | Commit _a__005_, Commit _b__006_ -> + Stdlib.( && ) + (Rev.equal _a__005_.rev _b__006_.rev) + (Rev.equal _a__005_.parent _b__006_.parent) + | Commit _, _ -> false + | _, Commit _ -> false + | Merge _a__007_, Merge _b__008_ -> + Stdlib.( && ) + (Rev.equal _a__007_.rev _b__008_.rev) + (Stdlib.( && ) + (Rev.equal _a__007_.parent1 _b__008_.parent1) + (Rev.equal _a__007_.parent2 _b__008_.parent2))) + : t -> t -> bool) + ;; let rev = function | Commit { rev; _ } | Merge { rev; _ } | Root { rev } -> rev @@ -45,7 +69,9 @@ end module T = struct [@@@coverage off] - type t = Line.t list [@@deriving equal, sexp_of] + type t = Line.t list [@@deriving sexp_of] + + let equal a b = equal_list Line.equal a b end include T diff --git a/lib/vcs/src/log.mli b/lib/vcs/src/log.mli index c229c7e..7f0a6a7 100644 --- a/lib/vcs/src/log.mli +++ b/lib/vcs/src/log.mli @@ -35,12 +35,15 @@ module Line : sig ; parent1 : Rev.t ; parent2 : Rev.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + val equal : t -> t -> bool val rev : t -> Rev.t end -type t = Line.t list [@@deriving equal, sexp_of] +type t = Line.t list [@@deriving sexp_of] + +val equal : t -> t -> bool (** {1 Accessors} *) diff --git a/lib/vcs/src/name_status.ml b/lib/vcs/src/name_status.ml index 4ac043f..14d9450 100644 --- a/lib/vcs/src/name_status.ml +++ b/lib/vcs/src/name_status.ml @@ -40,7 +40,7 @@ * * Changes: This has similarities with the module [Hg.Status]. We added support * for renames, removed support for [Changed_by Rev.t], added [similarity] values - * which are available in Git. The file utils return sets rather than lists. + * which are available in Git. *) open! Import @@ -63,6 +63,38 @@ module Change = struct ; similarity : int } [@@deriving sexp_of] + + let equal = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then true + else ( + match a__001_, b__002_ with + | Added _a__003_, Added _b__004_ -> Path_in_repo.equal _a__003_ _b__004_ + | Added _, _ -> false + | _, Added _ -> false + | Removed _a__005_, Removed _b__006_ -> Path_in_repo.equal _a__005_ _b__006_ + | Removed _, _ -> false + | _, Removed _ -> false + | Modified _a__007_, Modified _b__008_ -> Path_in_repo.equal _a__007_ _b__008_ + | Modified _, _ -> false + | _, Modified _ -> false + | Copied _a__009_, Copied _b__010_ -> + Stdlib.( && ) + (Path_in_repo.equal _a__009_.src _b__010_.src) + (Stdlib.( && ) + (Path_in_repo.equal _a__009_.dst _b__010_.dst) + (equal_int _a__009_.similarity _b__010_.similarity)) + | Copied _, _ -> false + | _, Copied _ -> false + | Renamed _a__011_, Renamed _b__012_ -> + Stdlib.( && ) + (Path_in_repo.equal _a__011_.src _b__012_.src) + (Stdlib.( && ) + (Path_in_repo.equal _a__011_.dst _b__012_.dst) + (equal_int _a__011_.similarity _b__012_.similarity))) + : t -> t -> bool) + ;; end module T = struct @@ -72,40 +104,34 @@ end include T let files_at_src (t : t) = - List.fold - t - ~init:(Set.empty (module Path_in_repo)) - ~f:(fun set change -> - match change with - | Added _ -> set - | Removed path - | Modified path - | Copied { src = path; dst = _; similarity = _ } - | Renamed { src = path; dst = _; similarity = _ } -> Set.add set path) + List.fold t ~init:[] ~f:(fun acc change -> + match change with + | Added _ -> acc + | Removed path + | Modified path + | Copied { src = path; dst = _; similarity = _ } + | Renamed { src = path; dst = _; similarity = _ } -> path :: acc) + |> List.dedup_and_sort ~compare:Path_in_repo.compare ;; let files_at_dst (t : t) = - List.fold - t - ~init:(Set.empty (module Path_in_repo)) - ~f:(fun set change -> - match change with - | Removed _ -> set - | Added path - | Modified path - | Copied { src = _; dst = path; similarity = _ } - | Renamed { src = _; dst = path; similarity = _ } -> Set.add set path) + List.fold t ~init:[] ~f:(fun acc change -> + match change with + | Removed _ -> acc + | Added path + | Modified path + | Copied { src = _; dst = path; similarity = _ } + | Renamed { src = _; dst = path; similarity = _ } -> path :: acc) + |> List.dedup_and_sort ~compare:Path_in_repo.compare ;; let files (t : t) = - List.fold - t - ~init:(Set.empty (module Path_in_repo)) - ~f:(fun set change -> - match change with - | Removed path | Added path | Modified path -> Set.add set path - | Copied { src; dst; similarity = _ } | Renamed { src; dst; similarity = _ } -> - Set.add (Set.add set src) dst) + List.fold t ~init:[] ~f:(fun acc change -> + match change with + | Removed path | Added path | Modified path -> path :: acc + | Copied { src; dst; similarity = _ } | Renamed { src; dst; similarity = _ } -> + src :: dst :: acc) + |> List.dedup_and_sort ~compare:Path_in_repo.compare ;; module Changed = struct @@ -116,5 +142,18 @@ module Changed = struct { src : Rev.t ; dst : Rev.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + let equal = + (fun a__034_ b__035_ -> + if Stdlib.( == ) a__034_ b__035_ + then true + else ( + match a__034_, b__035_ with + | Between _a__036_, Between _b__037_ -> + Stdlib.( && ) + (Rev.equal _a__036_.src _b__037_.src) + (Rev.equal _a__036_.dst _b__037_.dst)) + : t -> t -> bool) + ;; end diff --git a/lib/vcs/src/name_status.mli b/lib/vcs/src/name_status.mli index 30a712c..d51778d 100644 --- a/lib/vcs/src/name_status.mli +++ b/lib/vcs/src/name_status.mli @@ -58,19 +58,21 @@ module Change : sig ; similarity : int } [@@deriving sexp_of] + + val equal : t -> t -> bool end type t = Change.t list [@@deriving sexp_of] (** Returns the set of files that are involved by the changes, either at [src] or [dst]. *) -val files : t -> Set.M(Path_in_repo).t +val files : t -> Path_in_repo.t list (** Returns the set of files that are involved by the changes, that are also present at [src] or [dst] respectively. *) -val files_at_src : t -> Set.M(Path_in_repo).t -val files_at_dst : t -> Set.M(Path_in_repo).t +val files_at_src : t -> Path_in_repo.t list +val files_at_dst : t -> Path_in_repo.t list module Changed : sig (** Specifies which {!type:Name_status.t} we want to compute. *) @@ -79,5 +81,7 @@ module Changed : sig { src : Rev.t ; dst : Rev.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + val equal : t -> t -> bool end diff --git a/lib/vcs/src/num_lines_in_diff.ml b/lib/vcs/src/num_lines_in_diff.ml index d5a2311..75ae21c 100644 --- a/lib/vcs/src/num_lines_in_diff.ml +++ b/lib/vcs/src/num_lines_in_diff.ml @@ -26,7 +26,29 @@ module T = struct { insertions : int ; deletions : int } - [@@deriving compare, equal, sexp_of] + [@@deriving sexp_of] + + let compare = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then 0 + else ( + match compare_int a__001_.insertions b__002_.insertions with + | 0 -> compare_int a__001_.deletions b__002_.deletions + | n -> n) + : t -> t -> int) + ;; + + let equal = + (fun a__003_ b__004_ -> + if Stdlib.( == ) a__003_ b__004_ + then true + else + Stdlib.( && ) + (equal_int a__003_.insertions b__004_.insertions) + (equal_int a__003_.deletions b__004_.deletions) + : t -> t -> bool) + ;; let zero = { insertions = 0; deletions = 0 } diff --git a/lib/vcs/src/num_lines_in_diff.mli b/lib/vcs/src/num_lines_in_diff.mli index 27b3327..0f017d7 100644 --- a/lib/vcs/src/num_lines_in_diff.mli +++ b/lib/vcs/src/num_lines_in_diff.mli @@ -29,8 +29,10 @@ type t = { insertions : int ; deletions : int } -[@@deriving compare, equal, sexp_of] +[@@deriving sexp_of] +val compare : t -> t -> int +val equal : t -> t -> bool val zero : t val ( + ) : t -> t -> t val sum : t list -> t diff --git a/lib/vcs/src/num_status.ml b/lib/vcs/src/num_status.ml index 1910a53..910681b 100644 --- a/lib/vcs/src/num_status.ml +++ b/lib/vcs/src/num_status.ml @@ -30,7 +30,42 @@ module Key = struct { src : Path_in_repo.t ; dst : Path_in_repo.t } - [@@deriving compare, equal, hash, sexp_of] + [@@deriving sexp_of] + + let compare = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then 0 + else ( + match a__001_, b__002_ with + | One_file _a__003_, One_file _b__004_ -> Path_in_repo.compare _a__003_ _b__004_ + | One_file _, _ -> -1 + | _, One_file _ -> 1 + | Two_files _a__005_, Two_files _b__006_ -> + (match Path_in_repo.compare _a__005_.src _b__006_.src with + | 0 -> Path_in_repo.compare _a__005_.dst _b__006_.dst + | n -> n)) + : t -> t -> int) + ;; + + let equal = + (fun a__007_ b__008_ -> + if Stdlib.( == ) a__007_ b__008_ + then true + else ( + match a__007_, b__008_ with + | One_file _a__009_, One_file _b__010_ -> Path_in_repo.equal _a__009_ _b__010_ + | One_file _, _ -> false + | _, One_file _ -> false + | Two_files _a__011_, Two_files _b__012_ -> + Stdlib.( && ) + (Path_in_repo.equal _a__011_.src _b__012_.src) + (Path_in_repo.equal _a__011_.dst _b__012_.dst)) + : t -> t -> bool) + ;; + + let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) + let hash = (Stdlib.Hashtbl.hash : t -> int) end module Change = struct @@ -41,6 +76,20 @@ module Change = struct | Num_lines_in_diff of Num_lines_in_diff.t | Binary_file [@@deriving sexp_of] + + let equal = + (fun a__008_ b__009_ -> + if Stdlib.( == ) a__008_ b__009_ + then true + else ( + match a__008_, b__009_ with + | Num_lines_in_diff _a__010_, Num_lines_in_diff _b__011_ -> + Num_lines_in_diff.equal _a__010_ _b__011_ + | Num_lines_in_diff _, _ -> false + | _, Num_lines_in_diff _ -> false + | Binary_file, Binary_file -> true) + : t -> t -> bool) + ;; end type t = @@ -48,6 +97,17 @@ module Change = struct ; num_stat : Num_stat.t } [@@deriving sexp_of] + + let equal = + (fun a__014_ b__015_ -> + if Stdlib.( == ) a__014_ b__015_ + then true + else + Stdlib.( && ) + (Key.equal a__014_.key b__015_.key) + (Num_stat.equal a__014_.num_stat b__015_.num_stat) + : t -> t -> bool) + ;; end module T = struct @@ -64,5 +124,18 @@ module Changed = struct { src : Rev.t ; dst : Rev.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + let equal = + (fun a__022_ b__023_ -> + if Stdlib.( == ) a__022_ b__023_ + then true + else ( + match a__022_, b__023_ with + | Between _a__024_, Between _b__025_ -> + Stdlib.( && ) + (Rev.equal _a__024_.src _b__025_.src) + (Rev.equal _a__024_.dst _b__025_.dst)) + : t -> t -> bool) + ;; end diff --git a/lib/vcs/src/num_status.mli b/lib/vcs/src/num_status.mli index 52d5cde..6b6f861 100644 --- a/lib/vcs/src/num_status.mli +++ b/lib/vcs/src/num_status.mli @@ -26,7 +26,8 @@ module Key : sig { src : Path_in_repo.t ; dst : Path_in_repo.t } - [@@deriving compare, equal, hash, sexp_of] + + include Container_key.S with type t := t end module Change : sig @@ -39,6 +40,8 @@ module Change : sig | Num_lines_in_diff of Num_lines_in_diff.t | Binary_file [@@deriving sexp_of] + + val equal : t -> t -> bool end type t = @@ -46,6 +49,8 @@ module Change : sig ; num_stat : Num_stat.t } [@@deriving sexp_of] + + val equal : t -> t -> bool end type t = Change.t list [@@deriving sexp_of] @@ -57,5 +62,7 @@ module Changed : sig { src : Rev.t ; dst : Rev.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + val equal : t -> t -> bool end diff --git a/lib/vcs/src/path_in_repo.ml b/lib/vcs/src/path_in_repo.ml index d0a3bc4..8999af7 100644 --- a/lib/vcs/src/path_in_repo.ml +++ b/lib/vcs/src/path_in_repo.ml @@ -44,15 +44,7 @@ *) open! Import - -module T = struct - [@@@coverage off] - - type t = Relative_path.t [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Relative_path let root = Relative_path.empty let to_fpath = Relative_path.to_fpath diff --git a/lib/vcs/src/path_in_repo.mli b/lib/vcs/src/path_in_repo.mli index c81ffe0..92fe7a8 100644 --- a/lib/vcs/src/path_in_repo.mli +++ b/lib/vcs/src/path_in_repo.mli @@ -47,9 +47,9 @@ This is a wrapper for a [Fpath.t] relative to the repo root, used for accrued type safety. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t val root : t diff --git a/lib/vcs/src/platform.ml b/lib/vcs/src/platform.ml index ea3faf0..3a85405 100644 --- a/lib/vcs/src/platform.ml +++ b/lib/vcs/src/platform.ml @@ -21,14 +21,12 @@ open! Import -module T = struct - [@@@coverage off] +type t = GitHub [@@deriving enumerate, sexp_of] - type t = GitHub [@@deriving compare, enumerate, hash, sexp_of] -end - -include T -include Comparable.Make (T) +let compare = (Stdlib.compare : t -> t -> int) +let equal = (Stdlib.( = ) : t -> t -> bool) +let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) +let hash = (Stdlib.Hashtbl.hash : t -> int) let to_string = function | GitHub -> "GitHub" diff --git a/lib/vcs/src/platform.mli b/lib/vcs/src/platform.mli index abf4b94..f82fe2e 100644 --- a/lib/vcs/src/platform.mli +++ b/lib/vcs/src/platform.mli @@ -25,9 +25,11 @@ This is used to implement convenient utils, such as utils to clone repositories from GitHub, etc. *) -type t = GitHub [@@deriving compare, equal, enumerate, hash, sexp_of] +type t = GitHub -include Comparable.S with type t := t +include Container_key.S with type t := t + +val all : t list (** A string representing the platform, using the styled capitalization of the variant constructor. For example, ["GitHub"] is typically spelled with an diff --git a/lib/vcs/src/ref_kind.ml b/lib/vcs/src/ref_kind.ml index 497961f..61b0888 100644 --- a/lib/vcs/src/ref_kind.ml +++ b/lib/vcs/src/ref_kind.ml @@ -21,19 +21,62 @@ open! Import -module T = struct - [@@@coverage off] +[@@@coverage off] - type t = - | Local_branch of { branch_name : Branch_name.t } - | Remote_branch of { remote_branch_name : Remote_branch_name.t } - | Tag of { tag_name : Tag_name.t } - | Other of { name : string } - [@@deriving compare, hash, sexp_of] -end +type t = + | Local_branch of { branch_name : Branch_name.t } + | Remote_branch of { remote_branch_name : Remote_branch_name.t } + | Tag of { tag_name : Tag_name.t } + | Other of { name : string } +[@@deriving sexp_of] -include T -include Comparable.Make (T) +let compare = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then 0 + else ( + match a__001_, b__002_ with + | Local_branch _a__003_, Local_branch _b__004_ -> + Branch_name.compare _a__003_.branch_name _b__004_.branch_name + | Local_branch _, _ -> -1 + | _, Local_branch _ -> 1 + | Remote_branch _a__005_, Remote_branch _b__006_ -> + Remote_branch_name.compare + _a__005_.remote_branch_name + _b__006_.remote_branch_name + | Remote_branch _, _ -> -1 + | _, Remote_branch _ -> 1 + | Tag _a__007_, Tag _b__008_ -> + Tag_name.compare _a__007_.tag_name _b__008_.tag_name + | Tag _, _ -> -1 + | _, Tag _ -> 1 + | Other _a__009_, Other _b__010_ -> compare_string _a__009_.name _b__010_.name) + : t -> t -> int) +;; + +let equal = + (fun a__011_ b__012_ -> + if Stdlib.( == ) a__011_ b__012_ + then true + else ( + match a__011_, b__012_ with + | Local_branch _a__013_, Local_branch _b__014_ -> + Branch_name.equal _a__013_.branch_name _b__014_.branch_name + | Local_branch _, _ -> false + | _, Local_branch _ -> false + | Remote_branch _a__015_, Remote_branch _b__016_ -> + Remote_branch_name.equal _a__015_.remote_branch_name _b__016_.remote_branch_name + | Remote_branch _, _ -> false + | _, Remote_branch _ -> false + | Tag _a__017_, Tag _b__018_ -> Tag_name.equal _a__017_.tag_name _b__018_.tag_name + | Tag _, _ -> false + | _, Tag _ -> false + | Other _a__019_, Other _b__020_ -> equal_string _a__019_.name _b__020_.name) + : t -> t -> bool) +;; + +let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) +let hash = (Stdlib.Hashtbl.hash : t -> int) let to_string = function | Local_branch { branch_name } -> "refs/heads/" ^ Branch_name.to_string branch_name diff --git a/lib/vcs/src/ref_kind.mli b/lib/vcs/src/ref_kind.mli index 73f155e..d8bccdf 100644 --- a/lib/vcs/src/ref_kind.mli +++ b/lib/vcs/src/ref_kind.mli @@ -24,8 +24,7 @@ type t = | Remote_branch of { remote_branch_name : Remote_branch_name.t } | Tag of { tag_name : Tag_name.t } | Other of { name : string } -[@@deriving compare, equal, hash, sexp_of] -include Comparable.S with type t := t +include Container_key.S with type t := t val to_string : t -> string diff --git a/lib/vcs/src/refs.ml b/lib/vcs/src/refs.ml index cbdbeac..ce7cdf4 100644 --- a/lib/vcs/src/refs.ml +++ b/lib/vcs/src/refs.ml @@ -28,13 +28,26 @@ module Line = struct { rev : Rev.t ; ref_kind : Ref_kind.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + let equal = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then true + else + Stdlib.( && ) + (Rev.equal a__001_.rev b__002_.rev) + (Ref_kind.equal a__001_.ref_kind b__002_.ref_kind) + : t -> t -> bool) + ;; end module T = struct [@@@coverage off] - type t = Line.t list [@@deriving equal, sexp_of] + type t = Line.t list [@@deriving sexp_of] + + let equal a b = equal_list Line.equal a b end include T @@ -43,13 +56,14 @@ let tags (t : t) = List.filter_map t ~f:(function | { rev = _; ref_kind = Tag { tag_name } } -> Some tag_name | _ -> None) - |> Set.of_list (module Tag_name) + |> List.sort ~compare:Tag_name.compare ;; let local_branches (t : t) = List.filter_map t ~f:(function | { rev = _; ref_kind = Local_branch { branch_name } } -> Some branch_name | _ -> None) + |> List.sort ~compare:Branch_name.compare ;; let remote_branches (t : t) = @@ -57,11 +71,5 @@ let remote_branches (t : t) = | { rev = _; ref_kind = Remote_branch { remote_branch_name } } -> Some remote_branch_name | _ -> None) -;; - -let to_map (t : t) = - List.fold - t - ~init:(Map.empty (module Ref_kind)) - ~f:(fun acc { rev; ref_kind } -> Map.add_exn acc ~key:ref_kind ~data:rev) + |> List.sort ~compare:Remote_branch_name.compare ;; diff --git a/lib/vcs/src/refs.mli b/lib/vcs/src/refs.mli index 0e23bc9..e53c66a 100644 --- a/lib/vcs/src/refs.mli +++ b/lib/vcs/src/refs.mli @@ -33,21 +33,17 @@ module Line : sig { rev : Rev.t ; ref_kind : Ref_kind.t } - [@@deriving equal, sexp_of] + [@@deriving sexp_of] + + val equal : t -> t -> bool end -type t = Line.t list [@@deriving equal, sexp_of] +type t = Line.t list [@@deriving sexp_of] + +val equal : t -> t -> bool (** {1 Accessors} *) -val tags : t -> Set.M(Tag_name).t +val tags : t -> Tag_name.t list val local_branches : t -> Branch_name.t list val remote_branches : t -> Remote_branch_name.t list - -(** To lookup the revision of references (branch, tag, etc.), it is usually - quite cheap to get all refs using {!val:Vcs.refs}, turn the result into a - map with this function, and use the map for the lookups rather than trying - to run one git command per lookup. You may also use - {!val:Vcs.Graph.find_ref} if you build the complete graph with - {!val:Vcs.graph}. *) -val to_map : t -> Rev.t Map.M(Ref_kind).t diff --git a/lib/vcs/src/remote_branch_name.ml b/lib/vcs/src/remote_branch_name.ml index ad56ef1..65f476d 100644 --- a/lib/vcs/src/remote_branch_name.ml +++ b/lib/vcs/src/remote_branch_name.ml @@ -21,18 +21,40 @@ open! Import -module T = struct - [@@@coverage off] +[@@@coverage off] - type t = - { remote_name : Remote_name.t - ; branch_name : Branch_name.t - } - [@@deriving compare, hash, sexp_of] -end +type t = + { remote_name : Remote_name.t + ; branch_name : Branch_name.t + } +[@@deriving sexp_of] -include T -include Comparable.Make (T) +let compare = + (fun a__001_ b__002_ -> + if Stdlib.( == ) a__001_ b__002_ + then 0 + else ( + match Remote_name.compare a__001_.remote_name b__002_.remote_name with + | 0 -> Branch_name.compare a__001_.branch_name b__002_.branch_name + | n -> n) + : t -> t -> int) +;; + +let equal = + (fun a__003_ b__004_ -> + if Stdlib.( == ) a__003_ b__004_ + then true + else + Stdlib.( && ) + (Remote_name.equal a__003_.remote_name b__004_.remote_name) + (Branch_name.equal a__003_.branch_name b__004_.branch_name) + : t -> t -> bool) +;; + +[@@@coverage on] + +let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) +let hash = (Stdlib.Hashtbl.hash : t -> int) let to_string { remote_name; branch_name } = Printf.sprintf @@ -45,9 +67,10 @@ let of_string str = match String.lsplit2 str ~on:'/' with | None -> Error (`Msg (Printf.sprintf "%S: invalid remote_branch_name" str)) | Some (remote, branch) -> - let%bind.Result remote_name = Remote_name.of_string remote in - let%map.Result branch_name = Branch_name.of_string branch in - { remote_name; branch_name } + let ( let* ) = Stdlib.Result.bind in + let* remote_name = Remote_name.of_string remote in + let* branch_name = Branch_name.of_string branch in + Result.return { remote_name; branch_name } ;; let v str = diff --git a/lib/vcs/src/remote_branch_name.mli b/lib/vcs/src/remote_branch_name.mli index 810c0a6..d10aa45 100644 --- a/lib/vcs/src/remote_branch_name.mli +++ b/lib/vcs/src/remote_branch_name.mli @@ -23,7 +23,6 @@ type t = { remote_name : Remote_name.t ; branch_name : Branch_name.t } -[@@deriving compare, equal, hash, sexp_of] -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/remote_name.ml b/lib/vcs/src/remote_name.ml index 43364ff..dc6f18b 100644 --- a/lib/vcs/src/remote_name.ml +++ b/lib/vcs/src/remote_name.ml @@ -20,15 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/remote_name.mli b/lib/vcs/src/remote_name.mli index d19a2ea..416fd54 100644 --- a/lib/vcs/src/remote_name.mli +++ b/lib/vcs/src/remote_name.mli @@ -19,9 +19,9 @@ (*_ and , respectively. *) (*_******************************************************************************) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t (** {1 Some standard names} *) diff --git a/lib/vcs/src/repo_name.ml b/lib/vcs/src/repo_name.ml index 771c443..9773791 100644 --- a/lib/vcs/src/repo_name.ml +++ b/lib/vcs/src/repo_name.ml @@ -20,15 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/repo_name.mli b/lib/vcs/src/repo_name.mli index 80a27e0..76f2ac2 100644 --- a/lib/vcs/src/repo_name.mli +++ b/lib/vcs/src/repo_name.mli @@ -36,7 +36,7 @@ repository. For this, the GitHub {!module:User_handle} must be added. See {!module:Url} for a complete url to a repository. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/repo_root.ml b/lib/vcs/src/repo_root.ml index 9a5d0d0..ed993ec 100644 --- a/lib/vcs/src/repo_root.ml +++ b/lib/vcs/src/repo_root.ml @@ -43,15 +43,7 @@ *) open! Import - -module T = struct - [@@@coverage off] - - type t = Absolute_path.t [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Absolute_path let of_absolute_path t = t let to_absolute_path t = t diff --git a/lib/vcs/src/repo_root.mli b/lib/vcs/src/repo_root.mli index 21f1279..f4ebcb8 100644 --- a/lib/vcs/src/repo_root.mli +++ b/lib/vcs/src/repo_root.mli @@ -47,8 +47,9 @@ This is a wrapper around [Absolute_path.t] to increase type safety. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t +include Container_key.S with type t := t include Validated_string.S with type t := t val of_absolute_path : Absolute_path.t -> t diff --git a/lib/vcs/src/rev.ml b/lib/vcs/src/rev.ml index c8bcbfb..02464e7 100644 --- a/lib/vcs/src/rev.ml +++ b/lib/vcs/src/rev.ml @@ -20,13 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - type t = string [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Container_key.String_impl let invariant t = Int.(String.length t = 40) diff --git a/lib/vcs/src/rev.mli b/lib/vcs/src/rev.mli index 0368e0b..15861f0 100644 --- a/lib/vcs/src/rev.mli +++ b/lib/vcs/src/rev.mli @@ -23,7 +23,7 @@ repository. The name was inherited from Mercurial. For git, this correspond to the commit-hash. In both systems, these are 40-chars hashes. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/tag_name.ml b/lib/vcs/src/tag_name.ml index ae1380e..ef06593 100644 --- a/lib/vcs/src/tag_name.ml +++ b/lib/vcs/src/tag_name.ml @@ -20,15 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/tag_name.mli b/lib/vcs/src/tag_name.mli index aa48f18..afa6f41 100644 --- a/lib/vcs/src/tag_name.mli +++ b/lib/vcs/src/tag_name.mli @@ -19,7 +19,7 @@ (*_ and , respectively. *) (*_******************************************************************************) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/url.ml b/lib/vcs/src/url.ml index 2bb78ae..a04f99a 100644 --- a/lib/vcs/src/url.ml +++ b/lib/vcs/src/url.ml @@ -22,16 +22,20 @@ open! Import module Protocol = struct - module T = struct - [@@@coverage off] + [@@@coverage off] + + type t = + | Ssh + | Https + [@@deriving enumerate, sexp_of] - type t = - | Ssh - | Https - [@@deriving compare, equal, enumerate, hash, sexp_of] - end + let compare = (Stdlib.compare : t -> t -> int) + let equal = (Stdlib.( = ) : t -> t -> bool) - include T + [@@@coverage on] + + let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) + let hash = (Stdlib.Hashtbl.hash : t -> int) let to_string t ~(platform : Platform.t) = match platform, t with @@ -40,19 +44,52 @@ module Protocol = struct ;; end -module T = struct - [@@@coverage off] +[@@@coverage off] - type t = - { platform : Platform.t - ; protocol : Protocol.t - ; user_handle : User_handle.t - ; repo_name : Repo_name.t - } - [@@deriving compare, equal, hash, sexp_of] -end +type t = + { platform : Platform.t + ; protocol : Protocol.t + ; user_handle : User_handle.t + ; repo_name : Repo_name.t + } +[@@deriving sexp_of] + +let compare = + (fun a__005_ b__006_ -> + if Stdlib.( == ) a__005_ b__006_ + then 0 + else ( + match Platform.compare a__005_.platform b__006_.platform with + | 0 -> + (match Protocol.compare a__005_.protocol b__006_.protocol with + | 0 -> + (match User_handle.compare a__005_.user_handle b__006_.user_handle with + | 0 -> Repo_name.compare a__005_.repo_name b__006_.repo_name + | n -> n) + | n -> n) + | n -> n) + : t -> t -> int) +;; + +let equal = + (fun a__007_ b__008_ -> + if Stdlib.( == ) a__007_ b__008_ + then true + else + Stdlib.( && ) + (Platform.equal a__007_.platform b__008_.platform) + (Stdlib.( && ) + (Protocol.equal a__007_.protocol b__008_.protocol) + (Stdlib.( && ) + (User_handle.equal a__007_.user_handle b__008_.user_handle) + (Repo_name.equal a__007_.repo_name b__008_.repo_name))) + : t -> t -> bool) +;; + +[@@@coverage on] -include T +let seeded_hash = (Stdlib.Hashtbl.seeded_hash : int -> t -> int) +let hash = (Stdlib.Hashtbl.hash : t -> int) let to_string t = let { platform; protocol; user_handle; repo_name } = t in @@ -63,35 +100,33 @@ let to_string t = ;; let of_string (s : string) : (t, [ `Msg of string ]) Result.t = - let open Or_error.Let_syntax in + let ( let* ) = Stdlib.Result.bind in match List.find_map Platform.all ~f:(fun platform -> List.find_map Protocol.all ~f:(fun protocol -> let prefix = Protocol.to_string protocol ~platform in Option.map (String.chop_prefix s ~prefix) ~f:(fun rest -> - let%bind user_handle, rest = - String.lsplit2 rest ~on:'/' - |> Result.of_option ~error:(Error.of_string "missing user handle") + let* user_handle, rest = + String.lsplit2 rest ~on:'/' |> Result.of_option ~error:"missing user handle" in - let%bind repo_name = + let* repo_name = String.chop_suffix rest ~suffix:".git" - |> Result.of_option ~error:(Error.of_string "missing .git suffix") + |> Result.of_option ~error:"missing .git suffix" in - let%bind user_handle = + let* user_handle = match User_handle.of_string user_handle with | Ok _ as ok -> ok - | Error (`Msg m) -> Or_error.error_string m + | Error (`Msg m) -> Error m in - let%bind repo_name = + let* repo_name = match Repo_name.of_string repo_name with | Ok _ as ok -> ok - | Error (`Msg m) -> Or_error.error_string m + | Error (`Msg m) -> Error m in - return { platform; protocol; user_handle; repo_name }))) + Result.return { platform; protocol; user_handle; repo_name }))) with | Some (Ok _ as ok) -> ok - | Some (Error e) -> - Error (`Msg (Printf.sprintf "%S: invalid url. %s" s (Error.to_string_hum e))) + | Some (Error e) -> Error (`Msg (Printf.sprintf "%S: invalid url. %s" s e)) | None -> Error (`Msg (Printf.sprintf "%S: invalid url" s)) ;; diff --git a/lib/vcs/src/url.mli b/lib/vcs/src/url.mli index fea27d3..cb136c9 100644 --- a/lib/vcs/src/url.mli +++ b/lib/vcs/src/url.mli @@ -31,7 +31,10 @@ module Protocol : sig type t = | Ssh | Https - [@@deriving compare, equal, enumerate, hash, sexp_of] + + include Container_key.S with type t := t + + val all : t list end type t = @@ -40,7 +43,8 @@ type t = ; user_handle : User_handle.t ; repo_name : Repo_name.t } -[@@deriving compare, equal, hash, sexp_of] + +include Container_key.S with type t := t (** Create a complete string suitable for use with git commands, such as remote add, clone, etc. *) diff --git a/lib/vcs/src/user_email.ml b/lib/vcs/src/user_email.ml index d3d372f..c74f972 100644 --- a/lib/vcs/src/user_email.ml +++ b/lib/vcs/src/user_email.ml @@ -20,14 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, equal, hash, sexp_of] -end - -include T +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/user_email.mli b/lib/vcs/src/user_email.mli index 35f078b..afa6f41 100644 --- a/lib/vcs/src/user_email.mli +++ b/lib/vcs/src/user_email.mli @@ -19,6 +19,7 @@ (*_ and , respectively. *) (*_******************************************************************************) -type t [@@deriving compare, equal, hash, sexp_of] +type t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/user_handle.ml b/lib/vcs/src/user_handle.ml index 5e78365..a2c6549 100644 --- a/lib/vcs/src/user_handle.ml +++ b/lib/vcs/src/user_handle.ml @@ -20,15 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, hash, sexp_of] -end - -include T -include Comparable.Make (T) +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/user_handle.mli b/lib/vcs/src/user_handle.mli index b0f0a21..a5376e2 100644 --- a/lib/vcs/src/user_handle.mli +++ b/lib/vcs/src/user_handle.mli @@ -32,7 +32,7 @@ which includes the full first name and last name, including spaces etc. This module is part of the [Vcs] library for convenience. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t -include Comparable.S with type t := t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/user_name.ml b/lib/vcs/src/user_name.ml index dba29c6..76a83ba 100644 --- a/lib/vcs/src/user_name.ml +++ b/lib/vcs/src/user_name.ml @@ -20,14 +20,7 @@ (*******************************************************************************) open! Import - -module T = struct - [@@@coverage off] - - type t = string [@@deriving compare, equal, hash, sexp_of] -end - -include T +include Container_key.String_impl let invariant t = (not (String.is_empty t)) diff --git a/lib/vcs/src/user_name.mli b/lib/vcs/src/user_name.mli index 29be187..94bc3e7 100644 --- a/lib/vcs/src/user_name.mli +++ b/lib/vcs/src/user_name.mli @@ -25,6 +25,7 @@ [User_name.v "John Doe"]. This is not to be conflated with the {!module:User_handle}, which are used as GitHub logins and other contexts. *) -type t [@@deriving compare, equal, hash, sexp_of] +type t +include Container_key.S with type t := t include Validated_string.S with type t := t diff --git a/lib/vcs/src/vcs0.ml b/lib/vcs/src/vcs0.ml index 8d07c74..dc0c8b1 100644 --- a/lib/vcs/src/vcs0.ml +++ b/lib/vcs/src/vcs0.ml @@ -24,6 +24,7 @@ open! Import type 'a t = 'a Provider.t let create provider = provider +let ( let* ) = Stdlib.Result.bind let of_result ~step = function | Ok r -> r @@ -106,7 +107,7 @@ let current_revision (Provider.T { t; handler }) ~repo_root = let commit (Provider.T { t; handler }) ~repo_root ~commit_message = let module R = (val Provider.Handler.lookup handler ~trait:Trait.Rev_parse) in let module C = (val Provider.Handler.lookup handler ~trait:Trait.Commit) in - (let%bind.Or_error () = C.commit t ~repo_root ~commit_message in + (let* () = C.commit t ~repo_root ~commit_message in R.current_revision t ~repo_root) |> of_result ~step:(lazy [%sexp "Vcs.commit", { repo_root : Repo_root.t }]) ;; @@ -167,12 +168,11 @@ let graph (Provider.T { t; handler }) ~repo_root = let module L = (val Provider.Handler.lookup handler ~trait:Trait.Log) in let module R = (val Provider.Handler.lookup handler ~trait:Trait.Refs) in let graph = Graph.create () in - (let open Or_error.Let_syntax in - let%bind log = L.all t ~repo_root in - let%bind refs = R.show_ref t ~repo_root in + (let* log = L.all t ~repo_root in + let* refs = R.show_ref t ~repo_root in Graph.add_nodes graph ~log; Graph.set_refs graph ~refs; - return graph) + Result.return graph) |> of_result ~step:(lazy [%sexp "Vcs.graph", { repo_root : Repo_root.t }]) ;; diff --git a/lib/vcs/test/dune b/lib/vcs/test/dune index e2010bd..6b514fc 100644 --- a/lib/vcs/test/dune +++ b/lib/vcs/test/dune @@ -28,6 +28,7 @@ fpath fpath-sexp0 vcs + vcs_base vcs_git_provider) (instrumentation (backend bisect_ppx)) diff --git a/lib/vcs/test/test__graph.ml b/lib/vcs/test/test__graph.ml index 7cd4e9c..154f4e5 100644 --- a/lib/vcs/test/test__graph.ml +++ b/lib/vcs/test/test__graph.ml @@ -557,7 +557,7 @@ let ancestors graph node = then loop acc to_visit else loop (Set.add acc node) (Vcs.Graph.prepend_parents graph node to_visit) in - loop (Set.empty (module Vcs.Graph.Node)) [ node ] + loop (Set.empty (module Vcs_base.Vcs.Graph.Node)) [ node ] ;; let%expect_test "debug graph" = @@ -681,7 +681,7 @@ let%expect_test "debug graph" = print_ancestors r4; [%expect {| (#0 #1 #2 #3 #4) |}]; (* Low level int indexing. *) - let node_index node = print_s [%sexp (Vcs.Graph.node_index graph node : int)] in + let node_index node = print_s [%sexp (Vcs.Graph.node_index node : int)] in node_index (node ~rev:r1); [%expect {| 0 |}]; node_index (node ~rev:r4); diff --git a/lib/vcs/test/test__name_status.ml b/lib/vcs/test/test__name_status.ml index 911a7d7..07b5d29 100644 --- a/lib/vcs/test/test__name_status.ml +++ b/lib/vcs/test/test__name_status.ml @@ -26,8 +26,14 @@ let%expect_test "parse_exn" = let contents = Eio.Path.load path in let lines = String.split_lines contents in let name_status = Vcs_git_provider.Name_status.parse_lines_exn ~lines in - let files_at_src = Vcs.Name_status.files_at_src name_status in - let files_at_dst = Vcs.Name_status.files_at_dst name_status in + let files_at_src = + Vcs.Name_status.files_at_src name_status + |> Set.of_list (module Vcs_base.Vcs.Path_in_repo) + in + let files_at_dst = + Vcs.Name_status.files_at_dst name_status + |> Set.of_list (module Vcs_base.Vcs.Path_in_repo) + in print_s [%sexp (Set.diff files_at_dst files_at_src : Set.M(Vcs.Path_in_repo).t)]; [%expect {| @@ -63,7 +69,7 @@ let%expect_test "files" = (dst new_renamed_file) (similarity 100))) |}]; let files = Vcs.Name_status.files name_status in - print_s [%sexp (files : Set.M(Vcs.Path_in_repo).t)]; + print_s [%sexp (files : Vcs.Path_in_repo.t list)]; [%expect {| (added_file @@ -73,12 +79,18 @@ let%expect_test "files" = original_copied_file original_renamed_file removed_file) |}]; - let files_at_src = Vcs.Name_status.files_at_src name_status in + let files_at_src = + Vcs.Name_status.files_at_src name_status + |> Set.of_list (module Vcs_base.Vcs.Path_in_repo) + in print_s [%sexp (files_at_src : Set.M(Vcs.Path_in_repo).t)]; [%expect {| (modified_file original_copied_file original_renamed_file removed_file) |}]; - let files_at_dst = Vcs.Name_status.files_at_dst name_status in + let files_at_dst = + Vcs.Name_status.files_at_dst name_status + |> Set.of_list (module Vcs_base.Vcs.Path_in_repo) + in print_s [%sexp (files_at_dst : Set.M(Vcs.Path_in_repo).t)]; [%expect {| (added_file modified_file new_copied_file new_renamed_file) |}]; diff --git a/lib/vcs/test/test__platform.ml b/lib/vcs/test/test__platform.ml index 54169e9..5a1b256 100644 --- a/lib/vcs/test/test__platform.ml +++ b/lib/vcs/test/test__platform.ml @@ -24,3 +24,17 @@ let%expect_test "to_string_hum" = [%expect {| GitHub |}]; () ;; + +let%expect_test "hash" = + List.iter Vcs.Platform.all ~f:(fun t -> + let stdlib_hash = Stdlib.Hashtbl.hash t in + let vcs_hash = Vcs.Platform.hash t in + print_s [%sexp (t : Vcs.Platform.t), { stdlib_hash : int; vcs_hash : int }]); + [%expect + {| + (GitHub ( + (stdlib_hash 129913994) + (vcs_hash 129913994))) + |}]; + () +;; diff --git a/lib/vcs_base/src/author.ml b/lib/vcs_base/src/author.ml new file mode 100644 index 0000000..6fdb8e6 --- /dev/null +++ b/lib/vcs_base/src/author.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Author +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/author.mli b/lib/vcs_base/src/author.mli new file mode 100644 index 0000000..85bffb4 --- /dev/null +++ b/lib/vcs_base/src/author.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Author.t [@@deriving hash] + +include module type of Vcs.Author with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/branch_name.ml b/lib/vcs_base/src/branch_name.ml new file mode 100644 index 0000000..6a94f50 --- /dev/null +++ b/lib/vcs_base/src/branch_name.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Branch_name +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/branch_name.mli b/lib/vcs_base/src/branch_name.mli new file mode 100644 index 0000000..17c220c --- /dev/null +++ b/lib/vcs_base/src/branch_name.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Branch_name.t [@@deriving hash] + +include module type of Vcs.Branch_name with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/commit_message.ml b/lib/vcs_base/src/commit_message.ml new file mode 100644 index 0000000..6e2a3c4 --- /dev/null +++ b/lib/vcs_base/src/commit_message.ml @@ -0,0 +1,26 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Commit_message +include T + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/commit_message.mli b/lib/vcs_base/src/commit_message.mli new file mode 100644 index 0000000..c083b40 --- /dev/null +++ b/lib/vcs_base/src/commit_message.mli @@ -0,0 +1,24 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Commit_message.t [@@deriving hash] + +include module type of Vcs.Commit_message with type t := t diff --git a/lib/vcs_base/src/file_contents.ml b/lib/vcs_base/src/file_contents.ml new file mode 100644 index 0000000..317596e --- /dev/null +++ b/lib/vcs_base/src/file_contents.ml @@ -0,0 +1,26 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.File_contents +include T + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/file_contents.mli b/lib/vcs_base/src/file_contents.mli new file mode 100644 index 0000000..21ef823 --- /dev/null +++ b/lib/vcs_base/src/file_contents.mli @@ -0,0 +1,24 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.File_contents.t [@@deriving hash] + +include module type of Vcs.File_contents with type t := t diff --git a/lib/vcs_base/src/graph.ml b/lib/vcs_base/src/graph.ml new file mode 100644 index 0000000..0b09012 --- /dev/null +++ b/lib/vcs_base/src/graph.ml @@ -0,0 +1,51 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module Node = struct + module T = Vcs.Graph.Node + include T + include Comparable.Make (T) + + let hash t = Int.hash (Vcs.Graph.node_index t) + let hash_fold_t state t = Int.hash_fold_t state (Vcs.Graph.node_index t) +end + +module Descendance = struct + module T0 = struct + type t = Vcs.Graph.Descendance.t = + | Same_node + | Strict_ancestor + | Strict_descendant + | Other + [@@deriving hash] + end + + include ( + Vcs.Graph.Descendance : module type of Vcs.Graph.Descendance with type t := T0.t) + + include T0 +end + +include ( + Vcs.Graph : + module type of Vcs.Graph + with module Node := Vcs.Graph.Node + and module Descendance := Vcs.Graph.Descendance) diff --git a/lib/vcs_base/src/graph.mli b/lib/vcs_base/src/graph.mli new file mode 100644 index 0000000..0d4b2d4 --- /dev/null +++ b/lib/vcs_base/src/graph.mli @@ -0,0 +1,43 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +module Node : sig + type t = Vcs.Graph.Node.t [@@deriving hash] + + include module type of Vcs.Graph.Node with type t := t + include Comparable.S with type t := t +end + +module Descendance : sig + type t = Vcs.Graph.Descendance.t = + | Same_node + | Strict_ancestor + | Strict_descendant + | Other + [@@deriving hash] + + include module type of Vcs.Graph.Descendance with type t := t +end + +include + module type of Vcs.Graph + with module Node := Vcs.Graph.Node + and module Descendance := Vcs.Graph.Descendance diff --git a/lib/vcs_base/src/name_status.ml b/lib/vcs_base/src/name_status.ml new file mode 100644 index 0000000..d4230a3 --- /dev/null +++ b/lib/vcs_base/src/name_status.ml @@ -0,0 +1,64 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module Change = struct + type t = Vcs.Name_status.Change.t = + | Added of Path_in_repo.t + | Removed of Path_in_repo.t + | Modified of Path_in_repo.t + | Copied of + { src : Path_in_repo.t + ; dst : Path_in_repo.t + ; similarity : int + } + | Renamed of + { src : Path_in_repo.t + ; dst : Path_in_repo.t + ; similarity : int + } + + include ( + Vcs.Name_status.Change : module type of Vcs.Name_status.Change with type t := t) +end + +module Changed = struct + type t = Vcs.Name_status.Changed.t = + | Between of + { src : Rev.t + ; dst : Rev.t + } + + include ( + Vcs.Name_status.Changed : module type of Vcs.Name_status.Changed with type t := t) +end + +type t = Change.t list + +include ( + Vcs.Name_status : + module type of Vcs.Name_status + with type t := t + and module Change := Vcs.Name_status.Change + and module Changed := Vcs.Name_status.Changed) + +let files t = Set.of_list (module Path_in_repo) (Vcs.Name_status.files t) +let files_at_src t = Set.of_list (module Path_in_repo) (Vcs.Name_status.files_at_src t) +let files_at_dst t = Set.of_list (module Path_in_repo) (Vcs.Name_status.files_at_dst t) diff --git a/lib/vcs_base/src/name_status.mli b/lib/vcs_base/src/name_status.mli new file mode 100644 index 0000000..59ca212 --- /dev/null +++ b/lib/vcs_base/src/name_status.mli @@ -0,0 +1,61 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +module Change : sig + type t = Vcs.Name_status.Change.t = + | Added of Path_in_repo.t + | Removed of Path_in_repo.t + | Modified of Path_in_repo.t + | Copied of + { src : Path_in_repo.t + ; dst : Path_in_repo.t + ; similarity : int + } + | Renamed of + { src : Path_in_repo.t + ; dst : Path_in_repo.t + ; similarity : int + } + + include module type of Vcs.Name_status.Change with type t := t +end + +module Changed : sig + type t = Vcs.Name_status.Changed.t = + | Between of + { src : Rev.t + ; dst : Rev.t + } + + include module type of Vcs.Name_status.Changed with type t := t +end + +type t = Change.t list + +include + module type of Vcs.Name_status + with type t := t + and module Change := Vcs.Name_status.Change + and module Changed := Vcs.Name_status.Changed + +val files : t -> Set.M(Path_in_repo).t +val files_at_src : t -> Set.M(Path_in_repo).t +val files_at_dst : t -> Set.M(Path_in_repo).t diff --git a/lib/vcs_base/src/num_lines_in_diff.ml b/lib/vcs_base/src/num_lines_in_diff.ml new file mode 100644 index 0000000..f8d897c --- /dev/null +++ b/lib/vcs_base/src/num_lines_in_diff.ml @@ -0,0 +1,36 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +include Vcs.Num_lines_in_diff + +let to_string_hum { insertions; deletions } = + let int_hum i = Int.to_string_hum ~delimiter:',' i in + match + [ (if insertions > 0 then Some ("+" ^ int_hum insertions) else None) + ; (if deletions > 0 then Some ("-" ^ int_hum deletions) else None) + ] + |> List.filter_opt + with + | [] -> "0" + | [ hd ] -> hd + | [ a; b ] -> a ^ ", " ^ b + | _ :: _ :: _ :: _ -> assert false +;; diff --git a/lib/vcs_base/src/num_lines_in_diff.mli b/lib/vcs_base/src/num_lines_in_diff.mli new file mode 100644 index 0000000..6b0dadf --- /dev/null +++ b/lib/vcs_base/src/num_lines_in_diff.mli @@ -0,0 +1,31 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Num_lines_in_diff.t = + { insertions : int + ; deletions : int + } + +include module type of Vcs.Num_lines_in_diff with type t := t + +(** Returns a short string suitable for human consumption. + Some examples: [["0"; "+100"; "-15"; "+1,999, -13,898"]]. *) +val to_string_hum : t -> string diff --git a/lib/vcs_base/src/path_in_repo.ml b/lib/vcs_base/src/path_in_repo.ml new file mode 100644 index 0000000..c96cd5a --- /dev/null +++ b/lib/vcs_base/src/path_in_repo.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Path_in_repo +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/path_in_repo.mli b/lib/vcs_base/src/path_in_repo.mli new file mode 100644 index 0000000..109ed83 --- /dev/null +++ b/lib/vcs_base/src/path_in_repo.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Path_in_repo.t [@@deriving hash] + +include module type of Vcs.Path_in_repo with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/platform.ml b/lib/vcs_base/src/platform.ml new file mode 100644 index 0000000..c052a4e --- /dev/null +++ b/lib/vcs_base/src/platform.ml @@ -0,0 +1,32 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = struct + module T0 = struct + type t = Vcs.Platform.t = GitHub [@@deriving hash] + end + + include (Vcs.Platform : module type of Vcs.Platform with type t := T0.t) + include T0 +end + +include T +include Comparable.Make (T) diff --git a/lib/vcs_base/src/platform.mli b/lib/vcs_base/src/platform.mli new file mode 100644 index 0000000..62127bf --- /dev/null +++ b/lib/vcs_base/src/platform.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Platform.t = GitHub [@@deriving hash] + +include module type of Vcs.Platform with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/ref_kind.ml b/lib/vcs_base/src/ref_kind.ml new file mode 100644 index 0000000..3e01038 --- /dev/null +++ b/lib/vcs_base/src/ref_kind.ml @@ -0,0 +1,37 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = struct + module T0 = struct + type t = Vcs.Ref_kind.t = + | Local_branch of { branch_name : Branch_name.t } + | Remote_branch of { remote_branch_name : Remote_branch_name.t } + | Tag of { tag_name : Tag_name.t } + | Other of { name : string } + [@@deriving hash] + end + + include (Vcs.Ref_kind : module type of Vcs.Ref_kind with type t := T0.t) + include T0 +end + +include T +include Comparable.Make (T) diff --git a/lib/vcs_base/src/ref_kind.mli b/lib/vcs_base/src/ref_kind.mli new file mode 100644 index 0000000..9cdbbbc --- /dev/null +++ b/lib/vcs_base/src/ref_kind.mli @@ -0,0 +1,30 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Ref_kind.t = + | Local_branch of { branch_name : Branch_name.t } + | Remote_branch of { remote_branch_name : Remote_branch_name.t } + | Tag of { tag_name : Tag_name.t } + | Other of { name : string } +[@@deriving hash] + +include module type of Vcs.Ref_kind with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/refs.ml b/lib/vcs_base/src/refs.ml new file mode 100644 index 0000000..4001844 --- /dev/null +++ b/lib/vcs_base/src/refs.ml @@ -0,0 +1,48 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module Line = struct + type t = Vcs.Refs.Line.t = + { rev : Rev.t + ; ref_kind : Ref_kind.t + } + + include (Vcs.Refs.Line : module type of Vcs.Refs.Line with type t := t) +end + +type t = Line.t list + +include ( + Vcs.Refs : module type of Vcs.Refs with type t := t and module Line := Vcs.Refs.Line) + +let tags t = Set.of_list (module Tag_name) (Vcs.Refs.tags t) +let local_branches t = Set.of_list (module Branch_name) (Vcs.Refs.local_branches t) + +let remote_branches t = + Set.of_list (module Remote_branch_name) (Vcs.Refs.remote_branches t) +;; + +let to_map (t : t) = + List.fold + t + ~init:(Map.empty (module Ref_kind)) + ~f:(fun acc { rev; ref_kind } -> Map.add_exn acc ~key:ref_kind ~data:rev) +;; diff --git a/lib/vcs_base/src/refs.mli b/lib/vcs_base/src/refs.mli new file mode 100644 index 0000000..1244fc9 --- /dev/null +++ b/lib/vcs_base/src/refs.mli @@ -0,0 +1,45 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +module Line : sig + type t = Vcs.Refs.Line.t = + { rev : Rev.t + ; ref_kind : Ref_kind.t + } + + include module type of Vcs.Refs.Line with type t := t +end + +type t = Line.t list + +include module type of Vcs.Refs with type t := t and module Line := Vcs.Refs.Line + +val tags : t -> Set.M(Tag_name).t +val local_branches : t -> Set.M(Branch_name).t +val remote_branches : t -> Set.M(Remote_branch_name).t + +(** To lookup the revision of references (branch, tag, etc.), it is usually + quite cheap to get all refs using {!val:Vcs.refs}, turn the result into a + map with this function, and use the map for the lookups rather than trying + to run one git command per lookup. You may also use + {!val:Vcs.Graph.find_ref} if you build the complete graph with + {!val:Vcs.graph}. *) +val to_map : t -> Rev.t Map.M(Ref_kind).t diff --git a/lib/vcs_base/src/remote_branch_name.ml b/lib/vcs_base/src/remote_branch_name.ml new file mode 100644 index 0000000..b7f7c69 --- /dev/null +++ b/lib/vcs_base/src/remote_branch_name.ml @@ -0,0 +1,38 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = struct + module T0 = struct + type t = Vcs.Remote_branch_name.t = + { remote_name : Remote_name.t + ; branch_name : Branch_name.t + } + [@@deriving hash] + end + + include ( + Vcs.Remote_branch_name : module type of Vcs.Remote_branch_name with type t := T0.t) + + include T0 +end + +include T +include Comparable.Make (T) diff --git a/lib/vcs_base/src/remote_branch_name.mli b/lib/vcs_base/src/remote_branch_name.mli new file mode 100644 index 0000000..c38b160 --- /dev/null +++ b/lib/vcs_base/src/remote_branch_name.mli @@ -0,0 +1,29 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Remote_branch_name.t = + { remote_name : Remote_name.t + ; branch_name : Branch_name.t + } +[@@deriving hash] + +include module type of Vcs.Remote_branch_name with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/remote_name.ml b/lib/vcs_base/src/remote_name.ml new file mode 100644 index 0000000..d27fbc6 --- /dev/null +++ b/lib/vcs_base/src/remote_name.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Remote_name +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/remote_name.mli b/lib/vcs_base/src/remote_name.mli new file mode 100644 index 0000000..53bce6c --- /dev/null +++ b/lib/vcs_base/src/remote_name.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Remote_name.t [@@deriving hash] + +include module type of Vcs.Remote_name with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/repo_name.ml b/lib/vcs_base/src/repo_name.ml new file mode 100644 index 0000000..004663f --- /dev/null +++ b/lib/vcs_base/src/repo_name.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Repo_name +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/repo_name.mli b/lib/vcs_base/src/repo_name.mli new file mode 100644 index 0000000..44becd8 --- /dev/null +++ b/lib/vcs_base/src/repo_name.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Repo_name.t [@@deriving hash] + +include module type of Vcs.Repo_name with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/repo_root.ml b/lib/vcs_base/src/repo_root.ml new file mode 100644 index 0000000..9b1461e --- /dev/null +++ b/lib/vcs_base/src/repo_root.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Repo_root +include T +include Comparable.Make (T) + +let hash t = Absolute_path.hash (T.to_absolute_path t) +let hash_fold_t state t = Absolute_path.hash_fold_t state (T.to_absolute_path t) diff --git a/lib/vcs_base/src/repo_root.mli b/lib/vcs_base/src/repo_root.mli new file mode 100644 index 0000000..d672ddb --- /dev/null +++ b/lib/vcs_base/src/repo_root.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Repo_root.t [@@deriving hash] + +include module type of Vcs.Repo_root with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/rev.ml b/lib/vcs_base/src/rev.ml new file mode 100644 index 0000000..20a2c4b --- /dev/null +++ b/lib/vcs_base/src/rev.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Rev +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/rev.mli b/lib/vcs_base/src/rev.mli new file mode 100644 index 0000000..3d863fa --- /dev/null +++ b/lib/vcs_base/src/rev.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Rev.t [@@deriving hash] + +include module type of Vcs.Rev with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/tag_name.ml b/lib/vcs_base/src/tag_name.ml new file mode 100644 index 0000000..85f7886 --- /dev/null +++ b/lib/vcs_base/src/tag_name.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.Tag_name +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/tag_name.mli b/lib/vcs_base/src/tag_name.mli new file mode 100644 index 0000000..a56f43c --- /dev/null +++ b/lib/vcs_base/src/tag_name.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.Tag_name.t [@@deriving hash] + +include module type of Vcs.Tag_name with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/url.ml b/lib/vcs_base/src/url.ml new file mode 100644 index 0000000..e97cda1 --- /dev/null +++ b/lib/vcs_base/src/url.ml @@ -0,0 +1,47 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module Protocol = struct + module T0 = struct + type t = Vcs.Url.Protocol.t = + | Ssh + | Https + [@@deriving hash] + end + + include (Vcs.Url.Protocol : module type of Vcs.Url.Protocol with type t := T0.t) + include T0 +end + +module T0 = struct + type t = Vcs.Url.t = + { platform : Platform.t + ; protocol : Protocol.t + ; user_handle : User_handle.t + ; repo_name : Repo_name.t + } + [@@deriving hash] +end + +include ( + Vcs.Url : module type of Vcs.Url with type t := T0.t and module Protocol := Protocol) + +include T0 diff --git a/lib/vcs_base/src/url.mli b/lib/vcs_base/src/url.mli new file mode 100644 index 0000000..e10d51e --- /dev/null +++ b/lib/vcs_base/src/url.mli @@ -0,0 +1,39 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +module Protocol : sig + type t = Vcs.Url.Protocol.t = + | Ssh + | Https + [@@deriving hash] + + include module type of Vcs.Url.Protocol with type t := t +end + +type t = Vcs.Url.t = + { platform : Platform.t + ; protocol : Protocol.t + ; user_handle : User_handle.t + ; repo_name : Repo_name.t + } +[@@deriving hash] + +include module type of Vcs.Url with type t := t and module Protocol := Protocol diff --git a/lib/vcs_base/src/user_email.ml b/lib/vcs_base/src/user_email.ml new file mode 100644 index 0000000..be42e48 --- /dev/null +++ b/lib/vcs_base/src/user_email.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.User_email +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/user_email.mli b/lib/vcs_base/src/user_email.mli new file mode 100644 index 0000000..6f14a66 --- /dev/null +++ b/lib/vcs_base/src/user_email.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.User_email.t [@@deriving hash] + +include module type of Vcs.User_email with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/user_handle.ml b/lib/vcs_base/src/user_handle.ml new file mode 100644 index 0000000..69a4ce2 --- /dev/null +++ b/lib/vcs_base/src/user_handle.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.User_handle +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/user_handle.mli b/lib/vcs_base/src/user_handle.mli new file mode 100644 index 0000000..9928c49 --- /dev/null +++ b/lib/vcs_base/src/user_handle.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.User_handle.t [@@deriving hash] + +include module type of Vcs.User_handle with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/user_name.ml b/lib/vcs_base/src/user_name.ml new file mode 100644 index 0000000..4c91fa2 --- /dev/null +++ b/lib/vcs_base/src/user_name.ml @@ -0,0 +1,27 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module T = Vcs.User_name +include T +include Comparable.Make (T) + +let hash t = String.hash (T.to_string t) +let hash_fold_t state t = String.hash_fold_t state (T.to_string t) diff --git a/lib/vcs_base/src/user_name.mli b/lib/vcs_base/src/user_name.mli new file mode 100644 index 0000000..d981b2c --- /dev/null +++ b/lib/vcs_base/src/user_name.mli @@ -0,0 +1,25 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +type t = Vcs.User_name.t [@@deriving hash] + +include module type of Vcs.User_name with type t := t +include Comparable.S with type t := t diff --git a/lib/vcs_base/src/vcs_base.ml b/lib/vcs_base/src/vcs_base.ml new file mode 100644 index 0000000..a709d21 --- /dev/null +++ b/lib/vcs_base/src/vcs_base.ml @@ -0,0 +1,69 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +module Vcs = struct + module Author = Author + module Branch_name = Branch_name + module Commit_message = Commit_message + module File_contents = File_contents + module Graph = Graph + module Name_status = Name_status + module Num_lines_in_diff = Num_lines_in_diff + module Path_in_repo = Path_in_repo + module Platform = Platform + module Ref_kind = Ref_kind + module Refs = Refs + module Remote_branch_name = Remote_branch_name + module Remote_name = Remote_name + module Repo_name = Repo_name + module Repo_root = Repo_root + module Rev = Rev + module Tag_name = Tag_name + module Url = Url + module User_email = User_email + module User_handle = User_handle + module User_name = User_name + + include ( + Vcs : + module type of Vcs + with module Author := Vcs.Author + and module Branch_name := Vcs.Branch_name + and module Commit_message := Vcs.Commit_message + and module File_contents := Vcs.File_contents + and module Graph := Vcs.Graph + and module Name_status := Vcs.Name_status + and module Num_lines_in_diff := Vcs.Num_lines_in_diff + and module Path_in_repo := Vcs.Path_in_repo + and module Platform := Vcs.Platform + and module Ref_kind := Vcs.Ref_kind + and module Refs := Vcs.Refs + and module Remote_branch_name := Vcs.Remote_branch_name + and module Remote_name := Vcs.Remote_name + and module Repo_name := Vcs.Repo_name + and module Repo_root := Vcs.Repo_root + and module Rev := Vcs.Rev + and module Tag_name := Vcs.Tag_name + and module Url := Vcs.Url + and module User_email := Vcs.User_email + and module User_handle := Vcs.User_handle + and module User_name := Vcs.User_name) +end diff --git a/lib/vcs_base/src/vcs_base.mli b/lib/vcs_base/src/vcs_base.mli new file mode 100644 index 0000000..e7345a7 --- /dev/null +++ b/lib/vcs_base/src/vcs_base.mli @@ -0,0 +1,70 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) + +module Vcs : sig + (** {1 Extended Vcs API} *) + + module Author = Author + module Branch_name = Branch_name + module Commit_message = Commit_message + module File_contents = File_contents + module Graph = Graph + module Name_status = Name_status + module Num_lines_in_diff = Num_lines_in_diff + module Path_in_repo = Path_in_repo + module Platform = Platform + module Ref_kind = Ref_kind + module Refs = Refs + module Remote_branch_name = Remote_branch_name + module Remote_name = Remote_name + module Repo_name = Repo_name + module Repo_root = Repo_root + module Rev = Rev + module Tag_name = Tag_name + module Url = Url + module User_email = User_email + module User_handle = User_handle + module User_name = User_name + + include + module type of Vcs + with module Author := Vcs.Author + and module Branch_name := Vcs.Branch_name + and module Commit_message := Vcs.Commit_message + and module File_contents := Vcs.File_contents + and module Graph := Vcs.Graph + and module Name_status := Vcs.Name_status + and module Num_lines_in_diff := Vcs.Num_lines_in_diff + and module Path_in_repo := Vcs.Path_in_repo + and module Platform := Vcs.Platform + and module Ref_kind := Vcs.Ref_kind + and module Refs := Vcs.Refs + and module Remote_branch_name := Vcs.Remote_branch_name + and module Remote_name := Vcs.Remote_name + and module Repo_name := Vcs.Repo_name + and module Repo_root := Vcs.Repo_root + and module Rev := Vcs.Rev + and module Tag_name := Vcs.Tag_name + and module Url := Vcs.Url + and module User_email := Vcs.User_email + and module User_handle := Vcs.User_handle + and module User_name := Vcs.User_name +end diff --git a/lib/vcs_base/test/dune b/lib/vcs_base/test/dune new file mode 100644 index 0000000..42d8180 --- /dev/null +++ b/lib/vcs_base/test/dune @@ -0,0 +1,42 @@ +(library + (name vcs_base_test) + (public_name vcs-tests.vcs_base_test) + (inline_tests) + (flags + :standard + -w + +a-4-40-41-42-44-45-48-66 + -warn-error + +a + -open + Base + -open + Fpath_sexp0 + -open + Expect_test_helpers_base) + (libraries + base + eio + eio_main + err + expect_test_helpers_core.expect_test_helpers_base + fpath + fpath-sexp0 + vcs + vcs_base + vcs_git_provider) + (instrumentation + (backend bisect_ppx)) + (lint + (pps ppx_js_style -check-doc-comments)) + (preprocess + (pps + -unused-code-warnings=force + ppx_compare + ppx_enumerate + ppx_expect + ppx_hash + ppx_here + ppx_let + ppx_sexp_conv + ppx_sexp_value))) diff --git a/lib/vcs_base/test/test__platform.ml b/lib/vcs_base/test/test__platform.ml new file mode 100644 index 0000000..a0902da --- /dev/null +++ b/lib/vcs_base/test/test__platform.ml @@ -0,0 +1,38 @@ +(*******************************************************************************) +(* Vcs - a Versatile OCaml Library for Git Operations *) +(* Copyright (C) 2024 Mathieu Barbin *) +(* *) +(* This file is part of Vcs. *) +(* *) +(* Vcs is free software; you can redistribute it and/or modify it under *) +(* the terms of the GNU Lesser General Public License as published by the *) +(* Free Software Foundation either version 3 of the License, or any later *) +(* version, with the LGPL-3.0 Linking Exception. *) +(* *) +(* Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(* the file `NOTICE.md` at the root of this repository for more details. *) +(* *) +(* You should have received a copy of the GNU Lesser General Public License *) +(* and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(* and , respectively. *) +(*******************************************************************************) + +let%expect_test "monitor-hashes" = + List.iter Vcs.Platform.all ~f:(fun t -> + let stdlib_hash = Stdlib.Hashtbl.hash t in + let vcs_hash = Vcs.Platform.hash t in + let vcs_base_hash = Vcs_base.Vcs.Platform.hash t in + print_s + [%sexp + (t : Vcs.Platform.t), { stdlib_hash : int; vcs_hash : int; vcs_base_hash : int }]); + [%expect + {| + (GitHub ( + (stdlib_hash 129913994) + (vcs_hash 129913994) + (vcs_base_hash 0))) + |}]; + () +;; diff --git a/lib/vcs_base/test/test__platform.mli b/lib/vcs_base/test/test__platform.mli new file mode 100644 index 0000000..45af050 --- /dev/null +++ b/lib/vcs_base/test/test__platform.mli @@ -0,0 +1,20 @@ +(*_******************************************************************************) +(*_ Vcs - a Versatile OCaml Library for Git Operations *) +(*_ Copyright (C) 2024 Mathieu Barbin *) +(*_ *) +(*_ This file is part of Vcs. *) +(*_ *) +(*_ Vcs is free software; you can redistribute it and/or modify it under *) +(*_ the terms of the GNU Lesser General Public License as published by the *) +(*_ Free Software Foundation either version 3 of the License, or any later *) +(*_ version, with the LGPL-3.0 Linking Exception. *) +(*_ *) +(*_ Vcs is distributed in the hope that it will be useful, but WITHOUT ANY *) +(*_ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *) +(*_ FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License and *) +(*_ the file `NOTICE.md` at the root of this repository for more details. *) +(*_ *) +(*_ You should have received a copy of the GNU Lesser General Public License *) +(*_ and the LGPL-3.0 Linking Exception along with this library. If not, see *) +(*_ and , respectively. *) +(*_******************************************************************************) diff --git a/lib/vcs_command/src/vcs_command.ml b/lib/vcs_command/src/vcs_command.ml index 4771c59..2754964 100644 --- a/lib/vcs_command/src/vcs_command.ml +++ b/lib/vcs_command/src/vcs_command.ml @@ -456,9 +456,12 @@ let branch_revision_cmd = | None -> Vcs.current_branch vcs ~repo_root in let rev = - let refs = Vcs.refs vcs ~repo_root |> Vcs.Refs.to_map in - match Map.find refs (Local_branch { branch_name }) with - | Some rev -> rev + let refs = Vcs.refs vcs ~repo_root in + match + List.find refs ~f:(fun { Vcs.Refs.Line.ref_kind; rev = _ } -> + Vcs.Ref_kind.equal ref_kind (Local_branch { branch_name })) + with + | Some ref -> ref.rev | None -> (* This line is covered in tests, but we need to disable coverage reporting here. The reason is that bisect_ppx inserts an unvisitable diff --git a/lib/vcs_git_blocking/test/test__hello_commit.ml b/lib/vcs_git_blocking/test/test__hello_commit.ml index 80f4185..a166750 100644 --- a/lib/vcs_git_blocking/test/test__hello_commit.ml +++ b/lib/vcs_git_blocking/test/test__hello_commit.ml @@ -26,7 +26,7 @@ let%expect_test "hello commit" = let vcs = Vcs_git_blocking.create () in let mock_revs = Vcs.Mock_revs.create () in let cwd = Unix.getcwd () |> Absolute_path.v in - let repo_root = Vcs.For_test.init vcs ~path:cwd |> Or_error.ok_exn in + let repo_root = Vcs.For_test.init vcs ~path:cwd in let hello_file = Vcs.Path_in_repo.v "hello.txt" in Vcs.save_file vcs diff --git a/lib/vcs_git_eio/test/test__init.ml b/lib/vcs_git_eio/test/test__init.ml index 2878fee..8f5d822 100644 --- a/lib/vcs_git_eio/test/test__init.ml +++ b/lib/vcs_git_eio/test/test__init.ml @@ -29,7 +29,7 @@ let%expect_test "init" = let repo_root = Eio.Switch.on_release sw (fun () -> Eio.Path.rmtree Eio.Path.(Eio.Stdenv.fs env / path)); - Vcs.For_test.init vcs ~path:(Absolute_path.v path) |> Or_error.ok_exn + Vcs.For_test.init vcs ~path:(Absolute_path.v path) in require_equal [%here] diff --git a/lib/vcs_git_provider/test/test__name_status.ml b/lib/vcs_git_provider/test/test__name_status.ml index 35d3130..bee7d56 100644 --- a/lib/vcs_git_provider/test/test__name_status.ml +++ b/lib/vcs_git_provider/test/test__name_status.ml @@ -101,7 +101,7 @@ let%expect_test "parse_exn" = (Modified lib/super_master_mind/test/test__opening_book.ml) (Modified super-master-mind.opam) (Modified test/maker.t)) |}]; - print_s [%sexp (Vcs.Name_status.files name_status : Set.M(Vcs.Path_in_repo).t)]; + print_s [%sexp (Vcs.Name_status.files name_status : Vcs.Path_in_repo.t list)]; [%expect {| (.github/workflows/ci.yml diff --git a/lib/vcs_git_provider/test/test__refs.ml b/lib/vcs_git_provider/test/test__refs.ml index ba28e3c..55b095f 100644 --- a/lib/vcs_git_provider/test/test__refs.ml +++ b/lib/vcs_git_provider/test/test__refs.ml @@ -36,7 +36,7 @@ let%expect_test "parse_exn" = let refs = Vcs_git_provider.Refs.parse_lines_exn ~lines in print_s [%sexp - { tags = (Vcs.Refs.tags refs : Set.M(Vcs.Tag_name).t) + { tags = (Vcs.Refs.tags refs : Vcs.Tag_name.t list) ; local_branches = (Vcs.Refs.local_branches refs : Vcs.Branch_name.t list) ; remote_branches = (Vcs.Refs.remote_branches refs : Vcs.Remote_branch_name.t list) }]; diff --git a/lib/vcs_test_helpers/src/vcs_test_helpers.ml b/lib/vcs_test_helpers/src/vcs_test_helpers.ml index c07c65b..274df8e 100644 --- a/lib/vcs_test_helpers/src/vcs_test_helpers.ml +++ b/lib/vcs_test_helpers/src/vcs_test_helpers.ml @@ -29,7 +29,7 @@ type 'a env = 'a let init_temp_repo ~env ~sw ~vcs = let path = Stdlib.Filename.temp_dir ~temp_dir:(Unix.getcwd ()) "vcs" "test" in Eio.Switch.on_release sw (fun () -> Eio.Path.rmtree Eio.Path.(Eio.Stdenv.fs env / path)); - Vcs.For_test.init vcs ~path:(Absolute_path.v path) |> Or_error.ok_exn + Vcs.For_test.init vcs ~path:(Absolute_path.v path) ;; let redact_sexp err ~fields = diff --git a/test/expect/dune b/test/expect/dune index 9a34872..b4cb92a 100644 --- a/test/expect/dune +++ b/test/expect/dune @@ -13,7 +13,9 @@ -open Fpath_sexp0 -open - Expect_test_helpers_base) + Expect_test_helpers_base + -open + Vcs_base) (libraries base eio @@ -22,6 +24,7 @@ fpath fpath-sexp0 vcs + vcs_base vcs_git_blocking vcs_git_eio vcs_test_helpers)