         args))
 
 (defmacro
-  ^{:doc "Define a cluster including some remote machines"
+  ^{:doc "Define a cluster including some remote machines,for example:
+           (defcluster :mycluster
+                     :user \"login\"
+                     :addresses [\"a.domain.com\" \"b.domain.com\"])
+
+      Please see https://github.com/killme2008/clojure-control/wiki/Define-clusters
+     "
     :arglists '([name & options])
     :added "0.1"}
   defcluster [name & args]
   `(let [m# (apply hash-map ~(cons 'list (unquote-cluster args)))]
      (swap! clusters assoc ~name (assoc m# :name ~name))))
 
-(defmacro when-exit
+(defmacro ^:private when-exit
   ([test error]
      `(when-exit ~test ~error nil))
   ([test error else]

(def ^:private bash-redbold "\033[1;31m")
(def ^:private bash-greenbold "\033[1;32m")

(defmacro cli-bash-bold [& content]
  `(if *enable-color*
     (str bash-bold ~@content bash-reset)
     (str ~@content)))

(defmacro cli-bash-redbold [& content]
  `(if *enable-color*
     (str bash-redbold ~@content bash-reset)
     (str ~@content)))

(defmacro cli-bash-greenbold [& content]
  `(if *enable-color*
     (str bash-greenbold ~@content bash-reset)
     (str ~@content)))


(defstruct ExecProcess  :stdout :stderr :status)

(defn gen-log [host tag content]
  (str (cli-bash-redbold host ":")
       (cli-bash-greenbold tag ": ")
       (join " " content)))

(defn log-with-tag [host tag & content]
  (if (and *enable-logging* (not (blank? (join " " content))))
    (println (gen-log host tag content))))

(defn- not-nil? [obj]
  (not (nil? obj)))

(defn  ^:dynamic  exec [host user cmdcol]
  (let [rt (apply sh (filter not-nil? cmdcol))
        status (:exit rt)
        stdout (:out rt)
        stderr (:err rt)

                          ssh-options
                          [(ssh-client host user) cmd]))))

(defn rsync 
  "Rsync local files to remote machine's files,for example:
     (deftask :deploy \"scp files to remote machines\" []
    (rsync \"src/\" \":/home/login\"))

    Valid options:
    :rsync-options  -- rsync options string
  "
  {:arglists '([src dst & opts])}
  [host user cluster src dst & opts]
  (let [m (apply hash-map opts)
        rsync-options (or (:rsync-options m) (find-client-options host user cluster :rsync-options))]
    (log-with-tag host "rsync" rsync-options (str src " ==>" dst))
    (exec host
          user
