packages feed

omnifmt 0.1.0.1 → 0.2.0.0

raw patch · 5 files changed

+54/−45 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Omnifmt.Pipes: NotFound :: Status
- Omnifmt.Pipes: checkFileExists :: MonadIO m => Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m ()
+ Omnifmt.Directory: withCurrentDirectory :: (MonadIO m, MonadMask m) => FilePath -> m a -> m a

Files

CHANGELOG.md view
@@ -2,20 +2,20 @@  #### Upcoming -#### v0.1.0.1+#### v0.2.0.0 -*Revisions*+*Major*+* Removed `checkFileExists` from the pipeline (moved to `handle`). ([#12](https://github.com/hjwylde/omnifmt/issues/12)) -* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#14](https://github.com/hjwylde/omnifmt/issues/14))+*Revisions*+* Changed path outputs to be relative to the root directory. ([#12](https://github.com/hjwylde/omnifmt/issues/12))  #### v0.1.0.0  *Major*- * Extracted omnifmt out from git@github.com:hjwylde/git-fmt. ([#1](https://github.com/hjwylde/omnifmt/issues/1))  *Revisions*- * Fixed a bug causing the program to hang when not in the root directory. ([#7](https://github.com/hjwylde/omnifmt/issues/7)) * Fixed a bug where output files could be created outside of the temp directory. ([#11](https://github.com/hjwylde/omnifmt/issues/11)) * Fixed a bug that omitted searching the drive for a config file. ([#8](https://github.com/hjwylde/omnifmt/issues/8))
app/Main.hs view
@@ -27,7 +27,7 @@ import qualified Control.Monad.Parallel as Parallel import           Control.Monad.Reader -import           Data.List.Extra    (dropEnd, linesBy, lower)+import           Data.List.Extra    (dropEnd, linesBy, lower, nub) import           Data.Maybe         (fromJust, fromMaybe, isNothing) import           Data.Text          (Text) import qualified Data.Text          as T@@ -35,9 +35,10 @@ import qualified Data.Text.IO       as T import           Data.Time          (defaultTimeLocale, formatTime, getZonedTime) -import Omnifmt.Config  as Config+import Omnifmt.Config    as Config+import Omnifmt.Directory import Omnifmt.Exit-import Omnifmt.Options hiding (omnifmt)+import Omnifmt.Options   hiding (omnifmt) import Omnifmt.Pipes  import Options.Applicative@@ -47,7 +48,7 @@ import qualified Pipes.Prelude    as Pipes import           Prelude          hiding (filter, log) -import System.Directory.Extra+import System.Directory.Extra hiding (withCurrentDirectory) import System.FilePath import System.IO import System.IO.Temp@@ -74,20 +75,19 @@  handle :: (MonadIO m, MonadLogger m, MonadMask m, MonadParallel m, MonadReader Config m) => Options -> m () handle options = do-    rootDir         <- liftIO getCurrentDirectory-    filePaths       <- runPanic $ if null (argPaths options)-        then ask >>= expandDirectory . takeDirectory . fromJust . source+    rootDir             <- ask >>= liftIO . canonicalizePath . takeDirectory . fromJust . source+    absFilePaths        <- runPanic $ if null (argPaths options)+        then expandDirectory rootDir         else providedFilePaths options-    absFilePaths    <- forM filePaths $ \filePath -> ifM (liftIO $ doesFileExist filePath)-        (liftIO $ canonicalizePath filePath) (return filePath)+    let relFilePaths    = nub $ map (makeRelative rootDir) absFilePaths      numThreads <- liftIO getNumCapabilities >>= \numCapabilities ->         return $ fromMaybe numCapabilities (optThreads options)      (output, input) <- liftIO $ spawn unbounded -    withSystemTempDirectory "omnifmt" $ \tmpDir -> do-        runEffect $ each (map (\filePath -> omnifmt (makeRelative rootDir filePath) (tmpDir </> dropDrive filePath)) absFilePaths) >-> toOutput output+    withCurrentDirectory rootDir . withSystemTempDirectory "omnifmt" $ \tmpDir -> do+        runEffect $ each (map (\filePath -> omnifmt filePath (tmpDir </> filePath)) relFilePaths) >-> toOutput output          liftIO performGC @@ -96,7 +96,7 @@             liftIO performGC  providedFilePaths :: MonadIO m => Options -> m [FilePath]-providedFilePaths options = concatMapM expandDirectory $ concatMap splitter (argPaths options)+providedFilePaths options = concatMapM (liftIO . canonicalizePath >=> expandDirectory) $ concatMap splitter (argPaths options)     where         splitter = if optNull options then linesBy (== '\0') else (:[]) @@ -104,7 +104,7 @@ expandDirectory path = ifM (liftIO $ doesDirectoryExist path) (liftIO $ listFilesRecursive path) (return [path])  pipeline :: (MonadIO m, MonadLogger m, MonadReader Config m) => Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m ()-pipeline = checkFileSupported >-> checkFileExists >-> createPrettyFile >-> runProgram >-> checkFilePretty+pipeline = checkFileSupported >-> createPrettyFile >-> runProgram >-> checkFilePretty     where         createPrettyFile = select [Unknown] $ \item@(_, _, prettyFilePath) -> do             liftIO $ createDirectoryIfMissing True (takeDirectory prettyFilePath)@@ -118,9 +118,9 @@  logFunction :: MonadLogger m => Status -> Text -> m () logFunction status-    | status `elem` [Unknown, Error, Timeout]       = logWarnN-    | status `elem` [Unsupported, NotFound, Pretty] = logDebugN-    | otherwise                                     = logInfoN+    | status `elem` [Unknown, Error, Timeout]   = logWarnN+    | status `elem` [Unsupported, Pretty]       = logDebugN+    | otherwise                                 = logInfoN  filter :: Chatty -> LoggingT m a -> LoggingT m a filter Quiet    = filterLogger (\_ level -> level >= LevelError)
omnifmt.cabal view
@@ -1,5 +1,5 @@ name:           omnifmt-version:        0.1.0.1+version:        0.2.0.0  author:         Henry J. Wylde maintainer:     public@hjwylde.com@@ -56,6 +56,7 @@ library     hs-source-dirs: src/     exposed-modules:+        Omnifmt.Directory,         Omnifmt.Config,         Omnifmt.Exit,         Omnifmt.Pipes,@@ -70,6 +71,7 @@     build-depends:         aeson >= 0.8,         base >= 4.8 && < 5,+        exceptions >= 0.8,         extra >= 1.4,         filepath >= 1.4,         monad-logger >= 0.3,
+ src/Omnifmt/Directory.hs view
@@ -0,0 +1,27 @@+{-|+Module      : Omnifmt.Directory+Description : System directory utilities.++Copyright   : (c) Henry J. Wylde, 2015+License     : BSD3+Maintainer  : public@hjwylde.com++System directory utilities.+-}++module Omnifmt.Directory (+    -- * Changing directories+    withCurrentDirectory,+) where++import Control.Monad.Catch  (MonadMask, bracket)+import Control.Monad.Except++import System.Directory.Extra hiding (withCurrentDirectory)++-- | @withCurrentDirectory dir action@ performs @action@ with the current directory set to @dir@.+--   The current directory is reset back to what it was afterwards.+withCurrentDirectory :: (MonadIO m, MonadMask m) => FilePath -> m a -> m a+withCurrentDirectory dir action = bracket (liftIO getCurrentDirectory) (liftIO . setCurrentDirectory)+    $ \_ -> liftIO (setCurrentDirectory dir) >> action+
src/Omnifmt/Pipes.hs view
@@ -24,12 +24,10 @@     omnifmt,      -- * Transformers-    select, checkFileSupported, checkFileExists, runProgram, checkFilePretty, commit, diff,-    printFileStatus,+    select, checkFileSupported, runProgram, checkFilePretty, commit, diff, printFileStatus, ) where  import Control.Monad.Except-import Control.Monad.Extra import Control.Monad.Logger import Control.Monad.Reader @@ -38,8 +36,6 @@ import qualified Data.Text        as T import           Data.Tuple.Extra (fst3) -import GHC.IO.Exception (IOErrorType (..))- import Omnifmt.Config import Omnifmt.Process @@ -49,13 +45,11 @@ import System.Directory.Extra import System.Exit import System.FilePath-import System.IO.Error  -- | A status for a file going through the omnifmt pipeline. data Status = Unknown       -- ^ The file has not been processed.             | Error         -- ^ An error occurred somewhere.             | Unsupported   -- ^ The file type is unsupported (i.e., no applicable 'Program').-            | NotFound      -- ^ The file could not be found.             | Timeout       -- ^ A command timed out.             | Pretty        -- ^ The file is pretty.             | Ugly          -- ^ The file is ugly.@@ -79,13 +73,6 @@         then return item         else return (Unsupported, uglyFilePath, prettyFilePath) --- | Checks all 'Unknown' ugly file paths to see if they exist.-checkFileExists :: MonadIO m => Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m ()-checkFileExists = select [Unknown] $ \item@(_, uglyFilePath, prettyFilePath) ->-    ifM (liftIO $ doesFileExist uglyFilePath)-        (return item)-        (return (NotFound, uglyFilePath, prettyFilePath))- -- | Runs the applicable 'Program''s command on all 'Unknown' files. --   This reads in the ugly file path and writes out to the pretty file path. --@@ -138,11 +125,7 @@ --   This function updates the status to 'Prettified'. commit :: MonadIO m => Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m () commit = select [Ugly] $ \(_, uglyFilePath, prettyFilePath) -> do-    -- Try move the file, but if it's across a filesystem boundary then we may need to copy instead-    liftIO $ renameFile prettyFilePath uglyFilePath `catchIOError` \e ->-        if ioeGetErrorType e == UnsupportedOperation-            then copyFile prettyFilePath uglyFilePath >> removeFile prettyFilePath-            else ioError e+    liftIO $ renameFile prettyFilePath uglyFilePath      return (Prettified, uglyFilePath, prettyFilePath) @@ -158,8 +141,5 @@ -- | Logs the status of each file using the given function. printFileStatus :: MonadLogger m => (Status -> Text -> m ()) -> Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m () printFileStatus f = Pipes.mapM_ $ \(status, uglyFilePath, _) ->-    f status (T.pack $ uglyFilePath ++ ": " ++ showStatus status)-    where-        showStatus NotFound = "not found"-        showStatus status   = lower $ show status+    f status (T.pack $ uglyFilePath ++ ": " ++ lower (show status))