Add json1 format that ignores tabs
The new json1 format works just like json except that it treats tabs as single characters instead of 8-character tabstops. The main use case is to allow editors to pass -fjson1 so that they can consume the json output in a character-oriented way without breaking backwards compatibility. Also addresses #1048.
This commit is contained in:
parent
5fb1da6814
commit
50af8aba29
|
@ -7,6 +7,7 @@
|
||||||
Enable with `-o` flags or `enable=name` directives
|
Enable with `-o` flags or `enable=name` directives
|
||||||
- Source paths: Use `-P dir1:dir2` or a `source-path=dir1` directive
|
- Source paths: Use `-P dir1:dir2` or a `source-path=dir1` directive
|
||||||
to specify search paths for sourced files.
|
to specify search paths for sourced files.
|
||||||
|
- json1 format like --format=json but treats tabs as single characters
|
||||||
- SC2249: Warn about `case` with missing default case (verbose)
|
- SC2249: Warn about `case` with missing default case (verbose)
|
||||||
- SC2248: Warn about unquoted variables without special chars (verbose)
|
- SC2248: Warn about unquoted variables without special chars (verbose)
|
||||||
- SC2247: Warn about $"(cmd)" and $"{var}"
|
- SC2247: Warn about $"(cmd)" and $"{var}"
|
||||||
|
|
|
@ -153,7 +153,7 @@ not warn at all, as `ksh` supports decimals in arithmetic contexts.
|
||||||
|
|
||||||
: Json is a popular serialization format that is more suitable for web
|
: Json is a popular serialization format that is more suitable for web
|
||||||
applications. ShellCheck's json is compact and contains only the bare
|
applications. ShellCheck's json is compact and contains only the bare
|
||||||
minimum.
|
minimum. Tabs are 8 characters.
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
@ -167,6 +167,11 @@ not warn at all, as `ksh` supports decimals in arithmetic contexts.
|
||||||
...
|
...
|
||||||
]
|
]
|
||||||
|
|
||||||
|
**json1**
|
||||||
|
|
||||||
|
: This is the same as shellcheck's json format, but tabs are treated as
|
||||||
|
single characters instead of 8-character tabstops.
|
||||||
|
|
||||||
*quiet*
|
*quiet*
|
||||||
|
|
||||||
: Suppress all normal output. Exit with zero if no issues are found,
|
: Suppress all normal output. Exit with zero if no issues are found,
|
||||||
|
|
|
@ -141,7 +141,8 @@ formats :: FormatterOptions -> Map.Map String (IO Formatter)
|
||||||
formats options = Map.fromList [
|
formats options = Map.fromList [
|
||||||
("checkstyle", ShellCheck.Formatter.CheckStyle.format),
|
("checkstyle", ShellCheck.Formatter.CheckStyle.format),
|
||||||
("gcc", ShellCheck.Formatter.GCC.format),
|
("gcc", ShellCheck.Formatter.GCC.format),
|
||||||
("json", ShellCheck.Formatter.JSON.format),
|
("json", ShellCheck.Formatter.JSON.format False), -- JSON with 8-char tabs
|
||||||
|
("json1", ShellCheck.Formatter.JSON.format True), -- JSON with 1-char tabs
|
||||||
("tty", ShellCheck.Formatter.TTY.format options),
|
("tty", ShellCheck.Formatter.TTY.format options),
|
||||||
("quiet", ShellCheck.Formatter.Quiet.format options)
|
("quiet", ShellCheck.Formatter.Quiet.format options)
|
||||||
]
|
]
|
||||||
|
|
|
@ -22,6 +22,7 @@ module ShellCheck.Formatter.Format where
|
||||||
import ShellCheck.Data
|
import ShellCheck.Data
|
||||||
import ShellCheck.Interface
|
import ShellCheck.Interface
|
||||||
import ShellCheck.Fixer
|
import ShellCheck.Fixer
|
||||||
|
import Control.Monad
|
||||||
import Data.Array
|
import Data.Array
|
||||||
|
|
||||||
-- A formatter that carries along an arbitrary piece of data
|
-- A formatter that carries along an arbitrary piece of data
|
||||||
|
@ -54,5 +55,10 @@ makeNonVirtual comments contents =
|
||||||
where
|
where
|
||||||
list = lines contents
|
list = lines contents
|
||||||
arr = listArray (1, length list) list
|
arr = listArray (1, length list) list
|
||||||
fix c = removeTabStops c arr
|
untabbedFix f = newFix {
|
||||||
|
fixReplacements = map (\r -> removeTabStops r arr) (fixReplacements f)
|
||||||
|
}
|
||||||
|
fix c = (removeTabStops c arr) {
|
||||||
|
pcFix = liftM untabbedFix (pcFix c)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,12 @@ import GHC.Exts
|
||||||
import System.IO
|
import System.IO
|
||||||
import qualified Data.ByteString.Lazy.Char8 as BL
|
import qualified Data.ByteString.Lazy.Char8 as BL
|
||||||
|
|
||||||
format = do
|
format :: Bool -> IO Formatter
|
||||||
|
format removeTabs = do
|
||||||
ref <- newIORef []
|
ref <- newIORef []
|
||||||
return Formatter {
|
return Formatter {
|
||||||
header = return (),
|
header = return (),
|
||||||
onResult = collectResult ref,
|
onResult = collectResult removeTabs ref,
|
||||||
onFailure = outputError,
|
onFailure = outputError,
|
||||||
footer = finish ref
|
footer = finish ref
|
||||||
}
|
}
|
||||||
|
@ -96,8 +97,20 @@ instance ToJSON Fix where
|
||||||
]
|
]
|
||||||
|
|
||||||
outputError file msg = hPutStrLn stderr $ file ++ ": " ++ msg
|
outputError file msg = hPutStrLn stderr $ file ++ ": " ++ msg
|
||||||
collectResult ref result _ =
|
|
||||||
modifyIORef ref (\x -> crComments result ++ x)
|
collectResult removeTabs ref cr sys = mapM_ f groups
|
||||||
|
where
|
||||||
|
comments = crComments cr
|
||||||
|
groups = groupWith sourceFile comments
|
||||||
|
f :: [PositionedComment] -> IO ()
|
||||||
|
f group = do
|
||||||
|
let filename = sourceFile (head group)
|
||||||
|
result <- siReadFile sys filename
|
||||||
|
let contents = either (const "") id result
|
||||||
|
let comments' = if removeTabs
|
||||||
|
then makeNonVirtual comments contents
|
||||||
|
else comments
|
||||||
|
modifyIORef ref (\x -> comments' ++ x)
|
||||||
|
|
||||||
finish ref = do
|
finish ref = do
|
||||||
list <- readIORef ref
|
list <- readIORef ref
|
||||||
|
|
Loading…
Reference in New Issue