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 +3/−0
- README.md +70/−0
- cabal-src.cabal +11/−2
- hackage-docs.hs +110/−0
+ 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 }