diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,19 @@
+## Change in 0.18.0
+  - Make `executable` a shortcut of `executables: { package-name: ... }`
+  - Add support for `ghcjs-options` and `js-sources` (see #161)
+  - Allow `license-file` to be a list
+  - Accept input file on command-line (see #106)
+  - Add Paths_* when no modules are specified (see #86)
+
+## Changes in 0.17.1
+  - Do not descend into irrelevant directories when inferring modules (see #165)
+
+## Changes in 0.17.0
+  - Added custom-setup section
+  - Add support for `!include` directives
+
+## Changes in 0.16.0
+  - Warn when `name` is missing
+  - Support globs in `c-sources`
+  - Use binary I/O for cabal files avoiding problems with non-UTF-8 locales
+  - Fix rendering of `.` as directory (cabal syntax issue)
diff --git a/hpack.cabal b/hpack.cabal
--- a/hpack.cabal
+++ b/hpack.cabal
@@ -1,9 +1,9 @@
--- This file has been generated from package.yaml by hpack version 0.17.0.
+-- This file has been generated from package.yaml by hpack version 0.18.0.
 --
 -- see: https://github.com/sol/hpack
 
 name:           hpack
-version:        0.17.1
+version:        0.18.0
 synopsis:       An alternative format for Haskell packages
 description:    See README at <https://github.com/sol/hpack#readme>
 category:       Development
@@ -14,6 +14,9 @@
 license-file:   LICENSE
 build-type:     Simple
 cabal-version:  >= 1.10
+
+extra-source-files:
+    CHANGELOG.md
 
 source-repository head
   type: git
diff --git a/src/Hpack.hs b/src/Hpack.hs
--- a/src/Hpack.hs
+++ b/src/Hpack.hs
@@ -11,6 +11,7 @@
 , parseVerbosity
 , extractVersion
 , parseVersion
+, splitDirectory
 #endif
 ) where
 
@@ -28,6 +29,8 @@
 import           System.Environment
 import           System.Exit
 import           System.IO
+import           System.FilePath
+import           System.Directory
 import           Text.ParserCombinators.ReadP
 
 import           Paths_hpack (version)
@@ -38,9 +41,9 @@
 programVersion :: Version -> String
 programVersion v = "hpack version " ++ Version.showVersion v
 
-header :: Version -> String
-header v = unlines [
-    "-- This file has been generated from " ++ packageConfig ++ " by " ++ programVersion v ++ "."
+header :: FilePath -> Version -> String
+header p v = unlines [
+    "-- This file has been generated from " ++ p ++ " by " ++ programVersion v ++ "."
   , "--"
   , "-- see: https://github.com/sol/hpack"
   , ""
@@ -53,8 +56,8 @@
     ["--version"] -> putStrLn (programVersion version)
     ["--help"] -> printHelp
     _ -> case parseVerbosity args of
-      (verbose, [dir]) -> hpack dir verbose
-      (verbose, []) -> hpack "" verbose
+      (verbose, [dir]) -> hpack (Just dir) verbose
+      (verbose, []) -> hpack Nothing verbose
       _ -> do
         printHelp
         exitFailure
@@ -87,10 +90,10 @@
   [v] -> Just v
   _ -> Nothing
 
-hpack :: FilePath -> Bool -> IO ()
+hpack :: Maybe FilePath -> Bool -> IO ()
 hpack = hpackWithVersion version
 
-hpackResult :: FilePath -> IO Result
+hpackResult :: Maybe FilePath -> IO Result
 hpackResult = hpackWithVersionResult version
 
 data Result = Result {
@@ -101,9 +104,9 @@
 
 data Status = Generated | AlreadyGeneratedByNewerHpack | OutputUnchanged
 
-hpackWithVersion :: Version -> FilePath -> Bool -> IO ()
-hpackWithVersion v dir verbose = do
-    r <- hpackWithVersionResult v dir
+hpackWithVersion :: Version -> Maybe FilePath -> Bool -> IO ()
+hpackWithVersion v p verbose = do
+    r <- hpackWithVersionResult v p
     forM_ (resultWarnings r) $ \warning -> hPutStrLn stderr ("WARNING: " ++ warning)
     when verbose $ putStrLn $
       case resultStatus r of
@@ -111,9 +114,21 @@
         OutputUnchanged -> resultCabalFile r ++ " is up-to-date"
         AlreadyGeneratedByNewerHpack -> resultCabalFile r ++ " was generated with a newer version of hpack, please upgrade and try again."
 
-hpackWithVersionResult :: Version -> FilePath -> IO Result
-hpackWithVersionResult v dir = do
-  (warnings, cabalFile, new) <- run dir
+splitDirectory :: Maybe FilePath -> IO (Maybe FilePath, FilePath)
+splitDirectory Nothing = return (Nothing, packageConfig)
+splitDirectory (Just p) = do
+  isDirectory <- doesDirectoryExist p
+  return $ if isDirectory
+    then (Just p, packageConfig)
+    else let
+      file = takeFileName p
+      dir = takeDirectory p
+      in (guard (p /= file) >> Just dir, if null file then packageConfig else file)
+
+hpackWithVersionResult :: Version -> Maybe FilePath -> IO Result
+hpackWithVersionResult v p = do
+  (dir, file) <- splitDirectory p
+  (warnings, cabalFile, new) <- run dir file
   old <- fmap splitHeader <$> tryReadFile cabalFile
   let oldVersion = fmap fst old >>= extractVersion
   status <-
@@ -121,7 +136,7 @@
       if (fmap snd old == Just (lines new)) then
         return OutputUnchanged
       else do
-        B.writeFile cabalFile $ encodeUtf8 $ T.pack $ header v ++ new
+        B.writeFile cabalFile $ encodeUtf8 $ T.pack $ header file v ++ new
         return Generated
     else
       return AlreadyGeneratedByNewerHpack
diff --git a/src/Hpack/Config.hs b/src/Hpack/Config.hs
--- a/src/Hpack/Config.hs
+++ b/src/Hpack/Config.hs
@@ -80,7 +80,7 @@
   , packageCopyright = []
   , packageBuildType = Simple
   , packageLicense = Nothing
-  , packageLicenseFile = Nothing
+  , packageLicenseFile = []
   , packageTestedWith = Nothing
   , packageFlags = []
   , packageExtraSourceFiles = []
@@ -119,7 +119,7 @@
   ++ maybe [] sectionDependencies packageLibrary
 
 section :: a -> Section a
-section a = Section a [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] []
+section a = Section a [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] []
 
 packageConfig :: FilePath
 packageConfig = "package.yaml"
@@ -230,9 +230,11 @@
 , commonOptionsOtherExtensions :: Maybe (List String)
 , commonOptionsGhcOptions :: Maybe (List GhcOption)
 , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption)
+, commonOptionsGhcjsOptions :: Maybe (List GhcjsOption)
 , commonOptionsCppOptions :: Maybe (List CppOption)
 , commonOptionsCcOptions :: Maybe (List CcOption)
 , commonOptionsCSources :: Maybe (List FilePath)
+, commonOptionsJsSources :: Maybe (List FilePath)
 , commonOptionsExtraLibDirs :: Maybe (List FilePath)
 , commonOptionsExtraLibraries :: Maybe (List FilePath)
 , commonOptionsIncludeDirs :: Maybe (List FilePath)
@@ -308,6 +310,8 @@
     "Custom"    -> return Custom
     _           -> fail "build-type must be one of: Simple, Configure, Make, Custom"
 
+type ExecutableConfig = CaptureUnknownFields (Section ExecutableSection)
+
 data PackageConfig = PackageConfig {
   packageConfigName :: Maybe String
 , packageConfigVersion :: Maybe String
@@ -322,7 +326,7 @@
 , packageConfigCopyright :: Maybe (List String)
 , packageConfigBuildType :: Maybe BuildType
 , packageConfigLicense :: Maybe String
-, packageConfigLicenseFile :: Maybe String
+, packageConfigLicenseFile :: Maybe (List String)
 , packageConfigTestedWith :: Maybe String
 , packageConfigFlags :: Maybe (Map String (CaptureUnknownFields FlagSection))
 , packageConfigExtraSourceFiles :: Maybe (List FilePath)
@@ -331,7 +335,8 @@
 , packageConfigGit :: Maybe String
 , packageConfigCustomSetup :: Maybe (CaptureUnknownFields CustomSetupSection)
 , packageConfigLibrary :: Maybe (CaptureUnknownFields (Section LibrarySection))
-, packageConfigExecutables :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))
+, packageConfigExecutable :: Maybe ExecutableConfig
+, packageConfigExecutables :: Maybe (Map String ExecutableConfig)
 , packageConfigTests :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))
 , packageConfigBenchmarks :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))
 } deriving (Eq, Show, Generic)
