summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2018-01-24 13:25:27 +0100
committerYorhel <git@yorhel.nl>2018-01-24 13:25:27 +0100
commit005acbf1d2bdb56d358d1e4e3a74f498a6e9cbdc (patch)
tree3ea30f8567f8eae5bbcd23607ed0bd077efd813f
parent45c5ed1ded1c68d610597da8bffe2b19a00dddeb (diff)
Add some commandline options
-rw-r--r--Main.hs50
-rw-r--r--nginx-confgen.cabal1
-rw-r--r--nginx-confgen.pod28
3 files changed, 69 insertions, 10 deletions
diff --git a/Main.hs b/Main.hs
index 4744ac4..492c82b 100644
--- a/Main.hs
+++ b/Main.hs
@@ -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