git-fmt 0.4.0.0 → 0.4.1.0
raw patch · 5 files changed
+72/−28 lines, 5 filesdep +processdep ~optparse-applicative
Dependencies added: process
Dependency ranges changed: optparse-applicative
Files
- CHANGELOG.md +11/−0
- README.md +22/−1
- app/Git/Fmt/Options.hs +16/−11
- app/Main.hs +20/−15
- git-fmt.cabal +3/−1
CHANGELOG.md view
@@ -2,6 +2,17 @@ #### Upcoming +#### v0.4.1.0++*Minor*++* Added bash completion for `--mode` and arguments. ([#71](https://github.com/hjwylde/git-fmt/issues/71))++*Revisions*++* Changed path outputs to be relative to the root directory. ([#69](https://github.com/hjwylde/git-fmt/issues/69))+* Fixed a bug where `--operate-on` didn't work in subdirectories. ([#69](https://github.com/hjwylde/git-fmt/issues/69))+ #### v0.4.0.0 *Major*
README.md view
@@ -81,5 +81,26 @@ #### Configuration git-fmt delegates to omnifmt for configuration, see- [here](https://github.com/hjwylde/git-fmt#configuration) for documentation and examples.+ [here](https://github.com/hjwylde/omnifmt#configuration) for documentation and examples.++### Auto-completion++Add the following (depending on your shell) to include support for auto-completion.++**Bash:**++```bash+source <(git-fmt --bash-completion-script `which git-fmt`)+```++**zsh:**++```zsh+autoload -Uz bashcompinit && bashcompinit+source <(git-fmt --bash-completion-script `which git-fmt`)+```++**NB:** auto-completion doesn't work well with git's command macro. I.e., `git fmt <TAB>` won't+ work, but `git-fmt <TAB>` will. [#71](https://github.com/hjwylde/git-fmt/issues/71) will remain+ open until this is addressed.
app/Git/Fmt/Options.hs view
@@ -21,11 +21,12 @@ import Data.Char (isDigit) import Data.Version (showVersion) +import Git.Fmt.Version as This++import Omnifmt.Config as Config import Options.Applicative import Options.Applicative.Types (readerAsk) -import Git.Fmt.Version as This- -- | Options. data Options = Options { optChatty :: Chatty,@@ -56,22 +57,24 @@ -- | An optparse parser of a git-fmt command. gitFmtInfo :: ParserInfo Options-gitFmtInfo = info (infoOptions <*> gitFmt) fullDesc+gitFmtInfo = info (infoOptions <*> gitFmt) (fullDesc <> progDesc') where- infoOptions = helper <*> version <*> numericVersion- helper = abortOption ShowHelpText $ mconcat [+ infoOptions = helper <*> version <*> numericVersion+ helper = abortOption ShowHelpText $ mconcat [ short 'h', hidden, help "Show this help text" ]- version = infoOption ("Version " ++ showVersion This.version) $ mconcat [+ version = infoOption ("Version " ++ showVersion This.version) $ mconcat [ long "version", short 'V', hidden, help "Show this binary's version" ]- numericVersion = infoOption (showVersion This.version) $ mconcat [+ numericVersion = infoOption (showVersion This.version) $ mconcat [ long "numeric-version", hidden, help "Show this binary's version (without the prefix)" ] + progDesc' = progDesc $ "Formats the paths given by applying the rules found in the root `" ++ Config.defaultFileName ++ "'"+ -- | An options parser. gitFmt :: Parser Options gitFmt = Options@@ -92,6 +95,7 @@ <*> modeOption (mconcat [ long "mode", short 'm', metavar "MODE", value Normal, showDefaultWith $ const "normal",+ completeWith ["normal", "dry-run", "diff"], help "Specify the mode as either `normal', `dry-run' or `diff'" ]) <*> (@@ -111,15 +115,16 @@ help "Specify the number of threads to use" ]) <*> many (strArgument $ mconcat [- metavar "-- PATHS..."+ metavar "-- PATHS...",+ action "file" ]) where- natOption = option $ readerAsk >>= \opt -> if all isDigit opt- then return $ Just (read opt :: Int)- else readerError $ "not a natural number `" ++ opt ++ "'" modeOption = option $ readerAsk >>= \opt -> case opt of "normal" -> return Normal "dry-run" -> return DryRun "diff" -> return Diff _ -> readerError $ "unrecognised mode `" ++ opt ++ "'"+ natOption = option $ readerAsk >>= \opt -> if all isDigit opt+ then return $ Just (read opt :: Int)+ else readerError $ "not a natural number `" ++ opt ++ "'"
app/Main.hs view
@@ -10,6 +10,7 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_HADDOCK hide, prune #-} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-}@@ -27,7 +28,7 @@ import qualified Control.Monad.Parallel as Parallel import Control.Monad.Reader -import Data.List.Extra (dropEnd, intersect, linesBy, lower)+import Data.List.Extra (dropEnd, intersect, linesBy, lower, nub) import Data.Maybe (fromJust, fromMaybe, isNothing) import Data.Text (Text) import qualified Data.Text as T@@ -39,7 +40,8 @@ import Git.Fmt.Options import Git.Fmt.Pipes -import Omnifmt.Config as Config+import Omnifmt.Config as Config+import Omnifmt.Directory import Omnifmt.Exit import Omnifmt.Pipes import Omnifmt.Process@@ -51,7 +53,7 @@ import qualified Pipes.Prelude as Pipes import Prelude hiding (filter, log) -import System.Directory.Extra+import System.Directory.Extra hiding (withCurrentDirectory) import System.Exit import System.FilePath import System.IO@@ -65,7 +67,7 @@ main :: IO () main = do- options <- customExecParser gitFmtPrefs gitFmtInfo+ !options <- customExecParser gitFmtPrefs gitFmtInfo let chatty = if optMode options == Diff then Quiet else optChatty options flip runLoggingT (log $ optChatty options) . filter chatty $ do@@ -82,19 +84,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)+ rootDir <- runPanic $ init <$> runProcess_ "git" ["rev-parse", "--show-toplevel"]+ absFilePaths <- runPanic $ filterM (liftIO . doesFileExist) =<< if null (argPaths options) then initialFilePaths options else liftM2 intersect (initialFilePaths options) (providedFilePaths options)- absFilePaths <- filterM (liftIO . doesFileExist) filePaths >>= mapM (liftIO . canonicalizePath)+ let relFilePaths = nub $ map (makeRelative rootDir) absFilePaths numThreads <- liftIO getNumCapabilities >>= \numCapabilities -> return $ fromMaybe numCapabilities (optThreads options) (output, input) <- liftIO $ spawn unbounded - withSystemTempDirectory "git-fmt" $ \tmpDir -> do- runEffect $ each (map (\filePath -> omnifmt (makeRelative rootDir filePath) (tmpDir </> dropDrive filePath)) absFilePaths) >-> toOutput output+ withCurrentDirectory rootDir . withSystemTempDirectory "git-fmt" $ \tmpDir -> do+ runEffect $ each (map (\filePath -> omnifmt filePath (tmpDir </> filePath)) relFilePaths) >-> toOutput output liftIO performGC @@ -102,16 +104,19 @@ runEffect (fromInput input >-> pipeline >-> runner (optMode options)) >> liftIO performGC +initialFilePaths :: (MonadError ExitCode m, MonadIO m, MonadLogger m) => Options -> m [FilePath]+initialFilePaths options = do+ rootDir <- init <$> runProcess_ "git" ["rev-parse", "--show-toplevel"]++ map (rootDir </>) . linesBy (== '\0') <$> case optOperateOn options of+ Tracked -> runProcess_ "git" ["ls-files", "-z", "--full-name", rootDir]+ Reference ref -> runProcess_ "git" ["diff", ref, "--name-only", "-z"]+ 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 (:[]) expandDirectory path = ifM (liftIO $ doesDirectoryExist path) (liftIO $ listFilesRecursive path) (return [path])--initialFilePaths :: (MonadError ExitCode m, MonadIO m, MonadLogger m) => Options -> m [FilePath]-initialFilePaths options = linesBy (== '\0') <$> case optOperateOn options of- Tracked -> runProcess_ "git" ["ls-files", "-z"]- Reference ref -> runProcess_ "git" ["diff", ref, "--name-only", "-z"] pipeline :: (MonadIO m, MonadLogger m, MonadReader Config m) => Pipe (Status, FilePath, FilePath) (Status, FilePath, FilePath) m () pipeline = checkFileSupported >-> createPrettyFile >-> runProgram >-> checkFilePretty
git-fmt.cabal view
@@ -1,5 +1,5 @@ name: git-fmt-version: 0.4.0.0+version: 0.4.1.0 author: Henry J. Wylde maintainer: public@hjwylde.com@@ -34,6 +34,7 @@ default-language: Haskell2010 other-extensions:+ BangPatterns FlexibleContexts MultiParamTypeClasses OverloadedStrings@@ -50,6 +51,7 @@ optparse-applicative >= 0.11, pipes >= 4.1, pipes-concurrency >= 2.0,+ process >= 1.2, temporary >= 1.2, text >= 1.2, time >= 1.5