module Restyler.Config.Interpreter
( Interpreter(..)
, readInterpreter
)
where
import Restyler.Prelude
import Data.Aeson
import qualified Data.Text as T
import System.FilePath (takeFileName)
data Interpreter
= Sh
| Bash
| Python
| Ruby
deriving (Interpreter -> Interpreter -> Bool
(Interpreter -> Interpreter -> Bool)
-> (Interpreter -> Interpreter -> Bool) -> Eq Interpreter
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Interpreter -> Interpreter -> Bool
$c/= :: Interpreter -> Interpreter -> Bool
== :: Interpreter -> Interpreter -> Bool
$c== :: Interpreter -> Interpreter -> Bool
Eq, Int -> Interpreter -> ShowS
[Interpreter] -> ShowS
Interpreter -> String
(Int -> Interpreter -> ShowS)
-> (Interpreter -> String)
-> ([Interpreter] -> ShowS)
-> Show Interpreter
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Interpreter] -> ShowS
$cshowList :: [Interpreter] -> ShowS
show :: Interpreter -> String
$cshow :: Interpreter -> String
showsPrec :: Int -> Interpreter -> ShowS
$cshowsPrec :: Int -> Interpreter -> ShowS
Show)
instance FromJSON Interpreter where
parseJSON :: Value -> Parser Interpreter
parseJSON =
String
-> (Text -> Parser Interpreter) -> Value -> Parser Interpreter
forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText "Interpreter"
((Text -> Parser Interpreter) -> Value -> Parser Interpreter)
-> (Text -> Parser Interpreter) -> Value -> Parser Interpreter
forall a b. (a -> b) -> a -> b
$ (String -> Parser Interpreter)
-> (Interpreter -> Parser Interpreter)
-> Either String Interpreter
-> Parser Interpreter
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> Parser Interpreter
forall (m :: * -> *) a. MonadFail m => String -> m a
fail Interpreter -> Parser Interpreter
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(Either String Interpreter -> Parser Interpreter)
-> (Text -> Either String Interpreter)
-> Text
-> Parser Interpreter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String Interpreter
intepreterFromString
(String -> Either String Interpreter)
-> (Text -> String) -> Text -> Either String Interpreter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack
instance ToJSON Interpreter where
toJSON :: Interpreter -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> (Interpreter -> Text) -> Interpreter -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.toLower (Text -> Text) -> (Interpreter -> Text) -> Interpreter -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interpreter -> Text
forall a. Show a => a -> Text
tshow
readInterpreter :: Text -> Maybe Interpreter
readInterpreter :: Text -> Maybe Interpreter
readInterpreter contents :: Text
contents = do
Text
line <- [Text] -> Maybe Text
forall a. [a] -> Maybe a
headMaybe ([Text] -> Maybe Text) -> [Text] -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text -> [Text]
T.lines Text
contents
String -> Maybe Interpreter
parseInterpreter (String -> Maybe Interpreter)
-> (Text -> String) -> Text -> Maybe Interpreter
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> Maybe Interpreter) -> Text -> Maybe Interpreter
forall a b. (a -> b) -> a -> b
$ Text -> Text
T.strip Text
line
parseInterpreter :: String -> Maybe Interpreter
parseInterpreter :: String -> Maybe Interpreter
parseInterpreter ('#' : '!' : rest :: String
rest) =
Either String Interpreter -> Maybe Interpreter
forall a b. Either a b -> Maybe b
hush (Either String Interpreter -> Maybe Interpreter)
-> Either String Interpreter -> Maybe Interpreter
forall a b. (a -> b) -> a -> b
$ String -> Either String Interpreter
intepreterFromString (String -> Either String Interpreter)
-> Either String String -> Either String Interpreter
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< case String -> [String]
words String
rest of
[exec :: String
exec] -> String -> Either String String
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Either String String) -> String -> Either String String
forall a b. (a -> b) -> a -> b
$ ShowS
takeFileName String
exec
["/usr/bin/env", arg :: String
arg] -> String -> Either String String
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
arg
_ -> String -> Either String String
forall a b. a -> Either a b
Left "Unexpected shebang length"
parseInterpreter _ = Maybe Interpreter
forall a. Maybe a
Nothing
intepreterFromString :: String -> Either String Interpreter
intepreterFromString :: String -> Either String Interpreter
intepreterFromString "sh" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Sh
intepreterFromString "bash" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Bash
intepreterFromString "python" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Python
intepreterFromString "python2" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Python
intepreterFromString "python2.7" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Python
intepreterFromString "python3" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Python
intepreterFromString "python3.6" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Python
intepreterFromString "ruby" = Interpreter -> Either String Interpreter
forall a b. b -> Either a b
Right Interpreter
Ruby
intepreterFromString x :: String
x = String -> Either String Interpreter
forall a b. a -> Either a b
Left (String -> Either String Interpreter)
-> String -> Either String Interpreter
forall a b. (a -> b) -> a -> b
$ "Unknown executable: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
x