X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=matitaB%2Fmatita%2FmatitaFilesystem.ml;h=8f969750ba78c34dfe59bddd4673b5da909bcb07;hb=b3afed9fd3cc38ecd4578f6b0741be50872a2828;hp=77e65822163657ffc7af9fce3bb662999f41148e;hpb=92a81bb9f7e51807585feb00f102b1f02d6cf1d3;p=helm.git diff --git a/matitaB/matita/matitaFilesystem.ml b/matitaB/matita/matitaFilesystem.ml index 77e658221..8f969750b 100644 --- a/matitaB/matita/matitaFilesystem.ml +++ b/matitaB/matita/matitaFilesystem.ml @@ -25,9 +25,8 @@ exception SvnError of string;; -let mutex = Mutex.create ();; - -let to_be_committed = ref [];; +(* disable for debugging *) +let prerr_endline _ = () let exec_process cmd = let (stdout, stdin, stderr) as chs = Unix.open_process_full cmd [||] in @@ -79,10 +78,17 @@ let string_of_matita_flag = function exception SvnAnomaly of string -let stat_classify line = +let stat_classify line uid = + let basedir = (Helm_registry.get "matita.rt_base_dir") ^ "/users/" ^ uid ^ "/" in let rec aux n acc = match (line.[n], n) with - | _, n when n = 7 -> String.sub line 8 ((String.length line) - 8), acc + | _, n when n = 7 -> + let fn = String.sub line 8 ((String.length line) - 8) in + let prefix_len = String.length basedir in + let fn_len = String.length fn in + if String.sub fn 0 prefix_len = basedir + then String.sub fn prefix_len (fn_len - prefix_len), acc + else fn, acc | ' ', _ -> aux (n+1) acc | 'A',0 -> aux (n+1) (Add::acc) | 'C',_ when n = 0 || n = 1 -> aux (n+1) (Conflict::acc) @@ -103,9 +109,22 @@ let stat_classify line = | _ -> raise (SvnAnomaly line) in aux 0 [] +let count p l = + List.length (List.filter p l) + +exception Unimplemented + +let matita_flag_of_stat fs = + if List.mem Conflict fs then MConflict + else if List.mem Modified fs then MModified + else if List.mem Add fs then MAdd + else if List.mem Delete fs then raise Unimplemented + else if List.mem NotAdded fs then MUnversioned + else MSynchronized + let stat_user user = let rt_dir = Helm_registry.get "matita.rt_base_dir" in - let repo = Helm_registry.get "matita.weblib" in + let _repo = Helm_registry.get "matita.weblib" in let errno, outlines, errlines = exec_process ("svn stat " ^ rt_dir ^ "/users/" ^ user ^ "/") @@ -113,19 +132,30 @@ let stat_user user = let files, anomalies = List.fold_left (fun (facc,eacc) line -> try - (stat_classify line::facc), eacc + (stat_classify line user::facc), eacc with | SvnAnomaly l -> facc, l::eacc) ([],[]) outlines in + let files = + List.map (fun (fname,flags) -> fname,Some (matita_flag_of_stat flags)) files + in + if errno = 0 then files, anomalies else raise (SvnError ("Anomalies: " ^ (String.concat "\n" anomalies) ^ "\n\n" ^ (string_of_output outlines errlines))) ;; (* update and checkout *) -let up_classify line = +let up_classify line uid = + let basedir = (Helm_registry.get "matita.rt_base_dir") ^ "/users/" ^ uid ^ "/" in let rec aux n acc = match (line.[n], n) with - | _, n when n = 4 -> String.sub line 5 ((String.length line) - 5), acc + | _, n when n = 4 -> + let fn = String.sub line 5 ((String.length line) - 5) in + let prefix_len = String.length basedir in + let fn_len = String.length fn in + if String.sub fn 0 prefix_len = basedir + then String.sub fn prefix_len (fn_len - prefix_len), acc + else fn, acc | ' ', _ -> aux (n+1) acc | 'A',_ when n = 0 || n = 1 -> aux (n+1) (Add::acc) | 'C',_ when n = 0 || n = 1 -> aux (n+1) (Conflict::acc) @@ -136,18 +166,27 @@ let up_classify line = | _ -> raise (SvnAnomaly line) in aux 0 [] +let matita_flag_of_update fs = + if List.mem Conflict fs then Some MConflict + else if List.mem Delete fs then None + else if List.mem Merge fs then Some MModified + else Some MSynchronized + (* this should be executed only for a freshly created user so no CS is needed *) let checkout user = let rt_dir = Helm_registry.get "matita.rt_base_dir" in let repo = Helm_registry.get "matita.weblib" in - let errno, outlines, errlines = exec_process - ("svn co " ^ repo ^ " " ^ rt_dir ^ "/users/" ^ user ^ "/") + let errno, outlines, errlines = + prerr_endline + ("svn co --non-interactive " ^ repo ^ " " ^ rt_dir ^ "/users/" ^ user ^ "/"); + exec_process + ("svn co --non-interactive " ^ repo ^ " " ^ rt_dir ^ "/users/" ^ user ^ "/") in let files, anomalies = List.fold_left (fun (facc,eacc) line -> try - (up_classify line::facc), eacc + (up_classify line user::facc), eacc with | SvnAnomaly l -> facc, l::eacc) ([],[]) outlines in @@ -211,6 +250,7 @@ let html_of_library uid ft = List.filter (fun x -> String.sub x 0 1 <> ".") (Array.to_list (Sys.readdir (basedir ^ "/" ^ path))) in let subdirs = List.filter (fun x -> Sys.is_directory (gpath x)) dirlist in + let subdirs = List.sort String.compare subdirs in (* only .ma scripts, hidden files excluded *) let scripts = @@ -221,6 +261,7 @@ let html_of_library uid ft = not (Sys.is_directory (gpath x)) && (String.sub x 0 1 <> ".") && (String.sub x i len = ".ma") with Not_found | Invalid_argument _ -> false) dirlist in + let scripts = List.sort String.compare scripts in let subdirtags = String.concat "\n" (List.map (fun x -> aux (normalize_qfn (lpath x ^ "/"))) subdirs) in let scripttags = @@ -240,57 +281,71 @@ let reset_lib () = ignore (Sys.command ("rm -rf " ^ to_be_removed)) ;; -(* adds a user to the commit queue; concurrent instances possible, so we - * enclose the update in a CS - *) -let add_user uid = - Mutex.lock mutex; - to_be_committed := uid::List.filter (fun x -> x <> uid) !to_be_committed; - Mutex.unlock mutex; -;; - let update_user user = let rt_dir = Helm_registry.get "matita.rt_base_dir" in - let repo = Helm_registry.get "matita.weblib" in + let _repo = Helm_registry.get "matita.weblib" in let errno, outlines, errlines = exec_process - ("svn up " ^ rt_dir ^ "/users/" ^ user ^ "/") + ("svn up --non-interactive " ^ rt_dir ^ "/users/" ^ user ^ "/") in let files, anomalies = List.fold_left (fun (facc,eacc) line -> try - (up_classify line::facc), eacc + (let fname,flags = up_classify line user in + (fname, flags)::facc), eacc with | SvnAnomaly l -> facc, l::eacc) ([],[]) outlines in - if errno = 0 then files, anomalies + let added = count (fun (_,flags) -> List.mem Add flags) files in + let conflict = count (fun (_,flags) -> List.mem Conflict flags) files in + let del = count (fun (_,flags) -> List.mem Delete flags) files in + let upd = count (fun (_,flags) -> List.mem Update flags) files in + let merged = count (fun (_,flags) -> List.mem Merge flags) files in + + let files = + List.map (fun (fname,flags) -> fname,matita_flag_of_update flags) files + in + + if errno = 0 then files, anomalies, (added,conflict,del,upd,merged) else raise (SvnError (string_of_output outlines errlines)) ;; -(* this function and the next one should only be called by the server itself (or +let add_files user files = + if (List.length files > 0) then + (let rt_dir = Helm_registry.get "matita.rt_base_dir" in + let _repo = Helm_registry.get "matita.weblib" in + + let files = String.concat " " + (List.map ((^) (rt_dir ^ "/users/" ^ user ^ "/")) files) in + + let errno, outlines, errlines = + if files <> "" then + exec_process ("svn add --non-interactive " ^ files) + else 0,[],[] + in + if errno = 0 then + "BEGIN ADD - " ^ user ^ ":\n" ^ (string_of_output outlines errlines) ^ "END ADD - " ^ user ^ "\n\n" + else raise (SvnError (string_of_output outlines errlines))) + else ("ADD - nothing to do for " ^ user ^ "\n") +;; + +(* this function should only be called by the server itself (or * the admin) at a scheduled time, so no concurrent instances and no CS needed * also, svn should already be safe as far as concurrency is concerned *) -let commit user = - let rt_dir = Helm_registry.get "matita.rt_base_dir" in - let repo = Helm_registry.get "matita.weblib" in - - let errno, outlines, errlines = exec_process - ("svn ci --message \"commit by user " ^ user ^ "\" " ^ rt_dir ^ "/users/" ^ user ^ "/") - in - if errno = 0 then () - else raise (SvnError (string_of_output outlines errlines)) +let commit user files = + if (List.length files > 0) then + (let rt_dir = Helm_registry.get "matita.rt_base_dir" in + let _repo = Helm_registry.get "matita.weblib" in + + let files = String.concat " " + (List.map ((^) (rt_dir ^ "/users/" ^ user ^ "/")) files) in + + let errno, outlines, errlines = exec_process + ("svn ci --non-interactive --message \"commit by user " ^ user ^ "\" " ^ files) + in + if errno = 0 then + "BEGIN COMMIT - " ^ user ^ ":\n" ^ (string_of_output outlines errlines) ^ "END COMMIT - " ^ user ^ "\n\n" + else raise (SvnError (string_of_output outlines errlines))) + else ("COMMIT nothing to do for " ^ user ^ "\n") ;; -let do_global_commit () = - prerr_endline ("to be committed: " ^ String.concat " " !to_be_committed); - List.fold_left - (fun acc u -> - try - commit u; - acc - with - | SvnError outstr -> - prerr_endline outstr; - u::acc) - [] (List.rev !to_be_committed) -;;