packages feed

autoexporter 0.2.3 → 1.0.0

raw patch · 13 files changed

+186/−159 lines, 13 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Autoexporter: autoexport :: String -> FilePath -> FilePath -> IO ()
+ Autoexporter: isHaskellFile :: FilePath -> Bool
+ Autoexporter: isModuleName :: String -> Bool
+ Autoexporter: mainWithArgs :: [String] -> IO ()
+ Autoexporter: makeModuleName :: FilePath -> String
+ Autoexporter: makeOutput :: String -> FilePath -> [FilePath] -> String
+ Autoexporter: parseModuleName :: String -> Maybe ModuleName
+ Autoexporter: renderExport :: String -> String
+ Autoexporter: renderImport :: String -> String
+ Autoexporter: renderModule :: String -> [String] -> String
+ Autoexporter: takeWhileEnd :: (a -> Bool) -> [a] -> [a]
+ Autoexporter: unlines' :: [String] -> String

Files

+ CHANGELOG.markdown view
@@ -0,0 +1,7 @@+# Change log++Autoexporter uses [Semantic Versioning][].+The change log is available through the [releases on GitHub][].++[Semantic Versioning]: http://semver.org/spec/v2.0.0.html+[releases on GitHub]: https://github.com/tfausak/autoexporter/releases
− CHANGELOG.md
@@ -1,7 +0,0 @@-# Change log--Autoexporter uses [Semantic Versioning][].-The change log is available through the [releases on GitHub][].--[Semantic Versioning]: http://semver.org/spec/v2.0.0.html-[releases on GitHub]: https://github.com/tfausak/autoexporter/releases
+ LICENSE.markdown view
@@ -0,0 +1,23 @@+[The MIT License (MIT)][]++Copyright (c) 2016 Taylor Fausak++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.++[The MIT License (MIT)]: https://opensource.org/licenses/MIT
− LICENSE.md
@@ -1,23 +0,0 @@-[The MIT License (MIT)][]--Copyright (c) 2016 Taylor Fausak--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.--[The MIT License (MIT)]: https://opensource.org/licenses/MIT
+ README.markdown view
@@ -0,0 +1,66 @@+# [Autoexporter][]++[![Version badge][]][version]+[![Build badge][]][build]++Autoexporter automatically re-exports Haskell modules.++Let's say you have a module `M` that just exports some other modules. It might+look like this:++``` haskell+module M+  ( module M.A+  , module M.B+  ) where++import M.A+import M.B+```++This code is error-prone. If you add a new module, say `M.C`, you have to+remember to come back to this file and re-export it. And this code is tedious+to write. You have to list each module twice. You can do a little better, but+not much.++``` haskell+module M (module X) where+import M.A as X+import M.B as X+```++Now you don't have to write every module twice, but you still have to remember+to re-export everything. And the generated documentation for this module+doesn't include anything about the exported modules.++Autoexporter handles this for you. Instead of either of the above approaches,+simply drop this into the `M` module:++``` haskell+{-# OPTIONS_GHC -F -pgmF autoexporter #-}+```++That will generate code that looks like this:++``` haskell+module M (+  module M.A,+  module M.B,+) where+import M.A+import M.B+```++Autoexporter will generally behave as you'd expect, but there are a couple+things to look out for:++- Only immediate children will be re-exported. If you use this in some module+  `M`, it won't pull in `M.A.B`.++- You cannot selectively include or exclude any modules.++[Autoexporter]: https://github.com/tfausak/autoexporter+[Version badge]: https://www.stackage.org/package/autoexporter/badge/nightly?label=version+[version]: https://www.stackage.org/nightly/package/autoexporter+[Build badge]: https://travis-ci.org/tfausak/autoexporter.svg?branch=master+[build]: https://travis-ci.org/tfausak/autoexporter
− README.md
@@ -1,70 +0,0 @@-# [Autoexporter][]--Autoexporter automatically re-exports Haskell modules.--[![Version badge][]][version]-[![Build badge][]][build]---   [Install](#install)--   [Use](#use)--## Install--1.  Install [Stack][].--2.  `stack install autoexporter`--## Use--Let's say you have a module `M` that just exports some other modules. It might-look like this:--``` haskell-module M-    ( module M.A-    , module M.B-    ) where--import M.A-import M.B-```--This code is error-prone. If you add a new module, say `M.C`, you have to-remember to come back to this file and re-export it. And this code is tedious-to write. You have to list each module twice. You can do a little better, but-not much.--``` haskell-module M (module X) where-import M.A as X-import M.B as X-```--Now you don't have to write every module twice, but you still have to remember-to re-export everything. And the generated documentation for this module-doesn't include anything about the exported modules.--Autoexporter handles this for you. Instead of either of the above approaches,-simply drop this into the `M` module:--``` haskell-{-# OPTIONS_GHC -F -pgmF autoexporter #-}-```--That will generate code like the first example. A couple caveats:---   Only immediate children will be re-exported. If you use this in some module-    `M`, it won't pull in `M.A.B`.---   You cannot selectively leave out any modules. You also cannot selectively-    exclude any imports from any of the modules.--    -   This could be allowed via `-optF`. I will happily accept patches for-        this as well.--[Autoexporter]: https://github.com/tfausak/autoexporter-[Version badge]: https://www.stackage.org/package/autoexporter/badge/nightly?label=version-[version]: https://www.stackage.org/package/autoexporter-[Build badge]: https://travis-ci.org/tfausak/autoexporter.svg?branch=master-[build]: https://travis-ci.org/tfausak/autoexporter-[Stack]: http://haskellstack.org
autoexporter.cabal view
@@ -3,7 +3,7 @@ -- see: https://github.com/sol/hpack  name:           autoexporter-version:        0.2.3+version:        1.0.0 synopsis:       Automatically re-export modules. description:    Autoexporter automatically re-exports modules. category:       Utility@@ -11,14 +11,14 @@ bug-reports:    https://github.com/tfausak/autoexporter/issues maintainer:     Taylor Fausak license:        MIT+license-file:   LICENSE.markdown build-type:     Simple cabal-version:  >= 1.10  extra-source-files:-    CHANGELOG.md-    LICENSE.md+    CHANGELOG.markdown     package.yaml-    README.md+    README.markdown     stack.yaml  source-repository head@@ -27,7 +27,7 @@  library   hs-source-dirs:-      library+      source/library   ghc-options: -Wall   build-depends:       base >=4.7 && <4.10@@ -41,7 +41,7 @@ executable autoexporter   main-is: Main.hs   hs-source-dirs:-      executable+      source/executable   ghc-options: -Wall   build-depends:       base
− executable/Main.hs
@@ -1,3 +0,0 @@-module Main (module Autoexporter) where--import Autoexporter (main)
− library/Autoexporter.hs
@@ -1,41 +0,0 @@-module Autoexporter (main) where--import qualified Data.List as List-import qualified Data.Maybe as Maybe-import qualified Distribution.ModuleName as ModuleName-import qualified Distribution.Text as Text-import qualified System.Directory as Directory-import qualified System.Environment as Environment-import qualified System.FilePath as FilePath--main :: IO ()-main = do-    args <- Environment.getArgs-    case args of-        [name, inputFile, outputFile] -> do-            let moduleName = makeModuleName name--            let directory = FilePath.dropExtension inputFile-            files <- Directory.getDirectoryContents directory-            let haskellFiles = filter (\ f -> List.isSuffixOf ".hs" f || List.isSuffixOf ".lhs" f) files-            let paths = map (directory FilePath.</>) haskellFiles-            let modules = List.sort (map makeModuleName paths)-            let exports = init (unlines (map (\ x -> "    module " ++ x ++ ",") modules))-            let imports = init (unlines (map ("import " ++) modules))--            let output = unlines-                    [ unwords ["module", moduleName, "("]-                    , exports-                    , ") where"-                    , ""-                    , imports-                    ]-            writeFile outputFile output-        _ -> error ("unexpected arguments: " ++ show args)--makeModuleName :: FilePath -> String-makeModuleName name =-    let path = FilePath.dropExtension name-        parts = FilePath.splitDirectories path-        rest = reverse (takeWhile (\ x -> Maybe.isJust (Text.simpleParse x :: Maybe ModuleName.ModuleName)) (reverse parts))-    in  List.intercalate "." rest
package.yaml view
@@ -6,12 +6,11 @@     - base     - autoexporter     main: Main.hs-    source-dirs: executable+    source-dirs: source/executable extra-source-files:-- CHANGELOG.md-- LICENSE.md+- CHANGELOG.markdown - package.yaml-- README.md+- README.markdown - stack.yaml ghc-options: - -Wall@@ -22,9 +21,10 @@   - Cabal >=1.22 && <1.25   - directory >=1.2 && <1.4   - filepath >=1.3 && <1.5-  source-dirs: library+  source-dirs: source/library license: MIT+license-file: LICENSE.markdown maintainer: Taylor Fausak name: autoexporter synopsis: Automatically re-export modules.-version: '0.2.3'+version: '1.0.0'
+ source/executable/Main.hs view
@@ -0,0 +1,5 @@+module Main+  ( module Autoexporter+  ) where++import Autoexporter (main)
+ source/library/Autoexporter.hs view
@@ -0,0 +1,72 @@+module Autoexporter where++import qualified Data.List as List+import qualified Data.Maybe as Maybe+import qualified Distribution.ModuleName as ModuleName+import qualified Distribution.Text as Text+import qualified System.Directory as Directory+import qualified System.Environment as Environment+import qualified System.FilePath as FilePath++main :: IO ()+main = do+  args <- Environment.getArgs+  mainWithArgs args++mainWithArgs :: [String] -> IO ()+mainWithArgs args =+  case args of+    [name, inputFile, outputFile] -> autoexport name inputFile outputFile+    _ -> fail ("unexpected arguments: " ++ show args)++autoexport :: String -> FilePath -> FilePath -> IO ()+autoexport name inputFile outputFile = do+  let moduleName = makeModuleName name+  let directory = FilePath.dropExtension inputFile+  files <- Directory.getDirectoryContents directory+  let output = makeOutput moduleName directory files+  writeFile outputFile output++makeModuleName :: FilePath -> String+makeModuleName name =+  let path = FilePath.dropExtension name+      parts = FilePath.splitDirectories path+      rest = takeWhileEnd isModuleName parts+  in List.intercalate "." rest++takeWhileEnd :: (a -> Bool) -> [a] -> [a]+takeWhileEnd p xs = reverse (takeWhile p (reverse xs))++isModuleName :: String -> Bool+isModuleName x = Maybe.isJust (parseModuleName x)++parseModuleName :: String -> Maybe ModuleName.ModuleName+parseModuleName = Text.simpleParse++makeOutput :: String -> FilePath -> [FilePath] -> String+makeOutput moduleName directory files =+  let haskellFiles = filter isHaskellFile files+      paths = map (directory FilePath.</>) haskellFiles+      modules = List.sort (map makeModuleName paths)+  in renderModule moduleName modules++isHaskellFile :: FilePath -> Bool+isHaskellFile x = List.isSuffixOf ".hs" x || List.isSuffixOf ".lhs" x++renderModule :: String -> [String] -> String+renderModule name modules =+  unlines'+    [ unwords ["module", name, "("]+    , unlines' (map renderExport modules)+    , ") where"+    , unlines' (map renderImport modules)+    ]++unlines' :: [String] -> String+unlines' = List.intercalate "\n"++renderExport :: String -> String+renderExport x = "  module " ++ x ++ ","++renderImport :: String -> String+renderImport x = "import " ++ x
stack.yaml view
@@ -1,3 +1,1 @@-install-ghc: true-require-stack-version: ! '>=1.0.4'-resolver: lts-5.12+resolver: lts-7.14