Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Annlix
ShellCheck
提交
4968e7d9
S
ShellCheck
项目概览
Annlix
/
ShellCheck
与 Fork 源项目一致
Fork自
镜像 / koalaman / ShellCheck
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
S
ShellCheck
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4968e7d9
编写于
2月 02, 2014
作者:
V
Vidar Holen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added -s flag to override dialect, e.g. -s ksh
上级
075d58ee
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
57 addition
and
33 deletion
+57
-33
ShellCheck/Analytics.hs
ShellCheck/Analytics.hs
+22
-17
ShellCheck/Simple.hs
ShellCheck/Simple.hs
+9
-9
shellcheck.hs
shellcheck.hs
+26
-7
未找到文件。
ShellCheck/Analytics.hs
浏览文件 @
4968e7d9
...
...
@@ -15,7 +15,7 @@
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-}
module
ShellCheck.Analytics
(
AnalysisOption
(
..
),
filterByAnnotation
,
runAnalytics
)
where
module
ShellCheck.Analytics
(
AnalysisOption
(
..
),
filterByAnnotation
,
runAnalytics
,
shellForExecutable
)
where
import
ShellCheck.AST
import
ShellCheck.Data
...
...
@@ -41,7 +41,7 @@ data Parameters = Parameters {
shellType
::
Shell
}
data
AnalysisOption
=
NotImplemented
data
AnalysisOption
=
ForceShell
Shell
-- Checks that are run on the AST root
treeChecks
::
[
Parameters
->
Token
->
[
Note
]]
...
...
@@ -75,36 +75,41 @@ checksFor Bash = [
]
runAnalytics
::
[
AnalysisOption
]
->
Token
->
[
Note
]
runAnalytics
options
root
=
runList
root
treeChecks
runAnalytics
options
root
=
runList
options
root
treeChecks
runList
root
list
=
notes
runList
options
root
list
=
notes
where
params
=
Parameters
{
shellType
=
determineShell
root
,
shellType
=
getShellOption
,
parentMap
=
getParentTree
root
,
variableFlow
=
getVariableFlow
(
shellType
params
)
(
parentMap
params
)
root
}
notes
=
concatMap
(
\
f
->
f
params
root
)
list
getShellOption
=
fromMaybe
(
determineShell
root
)
.
msum
$
map
((
\
option
->
case
option
of
ForceShell
x
->
return
x
))
options
checkList
l
t
=
concatMap
(
\
f
->
f
t
)
l
prop_determineShell0
=
determineShell
(
T_Script
(
Id
0
)
"#!/bin/sh"
[]
)
==
Sh
prop_determineShell1
=
determineShell
(
T_Script
(
Id
0
)
"#!/usr/bin/env ksh"
[]
)
==
Ksh
prop_determineShell2
=
determineShell
(
T_Script
(
Id
0
)
""
[]
)
==
Bash
determineShell
(
T_Script
_
shebang
_
)
=
normaliz
e
$
shellFor
shebang
determineShell
(
T_Script
_
shebang
_
)
=
fromMaybe
Bash
.
shellForExecutabl
e
$
shellFor
shebang
where
shellFor
s
|
"/env "
`
isInfixOf
`
s
=
head
((
drop
1
$
words
s
)
++
[
""
])
shellFor
s
=
reverse
.
takeWhile
(
/=
'/'
)
.
reverse
$
s
normalize
"sh"
=
Sh
normalize
"ash"
=
Sh
normalize
"dash"
=
Sh
normalize
"ksh"
=
Ksh
normalize
"ksh93"
=
Ksh
normalize
"zsh"
=
Zsh
normalize
"bash"
=
Bash
normalize
_
=
Bash
shellForExecutable
"sh"
=
return
Sh
shellForExecutable
"ash"
=
return
Sh
shellForExecutable
"dash"
=
return
Sh
shellForExecutable
"ksh"
=
return
Ksh
shellForExecutable
"ksh93"
=
return
Ksh
shellForExecutable
"zsh"
=
return
Zsh
shellForExecutable
"bash"
=
return
Bash
shellForExecutable
_
=
Nothing
-- Checks that are run on each node in the AST
runNodeAnalysis
f
p
t
=
execWriter
(
doAnalysis
(
f
p
)
t
)
...
...
@@ -288,7 +293,7 @@ verifyNotTree f s = checkTree f s == Just False
checkNode
f
s
=
checkTree
(
runNodeAnalysis
f
)
s
checkTree
f
s
=
case
parseShell
"-"
s
of
(
ParseResult
(
Just
(
t
,
m
))
_
)
->
Just
.
not
.
null
$
runList
t
[
f
]
(
ParseResult
(
Just
(
t
,
m
))
_
)
->
Just
.
not
.
null
$
runList
[]
t
[
f
]
_
->
Nothing
...
...
ShellCheck/Simple.hs
浏览文件 @
4968e7d9
...
...
@@ -25,27 +25,27 @@ import Data.List
prop_findsParseIssue
=
let
comments
=
shellCheck
"echo
\"
$12
\"
"
in
let
comments
=
shellCheck
"echo
\"
$12
\"
"
[]
in
(
length
comments
)
==
1
&&
(
scCode
$
head
comments
)
==
1037
prop_commentDisablesParseIssue1
=
null
$
shellCheck
"#shellcheck disable=SC1037
\n
echo
\"
$12
\"
"
null
$
shellCheck
"#shellcheck disable=SC1037
\n
echo
\"
$12
\"
"
[]
prop_commentDisablesParseIssue2
=
null
$
shellCheck
"#shellcheck disable=SC1037
\n
#lol
\n
echo
\"
$12
\"
"
null
$
shellCheck
"#shellcheck disable=SC1037
\n
#lol
\n
echo
\"
$12
\"
"
[]
prop_findsAnalysisIssue
=
let
comments
=
shellCheck
"echo $1"
in
let
comments
=
shellCheck
"echo $1"
[]
in
(
length
comments
)
==
1
&&
(
scCode
$
head
comments
)
==
2086
prop_commentDisablesAnalysisIssue1
=
null
$
shellCheck
"#shellcheck disable=SC2086
\n
echo $1"
null
$
shellCheck
"#shellcheck disable=SC2086
\n
echo $1"
[]
prop_commentDisablesAnalysisIssue2
=
null
$
shellCheck
"#shellcheck disable=SC2086
\n
#lol
\n
echo $1"
null
$
shellCheck
"#shellcheck disable=SC2086
\n
#lol
\n
echo $1"
[]
shellCheck
::
String
->
[
ShellCheckComment
]
shellCheck
script
=
shellCheck
::
String
->
[
AnalysisOption
]
->
[
ShellCheckComment
]
shellCheck
script
options
=
let
(
ParseResult
result
notes
)
=
parseShell
"-"
script
in
let
allNotes
=
notes
++
(
concat
$
maybeToList
$
do
(
tree
,
posMap
)
<-
result
let
list
=
runAnalytics
[]
tree
let
list
=
runAnalytics
options
tree
return
$
map
(
noteToParseNote
posMap
)
$
filterByAnnotation
tree
list
)
in
...
...
shellcheck.hs
浏览文件 @
4968e7d9
...
...
@@ -18,10 +18,12 @@
import
Control.Exception
import
Control.Monad
import
Data.Char
import
Data.Maybe
import
GHC.Exts
import
GHC.IO.Device
import
Prelude
hiding
(
catch
)
import
ShellCheck.Simple
import
ShellCheck.Analytics
import
System.Console.GetOpt
import
System.Directory
import
System.Environment
...
...
@@ -37,7 +39,9 @@ options = [
Option
[
'f'
]
[
"format"
]
(
ReqArg
(
Flag
"format"
)
"FORMAT"
)
"output format"
,
Option
[
'e'
]
[
"exclude"
]
(
ReqArg
(
Flag
"exclude"
)
"CODE1,CODE2.."
)
"exclude types of warnings"
(
ReqArg
(
Flag
"exclude"
)
"CODE1,CODE2.."
)
"exclude types of warnings"
,
Option
[
's'
]
[
"shell"
]
(
ReqArg
(
Flag
"shell"
)
"SHELLNAME"
)
"Specify dialect (bash,sh,ksh,zsh)"
]
printErr
=
hPutStrLn
stderr
...
...
@@ -200,7 +204,14 @@ commentsFor options file =
liftM
(
getComments
options
)
$
readContents
file
getComments
options
contents
=
excludeCodes
(
getExclusions
options
)
$
shellCheck
contents
excludeCodes
(
getExclusions
options
)
$
shellCheck
contents
analysisOptions
where
analysisOptions
=
catMaybes
[
shellOption
]
shellOption
=
do
option
<-
getOption
options
"shell"
sh
<-
shellForExecutable
option
return
$
ForceShell
sh
readContents
file
=
if
file
==
"-"
then
getContents
else
readFile
file
...
...
@@ -216,9 +227,9 @@ makeNonVirtual comments contents =
real
rest
(
r
+
1
)
(
v
+
8
-
(
v
`
mod
`
8
))
target
real
(
_
:
rest
)
r
v
target
=
real
rest
(
r
+
1
)
(
v
+
1
)
target
getOption
[]
_
def
=
def
getOption
((
Flag
var
val
)
:
_
)
name
_
|
name
==
var
=
val
getOption
(
_
:
rest
)
flag
def
=
getOption
rest
flag
def
getOption
[]
_
=
Nothing
getOption
((
Flag
var
val
)
:
_
)
name
|
name
==
var
=
return
val
getOption
(
_
:
rest
)
flag
=
getOption
rest
flag
getOptions
options
name
=
map
(
\
(
Flag
_
val
)
->
val
)
.
filter
(
\
(
Flag
var
_
)
->
var
==
name
)
$
options
...
...
@@ -256,8 +267,9 @@ main = do
exitWith
code
process
Nothing
=
return
False
process
(
Just
(
options
,
files
))
=
let
format
=
getOption
options
"format"
"tty"
in
process
(
Just
(
options
,
files
))
=
do
verifyShellOption
options
let
format
=
fromMaybe
"tty"
$
getOption
options
"format"
in
case
Map
.
lookup
format
formats
of
Nothing
->
do
printErr
$
"Unknown format "
++
format
...
...
@@ -268,3 +280,10 @@ process (Just (options, files)) =
Just
f
->
do
f
options
files
verifyShellOption
options
=
let
shell
=
getOption
options
"shell"
in
if
isNothing
shell
then
return
()
else
when
(
isNothing
$
shell
>>=
shellForExecutable
)
$
do
printErr
$
"Unknown shell: "
++
(
fromJust
shell
)
exitWith
supportFailure
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录