Just to clarify, I just wanted to test this idea, to remove generating
Haskell code in Makefile. It seems to work well, so I wanted to ask for
comments, if you like the idea or not. If yes, I can resubmit is at a PATCH.


2013/10/30 Petr Pudlak <[email protected]>

> instead of generating a Haskell file in Makefile.
>
> Signed-off-by: Petr Pudlak <[email protected]>
> ---
>  .gitignore               |  1 -
>  Makefile.am              | 19 +++++++------------
>  src/Ganeti/THH.hs        | 47
> ++++++++++++++++++++++++++++++++++++++++++++++-
>  src/Ganeti/Version.hs    | 13 +++++++++++++
>  src/Ganeti/Version.hs.in | 12 ------------
>  5 files changed, 66 insertions(+), 26 deletions(-)
>  create mode 100644 src/Ganeti/Version.hs
>  delete mode 100644 src/Ganeti/Version.hs.in
>
> diff --git a/.gitignore b/.gitignore
> index 57aec29..0df8eb6 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -146,5 +146,4 @@
>  /src/Ganeti/Curl/Internal.hs
>  /src/Ganeti/Hs2Py/ListConstants.hs
>  /src/Ganeti/PyConstants.hs
> -/src/Ganeti/Version.hs
>  /test/hs/Test/Ganeti/TestImports.hs
> diff --git a/Makefile.am b/Makefile.am
> index 5d9ee40..b9203af 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -6,8 +6,10 @@
>  # - Use autogen.sh to generate Makefile.in and configure script.
>
>  # Automake doesn't export these variables before version 1.10.
> -abs_top_builddir = @abs_top_builddir@
> -abs_top_srcdir = @abs_top_srcdir@
> +# We need explicit `export` so that they're available as environment
> variables
> +# for Template Haskell.
> +export abs_top_builddir = @abs_top_builddir@
> +export abs_top_srcdir = @abs_top_srcdir@
>
>  # Helper values for calling builtin functions
>  empty :=
> @@ -618,7 +620,6 @@ HPCEXCL = --exclude Main \
>         --exclude Ganeti.Constants \
>         --exclude Ganeti.HTools.QC \
>         --exclude Ganeti.THH \
> -       --exclude Ganeti.Version \
>         --exclude Test.Ganeti.Attoparsec \
>         --exclude Test.Ganeti.TestCommon \
>         --exclude Test.Ganeti.TestHTools \
> @@ -726,7 +727,8 @@ HS_LIB_SRCS = \
>         src/Ganeti/Storage/Utils.hs \
>         src/Ganeti/THH.hs \
>         src/Ganeti/Types.hs \
> -       src/Ganeti/Utils.hs
> +       src/Ganeti/Utils.hs \
> +       src/Ganeti/Version.hs
>
>  HS_TEST_SRCS = \
>         test/hs/Test/AutoConf.hs \
> @@ -785,8 +787,7 @@ HS_BUILT_SRCS = \
>         src/AutoConf.hs \
>         src/Ganeti/Hs2Py/ListConstants.hs \
>         src/Ganeti/PyConstants.hs \
> -       src/Ganeti/Curl/Internal.hs \
> -       src/Ganeti/Version.hs
> +       src/Ganeti/Curl/Internal.hs
>  HS_BUILT_SRCS_IN = \
>         $(patsubst %,%.in,$(filter-out
> src/Ganeti/Curl/Internal.hs,$(HS_BUILT_SRCS))) \
>         src/Ganeti/Curl/Internal.hsc \
> @@ -1739,12 +1740,6 @@ regen-vcs-version:
>           fi; \
>         fi
>
> -src/Ganeti/Version.hs: src/Ganeti/Version.hs.in \
> -       vcs-version $(built_base_sources)
> -       set -e; \
> -       VCSVER=`cat $(abs_top_srcdir)/vcs-version`; \
> -       sed -e "s/%ver%/$$VCSVER/" < $< > $@
> -
>  src/Ganeti/Hs2Py/ListConstants.hs: src/Ganeti/Hs2Py/ListConstants.hs.in \
>                                    src/Ganeti/HsConstants.hs \
>                                  | stamp-directories
> diff --git a/src/Ganeti/THH.hs b/src/Ganeti/THH.hs
> index 4d8417b..fec40bd 100644
> --- a/src/Ganeti/THH.hs
> +++ b/src/Ganeti/THH.hs
> @@ -29,7 +29,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor,
> Boston, MA
>
>  -}
>
> -module Ganeti.THH ( declareSADT
> +module Ganeti.THH (
> +                  -- * General
> +                    declareSADT
>                    , declareLADT
>                    , declareILADT
>                    , declareIADT
> @@ -64,12 +66,20 @@ module Ganeti.THH ( declareSADT
>                    , DictObject(..)
>                    , genException
>                    , excErrMsg
> +                  -- * Compile-time configuration
> +                  , lookupCompileEnv
> +                  , getCompileEnv
> +                  , absSrcDir
> +                  , absSrcPath
> +                  , fileAsString
>                    ) where
>
>  import Control.Monad (liftM)
>  import Data.Char
>  import Data.List
>  import qualified Data.Set as Set
> +import qualified Data.Text as T
> +import qualified Data.Text.IO as T
>  import Language.Haskell.TH
>
>  import qualified Text.JSON as JSON
> @@ -80,6 +90,8 @@ import Ganeti.JSON
>  import Data.Maybe
>  import Data.Functor ((<$>))
>
> +import System.Environment (getEnvironment)
> +
>  -- * Exported types
>
>  -- | Class of objects that can be converted to 'JSObject'
> @@ -1270,3 +1282,36 @@ genLoadExc tname sname opdefs = do
>    let clause2 = Clause [VarP arg_else] (NormalB fail_type) []
>    sigt <- [t| JSON.JSValue -> JSON.Result $(conT tname) |]
>    return $ (SigD fname sigt, FunD fname [clause1, clause2])
> +
> +
> +-- Functions that work with compile-time configuration
> +
> +-- | Looks up an compile-time environment variable.
> +lookupCompileEnv :: String -> Q (Maybe String)
> +lookupCompileEnv key = lookup key `liftM` runIO getEnvironment
> +
> +-- | Looks up an compile-time environment variable and fail, if it's not
> +-- present.
> +getCompileEnv :: String -> Q String
> +getCompileEnv key = do
> +  v <- lookupCompileEnv key
> +  maybe (fail $ "Environment variable " ++ key ++ " not defined")
> +        return v
> +
> +-- | Return the absolute source directory path.
> +-- Currently it is retrieved from a system environment variable exported
> +-- inside Makefile.
> +absSrcDir :: Q FilePath
> +absSrcDir = getCompileEnv "abs_top_srcdir"
> +
> +-- | Prepends the absolute source directory path to the argument
> +-- ("/" included).
> +absSrcPath :: FilePath -> Q FilePath
> +absSrcPath path = liftM (\dir -> dir ++ "/" ++ path) absSrcDir
> +
> +-- | Loads the content of a file as a string constant expression.
> +-- The given path is relative to the source directory.
> +fileAsString :: FilePath -> Q Exp
> +fileAsString path = do
> +  -- addDependentFile path -- works only with template-haskell >= 2.7
> +  LitE . StringL . T.unpack . T.strip <$> runIO (T.readFile path)
> diff --git a/src/Ganeti/Version.hs b/src/Ganeti/Version.hs
> new file mode 100644
> index 0000000..ab6f25b
> --- /dev/null
> +++ b/src/Ganeti/Version.hs
> @@ -0,0 +1,13 @@
> +{-# LANGUAGE TemplateHaskell #-}
> +-- Hey Emacs, this is a -*- haskell -*- file
> +
> +module Ganeti.Version
> +    (
> +      version
> +    ) where
> +
> +import Ganeti.THH
> +
> +-- | The version of the sources.
> +version :: String
> +version = $( absSrcPath "vcs-version" >>= fileAsString )
> diff --git a/src/Ganeti/Version.hs.in b/src/Ganeti/Version.hs.in
> deleted file mode 100644
> index 012be82..0000000
> --- a/src/Ganeti/Version.hs.in
> +++ /dev/null
> @@ -1,12 +0,0 @@
> --- Hey Emacs, this is a -*- haskell -*- file
> -{- | Auto-generated module holding version information.
> --}
> -
> -module Ganeti.Version
> -    (
> -      version
> -    ) where
> -
> --- | The version of the sources.
> -version :: String
> -version = "(ganeti) version %ver%"
> --
> 1.8.4.1
>
>

Reply via email to