11(ns json-diff.core
2- (:require [clojure.data.json :as json]
3- [clojure.core.async :refer [>! <!! go chan]]
2+ (:require [clojure.string :as str]
3+ [clojure.java.io :as io]
4+ [clojure.data.json :as json]
5+ [clojure.core.async :refer [<!! go]]
6+ [clojure.tools.cli :refer [parse-opts]]
47 [lambdaisland.deep-diff2 :as ddiff]
5- [clojure.java.io :as io])
8+ [editscript.core :refer [diff] :rename {diff compact-diff}])
9+
610 (:gen-class ))
711
12+ (def cli-options
13+ [[" -m" " --mode MODE" " operation mode: 'visual' or 'patch'"
14+ :default :patch
15+ :parse-fn #(keyword %)
16+ :validate [#(% #{:visual :patch }) " possible modes are 'visual' or 'patch'" ]]])
817
9- (defn open- parse
10- " open JSON file and parses it"
18+ (defn parse-async
19+ " opens JSON file and parses it asynchronously, returns channel "
1120 [file-name]
12- (with-open [f (io/reader file-name)]
13- (json/read f)))
21+ (go (with-open [f (io/reader file-name)]
22+ (json/read f))))
23+
24+ (defn process
25+ [f & files]
26+ (->> files
27+ (map parse-async)
28+ (map <!!)
29+ (apply f)))
30+
31+ (defn patch
32+ " prints compact patch between two JSON objects"
33+ [left right]
34+ (println (compact-diff left right {:algo :quick })))
1435
1536(defn diff
16- " returns diff between JSON files"
17- [file-name1 file-name2]
18- (let [c1 (chan )
19- c2 (chan )]
20- (go (>! c1 (open-parse file-name1)))
21- (go (>! c2 (open-parse file-name2)))
22- (ddiff/diff (<!! c1) (<!! c2))))
37+ " prints visual diff between two JSON objects"
38+ [left right]
39+ (ddiff/pretty-print
40+ (ddiff/diff left right)))
41+
42+ (defn print-error-exit
43+ " prints error message and exits with error code"
44+ [msg code]
45+ (println msg)
46+ (System/exit code))
2347
2448(defn -main
25- " Main function"
49+ " main function"
2650 [& args]
27- (if (> 2 (count args))
28- (println " Not enough parameters!" )
29- (ddiff/pretty-print
30- (diff
31- (first args)
32- (second args)))))
51+ (let [{files :arguments
52+ errors :errors
53+ {:keys [mode]} :options } (parse-opts args cli-options)]
54+ (cond
55+ errors (print-error-exit (str/join " \n " errors) 1 )
56+ (not= 2 (count files)) (print-error-exit " you need to pass two JSON files!" 1 )
57+ (= :visual mode) (apply process diff files)
58+ (= :patch mode) (apply process patch files))))
0 commit comments