diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## Changes in 0.29.1
+  - Infer `license` from `license-file`
+
 ## Changes in 0.29.0
   - Put the `cabal-version` at the beginning of the generated file. This Is
     required with `cabal-version: 2.1` and higher. (see #292)
diff --git a/hpack.cabal b/hpack.cabal
--- a/hpack.cabal
+++ b/hpack.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: cfd597be64fbc0242e6c338653cce17e853d1ce5843d07785f81ce0f208ee198
+-- hash: 708562cac33767420b742070fb9e5bb031688eb4b55688a47c9803455468d2ee
 
 name:           hpack
-version:        0.29.0
+version:        0.29.1
 synopsis:       An alternative format for Haskell packages
 description:    See README at <https://github.com/sol/hpack#readme>
 category:       Development
@@ -46,6 +46,7 @@
     , pretty
     , scientific
     , text
+    , text-metrics
     , transformers
     , unordered-containers
     , vector
@@ -67,6 +68,7 @@
       Hpack.Options
       Hpack.Render.Dsl
       Hpack.Render.Hints
+      Hpack.SpdxLicenses
       Hpack.Syntax.Defaults
       Hpack.Syntax.Dependency
       Hpack.Syntax.Git
@@ -99,6 +101,7 @@
     , pretty
     , scientific
     , text
+    , text-metrics
     , transformers
     , unordered-containers
     , vector
@@ -140,6 +143,7 @@
     , template-haskell
     , temporary
     , text
+    , text-metrics
     , transformers
     , unordered-containers
     , vector
@@ -179,6 +183,7 @@
       Hpack.Render
       Hpack.Render.Dsl
       Hpack.Render.Hints
+      Hpack.SpdxLicenses
       Hpack.Syntax.Defaults
       Hpack.Syntax.Dependency
       Hpack.Syntax.Git
diff --git a/src/Hpack/Config.hs b/src/Hpack/Config.hs
--- a/src/Hpack/Config.hs
+++ b/src/Hpack/Config.hs
@@ -72,7 +72,7 @@
 ) where
 
 import           Control.Applicative
-import           Control.Arrow ((>>>), (&&&))
+import           Control.Arrow ((>>>))
 import           Control.Monad
 import           Data.Bifunctor
 import           Data.Bitraversable
@@ -504,7 +504,7 @@
 , packageConfigMaintainer :: Maybe (List String)
 , packageConfigCopyright :: Maybe (List String)
 , packageConfigBuildType :: Maybe BuildType
-, packageConfigLicense :: Maybe String
+, packageConfigLicense :: Maybe (Maybe String)
 , packageConfigLicenseFile :: Maybe (List String)
 , packageConfigTestedWith :: Maybe String
 , packageConfigFlags :: Maybe (Map String FlagSection)
@@ -580,8 +580,8 @@
   userDataDir <- liftIO $ maybe (getAppUserDataDirectory "hpack") return mUserDataDir
   toPackage userDataDir dir config
   where
-    addCabalFile :: (Package, [String]) -> DecodeResult
-    addCabalFile (pkg, warnings) = uncurry DecodeResult (cabalVersion pkg) (takeDirectory_ file </> (packageName pkg ++ ".cabal")) warnings
+    addCabalFile :: ((Package, String), [String]) -> DecodeResult
+    addCabalFile ((pkg, cabalVersion), warnings) = DecodeResult pkg cabalVersion (takeDirectory_ file </> (packageName pkg ++ ".cabal")) warnings
 
     takeDirectory_ :: FilePath -> FilePath
     takeDirectory_ p
@@ -600,29 +600,31 @@
   VerbatimBool b -> show b
   VerbatimNull -> ""
 
