Skip to content

Commit 1dea74d

Browse files
committed
Improve command rendering
Values to `git config` should be quoted to work properly, otherwise they (specifically aliases) would be set as multi-value configs. However, if we just blindly change this to be quoted values, we would split them into separate arguments for a proc, which would lead to the same issue. To improve this, we just need to use `[]` instead of `Text` for command args. Note: I've switched to "raw strings" (`[s|raw string|]`) in `AcquireRepositorySpec.hs` to remove escaping of double quotes. #299
1 parent f232b58 commit 1dea74d

File tree

3 files changed

+154
-142
lines changed

3 files changed

+154
-142
lines changed

src/Elegit/Git/Action.hs

+21-11
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,27 @@ import Universum hiding (print)
3838

3939
-- TODO: maybe, cover with tests
4040
class RenderGitCommand c where
41-
renderGC :: c -> Text
41+
commandArgs :: c -> [Text]
42+
toolName :: c -> Text
43+
toolName _ = "git"
44+
45+
renderGC :: RenderGitCommand c => c -> Text
46+
renderGC c = toolName c|+" "+|renderedArgs|+""
47+
where
48+
renderedArgs = T.intercalate " " (commandArgs c)
4249

4350
data GCurrentBranchData
4451
= GCurrentBranchData
4552

4653
instance RenderGitCommand GCurrentBranchData where
47-
renderGC _ = "rev-parse --abbrev-ref @"
54+
commandArgs _ = ["rev-parse", "--abbrev-ref", "@"]
4855

4956
newtype GBranchUpstreamData
5057
= GBranchUpstreamData { branch :: Text }
5158

5259
instance RenderGitCommand GBranchUpstreamData where
53-
renderGC (GBranchUpstreamData branchName) = "rev-parse --abbrev-ref "+|branchName|+"@{upstream}"
60+
commandArgs (GBranchUpstreamData branchName) =
61+
["rev-parse", "--abbrev-ref", branchName, "@{upstream}"]
5462

5563
data GLogData
5664
= GLogData
@@ -59,7 +67,8 @@ data GLogData
5967
, target :: Text
6068
}
6169
instance RenderGitCommand GLogData where
62-
renderGC (GLogData lType baseName targetName) = "log "+|logArg|+" "+|baseName|+".."+|targetName|+""
70+
commandArgs (GLogData lType baseName targetName) =
71+
["log ", logArg, ""+|baseName|+".."+|targetName|+""]
6372
where
6473
logArg :: Text
6574
logArg = case lType of
@@ -69,7 +78,7 @@ newtype GStatusData
6978
= GStatusData { statusType :: StatusType }
7079

7180
instance RenderGitCommand GStatusData where
72-
renderGC (GStatusData sType) = "status "+|statusFormat|+""
81+
commandArgs (GStatusData sType) = ["status", statusFormat]
7382
where
7483
statusFormat :: Text
7584
statusFormat = case sType of
@@ -78,7 +87,7 @@ instance RenderGitCommand GStatusData where
7887
data GStashListData
7988
= GStashListData
8089
instance RenderGitCommand GStashListData where
81-
renderGC _ = "stash list"
90+
commandArgs _ = ["stash", "list"]
8291

8392
data GReadConfigData
8493
= GReadConfigData
@@ -87,7 +96,7 @@ data GReadConfigData
8796
}
8897

8998
instance RenderGitCommand GReadConfigData where
90-
renderGC (GReadConfigData cScope cName) = "config "+|scopeText|+" --get "+|cName|+""
99+
commandArgs (GReadConfigData cScope cName) = ["config", scopeText, "--get", cName]
91100
where
92101
scopeText :: Text
93102
scopeText = case cScope of
@@ -103,7 +112,7 @@ data GSetConfigData
103112
}
104113

105114
instance RenderGitCommand GSetConfigData where
106-
renderGC (GSetConfigData cScope cName cValue) = "config "+|scopeText|+" "+|cName|+" "+|cValue|+""
115+
commandArgs (GSetConfigData cScope cName cValue) = ["config", scopeText, cName, "\""+|cValue|+"\""]
107116
where
108117
scopeText :: Text
109118
scopeText = case cScope of
@@ -118,7 +127,7 @@ data GUnsetConfigData
118127
}
119128

120129
instance RenderGitCommand GUnsetConfigData where
121-
renderGC (GUnsetConfigData cScope cName) = "config "+|scopeText|+" --unset "+|cName|+""
130+
commandArgs (GUnsetConfigData cScope cName) = ["config", scopeText, "--unset", cName]
122131
where
123132
scopeText :: Text
124133
scopeText = case cScope of
@@ -130,7 +139,8 @@ newtype GAliasesToRemoveData
130139
= GAliasesToRemoveData { scope :: ConfigScope }
131140

132141
instance RenderGitCommand GAliasesToRemoveData where
133-
renderGC (GAliasesToRemoveData cScope) = "config "+|scopeText|+" --name-only --get-regexp \"^alias.\" \"^elegant ([-a-z]+)$\""
142+
commandArgs (GAliasesToRemoveData cScope) =
143+
["config", scopeText, "--name-only", "--get-regexp", "\"^alias.\"", "\"^elegant ([-a-z]+)$\""]
134144
where
135145
scopeText :: Text
136146
scopeText = case cScope of
@@ -246,7 +256,7 @@ print content = liftF $ PrintText content ()
246256
-- Derived actions
247257

248258
formatGitCommand :: (RenderGitCommand gc, MonadFree GitF m) => gc -> m Text
249-
formatGitCommand gc = formatCommand ("git "+|renderGC gc|+"")
259+
formatGitCommand gc = formatCommand (renderGC gc)
250260

251261
setConfigVerbose :: MonadFree GitF m => ConfigScope -> Text -> Text -> m ()
252262
setConfigVerbose cScope cName cValue = do

src/Elegit/Git/Exec.hs

+11-11
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,16 @@ data GitCommand
2727

2828

2929
-- TODO: cover with tests
30-
renderGitCommand :: GitCommand -> Text
31-
renderGitCommand (GCCB gc) = renderGC gc
32-
renderGitCommand (GCBU gc) = renderGC gc
33-
renderGitCommand (GCL gc) = "-c color.ui=always "+|renderGC gc|+""
34-
renderGitCommand (GCS gc) = "-c color.status=always "+|renderGC gc|+""
35-
renderGitCommand (GCSL gc) = renderGC gc
36-
renderGitCommand (GCRC gc) = renderGC gc
37-
renderGitCommand (GCSC gc) = renderGC gc
38-
renderGitCommand (GCUC gc) = renderGC gc
39-
renderGitCommand (GCATR gc) = renderGC gc
30+
gitCommandArgs :: GitCommand -> [Text]
31+
gitCommandArgs (GCCB gc) = commandArgs gc
32+
gitCommandArgs (GCBU gc) = commandArgs gc
33+
gitCommandArgs (GCL gc) = "-c":"color.ui=always":commandArgs gc
34+
gitCommandArgs (GCS gc) = "-c":"color.status=always":commandArgs gc
35+
gitCommandArgs (GCSL gc) = commandArgs gc
36+
gitCommandArgs (GCRC gc) = commandArgs gc
37+
gitCommandArgs (GCSC gc) = commandArgs gc
38+
gitCommandArgs (GCUC gc) = commandArgs gc
39+
gitCommandArgs (GCATR gc) = commandArgs gc
4040

4141

4242
class Monad m => MonadGitExec m where
@@ -47,7 +47,7 @@ class Monad m => MonadGitExec m where
4747

4848
instance MonadIO m => MonadGitExec (GitExecT m) where
4949
execGit gc = do
50-
(eCode, outputBS, _errBS) <- readProcess $ proc "git" (toString <$> words (renderGitCommand gc))
50+
(eCode, outputBS, _errBS) <- readProcess $ proc "git" (toString <$> gitCommandArgs gc)
5151
case eCode of
5252
-- TODO: Handle error codes per `gc`
5353
ExitFailure _ -> do

0 commit comments

Comments
 (0)