Skip to content

Commit

Permalink
add working-dir flag
Browse files Browse the repository at this point in the history
`--working-dir /path/to/some/place/on/disk` will override the localtion
of where joker will start looking for a `.joker` config file.

This allows for `.joker` config file detection when reading from stdin
even if your present working directory does not contain a `.joker` file.
  • Loading branch information
nicwest committed Nov 24, 2017
1 parent 90bbd1f commit a0e5fde
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 10 deletions.
1 change: 1 addition & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ dependencies:
- go generate -v ./...
- go build -v
- ./linter-tests.sh
- ./flag-tests.sh
15 changes: 12 additions & 3 deletions core/procs.go
Original file line number Diff line number Diff line change
Expand Up @@ -1400,12 +1400,21 @@ func processData(data []byte) {
GLOBAL_ENV.ns.Value = currentNamespace
}

func findConfigFile(filename string) string {
func findConfigFile(filename string, workingDir string) string {
filename, err := filepath.Abs(filename)
if err != nil {
fmt.Fprintln(os.Stderr, "Error reading config file "+filename+": ", err)
return ""
}

if workingDir != "" {
workingDir, err = filepath.Abs(workingDir)
if err != nil {
fmt.Fprintln(os.Stderr, "Error resolving working directory"+workingDir+": ", err)
return ""
}
filename = filepath.Join(workingDir, ".joker")
}
for {
oldFilename := filename
filename = filepath.Dir(filename)
Expand Down Expand Up @@ -1455,10 +1464,10 @@ func knownMacrosToMap(km Object) (Map, error) {
return res, nil
}

func ReadConfig(filename string) {
func ReadConfig(filename string, workingDir string) {
LINTER_CONFIG = GLOBAL_ENV.CoreNamespace.Intern(MakeSymbol("*linter-config*"))
LINTER_CONFIG.Value = EmptyArrayMap()
configFileName := findConfigFile(filename)
configFileName := findConfigFile(filename, workingDir)
if configFileName == "" {
return
}
Expand Down
3 changes: 3 additions & 0 deletions flag-tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

./joker tests/run-flag-tests.joke
19 changes: 12 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,12 @@ func detectDialect(filename string) Dialect {
return CLJ
}

func lintFile(filename string, dialect Dialect) {
func lintFile(filename string, dialect Dialect, workingDir string) {
phase := PARSE
if dialect == EDN {
phase = READ
}
ReadConfig(filename)
ReadConfig(filename, workingDir)
configureLinterMode(dialect)
if processFile(filename, phase) == nil {
WarnOnUnusedNamespaces()
Expand All @@ -202,6 +202,7 @@ var parseFlag = pflag.Bool("parse", false, "parse the file")
var lintFlag = pflag.Bool("lint", false, "lint the file")

var lintDialect = pflag.String("dialect", "", "dialect to lint as. Valid options are clj, cljs, joker and edn")
var lintWorkingDir = pflag.String("working-dir", "", "override the working directory for the linter")

// these flags are here to support the preexisting `--lint<dialect>` flags:
var lintCljFlag = pflag.Bool("lintclj", false, "lint as clojure")
Expand Down Expand Up @@ -231,7 +232,7 @@ func init() {
case *lintJokerFlag:
*lintFlag = true
*lintDialect = "joker"
case *lintJokerFlag:
case *lintEDNFlag:
*lintFlag = true
*lintDialect = "edn"
}
Expand All @@ -242,8 +243,6 @@ func main() {
switch {
case *versionFlag:
println(VERSION)
case len(pflag.Args()) == 0:
repl(EVAL)
case *readFlag:
processFile(pflag.Arg(0), READ)
case *parseFlag:
Expand All @@ -262,8 +261,14 @@ func main() {
default:
dialect = detectDialect(pflag.Arg(0))
}
lintFile(pflag.Arg(0), dialect)
default:
filename := pflag.Arg(0)
if filename == "" {
filename = "--"
}
lintFile(filename, dialect, *lintWorkingDir)
case len(pflag.Args()) > 0:
processFile(pflag.Arg(0), EVAL)
default:
repl(EVAL)
}
}
1 change: 1 addition & 0 deletions tests/flags/config/.joker
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{:known-macros [foobar.macros/defthing]}
1 change: 1 addition & 0 deletions tests/flags/input-warning.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(let [a 1] "foo")
1 change: 1 addition & 0 deletions tests/flags/input.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(clojure.string/split "foobar")
1 change: 1 addition & 0 deletions tests/flags/input.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(.log js/console)
1 change: 1 addition & 0 deletions tests/flags/input.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{:foobar #foo/bar "something something"}
1 change: 1 addition & 0 deletions tests/flags/input.joke
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(joker.string/split "ha-ha-ha-ha" #"-")
6 changes: 6 additions & 0 deletions tests/flags/macro.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(ns test.foo
(:require [foobar.macros :refer [defthing]]))

(defthing something
"pewpew")

111 changes: 111 additions & 0 deletions tests/run-flag-tests.joke
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
(def exit-code 0)

(defn clean
[output]
(let [output (if (nil? output) "" output)]
(->> output
(joker.string/split-lines)
(remove #(joker.string/starts-with? % " "))
(remove #(= % ""))
(joker.string/join "\n"))))

(defn test-flags
[description flags expected]
(let [pwd (get (joker.os/env) "PWD")
flag-parts (joker.string/split flags #" ")
stdin? (some #(= "<" %) flag-parts)
cmd (str pwd "/joker")
output (if stdin?
(:err (joker.os/sh "sh" "-c" (str cmd " " flags)))
(:err (apply (partial joker.os/sh cmd) flag-parts)))
output (clean output)]
(when-not (= output expected)
(println "FAILED: testing" description "(" flags ")")
(println "EXPECTED")
(println expected)
(println "ACTUAL")
(println output)
(println "")
(var-set #'exit-code 1))))

(defn testing
[description & tests]
(let [tests (partition 2 tests)]
(doall (map (fn [[flags expected]]
(test-flags description flags expected)) tests))))

(testing "auto detect dialect from filename"
"--lint tests/flags/input.clj"
""
"--lint tests/flags/input-warning.clj"
"tests/flags/input-warning.clj:1:7: Parse warning: unused binding: a")

(testing "specify joker dialect"
"--lintjoker tests/flags/input.joke"
""

"--lint --dialect joker tests/flags/input.joke"
""

"--lintjoker tests/flags/input.clj"
"tests/flags/input.clj:1:2: Parse error: Unable to resolve symbol: clojure.string/split"

"--lint --dialect joker tests/flags/input.cljs"
"tests/flags/input.cljs:1:7: Parse error: Unable to resolve symbol: js/console")

(testing "specify clj dialect"
"--lintclj tests/flags/input.clj"
""

"--lint --dialect clj tests/flags/input.clj"
""

"--lintclj tests/flags/input.edn"
"tests/flags/input.edn:1:17: Read warning: No reader function for tag foo/bar"

"--lint --dialect clj tests/flags/input.cljs"
"tests/flags/input.cljs:1:7: Parse error: Unable to resolve symbol: js/console")

(testing "specify cljs dialect"
"--lintcljs tests/flags/input.cljs"
""

"--lint --dialect cljs tests/flags/input.cljs"
""

"--lintcljs tests/flags/input.edn"
"tests/flags/input.edn:1:17: Read warning: No reader function for tag foo/bar"

"--lintcljs tests/flags/input.clj"
"tests/flags/input.clj:1:2: Parse error: Unable to resolve symbol: clojure.string/split")

(testing "reading from stdin"
"--lint --dialect edn < tests/flags/input.edn"
""

"--lint --dialect clj < tests/flags/input.edn"
"<stdin>:1:17: Read warning: No reader function for tag foo/bar"

"--lint --dialect clj < tests/flags/input.clj"
""

"--lint --dialect cljs < tests/flags/input.clj"
"<stdin>:1:2: Parse error: Unable to resolve symbol: clojure.string/split"

"--lint --dialect cljs < tests/flags/input.cljs"
""

"--lint --dialect joker < tests/flags/input.cljs"
"<stdin>:1:7: Parse error: Unable to resolve symbol: js/console"

"--lint --dialect joker < tests/flags/input.joke"
"")

(testing "working direction override"
"--lint --dialect clj < tests/flags/macro.clj"
"<stdin>:4:11: Parse error: Unable to resolve symbol: something"

"--lint --dialect clj --working-dir tests/flags/config < tests/flags/macro.clj"
"")

(joker.os/exit exit-code)

0 comments on commit a0e5fde

Please sign in to comment.