packages feed

hsimport (empty) → 0.1

raw patch · 9 files changed

+307/−0 lines, 9 filesdep +attoparsecdep +basedep +cmdargssetup-changed

Dependencies added: attoparsec, base, cmdargs, directory, filepath, haskell-src-exts, lens, mtl, process, split, tasty, tasty-golden, text

Files

+ HsImport.hs view
@@ -0,0 +1,11 @@++module HsImport+   ( HsImportArgs+   , hsImportArgs+   , module HsImport.ImportSpec+   , module HsImport.Main+   ) where++import HsImport.Args+import HsImport.ImportSpec+import HsImport.Main
+ HsImport/Args.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE DeriveDataTypeable #-}++module HsImport.Args +   ( HsImportArgs(..)+   , hsImportArgs+   ) where++import System.Console.CmdArgs+++data HsImportArgs = HsImportArgs +   { moduleName    :: String+   , symbolName    :: String+   , inputSrcFile  :: FilePath+   , outputSrcFile :: FilePath+   } deriving (Data, Typeable, Show, Eq)+++hsImportArgs :: IO HsImportArgs+hsImportArgs = cmdArgs $ HsImportArgs +   { moduleName    = def &= help "The module to import"+   , symbolName    = def &= help "The symbol to import, if empty, the entire module is imported"+   , outputSrcFile = def &= help "Save modified source file to file, if empty, the source file is modified inplace" &= typFile+   , inputSrcFile  = def &= args &= typ "SOURCEFILE"+   }+   &= program "hsimport"+   &= summary summaryInfo+   &= help "A command line program for extending the import list of a Haskell source file."+   &= helpArg [explicit, name "help", name "h"]+   &= versionArg [explicit, name "version", name "v", summary versionInfo]+   where+      versionInfo = "hsimport version 0.1"+      summaryInfo = ""
+ HsImport/ImportSpec.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE TemplateHaskell, PatternGuards #-}++module HsImport.ImportSpec+   ( ImportSpec(..)+   , sourceFile+   , parsedSrcFile+   , moduleToImport+   , symbolToImport+   , saveToFile+   , hsImportSpec+   ) where++import Control.Lens+import qualified Language.Haskell.Exts as HS+import qualified HsImport.Args as Args+import HsImport.Args (HsImportArgs)++data ImportSpec = ImportSpec +   { _sourceFile     :: FilePath+   , _parsedSrcFile  :: HS.Module+   , _moduleToImport :: String+   , _symbolToImport :: Maybe String+   , _saveToFile     :: Maybe FilePath+   } deriving (Show)  ++makeLenses ''ImportSpec+++type Error = String+hsImportSpec :: HsImportArgs -> IO (Either Error ImportSpec)+hsImportSpec args+   | Just error <- checkArgs args = return $ Left error+   | otherwise = do+      result <- HS.parseFile $ Args.inputSrcFile args+      case result of+           HS.ParseOk modul -> return $ Right $+              ImportSpec (Args.inputSrcFile args) modul+                         (Args.moduleName args) symbolName saveToFile++           HS.ParseFailed _ error -> return $ Left error++   where+      symbolName =+         case Args.symbolName args of+              ""  -> Nothing+              sym -> Just sym++      saveToFile =+         case Args.outputSrcFile args of+              "" -> Nothing+              fp -> Just fp++      checkArgs args+         | null . Args.inputSrcFile $ args = Just "Missing source file!"+         | null . Args.moduleName $ args   = Just "Missing module name!"+         | otherwise                       = Nothing
+ HsImport/Main.hs view
@@ -0,0 +1,46 @@+{-# Language PatternGuards #-}++module HsImport.Main+   ( hsImport+   ) where++import Control.Lens+import System.Directory (copyFile)+import qualified Data.Text as T+import qualified Data.Text.IO as TIO+import qualified Language.Haskell.Exts as HS+import HsImport.ImportChange+import HsImport.ImportSpec+++hsImport :: ImportSpec -> IO ()+hsImport spec =+   case importChange (spec ^. moduleToImport) (spec ^. symbolToImport) (spec ^. parsedSrcFile) of+        ReplaceImport importDecl -> do+           let numDrops = HS.srcLine . HS.importLoc $ importDecl+               numTakes = max 0 (numDrops - 1)++           modifyImports importDecl (spec ^. sourceFile) (outputFile spec) numTakes numDrops++        AddImport importDecl -> do+           let numTakes = HS.srcLine . HS.importLoc $ importDecl+               numDrops = numTakes++           modifyImports importDecl (spec ^. sourceFile) (outputFile spec) numTakes numDrops++        NoImportChange+           | Just saveTo <- spec ^. saveToFile -> copyFile (spec ^. sourceFile) saveTo+           | otherwise                         -> return ()+   where+      modifyImports importDecl inputFile outputFile numTakes numDrops = do+         file <- TIO.readFile inputFile+         let importLine = HS.prettyPrint importDecl+             lines_     = lines . T.unpack $ file+             lines_'    = take numTakes lines_ ++ [importLine] ++ drop numDrops lines_+             file'      = T.pack . unlines $ lines_'++         TIO.writeFile outputFile file'++      outputFile spec+         | Just file <- spec ^. saveToFile = file+         | otherwise                       = spec ^. sourceFile
+ LICENSE view
@@ -0,0 +1,24 @@+Copyright (c) 2011, Daniel Trstenjak+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:+    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.+    * Redistributions in binary form must reproduce the above copyright+      notice, this list of conditions and the following disclaimer in the+      documentation and/or other materials provided with the distribution.+    * Neither the name of the <organization> nor the+      names of its contributors may be used to endorse or promote products+      derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL DANIEL TRSTENJAK BE LIABLE FOR ANY+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Main.hs view
@@ -0,0 +1,13 @@++module Main where++import System.Exit (exitFailure, exitSuccess)+import HsImport++main :: IO ()+main = do+   args      <- hsImportArgs+   maybeSpec <- hsImportSpec args+   case maybeSpec of+        Left  error -> putStrLn ("hsimport: " ++ error) >> exitFailure+        Right spec  -> hsImport spec                    >> exitSuccess
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ hsimport.cabal view
@@ -0,0 +1,57 @@+Name:          hsimport+Version:       0.1+License:       BSD3+License-file:  LICENSE+Author:        Daniel Trstenjak+Maintainer:    daniel.trstenjak@gmail.com+Build-Type:    Simple+Category:      Utils+Cabal-Version: >=1.6+Synopsis:      A command line program for extending the import list of a Haskell source file.+Description:   A command line program for extending the import list of a Haskell source file.++source-repository head+  type:     git+  location: https://github.com/dan-t/hsimport++Executable hsimport+  Main-is:       Main.hs+  other-modules: HsImport+                 HsImport.Args+                 HsImport.ImportSpec+                 HsImport.Main+  ghc-options:   -W -funbox-strict-fields+  Build-Depends: base >= 3 && < 5,+                 cmdargs >= 0.10.5 && < 0.11,+                 haskell-src-exts >= 1.14.0 && < 1.15,+                 lens >= 3.9.2 && < 4.0,+                 mtl >= 2.1.2 && < 2.2,+                 text >= 0.11.3.1 && < 0.12,+                 split >= 0.2.2 && < 0.3,+                 attoparsec >= 0.10.4.0 && < 0.11,+                 directory >= 1.2.0.1 && < 1.3++library+  ghc-options:   -W -funbox-strict-fields+  exposed-modules: HsImport+                   HsImport.Args+                   HsImport.ImportSpec+                   HsImport.Main+  Build-Depends: base >= 3 && < 5,+                 cmdargs >= 0.10.5 && < 0.11,+                 haskell-src-exts >= 1.14.0 && < 1.15,+                 lens >= 3.9.2 && < 4.0,+                 mtl >= 2.1.2 && < 2.2,+                 text >= 0.11.3.1 && < 0.12,+                 split >= 0.2.2 && < 0.3,+                 attoparsec >= 0.10.4.0 && < 0.11,+                 directory >= 1.2.0.1 && < 1.3++Executable hsimport-tests+  Main-is:       tests/Main.hs+  ghc-options:   -W -funbox-strict-fields+  Build-Depends: base >= 3 && < 5,+                 tasty >= 0.6 && < 0.7,+                 tasty-golden >= 2.2.0.1 && < 2.3,+                 filepath >= 1.3.0.1 && < 1.4,+                 process >= 1.1.0.2 && < 1.2
+ tests/Main.hs view
@@ -0,0 +1,65 @@++module Main where++import Test.Tasty+import Test.Tasty.Golden+import System.Process+import System.FilePath+import Data.List (intercalate)++main = defaultMain tests++tests :: TestTree+tests = testGroup "Tests" [moduleTests, symbolTests]++moduleTests :: TestTree+moduleTests = testGroup "Module Tests"+   [ hsImportTest "ModuleTest1" "Foo.Bar" ""+   , hsImportTest "ModuleTest2" "Foo.Bar.Blub" ""+   , hsImportTest "ModuleTest3" "Control.Monad" ""+   , hsImportTest "ModuleTest4" "Ugah.Argh2" ""+   , hsImportTest "ModuleTest5" "Control.Monad" ""+   , hsImportTest "ModuleTest6" "Control.Monad" ""+   , hsImportTest "ModuleTest7" "Control.Monad" ""+   , hsImportTest "ModuleTest8" "Control.Monad" ""+   , hsImportTest "ModuleTest9" "Control.Monad" ""+   ]+++symbolTests :: TestTree+symbolTests = testGroup "Symbol Tests"+   [ hsImportTest "SymbolTest1" "Foo.Bar" "foo"+   , hsImportTest "SymbolTest2" "Foo.Bar.Blub" "foo"+   , hsImportTest "SymbolTest3" "Control.Monad" "when"+   , hsImportTest "SymbolTest4" "Ugah.Argh2" "argh"+   , hsImportTest "SymbolTest5" "Control.Monad" "when"+   , hsImportTest "SymbolTest6" "Control.Monad" "unless"+   , hsImportTest "SymbolTest7" "Control.Monad" "unless"+   , hsImportTest "SymbolTest8" "Control.Monad" "unless"+   , hsImportTest "SymbolTest9" "Control.Monad" "unless"+   , hsImportTest "SymbolTest10" "Control.Applicative" "<$>"+   , hsImportTest "SymbolTest11" "Control.Applicative" "<$>"+   , hsImportTest "SymbolTest12" "Control.Applicative" "<$>"+   , hsImportTest "SymbolTest13" "Control.Applicative" "<*"+   , hsImportTest "SymbolTest14" "Control.Applicative" "<*"+   , hsImportTest "SymbolTest15" "Control.Applicative" "*>"+   ]+++hsImportTest :: String -> String -> String -> TestTree+hsImportTest testName moduleName symbolName =+   goldenVsFile testName goldenFile outputFile command+   where+      command = do+        handle <- runCommand $ "hsimport " ++ params+        waitForProcess handle+        return ()++      params      = intercalate " " [moduleParam, symbolParam, outputParam, inputFile]+      moduleParam = "-m '" ++ moduleName ++ "'"+      symbolParam = if null symbolName then "" else "-s '" ++ symbolName ++ "'"+      outputParam = "-o '" ++ outputFile ++ "'"++      goldenFile = "tests" </> "goldenFiles" </> testName <.> "hs"+      outputFile = "tests" </> "outputFiles" </> testName <.> "hs"+      inputFile  = "tests" </> "inputFiles"  </> testName <.> "hs"