From a9756e452500abd0b940f6fe23b08dd6b2a8846c Mon Sep 17 00:00:00 2001 From: Dominic Monroe Date: Sat, 22 Apr 2017 12:12:57 +0100 Subject: [PATCH] Add support for passing file argument Doing this required introducing proper CLI argument parsing. This was so namespaces could be distinguished from the files. I also introduced non-positional parsing for the nrepl, mostly for conformance. You can now provide either a file or stdin to the binary, and it will be used by kibit when linting. This also introduces support for Neomake, as it requires you to lint the file in-place, instead of being passed the current contents of the buffer via stdin. --- README.adoc | 15 +++++++++- install | 2 +- main.go | 60 ++++++++++++++++++++++++++++++++++------ plugin/clojure-check.vim | 20 +++++++++++--- 4 files changed, 82 insertions(+), 15 deletions(-) diff --git a/README.adoc b/README.adoc index 6e06532..bf79860 100644 --- a/README.adoc +++ b/README.adoc @@ -25,8 +25,10 @@ You can get output from eastwood & kibit on a running nREPL via [source,shell] ---- -$ ./output localhost:33999 app.website < src/app/website.clj +$ ./output -nrepl localhost:33999 -namespace app.website -file - < src/app/website.clj<1> +$ ./output -nrepl localhost:33999 -namespace app.website -file src/app/website.clj ---- +<1> Read from Stdin === REPL setup @@ -64,3 +66,14 @@ There is ALE integration available in this repo. It depends on Fireplace to find Plug 'w0rp/ale' Plug 'SevereOverfl0w/clojure-check', {'do': './install'} ---- + +==== Vim - Neomake + +There is Neomake integration available in this repo. It depends on Fireplace to find connection details. + +---- +Plug 'neomake/neomake' +Plug 'SevereOverfl0w/clojure-check', {'do': './install'} + +let g:neomake_clojure_enabled_makers = ['check'] +---- diff --git a/install b/install index d963f1e..3244cbf 100755 --- a/install +++ b/install @@ -1,6 +1,6 @@ #!/usr/bin/env bash -version=0.1 +version=0.2 cd "$(dirname "${BASH_SOURCE[0]}")" check_base="$(pwd)" bin_name="clojure-check-v$version" diff --git a/main.go b/main.go index 1520fa4..df9d37a 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "io/ioutil" "net" "os" + "flag" // "os/signal" // "syscall" "regexp" @@ -102,8 +103,27 @@ func eastwood(args []string, conn net.Conn) { printmsgid(conn, msgid) } -func kibit(input string, conn net.Conn) { - code := fmt.Sprintf(`(do (require 'kibit.check) (run! (fn [{:keys [file line expr alt]}] (printf "%%s:%%s: Consider using: %%s Instead of %%s\n" file line (pr-str alt) (pr-str expr))) (kibit.check/check-reader (java.io.StringReader. %v))))`, input) +func kibit(input string, file bool, conn net.Conn) { + var reader string + + reporter := `(fn [{:keys [file line expr alt]}] (printf "%s:%s:0: Consider using: %s Instead of %s\n" file line (pr-str alt) (pr-str expr)))` + + if file { + escapedFileBin, err := edn.Marshal(input) + + if err != nil { + fmt.Println(err) + return + } + + escapedFile := string(escapedFileBin) + + reader = fmt.Sprintf(`(kibit.check/check-file (java.io.File. %v) :reporter %v)`, escapedFile, reporter) + } else { + reader = fmt.Sprintf(`(run! %v (kibit.check/check-reader (java.io.StringReader. %v)))`, reporter, input) + } + + code := fmt.Sprintf(`(do (require 'kibit.check) %v)`, reader) msguuid, _ := uuid.NewRandom() msgid := msguuid.String() @@ -144,12 +164,30 @@ func kibit(input string, conn net.Conn) { } } +type namespaceFlags []string + +func (i *namespaceFlags) String() string { + return "my string representation" +} + +func (i *namespaceFlags) Set(value string) error { + *i = append(*i, value) + return nil +} + func main() { - args := os.Args - if len(args) < 2 { + var namespaces namespaceFlags + var file string + var nrepl string + flag.Var(&namespaces, "namespace", "Namespace to lint. Can be repeated multiple times") + flag.StringVar(&file, "file", "-", "File to lint via kibit. If - will be read from stdin. Default is -") + flag.StringVar(&nrepl, "nrepl", "", "nREPL connection details in form of host:port. Required.") + flag.Parse() + + if nrepl == "" { + fmt.Println("nrepl is a required parameter") return } - nrepl := args[1] conn, err := net.Dial("tcp", nrepl) if err != nil { @@ -166,9 +204,13 @@ func main() { // os.Exit(1) // }() - eastwood(args[2:], conn) + eastwood(namespaces, conn) - source_file_bytes, err := ioutil.ReadAll(os.Stdin) - b, err := edn.Marshal(string(source_file_bytes)) - kibit(string(b), conn) + if file == "-" { + source_file_bytes, _ := ioutil.ReadAll(os.Stdin) + b, _ := edn.Marshal(string(source_file_bytes)) + kibit(string(b), false, conn) + } else { + kibit(file, true, conn) + } } diff --git a/plugin/clojure-check.vim b/plugin/clojure-check.vim index f1ae552..857e48e 100644 --- a/plugin/clojure-check.vim +++ b/plugin/clojure-check.vim @@ -7,10 +7,9 @@ if exists('g:loaded_clojure_check') endif let g:loaded_clojure_check = 1 -let s:check_version = '0.1' +let s:check_version = '0.2' let s:base_dir = expand(':h:h') -" let s:clojure_check_bin = s:base_dir.'/bin/clojure-check-v'.s:check_version -let s:clojure_check_bin = s:base_dir.'clojure-check' +let s:clojure_check_bin = s:base_dir.'/bin/clojure-check-v'.s:check_version function! s:ClojureHost() return fireplace#client().connection.transport.host @@ -20,9 +19,13 @@ function! s:ClojurePort() return fireplace#client().connection.transport.port endfunction +function! s:ClojureCheckArgs(buffer) + return ['-nrepl', s:ClojureHost().':'.s:ClojurePort(), '-namespace', fireplace#ns(a:buffer)] +endfunction + function! ClojureCheck(buffer) try - return s:clojure_check_bin.' '.s:ClojureHost().':'.s:ClojurePort().' '.fireplace#ns(a:buffer) + return s:clojure_check_bin.' '.join(s:ClojureCheckArgs(a:buffer) + ['-file', '-'], ' ') catch /Fireplace/ return '' endtry @@ -37,3 +40,12 @@ try \}) catch /E117/ endtry + +let g:neomake_clojure_check_maker = { + \ 'exe': s:clojure_check_bin, + \ 'errorformat': '%f:%l:%c: %m', + \ } + +function! g:neomake_clojure_check_maker.args() + return s:ClojureCheckArgs(bufnr('%'))+ ['-file'] +endfunction