-cabalVersion :: Package -> (Package, String)
-cabalVersion pkg@Package{..} = (
+determineCabalVersion :: Maybe (License String) -> Package -> (Package, String)
+determineCabalVersion inferredLicense pkg@Package{..} = (
     pkg {
         packageVerbatim = deleteVerbatimField "cabal-version" packageVerbatim
-      , packageLicense = formatLicense <$> parsedLicense
+      , packageLicense = formatLicense <$> license
       }
   , "cabal-version: " ++ fromMaybe inferredCabalVersion verbatimCabalVersion ++ "\n\n"
   )
   where
-    parsedLicense = (fmap prettyShow . parseLicense &&& id) <$> packageLicense
+    license = parsedLicense <|> inferredLicense
 
+    parsedLicense = fmap prettyShow . parseLicense <$> packageLicense
+
     formatLicense = \ case
-      (MustSPDX spdx, _) -> spdx
-      (CanSPDX spdx, _) | version >= makeVersion [2,2] -> spdx
-      (CanSPDX _, original) -> original
-      (DontTouch, original) -> original
+      MustSPDX spdx -> spdx
+      CanSPDX _ spdx | version >= makeVersion [2,2] -> spdx
+      CanSPDX cabal _ -> prettyShow cabal
+      DontTouch original -> original
 
     mustSPDX :: Bool
-    mustSPDX = maybe False (f . fst) parsedLicense
+    mustSPDX = maybe False f license
       where
         f = \case
-          DontTouch -> False
-          CanSPDX _ -> False
+          DontTouch _ -> False
+          CanSPDX _ _ -> False
           MustSPDX _ -> True
 
     verbatimCabalVersion :: Maybe String
@@ -827,7 +829,7 @@
 type CommonOptionsWithDefaults a = Product DefaultsConfig (CommonOptions ParseCSources ParseCxxSources ParseJsSources a)
 type WithCommonOptionsWithDefaults a = Product DefaultsConfig (WithCommonOptions ParseCSources ParseCxxSources ParseJsSources a)
 
-toPackage :: FilePath -> FilePath -> ConfigWithDefaults -> Warnings (Errors IO) Package
+toPackage :: FilePath -> FilePath -> ConfigWithDefaults -> Warnings (Errors IO) (Package, String)
 toPackage userDataDir dir =
       expandDefaultsInConfig userDataDir dir
   >=> traverseConfig (expandForeignSources dir)
@@ -916,7 +918,7 @@
 
 type GlobalOptions = CommonOptions CSources CxxSources JsSources Empty
 
-toPackage_ :: MonadIO m => FilePath -> Product GlobalOptions (PackageConfig CSources CxxSources JsSources) -> Warnings m Package
+toPackage_ :: MonadIO m => FilePath -> Product GlobalOptions (PackageConfig CSources CxxSources JsSources) -> Warnings m (Package, String)
 toPackage_ dir (Product g PackageConfig{..}) = do
   let
     globalVerbatim = commonOptionsVerbatim g
@@ -949,14 +951,25 @@
 
   dataFiles <- expandGlobs "data-files" dataBaseDir (fromMaybeList packageConfigDataFiles)
 
+  let
+    licenseFiles :: [String]
+    licenseFiles = fromMaybeList $ packageConfigLicenseFile <|> do
+      guard licenseFileExists
+      Just (List ["LICENSE"])
+
+  inferredLicense <- case (packageConfigLicense, licenseFiles) of
+    (Nothing, [file]) -> do
+      input <- liftIO (tryReadFile (dir </> file))
+      case input >>= inferLicense of
+        Nothing -> do
+          tell ["Inferring license from file " ++ file ++ " failed!"]
+          return Nothing
+        license -> return license
+    _ -> return Nothing
+
   let defaultBuildType :: BuildType
       defaultBuildType = maybe Simple (const Custom) mCustomSetup
 
-      configLicenseFiles :: Maybe (List String)
-      configLicenseFiles = packageConfigLicenseFile <|> do
-        guard licenseFileExists
-        Just (List ["LICENSE"])
-
       pkg = Package {
         packageName = packageName_
       , packageVersion = maybe "0.0.0" unPackageVersion packageConfigVersion
@@ -970,8 +983,8 @@
       , packageMaintainer = fromMaybeList packageConfigMaintainer
       , packageCopyright = fromMaybeList packageConfigCopyright
       , packageBuildType = fromMaybe defaultBuildType packageConfigBuildType
-      , packageLicense = packageConfigLicense
-      , packageLicenseFile = fromMaybeList configLicenseFiles
+      , packageLicense = join packageConfigLicense
+      , packageLicenseFile = licenseFiles
       , packageTestedWith = packageConfigTestedWith
       , packageFlags = flags
       , packageExtraSourceFiles = extraSourceFiles
@@ -990,7 +1003,7 @@
 
   tell nameWarnings
   tell (formatMissingSourceDirs missingSourceDirs)
-  return pkg
+  return (determineCabalVersion inferredLicense pkg)
   where
     nameWarnings :: [String]
     packageName_ :: String
diff --git a/src/Hpack/License.hs b/src/Hpack/License.hs
--- a/src/Hpack/License.hs
+++ b/src/Hpack/License.hs
@@ -1,48 +1,53 @@
 {-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE ViewPatterns #-}
 module Hpack.License where
 
+import           Control.Arrow ((&&&))
+import           Data.List
+import           Data.Ord (comparing)
+import           Data.Text (Text)
+import qualified Data.Text as T
+import           Data.Text.Metrics
+
+import           Distribution.Pretty (prettyShow)
 import qualified Distribution.License as Cabal
 import qualified Distribution.SPDX.License as SPDX
+import           Distribution.SPDX.LicenseId
 import           Distribution.Parsec.Class (eitherParsec)
 
-data License a = DontTouch | CanSPDX a | MustSPDX a
+import           Hpack.SpdxLicenses (licenses)
+
+data License a = DontTouch String | CanSPDX Cabal.License a | MustSPDX a
   deriving (Eq, Show, Functor)
 
 parseLicense :: String -> License SPDX.License
-parseLicense license = case spdxLicense of
-  Right l | isUnknown -> MustSPDX l
-  Left  _ | isUnknown -> DontTouch
-  Right l -> CanSPDX l
-  Left  _ -> case cabalLicense of
-    Right l -> CanSPDX (Cabal.licenseToSPDX l)
-    Left _ -> DontTouch
+parseLicense license = case lookup license knownLicenses of
+  Just l -> CanSPDX l (Cabal.licenseToSPDX l)
+  Nothing -> case spdxLicense of
+    Just l -> MustSPDX l
+    Nothing -> DontTouch license
   where
-    spdxLicense :: Either String SPDX.License
-    spdxLicense  = eitherParsec license
+    knownLicenses :: [(String, Cabal.License)]
+    knownLicenses = map (prettyShow &&& id) (Cabal.BSD4 : Cabal.knownLicenses)
 
-    cabalLicense :: Either String Cabal.License
-    cabalLicense = eitherParsec license
+    spdxLicense :: Maybe SPDX.License
+    spdxLicense  = either (const Nothing) Just (eitherParsec license)
 
-    isUnknown = license `notElem` knownLicenses
+probabilities :: Text -> [(LicenseId, Double)]
+probabilities license = map (fmap probability) licenses
+  where
+    probability = realToFrac . levenshteinNorm license
 
-    knownLicenses = [
-        "GPL"
-      , "GPL-2"
-      , "GPL-3"
-      , "LGPL"
-      , "LGPL-2.1"
-      , "LGPL-3"
-      , "AGPL"
-      , "AGPL-3"
-      , "BSD2"
-      , "BSD3"
-      , "BSD4"
-      , "MIT"
-      , "ISC"
-      , "MPL-2.0"
-      , "Apache"
-      , "Apache-2.0"
-      , "PublicDomain"
-      , "AllRightsReserved"
-      , "OtherLicense"
-      ]
+inferLicense :: String -> Maybe (License String)
+inferLicense (T.pack -> xs) = case maximumBy (comparing snd) (probabilities xs) of
+  (license, n) | n > 0.85 -> Just (toLicense license)
+  _ -> Nothing
+  where
+    toLicense :: LicenseId -> License String
+    toLicense license = (case license of
+      MIT -> CanSPDX Cabal.MIT
+      BSD_2_Clause -> CanSPDX Cabal.BSD2
+      BSD_3_Clause -> CanSPDX Cabal.BSD3
+      BSD_4_Clause -> CanSPDX Cabal.BSD4
+      _ -> MustSPDX
+      ) (licenseId license)
diff --git a/src/Hpack/Render.hs b/src/Hpack/Render.hs
--- a/src/Hpack/Render.hs
+++ b/src/Hpack/Render.hs
@@ -1,6 +1,5 @@
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE ViewPatterns #-}
 {-# LANGUAGE CPP #-}
diff --git a/src/Hpack/SpdxLicenses.hs b/src/Hpack/SpdxLicenses.hs
new file mode 100644
--- /dev/null
+++ b/src/Hpack/SpdxLicenses.hs
@@ -0,0 +1,118 @@
+-- DO NOT MODIFY MANUALLY
+--
+-- This file has been generated with ./generate-spdx-licenses-module.sh.
+
+{-# LANGUAGE OverloadedStrings #-}
+module Hpack.SpdxLicenses where
+import Data.Text (Text)
+import Distribution.SPDX.LicenseId
+licenses :: [(LicenseId, Text)]
+licenses = [
+    (BSD_2_Clause, "\
+\Copyright (c) <year> <owner> . All rights reserved.\n\
+\\n\
+\Redistribution and use in source and binary forms, with or without modification,\n\
+\are permitted provided that the following conditions are met:\n\
+\\n\
+\1. Redistributions of source code must retain the above copyright notice,\n\
+\this list of conditions and the following disclaimer.\n\
+\\n\
+\2. Redistributions in binary form must reproduce the above copyright notice,\n\
+\this list of conditions and the following disclaimer in the documentation\n\
+\and/or other materials provided with the distribution.\n\
+\\n\
+\THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n\
+\AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
+\IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
+\ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n\
+\LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
+\DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n\
+\SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n\
+\CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n\
+\OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\n\
+\USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\
+\")
+  , (BSD_3_Clause, "\
+\Copyright (c) <year> <owner> . All rights reserved.\n\
+\\n\
+\Redistribution and use in source and binary forms, with or without modification,\n\
+\are permitted provided that the following conditions are met:\n\
+\\n\
+\1. Redistributions of source code must retain the above copyright notice,\n\
+\this list of conditions and the following disclaimer.\n\
+\\n\
+\2. Redistributions in binary form must reproduce the above copyright notice,\n\
+\this list of conditions and the following disclaimer in the documentation\n\
+\and/or other materials provided with the distribution.\n\
+\\n\
+\3. Neither the name of the copyright holder nor the names of its contributors\n\
+\may be used to endorse or promote products derived from this software without\n\
+\specific prior written permission.\n\
+\\n\
+\THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n\
+\AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
+\IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
+\ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n\
+\LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
+\DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n\
+\SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n\
+\CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n\
+\OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE\n\
+\USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\
+\")
+  , (BSD_4_Clause, "\
+\Copyright (c) <year> <owner> . All rights reserved.\n\
+\\n\
+\Redistribution and use in source and binary forms, with or without modification,\n\
+\are permitted provided that the following conditions are met:\n\
+\\n\
+\1. Redistributions of source code must retain the above copyright notice,\n\
+\this list of conditions and the following disclaimer.\n\
+\\n\
+\2. Redistributions in binary form must reproduce the above copyright notice,\n\
+\this list of conditions and the following disclaimer in the documentation\n\
+\and/or other materials provided with the distribution.\n\
+\\n\
+\3. All advertising materials mentioning features or use of this software must\n\
+\display the following acknowledgement:\n\
+\\n\
+\   This product includes software developed by the organization .\n\
+\\n\
+\4. Neither the name of the copyright holder nor the names of its contributors\n\
+\may be used to endorse or promote products derived from this software without\n\
+\specific prior written permission.\n\
+\\n\
+\THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER \"AS IS\" AND ANY EXPRESS OR IMPLIED\n\
+\WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY\n\
+\AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT\n\
+\HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,\n\
+\OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE\n\
+\GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
+\HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
+\LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
+\OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n\
+\DAMAGE.\n\
+\")
+  , (MIT, "\
+\MIT License\n\
+\\n\
+\Copyright (c) <year> <copyright holders>\n\
+\\n\
+\Permission is hereby granted, free of charge, to any person obtaining a copy\n\
+\of this software and associated documentation files (the \"Software\"), to deal\n\
+\in the Software without restriction, including without limitation the rights\n\
+\to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n\
+\copies of the Software, and to permit persons to whom the Software is furnished\n\
+\to do so, subject to the following conditions:\n\
+\\n\
+\The above copyright notice and this permission notice shall be included in\n\
+\all copies or substantial portions of the Software.\n\
+\\n\
+\THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n\
+\IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n\
+\FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n\
+\OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n\
+\WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF\n\
+\OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\
+\")
+  ]
diff --git a/test/EndToEndSpec.hs b/test/EndToEndSpec.hs
--- a/test/EndToEndSpec.hs
+++ b/test/EndToEndSpec.hs
@@ -351,6 +351,30 @@
             default-language: Haskell2010
           |]) {packageCabalVersion = "2.2"}
 
+      context "with a LICENSE file" $ do
+        before_ (writeFile "LICENSE" license) $ do
+          it "infers license" $ do
+            [i|
+            |] `shouldRenderTo` (package [i|
+            license-file: LICENSE
+            license: MIT
+            |])
+
+          context "when license can not be inferred" $ do
+            it "warns" $ do
+              writeFile "LICENSE" "some-licenese"
+              [i|
+              name: foo
+              |] `shouldWarn` ["Inferring license from file LICENSE failed!"]
+
+          context "when license is null" $ do
+            it "does not infer license" $ do
+              [i|
+              license: null
+              |] `shouldRenderTo` (package [i|
+              license-file: LICENSE
+              |])
+
     describe "build-type" $ do
       it "accept Simple" $ do
         [i|
@@ -1411,3 +1435,26 @@
 
 indentBy :: Int -> String -> String
 indentBy n = unlines . map (replicate n ' ' ++) . lines
+
+license :: String
+license = [i|
+Copyright (c) 2014-2018 Simon Hengel <sol@typeful.net>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+|]
diff --git a/test/Hpack/LicenseSpec.hs b/test/Hpack/LicenseSpec.hs
--- a/test/Hpack/LicenseSpec.hs
+++ b/test/Hpack/LicenseSpec.hs
@@ -2,41 +2,47 @@
 module Hpack.LicenseSpec (spec) where
 
 import           Helper
+import           Data.Maybe
 import           Data.String.Interpolate
 
 import           Distribution.Pretty (prettyShow)
+import           Distribution.Parsec.Class (simpleParsec)
+import qualified Distribution.License as Cabal
 
 import           Hpack.License
 
+cabal :: String -> Cabal.License
+cabal = fromJust . simpleParsec
+
 cabalLicenses :: [(String, License String)]
 cabalLicenses = [
-    ("GPL",               CanSPDX "LicenseRef-GPL")
-  , ("GPL-2",             CanSPDX "GPL-2.0-only")
-  , ("GPL-3",             CanSPDX "GPL-3.0-only")
+    ("GPL",               CanSPDX (cabal "GPL") "LicenseRef-GPL")
+  , ("GPL-2",             CanSPDX (cabal "GPL-2") "GPL-2.0-only")
+  , ("GPL-3",             CanSPDX (cabal "GPL-3") "GPL-3.0-only")
 
-  , ("LGPL",              CanSPDX "LicenseRef-LGPL")
-  , ("LGPL-2.1",          CanSPDX "LGPL-2.1-only")
-  , ("LGPL-3",            CanSPDX "LGPL-3.0-only")
+  , ("LGPL",              CanSPDX (cabal "LGPL") "LicenseRef-LGPL")
+  , ("LGPL-2.1",          CanSPDX (cabal "LGPL-2.1") "LGPL-2.1-only")
+  , ("LGPL-3",            CanSPDX (cabal "LGPL-3") "LGPL-3.0-only")
 
-  , ("AGPL",              CanSPDX "LicenseRef-AGPL")
-  , ("AGPL-3",            CanSPDX "AGPL-3.0-only")
+  , ("AGPL",              CanSPDX (cabal "AGPL") "LicenseRef-AGPL")
+  , ("AGPL-3",            CanSPDX (cabal "AGPL-3") "AGPL-3.0-only")
 
 
-  , ("BSD2",              CanSPDX "BSD-2-Clause")
-  , ("BSD3",              CanSPDX "BSD-3-Clause")
-  , ("BSD4",              CanSPDX "BSD-4-Clause")
+  , ("BSD2",              CanSPDX (cabal "BSD2") "BSD-2-Clause")
+  , ("BSD3",              CanSPDX (cabal "BSD3") "BSD-3-Clause")
+  , ("BSD4",              CanSPDX (cabal "BSD4") "BSD-4-Clause")
 
-  , ("MIT",               CanSPDX "MIT")
-  , ("ISC",               CanSPDX "ISC")
+  , ("MIT",               CanSPDX (cabal "MIT") "MIT")
+  , ("ISC",               CanSPDX (cabal "ISC") "ISC")
 
-  , ("MPL-2.0",           CanSPDX "MPL-2.0")
+  , ("MPL-2.0",           CanSPDX (cabal "MPL-2.0") "MPL-2.0")
 
-  , ("Apache",            CanSPDX "LicenseRef-Apache")
-  , ("Apache-2.0",        CanSPDX "Apache-2.0")
+  , ("Apache",            CanSPDX (cabal "Apache") "LicenseRef-Apache")
+  , ("Apache-2.0",        CanSPDX (cabal "Apache-2.0") "Apache-2.0")
 
-  , ("PublicDomain",      CanSPDX "LicenseRef-PublicDomain")
-  , ("OtherLicense",      CanSPDX "LicenseRef-OtherLicense")
-  , ("AllRightsReserved", CanSPDX "NONE")
+  , ("PublicDomain",      CanSPDX (cabal "PublicDomain") "LicenseRef-PublicDomain")
+  , ("OtherLicense",      CanSPDX (cabal "OtherLicense") "LicenseRef-OtherLicense")
+  , ("AllRightsReserved", CanSPDX (cabal "AllRightsReserved") "NONE")
   ]
 
 spdxLicenses :: [(String, License String)]
@@ -46,7 +52,7 @@
 
 unknownLicenses :: [(String, License String)]
 unknownLicenses = [
-    ("some-license",      DontTouch)
+    ("some-license",      DontTouch "some-license")
   ]
 
 spec :: Spec
@@ -55,3 +61,19 @@
     forM_ (cabalLicenses ++ spdxLicenses ++ unknownLicenses) $ \ (license, expected) -> do
       it [i|parses #{license}|] $ do
         prettyShow <$> parseLicense license `shouldBe` expected
+
+  describe "inferLicense" $ do
+    it "infers MIT" $ do
+      inferLicense <$> readFile "test/resources/mit" `shouldReturn` Just (CanSPDX Cabal.MIT "MIT")
+
+    it "infers BSD-2-Clause" $ do
+      inferLicense <$> readFile "test/resources/bsd2" `shouldReturn` Just (CanSPDX Cabal.BSD2 "BSD-2-Clause")
+
+    it "infers BSD-3-Clause" $ do
+      inferLicense <$> readFile "test/resources/bsd3" `shouldReturn` Just (CanSPDX Cabal.BSD3 "BSD-3-Clause")
+
+    it "infers BSD-4-Clause" $ do
+      inferLicense <$> readFile "test/resources/bsd4" `shouldReturn` Just (CanSPDX Cabal.BSD4 "BSD-4-Clause")
+
+    it "rejects unknown licenses" $ do
+      inferLicense "unknown" `shouldBe` Nothing
