Commits

camlspotter committed da58ace

spotinstall with no arg tries to work on all the installed ocamlfind packages

  • Participants
  • Parent commits 7a8ad17

Comments (0)

Files changed (11)

+1.1.0
+--------------
+
+- Now works without giving argument. Spotinstall checkes all the ocamlfind packages
+- Dependency over orakuda
+
 1.0.1
 --------------
 
 OCAML_NATIVE_LINK_FLAGS +=
 
 CAMLP4PACKS[]=
+    orakuda
 
 OCAMLPACKS[]= 
     spotlib
+    orakuda
 
 FILES[] = 
    spotinstall
 
+OCAMLDEPFLAGS= -syntax camlp4o -package orakuda.syntax
+OCAMLPPFLAGS = -syntax camlp4o -package orakuda.syntax
+
 MyOCamlProgram(spotinstall, $(FILES))
 
 .PHONY: install
 
 ::
 
+    spotinstall 
     spotinstall <packages>
 
-The command checks the files in the installation directory of OCamlFind package <package>, and if there are corresponding annotation files in the current and its sub directories, copy them to the installation directory.
+The command checks the files in the installation directory of OCamlFind package ``<package>``, and if there are corresponding annotation files in the current and its sub directories, copy them to the installation directory. If ``<packages>`` is omitted, all the installed ocamlfind packages (except those from OCaml compiler) are searched.
 
 If ``<package>`` is ``ocaml``, spotinstall works bit differently and copies the annotation files built under OCaml compiler source tree.
 
 OASISFormat: 0.2
 Name:        spotinstall
-Version:     1.0.1
+Version:     1.1.0
 Synopsis:    A tool to facilitate the installation of OCaml annotation files (.cmt, .cmti, .spot, .spit). 
 Authors:     Jun FURUSE
 License:     LGPL-2.0 with OCaml linking exception
+OASISFormat: 0.2
+Name:        spotinstall
+Version:     @version@
+Synopsis:    A tool to facilitate the installation of OCaml annotation files (.cmt, .cmti, .spot, .spit). 
+Authors:     Jun FURUSE
+License:     LGPL-2.0 with OCaml linking exception
+Plugins:      StdFiles (0.2)
+BuildType:    Custom (0.2)
+InstallType:    Custom (0.2)
+XCustomBuild: yes no | omake --install; PREFIX=$prefix omake
+XCustomInstall: PREFIX=$prefix omake install
+XCustomUninstall: PREFIX=$prefix omake uninstall
+BuildTools: omake

File opam/spotinstall.1.1.0/descr

+A tool to facilitate the installation of OCaml annotation files (.cmt, .cmti, .spot, .spit). 
+Many existing OCaml libraries, applications and the compiler itself do
+not produce or install the annotation files (.annot, .cmt, .cmti,
+.spot, .spit) which are essential for sub-expression type queries
+(caml-types.el), definition seaches and code refactoring (TypeRex and
+OCamlSpotter). If you want to use development tools, you have to:
+
+* Rebuild all the software from the source, adding -annot/-bin-annot
+  option to compiler flags in build scripts
+  i.e. Makefile/OCamlBuild/OMakefile.
+
+* Install those annotation files together with the library objects and
+  signatures. (Require modification of the build scripts)
+
+for all the programs.
+
+SpotInstall provides a post-installation workaround, consists of two things:
+
+* A very small compiler patch which activates -annot and -bin-annot if OCAML_ANNOT environment variable is defined. (You no longder need to add -annot/-bin-annot to the build scripts.)
+* A small tool to install annotation files to the library destination directory. (You no longer need to add annotation file installation to the build scripts.)
+
+For the first workaround, you need a small patch available from::
+
+    hg clone -b annot https://bitbucket.org/camlspotter/mutated_ocaml
+
+or included in this source package, ocaml-annot-<version>.patch.
+
+For the second one, you can use SpotInstall. This tool.

File opam/spotinstall.1.1.0/opam

+opam-version: "1"
+maintainer: "jun.furuse@gmail.com"
+build: [
+  ["ocaml" "setup.ml" "-configure" "--prefix" "%{prefix}%"]
+  ["ocaml" "setup.ml" "-build"]
+  ["ocaml" "setup.ml" "-install"]
+]
+remove: [
+  ["ocaml" "setup.ml" "-uninstall"]
+]
+depends: [ "ocamlfind" "spotlib" {>="2.0.0"} "omake" "orakuda"]
+ocaml-version: [>= "4.00.0"]

File opam/spotinstall.1.1.0/url

+archive: "https://bitbucket.org/camlspotter/spotinstall/get/1.1.0.tar.gz"

File opam/template/opam

-depends: [ "ocamlfind" "spotlib" {>="2.0.0"} "omake"]
+depends: [ "ocamlfind" "spotlib" {>="2.0.0"} "omake" "orakuda"]
 ocaml-version: [>= "4.00.0"]
 (* setup.ml generated for the first time by OASIS v0.3.0 *)
 
 (* OASIS_START *)
