packages feed

cabal-src 0.2.3 → 0.2.4

raw patch · 4 files changed

+194/−2 lines, 4 filesdep +Cabaldep +classy-prelude-conduitdep +http-clientdep ~basenew-component:exe:hackage-docs

Dependencies added: Cabal, classy-prelude-conduit, http-client, http-client-tls, temporary

Dependency ranges changed: base

Files

+ ChangeLog.md view
@@ -0,0 +1,3 @@+## 0.2.4++Added hackage-docs program
+ README.md view
@@ -0,0 +1,70 @@+cabal-src is a package intended to help solve the Cabal diamond dependency+problem.++## The problem++Let's say you have three packages. foo depends on the text package, and can use+any version of it. bar depends on text as well, but requires version 0.10.\*.+foobar depends on both of those.++If you upload these three packages to Hackage and install foobar, cabal will+build foo and bar against the same version of text, and then build foobar+against them. However, if you install these packages locally, foo will be built+against the most recent version of text (currently 0.11.something), and then+foobar will be unbuildable, since its dependencies depend on different versions+of text.++You can see sample packages demonstrating the issue in the *example* folder.++This is just one example of the diamond dependency issue. When dealing with+complicated systems such as Yesod, with dozens of packages that are in+development, the situation becomes much worse.++## Our solution++The important thing to note is that, if the packages are on Hackage, Cabal can+handle the situation. The reason is that Cabal has enough information to+calculate the correct versions of all dependencies to be used. So our goal is+to give Cabal access to information on all dependencies, even those not yet on+Hackage.++Instead of installing a local package with "cabal install", you can now use+"cabal-src-install". This program actually calls out to "cabal install", and if+that build succeeds, will perform the following steps:++1. Create a source tarball via "cabal sdist"++2. Copy this tarball into a special location in your .cabal folder.++3. Update a 00-index.tar file specifically kept for cabal-src.++4. Update your .cabal/config file to recognize the special cabal-src folder as necessary.++If you now install your "foo" and "bar" packages via "cabal-src-install", Cabal+has full access to their source code. When it comes time to install foobar,+Cabal can determine that foo can be recompiled with text 0.10 and will do so+automatically.++## Project status++This software should be considered alpha. We'll likely be using it for all+Yesod development going forward, so I expect that alpha to be upgraded to beta+and finally production quality in short order. All feedback is welcome!++## Usage++Simply replace a call to "cabal install" with a call to "cabal-src-install".+If you would like to only install the source tarball without actually+installing the binary package, run it with "cabal-src-install --src-only".++## mega-sdist++This package now also includes the mega-sdist util, which handles uploading to+Hackage from mega repos.++Compares local code against version on Hackage. Accepts the following options:++* __--gittag__: Automatically tag as well.+* __--test__: Automatically run cabal tests++Uses sources.txt to determine which packages to build.
cabal-src.cabal view
@@ -1,5 +1,5 @@ Name:                cabal-src-Version:             0.2.3+Version:             0.2.4 Synopsis:            Alternative install procedure to avoid the diamond dependency issue. Description:         Please see the README.md file on Github for more information: <https://github.com/yesodweb/cabal-src/blob/master/README.md>. License:             BSD3@@ -10,7 +10,7 @@ Build-type:          Simple Cabal-version:       >=1.6 homepage:            https://github.com/yesodweb/cabal-src-+extra-source-files:  README.md ChangeLog.md  Executable cabal-src-install   Main-is:             cabal-src-install.hs@@ -39,6 +39,15 @@                      , directory                      , conduit-extra                      , resourcet++Executable hackage-docs+  Main-is:             hackage-docs.hs+  Build-depends:       base+                     , http-client+                     , http-client-tls+                     , temporary+                     , classy-prelude-conduit+                     , Cabal  source-repository head   type:     git
+ hackage-docs.hs view
@@ -0,0 +1,110 @@+{-# LANGUAGE NoImplicitPrelude, OverloadedStrings #-}+import Distribution.PackageDescription+import Distribution.PackageDescription.Parse+import Distribution.Verbosity+import Distribution.Package+import ClassyPrelude.Conduit+import Distribution.Text (display)+import Data.Conduit.Process+import System.IO.Temp+import Network.HTTP.Client+import Network.HTTP.Client.MultipartFormData+import Network.HTTP.Client.TLS++main :: IO ()+main = withManager tlsManagerSettings $ \man -> do+    rawCreds <- readFile "/hackage-creds" `catchIO` \_ ->+        error "This tool requires a file /hackage-creds to be present and readable,\ncontaining your username and password for Hackage"+    (username, password) <-+        case words $ decodeUtf8 rawCreds of+            [x, y] -> return (encodeUtf8 x, encodeUtf8 y)+            _ -> error "/hackage-creds didn't look like how I wanted"+    srcsRaw <- readFile "sources.txt" `catchIO` \_ -> return "."+    forM_ (lines $ decodeUtf8 srcsRaw) (processDir username password man . fpFromText)++terror :: Text -> a+terror = error . unpack++processDir :: ByteString -> ByteString -> Manager -> FilePath -> IO ()+processDir username password man dir = do+    putStrLn $ "Processing " ++ fpToText dir+    cabals <- runResourceT $ sourceDirectory dir $$ foldMapC+        (\fp -> if hasExtension fp "cabal"+                    then asSet $ singletonSet fp+                    else mempty)+    cabal <- case setToList cabals of+        [] -> terror $ "No cabal files found in " ++ fpToText dir+        [x] -> return x+        xs -> terror $ "Multiple cabal files found in " ++ fpToText dir ++ ": " ++ tshow xs+    gpd <- readPackageDescription normal $ fpToString cabal+    case condLibrary gpd of+        Nothing -> putStrLn $ concat+            [ "No library in "+            , fpToText cabal+            , ", skipping"+            ]+        Just _ -> do+            let pd = packageDescription gpd+                PackageIdentifier name' version' = package pd+                name = pack $ display name'+                version = pack $ display version'+            runIn dir "cabal"+                [ "haddock"+                , "--hoogle"+                , "--hyperlink-source"+                , "--html-location=/package/$pkg-$version/docs"+                , "--contents-location=/package/$pkg-$version"+                ]+            withSystemTempDirectory "build-docs.XXXXXX" $ \tmp -> do+                let docsdir = concat+                        [ pack tmp+                        , "/"+                        , name+                        , "-"+                        , version+                        , "-docs"+                        ]+                    tarball = docsdir ++ ".tar.gz"+                runIn dir "cp"+                    [ "-R"+                    , "dist/doc/html/" ++ name+                    , docsdir+                    ]+                runIn dir "tar"+                    [ "cvz"+                    , "-C"+                    , pack tmp+                    , "--format=ustar"+                    , "-f"+                    , tarball+                    , concat+                        [ name+                        , "-"+                        , version+                        , "-docs"+                        ]+                    ]+                let url = unpack $ concat+                        [ "https://hackage.haskell.org/package/"+                        , name+                        , "-"+                        , version+                        , "/docs"+                        ]+                bs <- readFile $ fpFromText tarball+                let req = applyBasicAuth username password $ (fromString url)+                        { method = "PUT"+                        , requestHeaders =+                            [ ("Content-Type", "application/x-tar")+                            , ("Content-Encoding", "gzip")+                            ]+                        , requestBody = RequestBodyBS bs+                        }+                httpLbs req man >>= print++runIn :: FilePath -> Text -> [Text] -> IO ()+runIn dir cmd args = do+    print (dir, cmd, args)+    withCheckedProcess cp $ \ClosedStream Inherited Inherited -> return ()+  where+    cp = (proc (unpack cmd) (map unpack args)) { cwd = Just $ fpToString dir }