+ fn root => String.concatWith "/" (root :: rev ("" :: elems))
+ end
+
+datatype file_action' =
+ Add' of {src : string, dst : string}
+ | Delete' of string
+ | Modify' of {src : string, dst : string}
+
+fun shell ss = OS.Process.isSuccess (OS.Process.system (String.concat ss))
+
+fun shellF (ss, msg) =
+ let
+ val s = String.concat ss
+ in
+ if OS.Process.isSuccess (OS.Process.system s) then
+ ()
+ else
+ ErrorMsg.error NONE (msg s)
+ end
+
+fun findDiffs dom =
+ let
+ val realPath = getPath dom Config.resultRoot
+ val tmpPath = !currentPath
+
+ val dir = Posix.FileSys.opendir realPath
+
+ fun loopReal acts =
+ case Posix.FileSys.readdir dir of
+ NONE => (Posix.FileSys.closedir dir;
+ acts)
+ | SOME fname =>
+ let
+ val real = OS.Path.joinDirFile {dir = realPath,
+ file = fname}
+ val tmp = OS.Path.joinDirFile {dir = tmpPath,
+ file = fname}
+ in
+ if Posix.FileSys.ST.isDir (Posix.FileSys.stat real) then
+ loopReal acts
+ else if Posix.FileSys.access (tmp, []) then
+ if shell [Config.diff, " ", real, " ", tmp] then
+ loopReal acts
+ else
+ loopReal (Modify' {src = tmp, dst = real} :: acts)
+ else
+ loopReal (Delete' real :: acts)
+ end
+
+ val acts = loopReal []
+
+ val dir = Posix.FileSys.opendir realPath
+
+ fun loopTmp acts =
+ case Posix.FileSys.readdir dir of
+ NONE => (Posix.FileSys.closedir dir;
+ acts)
+ | SOME fname =>
+ let
+ val real = OS.Path.joinDirFile {dir = realPath,
+ file = fname}
+ val tmp = OS.Path.joinDirFile {dir = tmpPath,
+ file = fname}
+ in
+ if Posix.FileSys.ST.isDir (Posix.FileSys.stat tmp) then
+ loopTmp acts
+ else if Posix.FileSys.access (real, []) then
+ loopTmp acts
+ else
+ loopTmp (Add' {src = tmp, dst = real} :: acts)
+ end
+
+ val acts = loopTmp acts
+ in
+ acts