From 09c00d8edcf2490ac5c84d4c5fca8da688f4696b Mon Sep 17 00:00:00 2001 From: Brian McDevitt Date: Sun, 26 Aug 2012 19:01:31 -0500 Subject: [PATCH] Migrated to Clojure 1.3 and modular clojure.contrib. This required replacing contrib.Condition with Slingshot. Slingshot *should* be unnecessary in Clojure 1.4. --- project.clj | 13 ++-- src/subrosa/client.clj | 7 ++- src/subrosa/commands.clj | 80 ++++++++++++------------ src/subrosa/database.clj | 2 +- src/subrosa/netty.clj | 10 +-- src/subrosa/plugins.clj | 3 +- src/subrosa/plugins/catchup.clj | 4 +- src/subrosa/utils.clj | 2 +- test/subrosa/test/expect.clj | 39 ++++++++---- test/subrosa/test/plugins/fs_logging.clj | 1 - 10 files changed, 93 insertions(+), 68 deletions(-) diff --git a/project.clj b/project.clj index ecfec98..bd97210 100644 --- a/project.clj +++ b/project.clj @@ -3,10 +3,15 @@ :resources-path "etc" :repositories {"jboss" "http://repository.jboss.org/nexus/content/groups/public/"} - :dependencies [[org.clojure/clojure "1.2.1"] - [org.clojure/clojure-contrib "1.2.0"] - [org.clojure/tools.logging "0.2.3"] + :dependencies [[org.clojure/clojure "1.3.0"] + ; [org.clojure/clojure-contrib "1.2.0"] + [org.clojure/tools.logging "0.2.4"] + [org.clojure/tools.namespace "0.1.3"] + [slingshot "0.10.3"] [log4j "1.2.16"] [org.jboss.netty/netty "3.2.1.Final"] [swank-clojure "1.3.2"]] - :dev-dependencies [[lein-tar "1.0.5"]]) + :dev-dependencies [[lein-tar "1.0.5"] + [vimclojure/server "2.3.5"] + [lein-eclipse "1.0.0"] + [org.clojars.scott/lein-nailgun "1.1.0"]]) diff --git a/src/subrosa/client.clj b/src/subrosa/client.clj index dd45973..f035bd6 100644 --- a/src/subrosa/client.clj +++ b/src/subrosa/client.clj @@ -1,6 +1,7 @@ (ns subrosa.client (:require [subrosa.database :as db]) - (:use [clojure.contrib.condition :only [raise]] + (:use [clojure.set :only [difference]] + [slingshot.slingshot :only [throw+]] [subrosa.server] [subrosa.config :only [config]])) @@ -129,7 +130,7 @@ (send-welcome channel) (send-motd channel) (send-lusers channel)) - (raise {:type :protocol-error + (throw+ {:type :protocol-error :disconnect true :msg ":Bad Password"}))))) @@ -230,7 +231,7 @@ (send-to-client* chan msg))) (defn send-to-clients-in-rooms-for-nick [nick msg channel] - (doseq [chan (clojure.set/difference + (doseq [chan (difference (into #{} (for [room-name (rooms-for-nick nick) chan (channels-in-room room-name)] chan)) diff --git a/src/subrosa/commands.clj b/src/subrosa/commands.clj index b2fbbea..8bb1273 100644 --- a/src/subrosa/commands.clj +++ b/src/subrosa/commands.clj @@ -5,7 +5,7 @@ [subrosa.config :only [config]] [subrosa.server :only [supported-room-modes]] [clojure.string :only [join]] - [clojure.contrib.condition :only [raise]]) + [slingshot.slingshot :only [throw+]]) (:require [clojure.tools.logging :as log]) (:import [org.jboss.netty.channel ChannelFutureListener])) @@ -17,7 +17,7 @@ (when-not (empty? message) (log/debug "Received unhandled command:" message) (when (authenticated? channel) - (raise {:type :client-error + (throw+ {:type :client-error :code 421 :msg (format "%s :Unknown command" cmd)}))))))) @@ -65,13 +65,13 @@ (add-user-for-nick! channel nick) (maybe-add-authentication-step! channel "NICK") (maybe-update-authentication! channel)) - (raise {:type :client-error + (throw+ {:type :client-error :code 433 :msg (format "%s :Nickname is already in use" nick)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 432 :msg (format "%s :Erroneous nickname" nick)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 431 :msg ":No nickname given"}))) @@ -83,10 +83,10 @@ (update-user-for-nick! (nick-for-channel channel) parts) (maybe-add-authentication-step! channel "USER") (maybe-update-authentication! channel)) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "USER :Not enough parameters"}))) - (raise {:type :client-error + (throw+ {:type :client-error :code 462 :msg ":Unauthorized command (already registered)"}))) @@ -98,14 +98,14 @@ (dosync (maybe-add-authentication-step! channel "PASS") (maybe-update-authentication! channel)) - (raise {:type :protocol-error + (throw+ {:type :protocol-error :disconnect true :msg ":Bad Password"})) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :disconnect true :msg "PASS :Not enough parameters"})) - (raise {:type :client-error + (throw+ {:type :client-error :code 462 :disconnect true :msg ":Unauthorized command (already registered)"}))) @@ -150,13 +150,13 @@ (dispatch-message (format "TOPIC %s" room-name) channel) (dispatch-message (format "NAMES %s" room-name) channel) (run-hook 'join-hook channel room-name)) - (raise {:type :client-error + (throw+ {:type :client-error :code 403 :msg (format "%s :No such channel" room-name)}))))) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "JOIN :Not enough parameters"})) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "JOIN :Too many parameters"})))) @@ -179,11 +179,11 @@ room-name new-topic))) (run-hook 'topic-hook channel room-name old-topic new-topic)) - (raise {:type :client-error + (throw+ {:type :client-error :code 442 :msg (format "%s :You're not on that channel" room-name)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg (format "TOPIC :Not enough parameters")})) (if-let [topic (topic-for-room room-name)] @@ -191,10 +191,10 @@ (format "%s :%s" room-name topic)) (send-to-client channel 331 (format "%s :No topic is set" room-name)))) - (raise {:type :client-error + (throw+ {:type :client-error :code 403 :msg (format "%s :No such channel" room-name)}))) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "TOPIC :Not enough parameters"}))) @@ -224,13 +224,13 @@ (send-to-client* channel msg) (run-hook 'privmsg-nick-hook channel recipient plain-msg)) - (raise {:type :client-error + (throw+ {:type :client-error :code 401 :msg (format "%s :No such nick/channel" recipient)})))) - (raise {:type :client-error + (throw+ {:type :client-error :code 412 :msg ":No text to send"})) - (raise {:type :client-error + (throw+ {:type :client-error :code 411 :msg ":No recipient given (PRIVMSG)"})))) @@ -252,13 +252,13 @@ (defcommand ping [channel server] (if (not (empty? server)) (send-to-client* channel (format "PONG %s :%s" (hostname) server)) - (raise {:type :client-error + (throw+ {:type :client-error :code 409 :msg ":No origin specified"}))) (defcommand pong [channel server] (when (empty? server) - (raise {:type :client-error + (throw+ {:type :client-error :code 409 :msg ":No origin specified"}))) @@ -278,10 +278,10 @@ user-name (apply str (interpose " " rooms)))) (send-to-client channel 318 ":End of WHOIS list")) - (raise {:type :client-error + (throw+ {:type :client-error :code 401 :msg (format "%s :No such nick/channel" username)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 431 :msg ":No nickname given"}))) @@ -326,13 +326,13 @@ part-message)) (remove-nick-from-room! nick room) (run-hook 'part-hook channel room part-message)) - (raise {:type :client-error + (throw+ {:type :client-error :code 442 :msg (format "%s :You're not on that channel" room)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 403 :msg (format "%s :No such channel" room)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "PART :Not enough parameters"}))))) @@ -373,7 +373,7 @@ (send-to-client channel 303 (format ":%s" (apply str (interpose " " on-nicks))))) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "ISON :Not enough parameters"}))) @@ -396,20 +396,20 @@ (if (room-for-name room-name) (if (nick-in-room? sender-nick room-name) (do-invite) - (raise {:type :client-error + (throw+ {:type :client-error :code 442 :msg (format "%s :You're not on that channel" room-name)})) (do-invite)) - (raise {:type :client-error + (throw+ {:type :client-error :code 443 :msg (format "%s %s :is already on channel" target-nick room-name)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 401 :msg (format "%s :No such nick/channel" target-nick)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "INVITE :Not enough parameters"})))) @@ -432,17 +432,17 @@ comment)) (remove-nick-from-room! nick room) (run-hook 'kick-hook channel room nick comment)) - (raise {:type :client-error + (throw+ {:type :client-error :code 441 :msg (format "%s %s :They aren't on that channel" nick room)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 442 :msg (format "%s :You're not on that channel" room)})) - (raise {:type :client-error + (throw+ {:type :client-error :code 403 :msg (format "%s :No such channel" room)})))] (cond @@ -456,10 +456,10 @@ (doseq [[room nick] (zipmap rooms nicks)] (do-kick nick room)) - :else (raise {:type :client-error + :else (throw+ {:type :client-error :code 461 :msg "KICK :Not enough parameters"}))) - (raise {:type :client-error + (throw+ {:type :client-error :code 461 :msg "KICK :Not enough parameters"})))) @@ -491,14 +491,14 @@ (format-client channel) room-name (format-mode enable? new-mode)))))) - (raise {:type :client-error + (throw+ {:type :client-error :code 472 :msg (format "%s :is unknown mode char to me for %s" (first new-mode) room-name)})))) - (raise {:type :client-error + (throw+ {:type :client-error :code 501 :msg ":Unknown MODE flag"})) - (raise {:type :client-error + (throw+ {:type :client-error :code 401 :msg (format "%s :No such nick/channel" room-name)})))) diff --git a/src/subrosa/database.clj b/src/subrosa/database.clj index aa990fe..0eebf32 100644 --- a/src/subrosa/database.clj +++ b/src/subrosa/database.clj @@ -2,7 +2,7 @@ (:refer-clojure :exclude [get]) (:import [java.util UUID])) -(defonce db (ref {})) +(defonce ^:dynamic db (ref {})) (defn ensure-id [m] (if (:id m) diff --git a/src/subrosa/netty.clj b/src/subrosa/netty.clj index 4e4d44c..dfb2506 100644 --- a/src/subrosa/netty.clj +++ b/src/subrosa/netty.clj @@ -6,7 +6,8 @@ [subrosa.ssl :only [make-ssl-engine]] [subrosa.commands :only [dispatch-message quit]] [subrosa.plugins :only [load-plugins]] - [clojure.stacktrace :only [root-cause]]) + [clojure.stacktrace :only [root-cause]] + [slingshot.ex-info]) (:require [clojure.tools.logging :as log]) (:import [java.net InetSocketAddress] [java.util.concurrent Executors] @@ -20,7 +21,8 @@ [org.jboss.netty.channel.socket.nio NioServerSocketChannelFactory] [org.jboss.netty.handler.codec.frame Delimiters DelimiterBasedFrameDecoder] - [org.jboss.netty.handler.codec.string StringDecoder StringEncoder])) + [org.jboss.netty.handler.codec.string StringDecoder StringEncoder] + [slingshot ExceptionInfo])) ;; Some code and a lot of inspiration for the layout of this namespace came from ;; Zach Tellman's awesome aleph project: http://github.com/ztellman/aleph @@ -48,8 +50,8 @@ (defn netty-error-handler [up-or-down evt] (when (instance? ExceptionEvent evt) - (if (instance? clojure.contrib.condition.Condition (root-cause evt)) - (let [condition (meta (root-cause evt)) + (if (instance? ExceptionInfo (root-cause evt)) + (let [condition (:object (ex-data (root-cause evt))) chan-future-agent (condp = (:type condition) :client-error (send-to-client diff --git a/src/subrosa/plugins.clj b/src/subrosa/plugins.clj index 520ef79..4117736 100644 --- a/src/subrosa/plugins.clj +++ b/src/subrosa/plugins.clj @@ -1,7 +1,8 @@ (ns subrosa.plugins - (:use [clojure.contrib.find-namespaces])) + (:use [clojure.tools.namespace])) (defn find-plugins [] + (with-out-str (print (find-namespaces-on-classpath))) (filter #(.startsWith (str %) "subrosa.plugins.") (find-namespaces-on-classpath))) diff --git a/src/subrosa/plugins/catchup.clj b/src/subrosa/plugins/catchup.clj index b82484e..f89be33 100644 --- a/src/subrosa/plugins/catchup.clj +++ b/src/subrosa/plugins/catchup.clj @@ -3,7 +3,7 @@ [subrosa.config :only [config]] [subrosa.client] [subrosa.hooks :only [add-hook]] - [clojure.contrib.condition :only [raise]]) + [slingshot.slingshot :only [throw+]]) (:import (java.util Date) (java.text SimpleDateFormat))) @@ -61,6 +61,6 @@ sender type room msg))) (send-to-client* channel (format ":*** PRIVMSG %s :%s" room "Catchup Complete"))) - (raise {:type :client-error + (throw+ {:type :client-error :code 442 :msg (format "%s :You're not on that channel" room)})))))) diff --git a/src/subrosa/utils.clj b/src/subrosa/utils.clj index 8f46a94..270435d 100644 --- a/src/subrosa/utils.clj +++ b/src/subrosa/utils.clj @@ -16,7 +16,7 @@ (if (not (seq bindings)) `(do ~@body) (let [old-value-sym (gensym)] - `(let [~old-value-sym (.getRoot #'~(first bindings))] + `(let [~old-value-sym (.getRawRoot #'~(first bindings))] (alter-var-root #'~(first bindings) (fn [& _#] ~(second bindings))) (try (with-var-root ~(nnext bindings) ~@body) (finally diff --git a/test/subrosa/test/expect.clj b/test/subrosa/test/expect.clj index b98f14e..1734620 100644 --- a/test/subrosa/test/expect.clj +++ b/test/subrosa/test/expect.clj @@ -2,32 +2,39 @@ (:use [clojure.test] [clojure.string :only [join]] [subrosa.netty :only [create-server]] - [subrosa.config :only [config]]) + [subrosa.config :only [config]] + [slingshot.slingshot :only [try+ throw+]] + [clojure.java.io :only [delete-file file]]) (:require [clojure.tools.logging :as log]) (:import [java.io BufferedReader InputStreamReader] + [java.net SocketTimeoutException] [javax.net.ssl X509TrustManager SSLContext] [javax.net SocketFactory])) -(def *timeout* 10000) -(def *host* "localhost") -(def *port* 6789) +(def ^:dynamic *timeout* 10000) +(def ^:dynamic *host* "localhost") +(def ^:dynamic *port* 6789) (defn run-test-server [f] (let [server (create-server *port*)] - (try - (binding [log/log* (fn [& _])] + (try+ + ;(binding [log/log* (fn [& _])] ((:start-fn server)) (f) - ((:stop-fn server)))))) + ((:stop-fn server)))));) (defn socket-read-line [in] - (try + (try+ (let [read (.readLine in)] (if (nil? read) :timeout read)) - (catch java.net.SocketTimeoutException e - :timeout))) + (catch java.lang.RuntimeException e + (if (instance? SocketTimeoutException (.getCause e)) + (do + (log/error "Caught SocketTimeoutException") + :timeout) + (throw+ e))))) (defn create-socketfactory [] (if (config :ssl :keystore) @@ -52,7 +59,7 @@ (defmacro with-connection [s & body] `(let [~s (connect)] - (try + (try+ ~@body (finally (.close (:socket ~s)))))) @@ -100,3 +107,13 @@ (report {:type :fail :message ~msg :expected (str "(not-found? " ~string ")") :actual (str "found " ~string)})))))) + +(defn delete-file-recursively + "Delete file f. If it's a directory, recursively delete all its + contents. Raise an excepion if any deletion fails." + [f & [silently]] + (let [f (file f)] + (if (.isDirectory f) + (doseq [child (.listFiles f)] + (delete-file-recursively child silently))) + (delete-file f silently))) diff --git a/test/subrosa/test/plugins/fs_logging.clj b/test/subrosa/test/plugins/fs_logging.clj index 4fdea04..cc8d289 100644 --- a/test/subrosa/test/plugins/fs_logging.clj +++ b/test/subrosa/test/plugins/fs_logging.clj @@ -1,6 +1,5 @@ (ns subrosa.test.plugins.fs-logging (:use [clojure.test] - [clojure.contrib.io :only [delete-file-recursively]] [subrosa.hooks :only [hooks]] [subrosa.plugins.fs-logging :only [get-log-name format-date format-time add-hooks]]