summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/changes.tex9
-rw-r--r--src/Makefile6
-rw-r--r--src/RECENTNEWS94
-rw-r--r--src/mkProjectInfo.ml6
-rw-r--r--src/uitext.ml100
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