-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use the opam library (for read_only operations) #75
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,4 +36,5 @@ | |
base64 | ||
astring | ||
bos | ||
ppxlib)) | ||
(opam-state | ||
(>= 2.1.2)))) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ depends: [ | |
"base64" | ||
"astring" | ||
"bos" | ||
"ppxlib" | ||
"opam-state" {>= "2.1.2"} | ||
"odoc" {with-doc} | ||
] | ||
build: [ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,9 @@ open Bos | |
type t = { name : string; ver : string } | ||
|
||
(** Name and version of the binary package corresponding to a given package. *) | ||
let binary_name ~ocaml_version ~name ~ver ~pure_binary = | ||
let binary_name ~ocaml ~name ~ver ~pure_binary = | ||
let name = if pure_binary then name else name ^ "+bin+platform" in | ||
let ocaml_version = Ocaml_version.to_string ocaml_version in | ||
let ocaml_version = Opam.Conversions.version_of_pkg ocaml in | ||
{ name; ver = ver ^ "-ocaml" ^ ocaml_version } | ||
|
||
let name_to_string { name; ver } = name ^ "." ^ ver | ||
|
@@ -17,33 +17,41 @@ let name { name; ver = _ } = name | |
let has_binary_package repo { name; ver } = | ||
Repo.has_pkg (Binary_repo.repo repo) ~pkg:name ~ver | ||
|
||
let generate_opam_file original_name pure_binary archive_path ocaml_version = | ||
let generate_opam_file original_name pure_binary archive_path ocaml = | ||
let conflicts = if pure_binary then None else Some [ original_name ] in | ||
Repo.Opam_file.v | ||
~install:[ [ "cp"; "-pPR"; "."; "%{prefix}%" ] ] | ||
~depends:[ ("ocaml", Some ("=", Ocaml_version.to_string ocaml_version)) ] | ||
~depends:[ ("ocaml", Some ("=", Opam.Conversions.version_of_pkg ocaml)) ] | ||
?conflicts ~url:archive_path | ||
|
||
let should_remove = Fpath.(is_prefix (v "lib")) | ||
|
||
let process_path prefix path = | ||
let+ ex = Bos.OS.File.exists path in | ||
if not ex then None | ||
else | ||
match Fpath.rem_prefix prefix path with | ||
| None -> None | ||
| Some path -> | ||
if should_remove path then None else Some Fpath.(base prefix // path) | ||
match Fpath.of_string path with | ||
| Error (`Msg s) -> Error (`Msg s) | ||
| Ok path -> ( | ||
let+ ex = Bos.OS.File.exists path in | ||
if not ex then None | ||
else | ||
match Fpath.rem_prefix prefix path with | ||
| None -> None | ||
| Some path -> | ||
if should_remove path then None | ||
else Some Fpath.(base prefix // path)) | ||
|
||
(** Binary is already in the sandbox. Add this binary as a package in the local | ||
repo *) | ||
let make_binary_package opam_opts ~ocaml_version sandbox repo | ||
({ name; ver } as bname) ~name:query_name ~pure_binary = | ||
let make_binary_package opam_opts ~ocaml sandbox repo ({ name; ver } as bname) | ||
~name:query_name ~pure_binary = | ||
let prefix = Sandbox_switch.switch_path_prefix sandbox in | ||
let archive_path = | ||
Binary_repo.archive_path repo ~unique_name:(name_to_string bname ^ ".tar.gz") | ||
in | ||
Sandbox_switch.list_files opam_opts sandbox ~pkg:query_name >>= fun paths -> | ||
Opam.Queries.( | ||
with_switch_state | ||
~dir_name:(Sandbox_switch.get_sandbox_root sandbox) | ||
(files_installed_by_pkg query_name)) | ||
>>= fun paths -> | ||
Comment on lines
+50
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not wrap all of this into a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! I'd prefer to keep the |
||
let* paths = | ||
paths | ||
|> Result.List.filter_map (process_path prefix) | ||
|
@@ -61,7 +69,5 @@ let make_binary_package opam_opts ~ocaml_version sandbox repo | |
if not archive_created then | ||
Error (`Msg "Couldn't generate the package archive for unknown reason.") | ||
else | ||
let opam = | ||
generate_opam_file query_name pure_binary archive_path ocaml_version | ||
in | ||
let opam = generate_opam_file query_name pure_binary archive_path ocaml in | ||
Repo.add_package opam_opts (Binary_repo.repo repo) ~pkg:name ~ver opam |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
(library | ||
(name platform) | ||
(libraries astring angstrom ocaml-version bos.setup)) | ||
(libraries astring angstrom ocaml-version bos.setup opam-state)) |
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -136,59 +136,102 @@ module Repository = struct | |||||||||
Bos.Cmd.(v "repository" % "--this-switch" % "remove" % name) | ||||||||||
end | ||||||||||
|
||||||||||
module Show = struct | ||||||||||
let list_files opam_opts pkg_name = | ||||||||||
Cmd.run_l opam_opts Bos.Cmd.(v "show" % "--list-files" % pkg_name) | ||||||||||
|
||||||||||
let available_versions opam_opts pkg_name = | ||||||||||
let open Result.Syntax in | ||||||||||
let+ output = | ||||||||||
Cmd.run_s opam_opts | ||||||||||
Bos.Cmd.(v "show" % "-f" % "available-versions" % pkg_name) | ||||||||||
module Queries = struct | ||||||||||
let init () = | ||||||||||
OpamFormatConfig.init (); | ||||||||||
let root = OpamStateConfig.opamroot () in | ||||||||||
OpamStateConfig.load_defaults root |> ignore; | ||||||||||
OpamStateConfig.init ~root_dir:root () | ||||||||||
|
||||||||||
let latest_version ~metadata_universe ~pkg_universe ~ocaml package = | ||||||||||
let package = OpamPackage.Name.of_string package in | ||||||||||
Comment on lines
+146
to
+147
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we want to stop carrying strings around, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually that's one of your points! |
||||||||||
let compatible_ones = | ||||||||||
OpamPackage.Set.filter | ||||||||||
(fun pkg -> | ||||||||||
OpamPackage.Name.equal (OpamPackage.name pkg) package | ||||||||||
&& | ||||||||||
let pkg_opam_file = OpamPackage.Map.find pkg metadata_universe in | ||||||||||
let dependencies = OpamFile.OPAM.depends pkg_opam_file in | ||||||||||
let env _ = None in | ||||||||||
OpamFormula.verifies | ||||||||||
(OpamPackageVar.filter_depends_formula ~env dependencies) | ||||||||||
ocaml) | ||||||||||
pkg_universe | ||||||||||
in | ||||||||||
Comment on lines
+148
to
160
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems not very efficient to me: it will have to see all package and check if the name is the right one. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (but maybe it is not long, I should try it out, there are not so many opam package for a computer!) |
||||||||||
Astring.String.cuts ~sep:" " output |> List.rev | ||||||||||
|
||||||||||
let installed_version opam_opts pkg_name = | ||||||||||
match | ||||||||||
Cmd.run_s opam_opts | ||||||||||
Bos.Cmd.( | ||||||||||
v "show" % pkg_name % "-f" % "installed-version" % "--normalise") | ||||||||||
with | ||||||||||
| Ok "--" -> Ok None | ||||||||||
| Ok s -> Ok (Some s) | ||||||||||
| Error e -> Error e | ||||||||||
|
||||||||||
let installed_versions opam_opts pkg_names = | ||||||||||
let parse = | ||||||||||
let open Angstrom in | ||||||||||
let is_whitespace = function | ||||||||||
| '\x20' | '\x0a' | '\x0d' | '\x09' -> true | ||||||||||
| _ -> false | ||||||||||
in | ||||||||||
let whitespace = take_while is_whitespace in | ||||||||||
let word = whitespace *> take_till is_whitespace in | ||||||||||
let field f = whitespace *> string f *> word in | ||||||||||
let parse_double_line = both (field "name") (field "installed-version") in | ||||||||||
let parse = many parse_double_line in | ||||||||||
fun s -> | ||||||||||
match parse_string ~consume:Consume.All parse s with | ||||||||||
| Ok e -> Ok e | ||||||||||
| Error e -> Result.errorf "Error in parsing installed versions: %s" e | ||||||||||
try Some (OpamPackage.max_version compatible_ones package) | ||||||||||
with Not_found -> None | ||||||||||
|
||||||||||
let installed_versions pkg_names | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||
(sel : OpamTypes.switch_selections) = | ||||||||||
let installed_pkgs = sel.sel_installed in | ||||||||||
List.map | ||||||||||
(fun name -> | ||||||||||
let version = | ||||||||||
OpamPackage.package_of_name_opt installed_pkgs | ||||||||||
@@ OpamPackage.Name.of_string name | ||||||||||
in | ||||||||||
(name, version)) | ||||||||||
pkg_names | ||||||||||
|
||||||||||
let files_installed_by_pkg pkg_name | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||
(switch_state : 'lock OpamStateTypes.switch_state) = | ||||||||||
let changes_f = | ||||||||||
OpamPath.Switch.changes switch_state.switch_global.root | ||||||||||
switch_state.switch | ||||||||||
(OpamPackage.Name.of_string pkg_name) | ||||||||||
in | ||||||||||
let* res = | ||||||||||
Cmd.run_s opam_opts | ||||||||||
Bos.Cmd.( | ||||||||||
v "show" %% of_list pkg_names % "-f" % "name,installed-version" | ||||||||||
% "--normalise") | ||||||||||
in | ||||||||||
let+ res = parse res in | ||||||||||
List.map (function a, "--" -> (a, None) | a, s -> (a, Some s)) res | ||||||||||
|
||||||||||
let depends opam_opts pkg_name = | ||||||||||
Cmd.run_l opam_opts Bos.Cmd.(v "show" % "-f" % "depends:" % pkg_name) | ||||||||||
match OpamFile.Changes.read_opt changes_f with | ||||||||||
| None -> | ||||||||||
Result.errorf | ||||||||||
"Something went wrong looking for the files installed by %s" pkg_name | ||||||||||
| Some changes -> | ||||||||||
Ok | ||||||||||
(OpamDirTrack.check | ||||||||||
(OpamPath.Switch.root switch_state.switch_global.root | ||||||||||
switch_state.switch) | ||||||||||
changes | ||||||||||
|> List.fold_left | ||||||||||
(fun acc file -> | ||||||||||
match file with | ||||||||||
| filename, _ -> OpamFilename.to_string filename :: acc) | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you meant
Suggested change
|
||||||||||
[]) | ||||||||||
|
||||||||||
let get_pkg_universe (switch_state : 'lock OpamStateTypes.switch_state) = | ||||||||||
switch_state.available_packages | ||||||||||
|
||||||||||
let get_metadata_universe (switch_state : 'lock OpamStateTypes.switch_state) = | ||||||||||
switch_state.opams | ||||||||||
|
||||||||||
let get_switch = function | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. format error ? :) |
||||||||||
| None -> OpamStateConfig.get_switch () | ||||||||||
| Some dir -> | ||||||||||
OpamSwitch.of_dirname | ||||||||||
(Fpath.to_string dir |> OpamFilename.Dir.of_string) | ||||||||||
|
||||||||||
let with_switch_state ?dir_name f = | ||||||||||
let switch = get_switch dir_name in | ||||||||||
OpamGlobalState.with_ `Lock_read (fun global_state -> | ||||||||||
OpamSwitchState.with_ `Lock_read global_state ~switch | ||||||||||
(fun switch_state -> f switch_state)) | ||||||||||
|
||||||||||
let with_switch_state_sel ?dir_name f = | ||||||||||
let switch = get_switch dir_name in | ||||||||||
OpamGlobalState.with_ `Lock_read (fun global_state -> | ||||||||||
let sel = OpamSwitchState.load_selections ~lock_kind:`Lock_read global_state switch in | ||||||||||
f sel) | ||||||||||
|
||||||||||
let with_virtual_state f = | ||||||||||
OpamGlobalState.with_ `Lock_read (fun global_state -> | ||||||||||
OpamRepositoryState.with_ `Lock_read global_state (fun repo_state -> | ||||||||||
let virtual_state = | ||||||||||
OpamSwitchState.load_virtual global_state repo_state | ||||||||||
in | ||||||||||
f virtual_state)) | ||||||||||
end | ||||||||||
|
||||||||||
let version opam_opts pkg_name = | ||||||||||
Cmd.run_l opam_opts Bos.Cmd.(v "show" % "-f" % "version" % pkg_name) | ||||||||||
module Conversions = struct | ||||||||||
let version_of_pkg pkg = | ||||||||||
OpamPackage.version pkg |> OpamPackage.Version.to_string | ||||||||||
end | ||||||||||
|
||||||||||
let install opam_opts pkgs = | ||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why changing the type of
path
fromFpath.t
tostring
And if you do so, why not using thelet*
syntax?