diff options
-rw-r--r-- | doc/changes.tex | 9 | ||||
-rw-r--r-- | src/Makefile | 6 | ||||
-rw-r--r-- | src/RECENTNEWS | 94 | ||||
-rw-r--r-- | src/mkProjectInfo.ml | 6 | ||||
-rw-r--r-- | src/uitext.ml | 100 |
5 files changed, 109 insertions, 106 deletions
diff --git a/doc/changes.tex b/doc/changes.tex index e1da887..70e8b22 100644 --- a/doc/changes.tex +++ b/doc/changes.tex @@ -4,15 +4,6 @@ donate, you can find a link to the donation page on the \URL{http://www.cis.upenn.edu/~bcpierce/unison/lists.html}{Unison home page}. -\item The native OS X user interface has been enormously improved by Ben -Willmore and Trevor Jim. -% -(We have observed intermittent crashes of this UI when used for large -synchronizations. This problem has hopefully been fixed by a recent -improvement in locking when communicating between Objective C and OCaml; if -any further crashes are observed, we would appreciate hearing about them, -{\em especially} if they are repeatable.) - \item Several small fixes to the GTK2 UI to make it work better under Windows [thanks to Karl M for these]. diff --git a/src/Makefile b/src/Makefile index c902787..ebe0b9a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -198,11 +198,15 @@ prefsdocs: all ./$(NAME) -prefsdocs 2> prefsdocsjunk.tmp mv -f prefsdocsjunk.tmp prefsdocs.tmp -# For developers at Penn +# For developers runtest: $(MAKE) all NATIVE=false DEBUG=true ./unison test +repeattest: + $(MAKE) all NATIVE=false DEBUG=true UISTYLE=text + ./unison noprofile a.tmp b.tmp -repeat foo.tmp -debug ui + selftest: $(MAKE) all NATIVE=false DEBUG=true UISTYLE=text ./unison -selftest -ui text -batch diff --git a/src/RECENTNEWS b/src/RECENTNEWS index f142222..378cd71 100644 --- a/src/RECENTNEWS +++ b/src/RECENTNEWS @@ -1,60 +1,38 @@ -CHANGES FROM VERSION 2.27.19 - -* Copy small fix -------------------------------- -CHANGES FROM VERSION 2.27.14 - -* Copying over changes from 2.27 branch to developer sources (checkpoint) - -------------------------------- -CHANGES FROM VERSION 2.27.14 - -* Copying over changes from 2.27 branch to developer sources (checkpoint) - -------------------------------- -CHANGES FROM VERSION 2.27.17 - -* Restored old OSX GUI from version 2.17. This UI is not nearly as - pretty or featureful as the new one that's been under construction - for a while, but at least it works! (The new one does not handle - multiple UI threads correctly when it is calling back and forth - between OCaml and Objective C, leading to UI freezes and random - crashes.) - - Building Unison with 'make UISTYLE=mac' will build you the old, - working UI. Building with 'make UISTYLE=macnew' will build you the - new UI, in case you'd like to help fix it. :-) - -------------------------------- -CHANGES FROM VERSION 2.27.16 - -* Rename OSX GUI from "mac" to "macnew" (in preparation for restoring old - GUI and calling it "mac") - - -------------------------------- -CHANGES FROM VERSION 2.27.15 - -* Correction to earlier patch - -------------------------------- -CHANGES FROM VERSION 2.27.9 - -* Make the GTK(1) user interface compile again. (Thanks to Zvezdan - Petkovic.) - - -------------------------------- -CHANGES FROM VERSION 2.27.8 - -* Small fix. - - - -------------------------------- -CHANGES FROM VERSION 2.27.7 - -* Tidied documentation in preparation for new release. - +CHANGES FROM VERSION 2.28.-2 + +* Very preliminary support for triggering Unison from an external + filesystem-watching utility. The current implementation is very + simple, not efficient, and almost completely untested. Not ready + for real users. But if someone wants to help me improve it (e.g., + by writing a filesystem watcher for your favorite OS), please let + me know. + + On the Unison side, the new behavior is incredibly simple: + - use the text UI + - start Unison with the command-line flag "-repeat FOO", + where FOO is name of a file where Unison should look + for notifications of changes + - when it starts up, Unison will read the whole contents + of this file (on both hosts), which should be a + newline-separated list of paths (relative to the root + of the synchronization) and synchronize just these paths, + as if it had been started with the "-path=xxx" option for + each one of them + - when it finishes, it will sleep for a few seconds and then + examine the watchfile again; if anything has been added, it + will read the new paths, synchronize them, and go back to + sleep + - that's it! + + To use this to drive Unison "incrementally," just start it in + this mode and start up a tool (on each host) to watch for + new changes to the filesystem and append the appropriate paths + to the watchfile. Hopefully such tools should not be too hard + to write. + + Since I'm an OSX user, I'm particularly interested in writing a + watcher tool for this platform. If anybody knows about + programming against the Spotlight API and can give me a hand, + that would be much appreciated. ------------------------------- diff --git a/src/mkProjectInfo.ml b/src/mkProjectInfo.ml index 74d30ae..4b80e85 100644 --- a/src/mkProjectInfo.ml +++ b/src/mkProjectInfo.ml @@ -5,8 +5,8 @@ let projectName = "unison" let majorVersion = 2 -let minorVersion = 27 -let pointVersionOrigin = 207 (* Revision that corresponds to point version 0 *) +let minorVersion = 28 +let pointVersionOrigin = 229 (* Revision that corresponds to point version 0 *) (* Documentation: This is a program to construct a version of the form Major.Minor.Point, @@ -50,5 +50,3 @@ Printf.printf "MAJORVERSION=%d.%d\n" majorVersion minorVersion;; Printf.printf "VERSION=%d.%d.%d\n" majorVersion minorVersion pointVersion;; Printf.printf "NAME=%s\n" projectName;; - - diff --git a/src/uitext.ml b/src/uitext.ml index 420685a..b2ec468 100644 --- a/src/uitext.ml +++ b/src/uitext.ml @@ -584,44 +584,76 @@ let synchronizeOnce() = let watchinterval = 10 -let charsRead = ref [] +(* FIX; Using string concatenation to accumulate characters is + pretty inefficient! *) +let charsRead = ref "" let linesRead = ref [] -let whatcherchan = ref None - -(* -let suckOnFile () = - let ch = match !watcherchan with None -> assert false | Some(x) -> x in - let rec loop() = - match try Some(System.input_char ch) with End_of_file -> None with - None -> ... - | Some(c) -> - if c = '\n' then begin - linesRead := <turn (Safelist.rev !charsRead) into a string> :: !linesRead; - charsRead := [] - end else begin - charsRead := c :: !charsRead; - loop() - end in - loop() -*) +let watcherchan = ref None + +let suckOnWatcherFileLocal n = + Util.convertUnixErrorsToFatal + ("Reading changes from watcher process in file " ^ n) + (fun () -> + (* The main loop, invoked from two places below *) + let rec loop ch = + match try Some(input_char ch) with End_of_file -> None with + None -> + let res = !linesRead in + linesRead := []; + res + | Some(c) -> + if c = '\n' then begin + linesRead := !charsRead + :: !linesRead; + charsRead := ""; + loop ch + end else begin + charsRead := (!charsRead) ^ (String.make 1 c); + loop ch + end in + (* Make sure there's a file to watch, then read from it *) + match !watcherchan with + None -> + if Sys.file_exists n then begin + let ch = open_in n in + watcherchan := Some(ch); + loop ch + end else [] + | Some(ch) -> loop ch + ) + +let suckOnWatcherFileRoot: Common.root -> string -> (string list) Lwt.t = + Remote.registerRootCmd + "suckOnWatcherFile" + (fun (fspath, n) -> + Lwt.return (suckOnWatcherFileLocal n)) + +let suckOnWatcherFiles n = + Safelist.concat + (Lwt_unix.run ( + Globals.allRootsMap (fun r -> suckOnWatcherFileRoot r n))) let synchronizePathsFromFilesystemWatcher () = -assert false -(* let watcherfilename = Prefs.read Uicommon.repeat in - ... open this file on both client and server and store a channel in - a global variable in each... let rec loop failedPaths = - ... read (on both hosts) from this channel till it is empty, keep - any partial line in a buffer for next time, add all full lines - (from both hosts) to the Globals.paths preference, together - with failedPaths... - Prefs.set Globals.paths (failedPaths @ ...); - let (exitStatus,newFailedPaths) = synchronizeOnce() in - Trace.status (Printf.sprintf "\nSleeping for %d seconds...\n" watchinterval); - Unix.sleep watchinterval; - loop newFailedPaths -*) + let newpaths = suckOnWatcherFiles watcherfilename in + if newpaths <> [] then + display (Printf.sprintf "Changed paths:\n %s\n" + (String.concat "\n " newpaths)); + let p = failedPaths @ (Safelist.map Path.fromString newpaths) in + if p <> [] then begin + Prefs.set Globals.paths p; + let (exitStatus,newFailedPaths) = synchronizeOnce() in + debug (fun() -> Util.msg "Sleeping for %d seconds...\n" watchinterval); + Unix.sleep watchinterval; + loop newFailedPaths + end else begin + debug (fun() -> Util.msg "Nothing changed: sleeping for %d seconds...\n" + watchinterval); + Unix.sleep watchinterval; + loop [] + end in + loop [] let synchronizeUntilNoFailures () = let initValueOfPathsPreference = Prefs.read Globals.paths in @@ -639,7 +671,7 @@ let rec synchronizeUntilDone () = let repeatinterval = if Prefs.read Uicommon.repeat = "" then -1 else try int_of_string (Prefs.read Uicommon.repeat) - with Invalid_argument "int_of_string" -> + with Failure "int_of_string" -> (* If the 'repeat' pref is not a number, switch modes... *) synchronizePathsFromFilesystemWatcher() in |