Skip to content

Commit

Permalink
Support for stdin & stdout support
Browse files Browse the repository at this point in the history
  • Loading branch information
gvolpe committed Aug 6, 2020
1 parent 1a39ec0 commit 41aeca6
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 34 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,28 @@ Once compiled and installed (via `nix-build` or `cabal new-install`), you can us
dconf2nix -i data/dconf.settings -o output/dconf.nix
```

It is also possible to pipe the standard input to `dconf2nix` and expect the result in the standard output:

```shell
dconf dump / | dconf2nix > dconf.nix
```

Type `--help` for some more information.

```shell
dconf2nix - Convert dconf files to Nix
dconf2nix - Nixify dconf configuration files

Usage: dconf2nix [-v|--version] (-i|--input ARG) (-o|--output ARG)
[-t|--timeout ARG] [--verbose]
Usage: dconf2nix [-v|--version]
[[-t|--timeout ARG] [--verbose] | (-i|--input ARG)
(-o|--output ARG) [-t|--timeout ARG] [--verbose]]
Convert a dconf file into a Nix file, as expected by Home Manager.

Available options:
-h,--help Show this help text
-v,--version Show the current version
-t,--timeout ARG Timeout in seconds for the conversion
process (default: 5)
--verbose Verbose mode (debug)
-i,--input ARG Path to the dconf file (input)
-o,--output ARG Path to the Nix output file (to be created)
-t,--timeout ARG Timeout in seconds for the conversion
Expand Down
26 changes: 19 additions & 7 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,18 @@

module Main where

import CommandLine ( Args(..)
import CommandLine ( FileArgs(..)
, Input(..)
, StdinArgs(..)
, runArgs
)
import DConf.Data ( ProcessTimeout(..) )
import DConf2Nix ( dconf2nix )
import Data.Foldable ( traverse_ )
import DConf.Data ( ProcessTimeout(..)
, Verbosity(..)
)
import DConf2Nix ( dconf2nixFile
, dconf2nixStdin
)
import System.Timeout ( timeout )

timeoutMessage = unlines
Expand All @@ -17,9 +24,14 @@ timeoutMessage = unlines
, " ⛔ If the issue persists, run it again using --verbose and report the issue on Github. Sorry 😞."
]

dconf2nix :: ProcessTimeout -> IO () -> Maybe String -> IO ()
dconf2nix (ProcessTimeout t) fa successMsg = timeout (t * 1000000) fa >>= \case
Just _ -> traverse_ putStrLn successMsg
Nothing -> error timeoutMessage

main :: IO ()
main = runArgs >>= \case
(Args i o (ProcessTimeout t) v) ->
timeout (t * 1000000) (dconf2nix i o v) >>= \case
Just _ -> putStrLn "🚀 Successfully Nixified! ❄️"
Nothing -> error timeoutMessage
FileInput (FileArgs i o t v) ->
dconf2nix t (dconf2nixFile i o v) (Just "🚀 Successfully Nixified! ❄️")
StdinInput (StdinArgs t v) ->
dconf2nix t (dconf2nixStdin v) Nothing
51 changes: 36 additions & 15 deletions src/CommandLine.hs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
module CommandLine
( Args(..)
( FileArgs(..)
, Input(..)
, StdinArgs(..)
, runArgs
)
where
Expand All @@ -13,16 +15,35 @@ import DConf.Data ( InputFilePath(..)
import Options.Applicative
import Paths_dconf2nix ( version )

data Args = Args
data Input = FileInput FileArgs | StdinInput StdinArgs

data FileArgs = FileArgs
{ input :: InputFilePath
, output :: OutputFilePath
, processTimeout :: ProcessTimeout
, verbose :: Verbosity
}

args :: Parser Args
args =
Args
data StdinArgs = StdinArgs
{ stdinTimeout :: ProcessTimeout
, stdinVerbose :: Verbosity
}

timeoutArgs :: Parser ProcessTimeout
timeoutArgs = ProcessTimeout <$> option
auto
(long "timeout" <> short 't' <> showDefault <> value 5 <> help
"Timeout in seconds for the conversion process"
)

verbosityArgs :: Parser Verbosity
verbosityArgs =
flag Normal Verbose (long "verbose" <> help "Verbose mode (debug)")

fileArgs :: Parser Input
fileArgs =
fmap FileInput
$ FileArgs
<$> (InputFilePath <$> strOption
(long "input" <> short 'i' <> help "Path to the dconf file (input)")
)
Expand All @@ -31,12 +52,11 @@ args =
"Path to the Nix output file (to be created)"
)
)
<*> (ProcessTimeout <$> option auto
(long "timeout" <> short 't' <> showDefault <> value 5 <> help
"Timeout in seconds for the conversion process"
)
)
<*> flag Normal Verbose (long "verbose" <> help "Verbose mode (debug)")
<*> timeoutArgs
<*> verbosityArgs

stdinArgs :: Parser Input
stdinArgs = StdinInput <$> (StdinArgs <$> timeoutArgs <*> verbosityArgs)

versionInfo :: String
versionInfo = unlines
Expand All @@ -54,16 +74,17 @@ versionInfo = unlines
]

versionOpt :: Parser (a -> a)
versionOpt = infoOption versionInfo
versionOpt = infoOption
versionInfo
(long "version" <> short 'v' <> help "Show the current version")

runArgs :: IO Args
runArgs :: IO Input
runArgs = execParser opts
where
opts = info
(helper <*> versionOpt <*> args)
(helper <*> versionOpt <*> (stdinArgs <|> fileArgs))
( fullDesc
<> progDesc
"Convert a dconf file into a Nix file, as expected by Home Manager."
<> header "dconf2nix - Convert dconf files to Nix"
<> header "dconf2nix - Nixify dconf configuration files"
)
34 changes: 25 additions & 9 deletions src/DConf2Nix.hs
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
{-# LANGUAGE LambdaCase #-}

module DConf2Nix where

import qualified Data.Text as T
import qualified Data.Text.IO as T
import DConf.Data
import DConf ( dconfParser )
import qualified Nix
import Text.Parsec.Text ( parseFromFile )
import Text.Parsec ( ParseError
, runParser
)

dconf2nixFile :: InputFilePath -> OutputFilePath -> Verbosity -> IO ()
dconf2nixFile (InputFilePath input) (OutputFilePath output) v = do
parsed <- parseFromFile (dconfParser v) input
handler (T.writeFile output) (T.appendFile output) parsed

dconf2nixStdin :: Verbosity -> IO ()
dconf2nixStdin v = do
input <- T.getContents
handler T.putStr T.putStr $ runParser (dconfParser v) () "<stdin>" input

dconf2nix :: InputFilePath -> OutputFilePath -> Verbosity -> IO ()
dconf2nix (InputFilePath input) (OutputFilePath output) v = do
parseFromFile (dconfParser v) input >>= \case
Left err -> error (show err)
handler
:: (T.Text -> IO ())
-> (T.Text -> IO ())
-> Either ParseError [Entry]
-> IO ()
handler writer appender parsed = do
case parsed of
Left err -> error $ show err
Right xs -> do
T.writeFile output Nix.renderHeader
traverse (\e -> T.appendFile output (unNix $ Nix.renderEntry e)) xs
T.appendFile output Nix.renderFooter
writer Nix.renderHeader
traverse (\e -> appender (unNix $ Nix.renderEntry e)) xs
appender Nix.renderFooter

0 comments on commit 41aeca6

Please sign in to comment.