0 | module Pack.Runner.Query
2 | import Core.Name.Namespace
6 | import Data.SortedMap
7 | import Idris.Package.Types
8 | import Pack.CmdLn.Types
11 | import Pack.Database
12 | import Pack.Database.Tree
13 | import Pack.Runner.Database
14 | import Pack.Runner.Install
24 | record AppInfo (p : Package) where
27 | status : AppStatus p
33 | app : Maybe (AppInfo lib.pkg)
36 | name : QPkg -> PkgName
40 | nameStr : QPkg -> String
41 | nameStr = value . name
44 | dependencies : QPkg -> List PkgName
45 | dependencies = dependencies . lib
48 | isApp : QPkg -> Bool
49 | isApp (QP _ a) = isJust a
52 | installedLib : QPkg -> Bool
53 | installedLib qp = case qp.lib.status of
54 | Installed _ _ => True
58 | installedApp : QPkg -> Bool
59 | installedApp qp = case map status qp.app of
60 | Just (Installed _) => True
61 | Just (BinInstalled _) => True
62 | Just (Missing _) => False
66 | resolve : HasIO io => Env => PkgName -> EitherT PackErr io QPkg
69 | Just exe <- pure (exec lib.desc) | Nothing => pure (QP lib Nothing)
70 | st <- appStatus n lib.hash lib.pkg exe
71 | pure $
QP lib (Just $
AI exe st)
73 | pkgNames : (e : Env) => List PkgName
74 | pkgNames = keys e.all
80 | -> EitherT PackErr io (SortedMap PkgName (ResolvedLib U), List QPkg)
82 | ps <- traverse resolve pkgNames
83 | sm <- readIORef env.cache
91 | hashLookup : PkgName -> SortedMap PkgName (ResolvedLib U) -> Hash
92 | hashLookup x = maybe (MkHash "") hash . lookup x
98 | -> (q : Hash -> (parents,children : Tree PkgName) -> QPkg -> Maybe b)
99 | -> EitherT PackErr io (List b)
101 | (sm,ps) <- resolveAll
103 | let children := childMap sm
105 | parents := parentMap sm
109 | (\p => let n := name p in q (hashLookup n sm) (treeLookup n parents) (treeLookup n children) p)
112 | shortDesc : QPkg -> Maybe String
113 | shortDesc q = q.lib.desc.desc.brief
115 | modules : QPkg -> List String
116 | modules = map (show . fst) . modules . desc . desc . lib
118 | prettyDeps : QPkg -> List String
119 | prettyDeps qp = case dependencies qp of
120 | [] => ["Dependencies :"]
121 | h :: t => "Dependencies : \{h}" :: map (indent 15 . interpolate) t
123 | prettyModules : String -> QPkg -> List String
124 | prettyModules s qp = case filter (isInfixOf s) (modules qp) of
125 | [] => ["Modules :"]
126 | h :: t => "Modules : \{h}" :: map (indent 10) t
128 | status : PkgStatus p -> String
129 | status (Missing _) = "not installed"
130 | status (Installed _ _) = "installed"
132 | status' : AppStatus p -> String
133 | status' (Missing h) = "not installed"
134 | status' (Installed h) = "installed"
135 | status' (BinInstalled h) = "installed and on $PATH"
137 | libStatus : QPkg -> List String
138 | libStatus q = [ "Library : \{status q.lib.status}" ]
140 | appStatus : QPkg -> List String
141 | appStatus qp = case qp.app of
143 | Just (AI exe st) =>
144 | [ "Executable : \{exe}"
145 | , "App : \{status' st}"
148 | testFile : Maybe (File Rel) -> Maybe String
149 | testFile = map (\f => "Test File : \{f}")
151 | notice : Maybe String -> Maybe String
152 | notice = map (\f => "Notice : \{f}")
154 | details : Hash -> QPkg -> List String
155 | details hash qp = case qp.lib.pkg of
156 | Git url commit ipkg _ t n => [
157 | "Type : Git project"
159 | , "Commit : \{commit}"
160 | , "Install hash : \{hash}"
161 | , "ipkg File : \{ipkg}"
162 | ] ++ (catMaybes [testFile t, notice n])
165 | let ipkg := toAbsFile d i
166 | in [ "Type : Local Idris project"
167 | , "Location : \{ipkg.parent}"
168 | , "Install hash : \{hash}"
169 | , "ipkg File : \{ipkg.file}"
170 | ] ++ (catMaybes [testFile t])
173 | "Type : Idris core package"
176 | namePlusModules : String -> QPkg -> String
177 | namePlusModules n qp =
178 | unlines $
nameStr qp :: map (indent 2) (prettyModules n qp)
180 | keep : QueryMode -> String -> QPkg -> Bool
181 | keep PkgName q p = isInfixOf q (nameStr p)
182 | keep Dependency q p = any ((q ==) . value) (dependencies p)
183 | keep Module q p = any (isInfixOf q . show . fst) (modules p.lib.desc.desc)
188 | -> (query : String)
191 | -> (parents, children : Tree PkgName)
194 | resultString q Module h _ _ qp = namePlusModules q qp
195 | resultString _ _ h ps cs qp = case e.config.queryType of
196 | NameOnly => nameStr qp
199 | let Just d := shortDesc qp | Nothing => nameStr qp
200 | in "\{name qp}\n \{d}\n"
203 | let ds@(_ :: _) := dependencies qp | [] => nameStr qp
204 | in unlines $
nameStr qp :: map (indent 2 . interpolate) ds
206 | Details => unlines . (nameStr qp ::) . map (indent 2) $
concat [
207 | toList (("Brief : " ++) <$> shortDesc qp)
214 | Ipkg => unlines $
nameStr qp :: map (indent 2) (lines qp.lib.desc.cont)
216 | Tree => case filter ("base" /=) cs of
217 | Just tr' => prettyTree False tr'
218 | Nothing => prettyTree False cs
220 | ReverseTree => case filter ("base" /=) ps of
221 | Just tr' => prettyTree True tr'
222 | Nothing => prettyTree True ps
226 | {auto _ : HasIO io}
230 | -> EitherT PackErr io ()
232 | ss <- query_ $
\h,ps,cs,p => toMaybe (keep m n p) (resultString n m h ps cs p)
233 | putStrLn $
unlines ss
239 | instLib : QPkg -> Maybe String
240 | instLib qp = case qp.lib.status of
241 | Installed _ _ => Just "\{qp.lib.name}"
242 | Missing _ => Nothing
244 | instApp : QPkg -> Maybe String
245 | instApp (QP lib $
Just (AI _ st)) = case st of
246 | Installed _ => Just "\{lib.name} (not on $PATH)"
247 | BinInstalled _ => Just "\{lib.name}"
248 | Missing _ => Nothing
249 | instApp _ = Nothing
251 | apps : List QPkg -> String
252 | apps ps = case mapMaybe instApp ps of
254 | x :: xs => unlines $
255 | "\n\nInstalled Apps : \{x}" ::
258 | libs : List QPkg -> String
259 | libs ps = case mapMaybe instLib ps of
261 | x :: xs => unlines $
262 | "\nInstalled Libraries : \{x}" ::
266 | infoString : (e : Env) => List QPkg -> String
267 | infoString ps = """
268 | Package Collection : \{e.config.collection}
269 | Idris2 URL : \{e.db.idrisURL}
270 | Idris2 Version : \{e.db.idrisVersion}
271 | Idris2 Commit : \{e.db.idrisCommit}
272 | Scheme Executable : \{e.config.scheme}
273 | Pack Commit : \{Version.version}
274 | """ ++ apps ps ++ libs ps
277 | printInfo : HasIO io => Env -> EitherT PackErr io ()
278 | printInfo e = resolveAll >>= putStrLn . infoString . snd
286 | {auto _ : HasIO io}
287 | -> {auto _ : IdrisEnv}
289 | -> EitherT PackErr io (List QPkg, List QPkg)
290 | installedPkgs ns = do
291 | all <- filter installedLib . snd <$> resolveAll
292 | pure (all, filter inPkgs all)
293 | where inPkgs : QPkg -> Bool
294 | inPkgs qp = isNil ns || elem (name qp) ns
296 | imports : QPkg -> String
297 | imports = unlines . map ("import " ++) . modules
303 | noOut = "Main> \nMain> \n"
305 | removePre : String -> String
306 | removePre s = case isPrefixOf pre s of
307 | True => pack . drop (length pre) $
unpack s
310 | fuzzyTrim : String -> String
318 | {auto _ : HasIO io}
319 | -> {auto _ : IdrisEnv}
321 | -> (allPkgs : List QPkg)
323 | -> EitherT PackErr io ()
324 | fuzzyPkg q allPkgs qp = do
326 | finally (rmDir tmpDir) $
inDir tmpDir $
\d => do
327 | putStrLn "\{name qp}:\n"
328 | write (MkF d "test.idr") (imports qp)
329 | write (MkF d "input") ":fs \{q}\n"
331 | (cmd,env) <- idrisWithPkgs (map lib allPkgs)
345 | case noOut == str of
347 | False => putStrLn (fuzzyTrim str)
351 | {auto _ : HasIO io}
355 | -> EitherT PackErr io ()
357 | (allPkgs,rps) <- installedPkgs m
358 | traverse_ (fuzzyPkg q allPkgs) rps