Last active
January 2, 2016 09:34
-
-
Save Garciat/69a84718f6765dc8ff7a to your computer and use it in GitHub Desktop.
pacman packages by date
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
import std.process; | |
import std.string; | |
import std.range; | |
import std.algorithm; | |
import std.typecons; | |
import core.sys.posix.time; | |
bool notNullOrEmpty(T)(T s) | |
{ | |
return s != null || !s.empty; | |
} | |
bool notNull(T)(T s) | |
{ | |
return s != null; | |
} | |
auto dict(alias kf, alias vf, T)(T items) | |
{ | |
alias TK = typeof(kf(items.front)); | |
alias TV = typeof(vf(items.front)); | |
TV[TK] result; | |
foreach (item; items) | |
{ | |
result[kf(item)] = vf(item); | |
} | |
return result; | |
} | |
string[string][] getPacmanPackages() | |
{ | |
struct Property | |
{ | |
string key, value; | |
} | |
auto parseProperty(string line) | |
{ | |
auto ix = line.indexOf(':'); | |
if (ix == -1) return null; | |
auto k = line[0..ix].strip; | |
auto v = line[ix+1..$].strip; | |
return new Property(k, v); | |
} | |
auto parsePackage(string lines) | |
{ | |
return | |
lines | |
.splitter('\n') | |
.map!parseProperty | |
.filter!notNull | |
.dict!(x => x.key, x => x.value); | |
} | |
return | |
["pacman", "-Qi"] | |
.execute | |
.output | |
.splitter("\n\n") | |
.filter!notNullOrEmpty | |
.map!parsePackage | |
.array; | |
} | |
auto fmtDateTime(string s) | |
{ | |
tm time; | |
strptime(s.ptr, "%a %d %b %Y %I:%M:%S %p %Z", &time); | |
char buf[30]; | |
auto len = strftime(buf.ptr, buf.length, "%Y-%m-%dT%H:%M:%S%Z", &time); | |
auto fmt = buf[0..len].idup; | |
return fmt; | |
} | |
void main() | |
{ | |
auto pks = getPacmanPackages(); | |
foreach (pk; pks) | |
{ | |
writeln(pk["Install Date"].fmtDateTime, ' ', pk["Name"], ' ', pk["Version"]); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Data.Maybe | |
import Data.List | |
import Data.List.Split | |
import System.Process | |
import Data.Time.Parse | |
import Data.Time.LocalTime | |
import Data.Time.ISO8601 | |
import qualified Data.Text as T | |
---------------- | |
coalesce :: (a -> a -> Maybe a) -> [a] -> [a] | |
coalesce f x = | |
case x of | |
(p:q:x') -> | |
case f p q of | |
Nothing -> p : coalesce f (q : x') | |
Just r -> coalesce f (r : x') | |
_ -> x | |
fromRight :: Either a b -> b | |
fromRight (Right x) = x | |
strip :: String -> String | |
strip = T.unpack . T.strip . T.pack | |
---------------- | |
type Entry = (String, String) | |
type Package = [Entry] | |
pacmanQueryInfoRaw :: IO String | |
pacmanQueryInfoRaw = readProcess "pacman" ["-Qi"] [] | |
pacmanQueryInfo :: IO [Package] | |
pacmanQueryInfo = parsePackageList <$> pacmanQueryInfoRaw | |
parsePackageList :: String -> [Package] | |
parsePackageList input = map parsePackage blocks | |
where | |
blocks = endBy "\n\n" input | |
parsePackage :: String -> Package | |
parsePackage input = map fromRight $ coalesce joiner entries | |
where | |
inputLines = lines input | |
entries = map parsePackageEntry inputLines | |
joiner (Right (title, value)) (Left value') = Just $ Right (title, value ++ " " ++ value') | |
joiner _ _ = Nothing | |
parsePackageEntry :: String -> Either String Entry | |
parsePackageEntry input = | |
case break (== ':') input of | |
(value, []) -> Left $ strip value | |
(title, (_:value)) -> Right (strip title, strip value) | |
packageEntryValue :: String -> Package -> String | |
packageEntryValue key = fromJust . lookup key | |
packageName :: Package -> String | |
packageName = packageEntryValue "Name" | |
packageVersion :: Package -> String | |
packageVersion = packageEntryValue "Version" | |
packageInstallDate :: Package -> String | |
packageInstallDate = formatPackageDate . packageEntryValue "Install Date" | |
formatPackageDate :: String -> String | |
formatPackageDate input = formatISO8601 $ localTimeToUTC utc time | |
where | |
Just (time, _) = strptime "%a %d %b %Y %I:%M:%S %p" input | |
formatPackage :: Package -> String | |
formatPackage package = intercalate " " [installDate, name, version] | |
where | |
name = packageName package | |
version = packageVersion package | |
installDate = packageInstallDate package | |
main = do { packages <- pacmanQueryInfo | |
; putStrLn $ unlines $ map formatPackage packages | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment