1
1
(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]]
4
7
[lambdaisland.deep-diff2 :as ddiff]
5
- [clojure.java.io :as io])
8
+ [editscript.core :refer [diff] :rename {diff compact-diff}])
9
+
6
10
(:gen-class ))
7
11
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'" ]]])
8
17
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 "
11
20
[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 })))
14
35
15
36
(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))
23
47
24
48
(defn -main
25
- " Main function"
49
+ " main function"
26
50
[& 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