Source file commandInstall.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
open Ezcmd.TYPES
open EzFile.OP
open EzConfig.OP
let cmd_name = "install"
let add_repo ~repo ~url =
if Sys.file_exists (Globals.opam_repo_dir // repo ) then
Misc.call
[| "opam"; "remote" ; "set-url" ; repo;
"--all"; "--set-default"; url |]
else
Misc.call
[| "opam"; "remote" ; "add" ; repo ;
"--all"; "--set-default"; url |]
let install_exe () =
let s = FileString.read_file Sys.executable_name in
EzFile.write_file Globals.opambin_bin s;
Unix.chmod Globals.opambin_bin 0o755;
Printf.eprintf "Executable copied as %s\n%!" Globals.opambin_bin;
EzFile.make_dir ~p:true Globals.opam_plugins_bin_dir ;
Misc.call [|
"ln"; "-sf" ;
".." // Globals.command // Globals.command_exe ;
Globals.opam_plugins_bin_dir // Globals.command
|]
let install_hooks () =
Misc.change_opam_config (fun file_contents ->
let file_contents =
match CommandUninstall.remove_opam_hooks file_contents with
| None -> file_contents
| Some file_contents -> file_contents
in
Printf.eprintf "Adding %s hooks\n%!" Globals.command;
Some (
List.rev @@
Misc.opam_variable "pre-build-commands"
{| ["%s" "pre-build" name version depends] |}
Globals.opambin_bin ::
Misc.opam_variable "wrap-build-commands"
{| ["%s" "wrap-build" name version depends "--"] |}
Globals.opambin_bin ::
Misc.opam_variable "pre-install-commands"
{| ["%s" "pre-install" name version depends] |}
Globals.opambin_bin ::
Misc.opam_variable "wrap-install-commands"
{| ["%s" "wrap-install" name version depends "--"] |}
Globals.opambin_bin ::
Misc.opam_variable "post-install-commands"
{| ["%s" "post-install" name version depends installed-files] { error-code = 0} |}
Globals.opambin_bin ::
Misc.opam_variable "pre-remove-commands"
{| ["%s" "pre-remove" name version depends] |}
Globals.opambin_bin ::
List.rev file_contents
)
)
let install_repos () =
EzFile.make_dir ~p:true Globals.opambin_store_repo_packages_dir;
EzFile.write_file ( Globals.opambin_store_repo_dir // "repo" )
{|
opam-version: "2.0"
archive-mirrors: "../../cache"
|};
EzFile.write_file ( Globals.opambin_store_repo_dir // "version" )
"0.9.0";
add_repo ~repo:Globals.opam_opambin_repo
~url:( Printf.sprintf "file://%s"
Globals.opambin_store_repo_dir )
let install_patches () =
let patches_url = !!Config.patches_url in
if EzString.starts_with patches_url ~prefix:"file://" then
()
else
let opambin_patches_dir = Globals.opambin_patches_dir in
let tmp_dir = opambin_patches_dir ^ ".tmp" in
if EzString.starts_with patches_url ~prefix:"git@" then begin
Misc.call [| "rm"; "-rf"; tmp_dir |];
Misc.call [| "git"; "clone" ; patches_url ; tmp_dir |];
Misc.call [| "rm"; "-rf"; opambin_patches_dir |];
Misc.call [| "mv"; tmp_dir; opambin_patches_dir |]
end else
if EzString.starts_with patches_url ~prefix:"https://"
|| EzString.starts_with patches_url ~prefix:"http://" then begin
let output = Globals.opambin_dir // "relocation-patches.tar.gz" in
Printf.eprintf "Downloading patches...\n%!";
match Misc.wget ~url:patches_url ~output with
| None ->
Printf.kprintf failwith "Could not retrieve archive at %s" patches_url
| Some output ->
Misc.call [| "rm"; "-rf"; tmp_dir |];
EzFile.make_dir ~p:true tmp_dir ;
Unix.chdir tmp_dir ;
Misc.call [| "tar" ; "zxf" ; output |] ;
Unix.chdir Globals.curdir;
let patches_subdir = tmp_dir // "patches" in
if not ( Sys.file_exists patches_subdir ) then
Printf.kprintf failwith
"archive %s does not contain 'patches/' subdir" patches_url;
Misc.call [| "rm"; "-rf"; opambin_patches_dir |];
EzFile.make_dir ~p:true opambin_patches_dir;
Sys.rename patches_subdir (opambin_patches_dir // "patches");
Misc.call [| "rm"; "-rf"; tmp_dir |];
Sys.remove output
end
else
begin
Printf.eprintf
"Error: patches_url '%s' should either be local (file://) or git (git@, http[s]://)\n%!" patches_url;
exit 2
end
let action args =
Printf.eprintf "%s\n\n%!" Globals.about ;
EzFile.make_dir ~p:true Globals.opambin_dir ;
Config.save ();
EzFile.make_dir ~p:true Globals.opambin_cache_dir;
match args with
| [] ->
install_exe ();
install_hooks ();
install_repos ();
install_patches ()
| _ ->
List.iter (function
| "exe" -> install_exe ()
| "hooks" -> install_hooks ()
| "repos" -> install_repos ()
| "patches" -> install_patches ()
| s ->
Printf.eprintf "Error: unexpected argument %S" s;
exit 2)
args
let cmd =
let anon_args = ref [] in
{
cmd_name ;
cmd_action = (fun () -> action !anon_args) ;
cmd_args = [
[], Anons (fun list -> anon_args := list),
Ezcmd.info "No args = all, otherwise 'exe', 'hooks' and/or 'repos'";
];
cmd_man = [];
cmd_doc = "install in opam";
}