packages feed

cabal2arch 0.7.4 → 0.7.5

raw patch · 3 files changed

+187/−579 lines, 3 filesdep −pureMD5dep ~archlinuxdep ~basenew-component:exe:manycabal2archnew-uploader

Dependencies removed: pureMD5

Dependency ranges changed: archlinux, base

Files

Main.hs view
@@ -16,39 +16,23 @@ -- TODO: if build-type: Configure, accurate C library dependecies -- require downloading the source, and running configure ----- C libraries are dynamicall linked, should be listed in depends,+-- C libraries are dynamically linked, should be listed in depends, -- rather than makedepends -import Distribution.Package-import Distribution.PackageDescription import Distribution.PackageDescription.Parse-import Distribution.PackageDescription.Configuration import Distribution.Simple.Utils hiding (die) import Distribution.Verbosity-import Distribution.Version-import Distribution.Package-import Distribution.License import Distribution.Text-import Distribution.Compiler-import Distribution.System-import Distribution.Simple.PackageIndex  -- from the archlinux package: import Distribution.ArchLinux.PkgBuild--import Data.Digest.Pure.MD5-import qualified Data.ByteString.Lazy as B+import Distribution.ArchLinux.CabalTranslation  import Control.Monad import Control.Concurrent import qualified Control.OldException as C  import Data.List-import Data.Maybe-import qualified Data.Map as M-import Data.Monoid-import Data.Char-import Debug.Trace  import Text.PrettyPrint @@ -59,8 +43,15 @@ import System.Exit import System.FilePath import System.IO-import System.Process+import System.Process hiding(cwd) +comment :: String+comment = render $ vcat+ [ text "# Note: we list all package dependencies."+ , text "# Your package tool should understand 'provides' syntax"+ , text "#"+ , text "# Keep up to date on http://archhaskell.wordpress.com/"+ , text "#"]  main :: IO () main =@@ -101,26 +92,15 @@    cabalsrc  <- readPackageDescription normal cabalfile     -- Create a package description with all configurations resolved.-   let e_finalcabalsrc = finalizePackageDescription-        []-        (const True)  -- could check against prefered pkgs....-        (Platform X86_64 buildOS) -- linux/x86_64-        (CompilerId GHC (Version [6,10,3] []))--        -- now constrain it to solve in the context of a modern ghc only-        corePackages-        cabalsrc--   finalcabal <- case e_finalcabalsrc of-        Left deps     -> die $ "Unresolved dependencies: " ++show deps-        Right (pkg,_) ->-            return $ pkg { buildDepends = removeCoreFrom (buildDepends pkg) }--   let (pkgbuild', hooks) = cabal2pkg finalcabal+   let finalcabal = preprocessCabal cabalsrc+   finalcabal' <- case finalcabal of+                    Nothing -> die "Aborting..."+                    Just f -> return f+   let (pkgbuild', hooks) = cabal2pkg finalcabal'     pkgbuild  <- getMD5 pkgbuild'-   let doc       = pkg2doc email pkgbuild-+   let apkgbuild = AnnotatedPkgBuild { pkgBuiltWith = Just version, pkgHeader = comment, pkgBody = pkgbuild }+       doc = pkg2doc email apkgbuild        dir = arch_pkgname pkgbuild     setCurrentDirectory cwd@@ -163,132 +143,31 @@  ------------------------------------------------------------------------ --- | Given an abstract pkgbuild, download the source bundle,--- and compute its md5, returning a modified PkgBuild with--- the md5 set.------ TODO we may want to use a local package.+-- | Given an abstract pkgbuild, run "makepkg -g" to compute md5+-- of source files (possibly cached locally), and modify the PkgBuild+-- accordingly. -- getMD5 :: PkgBuild -> IO PkgBuild-getMD5 pkg@(PkgBuild { arch_source = ArchList [url] }) = do-   hPutStrLn stderr $ "Fetching " ++ url-   hFlush stderr-   eres <- myReadProcess "wget" [url] []+getMD5 pkg = do+   putStrLn "Feeding the PKGBUILD to `makepkg -g`..."+   eres <- readProcessWithExitCode "makepkg" ["-g"] (render $ disp pkg)    case eres of-       Left (_,s,_) -> do-            hPutStrLn stderr s-            hPutStrLn stderr $ "Couldn't download package: " ++ show url+       (ExitFailure _,_,err) -> do+            hPutStrLn stderr err+            hPutStrLn stderr $ "makepkg encountered an error while calculating MD5."             return pkg-       Right _ -> do-            src <- B.readFile (takeBaseName url <.> "gz")-            let !md5sum = show (md5 src)-            return pkg { arch_md5sum = ArchList [md5sum] }+       (ExitSuccess,out,err) -> do+            -- s should be "md5sums=(' ... ')"+            hPutStrLn stderr err+            if "md5sums=('" `isPrefixOf` out+               then+                 let md5sum = takeWhile (\x -> x `elem` "0123456789abcdef") $ drop 10 out+                 in return pkg { arch_md5sum = ArchList [md5sum] }+               else do+                 hPutStrLn stderr $ "Incorrect output from makepkg."+                 return pkg getMD5 _ = die "Malformed PkgBuild" --- attempt to filter out core packages we've already satisified--- not actuall correct, since it doesn't take any version--- info into account.------ TODO this should use configDependency to find the precise--- versions we have available on Arch.----removeCoreFrom :: [Dependency] -> [Dependency]-removeCoreFrom []               = []-removeCoreFrom (x@(Dependency n vr):xs) =-  case find (\(Dependency k _) -> n == k) corePackages of-    -- haskell-parsec, haskell-quickcheck-    Just (Dependency _ (ThisVersion v'))-        | withinRange v' vr         ->     removeCoreFrom xs--    Just (Dependency (PackageName "base") _)-                                    ->     removeCoreFrom xs--    Just (Dependency _ AnyVersion)  ->     removeCoreFrom xs-    _                               -> x : removeCoreFrom xs------- Core packages and their versions. These come with--- ghc, so we should be right.------ http://haskell.org/haskellwiki/Libraries_released_with_GHC------ And what Arch Linux thinks GHC provides:------ http://repos.archlinux.org/wsvn/packages/ghc/repos/extra-x86_64/PKGBUILD------ Note: we could just list these directly, and have yaourt solve them.------ NEW POLICY:---      We rely on all "provides" from the GHC library to be listed explicitly.----corePackages :: [Dependency]-corePackages =-    [---- Magic packages we have to remove-     Dependency (PackageName "base")             (ThisVersion (Version  [4,1,0,0] []))-    ,Dependency (PackageName "dph-base")           (AnyVersion)-    ,Dependency (PackageName "dph-par" )           (AnyVersion)-    ,Dependency (PackageName "dph-prim-interface") (AnyVersion)-    ,Dependency (PackageName "dph-prim-par"   )    (AnyVersion)-    ,Dependency (PackageName "dph-prim-seq"   )    (AnyVersion)-    ,Dependency (PackageName "dph-seq"        )    (AnyVersion)-    ,Dependency (PackageName "ghc")              (AnyVersion)-    ,Dependency (PackageName "ghc-prim")         (AnyVersion)-    ,Dependency (PackageName "integer")         (AnyVersion)-    ,Dependency (PackageName "integer-gmp")         (AnyVersion)-    ,Dependency (PackageName "ghc-binary")         (AnyVersion)---- Official Provides: http://repos.archlinux.org/wsvn/packages/ghc/repos/extra-x86_64/PKGBUILD---  ,Dependency (PackageName "array")            (ThisVersion (Version  [0,3,0,0] []))---  ,Dependency (PackageName "bytestring")       (ThisVersion (Version  [0,9,1,5] []))---  ,Dependency (PackageName "Cabal")            (ThisVersion (Version  [1,8,0,2] []))---  ,Dependency (PackageName "containers")       (ThisVersion (Version  [0,3,0,0] []))---  ,Dependency (PackageName "directory")        (ThisVersion (Version  [1,0,1,0] []))---  ,Dependency (PackageName "extensible-exceptions")         (AnyVersion)---  ,Dependency (PackageName "filepath")         (ThisVersion (Version  [1,1,0,3] []))---  ,Dependency (PackageName "haskell98")        (ThisVersion (Version  [1,0,1,1] []))---  ,Dependency (PackageName "hpc")              (ThisVersion (Version  [0,5,0,4] []))---  ,Dependency (PackageName "old-locale")       (ThisVersion (Version  [1,0,0,2] []))---  ,Dependency (PackageName "old-time")         (ThisVersion (Version  [1,0,0,1] []))---  ,Dependency (PackageName "pretty")           (ThisVersion (Version  [1,0,1,1] []))---  ,Dependency (PackageName "process")          (ThisVersion (Version  [1,0,1,2] []))---  ,Dependency (PackageName "random")           (ThisVersion (Version  [1,0,0,2] []))---  ,Dependency (PackageName "syb")              (ThisVersion (Version  [0,1,0,2] []))---  ,Dependency (PackageName "template-haskell") (ThisVersion (Version  [2,4,0,0] []))---  ,Dependency (PackageName "time")             (ThisVersion (Version  [1,1,4] []))---  ,Dependency (PackageName "unix")             (ThisVersion (Version  [2,4,0,0] []))---  utf8-string----- Removed in 6.12.x---  ,Dependency (PackageName "html")             (ThisVersion (Version  [1,0,1,2] []))---  ,Dependency (PackageName "integer")          (ThisVersion (Version  [0,1,0,0] []))---  ,Dependency (PackageName "QuickCheck")       (ThisVersion (Version  [1,2,0,0] []))---  ,Dependency (PackageName "haskell-src")      (ThisVersion (Version  [1,0,1,3] []))---  ,Dependency (PackageName "parsec")           (ThisVersion (Version  [2,1,0,0] []))---  ,Dependency (PackageName "packedstring")     (ThisVersion (Version  [0,1,0,1] []))---  ,Dependency (PackageName "parallel")         (ThisVersion (Version  [1,1,0,0] []))---  ,Dependency (PackageName "network")          (ThisVersion (Version  [2,2,0,1] []))---  ,Dependency (PackageName "mtl")              (ThisVersion (Version  [1,1,0,2] []))---  ,Dependency (PackageName "stm")              (ThisVersion (Version  [2,1,1,2] []))---  ,Dependency (PackageName "HUnit")            (ThisVersion (Version  [1,2,0,3] []))---  ,Dependency (PackageName "xhtml")            (ThisVersion (Version  [3000,2,0,1] []))---  ,Dependency (PackageName "regex-base")       (ThisVersion (Version  [0,72,0,2] []))---  ,Dependency (PackageName "regex-compat")     (ThisVersion (Version  [0,71,0,1] []))---  ,Dependency (PackageName "regex-posix")      (ThisVersion (Version  [0,72,0,2] []))---- Removed in 6.10.x---  ,Dependency (PackageName "editline")         (AnyVersion)---   Dependency (PackageName "ALUT")             (ThisVersion (Version  [2,1,0,0] []))---  ,Dependency (PackageName "cgi")              (ThisVersion (Version  [3001,1,5,1] []))---  ,Dependency (PackageName "fgl")              (ThisVersion (Version  [5,4,1,1] [])) -- gone---  ,Dependency (PackageName "GLUT")             (ThisVersion (Version  [2,1,1,1] []))---  ,Dependency (PackageName "OpenAL")           (ThisVersion (Version  [1,3,1,1] [])) -- gone---  ,Dependency (PackageName "readline")         (ThisVersion (Version  [1,0,1,0] []))--    ]- -- Return the path to a .cabal file. -- If not arguments are specified, use ".", -- if the argument looks like a url, download that@@ -333,412 +212,7 @@             then die $ "directory doesn't exist: " ++ show dir             else findPackageDesc dir -findCLibs :: PackageDescription -> [String]-findCLibs (PackageDescription { library = lib, executables = exe }) =-    -- warn for packages not in list.-    filter (not . null) $ map (canonicalise . map toLower) (some ++ rest)-  where-    some = concatMap (extraLibs.buildInfo) exe-    rest = case lib of-                    Nothing -> []-                    Just l  -> extraLibs (libBuildInfo l) ++-                                map (\(Dependency (PackageName n) _) ->-                                    if '-' `elem` n -                                        then reverse . drop 1 . dropWhile (/= '-') .  reverse $ n-                                        else n)-                                        (pkgconfigDepends (libBuildInfo l))--    canonicalise k = case M.lookup k translationTable of-        Nothing -> trace ("WARNING: this library depends on a C library we do not know the pacman name for (" ++ map toLower k ++ ") . Check the C library names in the generated PKGBUILD File") $ map toLower k-        Just s  -> s--    -- known pacman packages for C libraries we use:-    translationTable = M.fromList-        [("Imlib2",     "imlib2")-        ,("SDL",        "sdl")-        ,("alut",       "freealut")-        ,("bz2",        "bzip2")-        ,("cblas",      "blas")-        ,("crack",      "cracklib")-        ,("crypto",     "openssl")-        ,("curl",       "curl")-        ,("freetype",   "freetype2")-        ,("glib",       "glib2")-        ,("wmflite",    "libwmf")-        ,("il",    "devil")--        ,("jpeg",       "libjpeg")-        ,("ldap",       "libldap")-        ,("pcap",       "libpcap")-        ,("png",        "libpng")-        ,("x11",        "libx11")-        ,("xrandr",     "libxrandr")-        ,("xml2",       "libxml2")-        ,("exif",       "libexif")-        ,("tiff",       "libtiff")-        ,("sndfile",    "libsndfile")-        ,("gcrypt",     "libgcrypt")-        ,("fftw3",      "fftw")--        ,("pq",         "postgresql")-        ,("ssl",        "openssl")-        ,("wx",         "wxgtk")-        ,("xenctrl",    "xen")-        ,("odbc",       "unixodbc")-        ,("z",          "zlib")-        ,("curses",     "ncurses")-        ,("xslt",       "libxslt")-        ,("csound64",   "csound5")-        ,("uuid",       "e2fsprogs")-        ,("doublefann", "fann")-        ,("ev",         "libev")--        ,("pthread",    "")-        ,("m",          "")-        ,("gl",         "")-        ,("glu",        "")-        ,("db_cxx",     "")-        ,("db_cxx",     "")-        ,("xdamage",    "")--        ,("icui18n",          "icu")-        ,("icuuc",          "icu")-        ,("icudata",          "icu")--        ,("netsnmp",        "net-snmp")-        ,("asound",        "alsa-lib")-        ,("ffi",        "libffi")-        ,("ogg",        "libogg")-        ,("theora",        "libtheora")-        ,("mtp",        "libmtp")-        ,("zmq",        "zeromq")-        ,("cv",        "opencv")-        ,("highgui",        "opencv")-        ,("xss",        "libxss")-        ,("idn",        "libidn")-        ,("libgsasl",        "gsasl")-        ,("event",        "libevent")-        ,("gcc_s",        "gcc-libs")---        -- subsumed into glib--        ,("gobject",                "")-        ,("gmodule",                "glib2")-        ,("gio",                    "")-        ,("gthread",                "")-        ,("gnome-vfs-module",       "")-        ,("gstreamer-audio",        "")-        ,("gstreamer-base",         "")-        ,("gstreamer-controller",   "")-        ,("gstreamer-dataprotocol", "")-        ,("gstreamer-net",          "")-        ,("ogremain",          "")-        ,("gnutls-extra",          "")-        ,("pangocairo",        "pango")--        ,("webkit",      "libwebkit")-        ,("gtk+",        "gtkglext")-        ,("gdk",        "gtk")-        ,("gdk-x11-2.0",        "gtk")-        ,("gtk-x11-2.0",        "gtk")-        ,("xine",        "xine-lib")-        ,("ncursesw",        "ncurses")-        ,("panel",          "ncurses")--        ,("gstreamer",   "gstreamer0.10")-        ,("gstreamer-plugins-base", "gstreamer0.10-base")-        ]-        -- atlas--shouldNotBeLibraries :: [String]-shouldNotBeLibraries =-    ["xmonad"-    ,"gitit"-    ,"yavie"-    ,"berp"-    ,"l-seed"-    ,"hspresent"-    ,"haskell-platform"-    ,"xmonad-contrib"-    ,"lambdabot"-    ,"piet"-    ,"hsffig"-    ,"yi"-    ,"haddock"-    ,"hscolour"-    ,"line2pdf"-    ,"distract"-    ,"derive"-    ,"Hedi"-    ,"conjure"-    ,"clevercss"-    ,"cpphs"-    ,"backdropper"-    ,"darcs-beta"-    ,"gtk2hs"-    ,"darcs"-    ,"greencard"--- the pandoc package doesnt' ship haskell-pandoc---    ,"pandoc"-    ,"pugs-drift"-    ,"wol"-    ,"timepiece"-    ,"hledger"-    ,"hp2any-graph"-    ,"hp2any-manager"-    ]---- translate some library dependencies to gtk names----gtk2hsIfy :: [Dependency] -> [Dependency]-gtk2hsIfy = id--{--gtk2hsIfy [] = []-gtk2hsIfy xs | foundSome = Dependency (PackageName "gtk2hs") AnyVersion :-                           [ v | v@(Dependency n _) <- xs-                           , n `notElem` gtkLibs ]-             | otherwise = xs--    where-        foundSome = not . null $ filter (`elem` gtkLibs) (map unDep xs)-        unDep (Dependency n _) = n--}---- TODO: will need to remove this:-gtkLibs :: [PackageName]-gtkLibs = map PackageName-    []-    {--    ["glade" -- guihaskell-    ,"cairo"-    ,"glib"-    ,"gtk"-    ,"gconf"-    ,"gtkglext"-    ,"gtksourceview2"-    ,"mozembed"-    ,"svgcairo"-    ]-    -}-- --------------------------------------------------------------------------- Parsing and pretty printing:------- | Translate an abstract PkgBuild file into a document structure----pkg2doc :: String -> PkgBuild -> Doc-pkg2doc email pkg = vcat- [ text "# Contributor:"-    <+> text email- , text "# Package generated by cabal2arch" <+> disp version- , text "# Note: we list all package dependencies."- , text "# Your package tool should understand 'provides' syntax"- , text "#"- , text "# Keep up to date on http://archhaskell.wordpress.com/"- , text "#"- , text "pkgname"-    <=> text (arch_pkgname pkg)- , text "pkgrel"-    <=> int (arch_pkgrel pkg)- , text "pkgver"-    <=> disp (arch_pkgver pkg)- , text "pkgdesc"-    <=> text (show (arch_pkgdesc pkg))- , text "url"-    <=> doubleQuotes (text (arch_url pkg))- , text "license"-    <=> disp (arch_license pkg)- , text "arch"-    <=> disp (arch_arch pkg)- , text "makedepends"-    <=> disp (arch_makedepends pkg)- , case arch_depends pkg of-        ArchList [] -> empty-        _           -> text "depends" <=> disp (arch_depends pkg)- , text "options" <=> disp (arch_options pkg)- , text "source"-    <=> dispNoQuotes (arch_source pkg)- , case arch_install pkg of-    Nothing -> empty-    Just p  -> text "install" <=> disp p- , text "md5sums"-    <=> disp (arch_md5sum pkg)- , hang-    (text "build() {") 4-             (vcat $ (map text) (arch_build pkg))-   $$ char '}'- ]------- | Tranlsate a generic cabal file into a PGKBUILD----cabal2pkg :: PackageDescription -> (PkgBuild, Maybe String)-cabal2pkg cabal---- TODO decide if its a library or an executable,--- handle mullltipackages--- extract C dependencies---- = trace (show cabal) $-  =-  (emptyPkgBuild-    { arch_pkgname = archName-    , arch_pkgver  = vers-    , arch_url     = "http://hackage.haskell.org/package/"++display name- --       else homepage cabal-    , arch_pkgdesc = case synopsis cabal of-                          [] -> take 80 (description cabal)-                          s  -> s-    , arch_license =-        ArchList . return $-            case license cabal of-                x@GPL {} -> x-                x@LGPL {} -> x-                l    -> UnknownLicense ("custom:"++ show l)--    -- All Hackage packages depend on GHC at build time-    -- All Haskell libraries are prefixed with "haskell-"-    , arch_makedepends = if not hasLibrary-            then my_makedepends-            else ArchList [] -- makedepends should not duplicate depends--    , arch_depends =-        (if not (isLibrary)-            then-                ArchList [ArchDep (Dependency (PackageName "gmp") AnyVersion)]-                                `mappend`-                                anyClibraries-            else ArchList [])-        `mappend`-            -- libraries have 'register-time' dependencies on-            -- their dependent Haskell libraries.-            ---           (if hasLibrary then my_makedepends-                          else ArchList [])--    -- need the dependencies of all flags that are on by default, for all libraries and executables--    -- Hackage programs only need their own source to build-    , arch_source  = ArchList . return $-          "http://hackage.haskell.org/packages/archive/"-       ++ (display name </> display vers </> display name <-> display vers <.> "tar.gz")--    , arch_build =-        [ "cd ${srcdir}/" </> display name <-> display vers-        , "runhaskell Setup configure --prefix=/usr --docdir=/usr/share/doc/${pkgname} || return 1"-        , "runhaskell Setup build                   || return 1"-        ] ++--    -- Only needed for libraries:-        (if hasLibrary-           then-            [ "runhaskell Setup haddock || return 1"-            , "runhaskell Setup register   --gen-script || return 1"-            , "runhaskell Setup unregister --gen-script || return 1"-            , "install -D -m744 register.sh   ${pkgdir}/usr/share/haskell/$pkgname/register.sh"-            , "install    -m744 unregister.sh ${pkgdir}/usr/share/haskell/$pkgname/unregister.sh"-            , "install -d -m755 $pkgdir/usr/share/doc/ghc/html/libraries"-            , "ln -s /usr/share/doc/${pkgname}/html ${pkgdir}/usr/share/doc/ghc/html/libraries/" ++ (display name)-            ]-           else [])-         ++-         ["runhaskell Setup copy --destdir=${pkgdir} || return 1"]-         ++-         (if not (null (licenseFile cabal)) && (case license cabal of GPL {} -> False; LGPL {} -> False; _ -> True)-          then-              [ "install -D -m644 " ++ licenseFile cabal ++ " ${pkgdir}/usr/share/licenses/$pkgname/LICENSE || return 1"-              , "rm -f ${pkgdir}/usr/share/doc/${pkgname}/LICENSE"-              ]-          else [])--    -- if its a library:-    , arch_install = if hasLibrary then Just $ install_hook_name archName-                                   else Nothing--    }, if hasLibrary-          then Just (install_hook archName)-          else Nothing-    )--  where-    archName = map toLower (if isLibrary then "haskell-" ++ display name else display name)-    name     = pkgName (package cabal)-    vers     = pkgVersion (package cabal)--    -- build time dependencies-    my_makedepends =-     (arch_makedepends emptyPkgBuild)-        `mappend`-     -- Haskell libraries-     -- TODO: use a real package spec to compute these names-     -- based on what is in Arch.-     ArchList-         [ ArchDep (Dependency (PackageName $-               if d `notElem` shouldNotBeLibraries-                    then "haskell" <-> map toLower (display d) else display d) v)-         | Dependency (PackageName d) v <- gtk2hsIfy (buildDepends cabal) ]-        `mappend`-     anyClibraries-        `mappend`-     ArchList [ ArchDep d' | b <- allBuildInfo cabal-                          , d@(Dependency n _) <- buildTools b-                          , n /= PackageName "hsc2hs"-                          , let d' | n `elem` gtkTools-                                        = Dependency (PackageName "gtk2hs-buildtools") AnyVersion-                                   | otherwise        = d-                          ]--    gtkTools = map PackageName ["gtk2hsTypeGen" , "gtk2hsHookGenerator", "gtk2hsC2hs"]--    -- TODO: need a 'nub' in here.--    hasLibrary = isJust (library cabal)-    isLibrary  = isJust (library cabal) -- && null (executables cabal)-                    && map toLower (display name) `notElem` shouldNotBeLibraries--    anyClibraries | null libs = ArchList []-                  | otherwise = ArchList libs-       where-         libs = [ ArchDep (Dependency (PackageName s) AnyVersion) | s <- nub (findCLibs cabal) ]---- quickcheck 2.--- parsec 3------- post install, and pre-remove hooks to run, to sync up ghc-pkg----install_hook_name :: String -> String-install_hook_name pkgname = pkgname <.> "install"--install_hook :: String -> String-install_hook pkgname = unlines-    [ "HS_DIR=/usr/share/haskell/" ++ pkgname-    , "post_install() {"-    , "  ${HS_DIR}/register.sh"-    , "  (cd /usr/share/doc/ghc/html/libraries; ./gen_contents_index)"-    , "}"-    , "pre_upgrade() {"-    , "  ${HS_DIR}/unregister.sh"-    , "}"-    , "post_upgrade() {"-    , "  ${HS_DIR}/register.sh"-    , "  (cd /usr/share/doc/ghc/html/libraries; ./gen_contents_index)"-    , "}"-    , "pre_remove() {"-    , "  ${HS_DIR}/unregister.sh"-    , "}"-    , "post_remove() {"-    , "  (cd /usr/share/doc/ghc/html/libraries; ./gen_contents_index)"-    , "}"-    , "op=$1"-    , "shift"-    , "$op $*" ]-------------------------------------------------------------------------- -- Some extras -- @@ -768,12 +242,6 @@ die s = do     hPutStrLn stderr $ "cabal2pkg:\n" ++ s     exitWith (ExitFailure 1)--(<=>) :: Doc -> Doc -> Doc-x <=> y = x <> char '=' <> y--(<->) :: String -> String -> String-x <-> y = x ++ "-" ++ y  -- Safe wrapper for getEnv getEnvMaybe :: String -> IO (Maybe String)
cabal2arch.cabal view
@@ -1,29 +1,41 @@ name:               cabal2arch-version:            0.7.4-homepage:           http://code.haskell.org/~dons/code/cabal2arch-synopsis:           Create Arch Linux packages from Cabal packages-description:        Create Arch Linux packages from Cabal packages+version:            0.7.5+homepage:           http://github.com/archhaskell/+synopsis:           Create Arch Linux packages from Cabal packages.+description:        Create Arch Linux packages from Cabal packages. category:           Distribution license:            BSD3 license-file:       LICENSE-author:             Don Stewart-maintainer:         dons@galois.com-cabal-version:      >= 1.2+author:             Don Stewart <dons@galois.com>+maintainer:         ArchHaskell Team <arch-haskell@haskell.org>+cabal-version:      >= 1.6 build-type:         Simple +source-repository head+  type:                 git+  location:             git://github.com/archhaskell/cabal2arch.git+ executable cabal2arch     main-is:            Main.hs     ghc-options:        -Wall -    build-depends:      +    build-depends:         base >= 4 && <= 6,         pretty,         process,         directory,         containers,         bytestring,-        Cabal   > 1.8,-        pureMD5 >= 0.2.1,+        Cabal > 1.8,         filepath,-        archlinux > 0.1+        archlinux >= 0.3.3 +executable manycabal2arch+    main-is:            scripts/manycabal2arch.hs+    ghc-options:        -Wall++    build-depends:+        base >=4 && <6,+        directory,+        filepath,+        archlinux >= 0.3.3
+ scripts/manycabal2arch.hs view
@@ -0,0 +1,128 @@+-- |+-- Module    : manycabal2arch: batch creation of PKGBUILDs from Hackage tarball+-- Copyright : (c) Rémy Oudompheng 2010+-- License   : BSD3+--+-- Maintainer: Arch Haskell Team <arch-haskell@haskell.org>+-- Stability : provisional+-- Portability:+--++import Distribution.ArchLinux.PkgBuild+import Distribution.ArchLinux.CabalTranslation+import Distribution.ArchLinux.HackageTranslation++import Distribution.PackageDescription+import Distribution.Text+import Text.PrettyPrint++import Data.List+import qualified Data.ByteString.Lazy as Bytes+import System.Directory+import System.FilePath++-- Input/output+import System.Environment+import System.IO+import System.Process+import System.Exit++import qualified Control.OldException as C++import Debug.Trace++import Paths_cabal2arch++exportPackage :: FilePath -> String -> GenericPackageDescription -> IO ()+exportPackage dot email p = do+  let q = preprocessCabal p+  case q of+    Nothing -> return ()+    Just p' -> do+      let (pkg, script) = cabal2pkg p'+          pkgname = trace ("Converting package " ++ arch_pkgname pkg) (arch_pkgname pkg)+      pkgbuild  <- getMD5 pkg+      let apkgbuild = AnnotatedPkgBuild { pkgBuiltWith = Just version, pkgHeader = comment, pkgBody = pkgbuild }+          rawpkgbuild = (render $ pkg2doc email apkgbuild) ++ "\n"++      createDirectoryIfMissing True (dot </> pkgname)+      writeFile (dot </> pkgname </> "PKGBUILD") rawpkgbuild+      case script of+        Nothing -> return ()+        Just s -> writeFile (dot </> pkgname </> pkgname ++ ".install") s++main :: IO ()+main = do+  argv <- getArgs+  x <- case argv of+    _:_:_:_ -> return ()+    _ -> help+  pkglist <- readFile (argv !! 0)+  tarball <- Bytes.readFile (argv !! 1)+  repo <- canonicalizePath (argv !! 2)+  email <- do+    r <- getEnvMaybe "ARCH_HASKELL"+    case r of+      Nothing -> do hPutStrLn stderr "Warning: ARCH_HASKELL environment variable not set. Set this to the maintainer contact you wish to use. \n E.g. 'Arch Haskell Team <arch-haskell@haskell.org>'"+                    return []+      Just s  -> return s+  let cabals = getSpecifiedCabalsFromTarball tarball (lines pkglist)+  mapM (exportPackage repo email) cabals+  return ()++-- Safe wrapper for getEnv                                                                                            +getEnvMaybe :: String -> IO (Maybe String)+getEnvMaybe name = C.handle (const $ return Nothing) (Just `fmap` getEnv name)++comment :: String+comment = render $ vcat+ [ text "# Note: we list all package dependencies."+ , text "# Your package tool should understand 'provides' syntax"+ , text "#"+ , text "# Keep up to date on http://archhaskell.wordpress.com/"+ , text "#"]++-- | Given an abstract pkgbuild, run "makepkg -g" to compute md5+-- of source files (possibly cached locally), and modify the PkgBuild+-- accordingly.+--+getMD5 :: PkgBuild -> IO PkgBuild+getMD5 pkg = do+   putStrLn "Feeding the PKGBUILD to `makepkg -g`..."+   eres <- readProcessWithExitCode "makepkg" ["-g"] (render $ disp pkg)+   case eres of+       (ExitFailure _,_,err) -> do+            hPutStrLn stderr err+            hPutStrLn stderr $ "makepkg encountered an error while calculating MD5."+            return pkg+       (ExitSuccess,out,err) -> do+            -- s should be "md5sums=(' ... ')"+            hPutStrLn stderr err+            if "md5sums=('" `isPrefixOf` out+               then+                 let md5sum = takeWhile (\x -> x `elem` "0123456789abcdef") $ drop 10 out+                 in return pkg { arch_md5sum = ArchList [md5sum] }+               else do+                 hPutStrLn stderr $ "Incorrect output from makepkg."+                 return pkg++--+-- | Help file+--+help :: IO a+help = do+ hPutStrLn stderr $ unlines+    [ "Usage: manycabal2arch pkglist tarball destination"+    , ""+    , "  Generate a ABS-like tree from a list of packages and the"+    , "  uncompressed Hackage tarball"+    , ""+    , "Arguments: pkglist"+    , "              A file with lines of the form \"<package-name> <version-number>\""+    , "           tarball"+    , "              The path to 00-index.tar, for example"+    , "              $HOME/.cabal/packages/hackage.haskell.org/00-index.tar"+    , "           destination"+    , "              The directory where the repository will be created"+    ]+ exitWith ExitSuccess