packages feed

git-fmt 0.2.1.2 → 0.2.2.0

raw patch · 8 files changed

+94/−255 lines, 8 filesdep ~aeson

Dependency ranges changed: aeson

Files

− CHANGELOG.md
@@ -1,82 +0,0 @@-## Changelog--#### Upcoming--#### v0.2.1.2--*Revisions*--* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))--#### v0.2.1.1--*Revisions*--* Fixed a bug where passing arguments would only work when running in the git directory. ([#57](https://github.com/hjwylde/git-fmt/issues/57))--#### v0.2.1.0--*Minor*--* Added default use of stdin and stdout when variables not specified in a program command. ([#49](https://github.com/hjwylde/git-fmt/issues/49))--#### v0.2.0.2--*Revisions*--* Fixed a bug causing prettifying to fail across filesystem boundaries. ([#72](https://github.com/hjwylde/git-fmt/issues/72))--#### v0.2.0.1--*Revisions*--* Fixed a bug where passing arguments would only work when running in the git directory. ([#57](https://github.com/hjwylde/git-fmt/issues/57))--#### v0.2.0.0--*Major*--* Removed `--list-ugly` and `--dry-run` options. ([#29](https://github.com/hjwylde/git-fmt/issues/29))-* Restricted use of `--quiet` and `--verbose` at the same time. ([#35](https://github.com/hjwylde/git-fmt/issues/35))-* Updated project structure to delegate pretty printing to other binaries. ([#38](https://github.com/hjwylde/git-fmt/issues/38))-* Added a `.omniyaml.yaml` config file. ([#38](https://github.com/hjwylde/git-fmt/issues/38))--*Minor*--* Added `--mode` option (either `normal` or `dry-run`). ([#29](https://github.com/hjwylde/git-fmt/issues/29))-* Added `--null` option (use the null terminator as the delimiter for inputs). ([#27](https://github.com/hjwylde/git-fmt/issues/27))-* Added support for directories as arguments (directories include all files within recursively). ([#30](https://github.com/hjwylde/git-fmt/issues/30))-* Added parallelisation. ([#48](https://github.com/hjwylde/git-fmt/issues/48))--*Revisions*--* Added a warning for when files aren't found. ([#29](https://github.com/hjwylde/git-fmt/issues/29))-* Updated internal use of `git ls-files` to use the null terminator option. ([#27](https://github.com/hjwylde/git-fmt/issues/27))-* Fixed debug log messages to have timestamp and log level on all lines. ([#33](https://github.com/hjwylde/git-fmt/issues/33))-* Tidied up error messages from git. ([#40](https://github.com/hjwylde/git-fmt/issues/40))-* Tidied up error messages from parsing the config. ([#43](https://github.com/hjwylde/git-fmt/issues/43))--#### v0.1.0.3--*Revisions*--* Fixed a bug where passing arguments would only work when running in the git directory. ([#57](https://github.com/hjwylde/git-fmt/issues/57))--#### v0.1.0.2--*Revisions*--* Fixed a bug where UTF-8 characters in strings weren't printed properly. ([#26](https://github.com/hjwylde/git-fmt/issues/26))--#### v0.1.0.1--*Revisions*--* Fixed a bug where integers were printed as rationals. ([#25](https://github.com/hjwylde/git-fmt/issues/25))--#### v0.1.0.0--This is first release of the `git-fmt` binary!-It provides a basic syntax for formatting files in a git repository.-Currently only JSON is supported.-
− README.md
@@ -1,94 +0,0 @@-# git-fmt--[![Project Status: Wip - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](http://www.repostatus.org/badges/1.0.0/wip.svg)](http://www.repostatus.org/#wip)-[![Build Status](https://travis-ci.org/hjwylde/git-fmt.svg?branch=master)](https://travis-ci.org/hjwylde/git-fmt)-[![Release](https://img.shields.io/github/release/hjwylde/git-fmt.svg)](https://github.com/hjwylde/git-fmt/releases/latest)--(Side note: the formatting component of this project will eventually be split out and named omnifmt.)--`git-fmt` adds a custom command to Git that automatically formats code by using external-    pretty-printers.-The idea was taken from [gofmt](https://golang.org/cmd/gofmt/), just with a bit of expansion to more-    languages.--Formatted code is:--* Easier to write: never worry about minor formatting concerns while hacking away.-* Easier to read: when all code looks the same you need not mentally convert others' formatting-  style into something you can understand.-* Easier to maintain: mechanical changes to the source don't cause unrelated changes to the file's-  formatting; diffs show only the real changes.-* Uncontroversial: never have a debate about spacing or brace position ever again.--(Bullet points taken from https://blog.golang.org/go-fmt-your-code.)--### Installing--Installing `git-fmt` is easiest done using either-    [stack](https://github.com/commercialhaskell/stack) (recommended) or-    [Cabal](https://github.com/haskell/cabal).-Alternatively you may download a pre-compiled binary of the-    [latest release](https://github.com/hjwylde/git-fmt/releases/latest).--**Using stack:**--```bash-stack install git-fmt-export PATH=$PATH:~/.local/bin-```--**Using Cabal:**--```bash-cabal-install git-fmt-export PATH=$PATH:~/.cabal/bin-```--### Usage--`git-fmt` itself just provides a way to select files in the git repository and pipe them through a-    pretty-printer.-It also provides a dry-run mode that will show you which files need prettifying.--#### Configuration--Configuration is done through an `.omnifmt.yaml` file in the repository's top-level directory.--To show how, here's an example `.omnifmt.yaml` with 4 programs:-```yaml-haskell:-    extensions: ["hs", "lhs"]-    command:    "stylish-haskell {{input}} > {{output}}"--javascript:-    extensions: ["js"]-    command:    "js-beautify -"--json:-    extensions: ["json"]-    command:    "json_pp"--ruby:-    extensions: ["rb"]-    command:    "ruby-beautify {{input}}"-```--That's all it takes!-Each command declares how to read the input file and how to write to the output file.-If the input variable is omitted, it is fed to the command through `stdin`.-Likewise if the output variable is omitted it is read from `stdout`.-The output file is used to compare whether the original input was pretty or ugly before writing-    to the original.--Extensions is pretty self explanatory, but if you use the same extension more than once then-    precedence goes to the first defined pretty-printer.--#### Examples--See the [examples/](https://github.com/hjwylde/git-fmt/tree/master/examples/) directory for some-    common pretty-printers and their corresponding omnifmt config.-Just don't forget to actually call the config file `.omnifmt.yaml`!--**NB:** Be careful when using these examples, I have not tested the pretty-printers fully to check-    that they will not destroy your code by accident.-
git-fmt.cabal view
@@ -1,5 +1,5 @@ name:           git-fmt-version:        0.2.1.2+version:        0.2.2.0  author:         Henry J. Wylde maintainer:     public@hjwylde.com@@ -17,8 +17,6 @@ category:       Development build-type:     Simple -extra-source-files: CHANGELOG.md README.md- source-repository head     type:       git     location:   git@github.com:hjwylde/git-fmt@@ -26,6 +24,7 @@ executable git-fmt     main-is:        Main.hs     hs-source-dirs: app/+    ghc-options:    -threaded -with-rtsopts=-N      default-language: Haskell2010     other-extensions:@@ -48,18 +47,19 @@         Git.Fmt.Options.Applicative.Parser     other-modules:         Git.Fmt.Config,+        Git.Fmt.Exit,         Git.Fmt.Process,         Git.Fmt.Version,-        Paths_git_fmt,-        System.IO.Extra'+        Paths_git_fmt      default-language: Haskell2010     other-extensions:         FlexibleContexts+        MultiParamTypeClasses         OverloadedStrings         TemplateHaskell     build-depends:-        aeson == 0.8.*,+        aeson >= 0.8 && < 0.10,         base == 4.8.*,         directory == 1.2.*,         exceptions == 0.8.*,
src/Git/Fmt.hs view
@@ -10,8 +10,9 @@ Options and handler for the git-fmt command. -} -{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE TemplateHaskell       #-}  module Git.Fmt (     -- * Options@@ -21,38 +22,40 @@     handle, ) where -import              Control.Monad.Catch     (MonadMask)-import              Control.Monad.Extra-import              Control.Monad.IO.Class-import              Control.Monad.Logger-import              Control.Monad.Parallel  (MonadParallel)-import qualified    Control.Monad.Parallel  as Parallel-import              Control.Monad.Reader+import           Control.Applicative+import           Control.Concurrent+import           Control.Monad.Catch    (MonadMask)+import           Control.Monad.Extra+import           Control.Monad.IO.Class+import           Control.Monad.Logger+import           Control.Monad.Parallel (MonadParallel)+import qualified Control.Monad.Parallel as Parallel+import           Control.Monad.Reader -import              Data.List.Extra     (chunksOf, linesBy, lower, nub)-import qualified    Data.Text           as T-import              Data.Yaml           (prettyPrintParseException)-import              Data.Yaml.Include   (decodeFileEither)+import           Data.List.Extra   (chunksOf, linesBy, lower, nub)+import           Data.Maybe        (fromMaybe)+import qualified Data.Text         as T+import           Data.Yaml         (prettyPrintParseException)+import           Data.Yaml.Include (decodeFileEither) -import Git.Fmt.Config   as Config+import Git.Fmt.Config  as Config+import Git.Fmt.Exit import Git.Fmt.Process-import GHC.IO.Exception (IOErrorType(..))  import Prelude hiding (read)  import System.Directory.Extra hiding (withCurrentDirectory) import System.Exit import System.FilePath-import System.IO.Error-import System.IO.Extra' import System.IO.Temp  -- | Options. data Options = Options {-        optChatty   :: Chatty,-        optNull     :: Bool,-        optMode     :: Mode,-        argPaths    :: [FilePath]+        optChatty     :: Chatty,+        optNull       :: Bool,+        optNumThreads :: Maybe Int,+        optMode       :: Mode,+        argPaths      :: [FilePath]     }     deriving (Eq, Show) @@ -73,6 +76,8 @@             (liftIO $ listFilesRecursive path)             (return [path])             )+    numThreads  <- liftIO getNumCapabilities >>= \numCapabilities ->+        return $ fromMaybe numCapabilities (optNumThreads options)      unlessM (liftIO . doesFileExist $ gitDir </> Config.defaultFileName) $ panic (gitDir </> Config.defaultFileName ++ ": not found") @@ -83,7 +88,7 @@     let supportedFilePaths = filter (supported config . T.pack . drop 1 . lower . takeExtension) filePaths      flip runReaderT config . withSystemTempDirectory "git-fmt" $ \tmpDir ->-        Parallel.sequence_ . map sequence . nChunks 8 . flip map supportedFilePaths $ \filePath -> ifM (liftIO $ doesFileExist filePath)+        Parallel.sequence_ . map sequence . nChunks numThreads . flip map supportedFilePaths $ \filePath -> ifM (liftIO $ doesFileExist filePath)             (fmt options filePath (tmpDir </> filePath))             ($(logWarn) $ T.pack (filePath ++ ": not found"))     where@@ -120,11 +125,7 @@ normal filePath tmpFilePath = do     $(logInfo) $ T.pack (filePath ++ ": prettified") -    -- Try move the file, but if it's across a filesystem boundary then we may need to copy instead-    liftIO $ renameFile tmpFilePath filePath `catchIOError` \e ->-        if ioeGetErrorType e == UnsupportedOperation-            then copyFile tmpFilePath filePath >> removeFile tmpFilePath-            else ioError e+    liftIO $ renameFile tmpFilePath filePath  dryRun :: (MonadIO m, MonadLogger m) => FilePath -> FilePath -> m () dryRun filePath _ = $(logInfo) $ T.pack (filePath ++ ": ugly")@@ -138,12 +139,12 @@         else panic ".git/: not found"  runProgram :: (MonadIO m, MonadLogger m) => Program -> FilePath -> FilePath -> m (ExitCode, String, String)-runProgram program inputFilePath tmpFilePath = do+runProgram program filePath tmpFilePath = do     liftIO $ createDirectoryIfMissing True (takeDirectory tmpFilePath)      runCommand . T.unpack $ substitute (T.concat [command program, inputSuffix, outputSuffix]) [-        (inputVariableName, T.pack $ '"':inputFilePath ++ "\""),-        (outputVariableName, T.pack $ '"':tmpFilePath ++ "\"")+        (inputVariableName, quote filePath),+        (outputVariableName, quote tmpFilePath)         ]     where         inputSuffix@@ -152,4 +153,8 @@         outputSuffix             | usesOutputVariable (command program)  = T.empty             | otherwise                             = T.pack " > " `T.append` outputVariableName+        quote str   = T.pack $ '"':concatMap escape str ++ "\""+        escape '\\' = "\\\\"+        escape '"'  = "\\\""+        escape c    = [c] 
+ src/Git/Fmt/Exit.hs view
@@ -0,0 +1,39 @@++{-|+Module      : Git.Fmt.Exit+Description : Extra exit utilities.++Copyright   : (c) Henry J. Wylde, 2015+License     : BSD3+Maintainer  : public@hjwylde.com++Extra exit utilities.+-}++{-# LANGUAGE TemplateHaskell #-}++module Git.Fmt.Exit (+    -- * Exiting+    panicWith, panic, exitFast,+) where++import Control.Monad.IO.Class+import Control.Monad.Logger++import Data.Text (pack)++import System.Exit++-- | Panics, logging the error to stderr and exiting fast with the code.+panicWith :: (MonadIO m, MonadLogger m) => String -> Int -> m a+panicWith error code = $(logError) (pack error) >> exitFast code++-- | Panics, logging the error to stderr and exiting fast with 128.+panic :: (MonadIO m, MonadLogger m) => String -> m a+panic error = panicWith error 128++-- | Exits fast with the given code (may be 0 for success!).+exitFast :: (MonadIO m) => Int -> m a+exitFast 0 = liftIO exitSuccess+exitFast code = liftIO $ exitWith (ExitFailure code)+
src/Git/Fmt/Options/Applicative/Parser.hs view
@@ -15,6 +15,7 @@     gitFmtPrefs, gitFmtInfo, gitFmt, ) where +import Data.Char    (isDigit) import Data.Version (showVersion)  import Options.Applicative@@ -59,6 +60,11 @@         long "null", short '0',         help "Input files are delimited by a null terminator instead of white space"         ])+    <*> natOption (mconcat [+        long "threads", metavar "INT",+        value Nothing, showDefaultWith $ const "number of processors",+        help "Specify the number of threads to use"+        ])     <*> modeOption (mconcat [         long "mode", short 'm', metavar "MODE",         value Normal, showDefaultWith $ const "normal",@@ -68,7 +74,10 @@         metavar "-- PATHS..."         ])     where-        modeOption = option $ readerAsk >>= \opt -> case opt of+        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             _           -> readerError $ "unrecognised mode `" ++ opt ++ "'"
src/Git/Fmt/Process.hs view
@@ -22,10 +22,11 @@  import Data.Text hiding (unwords) +import Git.Fmt.Exit+ import           System.Exit-import           System.IO.Extra'-import           System.Process   (CmdSpec (..), CreateProcess)-import qualified System.Process   as System+import           System.Process (CmdSpec (..), CreateProcess)+import qualified System.Process as System  -- | Runs the given executable with the arguments. --   Returns the exit code, stdout and stderr.
− src/System/IO/Extra'.hs
@@ -1,39 +0,0 @@--{-|-Module      : System.IO.Extra'-Description : Extra extra IO utilities.--Copyright   : (c) Henry J. Wylde, 2015-License     : BSD3-Maintainer  : public@hjwylde.com--Extra extra IO utilities.--}--{-# LANGUAGE TemplateHaskell #-}--module System.IO.Extra' (-    -- * Exiting-    panicWith, panic, exitFast,-) where--import Control.Monad.IO.Class-import Control.Monad.Logger--import Data.Text (pack)--import System.Exit---- | Panics, logging the error to stderr and exiting fast with the code.-panicWith :: (MonadIO m, MonadLogger m) => String -> Int -> m a-panicWith error code = $(logError) (pack error) >> exitFast code---- | Panics, logging the error to stderr and exiting fast with 128.-panic :: (MonadIO m, MonadLogger m) => String -> m a-panic error = panicWith error 128---- | Exits fast with the given code (may be 0 for success!).-exitFast :: (MonadIO m) => Int -> m a-exitFast 0 = liftIO exitSuccess-exitFast code = liftIO $ exitWith (ExitFailure code)-