diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 0.2.5
+
+hackage-docs now also handles uploads from tarballs dir
+
 ## 0.2.4
 
 Added hackage-docs program
diff --git a/cabal-src.cabal b/cabal-src.cabal
--- a/cabal-src.cabal
+++ b/cabal-src.cabal
@@ -1,5 +1,5 @@
 Name:                cabal-src
-Version:             0.2.4
+Version:             0.2.5
 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
diff --git a/hackage-docs.hs b/hackage-docs.hs
--- a/hackage-docs.hs
+++ b/hackage-docs.hs
@@ -10,6 +10,7 @@
 import Network.HTTP.Client
 import Network.HTTP.Client.MultipartFormData
 import Network.HTTP.Client.TLS
+import Filesystem (isDirectory)
 
 main :: IO ()
 main = withManager tlsManagerSettings $ \man -> do
@@ -19,8 +20,22 @@
         case words $ decodeUtf8 rawCreds of
             [x, y] -> return (encodeUtf8 x, encodeUtf8 y)
             _ -> error "/hackage-creds didn't look like how I wanted"
+
+    whenM (isDirectory "tarballs") $ runResourceT
+        $ sourceDirectory "tarballs"
+       $$ mapM_C (liftIO . uploadTarball username password man)
+
     srcsRaw <- readFile "sources.txt" `catchIO` \_ -> return "."
     forM_ (lines $ decodeUtf8 srcsRaw) (processDir username password man . fpFromText)
+
+uploadTarball :: ByteString -> ByteString -> Manager -> FilePath -> IO ()
+uploadTarball username password man fp = do
+    let formData =
+            [ partFile "package" $ fpToString fp
+            ]
+    req1 <- formDataBody formData "http://hackage.haskell.org/packages/"
+    let req2 = applyBasicAuth username password req1
+    tryAny (httpLbs req2 man) >>= print
 
 terror :: Text -> a
 terror = error . unpack
