haskdogs 0.4.2 → 0.4.4
raw patch · 3 files changed
+78/−37 lines, 3 filesdep +containers
Dependencies added: containers
Files
- README.md +34/−1
- haskdogs.cabal +3/−1
- src/Main.hs +41/−35
README.md view
@@ -39,7 +39,40 @@ $ haskdogs -Emacs users would probably want to add -e option to build Emacs-compatible TAGS.+Emacs users would probably want to add -e hasktags option to build Emacs-compatible TAGS.++++ $ haskdogs --help+ haskdogs - Recursive hasktags-based TAGS generator for a Haskell project++ Usage: haskdogs [--version] [-d|--dir-list FILE] [-f|--file-list FILE]+ [--hasktags-args OPTS] [--ghc-pkg-args OPTS] [--use-stack ARG]+ [OPTS]++ Available options:+ -h,--help Show this help text+ --version Show version number+ -d,--dir-list FILE File containing directory list to process+ -f,--file-list FILE File containing Haskell sources to process+ --hasktags-args OPTS Arguments to pass to hasktags. -c -x is the default+ --ghc-pkg-args OPTS Arguments to pass to ghc-pkgs+ --use-stack ARG Execute ghc-pkg via stack, arg is ON, OFF or AUTO+ (the default)+ OPTS More hasktags options, use `--' to pass flags+ starting with `-'+++The following error could be caused by (over)strict Haskell policy regarding+Unicode locale:++ haskdogs: fd:5: hGetContents: invalid argument (invalid byte sequence)++It usually happens when the program tries to print Unicode character to+non-unicode console. In order to overcome, try the following setting:++ export LANG=en_US.UTF8+ VIM HINT --------
haskdogs.cabal view
@@ -1,5 +1,5 @@ Name: haskdogs-Version: 0.4.2+Version: 0.4.4 Synopsis: Generate tags file for Haskell project and its nearest deps Homepage: http://github.com/grwlf/haskdogs License: BSD3@@ -30,6 +30,7 @@ Executable haskdogs Default-language: Haskell2010+ other-modules: Paths_haskdogs Hs-source-dirs: src Main-is: Main.hs Build-depends: base >= 4.8 && < 5@@ -39,6 +40,7 @@ , directory , optparse-applicative , process+ , containers Ghc-options: -fwarn-tabs
src/Main.hs view
@@ -11,9 +11,12 @@ import System.Process (readProcess) import System.FilePath +import Data.Set (Set)+import qualified Data.Set as Set import Options.Applicative import qualified Options.Applicative as O-import Data.Version+import Data.Version (showVersion)+import qualified Paths_haskdogs as Paths {- ___ _ _@@ -30,13 +33,15 @@ , cli_hasktags_args1 :: String , cli_ghc_pkgs_args :: String , cli_use_stack :: Tristate- , cli_use_sandbox :: Tristate+ -- , cli_use_sandbox :: Tristate , cli_hasktags_args2 :: [String] } deriving(Show) data Tristate = ON | OFF | AUTO deriving(Eq, Ord, Show, Read) +def_hasktags_args = words "-c -x"+ optsParser :: Parser Opts optsParser = Opts <$> strOption (@@ -54,8 +59,8 @@ <*> strOption ( long "hasktags-args" <> metavar "OPTS" <>- value "-c -x" <>- help "Arguments to pass to hasktags")+ value "" <>+ help ("Arguments to pass to hasktags. " ++ unwords def_hasktags_args ++ " is the default")) <*> strOption ( long "ghc-pkg-args" <> metavar "OPTS" <>@@ -64,22 +69,21 @@ <*> option auto ( long "use-stack" <> value AUTO <>- help "Execute ghc-pkg via stack")- <*> option auto (- long "include-sandbox" <>- value AUTO <>- help "(!UNIMPLEMENTED!) Include .cabal-sandbox package databases")- <*> many (argument str (metavar "OPTS" <> help "More hasktags options"))+ help "Execute ghc-pkg via stack, arg is ON, OFF or AUTO (the default)")+ -- <*> option auto (+ -- long "include-sandbox" <>+ -- value AUTO <>+ -- help "(!UNIMPLEMENTED!) Include .cabal-sandbox package databases")+ <*> many (argument str (metavar "OPTS" <> help "More hasktags options, use `--' to pass flags starting with `-'")) -exename, versionId :: String+exename :: String exename = "haskdogs"-versionId = "0.4.0" -version :: Parser (a -> a)-version = infoOption (exename ++ " version " ++ versionId)+versionParser :: Parser (a -> a)+versionParser = infoOption (exename ++ " version " ++ (showVersion Paths.version)) (long "version" <> help "Show version number") -opts = info (helper <*> version <*> optsParser)+opts = info (helper <*> versionParser <*> optsParser) ( fullDesc <> header (exename ++ " - Recursive hasktags-based TAGS generator for a Haskell project" )) {-@@ -113,7 +117,7 @@ eprint = hPutStrLn stderr runp nm args inp = do- vprint $ nm ++ " " ++ unwords args+ vprint $ "> " ++ nm ++ " " ++ unwords args readProcess nm args inp -- Run GNU which tool@@ -146,16 +150,16 @@ | null cli_dirlist_file = return [] | otherwise = readLinedFile cli_dirlist_file - readSourceFile :: IO [FilePath]+ readSourceFile :: IO (Set FilePath) readSourceFile- | null cli_filelist_file = return []- | otherwise = readLinedFile cli_filelist_file+ | null cli_filelist_file = return Set.empty+ | otherwise = Set.fromList <$> readLinedFile cli_filelist_file cli_hasktags_args = (words cli_hasktags_args1) ++ cli_hasktags_args2 runp_ghc_pkgs args = go cli_use_stack where- go ON = runp "stack" (["exec", "ghc-pkg", "--"] ++ args) []- go OFF = runp "ghc-pkg" args []+ go ON = runp "stack" (["exec", "ghc-pkg", "--"] ++ (words cli_ghc_pkgs_args) ++ args) []+ go OFF = runp "ghc-pkg" (words cli_ghc_pkgs_args ++ args) [] go AUTO = if has_stack then go ON else go OFF cabal_or_stack = go cli_use_stack where@@ -164,20 +168,21 @@ go AUTO = if has_stack then go ON else go OFF -- Finds *hs in dirs, but filter-out Setup.hs- findSources :: [FilePath] -> IO [FilePath]+ findSources :: [FilePath] -> IO (Set FilePath)+ findSources [] = return Set.empty findSources dirs =- filter (not . isSuffixOf "Setup.hs") . lines <$>+ Set.fromList . filter (not . isSuffixOf "Setup.hs") . lines <$> runp "find" (dirs ++ words "-type f -and ( -name *\\.hs -or -name *\\.lhs -or -name *\\.hsc )") [] grepImports :: String -> Maybe String grepImports line = case words line of- ("import":"qualified":x:_) -> Just x- ("import":x:_) -> Just x+ ("import":"qualified":x:_) -> Just (filter (/=';') x)+ ("import":x:_) -> Just (filter (/=';') x) _ -> Nothing -- Produces list of imported modules for file.hs given- findModules :: [FilePath] -> IO [String]- findModules files = (catMaybes . map grepImports . lines) <$> runp "cat" files []+ findModules :: Set FilePath -> IO [String]+ findModules files = (catMaybes . map grepImports . lines) <$> runp "cat" (Set.toList files) [] -- Maps import name to haskell package name iname2module :: String -> IO (Maybe String)@@ -191,18 +196,19 @@ -- Unapcks haskel package to the sourcedir unpackModule :: FilePath -> IO (Maybe FilePath)- unpackModule ((datadir</>) -> p) = do- exists <- doesDirectoryExist (datadir</>p)+ unpackModule mod = do+ let p = datadir</>mod+ exists <- doesDirectoryExist p case exists of True -> do- vprint $ "Already unpacked " ++ p+ vprint $ "Already unpacked " ++ mod return (Just p) False -> do bracket_ (setCurrentDirectory datadir) (setCurrentDirectory cwd) $- ( runp cabal_or_stack ["unpack", p] [] >> return (Just p)+ ( runp cabal_or_stack ["unpack", mod] [] >> return (Just p) ) `catch` (\(_ :: SomeException) ->- eprint ("Can't unpack " ++ p) >> return Nothing+ eprint ("Can't unpack " ++ mod) >> return Nothing ) unpackModules :: [FilePath] -> IO [FilePath]@@ -213,12 +219,12 @@ checkapp "hasktags" files <- do dirs <- readDirFile- ss_local <- (++) <$> readSourceFile <*> findSources dirs+ ss_local <- Set.union <$> readSourceFile <*> findSources dirs when (null ss_local) $ do fail $ "Haskdogs were not able to find any sources in " <> (intercalate ", " dirs) ss_l1deps <- findModules ss_local >>= inames2modules >>= unpackModules >>= findSources- return $ ss_local ++ ss_l1deps- runp "hasktags" (cli_hasktags_args ++ files) []+ return $ ss_local `mappend` ss_l1deps+ runp "hasktags" ((if null cli_hasktags_args then def_hasktags_args else cli_hasktags_args) ++ Set.toList files) [] putStrLn "\nSuccess" {- _real_main_ -}