Commit 2de66e6a authored by phil's avatar phil

multiple changes

- upgrade lumo
- add lumo as dev dependency
- introduce debug logging via log/debug and -d
- assert-exactly-one
- fix add period
- introduce safe-transform, which wraps transform in an error handler
- use context (binned events) in all subcommands
parent 28faaa21
......@@ -15,4 +15,4 @@ fi
KLASSPATH=$(cat $KLASSPATHFILE)
export NODE_PATH=$BASEDIR/node_modules
exec lumo -K -c "$KLASSPATH" -m easy.core $@
exec $BASEDIR/node_modules/.bin/lumo -K -c "$KLASSPATH" -m easy.core $@
......@@ -1055,6 +1055,12 @@
"log-utils": "^0.2.1"
}
},
"lumo-cljs": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/lumo-cljs/-/lumo-cljs-1.10.1.tgz",
"integrity": "sha512-pqgygbEEnzOjFUxejr/jK7gRhuQx0acd3PLyJwkz4ZyVHWyzGGhUxwzgYX/df4wKm7Zixfp73G0S0PFXiNHULQ==",
"dev": true
},
"map-cache": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
......
......@@ -21,5 +21,8 @@
"js-yaml": "^3.12.0",
"sprintf-js": "^1.1.2",
"sync-exec": "^0.6.2"
},
"devDependencies": {
"lumo-cljs": "^1.10.1"
}
}
......@@ -2,6 +2,7 @@
(:require [cljs.spec.alpha :as s]
[easy.config :refer [config]]
[easy.util :as util :refer [assoc*]]
[easy.log :as log]
[easy.common :as common]))
......@@ -16,21 +17,34 @@
:opt-un [::since
::until]))
(s/def ::rates (s/coll-of ::rate-entry))
(s/def ::rates (s/coll-of ::rate-entry :kind vector?))
;; helpers
(defn- assert-exactly-one [coll]
(case (count coll)
;; non found -> abort
0 (util/die "Collection with one expected entry found empty!")
;; all good
1 (first coll)
;; else (more than 1)
(do
(util/warn (str "Found more than one entry in collection, "
"when exactly one was expected. "
"Just picked the first from " coll))
(first coll))))
(defn lookup-rate
[key {:keys [date]}]
(->> @config
key
(common/validate! ::rates)
;; TODO: use `(common/validate! ::rates)` here
(filter #(or (nil? (:since %)) (>= date (:since %))))
(filter #(or (nil? (:until %)) (<= date (:until %))))
;; TODO: assert-exactly-one!
first
assert-exactly-one
:rate))
......@@ -44,4 +58,4 @@
year (.getFullYear date)
semester (if (< (.getMonth date) 6) 1 2)
period (str year "-H" semester)]
(assoc* evt :period)))
(assoc* evt :period period)))
......@@ -5,10 +5,11 @@
[easy.config :as config :refer [config]]
[easy.customers :as customers]
[easy.templating :as templating]
[easy.transform :refer [transform]]
[easy.transform :refer [safe-transform]]
[easy.overview :as overview]
[easy.invoice :as invoice]
[easy.common :as common]
[easy.log :as log]
[easy.common.invoice-no :as invoice-no]
[clojure.tools.cli :refer [parse-opts]]
[cljs.pprint :refer [pprint]]
......@@ -36,13 +37,11 @@
"Transforms all events, renders and prints their ledger
representation."
[events options]
;; TODO: use the context building with bin-by in every other
;; subcommand as well
(let [context (util/bin-by (comp keyword :type) events)]
(->> events
(map invoice-no/unify)
;; transform all events within the `context`
(map (partial transform context))
(map (partial safe-transform context))
;; filter to the events that belong to the year given with -y
;; TODO: do not filter when year is not given
(filter #(.startsWith (:iso-date %) (:year options)))
......@@ -54,15 +53,16 @@
(defn invoice!
"Generates an invoice PDF and prints a report."
[events options]
(->> events
(filter #(= "invoice" (:type %)))
(map invoice/add-invoice-no)
(filter #(= (:invoice-no %) (:no options)))
first
(transform events)
invoice/transform-latex!
templating/render-report
println))
(let [context (util/bin-by (comp keyword :type) events)]
(->> events
(filter #(= "invoice" (:type %)))
(map invoice/add-invoice-no)
(filter #(= (:invoice-no %) (:no options)))
first
(safe-transform context)
invoice/transform-latex!
templating/render-report
println)))
(defn transform!
......@@ -70,7 +70,7 @@
[events options]
(let [context (util/bin-by (comp keyword :type) events)]
(->> events
(map (partial transform context))
(map (partial safe-transform context))
pprint)))
......@@ -81,20 +81,23 @@
(defn validate!
"Validates all input events and exits."
"Validates all input events and exits. Good to check for warnings."
[events options]
(->> events
(map (partial transform events))))
(let [context (util/bin-by (comp keyword :type) events)]
(->> events
(map (partial safe-transform context))
doall)))
(defn overview!
"Renders an overview."
[events options]
(->> events
(map (partial transform events))
overview/crunch-numbers
templating/render-overview
println))
(let [context (util/bin-by (comp keyword :type) events)]
(->> events
(map (partial safe-transform context))
overview/crunch-numbers
templating/render-overview
println)))
;; main
......@@ -141,7 +144,8 @@
(def cli-options
[["-i" "--input INPUT" "Input file"]
[["-d" "--debug" "Debug output"]
["-i" "--input INPUT" "Input file"]
["-y" "--year NUMBER" "Year"]
["-n" "--no NUMBER" "Invoice No"]])
......
......@@ -103,6 +103,6 @@
util/slurp
util/parse-yaml
(util/validate! ::customers)
merge-defaults
(map merge-defaults)
(map transform)
(util/validate! ::customers)))
......@@ -18,12 +18,13 @@
```"
(:require [cljs.spec.alpha :as s]
[easy.util :as util :refer [assoc*]]
[easy.log :as log]
[easy.common :as common]
[easy.common.invoice-no :as invoice-no]
[easy.common.tax :as tax]
[easy.templating :as templating]
[easy.config :refer [config]]
[easy.transform :refer [transform]]
[easy.transform :refer [transform safe-transform]]
[easy.invoice.item :as item]
[easy.customers :as customers]
[clojure.string :refer [join replace split]]
......@@ -121,7 +122,7 @@
(->> ctx
(filter #(= invoice-no (:invoice-no %)))
first
(transform nil)
(safe-transform nil)
(assoc* evt :settlement))))
......
(ns easy.log
(:require [clojure.pprint :refer [pprint]]
[clojure.string :refer [join replace]]
[easy.config :refer [config]]))
(defn warn [msg]
(.error js/console (clj->js msg))
msg)
(defn debug [& args]
(if (-> @config :options :options :debug)
(->> args
reverse
(apply prn-str)
warn))
(first args))
;; (defn spy [& args]
;; (apply pprint args)
;; (last args))
......@@ -40,8 +40,7 @@
(defn- add-redistribution-factor
[account {:keys [redistribution-factor] :or {redistribution-factor 0.1}}]
(--> account
(assoc* :redistribution-factor redistribution-factor)))
(assoc* account :redistribution-factor redistribution-factor))
(defn- add-redistribution-amount [account]
......
......@@ -9,11 +9,13 @@
```"
(:require [cljs.spec.alpha :as s]
[easy.util :as util :refer [assoc*]]
[easy.log :as log]
[easy.common :as common]
[easy.common.tax :as tax]
[easy.common.invoice-no :as invoice-no]
[easy.templating :as templating]
[easy.config :refer [config]]
[easy.transform :refer [transform]]
[easy.transform :refer [transform safe-transform]]
[easy.settlement.item :as item]
[easy.customers :as customers]
[clojure.string :refer [join replace split]]
......@@ -101,7 +103,7 @@
(->> context
(filter #(= invoice-no (:invoice-no %)))
first
(transform nil)
(safe-transform nil)
(assoc* evt :invoice))))
......@@ -273,6 +275,7 @@
(defn add-debug [evt]
(assoc* evt :debug (prn-str evt)))
;; `context` can be a map of types and vectors of events
;;
;; `context` can also be nil, this is the case if the event is
......@@ -286,7 +289,7 @@
(assert-invoice! context)
add-deferral
common/add-iso-date
add-period
tax/add-period
add-tax-rate-in
add-tax-rate-out
transform-items
......
......@@ -2,7 +2,8 @@
"The transform function is no only a multimethod but also
overloaded (i.e. has multiple arities). Transform has to has its own
namespace to avoid cyclic dependencies."
(:require [easy.util :as util]))
(:require [easy.util :as util]
[easy.config :refer [config]]))
(defmulti transform
......@@ -23,3 +24,16 @@
;; silently ignoring transformation of nil
(defmethod transform nil [_ _]
nil)
(defn safe-transform [ctx evt]
(if (-> @config :options :options :debug)
(prn (str "TRANSFORM " (:type evt))))
(try
(transform ctx evt)
(catch :default e
(util/warn (str "Transform failed with `"
e "` on\n\n" (util/write-yaml evt)
"\n" (.-stack e)))
(process.exit 1) ;; halt on error
evt)))
......@@ -6,7 +6,8 @@
["js-yaml" :as yaml]
["sync-exec" :as exec]
["sprintf-js" :refer [sprintf]]
[cljs-time.format :as time]))
[cljs-time.format :as time]
[clojure.string :as str]))
(defn bin-by
......@@ -26,7 +27,6 @@
(replace "#" "\\#")
(replace "&" "\\&")))
(defn warn [msg]
(.error js/console (clj->js msg))
msg)
......@@ -55,6 +55,20 @@
(.writeFileSync fs path content))
(defn indent
"Indents a multiline string `s` by `n` spaces."
[s n]
(let [i (apply str (repeat n " "))]
(str i (str/replace s "\n" (str "\n" i)))))
(defn write-yaml [x]
(-> x
clj->js
yaml/safeDump
(indent 2)))
(defn parse-yaml [string]
(-> (yaml/load string)
(js->clj :keywordize-keys true)))
......@@ -119,3 +133,8 @@
(defn exit [c]
(.exit js/process (or c 0)))
(defn die [s]
(warn s)
(exit 1))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment