{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module Debian.Deb where

import Control.Monad

import Debian.Control.Common
import System.Directory (canonicalizePath, withCurrentDirectory)
import System.Exit (ExitCode(..))
import System.Process (readProcessWithExitCode)
import System.IO.Temp (withSystemTempDirectory)

fields :: (ControlFunctions a) => FilePath -> IO (Control' a)
fields :: FilePath -> IO (Control' a)
fields FilePath
debFP =
    FilePath -> (FilePath -> IO (Control' a)) -> IO (Control' a)
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
FilePath -> (FilePath -> m a) -> m a
withSystemTempDirectory (FilePath
"fields.XXXXXX") ((FilePath -> IO (Control' a)) -> IO (Control' a))
-> (FilePath -> IO (Control' a)) -> IO (Control' a)
forall a b. (a -> b) -> a -> b
$ \FilePath
tmpdir ->
      do FilePath
debFP <- FilePath -> IO FilePath
canonicalizePath FilePath
debFP
         FilePath -> IO (Control' a) -> IO (Control' a)
forall a. FilePath -> IO a -> IO a
withCurrentDirectory FilePath
tmpdir (IO (Control' a) -> IO (Control' a))
-> IO (Control' a) -> IO (Control' a)
forall a b. (a -> b) -> a -> b
$
           do (ExitCode
res, FilePath
out, FilePath
err) <- FilePath
-> [FilePath] -> FilePath -> IO (ExitCode, FilePath, FilePath)
readProcessWithExitCode FilePath
"ar" [FilePath
"x",FilePath
debFP,FilePath
"control.tar.gz"] FilePath
""
              Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ExitCode
res ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
/= ExitCode
ExitSuccess) (FilePath -> IO ()
forall a. HasCallStack => FilePath -> a
error (FilePath -> IO ()) -> FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Dpkg.fields: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath -> FilePath
forall a. Show a => a -> FilePath
show FilePath
out FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
"\n" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath -> FilePath
forall a. Show a => a -> FilePath
show FilePath
err FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
"\n" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ ExitCode -> FilePath
forall a. Show a => a -> FilePath
show ExitCode
res)
              (ExitCode
res, FilePath
out, FilePath
err) <- FilePath
-> [FilePath] -> FilePath -> IO (ExitCode, FilePath, FilePath)
readProcessWithExitCode FilePath
"tar" [FilePath
"xzf", FilePath
"control.tar.gz", FilePath
"./control"] FilePath
""
              Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ExitCode
res ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
/= ExitCode
ExitSuccess) (FilePath -> IO ()
forall a. HasCallStack => FilePath -> a
error (FilePath -> IO ()) -> FilePath -> IO ()
forall a b. (a -> b) -> a -> b
$ FilePath
"Dpkg.fields: " FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath -> FilePath
forall a. Show a => a -> FilePath
show FilePath
out FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
"\n" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath -> FilePath
forall a. Show a => a -> FilePath
show FilePath
err FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
"\n" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ ExitCode -> FilePath
forall a. Show a => a -> FilePath
show ExitCode
res)
              Either ParseError (Control' a)
c <- FilePath -> IO (Either ParseError (Control' a))
forall a.
ControlFunctions a =>
FilePath -> IO (Either ParseError (Control' a))
parseControlFromFile FilePath
"control"
              case Either ParseError (Control' a)
c of
                Left ParseError
e -> FilePath -> IO (Control' a)
forall a. HasCallStack => FilePath -> a
error (ParseError -> FilePath
forall a. Show a => a -> FilePath
show ParseError
e)
                (Right Control' a
c) -> Control' a -> IO (Control' a)
forall (m :: * -> *) a. Monad m => a -> m a
return Control' a
c -- I don't think we need seq because parsec will force everything from the file