Compare commits

...

3 commits

Author SHA1 Message Date
Mirek Kratochvil 4499144a4d test more builds 2025-07-29 08:22:52 +02:00
Mirek Kratochvil 8f9677e40f improve the patch subcommand a little
closes https://github.com/exaexa/werge/issues/1
2025-07-23 11:18:27 +02:00
Mirek Kratochvil b52b106ac5 allow picking patches from files 2025-07-23 10:50:17 +02:00
5 changed files with 78 additions and 24 deletions

View file

@ -8,17 +8,26 @@ on:
jobs:
build:
runs-on: ubuntu-latest
name: Build ${{ github.ref_name }} OS:${{ matrix.os }} GHC:${{ matrix.ghc }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-22.04, macos-15]
ghc:
- "9.6"
- "9.12"
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: haskell-actions/setup@v2
with:
ghc-version: '9.4'
- run: |
cabal build
xz -9 < `cabal exec which werge` > werge-${{ github.ref_name }}-`uname -m`.xz
ghc-version: ${{ matrix.ghc }}
- name: build
run: |
mkdir dist
cabal install exe:werge --install-method=copy --overwrite-policy=always --installdir=dist
strip dist/werge
mv dist/werge dist/werge-${{ github.ref_name }}_${{ matrix.os }}_ghc-${{ matrix.ghc }}
xz dist/werge-*
- uses: softprops/action-gh-release@v2
with:
files: werge-*.xz
files: dist/werge-*.xz

45
Main.hs
View file

@ -30,13 +30,16 @@ data Op
| Add
deriving (Show, Eq)
pdiff :: FilePath -> IO [(Op, Tok)]
pdiff path = map go . lines <$> readFile path
pdiff' :: [String] -> [(Op, Tok)]
pdiff' = map go
where
go ('-':s) = (Del, s)
go (' ':s) = (Keep, 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
= Ok [String]
@ -286,6 +289,21 @@ format Config {..} h = go False
[cfgLabelStart, Toks.glue o, cfgLabelDiff, Toks.glue n, cfgLabelEnd]
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 CmdDiff3 {..} cfg =
withSystemTempDirectory "werge-diff3" $ \workdir -> do
@ -343,12 +361,21 @@ runCmd CmdDiff {..} cfg = do
runCmd CmdPatch {..} cfg = do
withSystemTempDirectory "werge-patch" $ \workdir -> do
let f = workdir </> "file"
bracketFile patchMy ReadMode $ \h -> hSplitToFile cfg h f
_ <- runPatch f stdin
conflicted <- pmerge f >>= format cfg stdout -- TODO try to resolve more?
if conflicted
then exitWith (ExitFailure 1)
else exitSuccess
case patchTarget of
Just patchMy -> do
bracketFile patchMy ReadMode $ \h -> hSplitToFile cfg h f
_ <-
case patchInput of
Nothing -> runPatch f stdin
Just path -> bracketFile path ReadMode $ runPatch f
conflicted <- pmerge f >>= format cfg stdout -- TODO try to resolve more?
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 CmdGlue _ = getContents >>= putStr . Toks.glue . Toks.fromFile

21
Opts.hs
View file

@ -229,7 +229,8 @@ data Command
, diffUnified :: Maybe Int
}
| CmdPatch
{ patchMy :: FilePath
{ patchTarget :: Maybe FilePath
, patchInput :: Maybe FilePath
}
| CmdBreak
| CmdGlue
@ -294,7 +295,21 @@ cmdDiff = do
cmdPatch :: Parser Command
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 <-
optional . strOption
$ long "patch"
<> short 'p'
<> metavar "PATCH"
<> help "File with the patch (default: stdin)"
pure CmdPatch {..}
-- TODO have some option to output the (partially merged) my/old/your files so
@ -314,7 +329,7 @@ cmd =
$ progDesc "Find differences between two files"
, command "patch"
$ info cmdPatch
$ progDesc "Apply a patch from `diff' to file"
$ progDesc "Modify a file using a patch from `diff'"
, command "break"
$ info (pure CmdBreak)
$ progDesc "Break text to tokens"

View file

@ -279,12 +279,15 @@ Available options:
#### 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:
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
```

View file

@ -1,6 +1,6 @@
cabal-version: 3.0
name: werge
version: 0.1.0.0
version: 0.2.0.0
synopsis: mergetool for mangled-up bite-size changes
license: GPL-3.0-or-later
license-file: LICENSE