From 1bce426fcfd6ff176800bd70d7a298cf261d8512 Mon Sep 17 00:00:00 2001 From: Georg Pfuetzenreuter Date: Sun, 21 Jan 2024 02:16:35 +0100 Subject: [PATCH 1/2] Implement rcfile option This introduces the "--rcfile" argument which allows a specific shellcheckrc file to be passed. If specified and the given file exists, the default locations will not be searched and the specified file will be used. Signed-off-by: Georg Pfuetzenreuter --- shellcheck.1.md | 5 +++++ shellcheck.hs | 39 +++++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/shellcheck.1.md b/shellcheck.1.md index 89f6d50..42a0429 100644 --- a/shellcheck.1.md +++ b/shellcheck.1.md @@ -71,6 +71,11 @@ not warn at all, as `ksh` supports decimals in arithmetic contexts. : Don't try to look for .shellcheckrc configuration files. +--rcfile\ RCFILE + +: Prefer the specified configuration file over searching for one + in the default locations. + **-o**\ *NAME1*[,*NAME2*...],\ **--enable=***NAME1*[,*NAME2*...] : Enable optional checks. The special name *all* enables all of them. diff --git a/shellcheck.hs b/shellcheck.hs index 00b699b..42554f3 100644 --- a/shellcheck.hs +++ b/shellcheck.hs @@ -76,7 +76,8 @@ data Options = Options { externalSources :: Bool, sourcePaths :: [FilePath], formatterOptions :: FormatterOptions, - minSeverity :: Severity + minSeverity :: Severity, + rcfile :: FilePath } defaultOptions = Options { @@ -86,7 +87,8 @@ defaultOptions = Options { formatterOptions = newFormatterOptions { foColorOption = ColorAuto }, - minSeverity = StyleC + minSeverity = StyleC, + rcfile = [] } usageHeader = "Usage: shellcheck [OPTIONS...] FILES..." @@ -107,6 +109,9 @@ options = [ (NoArg $ Flag "list-optional" "true") "List checks disabled by default", Option "" ["norc"] (NoArg $ Flag "norc" "true") "Don't look for .shellcheckrc files", + Option "" ["rcfile"] + (ReqArg (Flag "rcfile") "RCFILE") + "Prefer the specified configuration file over searching for one", Option "o" ["enable"] (ReqArg (Flag "enable") "check1,check2..") "List of optional checks to enable (or 'all')", @@ -367,6 +372,11 @@ parseOption flag options = } } + Flag "rcfile" str -> do + return options { + rcfile = str + } + Flag "enable" value -> let cs = checkSpec options in return options { checkSpec = cs { @@ -441,18 +451,23 @@ ioInterface options files = do fallback :: FilePath -> IOException -> IO FilePath fallback path _ = return path + -- Returns the name and contents of .shellcheckrc for the given file getConfig cache filename = do - path <- normalize filename - let dir = takeDirectory path - (previousPath, result) <- readIORef cache - if dir == previousPath - then return result - else do - paths <- getConfigPaths dir - result <- findConfig paths - writeIORef cache (dir, result) - return result + contents <- readConfig (rcfile options) + if isNothing contents + then do + path <- normalize filename + let dir = takeDirectory path + (previousPath, result) <- readIORef cache + if dir == previousPath + then return result + else do + paths <- getConfigPaths dir + result <- findConfig paths + writeIORef cache (dir, result) + return result + else return contents findConfig paths = case paths of From 6a44a19f17c4a0590693587af3b5209d7b1b59fe Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sat, 3 Feb 2024 13:34:49 -0800 Subject: [PATCH 2/2] Only read --rcfile once, and skip search if unavailable --- shellcheck.hs | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/shellcheck.hs b/shellcheck.hs index 42554f3..e933d6c 100644 --- a/shellcheck.hs +++ b/shellcheck.hs @@ -77,7 +77,7 @@ data Options = Options { sourcePaths :: [FilePath], formatterOptions :: FormatterOptions, minSeverity :: Severity, - rcfile :: FilePath + rcfile :: Maybe FilePath } defaultOptions = Options { @@ -88,7 +88,7 @@ defaultOptions = Options { foColorOption = ColorAuto }, minSeverity = StyleC, - rcfile = [] + rcfile = Nothing } usageHeader = "Usage: shellcheck [OPTIONS...] FILES..." @@ -374,7 +374,7 @@ parseOption flag options = Flag "rcfile" str -> do return options { - rcfile = str + rcfile = Just str } Flag "enable" value -> @@ -453,21 +453,31 @@ ioInterface options files = do -- Returns the name and contents of .shellcheckrc for the given file - getConfig cache filename = do - contents <- readConfig (rcfile options) - if isNothing contents - then do - path <- normalize filename - let dir = takeDirectory path - (previousPath, result) <- readIORef cache - if dir == previousPath - then return result - else do - paths <- getConfigPaths dir - result <- findConfig paths - writeIORef cache (dir, result) - return result - else return contents + getConfig cache filename = + case rcfile options of + Just file -> do + -- We have a specified rcfile. Ignore normal rcfile resolution. + (path, result) <- readIORef cache + if path == "/" + then return result + else do + result <- readConfig file + when (isNothing result) $ + hPutStrLn stderr $ "Warning: unable to read --rcfile " ++ file + writeIORef cache ("/", result) + return result + + Nothing -> do + path <- normalize filename + let dir = takeDirectory path + (previousPath, result) <- readIORef cache + if dir == previousPath + then return result + else do + paths <- getConfigPaths dir + result <- findConfig paths + writeIORef cache (dir, result) + return result findConfig paths = case paths of @@ -505,7 +515,7 @@ ioInterface options files = do where handler :: FilePath -> IOException -> IO (String, Bool) handler file err = do - putStrLn $ file ++ ": " ++ show err + hPutStrLn stderr $ file ++ ": " ++ show err return ("", True) andM a b arg = do