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 +5/−5
- app/Main.hs +16/−16
- omnifmt.cabal +3/−1
- src/Omnifmt/Directory.hs +27/−0
- src/Omnifmt/Pipes.hs +3/−23
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))