From 67d27ea42dc9defed1a9cca5af500e9584b9d17d Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sun, 4 Nov 2012 21:44:48 -0800 Subject: [PATCH] Tweaked some messages and added more badcases --- Makefile | 6 +++++- Shpell/Analytics.hs | 2 +- Shpell/Parser.hs | 24 ++++++++++++------------ badcase/ampersemi | 1 + badcase/apostrophecked | 1 + badcase/badKnR | 3 +++ badcase/badescape | 1 + badcase/badindenting | 7 +++++++ badcase/heredoccasefault | 3 +++ badcase/heredoclinefault | 2 ++ badcase/intosame | 2 +- badcase/largepositionals | 1 + badcase/lolbackticks | 1 + badcase/lonelydollar | 1 + badcase/mvmp3s | 4 ++++ badcase/mvmp3sfixed | 5 +++++ badcase/stillapostrophecked | 1 + badcase/superfluousfunction | 1 + badcase/unquotedexpansion | 1 + badcase/uuoc | 1 + badcase/worseindenting | 6 ++++++ shpell.hs | 2 +- 22 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 badcase/ampersemi create mode 100644 badcase/apostrophecked create mode 100644 badcase/badKnR create mode 100644 badcase/badescape create mode 100644 badcase/badindenting create mode 100644 badcase/heredoccasefault create mode 100644 badcase/heredoclinefault create mode 100644 badcase/largepositionals create mode 100644 badcase/lolbackticks create mode 100644 badcase/lonelydollar create mode 100644 badcase/mvmp3s create mode 100644 badcase/mvmp3sfixed create mode 100644 badcase/stillapostrophecked create mode 100644 badcase/superfluousfunction create mode 100644 badcase/unquotedexpansion create mode 100644 badcase/uuoc create mode 100644 badcase/worseindenting diff --git a/Makefile b/Makefile index f2b3887..003a4f1 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ all: .tests shpell true -shpell: +shpell: regardless ghc --make shpell #GHC handles the dependencies .tests: *.hs */*.hs @@ -9,3 +9,7 @@ shpell: clean: rm -f .tests shpell *.hi *.o Shpell/*.hi Shpell/*.o + +regardless: + : + diff --git a/Shpell/Analytics.hs b/Shpell/Analytics.hs index a81c9ea..d2cd8ff 100644 --- a/Shpell/Analytics.hs +++ b/Shpell/Analytics.hs @@ -67,7 +67,7 @@ checkBasic f s = case parseShell "-" s of prop_checkUuoc = verify checkUuoc "cat foo | grep bar" checkUuoc (T_Pipeline _ (T_Redirecting _ _ f@(T_SimpleCommand id _ _):_:_)) = - case deadSimple f of ["cat", _] -> addNoteFor id $ Note InfoC "UUOC: 'cat foo | bar | baz' is better written as 'bar < foo | baz'" + case deadSimple f of ["cat", _] -> addNoteFor id $ Note StyleC "Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead." _ -> return () checkUuoc _ = return () diff --git a/Shpell/Parser.hs b/Shpell/Parser.hs index 0734d4e..5373751 100644 --- a/Shpell/Parser.hs +++ b/Shpell/Parser.hs @@ -318,12 +318,13 @@ readSingleQuoted = do id <- getNextId singleQuote s <- readSingleQuotedPart `reluctantlyTill` singleQuote + pos <- getPosition singleQuote "End single quoted string" let string = concat s return (T_SingleQuoted id string) `attempting` do x <- lookAhead anyChar - when (isAlpha x && isAlpha (last string)) $ parseProblem WarningC "This apostrophe terminated the single quoted string." + when (isAlpha x && isAlpha (last string)) $ parseProblemAt pos WarningC "This apostrophe terminated the single quoted string!" readSingleQuotedLiteral = do singleQuote @@ -338,7 +339,7 @@ readSingleQuotedPart = prop_readBackTicked = isWarning readBackTicked "`ls *.mp3`" readBackTicked = do id <- getNextId - parseNote StyleC "Ignoring deprecated `..` backtick expansion. Use $(..) instead." + parseNote InfoC "Ignoring deprecated `..` backtick expansion. Use $(..) instead." pos <- getPosition char '`' f <- readGenericLiteral (char '`') @@ -381,15 +382,15 @@ readNormalLiteralPart = do readNormalEscaped <|> (anyChar `reluctantlyTill1` quotable) readNormalEscaped = do - backslash pos <- getPosition + backslash do next <- (quotable <|> oneOf "?*[]") return $ if next == '\n' then "" else [next] <|> do next <- anyChar "No character after \\" - parseNoteAt pos WarningC $ "This character doesn't need escaping here, the \\ is ignored" + parseNoteAt pos WarningC $ "Did you mean \"$(printf \"\\" ++ [next] ++ "\")\"? The shell just ignores the \\ here." return [next] readSingleEscaped = do @@ -502,8 +503,7 @@ readDollarVariable = do name <- readVariableName return $ T_DollarVariable id (name) - char '$' - positional <|> special <|> regular + try $ char '$' >> (positional <|> special <|> regular) readVariableName = do f <- variableStart @@ -512,7 +512,7 @@ readVariableName = do readDollarLonely = do id <- getNextId - parseNote ErrorC "$ is not used specially and should therefore be escaped" + parseNote StyleC "$ is not used specially and should therefore be escaped" char '$' return $ T_Literal id "$" @@ -543,15 +543,15 @@ readHereDoc = do `attempting` (eof >> debugHereDoc tokenPosition endToken hereInfo) verifyHereDoc dashed quoted spacing hereInfo = do - when (not dashed && spacing /= "") $ parseNote ErrorC "When using << instead of <<-, the end tokens can't be indented" + when (not dashed && spacing /= "") $ parseNote ErrorC "Use <<- instead of << if you want to indent the end token" when (dashed && filter (/= '\t') spacing /= "" ) $ parseNote ErrorC "When using <<-, you can only indent with tabs" return () debugHereDoc pos endToken doc = if endToken `isInfixOf` doc - then parseProblemAt pos ErrorC (endToken ++ " was part of the here document, but not by itself at the start of the line") + then parseProblemAt pos ErrorC ("Found " ++ endToken ++ " further down, but not by itself at the start of the line") else if (map toLower endToken) `isInfixOf` (map toLower doc) - then parseProblemAt pos ErrorC (endToken ++ " appears in the here document, but with different case") + then parseProblemAt pos ErrorC ("Found " ++ endToken ++ " further down, but with wrong casing.") else parseProblemAt pos ErrorC ("Couldn't find end token `" ++ endToken ++ "' in the here document ") @@ -797,7 +797,7 @@ readInClause = do do { lookAhead (g_Do); - parseNote ErrorC "You need a line feed or semicolon before the 'do' (in Bash)"; + parseNote ErrorC "You need a line feed or semicolon before the 'do'"; } <|> do { optional $ g_Semi; disregard allspacing; @@ -843,7 +843,7 @@ readFunctionDefinition = do readFunctionSignature = do - acceptButWarn (string "function" >> linewhitespace >> spacing) StyleC "Drop the keyword 'function'. It's optional in Bash but illegal in others." + acceptButWarn (string "function" >> linewhitespace >> spacing) InfoC "Drop the keyword 'function'. It's optional in Bash but invalid in other shells." name <- readVariableName spacing g_Lparen diff --git a/badcase/ampersemi b/badcase/ampersemi new file mode 100644 index 0000000..f8a2a4c --- /dev/null +++ b/badcase/ampersemi @@ -0,0 +1 @@ +wget url &; echo "It's backgrounded." diff --git a/badcase/apostrophecked b/badcase/apostrophecked new file mode 100644 index 0000000..5649626 --- /dev/null +++ b/badcase/apostrophecked @@ -0,0 +1 @@ +echo 'Shpell... It's the best!' diff --git a/badcase/badKnR b/badcase/badKnR new file mode 100644 index 0000000..c975dc5 --- /dev/null +++ b/badcase/badKnR @@ -0,0 +1,3 @@ +for f in * do + echo "$f" +done diff --git a/badcase/badescape b/badcase/badescape new file mode 100644 index 0000000..86c0c21 --- /dev/null +++ b/badcase/badescape @@ -0,0 +1 @@ +echo hello\nword diff --git a/badcase/badindenting b/badcase/badindenting new file mode 100644 index 0000000..cd3bdd1 --- /dev/null +++ b/badcase/badindenting @@ -0,0 +1,7 @@ +# Caution, white space sensitive file! +if true +then + cat <<- FOO + Some text + FOO +fi diff --git a/badcase/heredoccasefault b/badcase/heredoccasefault new file mode 100644 index 0000000..a365458 --- /dev/null +++ b/badcase/heredoccasefault @@ -0,0 +1,3 @@ +cat << EOF +Hello world +Eof diff --git a/badcase/heredoclinefault b/badcase/heredoclinefault new file mode 100644 index 0000000..e4838c9 --- /dev/null +++ b/badcase/heredoclinefault @@ -0,0 +1,2 @@ +cat << EOF +Hello world EOF diff --git a/badcase/intosame b/badcase/intosame index 7ebdf21..2aa8956 100644 --- a/badcase/intosame +++ b/badcase/intosame @@ -1 +1 @@ -cat compile.sh |tr -d '\r' > compile.sh +sed 's/foo/bar/g' myfile > myfile diff --git a/badcase/largepositionals b/badcase/largepositionals new file mode 100644 index 0000000..4db5aa9 --- /dev/null +++ b/badcase/largepositionals @@ -0,0 +1 @@ +ls ... "9" "$10" # DOS 4ever diff --git a/badcase/lolbackticks b/badcase/lolbackticks new file mode 100644 index 0000000..f62bc71 --- /dev/null +++ b/badcase/lolbackticks @@ -0,0 +1 @@ +echo `ls` diff --git a/badcase/lonelydollar b/badcase/lonelydollar new file mode 100644 index 0000000..71d5b6b --- /dev/null +++ b/badcase/lonelydollar @@ -0,0 +1 @@ +echo "$ is special now?" diff --git a/badcase/mvmp3s b/badcase/mvmp3s new file mode 100644 index 0000000..9569880 --- /dev/null +++ b/badcase/mvmp3s @@ -0,0 +1,4 @@ +for f in *.mp3 +do + mv $f /music +done diff --git a/badcase/mvmp3sfixed b/badcase/mvmp3sfixed new file mode 100644 index 0000000..d8f52f9 --- /dev/null +++ b/badcase/mvmp3sfixed @@ -0,0 +1,5 @@ +# There, I fixed it! +for f in "$(ls *.mp3)" +do + mv "$f" /music +done diff --git a/badcase/stillapostrophecked b/badcase/stillapostrophecked new file mode 100644 index 0000000..f8c27d6 --- /dev/null +++ b/badcase/stillapostrophecked @@ -0,0 +1 @@ +echo 'Shpell... It\'s the best!' diff --git a/badcase/superfluousfunction b/badcase/superfluousfunction new file mode 100644 index 0000000..ad54c10 --- /dev/null +++ b/badcase/superfluousfunction @@ -0,0 +1 @@ +function foo() { echo bar; } diff --git a/badcase/unquotedexpansion b/badcase/unquotedexpansion new file mode 100644 index 0000000..3c8ec69 --- /dev/null +++ b/badcase/unquotedexpansion @@ -0,0 +1 @@ +echo Your locales: $(locale) diff --git a/badcase/uuoc b/badcase/uuoc new file mode 100644 index 0000000..cab0386 --- /dev/null +++ b/badcase/uuoc @@ -0,0 +1 @@ +cat foo | grep bar diff --git a/badcase/worseindenting b/badcase/worseindenting new file mode 100644 index 0000000..ef4d43a --- /dev/null +++ b/badcase/worseindenting @@ -0,0 +1,6 @@ +if true +then + cat << FOO + Some text + FOO +fi diff --git a/shpell.hs b/shpell.hs index 51ff01a..2aeac49 100644 --- a/shpell.hs +++ b/shpell.hs @@ -14,7 +14,7 @@ ansi n = "\x1B[" ++ (show n) ++ "m" colorForLevel "error" = 31 -- red colorForLevel "warning" = 33 -- yellow colorForLevel "info" = 33 -- yellow -colorForLevel "style" = 31 -- green +colorForLevel "style" = 32 -- green colorForLevel "message" = 1 -- bold colorForLevel "source" = 0 -- none colorForLevel _ = 0 -- none -- GitLab