agilecreativity / clj-scratch

Clojure REPL with features loaded ready to be productive

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Scratch

Clojure REPL with features loaded ready to be productive

Being able to explore a problem with programming tools in an interactive fashion can be very productive.

There have been countless times I had to do some one-off investigating and a wrote a quick shell one-liner that grew into a monster of ten pipes with five sub-shells, three xargs and quoted quotes within quoted quotes.

Clojure is an amazing tool for interactive tasks, but just starting up a plain REPL, it's hard to be productive right away for one-off tasks. You need to load some additional libraries depending on your context.

scratch is an opinionated toolbox to have everything ready whenever I realize my shell commands are getting out of hand again.

Of course loading all these dependencies comes at a cost, however not being interrupted while working on a problem can be a good trait-off, especially if you keep the same REPL session running for most of the time anyways. The most common tools are required by default and the other dependencies can be loaded on demand.

Run It

Try it out with:

clojure -Sdeps '{:deps {clj-scratch {:git/url "https://github.com/jorinvo/clj-scratch" :sha "c7dfa3e6f496e30d5ff39506fb893c5fc733081c"}}}' -m scratch

A Git hash can be used to simply try out the REPL without downloading anything manually, but I prefer using a local copy of the repository so I can easily adopt changes as I go.

I created an alias like this:

alias scratch='clojure -Sdeps "{:deps {clj-scratch {:local/root \"/path/to/clj-scratch\"}}}" -m scratch'

Features

Dev Tools

OS

  • Info About Operating System in vars username, home, pwd, os
  • Run shell commands using (sh "cowsay" "hi")

File System

  • Directory listing with (ls) or (ls "some/path")
  • Check file properties with helpers like (dir? "some/path") and (exists? "some/path")
  • Also clojure.java.io is available as io. Checkout (jmethods (io/file "."))

JSON

  • Using jsonista
  • Read JSON from file or streams with (json/read (io/file "some.json"))
  • Output data as JSON with (json/str data), (json/strp data) or (json/write "path/out.json" data)

Networking

  • Check network types with helpers like (valid-port? 112233) or (valid-url? "not-valid")
  • Get host name from URL with (hostname "https://example.com")
  • Get a random free port with (get-free-port)
  • Ping a domain with (ping "example.com")
  • Get IPs for a domain with (nslookup "example.com")

Aleph

Aleph provides great tooling to work with HTTP, WebSockets, TCP and UDP as client and server.

It's included as dependency but not loaded by default:

(require '[aleph.http :as http]
         '[aleph.tcp :as tcp]
         '[aleph.udp :as udp]
         '[byte-streams :as byte-streams]
         '[manifold.stream :as stream]
         '[manifold.deferred :as deferred])

Example - Make a HTTP requests:

(-> @(http/get "https://example.com") :body byte-streams/to-string)

Checkout Aleph for more.

HTML

  • hiccup to generate HTML
  • Parse HTML with tagsoup
  • Use specter to transform deeply nested structures (like HTML!)

The tools are included as dependencies but not loaded by default:

(require '[hiccup.core :refer [html]])
(require '[com.rpl.specter :as specter])
(require '[pl.danieljanus.tagsoup :as tagsoup])

(def data (tagsoup/parse "https://example.com"))

(def CHILDREN (specter/nthpath 2))

(defn where-tag [tag]
  [(specter/pred #(= tag (first %))) CHILDREN])

(def TITLE [CHILDREN
            (where-tag :head)
            (where-tag :title)])

(html (specter/transform TITLE str/upper-case data))

SQL

  • jdbc is available
  • Make sure to require it first:
(require '[clojure.java.jdbc :as jdbc])
  • SQLite, PostgreSQL and MySQL drivers are included

Working with time

(require '[java-time :as time])
  • There are excellent examples here

Cryptography

  • buddy is included to provide crypto functionality
(require '[buddy.core.hash :as hash]
         '[buddy.core.mac :as mac]
         '[buddy.core.codecs :as codecs]
         '[buddy.core.codecs.base64 :as base64]
         '[buddy.hashers :as hashers])
  • Common namespaces are available: hash, mac, codecs, base64`` hashers
  • sha hash: (-> (hash/sha256 "some val") (codecs/bytes->hex))
  • base64 string: (codecs/bytes->str (base64/encode "some val"))

More core data structures

Commonly used core namespaces are already available:

[clojure.edn :as edn]
[clojure.data :refer [diff]]
[clojure.set :as set]
[clojure.string :as str]
[clojure.walk :refer [postwalk]]
[clojure.spec.alpha :as spec]

License

MIT

About

Clojure REPL with features loaded ready to be productive

License:MIT License


Languages

Language:Clojure 100.0%