diff --git a/cabal2nix.cabal b/cabal2nix.cabal
--- a/cabal2nix.cabal
+++ b/cabal2nix.cabal
@@ -1,5 +1,5 @@
 name:               cabal2nix
-version:            2.13
+version:            2.14
 synopsis:           Convert Cabal files into Nix build instructions.
 description:
   Convert Cabal files into Nix build instructions. Users of Nix can install the latest
diff --git a/src/Cabal2nix.hs b/src/Cabal2nix.hs
--- a/src/Cabal2nix.hs
+++ b/src/Cabal2nix.hs
@@ -46,7 +46,7 @@
   , optMaintainer :: [String]
 --, optPlatform :: [String]       -- TODO: fix command line handling of platforms
   , optHaddock :: Bool
-  , optHpack :: Bool
+  , optHpack :: HpackUse
   , optDoCheck :: Bool
   , optJailbreak :: Bool
   , optDoBenchmark :: Bool
@@ -74,7 +74,14 @@
           <*> many (strOption $ long "maintainer" <> metavar "MAINTAINER" <> help "maintainer of this package (may be specified multiple times)")
 --        <*> many (strOption $ long "platform" <> metavar "PLATFORM" <> help "supported build platforms (may be specified multiple times)")
           <*> flag True False (long "no-haddock" <> help "don't run Haddock when building this package")
-          <*> switch (long "hpack" <> help "run hpack before configuring this package (only non-hackage packages)")
+          <*>
+          (
+            flag' ForceHpack (long "hpack" <> help "run hpack before configuring this package (only non-hackage packages)")
+            <|>
+            flag' NoHpack (long "no-hpack" <> help "disable hpack run and use only cabal disregarding package.yaml existence")
+            <|>
+            pure PackageYamlHpack
+          )
           <*> flag True False (long "no-check" <> help "don't run regression test suites of this package")
           <*> switch (long "jailbreak" <> help "disregard version restrictions on build inputs")
           <*> switch (long "benchmark" <> help "enable benchmarks for this package")
diff --git a/src/Distribution/Nixpkgs/Fetch.hs b/src/Distribution/Nixpkgs/Fetch.hs
--- a/src/Distribution/Nixpkgs/Fetch.hs
+++ b/src/Distribution/Nixpkgs/Fetch.hs
@@ -78,7 +78,7 @@
     let isHackagePackage = "mirror://hackage/" `L.isPrefixOf` derivUrl
         fetched = derivKind /= ""
     in if isHackagePackage then attr "sha256" $ string derivHash
-       else if not fetched then attr "src" $ text derivUrl
+       else if not fetched then attr "src" $ string derivUrl
             else vcat
                  [ text "src" <+> equals <+> text ("fetch" ++ derivKind) <+> lbrace
                  , nest 2 $ vcat
diff --git a/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs b/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs
--- a/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs
+++ b/src/Distribution/Nixpkgs/Haskell/FromCabal/PostProcess.hs
@@ -182,6 +182,7 @@
   , ("xmonad >= 0.14.2", set phaseOverrides xmonadPostInstall)
   , ("zip-archive < 0.3.1", over (testDepends . tool) (replace (self "zip") (pkg "zip")))
   , ("zip-archive >= 0.3.1 && < 0.3.2.3", over (testDepends . tool) (Set.union (Set.fromList [pkg "zip", pkg "unzip"])))   -- https://github.com/jgm/zip-archive/issues/35
+  , ("zip-archive >= 0.4", set (testDepends . tool . contains (pkg "which")) True)
   ]
 
 pkg :: Identifier -> Binding
diff --git a/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs b/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs
--- a/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs
+++ b/src/Distribution/Nixpkgs/Haskell/PackageSourceSpec.hs
@@ -1,5 +1,5 @@
 module Distribution.Nixpkgs.Haskell.PackageSourceSpec
