Fork me on GitHub
#beginners
<
2021-11-21
>
Eddie01:11:38

What is the easiest way to run a library’s tests on cljs? All I want is for CI to check compatibility.

Michael Lewis01:11:47

hi, I’m 100% new to Clojure, thought I’ve done FP for years with variously Scala/Haskell etc. I wanted to learn Clojure, one thing I’m trying to find out - is there a ‘community standard’ equivalent to say Python’s Sphinx (Scala SBT Microsites etc) I’d like to learn by doing a small project and like to have that stuff setup at the start….

Eddie02:11:30

The most common tools that I am aware of are https://github.com/weavejester/codox and https://cljdoc.org/. They both take somewhat different approaches to generating documentation sites.

Michael Lewis09:11:27

@U7XR2PZFW Thanks very much. I’ll take a look.

Benjamin09:11:13

Hi what is a useful example where spec/conform destructures something

(s/def ::distance (s/cat :amount (s/and number? pos?)
                         :unit #{:meters :miles}))

(s/conform ::distance [3 :meters])
this is already quite sick so I know about sequential ones now. Is there more?

pavlosmelissinos11:11:31

Not exactly destructuring but conforming s/or is quite interesting:

(s/def ::distance (s/cat :amount (s/and number? pos?)
                          :unit   (s/or :predefined #{:meters :miles} :custom string?)))

(s/conform ::distance [3 :meters])
;;=> {:amount 3, :unit [:predefined :meters]}

(s/conform ::distance [3 "league"])
;;=> {:amount 3, :unit [:custom "league"]}

👀 1
Benjamin11:11:59

I love the idea of defining a data shape and conforming to it.

Benjamin12:11:23

Is there a way to say "i want an x, but if it's a y, then use fn ... to transform to x". Basically I'm asking for nested comforming. Or a spec that takes the return value of the validation function instead of just checking boolean

pavlosmelissinos13:11:54

spec is not meant to be used for coercion

pavlosmelissinos13:11:35

Just use normal clojure functions before you validate your input with spec. There are third party libraries that do coercion based on spec, e.g. https://github.com/metosin/spec-tools/blob/master/docs/01_coercion.md

Benjamin13:11:38

I also saw a stackoverflow answer quoting Alex Miller to not do it kappa

cdeszaq01:11:17

Alternatively, use Spec to conform the “raw” (uncoerced) data into a known shape, and then coerce it from there into the shape you want. The tighter your bounds, the less complexity your coercion has to deal with.

Mor Gazith11:11:24

hey, i’m trying to decode a base64 string representing a png file, but keep getting 0xefbfbd (AKA REPLACEMENT CHARACTER) in the resulting string, making the resulting png file corrupt. i’ve tried using java.util.Base64 like so:

(:import (java.util Base64))
...
(defn decode [attachment]
  (let [decoded (->> attachment :data (.decode (Base64/getDecoder)))]
    (String. decoded "UTF-8")))
tried using org.apache.commons.codec.binary.Base64 like this:
(:import (org.apache.commons.codec.binary Base64))
...
(defn decode [attachment]
  (-> attachment :data Base64/decodeBase64 (String.)))
also tried using byte-streams:
(:require [byte-streams :refer (seq-of bytes=) :as bytes])
...
(:import (org.apache.commons.codec.binary Base64))
...
(defn decode [attachment]
  (bytes/to-string (Base64/decodeBase64 (bytes/to-byte-array (:data attachment)))))
i then spit the result to a file, and it always of size 61k, while the original one was 35k, and it starts with: efbf bd50 4e47 instead of 8950 4e47 what am i doing wrong?

alexmiller13:11:35

Spit is for character streams not binary data

Mor Gazith14:11:37

thanks, that worked so it seems that this works for producing a binary decoded object:

(let [contents (-> attachment :data Base64/decodeBase64)]
however when i try to put that as the body of an httpkit/request i get class [B is not understandable when i try to cast it to a string like:
(String. contents) 
the POST body is again corrupt i’m trying to send a POST request with a binary body, any ideas?

Michael W15:11:28

For HTTP you normally set the mime type to "application/octet-stream" and don't transform the binary before posting.

Mor Gazith15:11:54

i’ve tried that, but it didn’t work. just got it working now by wrapping the binary body with a java inputstream via: (.ByteArrayInputStream. contents)

Michael W15:11:09

What HTTP client are you using?

popeye18:11:52

is there any book and learning material to write complete secured real time web application in clojure?

Andy Carlile19:11:41

hello wizards, i just recently finished a https://github.com/jollyblondgiant/cljs-pokedex built from the lein new re-frame <app> template and am attempting to deploy it, either to heroku or to github pages. attempting to deploy to heroku with git push heroku master fails with npm ERR! missing script: start ; deploying to github pages fails because requests to load in my app.js fail with a 404 . I've set up my index.html according to https://clojureverse.org/t/deploying-a-shadow-cljs-project-very-new-to-web-development/5299/2 but while https://jollyblondgiant.github.io/cljs-pokedex/ can find its css, it apparently doesn't find any javascript. what updates do I need to make to enable deployment on heroku? github? thank you so much!

Andy Carlile21:11:00

I've updated my repo with a procfile and project.clj for heroku deployment and my app appears to build, only for this error in my heroku logs --tail : bash: shadow-cljs: command not found

Andy Carlile22:11:51

do I have to jar up my project? I ran npm install && npm run release before committing and git push heroku master . what's a good Procfile for an app made with shadow-cljs?

runswithd6s22:11:24

Try npx shadow-cljs. Unless you install shadow-cljs globally, your path won't see the executable. Using npx will wrapper that in the npm environment appropriately.

runswithd6s22:11:53

Alternative, npm install -g shadow-cljs before your npm install && npm run release. I generally put the npx shadow-cljs COMMAND in the npm script commands.

Andy Carlile22:11:36

where can i set such npm script commands? is that in shadow-cljs.edn or with heroku?

Andy Carlile22:11:10

my errors advanced: now I get to

Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
Stopping process with SIGKILL
Process exited with status 137
State changed from starting to crashed
but i bound :nrepl {:port process.env.PORT} in my shadow-cljs.edn. is this not where that goes?

Andy Carlile22:11:17

btw your note of using npm install -g shadow-cljs was the ticket to move past bash: shadow-cljs not found error

dpsutton22:11:28

You shouldn't be building clojurescript on Heroku. You should build a jar once you have compiled a production build

Andy Carlile22:11:15

where can I read up on how to do this? I compiled prod with npm run release

dpsutton22:11:13

I don't know of a good guide. It can be tough to find good resources for how to build a jar. There are lots of concepts that can be overwhelming as a beginner. I'm away from my computer so I cannot locate any resources for you right now unfortunately

Andy Carlile22:11:37

I tried:

clj -M -m cljs.main --optimizations advanced -c hello-world.core
but get:
Execution error (FileNotFoundException) at clojure.main/main (main.java:40).
Could not locate cljs/main__init.class, cljs/main.clj or cljs/main.cljc on classpath.
I added a deps.edn : {:deps {org.clojure/clojurescript {:mvn/version "1.10.758"}}} and still get the same error

Andy Carlile22:11:23

alternatively, is it possible to host this on github pages? I can't quite get all my resources, most notably my app.js, to load

Ngoc Khuat23:11:21

I haven’t tried but I think we could. Alternatively you can use https://vercel.com . You just need to tell vercel: • build command : I configured npm run release => shadow-cljs release {APP_NAME} • Path to build output : for my case it’s public/ For reference : this is the repo I deployed to vercel : https://github.com/qnkhuat/rtdraw

Andy Carlile00:11:52

thank you so much! I got deployed here: https://cljs-pokedex.vercel.app/ however, it looks like it's having trouble importing one of my font stylesheets.

🙌 1
pokeball 1