packages feed

porte (empty) → 0.0.2

raw patch · 7 files changed

+293/−0 lines, 7 filesdep +basedep +bytestringdep +containerssetup-changed

Dependencies added: base, bytestring, containers, stringsearch

Files

+ LICENSE view
@@ -0,0 +1,23 @@+Copyright (C) 2008 Samy Al Bahra+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:+ 1. Redistributions of source code must retain the above copyright+    notice, this list of conditions and the following disclaimer.+ 2. Redistributions in binary form must reproduce the above copyright+    notice, this list of conditions and the following disclaimer in the+    documentation and/or other materials provided with the distribution.++ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ SUCH DAMAGE.
+ Porte/Ports.hs view
@@ -0,0 +1,144 @@+module Porte.Ports where+import Control.Exception+import Control.Monad+import Data.ByteString.Search.KnuthMorrisPratt+import qualified Data.ByteString.Lazy.Char8     as B+import qualified Data.ByteString.Char8          as C +import qualified Data.List                      as L+import qualified System.IO                      as I+import qualified System.Environment             as E++portsIndex = "/usr/ports/INDEX-8"+portsPrefix = "/usr/ports/"++type Name = B.ByteString+type DistributionName = B.ByteString +type Path = B.ByteString+type Prefix = B.ByteString+type Comment = B.ByteString+type DescriptionPath = B.ByteString+type PortDescription = Maybe B.ByteString+type Maintainer = B.ByteString+type Categories = [B.ByteString]+type ExtractDepends = [B.ByteString]+type PatchDepends = [B.ByteString]+type FetchDepends = [B.ByteString]+type BuildDepends = [B.ByteString]+type RunDepends = [B.ByteString]+type Website = B.ByteString++data Port = Port {+              name :: Name,+              distributionName :: DistributionName,+              path :: Path,+              comment :: Comment,+              descriptionPath :: DescriptionPath,+              maintainer :: Maintainer,+              categories :: Categories,+              buildDepends :: BuildDepends,+              website :: Website,+              extractDepends :: ExtractDepends+            } deriving (Eq, Show, Read)++type PortField = Port -> B.ByteString+type PortQuery = [(PortField, String)]++toField :: String -> Maybe PortField+toField "name" = Just name+toField "package" = Just distributionName+toField "distributionName" = Just distributionName+toField "path" = Just path+toField "comment" = Just comment+toField "category" = Just category+toField "maintainer" = Just maintainer+toField "website" = Just website+toField _ = Nothing++search :: PortQuery -> [Port] -> [Port]+search (x:xs) p =+  search xs $ filter f p+  where+  f p = case (matchSL (C.pack $ snd x) (fst x p)) of+          [] -> False+          _  -> True +search _ p = p++find :: PortQuery -> [Port] -> [Port]+find (x:xs) p = find xs $ filter f p+                where+                f p = (B.pack $ snd x) == (fst x p)+find _ p = p++description :: Port -> IO (Maybe B.ByteString)+description p =+  do+  o <- try $ (B.readFile . B.unpack . descriptionPath) p+  case (o) of+    Left h  -> return Nothing +    Right h -> return $ Just $ B.filter (/= '\n') h++glue :: (Port -> [B.ByteString]) -> Port -> B.ByteString+glue f p = B.concat $ L.intersperse (B.pack " ") (f p) +category = glue categories +buildDepend = glue buildDepends+extractDepend = glue extractDepends++parseEntry :: B.ByteString -> Port+parseEntry =+  parseEntry' . B.split '|' +  where+  parseEntry' +     (name           :+      path           :+      prefix         : +      comment        :+      pkgDescr       :+      maintainer     :+      categories     :+      buildDepends   :+      runDepends     :+      website        :+      extractDepends : _) =+        Port (B.tail . B.dropWhile (/= '/') $ path')+             (name)+             (path')+             (comment)+             (pkgDescr)+             (maintainer)+             (B.words categories)+             (B.words buildDepends)+             (website)+             (B.words extractDepends)+             where+             path' = B.drop (B.length $ B.pack portsPrefix) $ path++parseIndex :: B.ByteString -> [Port]+parseIndex = map parseEntry . B.lines++index :: (Maybe String) -> IO [Port]+index (Just []) = index (Just portsIndex)+index Nothing = do+ o <- try $ E.getEnv "INDEX"+ case o of+   Right h -> index $ Just h+   _       -> index $ Just portsIndex+index (Just path) = do+  o <- try $ B.readFile path+  case o of+    Left h -> error $ "INDEX file (" ++ path ++ ") could not be opened"+    Right h -> return $ parseIndex h ++putPorts :: [PortField] -> [Port] -> IO ()+putPorts f = hPutPorts I.stdout f++hPutPorts :: I.Handle -> [PortField] -> [Port] -> IO ()+hPutPorts h f p = forM_ p (hPutPort h f)++putPort :: [PortField] -> Port -> IO ()+putPort f = hPutPort I.stdout f++hPutPort :: I.Handle -> [PortField] -> Port -> IO ()+hPutPort h [f] p = B.hPut h (f p) >> I.hPutChar h '\n' +hPutPort h (f:fs) p = B.hPut h (f p) >> I.hPutStr h ", " >> hPutPort h fs p  +hPutPort h _ p = I.hPutChar h '\n' +
+ Porte/Statistics.hs view
@@ -0,0 +1,19 @@+module Porte.Statistics where+import qualified Data.ByteString.Lazy.Char8 as B+import qualified Porte.Ports                as P+import qualified Data.Map                   as M +import qualified System.IO                  as I+import Text.Printf(printf)++type FrequencyMap = M.Map B.ByteString Int+type FieldFrequency = (B.ByteString, Int) ++mapFrequency :: [B.ByteString] -> FrequencyMap +mapFrequency (x:xs) = M.insertWith' (+) x 1 $ mapFrequency xs+mapFrequency _ = M.empty++fieldsFrequency f r = M.assocs $ mapFrequency (concat $ map f r)+fieldFrequency f r = M.assocs $ mapFrequency (map f r)++printFrequency :: FieldFrequency -> IO ()+printFrequency (a, b) = I.putStr (printf "%5d " b) >> B.putStrLn a 
+ Porte/Tool.hs view
@@ -0,0 +1,84 @@+module Porte.Tool(toolMain) where+import System.Environment+import System.Exit+import Control.Monad+import qualified Data.ByteString.Lazy.Char8 as B+import qualified Porte.Ports      as P+import qualified Porte.Statistics as S+import qualified System.IO        as I++version = "0.0.2"++-- Generic port print format+printFormat = [P.path, P.comment, P.website]++-- Exception raising toField+toField :: String -> P.PortField+toField f =+  case (P.toField f) of+    Nothing -> error $ "Unknown field: " ++ f+    Just f  -> f++-- Statistics mode+doStatistics :: [String] -> IO ()+doStatistics (a:m:_) =+  case a of+    "frequency" ->  case m of+                      "categories"      -> doOutput $ S.fieldsFrequency P.categories +                      "buildDepends"    -> doOutput $ S.fieldsFrequency P.buildDepends+                      "extractDepends"  -> doOutput $ S.fieldsFrequency P.extractDepends+                      _                 -> doOutput $ S.fieldFrequency (toField m) +    _           -> error $ "Unknown statistics mode"+   where+   doOutput f = P.index Nothing >>= flip forM_ S.printFrequency . f +doStatistics _ = toolUsage >> die++-- List all available ports in INDEX+doIndex :: IO ()+doIndex =+  P.index Nothing >>= P.putPorts printFormat ++-- Build port query from user input+parseSearch :: [String] -> P.PortQuery+parseSearch q =+  build [] q+  where+  build p (f:q:qs) = build ((toField f, q) : p) qs +  build p (_:[]) = error "Parse error"+  build p _ = p ++-- Generic search action+genericSearch :: (P.PortQuery -> [P.Port] -> [P.Port]) -> [String] -> IO ()+genericSearch f [] = exit+genericSearch f q = do+  ports <- P.index Nothing+  P.putPorts printFormat $ (f . parseSearch) q ports++doSearch q = genericSearch P.search q +doFind q = genericSearch P.find q ++die = exitWith (ExitFailure 1)+exit = exitWith (ExitSuccess)++hToolUsage :: I.Handle -> IO ()+hToolUsage h = I.hPutStrLn h "Usage: porte [-hvlsfS]" ++toolUsage = hToolUsage I.stderr++printVersion :: IO ()+printVersion = I.putStrLn $ "Porte.Tool " ++ version++toolMain = do+  argv <- getArgs+  case (null argv) of +    True -> toolUsage >> die+    _    -> case (head argv) of+              "-h" -> hToolUsage I.stdout+              "-v" -> printVersion+              "-l" -> doIndex+              "-s" -> doSearch $ tail argv+              "-f" -> doFind $ tail argv+              "-S" -> doStatistics $ tail argv+              _    -> toolUsage >> die ++ 
+ Porte/porte.hs view
@@ -0,0 +1,3 @@+import Porte.Tool ++main = toolMain 
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ porte.cabal view
@@ -0,0 +1,18 @@+Name:                porte+Version:             0.0.2+Cabal-Version:       >= 1.2+Synopsis:            FreeBSD ports interface+Description:         Haskell FreeBSD ports analysis library+Category:            System+License:             BSD3+License-file:        LICENSE+Author:              Samy Al Bahra+Maintainer:          sbahra@kerneled.org+Build-Type:          Simple++Library+  Build-Depends:       base, bytestring, containers, stringsearch+  Exposed-Modules:     Porte.Tool Porte.Statistics Porte.Ports++Executable porte+  Main-is:             Porte/porte.hs