-  ( Package(..), getPackage, getPackage', loadHackageDB, sourceFromHackage
+  ( HpackUse(..), Package(..), getPackage, getPackage', loadHackageDB, sourceFromHackage
   ) where
 
 import qualified Control.Exception as Exception
@@ -32,6 +32,11 @@
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
 
+data HpackUse
+  = ForceHpack
+  | PackageYamlHpack
+  | NoHpack
+
 data Package = Package
   { pkgSource   :: DerivationSource
   , pkgRanHpack :: Bool -- ^ If hpack generated a new cabal file
@@ -39,8 +44,8 @@
   }
   deriving (Show)
 
-getPackage :: Bool
-           -- ^ Whether hpack should regenerate the cabal file.
+getPackage :: HpackUse
+           -- ^ the way hpack should be used.
            -> Bool
            -- ^ Whether to fetch submodules if fetching from git
            -> Maybe FilePath
@@ -52,8 +57,8 @@
 getPackage optHpack optSubmodules optHackageDB optHackageSnapshot =
   getPackage' optHpack optSubmodules (loadHackageDB optHackageDB optHackageSnapshot)
 
-getPackage' :: Bool
-            -- ^ Whether hpack should regenerate the cabal file.
+getPackage' :: HpackUse
+            -- ^ the way hpack should be used.
             -> Bool
             -- ^ Whether to fetch submodules if fetching from git
             -> IO DB.HackageDB
@@ -63,8 +68,8 @@
   (derivSource, ranHpack, pkgDesc) <- fetchOrFromDB optHpack optSubmodules hackageDB source
   (\s -> Package s ranHpack pkgDesc) <$> maybe (sourceFromHackage (sourceHash source) (showPackageIdentifier pkgDesc) $ sourceCabalDir source) return derivSource
 
-fetchOrFromDB :: Bool
-              -- ^ Whether hpack should regenerate the cabal file
+fetchOrFromDB :: HpackUse
+              -- ^ the way hpack should be used
               -> Bool
               -- ^ Whether to fetch submodules if fetching from git
               -> IO DB.HackageDB
@@ -175,7 +180,7 @@
   name = Cabal.unPackageName (Cabal.packageName pkgId)
   version = Cabal.packageVersion pkgId
 
-cabalFromPath :: Bool -- ^ Whether hpack should regenerate the cabal file
+cabalFromPath :: HpackUse -- ^ the way hpack should be used
               -> FilePath -> MaybeT IO (Bool, Bool, Cabal.GenericPackageDescription)
 cabalFromPath optHpack path = do
   d <- liftIO $ doesDirectoryExist path
@@ -185,21 +190,25 @@
     return (d, ranHpack, pkg)
   else (,,) d False <$> cabalFromFile False path
 
-cabalFromDirectory :: Bool -- ^ Whether hpack should regenerate the cabal file
+cabalFromDirectory :: HpackUse -- ^ the way hpack should be used
                    -> FilePath -> MaybeT IO (Bool, Cabal.GenericPackageDescription)
-cabalFromDirectory True dir = hpackDirectory dir
-cabalFromDirectory False dir = do
+cabalFromDirectory ForceHpack dir = hpackDirectory dir
+cabalFromDirectory NoHpack dir = onlyCabalFromDirectory dir "*** No .cabal file was found. Exiting."
+cabalFromDirectory PackageYamlHpack dir = do
   useHpack <- liftIO $ doesFileExist (dir </> "package.yaml")
   if useHpack
     then do
       liftIO $ hPutStrLn stderr "*** found package.yaml. Using hpack..."
       hpackDirectory dir
-    else do
-      cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)
-      case cabals of
-        [] -> fail "*** Found neither a .cabal file nor package.yaml. Exiting."
-        [cabalFile] -> (,) False <$> cabalFromFile True cabalFile
-        _ -> liftIO $ fail ("*** found more than one cabal file (" ++ show cabals ++ "). Exiting.")
+    else onlyCabalFromDirectory dir "*** Found neither a .cabal file nor package.yaml. Exiting."
+
+onlyCabalFromDirectory :: FilePath -> String -> MaybeT IO (Bool, Cabal.GenericPackageDescription)
+onlyCabalFromDirectory dir errMsg = do
+  cabals <- liftIO $ getDirectoryContents dir >>= filterM doesFileExist . map (dir </>) . filter (".cabal" `isSuffixOf`)
+  case cabals of
+    [] -> fail errMsg
+    [cabalFile] -> (,) False <$> cabalFromFile True cabalFile
+    _ -> liftIO $ fail ("*** found more than one cabal file (" ++ show cabals ++ "). Exiting.")
 
 handleIO :: (Exception.IOException -> IO a) -> IO a -> IO a
 handleIO = Exception.handle
