map: Support --json option
Sponsored-by: Dartmouth College's OpenNeuro project
This commit is contained in:
parent
4a98d12b7d
commit
52a8b5b117
5 changed files with 113 additions and 17 deletions
|
@ -6,6 +6,7 @@ git-annex (10.20250521) UNRELEASED; urgency=medium
|
||||||
configured but fails, prevent initialization. This allows the user to
|
configured but fails, prevent initialization. This allows the user to
|
||||||
fix their configuration and avoid crippled filesystem detection
|
fix their configuration and avoid crippled filesystem detection
|
||||||
entering an adjusted branch.
|
entering an adjusted branch.
|
||||||
|
* map: Support --json option.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Thu, 22 May 2025 12:43:38 -0400
|
-- Joey Hess <id@joeyh.name> Thu, 22 May 2025 12:43:38 -0400
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
|
|
||||||
module Command.Map where
|
module Command.Map where
|
||||||
|
|
||||||
import qualified Data.Map as M
|
|
||||||
|
|
||||||
import Command
|
import Command
|
||||||
import qualified Git
|
import qualified Git
|
||||||
import qualified Git.Url
|
import qualified Git.Url
|
||||||
|
@ -25,12 +23,17 @@ import Logs.Trust
|
||||||
import Types.TrustLevel
|
import Types.TrustLevel
|
||||||
import qualified Remote.Helper.Ssh as Ssh
|
import qualified Remote.Helper.Ssh as Ssh
|
||||||
import qualified Utility.Dot as Dot
|
import qualified Utility.Dot as Dot
|
||||||
|
import qualified Messages.JSON as JSON
|
||||||
|
import Messages.JSON ((.=))
|
||||||
|
import Utility.Aeson (packString)
|
||||||
|
|
||||||
|
import qualified Data.Map as M
|
||||||
|
|
||||||
-- a repo and its remotes
|
-- a repo and its remotes
|
||||||
type RepoRemotes = (Git.Repo, [Git.Repo])
|
type RepoRemotes = (Git.Repo, [Git.Repo])
|
||||||
|
|
||||||
cmd :: Command
|
cmd :: Command
|
||||||
cmd = dontCheck repoExists $
|
cmd = dontCheck repoExists $ withAnnexOptions [jsonOptions] $
|
||||||
command "map" SectionQuery
|
command "map" SectionQuery
|
||||||
"generate map of repositories"
|
"generate map of repositories"
|
||||||
paramNothing (withParams seek)
|
paramNothing (withParams seek)
|
||||||
|
@ -45,19 +48,23 @@ start = startingNoMessage (ActionItemOther Nothing) $ do
|
||||||
umap <- uuidDescMap
|
umap <- uuidDescMap
|
||||||
trustmap <- trustMapLoad
|
trustmap <- trustMapLoad
|
||||||
|
|
||||||
file <- (</>)
|
ifM (outputJSONMap rs trustmap umap)
|
||||||
<$> fromRepo gitAnnexDir
|
( next $ return True
|
||||||
<*> pure (literalOsPath "map.dot")
|
, do
|
||||||
|
file <- (</>)
|
||||||
|
<$> fromRepo gitAnnexDir
|
||||||
|
<*> pure (literalOsPath "map.dot")
|
||||||
|
|
||||||
liftIO $ writeFile (fromOsPath file) (drawMap rs trustmap umap)
|
liftIO $ writeFile (fromOsPath file) (drawMap rs trustmap umap)
|
||||||
next $
|
next $
|
||||||
ifM (Annex.getRead Annex.fast)
|
ifM (Annex.getRead Annex.fast)
|
||||||
( runViewer file []
|
( runViewer file []
|
||||||
, runViewer file
|
, runViewer file
|
||||||
[ ("xdot", [File (fromOsPath file)])
|
[ ("xdot", [File (fromOsPath file)])
|
||||||
, ("dot", [Param "-Tx11", File (fromOsPath file)])
|
, ("dot", [Param "-Tx11", File (fromOsPath file)])
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
runViewer :: OsPath -> [(String, [CommandParam])] -> Annex Bool
|
runViewer :: OsPath -> [(String, [CommandParam])] -> Annex Bool
|
||||||
runViewer file [] = do
|
runViewer file [] = do
|
||||||
|
@ -198,7 +205,8 @@ same a b
|
||||||
{- reads the config of a remote, with progress display -}
|
{- reads the config of a remote, with progress display -}
|
||||||
scan :: Git.Repo -> Annex Git.Repo
|
scan :: Git.Repo -> Annex Git.Repo
|
||||||
scan r = do
|
scan r = do
|
||||||
showStartMessage (StartMessage "map" (ActionItemOther (Just $ UnquotedString $ Git.repoDescribe r)) (SeekInput []))
|
unlessM jsonOutputEnabled $
|
||||||
|
showStartMessage (StartMessage "map" (ActionItemOther (Just $ UnquotedString $ Git.repoDescribe r)) (SeekInput []))
|
||||||
v <- tryScan r
|
v <- tryScan r
|
||||||
case v of
|
case v of
|
||||||
Just r' -> do
|
Just r' -> do
|
||||||
|
@ -269,7 +277,7 @@ tryScan r
|
||||||
configlist
|
configlist
|
||||||
ok -> return ok
|
ok -> return ok
|
||||||
|
|
||||||
sshnote = do
|
sshnote = unlessM jsonOutputEnabled $ do
|
||||||
showAction "sshing"
|
showAction "sshing"
|
||||||
showOutput
|
showOutput
|
||||||
|
|
||||||
|
@ -287,3 +295,33 @@ safely a = do
|
||||||
case result of
|
case result of
|
||||||
Left _ -> return Nothing
|
Left _ -> return Nothing
|
||||||
Right r' -> return $ Just r'
|
Right r' -> return $ Just r'
|
||||||
|
|
||||||
|
outputJSONMap :: [RepoRemotes] -> TrustMap -> UUIDDescMap -> Annex Bool
|
||||||
|
outputJSONMap rs trustmap umap =
|
||||||
|
showFullJSON $ JSON.AesonObject $ case mapo of
|
||||||
|
JSON.Object obj -> obj
|
||||||
|
_ -> error "internal"
|
||||||
|
where
|
||||||
|
mapo = JSON.object
|
||||||
|
[ "nodes" .= map mknode (filterdead fst rs)
|
||||||
|
]
|
||||||
|
|
||||||
|
mknode (r, remotes) = JSON.object
|
||||||
|
[ "name" .= packString (repoName umap r)
|
||||||
|
, "uuid" .= mkuuid (getUncachedUUID r)
|
||||||
|
, "url" .= packString (Git.repoLocation r)
|
||||||
|
, "remotes" .= map mkremote (filterdead id remotes)
|
||||||
|
]
|
||||||
|
|
||||||
|
mkremote r = JSON.object
|
||||||
|
[ "name" .= packString (repoName umap r)
|
||||||
|
, "uuid" .= mkuuid (getUncachedUUID r)
|
||||||
|
, "url" .= packString (Git.repoLocation r)
|
||||||
|
]
|
||||||
|
|
||||||
|
mkuuid NoUUID = Nothing
|
||||||
|
mkuuid u = Just $ packString $ fromUUID u
|
||||||
|
|
||||||
|
filterdead f = filter
|
||||||
|
(\i -> M.lookup (getUncachedUUID (f i)) trustmap /= Just DeadTrusted)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,10 @@ on that host.
|
||||||
|
|
||||||
Don't display the generated Graphviz file, but save it for later use.
|
Don't display the generated Graphviz file, but save it for later use.
|
||||||
|
|
||||||
|
* `--json`
|
||||||
|
|
||||||
|
Output the map as a JSON object.
|
||||||
|
|
||||||
* Also the [[git-annex-common-options]](1) can be used.
|
* Also the [[git-annex-common-options]](1) can be used.
|
||||||
|
|
||||||
# SEE ALSO
|
# SEE ALSO
|
||||||
|
|
|
@ -6,3 +6,5 @@ Please let me know on how feasible that would be, and any other thoughts you hav
|
||||||
|
|
||||||
[[!meta author=yoh]]
|
[[!meta author=yoh]]
|
||||||
[[!tag projects/openneuro]]
|
[[!tag projects/openneuro]]
|
||||||
|
|
||||||
|
> [[done]] --[[Joey]]
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 2"""
|
||||||
|
date="2025-05-28T18:11:34Z"
|
||||||
|
content="""
|
||||||
|
I went ahead and implemented `git-annx map --json`.
|
||||||
|
|
||||||
|
Example output, after being passed through `jq` to pretty-print it:
|
||||||
|
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"name": "joey@darkstar:~/tmp/mapbench/a",
|
||||||
|
"remotes": [
|
||||||
|
{
|
||||||
|
"name": "joey@darkstar:~/tmp/mapbench/b",
|
||||||
|
"url": "/home/joey/tmp/mapbench/b",
|
||||||
|
"uuid": "645d92d8-6461-43c1-b23c-6dd04dc3a015"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "/home/joey/tmp/mapbench/a",
|
||||||
|
"uuid": "3f34e4c2-dd19-433a-ab04-9fd4be959325"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "joey@darkstar:~/tmp/mapbench/b",
|
||||||
|
"remotes": [
|
||||||
|
{
|
||||||
|
"name": "joey@darkstar:~/tmp/mapbench/a",
|
||||||
|
"url": "/home/joey/tmp/mapbench/a",
|
||||||
|
"uuid": "3f34e4c2-dd19-433a-ab04-9fd4be959325"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": "/home/joey/tmp/mapbench/b",
|
||||||
|
"uuid": "645d92d8-6461-43c1-b23c-6dd04dc3a015"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unknown",
|
||||||
|
"remotes": [
|
||||||
|
{
|
||||||
|
"name": "joey@darkstar:~/tmp/mapbench/b",
|
||||||
|
"url": "/home/joey/tmp/mapbench/b",
|
||||||
|
"uuid": "645d92d8-6461-43c1-b23c-6dd04dc3a015"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": ".",
|
||||||
|
"uuid": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"error-messages": []
|
||||||
|
}
|
||||||
|
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue