diff --git a/cabalize.cabal b/cabalize.cabal index 21a3caf..fc0f7e7 100644 --- a/cabalize.cabal +++ b/cabalize.cabal @@ -15,7 +15,6 @@ library aeson , base == 4.* , base-compat - , base-compat , directory , filepath , interpolate @@ -41,7 +40,6 @@ test-suite spec aeson , base == 4.* , base-compat - , base-compat , directory , filepath , hspec == 2.* diff --git a/package.yaml b/package.yaml index d91afb3..58bc618 100644 --- a/package.yaml +++ b/package.yaml @@ -1,6 +1,7 @@ name: cabalize dependencies: + - aeson - base == 4.* - base-compat - directory @@ -14,3 +15,4 @@ tests: main: test/Spec.hs dependencies: - hspec == 2.* + - temporary diff --git a/src/Config.hs b/src/Config.hs index 605fce6..8e6cb47 100644 --- a/src/Config.hs +++ b/src/Config.hs @@ -20,7 +20,7 @@ import Util data TestSection = TestSection { testSectionMain :: FilePath -, testSectionDependencies :: Maybe [String] +, testSectionDependencies :: Maybe (List Dependency) } deriving (Eq, Show, Generic) instance FromJSON TestSection where @@ -28,8 +28,8 @@ instance FromJSON TestSection where data ConfigFile = ConfigFile { configFileName :: String -, configFileDependencies :: [String] -, configFileTests :: HashMap String TestSection +, configFileDependencies :: Maybe [Dependency] +, configFileTests :: Maybe (HashMap String TestSection) } deriving (Eq, Show, Generic) instance FromJSON ConfigFile where @@ -64,12 +64,13 @@ data Test = Test { mkPackage :: ConfigFile -> IO Package mkPackage ConfigFile{..} = do - library <- mkLibrary configFileDependencies + let dependencies = fromMaybe [] configFileDependencies + library <- mkLibrary dependencies let package = Package { packageName = configFileName , packageVersion = [0,0,0] , packageLibrary = library - , packageTests = (map (uncurry $ testConfigToTest configFileDependencies) . Map.toList) configFileTests + , packageTests = (map (uncurry $ testConfigToTest dependencies) . Map.toList) (fromMaybe mempty configFileTests) } return package @@ -87,4 +88,4 @@ getModules src = do toModules = catMaybes . map toModule testConfigToTest :: [Dependency] -> String -> TestSection -> Test -testConfigToTest dependencies name t = Test name (testSectionMain t) (dependencies ++ fromMaybe [] (testSectionDependencies t)) +testConfigToTest dependencies name t = Test name (testSectionMain t) (dependencies ++ maybe [] fromList (testSectionDependencies t)) diff --git a/src/Util.hs b/src/Util.hs index 5484c40..de57176 100644 --- a/src/Util.hs +++ b/src/Util.hs @@ -13,6 +13,12 @@ import Data.Aeson.Types genericParseJSON_ :: (Generic a, GFromJSON (Rep a)) => String -> Value -> Parser a genericParseJSON_ name = genericParseJSON defaultOptions {fieldLabelModifier = camelTo '_' . drop (length name)} +newtype List a = List {fromList :: [a]} + deriving (Eq, Show) + +instance FromJSON a => FromJSON (List a) where + parseJSON v = List <$> (parseJSON v <|> (return <$> parseJSON v)) + toModule :: FilePath -> Maybe String toModule = fmap (map f . reverse) . stripPrefix (reverse ".hs") . reverse where diff --git a/test/CabalizeSpec.hs b/test/CabalizeSpec.hs deleted file mode 100644 index 0acc42a..0000000 --- a/test/CabalizeSpec.hs +++ /dev/null @@ -1,54 +0,0 @@ -{-# LANGUAGE QuasiQuotes #-} -module CabalizeSpec (main, spec) where - -import Test.Hspec -import Data.String.Interpolate -import Data.String.Interpolate.Util - -import Cabalize - -main :: IO () -main = hspec spec - -spec :: Spec -spec = do - describe "cabalize" $ do - it "creates cabal file" $ do - cabalize `shouldReturn` ("cabalize.cabal", unindent [i| - -- This file has been generated from package.yaml by Cabalize. - name: cabalize - version: 0.0.0 - build-type: Simple - cabal-version: >= 1.10 - - library - hs-source-dirs: src - exposed-modules: - Cabalize - Config - Util - build-depends: - base == 4.* - , base-compat - , directory - , filepath - , interpolate - , unordered-containers - , yaml - default-language: Haskell2010 - - test-suite spec - type: exitcode-stdio-1.0 - hs-source-dirs: test - main-is: Spec.hs - build-depends: - base == 4.* - , base-compat - , directory - , filepath - , hspec == 2.* - , interpolate - , unordered-containers - , yaml - default-language: Haskell2010 - |]) diff --git a/test/ConfigSpec.hs b/test/ConfigSpec.hs index 4f34513..1eed319 100644 --- a/test/ConfigSpec.hs +++ b/test/ConfigSpec.hs @@ -19,11 +19,51 @@ spec = around_ inTempDirectory $ do it "reads package config" $ do writeFile "package.yaml" [i| name: foo - dependencies: - - base - - tests: - spec: - main: test/Spec.hs |] - readConfig "package.yaml" `shouldReturn` Just (package "foo") {packageTests = [Test "spec" "test/Spec.hs" ["base"]], packageLibrary = Library [] ["base"]} + readConfig "package.yaml" `shouldReturn` Just (package "foo") + + context "when reading test section" $ do + it "reads test section" $ do + writeFile "package.yaml" [i| + name: foo + tests: + spec: + main: test/Spec.hs + |] + readConfig "package.yaml" `shouldReturn` Just (package "foo") {packageTests = [Test "spec" "test/Spec.hs" []]} + + it "accepts single dependency" $ do + writeFile "package.yaml" [i| + name: foo + tests: + spec: + main: test/Spec.hs + dependencies: hspec + |] + readConfig "package.yaml" `shouldReturn` Just (package "foo") {packageTests = [Test "spec" "test/Spec.hs" ["hspec"]]} + + it "accepts list of dependencies" $ do + writeFile "package.yaml" [i| + name: foo + tests: + spec: + main: test/Spec.hs + dependencies: + - hspec + - QuickCheck + |] + readConfig "package.yaml" `shouldReturn` Just (package "foo") {packageTests = [Test "spec" "test/Spec.hs" ["hspec", "QuickCheck"]]} + + context "when both top-level and section specific dependencies are specified" $ do + it "combines dependencies" $ do + writeFile "package.yaml" [i| + name: foo + dependencies: + - base + + tests: + spec: + main: test/Spec.hs + dependencies: hspec + |] + readConfig "package.yaml" `shouldReturn` Just (package "foo") {packageTests = [Test "spec" "test/Spec.hs" ["base", "hspec"]], packageLibrary = Library [] ["base"]} diff --git a/test/UtilSpec.hs b/test/UtilSpec.hs index 4c30c43..618c9e4 100644 --- a/test/UtilSpec.hs +++ b/test/UtilSpec.hs @@ -1,6 +1,8 @@ +{-# LANGUAGE OverloadedStrings #-} module UtilSpec (main, spec) where import Test.Hspec +import Data.Aeson import Util @@ -12,3 +14,10 @@ spec = do describe "toModule" $ do it "maps a path to a module name" $ do toModule "Foo/Bar/Baz.hs" `shouldBe` Just "Foo.Bar.Baz" + + describe "List" $ do + it "can be a single value" $ do + fromJSON (toJSON $ Number 23) `shouldBe` Success (List [23 :: Int]) + + it "can be a list of values" $ do + fromJSON (toJSON [Number 23, Number 42]) `shouldBe` Success (List [23, 42 :: Int])