addurl, get: Added --json-progress option, which adds progress objects to the json output.
This doesn't work right when used with -J yet, and there is some really ugly hand-crafting of part of the json output.
This commit is contained in:
parent
f421a7f001
commit
05d4438383
12 changed files with 55 additions and 12 deletions
|
@ -6,6 +6,8 @@ git-annex (6.20160908) UNRELEASED; urgency=medium
|
||||||
over ssh etc.
|
over ssh etc.
|
||||||
* Make --json and --quiet work when used with -J.
|
* Make --json and --quiet work when used with -J.
|
||||||
Previously, -J override the other options.
|
Previously, -J override the other options.
|
||||||
|
* addurl, get: Added --json-progress option, which adds progress
|
||||||
|
objects to the json output.
|
||||||
* Remove key:null from git-annex add --json output.
|
* Remove key:null from git-annex add --json output.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Thu, 08 Sep 2016 12:48:55 -0400
|
-- Joey Hess <id@joeyh.name> Thu, 08 Sep 2016 12:48:55 -0400
|
||||||
|
|
|
@ -286,12 +286,19 @@ combiningOptions =
|
||||||
shortopt o h = globalFlag (Limit.addToken [o]) ( short o <> help h <> hidden )
|
shortopt o h = globalFlag (Limit.addToken [o]) ( short o <> help h <> hidden )
|
||||||
|
|
||||||
jsonOption :: GlobalOption
|
jsonOption :: GlobalOption
|
||||||
jsonOption = globalFlag (Annex.setOutput JSONOutput)
|
jsonOption = globalFlag (Annex.setOutput (JSONOutput False))
|
||||||
( long "json" <> short 'j'
|
( long "json" <> short 'j'
|
||||||
<> help "enable JSON output"
|
<> help "enable JSON output"
|
||||||
<> hidden
|
<> hidden
|
||||||
)
|
)
|
||||||
|
|
||||||
|
jsonProgressOption :: GlobalOption
|
||||||
|
jsonProgressOption = globalFlag (Annex.setOutput (JSONOutput True))
|
||||||
|
( long "json-progress" <> short 'j'
|
||||||
|
<> help "include progress in JSON output"
|
||||||
|
<> hidden
|
||||||
|
)
|
||||||
|
|
||||||
-- Note that a command that adds this option should wrap its seek
|
-- Note that a command that adds this option should wrap its seek
|
||||||
-- action in `allowConcurrentOutput`.
|
-- action in `allowConcurrentOutput`.
|
||||||
jobsOption :: GlobalOption
|
jobsOption :: GlobalOption
|
||||||
|
|
|
@ -31,7 +31,7 @@ import Annex.Quvi
|
||||||
import qualified Utility.Quvi as Quvi
|
import qualified Utility.Quvi as Quvi
|
||||||
|
|
||||||
cmd :: Command
|
cmd :: Command
|
||||||
cmd = notBareRepo $ withGlobalOptions [jobsOption, jsonOption] $
|
cmd = notBareRepo $ withGlobalOptions [jobsOption, jsonOption, jsonProgressOption] $
|
||||||
command "addurl" SectionCommon "add urls to annex"
|
command "addurl" SectionCommon "add urls to annex"
|
||||||
(paramRepeating paramUrl) (seek <$$> optParser)
|
(paramRepeating paramUrl) (seek <$$> optParser)
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import Annex.Wanted
|
||||||
import qualified Command.Move
|
import qualified Command.Move
|
||||||
|
|
||||||
cmd :: Command
|
cmd :: Command
|
||||||
cmd = withGlobalOptions (jobsOption : jsonOption : annexedMatchingOptions) $
|
cmd = withGlobalOptions (jobsOption : jsonOption : jsonProgressOption : annexedMatchingOptions) $
|
||||||
command "get" SectionCommon
|
command "get" SectionCommon
|
||||||
"make content of annexed files available"
|
"make content of annexed files available"
|
||||||
paramPaths (seek <$$> optParser)
|
paramPaths (seek <$$> optParser)
|
||||||
|
|
|
@ -79,7 +79,7 @@ seek o = do
|
||||||
(seeker $ whenAnnexed $ start now o)
|
(seeker $ whenAnnexed $ start now o)
|
||||||
(forFiles o)
|
(forFiles o)
|
||||||
Batch -> withMessageState $ \s -> case outputType s of
|
Batch -> withMessageState $ \s -> case outputType s of
|
||||||
JSONOutput -> batchInput parseJSONInput $
|
JSONOutput _ -> batchInput parseJSONInput $
|
||||||
commandAction . startBatch now
|
commandAction . startBatch now
|
||||||
_ -> error "--batch is currently only supported in --json mode"
|
_ -> error "--batch is currently only supported in --json mode"
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ commandProgressDisabled :: Annex Bool
|
||||||
commandProgressDisabled = withMessageState $ \s -> return $
|
commandProgressDisabled = withMessageState $ \s -> return $
|
||||||
case outputType s of
|
case outputType s of
|
||||||
QuietOutput -> True
|
QuietOutput -> True
|
||||||
JSONOutput -> True
|
JSONOutput _ -> True
|
||||||
NormalOutput -> concurrentOutputEnabled s
|
NormalOutput -> concurrentOutputEnabled s
|
||||||
|
|
||||||
{- Use to show a message that is displayed implicitly, and so might be
|
{- Use to show a message that is displayed implicitly, and so might be
|
||||||
|
|
|
@ -26,20 +26,20 @@ outputMessage' endmessage json msg = withMessageState $ \s -> case outputType s
|
||||||
NormalOutput
|
NormalOutput
|
||||||
| concurrentOutputEnabled s -> concurrentMessage s False msg q
|
| concurrentOutputEnabled s -> concurrentMessage s False msg q
|
||||||
| otherwise -> liftIO $ flushed $ putStr msg
|
| otherwise -> liftIO $ flushed $ putStr msg
|
||||||
JSONOutput -> void $ outputJSON json endmessage s
|
JSONOutput _ -> void $ outputJSON json endmessage s
|
||||||
QuietOutput -> q
|
QuietOutput -> q
|
||||||
|
|
||||||
outputJSON :: IO () -> Bool -> MessageState -> Annex Bool
|
outputJSON :: IO () -> Bool -> MessageState -> Annex Bool
|
||||||
outputJSON json endmessage s = case outputType s of
|
outputJSON json endmessage s = case outputType s of
|
||||||
JSONOutput
|
JSONOutput withprogress
|
||||||
| concurrentOutputEnabled s -> do
|
| withprogress || concurrentOutputEnabled s -> do
|
||||||
-- Buffer json fragments until end is reached.
|
-- Buffer json fragments until end is reached.
|
||||||
if endmessage
|
if endmessage
|
||||||
then do
|
then do
|
||||||
Annex.changeState $ \st ->
|
Annex.changeState $ \st ->
|
||||||
st { Annex.output = s { jsonBuffer = [] } }
|
st { Annex.output = s { jsonBuffer = [] } }
|
||||||
liftIO $ flushed $ do
|
liftIO $ flushed $ do
|
||||||
sequence_ $ reverse $ jsonBuffer s
|
showJSONBuffer s
|
||||||
json
|
json
|
||||||
else Annex.changeState $ \st ->
|
else Annex.changeState $ \st ->
|
||||||
st { Annex.output = s { jsonBuffer = json : jsonBuffer s } }
|
st { Annex.output = s { jsonBuffer = json : jsonBuffer s } }
|
||||||
|
@ -49,6 +49,9 @@ outputJSON json endmessage s = case outputType s of
|
||||||
return True
|
return True
|
||||||
_ -> return False
|
_ -> return False
|
||||||
|
|
||||||
|
showJSONBuffer :: MessageState -> IO ()
|
||||||
|
showJSONBuffer s = sequence_ $ reverse $ jsonBuffer s
|
||||||
|
|
||||||
outputError :: String -> Annex ()
|
outputError :: String -> Annex ()
|
||||||
outputError msg = withMessageState $ \s ->
|
outputError msg = withMessageState $ \s ->
|
||||||
if concurrentOutputEnabled s
|
if concurrentOutputEnabled s
|
||||||
|
|
|
@ -13,6 +13,7 @@ module Messages.JSON (
|
||||||
note,
|
note,
|
||||||
add,
|
add,
|
||||||
complete,
|
complete,
|
||||||
|
progress,
|
||||||
DualDisp(..),
|
DualDisp(..),
|
||||||
ObjectMap(..),
|
ObjectMap(..),
|
||||||
JSONActionItem(..),
|
JSONActionItem(..),
|
||||||
|
@ -30,6 +31,8 @@ import Prelude
|
||||||
|
|
||||||
import qualified Utility.JSONStream as Stream
|
import qualified Utility.JSONStream as Stream
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
import Utility.Metered
|
||||||
|
import Utility.Percentage
|
||||||
|
|
||||||
start :: String -> Maybe FilePath -> Maybe Key -> IO ()
|
start :: String -> Maybe FilePath -> Maybe Key -> IO ()
|
||||||
start command file key = B.hPut stdout $ Stream.start $ Stream.AesonObject o
|
start command file key = B.hPut stdout $ Stream.start $ Stream.AesonObject o
|
||||||
|
@ -53,6 +56,20 @@ add = B.hPut stdout . Stream.add
|
||||||
complete :: Stream.JSONChunk a -> IO ()
|
complete :: Stream.JSONChunk a -> IO ()
|
||||||
complete v = B.hPut stdout $ Stream.start v `B.append` Stream.end
|
complete v = B.hPut stdout $ Stream.start v `B.append` Stream.end
|
||||||
|
|
||||||
|
progress :: IO () -> Integer -> BytesProcessed -> IO ()
|
||||||
|
progress jsonbuffer size bytesprocessed = do
|
||||||
|
B.hPut stdout $ Stream.start $ Stream.AesonObject o
|
||||||
|
putStr ",\"action\":"
|
||||||
|
jsonbuffer
|
||||||
|
B.hPut stdout $ Stream.end
|
||||||
|
B.hPut stdout $ Stream.end
|
||||||
|
where
|
||||||
|
n = fromBytesProcessed bytesprocessed :: Integer
|
||||||
|
Object o = object
|
||||||
|
[ "byte-progress" .= n
|
||||||
|
, "percent-progress" .= showPercentage 2 (percentage size n)
|
||||||
|
]
|
||||||
|
|
||||||
-- A value that can be displayed either normally, or as JSON.
|
-- A value that can be displayed either normally, or as JSON.
|
||||||
data DualDisp = DualDisp
|
data DualDisp = DualDisp
|
||||||
{ dispNormal :: String
|
{ dispNormal :: String
|
||||||
|
|
|
@ -16,6 +16,7 @@ import Utility.Metered
|
||||||
import Types
|
import Types
|
||||||
import Types.Messages
|
import Types.Messages
|
||||||
import Types.Key
|
import Types.Key
|
||||||
|
import qualified Messages.JSON as JSON
|
||||||
|
|
||||||
#ifdef WITH_CONCURRENTOUTPUT
|
#ifdef WITH_CONCURRENTOUTPUT
|
||||||
import Messages.Concurrent
|
import Messages.Concurrent
|
||||||
|
@ -35,7 +36,6 @@ metered othermeter key a = case keySize key of
|
||||||
Just size -> withMessageState (go $ fromInteger size)
|
Just size -> withMessageState (go $ fromInteger size)
|
||||||
where
|
where
|
||||||
go _ (MessageState { outputType = QuietOutput }) = nometer
|
go _ (MessageState { outputType = QuietOutput }) = nometer
|
||||||
go _ (MessageState { outputType = JSONOutput }) = nometer
|
|
||||||
go size (MessageState { outputType = NormalOutput, concurrentOutputEnabled = False }) = do
|
go size (MessageState { outputType = NormalOutput, concurrentOutputEnabled = False }) = do
|
||||||
showOutput
|
showOutput
|
||||||
(progress, meter) <- mkmeter size
|
(progress, meter) <- mkmeter size
|
||||||
|
@ -57,6 +57,12 @@ metered othermeter key a = case keySize key of
|
||||||
#else
|
#else
|
||||||
nometer
|
nometer
|
||||||
#endif
|
#endif
|
||||||
|
go _ (MessageState { outputType = JSONOutput False }) = nometer
|
||||||
|
go size (MessageState { outputType = JSONOutput True }) = do
|
||||||
|
buf <- withMessageState $ return . showJSONBuffer
|
||||||
|
m <- liftIO $ rateLimitMeterUpdate 0.1 (Just size) $
|
||||||
|
JSON.progress buf size
|
||||||
|
a (combinemeter m)
|
||||||
|
|
||||||
mkmeter size = do
|
mkmeter size = do
|
||||||
progress <- liftIO $ newProgress "" size
|
progress <- liftIO $ newProgress "" size
|
||||||
|
|
|
@ -15,7 +15,7 @@ import Data.Default
|
||||||
import System.Console.Regions (ConsoleRegion)
|
import System.Console.Regions (ConsoleRegion)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data OutputType = NormalOutput | QuietOutput | JSONOutput
|
data OutputType = NormalOutput | QuietOutput | JSONOutput Bool
|
||||||
deriving (Show)
|
deriving (Show)
|
||||||
|
|
||||||
data SideActionBlock = NoBlock | StartBlock | InBlock
|
data SideActionBlock = NoBlock | StartBlock | InBlock
|
||||||
|
|
|
@ -88,6 +88,10 @@ be used to get better filenames.
|
||||||
Enable JSON output. This is intended to be parsed by programs that use
|
Enable JSON output. This is intended to be parsed by programs that use
|
||||||
git-annex. Each line of output is a JSON object.
|
git-annex. Each line of output is a JSON object.
|
||||||
|
|
||||||
|
* `--json-progress`
|
||||||
|
|
||||||
|
Include progress objects in JSON output.
|
||||||
|
|
||||||
# CAVEATS
|
# CAVEATS
|
||||||
|
|
||||||
If annex.largefiles is configured, and does not match a file, `git annex
|
If annex.largefiles is configured, and does not match a file, `git annex
|
||||||
|
|
|
@ -86,7 +86,7 @@ or transferring them from some kind of key-value store.
|
||||||
displayed. If the specified file's content is already present, or
|
displayed. If the specified file's content is already present, or
|
||||||
it is not an annexed file, a blank line is output in response instead.
|
it is not an annexed file, a blank line is output in response instead.
|
||||||
|
|
||||||
Since the usual progress output while getting a file is verbose and not
|
Since the usual output while getting a file is verbose and not
|
||||||
machine-parseable, you may want to use --json in combination with
|
machine-parseable, you may want to use --json in combination with
|
||||||
--batch.
|
--batch.
|
||||||
|
|
||||||
|
@ -95,6 +95,10 @@ or transferring them from some kind of key-value store.
|
||||||
Enable JSON output. This is intended to be parsed by programs that use
|
Enable JSON output. This is intended to be parsed by programs that use
|
||||||
git-annex. Each line of output is a JSON object.
|
git-annex. Each line of output is a JSON object.
|
||||||
|
|
||||||
|
* `--json-progress`
|
||||||
|
|
||||||
|
Include progress objects in JSON output.
|
||||||
|
|
||||||
# SEE ALSO
|
# SEE ALSO
|
||||||
|
|
||||||
[[git-annex]](1)
|
[[git-annex]](1)
|
||||||
|
|
Loading…
Reference in a new issue