@@ -425,7 +430,7 @@
 , packageCopyright :: [String]
 , packageBuildType :: BuildType
 , packageLicense :: Maybe String
-, packageLicenseFile :: Maybe FilePath
+, packageLicenseFile :: [FilePath]
 , packageTestedWith :: Maybe String
 , packageFlags :: [Flag]
 , packageExtraSourceFiles :: [FilePath]
@@ -463,9 +468,11 @@
 , sectionOtherExtensions :: [String]
 , sectionGhcOptions :: [GhcOption]
 , sectionGhcProfOptions :: [GhcProfOption]
+, sectionGhcjsOptions :: [GhcjsOption]
 , sectionCppOptions :: [CppOption]
 , sectionCcOptions :: [CcOption]
 , sectionCSources :: [FilePath]
+, sectionJsSources :: [FilePath]
 , sectionExtraLibDirs :: [FilePath]
 , sectionExtraLibraries :: [FilePath]
 , sectionIncludeDirs :: [FilePath]
@@ -514,24 +521,30 @@
 
 mkPackage :: FilePath -> (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package)
 mkPackage dir (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do
+  libraryResult <- mapM (toLibrary dir packageName_ globalOptions) mLibrarySection
   let
-    nameWarnings :: [String]
-    name :: String
-    (nameWarnings, name) = maybe (["Package name not specified, inferred " ++ show inferredName], inferredName) ((,) []) packageConfigName
-      where inferredName = takeBaseName dir
+    executableWarnings :: [String]
+    executableSections :: [(String, Section ExecutableSection)]
+    (executableWarnings, executableSections) = (warnings, map (fmap captureUnknownFieldsValue) sections)
+      where
+        sections = case (packageConfigExecutable, packageConfigExecutables) of
+          (Nothing, Nothing) -> []
+          (Just executable, _) -> [(packageName_, executable)]
+          (Nothing, Just executables) -> Map.toList executables
 
-    mCustomSetup :: Maybe CustomSetup
-    mCustomSetup = toCustomSetup <$> mCustomSetupSection
+        warnings = ignoringExecutablesWarning ++ unknownFieldWarnings
+        ignoringExecutablesWarning = case (packageConfigExecutable, packageConfigExecutables) of
+          (Just _, Just _) -> ["Ignoring field \"executables\" in favor of \"executable\""]
+          _ -> []
+        unknownFieldWarnings = formatUnknownSectionFields (isJust packageConfigExecutables) "executable" sections
 
-  libraryResult <- mapM (toLibrary dir name globalOptions) mLibrarySection
-  let
     mLibrary :: Maybe (Section Library)
     mLibrary = fmap snd libraryResult
 
     libraryWarnings :: [String]
     libraryWarnings = maybe [] fst libraryResult
 
-  (executablesWarnings, executables) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) executableSections)
+  (executablesWarnings, executables) <- toExecutables dir globalOptions executableSections
   (testsWarnings, tests) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) testsSections)
   (benchmarksWarnings, benchmarks) <- toExecutables dir globalOptions  (map (fmap captureUnknownFieldsValue) benchmarkSections)
 
@@ -553,8 +566,13 @@
   let defaultBuildType :: BuildType
       defaultBuildType = maybe Simple (const Custom) mCustomSetup
 
+      configLicenseFiles :: Maybe (List String)
+      configLicenseFiles = packageConfigLicenseFile <|> do
+        guard licenseFileExists
+        Just (List ["LICENSE"])
+
       pkg = Package {
-        packageName = name
+        packageName = packageName_
       , packageVersion = fromMaybe "0.0.0" packageConfigVersion
       , packageSynopsis = packageConfigSynopsis
       , packageDescription = packageConfigDescription
@@ -567,7 +585,7 @@
       , packageCopyright = fromMaybeList packageConfigCopyright
       , packageBuildType = fromMaybe defaultBuildType packageConfigBuildType
       , packageLicense = packageConfigLicense
-      , packageLicenseFile = packageConfigLicenseFile <|> (guard licenseFileExists >> Just "LICENSE")
+      , packageLicenseFile = fromMaybeList configLicenseFiles
       , packageTestedWith = packageConfigTestedWith
       , packageFlags = flags
       , packageExtraSourceFiles = extraSourceFiles
@@ -586,10 +604,11 @@
         ++ flagWarnings
         ++ maybe [] (formatUnknownFields "custom-setup section") (captureUnknownFieldsFields <$> packageConfigCustomSetup)
         ++ maybe [] (formatUnknownFields "library section") (captureUnknownFieldsFields <$> packageConfigLibrary)
-        ++ formatUnknownSectionFields "executable" executableSections
-        ++ formatUnknownSectionFields "test" testsSections
+        ++ formatUnknownSectionFields True "test" testsSections
+        ++ formatUnknownSectionFields True "benchmark" benchmarkSections
         ++ formatMissingSourceDirs missingSourceDirs
         ++ libraryWarnings
+        ++ executableWarnings
         ++ executablesWarnings
         ++ testsWarnings
         ++ benchmarksWarnings
@@ -598,9 +617,16 @@
 
   return (warnings, pkg)
   where
-    executableSections :: [(String, CaptureUnknownFields (Section ExecutableSection))]
-    executableSections = toList packageConfigExecutables
+    nameWarnings :: [String]
+    packageName_ :: String
+    (nameWarnings, packageName_) = case packageConfigName of
+      Nothing -> let inferredName = takeBaseName dir in
+        (["Package name not specified, inferred " ++ show inferredName], inferredName)
+      Just n -> ([], n)
 
+    mCustomSetup :: Maybe CustomSetup
+    mCustomSetup = toCustomSetup <$> mCustomSetupSection
+
     testsSections :: [(String, CaptureUnknownFields (Section ExecutableSection))]
     testsSections = toList packageConfigTests
 
@@ -630,11 +656,13 @@
       where
         f field = "Ignoring unknown field " ++ show field ++ " in " ++ name
 
-    formatUnknownSectionFields :: String -> [(String, CaptureUnknownFields a)] -> [String]
-    formatUnknownSectionFields sectionType = concatMap f . map (fmap captureUnknownFieldsFields)
+    formatUnknownSectionFields :: Bool -> String -> [(String, CaptureUnknownFields a)] -> [String]
+    formatUnknownSectionFields showSect sectionType = concatMap f . map (fmap captureUnknownFieldsFields)
       where
         f :: (String, [String]) -> [String]
-        f (sect, fields) = formatUnknownFields (sectionType ++ " section " ++ show sect) fields
+        f (sect, fields) = formatUnknownFields
+          (sectionType ++ " section" ++ if showSect then " " ++ show sect else "")
+          fields
 
     formatMissingSourceDirs = map f
       where
@@ -671,12 +699,23 @@
   (warnings, files) <- expandGlobs "c-sources" dir sectionCSources
   return (warnings, sect {sectionCSources = files})
 
+expandJsSources :: FilePath -> Section a -> IO ([String], Section a)
+expandJsSources dir sect@Section{..} = do
+  (warnings, files) <- expandGlobs "js-sources" dir sectionJsSources
+  return (warnings, sect {sectionJsSources = files})
+
+expandForeignSources :: FilePath -> Section a -> IO ([String], Section a)
+expandForeignSources dir sect = do
+  (cWarnings, sect_) <- expandCSources dir sect
+  (jsWarnings, sect__) <- expandJsSources dir sect_
+  return (cWarnings ++ jsWarnings, sect__)
+
 toCustomSetup :: CustomSetupSection -> CustomSetup
 toCustomSetup CustomSetupSection{..} = CustomSetup
   { customSetupDependencies = fromMaybeList customSetupSectionDependencies }
 
 toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO ([String], Section Library)
-toLibrary dir name globalOptions library = traverse fromLibrarySection sect >>= expandCSources dir
+toLibrary dir name globalOptions library = traverse fromLibrarySection sect >>= expandForeignSources dir
   where
     sect :: Section LibrarySection
     sect = mergeSections globalOptions library
@@ -693,7 +732,7 @@
 
 toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO ([String], [Section Executable])
 toExecutables dir globalOptions executables = do
-  result <- mapM toExecutable sections >>= mapM (expandCSources dir)
+  result <- mapM toExecutable sections >>= mapM (expandForeignSources dir)
   let (warnings, xs) = unzip result
   return (concat warnings, xs)
   where
@@ -724,9 +763,11 @@
   , sectionOtherExtensions = sectionOtherExtensions globalOptions ++ sectionOtherExtensions options
   , sectionGhcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options
   , sectionGhcProfOptions = sectionGhcProfOptions globalOptions ++ sectionGhcProfOptions options
+  , sectionGhcjsOptions = sectionGhcjsOptions globalOptions ++ sectionGhcjsOptions options
   , sectionCppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options
   , sectionCcOptions = sectionCcOptions globalOptions ++ sectionCcOptions options
   , sectionCSources = sectionCSources globalOptions ++ sectionCSources options
+  , sectionJsSources = sectionJsSources globalOptions ++ sectionJsSources options
   , sectionExtraLibDirs = sectionExtraLibDirs globalOptions ++ sectionExtraLibDirs options
   , sectionExtraLibraries = sectionExtraLibraries globalOptions ++ sectionExtraLibraries options
   , sectionIncludeDirs = sectionIncludeDirs globalOptions ++ sectionIncludeDirs options
@@ -748,9 +789,11 @@
       , sectionOtherExtensions = fromMaybeList commonOptionsOtherExtensions
       , sectionGhcOptions = fromMaybeList commonOptionsGhcOptions
       , sectionGhcProfOptions = fromMaybeList commonOptionsGhcProfOptions
+      , sectionGhcjsOptions = fromMaybeList commonOptionsGhcjsOptions
       , sectionCppOptions = fromMaybeList commonOptionsCppOptions
       , sectionCcOptions = fromMaybeList commonOptionsCcOptions
       , sectionCSources = fromMaybeList commonOptionsCSources
+      , sectionJsSources = fromMaybeList commonOptionsJsSources
       , sectionExtraLibDirs = fromMaybeList commonOptionsExtraLibDirs
       , sectionExtraLibraries = fromMaybeList commonOptionsExtraLibraries
       , sectionIncludeDirs = fromMaybeList commonOptionsIncludeDirs
@@ -779,12 +822,12 @@
 
 determineModules :: String -> [String] -> Maybe (List String) -> Maybe (List String) -> ([String], [String])
 determineModules name modules mExposedModules mOtherModules = case (mExposedModules, mOtherModules) of
-  (Nothing, Nothing) -> (modules, [])
+  (Nothing, Nothing) -> (modules, [pathsModuleFromPackageName name])
   _ -> (exposedModules, otherModules)
-  where
-    otherModules   = maybe ((modules \\ exposedModules) ++ pathsModule) fromList mOtherModules
-    exposedModules = maybe (modules \\ otherModules)   fromList mExposedModules
-    pathsModule = [pathsModuleFromPackageName name] \\ exposedModules
+    where
+      otherModules   = maybe ((modules \\ exposedModules) ++ pathsModule) fromList mOtherModules
+      exposedModules = maybe (modules \\ otherModules)   fromList mExposedModules
+      pathsModule = [pathsModuleFromPackageName name] \\ exposedModules
 
 getModules :: FilePath -> FilePath -> IO [String]
 getModules dir src_ = sort <$> do
diff --git a/src/Hpack/Run.hs b/src/Hpack/Run.hs
--- a/src/Hpack/Run.hs
+++ b/src/Hpack/Run.hs
@@ -34,9 +34,10 @@
 import           Hpack.Render
 import           Hpack.FormattingHints
 
-run :: FilePath -> IO ([String], FilePath, String)
-run dir = do
-  mPackage <- readPackageConfig (dir </> packageConfig)
+run :: Maybe FilePath -> FilePath -> IO ([String], FilePath, String)
+run mDir c = do
+  let dir = fromMaybe "" mDir
+  mPackage <- readPackageConfig (dir </> c)
   case mPackage of
     Right (warnings, pkg) -> do
       let cabalFile = dir </> (packageName pkg ++ ".cabal")
@@ -105,7 +106,9 @@
       , ("maintainer", formatList packageMaintainer)
       , ("copyright", formatList packageCopyright)
       , ("license", packageLicense)
-      , ("license-file", packageLicenseFile)
+      , case packageLicenseFile of
+          [file] -> ("license-file", Just file)
+          files  -> ("license-files", formatList files)
       , ("tested-with", packageTestedWith)
       , ("build-type", Just (show packageBuildType))
       , ("cabal-version", cabalVersion)
@@ -219,11 +222,13 @@
   , renderOtherExtensions sectionOtherExtensions
   , renderGhcOptions sectionGhcOptions
   , renderGhcProfOptions sectionGhcProfOptions
+  , renderGhcjsOptions sectionGhcjsOptions
   , renderCppOptions sectionCppOptions
   , renderCcOptions sectionCcOptions
   , renderDirectories "include-dirs" sectionIncludeDirs
   , Field "install-includes" (LineSeparatedList sectionInstallIncludes)
   , Field "c-sources" (LineSeparatedList sectionCSources)
+  , Field "js-sources" (LineSeparatedList sectionJsSources)
   , renderDirectories "extra-lib-dirs" sectionExtraLibDirs
   , Field "extra-libraries" (LineSeparatedList sectionExtraLibraries)
   , renderLdOptions sectionLdOptions
@@ -268,6 +273,9 @@
 
 renderGhcProfOptions :: [GhcProfOption] -> Element
 renderGhcProfOptions = Field "ghc-prof-options" . WordList
+
+renderGhcjsOptions :: [GhcjsOption] -> Element
+renderGhcjsOptions = Field "ghcjs-options" . WordList
 
 renderCppOptions :: [CppOption] -> Element
 renderCppOptions = Field "cpp-options" . WordList
diff --git a/src/Hpack/Util.hs b/src/Hpack/Util.hs
--- a/src/Hpack/Util.hs
+++ b/src/Hpack/Util.hs
@@ -3,6 +3,7 @@
   List(..)
 , GhcOption
 , GhcProfOption
+, GhcjsOption
 , CppOption
 , CcOption
 , LdOption
@@ -54,6 +55,7 @@
 
 type GhcOption = String
 type GhcProfOption = String
+type GhcjsOption = String
 type CppOption = String
 type CcOption = String
 type LdOption = String
diff --git a/test/Hpack/ConfigSpec.hs b/test/Hpack/ConfigSpec.hs
--- a/test/Hpack/ConfigSpec.hs
+++ b/test/Hpack/ConfigSpec.hs
@@ -6,7 +6,6 @@
 
 , package
 , executable
-, library
 ) where
 
 import           Helper
@@ -30,7 +29,7 @@
 executable name main_ = Executable name main_ []
 
 library :: Library
-library = Library Nothing [] [] []
+library = Library Nothing [] ["Paths_foo"] []
 
 withPackage :: String -> IO () -> (([String], Package) -> Expectation) -> Expectation
 withPackage content beforeAction expectation = withTempDirectory $ \dir_ -> do
@@ -117,6 +116,15 @@
         captureUnknownFieldsValue <$> decodeEither input
           `shouldBe` Right (section Empty){sectionCSources = ["foo.c", "bar/*.c"]}
 
+      it "accepts js-sources" $ do
+        let input = [i|
+              js-sources:
+                - foo.js
+                - bar/*.js
+              |]
+        captureUnknownFieldsValue <$> decodeEither input
+          `shouldBe` Right (section Empty){sectionJsSources = ["foo.js", "bar/*.js"]}
+
       it "accepts extra-lib-dirs" $ do
         let input = [i|
               extra-lib-dirs:
@@ -296,6 +304,9 @@
     it "adds the Paths_* module to the other-modules" $ do
       determineModules "foo" [] (Just $ List ["Foo"]) Nothing `shouldBe` (["Foo"], ["Paths_foo"])
 
+    it "adds the Paths_* module to the other-modules when no modules are specified" $ do
+      determineModules "foo" [] Nothing Nothing `shouldBe` ([], ["Paths_foo"])
+
     it "replaces dashes with underscores in Paths_*" $ do
       determineModules "foo-bar" [] (Just $ List ["Foo"]) Nothing `shouldBe` (["Foo"], ["Paths_foo_bar"])
 
@@ -470,14 +481,20 @@
         (do
         touch "LICENSE"
         )
-        (packageLicenseFile >>> (`shouldBe` Just "LICENSE"))
+        (packageLicenseFile >>> (`shouldBe` ["LICENSE"]))
 
     it "accepts license file" $ do
       withPackageConfig_ [i|
         license-file: FOO
         |]
-        (packageLicenseFile >>> (`shouldBe` Just "FOO"))
+        (packageLicenseFile >>> (`shouldBe` ["FOO"]))
 
+    it "accepts list of license files" $ do
+      withPackageConfig_ [i|
+        license-file: [FOO, BAR]
+        |]
+        (packageLicenseFile >>> (`shouldBe` ["FOO", "BAR"]))
+
     it "accepts build-type: Simple" $ do
       withPackageConfig_ [i|
         build-type: Simple
@@ -619,6 +636,30 @@
         }
         )
 
+    it "accepts ghcjs-options" $ do
+      withPackageConfig_ [i|
+        ghcjs-options: -dedupe
+        library:
+          ghcjs-options: -ghcjs1
+
+        executables:
+          foo:
+            main: Main.hs
+            ghcjs-options: -ghcjs2
+
+
+        tests:
+          spec:
+            main: Spec.hs
+            ghcjs-options: -ghcjs3
+        |]
+        (`shouldBe` package {
+          packageLibrary = Just (section library) {sectionGhcjsOptions = ["-dedupe", "-ghcjs1"]}
+        , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionGhcjsOptions = ["-dedupe", "-ghcjs2"]}]
+        , packageTests = [(section $ executable "spec" "Spec.hs") {sectionGhcjsOptions = ["-dedupe", "-ghcjs3"]}]
+        }
+        )
+
     it "accepts ld-options" $ do
       withPackageConfig_ [i|
         library:
@@ -787,6 +828,30 @@
           )
           (packageLibrary >>> (`shouldBe` Just (section library) {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}))
 
+      it "accepts js-sources" $ do
+        withPackageConfig [i|
+          library:
+            js-sources:
+              - jsbits/*.js
+          |]
+          (do
+          touch "jsbits/foo.js"
+          touch "jsbits/bar.js"
+          )
+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}))
+
+      it "accepts global js-sources" $ do
+        withPackageConfig [i|
+          js-sources:
+            - jsbits/*.js
+          library: {}
+          |]
+          (do
+          touch "jsbits/foo.js"
+          touch "jsbits/bar.js"
+          )
+          (packageLibrary >>> (`shouldBe` Just (section library) {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}))
+
       it "allows to specify exposed" $ do
         withPackageConfig_ [i|
           library:
@@ -865,7 +930,7 @@
           ]
           )
 
-      it "reads executable section" $ do
+      it "reads executables section" $ do
         withPackageConfig_ [i|
           executables:
             foo:
@@ -873,6 +938,44 @@
           |]
           (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main.hs"]))
 
+      it "reads executable section" $ do
+        withPackageConfig_ [i|
+          executable:
+            main: driver/Main.hs
+          |]
+          (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main.hs"]))
+
+      it "warns on unknown executable fields" $ do
+        withPackageWarnings_ [i|
+          name: foo
+          executable:
+            main: Main.hs
+            unknown: true
+          |]
+          (`shouldBe` ["Ignoring unknown field \"unknown\" in executable section"])
+
+      context "with both executable and executables" $ do
+        it "gives executable precedence" $ do
+          withPackageConfig_ [i|
+            executable:
+              main: driver/Main1.hs
+            executables:
+              foo2:
+                main: driver/Main2.hs
+            |]
+            (packageExecutables >>> (`shouldBe` [section $ executable "foo" "driver/Main1.hs"]))
+
+        it "warns" $ do
+          withPackageWarnings_ [i|
+            name: foo
+            executable:
+              main: driver/Main1.hs
+            executables:
+              foo2:
+                main: driver/Main2.hs
+            |]
+            (`shouldBe` ["Ignoring field \"executables\" in favor of \"executable\""])
+
       it "accepts arbitrary entry points as main" $ do
         withPackageConfig_ [i|
           executables:
@@ -1040,6 +1143,50 @@
           touch "cbits/bar.c"
           )
           (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionCSources = ["cbits/bar.c", "cbits/foo.c"]}]})
+
+      it "accepts js-sources" $ do
+        withPackageConfig [i|
+          executables:
+            foo:
+              main: driver/Main.hs
+              js-sources:
+                - jsbits/*.js
+          |]
+          (do
+          touch "jsbits/foo.js"
+          touch "jsbits/bar.js"
+          )
+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}]})
+
+      it "accepts global js-sources" $ do
+        withPackageConfig [i|
+          js-sources:
+            - jsbits/*.js
+          executables:
+            foo:
+              main: driver/Main.hs
+          |]
+          (do
+          touch "jsbits/foo.js"
+          touch "jsbits/bar.js"
+          )
+          (`shouldBe` package {packageExecutables = [(section $ executable "foo" "driver/Main.hs") {sectionJsSources = ["jsbits/bar.js", "jsbits/foo.js"]}]})
+
+    context "when reading benchmark section" $ do
+      it "warns on unknown fields" $ do
+        withPackageWarnings_ [i|
+          name: foo
+          benchmarks:
+            foo:
+              main: Main.hs
+              bar: 42
+              baz: 23
+          |]
+          (`shouldBe` [
+            "Ignoring unknown field \"bar\" in benchmark section \"foo\""
+          , "Ignoring unknown field \"baz\" in benchmark section \"foo\""
+          ]
+          )
 
     context "when reading test section" $ do
       it "warns on unknown fields" $ do
diff --git a/test/Hpack/RunSpec.hs b/test/Hpack/RunSpec.hs
--- a/test/Hpack/RunSpec.hs
+++ b/test/Hpack/RunSpec.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Hpack.RunSpec (spec) where
 
-import           Test.Hspec
+import           Helper
 import           Data.List.Compat
 
 import           Hpack.ConfigSpec hiding (spec)
@@ -9,6 +9,9 @@
 import           Hpack.Render
 import           Hpack.Run
 
+library :: Library
+library = Library Nothing [] [] []
+
 spec :: Spec
 spec = do
   describe "renderPackage" $ do
@@ -60,6 +63,25 @@
         , "cabal-version: >= 1.10"
         ]
 
+    it "includes license-file" $ do
+      renderPackage_ package {packageLicenseFile = ["FOO"]} `shouldBe` unlines [
+          "name: foo"
+        , "version: 0.0.0"
+        , "license-file: FOO"
+        , "build-type: Simple"
+        , "cabal-version: >= 1.10"
+        ]
+
+    it "aligns license-files" $ do
+      renderPackage defaultRenderSettings 16 [] [] package {packageLicenseFile = ["FOO", "BAR"]} `shouldBe` unlines [
+          "name:           foo"
+        , "version:        0.0.0"
+        , "license-files:  FOO,"
+        , "                BAR"
+        , "build-type:     Simple"
+        , "cabal-version:  >= 1.10"
+        ]
+
     it "includes copyright holder" $ do
       renderPackage_ package {packageCopyright = ["(c) 2015 Simon Hengel"]} `shouldBe` unlines [
           "name: foo"
@@ -244,6 +266,7 @@
           , "  ghc-prof-options: -fprof-auto -rtsopts"
           , "  default-language: Haskell2010"
           ]
+
   describe "renderConditional" $ do
     it "renders conditionals" $ do
       let conditional = Conditional "os(windows)" (section ()) {sectionDependencies = ["Win32"]} Nothing
diff --git a/test/HpackSpec.hs b/test/HpackSpec.hs
--- a/test/HpackSpec.hs
+++ b/test/HpackSpec.hs
@@ -1,5 +1,7 @@
 module HpackSpec (spec) where
 
+import           Helper
+
 import           Prelude ()
 import           Prelude.Compat
 
@@ -7,8 +9,6 @@
 import           Control.DeepSeq
 import           Data.Version (Version(..), showVersion)
 
-import           Test.Hspec
-import           Test.Mockery.Directory
 import           Test.QuickCheck
 
 import           Hpack
@@ -47,9 +47,9 @@
       it "does not write a new cabal file" $ do
         inTempDirectory $ do
           writeFile "package.yaml" "name: foo"
-          hpackWithVersion (makeVersion [0,8,0]) "." False
+          hpackWithVersion (makeVersion [0,8,0]) Nothing False
           old <- readFile "foo.cabal" >>= (return $!!)
-          hpackWithVersion (makeVersion [0,10,0]) "." False
+          hpackWithVersion (makeVersion [0,10,0]) Nothing False
           readFile "foo.cabal" `shouldReturn` old
 
     context "when exsting cabal file was generated with a newer version of hpack" $ do
@@ -59,7 +59,7 @@
               "name: foo"
             , "version: 0.1.0"
             ]
-          hpackWithVersion (makeVersion [0,10,0]) "." False
+          hpackWithVersion (makeVersion [0,10,0]) Nothing False
           old <- readFile "foo.cabal" >>= (return $!!)
 
           writeFile "package.yaml" $ unlines [
@@ -67,5 +67,43 @@
             , "version: 0.2.0"
             ]
 
-          hpackWithVersion (makeVersion [0,8,0]) "." False
+          hpackWithVersion (makeVersion [0,8,0]) Nothing False
           readFile "foo.cabal" `shouldReturn` old
+
+  describe "splitDirectory" $ do
+    context "when given Nothing" $ do
+      it "defaults file name to package.yaml" $ do
+        splitDirectory Nothing `shouldReturn` (Nothing, "package.yaml")
+
+    context "when given a directory" $ do
+      it "defaults file name to package.yaml" $ do
+        withTempDirectory $ \dir -> do
+          splitDirectory (Just dir) `shouldReturn` (Just dir, "package.yaml")
+
+    context "when given a file name" $ do
+      it "defaults directory to Nothing" $ do
+        inTempDirectory $ do
+          touch "foo.yaml"
+          splitDirectory (Just "foo.yaml") `shouldReturn` (Nothing, "foo.yaml")
+
+    context "when given a path to a file" $ do
+      it "splits directory from file name" $ do
+        withTempDirectory $ \dir -> do
+          let file = dir </> "foo.yaml"
+          touch file
+          splitDirectory (Just file) `shouldReturn` (Just dir, "foo.yaml")
+
+    context "when path does not exist" $ do
+      it "defaults directory to Nothing" $ do
+        inTempDirectory $ do
+          splitDirectory (Just "test/foo.yaml") `shouldReturn` (Just "test", "foo.yaml")
+
+    context "when file does not exist" $ do
+      it "defaults directory to Nothing" $ do
+        inTempDirectory $ do
+          splitDirectory (Just "test") `shouldReturn` (Nothing, "test")
+
+    context "when directory does not exist" $ do
+      it "defaults directory to Nothing" $ do
+        inTempDirectory $ do
+          splitDirectory (Just "test/") `shouldReturn` (Just "test", "package.yaml")
