Skip to content

Instantly share code, notes, and snippets.

@ooesili
Created April 30, 2014 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ooesili/72969c1dda374479946c to your computer and use it in GitHub Desktop.
Save ooesili/72969c1dda374479946c to your computer and use it in GitHub Desktop.
What Arch packages are installed?
import System.Process
import Data.List
type Package = String
type Group = String
type GroupSpec = (Group, [Package])
main :: IO ()
main = do
---- get data from pacman
groupList <- pacman "-Qg"
explicit <- pacman "-Qqe"
---- format data
let groupSpecs = collectGroups $ pairWords groupList
ungrouped = filterUngrouped groupSpecs explicit
---- output data
-- explicitly installed, and ungrouped
putStrLn "----- EXPLICIT -----"
mapM_ putStrLn ungrouped
putStrLn ""
-- installed group and their packages
putStrLn "----- GROUPS -----"
mapM_ (putStr . showGroupSpec) groupSpecs
-- converts a groupSpec into a string
showGroupSpec :: GroupSpec -> String
showGroupSpec (grp, pkgs) = unlines $ (grp ++ ":") : indentedPkgs
where indentedPkgs = map (" "++) pkgs
-- run the pacman command with the given args
pacman :: String -> IO [String]
pacman args = fmap lines $ readProcess "pacman" (words args) ""
-- split a list of strings into words pairs
pairWords :: [String] -> [(Group, Package)]
pairWords = map go
where go line = let [x, y] = words line in (x, y)
-- group tuples by their first element
collectGroups :: [(Group, Package)] -> [GroupSpec]
collectGroups = foldl go []
where go [] (grp, pkg) = [(grp, [pkg])]
go (a@(agrp, apkgs):as) pair@(grp, pkg) =
if agrp == grp then (agrp, pkg:apkgs) : as
else a : go as pair
-- filter packages not in any groups
filterUngrouped :: [GroupSpec] -> [Package] -> [Package]
filterUngrouped gss ps = ps \\ grouped
where grouped = concatMap snd gss
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment