improve the patch subcommand a little
closes https://github.com/exaexa/werge/issues/1
This commit is contained in:
parent
b52b106ac5
commit
8f9677e40f
48
Main.hs
48
Main.hs
|
|
@ -30,13 +30,16 @@ data Op
|
||||||
| Add
|
| Add
|
||||||
deriving (Show, Eq)
|
deriving (Show, Eq)
|
||||||
|
|
||||||
pdiff :: FilePath -> IO [(Op, Tok)]
|
pdiff' :: [String] -> [(Op, Tok)]
|
||||||
pdiff path = map go . lines <$> readFile path
|
pdiff' = map go
|
||||||
where
|
where
|
||||||
go ('-':s) = (Del, s)
|
go ('-':s) = (Del, s)
|
||||||
go (' ':s) = (Keep, s)
|
go (' ':s) = (Keep, s)
|
||||||
go ('+':s) = (Add, s)
|
go ('+':s) = (Add, s)
|
||||||
go _ = error "unexpected output from diff"
|
go _ = error "unexpected contents in diff"
|
||||||
|
|
||||||
|
pdiff :: FilePath -> IO [(Op, Tok)]
|
||||||
|
pdiff path = pdiff' . lines <$> readFile path
|
||||||
|
|
||||||
data Merged
|
data Merged
|
||||||
= Ok [String]
|
= Ok [String]
|
||||||
|
|
@ -286,6 +289,21 @@ format Config {..} h = go False
|
||||||
[cfgLabelStart, Toks.glue o, cfgLabelDiff, Toks.glue n, cfgLabelEnd]
|
[cfgLabelStart, Toks.glue o, cfgLabelDiff, Toks.glue n, cfgLabelEnd]
|
||||||
go True xs
|
go True xs
|
||||||
|
|
||||||
|
fmtPatch :: Config -> Handle -> Handle -> IO ()
|
||||||
|
fmtPatch cfg out h = hGetContents h >>= go . lines
|
||||||
|
where
|
||||||
|
go all@(l:ls)
|
||||||
|
| patchLine l = do
|
||||||
|
let (p, ls') = span patchLine all
|
||||||
|
format cfg out . chunks $ pdiff' p
|
||||||
|
go ls'
|
||||||
|
| otherwise = hPutStrLn out l >> go ls
|
||||||
|
go [] = pure ()
|
||||||
|
patchLine (' ':_) = True
|
||||||
|
patchLine ('-':_) = True
|
||||||
|
patchLine ('+':_) = True
|
||||||
|
patchLine _ = False
|
||||||
|
|
||||||
runCmd :: Command -> Config -> IO ()
|
runCmd :: Command -> Config -> IO ()
|
||||||
runCmd CmdDiff3 {..} cfg =
|
runCmd CmdDiff3 {..} cfg =
|
||||||
withSystemTempDirectory "werge-diff3" $ \workdir -> do
|
withSystemTempDirectory "werge-diff3" $ \workdir -> do
|
||||||
|
|
@ -343,15 +361,21 @@ runCmd CmdDiff {..} cfg = do
|
||||||
runCmd CmdPatch {..} cfg = do
|
runCmd CmdPatch {..} cfg = do
|
||||||
withSystemTempDirectory "werge-patch" $ \workdir -> do
|
withSystemTempDirectory "werge-patch" $ \workdir -> do
|
||||||
let f = workdir </> "file"
|
let f = workdir </> "file"
|
||||||
bracketFile patchMy ReadMode $ \h -> hSplitToFile cfg h f
|
case patchTarget of
|
||||||
_ <-
|
Just patchMy -> do
|
||||||
case patchInput of
|
bracketFile patchMy ReadMode $ \h -> hSplitToFile cfg h f
|
||||||
Nothing -> runPatch f stdin
|
_ <-
|
||||||
Just path -> bracketFile path ReadMode $ runPatch f
|
case patchInput of
|
||||||
conflicted <- pmerge f >>= format cfg stdout -- TODO try to resolve more?
|
Nothing -> runPatch f stdin
|
||||||
if conflicted
|
Just path -> bracketFile path ReadMode $ runPatch f
|
||||||
then exitWith (ExitFailure 1)
|
conflicted <- pmerge f >>= format cfg stdout -- TODO try to resolve more?
|
||||||
else exitSuccess
|
if conflicted
|
||||||
|
then exitWith (ExitFailure 1)
|
||||||
|
else exitSuccess
|
||||||
|
Nothing -> do
|
||||||
|
case patchInput of
|
||||||
|
Nothing -> fmtPatch cfg stdout stdin
|
||||||
|
Just path -> bracketFile path ReadMode $ fmtPatch cfg stdout
|
||||||
runCmd CmdBreak cfg = hSplit cfg stdin stdout
|
runCmd CmdBreak cfg = hSplit cfg stdin stdout
|
||||||
runCmd CmdGlue _ = getContents >>= putStr . Toks.glue . Toks.fromFile
|
runCmd CmdGlue _ = getContents >>= putStr . Toks.glue . Toks.fromFile
|
||||||
|
|
||||||
|
|
|
||||||
12
Opts.hs
12
Opts.hs
|
|
@ -229,7 +229,7 @@ data Command
|
||||||
, diffUnified :: Maybe Int
|
, diffUnified :: Maybe Int
|
||||||
}
|
}
|
||||||
| CmdPatch
|
| CmdPatch
|
||||||
{ patchMy :: FilePath
|
{ patchTarget :: Maybe FilePath
|
||||||
, patchInput :: Maybe FilePath
|
, patchInput :: Maybe FilePath
|
||||||
}
|
}
|
||||||
| CmdBreak
|
| CmdBreak
|
||||||
|
|
@ -295,7 +295,15 @@ cmdDiff = do
|
||||||
|
|
||||||
cmdPatch :: Parser Command
|
cmdPatch :: Parser Command
|
||||||
cmdPatch = do
|
cmdPatch = do
|
||||||
patchMy <- strArgument $ metavar "MYFILE" <> help "File to be modified"
|
patchTarget <-
|
||||||
|
asum
|
||||||
|
[ Just <$> strArgument (metavar "MYFILE" <> help "File to be patched")
|
||||||
|
, flag' Nothing
|
||||||
|
$ long "format"
|
||||||
|
<> short 'f'
|
||||||
|
<> help
|
||||||
|
"Do not patch anything, only format the patch using conflict marks on joined tokens"
|
||||||
|
]
|
||||||
patchInput <-
|
patchInput <-
|
||||||
optional . strOption
|
optional . strOption
|
||||||
$ long "patch"
|
$ long "patch"
|
||||||
|
|
|
||||||
|
|
@ -279,12 +279,15 @@ Available options:
|
||||||
|
|
||||||
#### Patching files in place
|
#### Patching files in place
|
||||||
```
|
```
|
||||||
Usage: werge patch MYFILE
|
Usage: werge patch (MYFILE | (-f|--format)) [-p|--patch PATCH]
|
||||||
|
|
||||||
Apply a patch from `diff' to file
|
Modify a file using a patch from `diff'
|
||||||
|
|
||||||
Available options:
|
Available options:
|
||||||
MYFILE File to be modified
|
MYFILE File to be patched
|
||||||
|
-f,--format Do not patch anything, only format the patch using
|
||||||
|
conflict marks on joined tokens
|
||||||
|
-p,--patch PATCH File with the patch (default: stdin)
|
||||||
-h,--help Show this help text
|
-h,--help Show this help text
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue