0.2.3 docs





    Nov 30, 2014

    Quality Clojure


    Index of all namespaces

    « Project + dependencies

    Assess Clojure libraries based on a number of different metrics.

    Utilize core.logic to implement a simple wandering walk for the bot.
    clojure.browser.event — cljsDocsSource
    This namespace contains functions to work with browser
    events.  It is based on the Google Closure Library event system. — cljsDocsSource
    Network communication library, wrapping
    Includes a common API over XhrIo, CrossPageChannel, and Websockets.
    taoensso.encore — cljsDocsSource
    Some tools I use often, w/o any external deps.


    A abs ajax-lite as-?bool as-?email as-?float as-?int as-?kw as-?name as-?nblank as-?nemail as-bool as-float as-int as-map assert-min-encore-version assertion-error assoc-conj assoc-some assoc-when atom?

    B backport-run!

    C chan? clamp clj1098 coerce-xhr-params conj-some console-log contains-in? count-words

    D debugf dissoc-in distinct-by distinct-elements? distinctv

    E encore-version error-data error? errorf exp-backoff explode-keyword

    F fatalf filter-keys filter-kvs filter-vals format format* format-query-string fq-name fzipmap

    G gc-now? gc-rate get-pooled-xhr! get-window-location greatest

    H hcond hpred hthrow

    I infof interleave-all into-all

    J join-once

    K keys<= keys= keys=nnil? keys>= keywordize-map ks-nnil? ks<= ks= ks>= kw-identical?

    L *log-level* least log log? logf logging-level logp

    M map->Swapped map-keys map-kvs map-vals mapply memoize* memoize-1 memoize1 memoize_ memoized merge-deep merge-deep-with merge-keywords merge-url-with-query-string ms ms->secs

    N name-with-attrs nano-time nblank-str? nblank? nested-merge nested-merge-with nil->str nneg-int? nneg-num? nneg? nnil-set nnil= nnil? non-throwing norm-word-breaks now-dt now-udt now-udt-mock-fn nvec?

    O oget

    P parse-bool parse-float parse-int parse-query-params path pos-int? pos-num? pow pr-edn

    Q queue queue* queue?

    R rate-limit rate-limited rate-limiter rate-limiter* rcompare re-pattern? read-edn read-edn-str remove-vals removev repeatedly-into replace-in replace-in* reportf reset-in! round round* round1 round2 rsome

    S ->?singleton ->Swapped sayf sayp secs secs->ms seq-kvs set* set-exp-backoff-timeout! singleton? spaced-str spaced-str-with-nils str-?index str-contains? str-ends-with? str-replace str-starts-with? stringy? sub-indexes substr subvec* swap-in! swap-val! Swapped swapped swapped* swapped*-in swapped?

    T takev tracef translate-signed-idx

    U udt? undefined->nil update-in* url-decode url-encode uuid-str

    V ->vec vec* vec2? vec3? vsplit-first vsplit-last

    W warnf

    X xdistinct xhr-pool_

    Z zero-num?

    taoensso.sente — cljsDocsSource
    Channel sockets. Otherwise known as The Shiz.
        Protocol  | client>server | client>server ?+ ack/reply | server>user[1] push
      * WebSockets:       ✓              [2]                           ✓
      * Ajax:            [3]              ✓                           [4]
      [1] By user-id => ALL of a user's connected clients (browser tabs, devices,
          etc.). Note that user > session > client > connection for consistency
          over time + multiple devices.
      [2] Emulate with cb-uuid wrapping.
      [3] Emulate with dummy-cb wrapping.
      [4] Emulate with long-polling.
      * chsk  - Channel socket.
      * hk-ch - Http-kit Channel.
      * uid   - User-id. An application-specified identifier unique to each user
                and sessionized under :uid key to enable server>user push.
                May have semantic meaning (e.g. username, email address), or not
                (e.g. random uuid) - app's discresion.
      * cb    - Callback.
      * tout  - Timeout.
      * ws    - WebSocket/s.
      * pstr  - Packed string. Arbitrary Clojure data serialized as a string (e.g.
                edn) for client<->server comms.
    Special messages (implementation detail):
      * Callback replies: :chsk/closed, :chsk/timeout, :chsk/error.
      * Client-side events:
          [:chsk/handshake [<?uid> <?csrf-token>]],
          [:chsk/state <new-state>],
          [:chsk/recv <[buffered-evs]>] ; server>user push
      * Server-side events:
          [:chsk/bad-package <packed-str>], ; was :chsk/bad-edn
          [:chsk/bad-event <chsk-event>],
      * Callback wrapping: [<clj> <?cb-uuid>] for [2],[3].
    Notable implementation details:
      * core.async is used liberally where brute-force core.async allows for
        significant implementation simplifications. We lean on core.async's strong
        efficiency here.
      * For WebSocket fallback we use long-polling rather than HTTP 1.1 streaming
        (chunked transfer encoding). Http-kit _does_ support chunked transfer
        encoding but a small minority of browsers &/or proxies do not. Instead of
        implementing all 3 modes (WebSockets, streaming, long-polling) - it seemed
        reasonable to focus on the two extremes (performance + compatibility). In
        any case client support for WebSockets is growing rapidly so fallback
        modes will become increasingly irrelevant while the extra simplicity will
        continue to pay dividends.
    General-use notes:
      * Single HTTP req+session persists over entire chsk session but cannot
        modify sessions! Use standard a/sync HTTP Ring req/resp for logins, etc.
      * Easy to wrap standard HTTP Ring resps for transport over chsks. Prefer
        this approach to modifying handlers (better portability).
    taoensso.sente.interfaces — cljsDocsSource
    Experimental (pre-alpha): subject to change.
    Public interfaces / extension points.
    The README below is fetched from the published project artifact. Some relative links may be broken.

    ![](logo.png) Quality Clojure

    ![Gitter]( Chat.svg) Stories in Ready Build Status

    Use a number of existing tools like Kibit, Eastwood, and Bikeshed to get feedback about a particular library. When it’s finished, you’ll be able to point to a github repository, and the service will suck it in. From that point, there are a few things that will happen:

    • import the repository into Datomic
    • run kibit, import comments into Datomic
    • run eastwood, import comments into Datomic
    • run bikeshed, import comments into Datomic
    • run pygments on each source file to output a static html file for display

    At this point, you can access the repository at /repo/<github user or org>/<repo-name>/ and get a listing of the files available to view, as well as overall stats for the repository. From here, you can drill down and view individual files and the notes and comments associated with each one.


    You will need:

    • Clojure - 1.6.0 or above.
    • Leiningen - 2.0.0 or above.
    • Pygments - For syntax highlighting; will need to be available on your path.
    • Datomic - Currently only tested on Datomic Free. Try this setup tutorial if you have trouble. Not necessary to setup Datomic Free if you are only developing.
    • Docker - Used to isolate eastwood linting.
    • Until #76 is resolved, you’ll need kibit installed in the user profile as a plugin. The user running qualityclj will need a profiles.clj that might look like this: {:user {:plugins [[lein-kibit "0.0.8"]]}}.


    Quality Clojure expects to have sudo-less access to the docker command.

    OS X

    This can be achieved on OSX by using the installer from docker.


    Pick your favorite installation from docker’s install listing, and then peruse docker attack vectors to understand the risks, and finally follow the directions to enable non-sudo access to the docker command specifically for the user running Quality Clojure.

    Setting up a Production Instance

    Please keep in mind Quality Clojure is in development

    First, create a production uberjar from the command line:

    lein uberjar

    Place the resulting uberjar where you want Quality Clojure to run.

    In the root of your Datomic directory, start the Datomic transactor (you did remember to install Datomic, didn’t you?):

    bin/transactor config/samples/

    Finally, run the jar. Make sure to pass in the URI for the production database, as well as:

    java -jar standalone.jar 'datomic:free://localhost:4334/<db-name>' \
    '/srv/quality/repos' 'srv/quality/highlight'

    With any luck, everything should be up, running correctly, and viewable from http://localhost:8090/.



    For development, we use an in-memory version of Datomic instead of more robust options, such as running the transactor with the free storage protocol. This in-memory version is already part of Quality Clojure and no installation is required by the developer to set it up. How great is that?!

    This means whatever is sent to the database does not persist beyond the repl or program it is launched in.

    It is important to ensure the database is running and populated with schemas before trying to use it. In fact, we thought it was so important, we made a function to do just that! Simply call (qualityclj.models.db/ensure-db) to initialize the database.

    Alternatively, (qualityclj.repl/start-server) will, among other things, ensure the database is ready.


    To start the application web server from the qualityclj.repl namespace:

    qualityclj.repl=> (start-server)

    For a tighter thought-code-feedback loop when working on the client side, start figwheel. In a nutshell, figwheel updates compiled ClojureScript to the browser so you won’t have to manually reload the page constantly:

    lein figwheel


    Coming soon, I promise ;-)

    The plan is to use clojure.test once we have a core not in constant flux.

    If you are contributing, please make sure that there are tests to cover any new functionality introduced, or bugs fixed.

    The ClojureScript tests require phantomjs to be on your PATH. Downloads can be found on the homepage.


    We are using Timbre for logging.

    If you have a namespace where you want logging or profiling, insert the following to use Timbre in the namespace:

    ;; The ns needing some love
    (ns sad-without-logging (:require [taoensso.timbre :as timbre]))
    (timbre/refer-timbre) ;; Provides useful Timbre aliases in the ns

    And you’re good to go. Here is a simple example of logging to get you going:

    (defn can-i-has-logging []
         (debug "startin difficult computashuns")
         (spy :info (+ 0 1 2 3 4 5 6))
         (spy :warn "u liek teh math" (* 9 8 7)))
    ; 2014-Oct-09 21:35:51 -0400 cat-pc DEBUG [qualityclj.repl] - startin difficult computashuns
    ; 2014-Oct-09 21:35:51 -0400 cat-pc INFO [qualityclj.repl] - (+ 0 1 2 3 4 5 6) 21
    ; 2014-Oct-09 21:35:51 -0400 cat-pc WARN [qualityclj.repl] - u liek the math 504
    ;=> 504

    Check out Timbre for more information and how to use it’s great logging and profiling capabilities.


    Check out the issues!


    Copyright © 2014 Chris Sims and Scott Bauer