diff options
author | Yorhel <git@yorhel.nl> | 2018-01-24 13:25:27 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2018-01-24 13:25:27 +0100 |
commit | 005acbf1d2bdb56d358d1e4e3a74f498a6e9cbdc (patch) | |
tree | 3ea30f8567f8eae5bbcd23607ed0bd077efd813f | |
parent | 45c5ed1ded1c68d610597da8bffe2b19a00dddeb (diff) |
Add some commandline options
-rw-r--r-- | Main.hs | 50 | ||||
-rw-r--r-- | nginx-confgen.cabal | 1 | ||||
-rw-r--r-- | nginx-confgen.pod | 28 |
3 files changed, 69 insertions, 10 deletions
@@ -8,13 +8,14 @@ import qualified Data.Array as A import Data.Char (isSpace) import Data.HashMap.Strict (HashMap) import qualified Data.HashMap.Strict as M -import Data.List (intercalate) +import Data.Semigroup ((<>)) import Data.Void +import Options.Applicative hiding (Parser, ParseError) import System.Directory import System.IO (hPutStrLn,stderr) import System.IO.Error (tryIOError) import System.Process -import Text.Megaparsec +import Text.Megaparsec hiding (option,hidden) import Text.Megaparsec.Char import qualified Text.Megaparsec.Char.Lexer as L import qualified Text.Regex.TDFA as R @@ -74,7 +75,7 @@ parser = between ws eof $ many stmt arg :: Parser Arg arg = ArgArray <$> arrayvar <|> ArgBlock <$> blockvar - <|> ArgString <$> lexeme str + <|> ArgString <$> lexeme fstr <?> "argument" where -- My understanding from reading ngx_conf_file.c: Single/double quoted and @@ -84,7 +85,7 @@ parser = between ws eof $ many stmt -- directive. (Which means that "${v}" and "$v" are not equivalent if the -- directive does not resolve variables, which means our parse/format -- round-trip is buggy) - str = between (char '"' ) (char '"' ) (qstr (/='"' ) <|> return [Literal ""]) + fstr = between (char '"' ) (char '"' ) (qstr (/='"' ) <|> return [Literal ""]) <|> between (char '\'') (char '\'') (qstr (/='\'') <|> return [Literal ""]) <|> qstr (\c -> not (isSpace c) && c /= '{' && c /= ';') @@ -121,7 +122,7 @@ parser = between ws eof $ many stmt fmt :: Conf -> String -fmt conf = intercalate "\n" $ concatMap dir conf +fmt conf = concatMap (++"\n") $ concatMap dir conf where indent = map (" "++) @@ -479,9 +480,40 @@ procConf gst gconf = foldM p (gst, []) gconf + + +data Options = Options + { optVersion :: Bool + , optInput :: String + , optOutput :: String + } + main :: IO () main = do - input <- getContents - case parse parser "-" input of - Left e -> putStr $ parseErrorPretty e - Right r -> procConf' (PState mempty mempty mempty mempty mempty 15) r >>= putStrLn . fmt + o <- execParser opts + if optVersion o + -- I could use cabal's Paths_* module here to get the version from the + -- cabal file, but unfortunately that also puts all my build paths in the + -- generated binary. + then putStrLn "nginx-confgen 1.0" + else prog o + + where + opts = info (optparse <**> helper) fullDesc + optparse = Options + <$> switch (short 'V' <> long "version" <> hidden <> help "Show program version") + <*> strOption (short 'i' <> metavar "FILE" <> value "-" <> showDefault <> help "Input file") + <*> strOption (short 'o' <> metavar "FILE" <> value "-" <> showDefault <> help "Output file") + + prog o = do + input <- if optInput o == "-" + then getContents + else readFile (optInput o) + + case parse parser (optInput o) input of + Left e -> hPutStrLn stderr $ parseErrorPretty e + Right r -> do + output <- fmt <$> procConf' (PState mempty mempty mempty mempty mempty 15) r + if optOutput o == "-" + then putStr output + else writeFile (optOutput o) output diff --git a/nginx-confgen.cabal b/nginx-confgen.cabal index ee4acb2..8ebb227 100644 --- a/nginx-confgen.cabal +++ b/nginx-confgen.cabal @@ -21,6 +21,7 @@ executable nginx-confgen , base , directory , megaparsec + , optparse-applicative , process , regex-tdfa , unordered-containers diff --git a/nginx-confgen.pod b/nginx-confgen.pod index 10af518..2bc0176 100644 --- a/nginx-confgen.pod +++ b/nginx-confgen.pod @@ -7,7 +7,7 @@ files. =head1 SYNOPSIS -nginx-confgen <input.conf >output.conf +nginx-confgen -i input.conf -o output.conf =head1 DESCRIPTION @@ -30,6 +30,32 @@ below. B<WARNING:> Do NOT use nginx-confgen with untrusted input, the C<pre_exec> directive allows, by design, arbitrary code execution. +=head1 OPTIONS + +The following command-line options are supported: + +=over + +=item -h + +Show help text. + +=item -V, --version + +Show program version. + +=item -i I<FILE> + +Use the given file name as input file. If this option is not given or set to +C<->, then the file will be read from standard input. + +=item -o I<FILE> + +Write the output to the given file. If this option is not given or set to C<->, +then the file will be written to standard output. + +=back + =head1 DIRECTIVES |