-(* DO NOT EDIT (digest: 35e32d9b70dd4c803e5a9b5eec419a5a) *)
+(* DO NOT EDIT (digest: ad200ac700b4a28bf02fb0c656476005) *)
 (*
    Regenerated by OASIS v0.3.0
    Visit http://oasis.forge.ocamlcore.org for more information and
           ocaml_version = None;
           findlib_version = None;
           name = "spotinstall";
-          version = "1.0.1";
+          version = "1.1.0";
           license =
             OASISLicense.DEP5License
               (OASISLicense.DEP5Unit
           };
      oasis_fn = Some "_oasis";
      oasis_version = "0.3.0";
-     oasis_digest = Some "\158\223\232\189&Y*Xc\001\003c\173g~\146";
+     oasis_digest =
+       Some "\157\019\213\154\231\180\195\243\188\235\r)\164\2188`";
      oasis_exec = None;
      oasis_setup_args = [];
      setup_update = false;
 
 let setup () = BaseSetup.setup setup_t;;
 
-# 5578 "setup.ml"
+# 5579 "setup.ml"
 (* OASIS_STOP *)
 let () = setup ();;

File spotinstall.ml

 open Spotlib.Spot
 open Unix
+open Printf
 
 type dest = 
   | Package of string
   | Path of string
 
+let show_dest = function
+  | Package s -> sprintf "package %s" s
+  | Path s -> s
+
 let dests, verbose = 
   match 
     imp [] & fun dests -> 
           "spotinstall <packages-or-abs-paths>\n  \
            Check the files installed as ocamlfind package <package>, or files in directory <abs-path> and if there are corresponding .cmt/.cmti/.spot/.spit files in the current and sub directories, copy them to the installation directory."
   with
-  | [], _ -> failwith "You must specify at least one package name or absolute path"
-  | dests, v -> dests, v
+  | [], v -> `All, v
+  | dests, v -> `Some dests, v
 
-let ocamlfind_path = 
-  match 
-    imp_ None & fun ocamlfind_path ->
-      ignore & shell_command "ocamlfind printconf destdir" & function
-        | (`Out, `Read line) ->
-            begin match !ocamlfind_path with
-            | Some _ -> failwith "ocamlfind printconf destdir prints more than one line"
-            | None -> ocamlfind_path := Some (String.chop_newline line)
+module OCamlFind = struct
+
+  let path = 
+    match 
+      imp_ None & fun ocamlfind_path ->
+        ignore & shell_command "ocamlfind printconf destdir" & function
+          | (`Out, `Read line) ->
+              begin match !ocamlfind_path with
+              | Some _ -> failwith "ocamlfind printconf destdir prints more than one line"
+              | None -> ocamlfind_path := Some (String.chop_newline line)
+              end
+          | _ -> ()
+    with
+    | None -> failwith "No ocamlfind installtion path found. Check your ocamlfind."
+    | Some p -> p
+  
+  let dest_dir package = 
+    match 
+      imp_ None & fun result ->
+        ignore & shell_command (sprintf "ocamlfind query %s" package) & function
+          | (`Out, `Read line) ->
+              begin match !result with
+              | Some _ -> failwith "ocamlfind query package prints more than one line"
+              | None -> result := Some (String.chop_newline line)
+              end
+          | _ -> ()
+    with
+    | None -> failwithf "No ocamlfind installtion path for package \"%s\" found. Check your ocamlfind." package
+    | Some p -> p
+
+  let packages =
+    StringSet.to_list
+    & imp_ StringSet.empty 
+    & fun packs ->
+      ignore & shell_command "ocamlfind list" (function
+        | (`Err, `Read s) -> prerr_endline s
+        | (`Out, `Read s) ->
+            begin 
+              s |> <:m<\[(distributed with Ocaml|internal)\]>> -> () (* exclude bases *)
+                | <:m<(^[^. ]+)>> as x -> packs := StringSet.add x#_1 !packs
+                | _ -> ()
             end
-        | _ -> ()
-  with
-  | None -> failwith "No ocamlfind installtion path found. Check your ocamlfind."
-  | Some p -> p
+        | _ -> ())
+end
 
-let ocamlfind_dest_dir package = 
-  match 
-    imp_ None & fun result ->
-      ignore & shell_command (Printf.sprintf "ocamlfind query %s" package) & function
-        | (`Out, `Read line) ->
-            begin match !result with
-            | Some _ -> failwith "ocamlfind query package prints more than one line"
-            | None -> result := Some (String.chop_newline line)
-            end
-        | _ -> ()
-  with
-  | None -> failwith "No ocamlfind installtion path for the package found. Check your ocamlfind."
-  | Some p -> p
+module OCaml = struct
 
-let ocaml_where = 
-  match 
-    imp_ None & fun ocaml_where ->
-      ignore & shell_command "ocamlc -where" & function
-        | (`Out, `Read line) ->
-            begin match !ocaml_where with
-            | Some _ -> failwith "ocamlc -where prints more than one line"
-            | None -> ocaml_where := Some (String.chop_newline line)
-            end
-        | _ -> ()
-  with
-  | None -> failwith "ocamlc -where failed."
-  | Some p -> p
+  let where = 
+    match 
+      imp_ None & fun ocaml_where ->
+        ignore & shell_command "ocamlc -where" & function
+          | (`Out, `Read line) ->
+              begin match !ocaml_where with
+              | Some _ -> failwith "ocamlc -where prints more than one line"
+              | None -> ocaml_where := Some (String.chop_newline line)
+              end
+          | _ -> ()
+    with
+    | None -> failwith "ocamlc -where failed."
+    | Some p -> p
+
+end
 
 let exts_of_sp = function
   | ".cmx" | ".cmo" -> [ ".spot"; ".cmt" ]
   | _ -> assert false
 
 let find_installed_cms tbl package =
+  eprintf "finding cms of %s...\n%!" (show_dest package);
   let dest_dir = match package with 
-    | Package "ocaml" -> ocaml_where 
-    | Package package -> ocamlfind_dest_dir package 
+    | Package "ocaml" -> OCaml.where 
+    | Package package -> OCamlFind.dest_dir package 
     | Path p -> p
   in
-  Unix.find [dest_dir] &~ fun path -> 
-    if path.Unix.base = "site-lib" && package = Package "ocaml" then 
-      Unix.prune ()
-    else match Filename.split_extension path.Unix.base with
+  find [dest_dir] &~ fun path -> 
+    if path.base = "site-lib" && package = Package "ocaml" then 
+      prune ()
+    else match Filename.split_extension path.base with
     | body, (".cmx" | ".cmo" | ".cmi" as ext) -> 
-        if verbose then Printf.eprintf "found %s\n" path.Unix.path;
-        Hashtbl.add tbl (body, ext) path.Unix.path
+        if verbose then Printf.eprintf "found %s\n" path.path;
+        Hashtbl.add tbl (body, ext) (package, path.path)
     | _ -> ()
 
+let dests = 
+  match dests with
+  | `Some dests -> dests
+  | `All -> List.map (fun x -> Package x) OCamlFind.packages
+
 let installed_cms = 
   let tbl = Hashtbl.create 107 in
   List.iter (fun package -> find_installed_cms tbl package) dests;
 (* For each installed *.cm* file, we try to find the same file in the current directory,
    then copy the accompanied .spot/.spit *)
 
-let _ =
+let () =
   let copied = Hashset.create 107 in
 
-  Unix.find ["."] ~f:(fun path ->
-    match Filename.split_extension path.Unix.base with
+  eprintf "Traversing the current directory to find compiled files...\n%!";
+
+  find ["."] ~f:(fun path ->
+    match Filename.split_extension path.base with
     | body, (".cmx" | ".cmo" | ".cmi" | ".ml" as ext) -> 
-        List.map (fun ext -> path.Unix.dir ^/ body ^ ext) (exts_of_sp ext)
+        List.map (fun ext -> path.dir ^/ body ^ ext) (exts_of_sp ext)
         |> List.find_all Sys.file_exists 
         |> List.iter (fun spotspit ->
-            let found = Hashtbl.find_all installed_cms (body, ext) in
-            List.iter (fun p -> 
-              match Unix.cmp p path.Unix.path with
-              | `Different | `Error -> ()
-              | `Same ->
-                  (* The file is installed! If there is .spot/.spit, copy it! *)
-                  let dirname = Filename.dirname p in
-                  match 
-                    Unix.command ["cp"; spotspit; dirname] (function
-                      | (`Err, `Read mes) -> Printf.eprintf "Failed to copy %s to %s: %s\n" spotspit dirname mes
-                      | _ -> ())
-                  with
-                  | WEXITED 0 -> 
-                      Hashset.add copied p;
-                      Printf.eprintf "Copied %s to %s\n" spotspit dirname
-                  | WEXITED _ -> ()
-                  | _ -> Printf.eprintf "Failed to copy %s to %s: SOME STRANGE READON\n" spotspit dirname
-            ) found)
+          Hashtbl.find_all installed_cms (body, ext) 
+          |> List.iter (fun (_package, p) -> 
+            match cmp p path.path with
+            | `Different | `Error -> ()
+            | `Same ->
+                (* The file is installed! If there is .spot/.spit, copy it! *)
+                let dirname = Filename.dirname p in
+                match 
+                  command ["cp"; spotspit; dirname] (function
+                    | (`Err, `Read mes) -> eprintf "Failed to copy %s to %s: %s\n%!" spotspit dirname mes
+                    | _ -> ())
+                with
+                | WEXITED 0 -> 
+                    Hashset.add copied p;
+                    eprintf "Copied %s to %s\n%!" spotspit dirname
+                | WEXITED _ -> ()
+                | _ -> eprintf "Failed to copy %s to %s: SOME STRANGE READON\n%!" spotspit dirname))
     | _ -> ());
 
   (* check not found *)
-  Hashtbl.iter (fun _ path -> 
+  Hashtbl.iter (fun _ (package, path) -> 
     if not (Hashset.mem copied path) then
-      Printf.eprintf "No spot/spit/cmt/cmti found for %s\n" path) installed_cms
+      Printf.eprintf "No binannot file found %s (%s)\n" path (show_dest package)) 
+    installed_cms