Windows: Improve handling of shebang in external special remote program, searching for the program in the PATH.

findShellCommand needs a full path to a file in order to check it for a
shebang on Windows. It was being run with only the base name of the external
special remote program, which would only work when it was in the current
directory.

This is why users in
https://github.com/DanielDent/git-annex-remote-rclone/pull/10 and elsewhere
were complaining that the previous improvements to git-annex didn't make
git-remote-rclone work on Windows.

Also, reworked checkearlytermination, which while it worked, seemed
to rely on a race condition. And, improved its error messages.

This commit was sponsored by Shane-o on Patreon.
This commit is contained in:
Joey Hess 2017-03-08 15:56:55 -04:00
parent 0d1a1838c5
commit 5358fb992a
No known key found for this signature in database
GPG key ID: C910D9222512E3C7
5 changed files with 28 additions and 12 deletions

View file

@ -11,6 +11,8 @@ git-annex (6.20170301.2) UNRELEASED; urgency=medium
jobs than remotes.
* fsck -q: When a file has bad content, include the name of the file
in the warning message.
* Windows: Improve handling of shebang in external special remote
program, searching for the program in the PATH.
-- Joey Hess <id@joeyh.name> Thu, 02 Mar 2017 12:51:40 -0400

View file

@ -375,7 +375,8 @@ startExternal external = do
return st
where
start errrelayer g = liftIO $ do
(cmd, ps) <- findShellCommand basecmd
cmdpath <- searchPath basecmd
(cmd, ps) <- maybe (pure (basecmd, [])) findShellCommand cmdpath
let basep = (proc cmd (toCommand ps))
{ std_in = CreatePipe
, std_out = CreatePipe
@ -383,9 +384,8 @@ startExternal external = do
}
p <- propgit g basep
(Just hin, Just hout, Just herr, ph) <-
createProcess p `catchIO` runerr
createProcess p `catchIO` runerr cmdpath
stderrelay <- async $ errrelayer herr
checkearlytermination =<< getProcessExitCode ph
cv <- newTVarIO $ externalDefaultConfig external
pv <- newTVarIO Unprepared
pid <- atomically $ do
@ -409,15 +409,11 @@ startExternal external = do
environ <- propGitEnv g
return $ p { env = Just environ }
runerr _ = giveup ("Cannot run " ++ basecmd ++ " -- Make sure it's in your PATH and is executable.")
checkearlytermination Nothing = noop
checkearlytermination (Just exitcode) = ifM (inPath basecmd)
( giveup $ unwords [ "failed to run", basecmd, "(" ++ show exitcode ++ ")" ]
, do
path <- intercalate ":" <$> getSearchPath
giveup $ basecmd ++ " is not installed in PATH (" ++ path ++ ")"
)
runerr (Just cmd) _ =
giveup $ "Cannot run " ++ cmd ++ " -- Make sure it's executable and that its dependencies are installed."
runerr Nothing _ = do
path <- intercalate ":" <$> getSearchPath
giveup $ "Cannot run " ++ basecmd ++ " -- It is not installed in PATH (" ++ path ++ ")"
stopExternal :: External -> Annex ()
stopExternal external = liftIO $ do

View file

@ -227,6 +227,8 @@ inPath command = isJust <$> searchPath command
-
- The command may be fully qualified already, in which case it will
- be returned if it exists.
-
- Note that this will find commands in PATH that are not executable.
-}
searchPath :: String -> IO (Maybe FilePath)
searchPath command

View file

@ -54,3 +54,5 @@ VERSION 1
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
Oh yeah! This software is awesome. After getting used to having "dummy" shortcuts to content I don't currently have, with the simple ability to get/drop that content, I can't believe I haven't seen this anywhere before. If there is anything more impressive than this software, it's the support it has had from Joey over all this time. I'd have pulled my hair out long ago. :P
> [[fixed|done]] although untested --[[Joey]]

View file

@ -0,0 +1,14 @@
[[!comment format=mdwn
username="joey"
subject="""comment 3"""
date="2017-03-08T19:36:57Z"
content="""
Looking into it a bit more, the problem seems to be that findShellCommand
expects a path to a file to examine, but when it's used for an external
special remote, it's only given the name of the command.
So, I fixed it by searching for the command in the PATH.
I have still not tested if this works on Windows, but probably, I think.
As long as PATH is set on Windows at least.
"""]]