             s3ObjectsTask (s3-list-objects s3)
             filesTask (readdir-recursive dir)
             [err1 s3keys] (<! s3ObjectsTask)
-            [err2 files] (<! filesTask)]
-        (cond
-          err1 [err1 nil]
-          err2 [err2 nil]
-          :else
-            (let [[onlyremote onlylocal both] (partition-files s3keys files)]
-              (println "Remote: " (s/join onlyremote " | "))
-              (println "Local: " (s/join onlylocal " | "))
-              (println "Both: " (s/join both " | "))
-              [nil true]))))))+            [err2 files] (<! filesTask)
+            firstErr (or err1 err2)]
+        (if firstErr
+          [firstErr nil]
+          (let [[onlyremote onlylocal both] (partition-files s3keys files)
+                deleteTask (delete-files s3 onlyremote delete whatif verbose)
+                copyTask (copy-files s3 onlylocal whatif)
+                updateTask (update-files-if-changed s3 both whatif force verbose)
+                [deleteErr _] (<! deleteTask)
+                [copyErr _] (<! copyTask)
+                [updateErr _] (<! updateTask)
+                firstErr (or deleteErr copyErr updateErr)]
+            (if firstErr
+              [firstErr nil]
+              [nil true])))))))
        (filter (fn [[_ _ etag]] (not= etag :notfound)))
        (vec))])

(defn bucketsync
  {:summary "Synchronize a remote Amazon S3 bucket with a local asset directory."
   :doc "usage: biblecli bucketsync [--force] [-f] [--whatif] [--bucket <bucket>] [--region <region>] [--profile <profile>] <dir>
   -f,
   --force               Upload all files, changed and unchanged, generally to refresh the http headers.
   --whatif              Print bucket changes that would be made without actually making changes.
   --bucket <bucket>     S3 bucket id. Defaults to kingjames-beta.
   --region <region>     S3 region. Defaults to us-east-1.
   --profile <profile>   S3 credentials profile. Uses the default profile if not specified.
   <dir>                 Source asset directory."
   :async true
   :cmdline-opts {:boolean ["force" "whatif"]
                  :string ["bucket" "region" "profile"]
                  :alias {:force "f"}
                  :default {:bucket "kingjames-beta"
                            :region "us-east-1"
                            :profile "default"}}}
  [{dir :_ force :force whatif :whatif bucket :bucket region :region profile :profile}]
  (go
    (if (not= (count dir) 1)
      ["<dir> parameter required." nil]

(ns biblecli.commands.bucketsync
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require [cljs.core.async :refer [to-chan chan put! tap mult <!]]
            [cljs.nodejs :refer [require process]]
            [clojure.string :as s]))

(def AWS (require "aws-sdk"))
(def fs (require "fs"))
(def path (require "path"))

(defn readdir [dir]
  (let [chan (chan)
