packages feed

copr (empty) → 1.0.0

raw patch · 9 files changed

+379/−0 lines, 9 filesdep +aesondep +basedep +bytestringsetup-changed

Dependencies added: aeson, base, bytestring, containers, hlint, http-streams, io-streams, semigroups, text

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2014, Ricky Elrod++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * 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.++    * Neither the name of Ricky Elrod nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT+OWNER 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ copr.cabal view
@@ -0,0 +1,46 @@+name:                copr+version:             1.0.0+synopsis:            Haskell interface to the Fedora Copr system+description:+  This provides a Haskell interface to the Fedora Copr public build system.+homepage:            https://github.com/CodeBlock/copr-hs+license:             BSD3+license-file:        LICENSE+author:              Ricky Elrod+maintainer:          ricky@elrod.me+copyright:           2014 Ricky Elrod+category:            Fedora+build-type:          Simple+cabal-version:       >=1.10++library+  exposed-modules:     Fedora.Copr+                     , Fedora.Copr.CoprBuild+                     , Fedora.Copr.CoprProject+                     , Fedora.Copr.CoprStatus+                     , Fedora.Copr.ListCoprs++  build-depends:       aeson >= 0.6+                     , base >=4.6 && <4.7+                     , bytestring >= 0.10+                     , containers >= 0.5+                     , http-streams >= 0.7+                     , io-streams >= 1.1+                     , semigroups >= 0.12+                     , text >= 0.11+  hs-source-dirs:      src+  default-language:    Haskell2010+  ghc-options:         -Wall++test-suite hlint+  hs-source-dirs:      tests+  main-is:             hlint.hs+  type:                exitcode-stdio-1.0+  default-language:    Haskell2010+  ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N+  build-depends:       base+                     , hlint >= 1.7++source-repository head+  type:     git+  location: git://github.com/CodeBlock/copr-hs.git
+ src/Fedora/Copr.hs view
@@ -0,0 +1,146 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module : Fedora.Copr+-- Copyright : (c) Ricky Elrod 2014+-- License : BSD3+-- Maintainer : ricky@elrod.me+-- Stability : experimental+-- Portability : portable+--+-- Provides a Haskell interface to the Fedora+-- <http://copr.fedoraproject.org/ Copr> build system+-- <http://copr.fedoraproject.org/api API>.++module Fedora.Copr+    (+      module C+    , CoprConfig (..)+    , Username+    , defaultConfig+    , withConfig+    , addBuild+    , buildStatus+    , coprs+    , new+    ) where++import Fedora.Copr.CoprBuild   as C (CoprBuild (), CoprBuildResponse ())+import Fedora.Copr.CoprProject as C (CoprProject (), NewCoprResponse ())+import Fedora.Copr.CoprStatus  as C (CoprStatusResponse ())+import Fedora.Copr.ListCoprs   as C (Coprs ())++import Data.Aeson+import qualified Data.ByteString as S+import qualified Data.ByteString.Char8 as C8+import qualified Data.ByteString.Lazy as LS+import Data.Monoid (mappend)+import Network.Http.Client+import qualified System.IO.Streams.ByteString as SBS++data CoprConfig = CoprConfig {+    domain :: Hostname     -- ^ The domain on which Copr is hosted.+  , port   :: Port         -- ^ The port on which Copr operates.+  , login  :: S.ByteString -- ^ The API login (/not/ the same as username).+  , token  :: S.ByteString -- ^ The API token.+} deriving (Eq, Show)++type Username = S.ByteString+type ProjectName = S.ByteString++defaultConfig :: CoprConfig+defaultConfig = CoprConfig {+    domain = "copr.fedoraproject.org"+  , port = 80+  , login = ""+  , token = ""+}++-- | A utility wrapper for calling API methods with a 'CoprConfig'.+--+--   You can use this to do things like:+--+--   >>> let c = defaultConfig { login = "your_login", token = "your_token" }+--   >>> withConfig c $ coprs "codeblock"+withConfig :: CoprConfig -> (CoprConfig -> IO a) -> IO a+withConfig = flip id++-- | Sets things that are common to all requests that we make.+prepareRequest :: CoprConfig -> Method -> S.ByteString -> RequestBuilder ()+prepareRequest c m url = do+  http m url+  setAccept "application/json"+  setContentType "application/json"+  setAuthorizationBasic (login c) (token c)++finishRequest :: FromJSON a => Connection -> IO a+finishRequest cnx = do+  x <- receiveResponse cnx jsonHandler+  closeConnection cnx+  return x++-- | Perform a GET request to the API, with authentication.+--+--   Requests that don't need authentication result in the authentication+--   details being ignored, so we don't have to worry about not sending them+--   in that case.+apiGet :: FromJSON a => S.ByteString -> CoprConfig -> IO a+apiGet url c = do+  cnx <- openConnection (domain c) (port c)+  q <- buildRequest $ prepareRequest c GET url+  sendRequest cnx q emptyBody+  finishRequest cnx++-- | Perform a POST request to the API, with authentication.+apiPost :: (ToJSON a, FromJSON b) => S.ByteString -> a -> CoprConfig -> IO b+apiPost url d c = do+  cnx <- openConnection (domain c) (port c)+  q <- buildRequest $ do+    prepareRequest c POST url+    setContentLength $ LS.length (encode d)+  body <- SBS.fromLazyByteString (encode d)+  sendRequest cnx q (inputStreamBody body)+  finishRequest cnx++-- | Retrieve a list of copr projects for an individual user.+--+--   This makes use of the @\/api\/coprs/[username]\/@ endpoint.+--+--   > withConfig c $ coprs "codeblock"+coprs :: Username   -- ^ The username of the person whose projects we want to list.+      -> CoprConfig -- ^ The configuration to use.+      -> IO Coprs+coprs u = apiGet ("/api/coprs/" `mappend` u `mappend` "/")++-- | Create a new copr project.+--+--   This makes use of the @\/api\/coprs/[username]\/new\/@ endpoint.+--+--   > withConfig c $ new "codeblock" (CoprProject "testproject" [] [] (NEL.fromList ["fedora-20-x86_64"]))+new :: Username       -- ^ The username of the person whose project should be created.+    -> CoprProject    -- ^ The copr project to be created.+    -> CoprConfig     -- ^ The configuration to use.+    -> IO NewCoprResponse+new u = apiPost ("/api/coprs/" `mappend` u `mappend` "/new/")++-- | Add a build to a copr project.+--+--   This makes use of the @\/api\/coprs/[username]\/[project]\/new_build\/@ endpoint.+--+--   > withConfig c $ addBuild "codeblock" "testproject" (CoprBuild (NEL.fromList ["http://example.com/foo-1.0.0.src.rpm"]) 2048 3600)+addBuild :: Username    -- ^ The username of the person who owns the copr project.+         -> ProjectName -- ^ The project to add the build to.+         -> CoprBuild   -- ^ A representation of the build to add.+         -> CoprConfig  -- ^ The configuration to use.+         -> IO CoprBuildResponse+addBuild u p = apiPost ("/api/coprs/" `mappend` u `mappend` "/" `mappend` p `mappend` "/new_build/")++-- | Check the status of a copr build+--+--   This makes use of the @\/api\/coprs\/build_status/[build_id]\/@ endpoint.+--+--   > withConfig c $ buildStatus 1033+buildStatus :: Int        -- ^ The build ID number to check.+            -> CoprConfig -- ^ The configuration to use.+            -> IO CoprStatusResponse+buildStatus i = apiGet ("/api/coprs/build_status/" `mappend` C8.pack (show i) `mappend` "/")
+ src/Fedora/Copr/CoprBuild.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE OverloadedStrings #-}++module Fedora.Copr.CoprBuild (+    CoprBuild (..)+  , CoprBuildResponse (..)) where++import Control.Applicative+import Control.Monad (mzero)+import Data.Aeson+import qualified Data.ByteString as S+import qualified Data.List.NonEmpty as NEL++data CoprBuildResponse = CoprBuildResponse {+    output  :: String+  , buildId :: Maybe Int+  , message :: Maybe String+  , error   :: Maybe String+} deriving (Eq, Show)++instance FromJSON CoprBuildResponse where+  parseJSON (Object v) = CoprBuildResponse <$>+                             v .:  "output"+                         <*> v .:? "id"+                         <*> v .:? "message"+                         <*> v .:? "error"+  parseJSON _          = mzero++data CoprBuild = CoprBuild {+    packages :: NEL.NonEmpty S.ByteString+  , memory   :: Int+  , timeout  :: Int+} deriving (Eq, Show)++instance ToJSON CoprBuild where+  toJSON (CoprBuild p m t) = object [ "pkgs" .= S.intercalate " " (NEL.toList p)+                                    , "memory" .= m+                                    , "timeout" .= t+                                    ]
+ src/Fedora/Copr/CoprProject.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE OverloadedStrings #-}++module Fedora.Copr.CoprProject (+    CoprProject (..)+  , NewCoprResponse (..)) where++import Control.Applicative+import Control.Monad (mzero)+import Data.Aeson+import qualified Data.ByteString as S+import qualified Data.ByteString.Char8 as C8+import qualified Data.List.NonEmpty as NEL+import qualified Data.Text as T++data NewCoprResponse = NewCoprResponse {+    output  :: String+  , message :: Maybe String+  , error   :: Maybe String+} deriving (Eq, Show)++instance FromJSON NewCoprResponse where+  parseJSON (Object v) = NewCoprResponse <$>+                             v .:  "output"+                         <*> v .:? "message"+                         <*> v .:? "error"+  parseJSON _          = mzero++data CoprProject = CoprProject {+    name            :: S.ByteString+  , repos           :: [S.ByteString]+  , initialPackages :: [S.ByteString]+  , chroots         :: NEL.NonEmpty S.ByteString+  , description     :: Maybe S.ByteString+  , instructions    :: Maybe S.ByteString+} deriving (Eq, Show)++instance ToJSON CoprProject where+  toJSON (CoprProject n r p c d i) = object $ [ "name" .= n+                                          , "repos" .= S.intercalate " " r+                                          , "initial_pkgs" .= S.intercalate " " p+                                          , "description" .= d+                                          , "instructions" .= i+                                          ] ++ map (\x -> T.pack (C8.unpack x) .= C8.pack "y") (NEL.toList c)
+ src/Fedora/Copr/CoprStatus.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE OverloadedStrings #-}++module Fedora.Copr.CoprStatus (+    CoprStatusResponse (..)) where++import Control.Applicative+import Control.Monad (mzero)+import Data.Aeson++data CoprStatusResponse = CoprStatusResponse {+    output :: String+  , status :: Maybe String+  , error  :: Maybe String+} deriving (Eq, Show)++instance FromJSON CoprStatusResponse where+  parseJSON (Object v) = CoprStatusResponse <$>+                             v .:  "output"+                         <*> v .:? "status"+                         <*> v .:? "error"+  parseJSON _          = mzero
+ src/Fedora/Copr/ListCoprs.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE OverloadedStrings #-}++module Fedora.Copr.ListCoprs (+    Coprs (..)+  , Repo (..)) where++import Control.Applicative+import Control.Monad (mzero)+import Data.Aeson+import qualified Data.ByteString as S+import Data.Map (Map)++data Coprs = Coprs {+    output :: String+  , repos  :: Maybe [Repo]+  , error  :: Maybe String+} deriving (Eq, Show)++data Repo = Repo {+    yumRepos        :: Map S.ByteString S.ByteString+  , additionalRepos :: S.ByteString+  , instructions    :: S.ByteString+  , name            :: S.ByteString+  , description     :: S.ByteString+} deriving (Eq, Show)++instance FromJSON Repo where+  parseJSON (Object v) = Repo <$>+                             v .: "yum_repos"+                         <*> v .: "additional_repos"+                         <*> v .: "instructions"+                         <*> v .: "name"+                         <*> v .: "description"+  parseJSON _          = mzero++instance FromJSON Coprs where+  parseJSON (Object v) = Coprs <$>+                             v .: "output"+                         <*> v .:? "repos"+                         <*> v .:? "error"+  parseJSON _          = mzero
+ tests/hlint.hs view
@@ -0,0 +1,12 @@+module Main where++import Control.Monad+import Language.Haskell.HLint+import System.Environment+import System.Exit++main :: IO ()+main = do+  args <- getArgs+  hints <- hlint $ ["src", "--cpp-define=HLINT", "--cpp-ansi"] ++ args+  unless (null hints) exitFailure