Set up Travis CI builds against GHC 7.6.3, 7.8.4, and 7.10.1

This commit is contained in:
Matvey Aksenov 2015-04-03 21:15:43 +00:00
parent ab79efd94c
commit ebccd8628f
11 changed files with 76 additions and 40 deletions

35
.travis.yml Normal file
View File

@ -0,0 +1,35 @@
env:
- CABALVER=1.18 GHCVER=7.6.3
- CABALVER=1.18 GHCVER=7.8.4
- CABALVER=1.22 GHCVER=7.10.1
before_install:
- travis_retry sudo add-apt-repository -y ppa:hvr/ghc
- travis_retry sudo apt-get update
- travis_retry sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER npm
- export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$PATH
install:
- cabal --version
- echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
- travis_retry cabal update
- cabal install --only-dependencies --enable-tests --enable-benchmarks
- npm install ldapjs
script:
- cabal configure --enable-tests -v2
- cabal build
- cabal test
- |
if [ $GHCVER = "7.10.1" ]; then
cabal check
fi
- cabal sdist
- export SRC_TGZ=$(cabal info . | awk '{print $2 ".tar.gz";exit}') ;
cd dist/;
if [ -f "$SRC_TGZ" ]; then
cabal install --force-reinstalls "$SRC_TGZ";
else
echo "expected '$SRC_TGZ' not found";
exit 1;
fi

View File

@ -2,6 +2,7 @@
ldap-client ldap-client
=========== ===========
[![Build Status](https://travis-ci.org/supki/ldap-client.svg?branch=master)](https://travis-ci.org/supki/ldap-client)
This library implements (the parts of) [RFC 4511][rfc4511] This library implements (the parts of) [RFC 4511][rfc4511]
@ -22,24 +23,8 @@ IntermediateResponse Message | 4.13 | ✘
StartTLS Operation | 4.14 | ✔† StartTLS Operation | 4.14 | ✔†
LDAP over TLS | - | ✔ LDAP over TLS | - | ✔
\*: approximate and extensible matches are untested, so probably do not work \* Approximate and extensible matches are untested, so probably do not work
†: only serves as an example of Extended Operation, meaning that it does not change † Only serves as an example of Extended Operation. It's useless for all practical purposes as it does not actually enable TLS. In other words, use LDAP over TLS instead.
connection's state on success, so it's useless for all practical purposes.
In other words, use LDAP over TLS instead.
```
% git grep '\bString\b' | wc -l
2
```
Testing
-------
```shell
% sudo apt-get install npm
% npm install ldapjs
% cabal test
```
[rfc4511]: https://tools.ietf.org/html/rfc4511 [rfc4511]: https://tools.ietf.org/html/rfc4511
[LDAP]: https://hackage.haskell.org/package/LDAP [LDAP]: https://hackage.haskell.org/package/LDAP

View File

@ -33,6 +33,7 @@ library
Ldap.Client.Bind Ldap.Client.Bind
Ldap.Client.Compare Ldap.Client.Compare
Ldap.Client.Delete Ldap.Client.Delete
Ldap.Client.Extended
Ldap.Client.Internal Ldap.Client.Internal
Ldap.Client.Modify Ldap.Client.Modify
Ldap.Client.Search Ldap.Client.Search
@ -40,7 +41,7 @@ library
asn1-encoding >= 0.9 asn1-encoding >= 0.9
, asn1-types >= 0.3 , asn1-types >= 0.3
, async , async
, base >= 4.7 && < 5 , base >= 4.6 && < 5
, bytestring , bytestring
, connection >= 0.2 , connection >= 0.2
, containers , containers
@ -59,17 +60,18 @@ test-suite spec
main-is: main-is:
Spec.hs Spec.hs
other-modules: other-modules:
Ldap.Client
Ldap.Client.AddSpec Ldap.Client.AddSpec
Ldap.Client.BindSpec Ldap.Client.BindSpec
Ldap.Client.CompareSpec Ldap.Client.CompareSpec
Ldap.Client.DeleteSpec Ldap.Client.DeleteSpec
Ldap.Client.InternalSpec Ldap.Client.ExtendedSpec
Ldap.Client.ModifySpec Ldap.Client.ModifySpec
Ldap.Client.SearchSpec Ldap.Client.SearchSpec
SpecHelper SpecHelper
build-depends: build-depends:
base >= 4.7 && < 5 base >= 4.6 && < 5
, bytestring
, hspec , hspec
, ldap-client , ldap-client
, process , process
, semigroups

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
module Ldap.Asn1.FromAsn1 module Ldap.Asn1.FromAsn1
( FromAsn1(..) ( FromAsn1(..)
, Parser , Parser
@ -6,7 +7,11 @@ module Ldap.Asn1.FromAsn1
, next , next
) where ) where
#if __GLASGOW_HASKELL__ >= 710
import Control.Applicative (Alternative(..), liftA2, optional) import Control.Applicative (Alternative(..), liftA2, optional)
#else
import Control.Applicative (Applicative(..), Alternative(..), liftA2, optional)
#endif
import Control.Monad (MonadPlus(..), (>=>), guard) import Control.Monad (MonadPlus(..), (>=>), guard)
import Data.ASN1.Types (ASN1) import Data.ASN1.Types (ASN1)
import qualified Data.ASN1.Types as Asn1 import qualified Data.ASN1.Types as Asn1

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE BangPatterns #-} {-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NamedFieldPuns #-}
@ -44,6 +45,9 @@ module Ldap.Client
, waitSTM , waitSTM
) where ) where
#if __GLASGOW_HASKELL__ < 710
import Control.Applicative ((<$>))
#endif
import qualified Control.Concurrent.Async as Async import qualified Control.Concurrent.Async as Async
import Control.Concurrent.STM (atomically) import Control.Concurrent.STM (atomically)
import Control.Concurrent.STM.TMVar (putTMVar) import Control.Concurrent.STM.TMVar (putTMVar)

View File

@ -32,6 +32,7 @@ import Control.Exception (Exception, throwIO)
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.List.NonEmpty (NonEmpty) import Data.List.NonEmpty (NonEmpty)
import Data.Text (Text) import Data.Text (Text)
import Data.Typeable (Typeable)
import Network (PortNumber) import Network (PortNumber)
import qualified Ldap.Asn1.Type as Type import qualified Ldap.Asn1.Type as Type
@ -71,7 +72,7 @@ newtype Password = Password ByteString
data ResponseError = data ResponseError =
ResponseInvalid Request Response ResponseInvalid Request Response
| ResponseErrorCode Request Type.ResultCode Dn Text | ResponseErrorCode Request Type.ResultCode Dn Text
deriving (Show, Eq) deriving (Show, Eq, Typeable)
instance Exception ResponseError instance Exception ResponseError

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NamedFieldPuns #-}
module Ldap.Client.Search module Ldap.Client.Search
( search ( search
@ -21,7 +22,11 @@ import Data.Int (Int32)
import Data.List.NonEmpty (NonEmpty((:|))) import Data.List.NonEmpty (NonEmpty((:|)))
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (mapMaybe) import Data.Maybe (mapMaybe)
#if __GLASGOW_HASKELL__ >= 710
import Data.Semigroup (Semigroup(..)) import Data.Semigroup (Semigroup(..))
#else
import Data.Semigroup (Semigroup(..), Monoid(..))
#endif
import qualified Ldap.Asn1.Type as Type import qualified Ldap.Asn1.Type as Type
import Ldap.Client.Internal import Ldap.Client.Internal

View File

@ -1,7 +1,7 @@
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module Ldap.Client.AddSpec (spec) where module Ldap.Client.AddSpec (spec) where
import qualified Data.List.NonEmpty as NonEmpty
import Data.Monoid ((<>)) import Data.Monoid ((<>))
import Test.Hspec import Test.Hspec
@ -21,9 +21,9 @@ spec = do
it "adds an entry" $ do it "adds an entry" $ do
res <- locally $ \l -> do res <- locally $ \l -> do
Ldap.add l vulpix Ldap.add l vulpix
[ (Attr "cn", ["vulpix"]) [ (Attr "cn", (NonEmpty.fromList ["vulpix"]))
, (Attr "evolution", ["0"]) , (Attr "evolution", (NonEmpty.fromList ["0"]))
, (Attr "type", ["fire"]) , (Attr "type", (NonEmpty.fromList ["fire"]))
] ]
res <- go l (Attr "cn" := "vulpix") res <- go l (Attr "cn" := "vulpix")
dns res `shouldBe` [vulpix] dns res `shouldBe` [vulpix]

View File

@ -1,4 +1,3 @@
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module Ldap.Client.DeleteSpec (spec) where module Ldap.Client.DeleteSpec (spec) where

View File

@ -1,7 +1,7 @@
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
module Ldap.Client.SearchSpec (spec) where module Ldap.Client.SearchSpec (spec) where
import qualified Data.List.NonEmpty as NonEmpty
import Data.Monoid ((<>)) import Data.Monoid ((<>))
import Test.Hspec import Test.Hspec
import Ldap.Client as Ldap import Ldap.Client as Ldap
@ -70,17 +70,17 @@ spec = do
it "and filter" $ do it "and filter" $ do
res <- locally $ \l -> do res <- locally $ \l -> do
res <- go l (And [ Attr "type" := "fire" res <- go l (And (NonEmpty.fromList [ Attr "type" := "fire"
, Attr "evolution" := "1" , Attr "evolution" := "1"
]) ]))
dns res `shouldBe` [charmeleon] dns res `shouldBe` [charmeleon]
res `shouldBe` Right () res `shouldBe` Right ()
it "or filter" $ do it "or filter" $ do
res <- locally $ \l -> do res <- locally $ \l -> do
res <- go l (Or [ Attr "type" := "fire" res <- go l (Or (NonEmpty.fromList [ Attr "type" := "fire"
, Attr "evolution" := "1" , Attr "evolution" := "1"
]) ]))
dns res `shouldMatchList` dns res `shouldMatchList`
[ ivysaur [ ivysaur
, charizard , charizard
@ -116,9 +116,9 @@ spec = do
it "not filter" $ do it "not filter" $ do
res <- locally $ \l -> do res <- locally $ \l -> do
res <- go l (Not (Or [ Attr "type" := "fire" res <- go l (Not (Or (NonEmpty.fromList [ Attr "type" := "fire"
, Attr "evolution" :>= "1" , Attr "evolution" :>= "1"
])) ])))
dns res `shouldMatchList` dns res `shouldMatchList`
[ bulbasaur [ bulbasaur
, squirtle , squirtle

View File

@ -1,4 +1,4 @@
#!/usr/bin/env nodejs #!/usr/bin/env js
var fs = require('fs'); var fs = require('fs');
var ldapjs = require('ldapjs'); var ldapjs = require('ldapjs');
@ -183,6 +183,6 @@ server.compare('o=localhost', [], function(req, res, next) {
return next(new ldapjs.NoSuchObjectError(req.dn.toString())); return next(new ldapjs.NoSuchObjectError(req.dn.toString()));
}); });
server.listen(port, function() { server.listen(port, '0.0.0.0', function() {
console.log("ldaps://localhost:%d", port); console.log("ldaps://localhost:%d", port);
}); });