From 9e665dc72cd3230502340154173f22096895bd5f Mon Sep 17 00:00:00 2001
From: Jaseem Abid <jaseemabid@gmail.com>
Date: Sat, 21 Mar 2015 19:32:57 +0530
Subject: [PATCH] Make functorrent a library and an executable

This is a prerequisite for testing, as well as code organization.

1. `$ cabal repl` will build and import Functorrent library.
2. Making module exports explicit
---
 functorrent.cabal                 | 43 +++++++++++++++++++++++--------
 src/FuncTorrent.hs                | 32 +++++++++++++++++++++++
 src/{ => FuncTorrent}/Bencode.hs  |  7 ++++-
 src/{ => FuncTorrent}/Logger.hs   |  4 +--
 src/{ => FuncTorrent}/Metainfo.hs | 14 ++++++++--
 src/{ => FuncTorrent}/Peer.hs     | 16 ++++++++----
 src/{ => FuncTorrent}/Tracker.hs  | 13 +++++++---
 src/{ => FuncTorrent}/Utils.hs    |  2 +-
 src/Main.hs                       | 10 +++----
 9 files changed, 110 insertions(+), 31 deletions(-)
 create mode 100644 src/FuncTorrent.hs
 rename src/{ => FuncTorrent}/Bencode.hs (97%)
 rename src/{ => FuncTorrent}/Logger.hs (98%)
 rename src/{ => FuncTorrent}/Metainfo.hs (94%)
 rename src/{ => FuncTorrent}/Peer.hs (91%)
 rename src/{ => FuncTorrent}/Tracker.hs (89%)
 rename src/{ => FuncTorrent}/Utils.hs (86%)

diff --git a/functorrent.cabal b/functorrent.cabal
index 915fe71..e72f301 100644
--- a/functorrent.cabal
+++ b/functorrent.cabal
@@ -1,5 +1,5 @@
--- Initial functorrent.cabal generated by cabal init.  For further 
--- documentation, see http://haskell.org/cabal/users-guide/
+-- Initial functorrent.cabal generated by cabal init. For further documentation,
+-- see http://haskell.org/cabal/users-guide/
 
 name:                functorrent
 version:             0.1.0.0
@@ -9,28 +9,49 @@ license:             GPL-3
 license-file:        LICENSE
 author:              Ramakrishnan Muthukrishnan
 maintainer:          ram@rkrishnan.org
--- copyright:           
+-- copyright:
 category:            Network
 build-type:          Simple
--- extra-source-files:  
-cabal-version:       >=1.10
+extra-source-files:  README
+cabal-version:       >=1.18
 
-executable functorrent
-  main-is:             Main.hs
-  -- other-modules:       
-  -- other-extensions:    
+library
+  exposed-modules:     FuncTorrent
+                       FuncTorrent.Bencode,
+                       FuncTorrent.Logger,
+                       FuncTorrent.Metainfo,
+                       FuncTorrent.Peer,
+                       FuncTorrent.Tracker
+  other-extensions:    OverloadedStrings
+  hs-source-dirs:      src
+  ghc-options:         -Wall -fwarn-incomplete-patterns
+  default-language:    Haskell2010
   build-depends:       base,
                        HTTP,
                        base16-bytestring,
                        binary,
-                       bytestring,                    
+                       bytestring,
                        containers,
                        cryptohash,
                        doctest,
-                       network-uri, 
+                       network-uri,
                        parsec,
                        time
 
+executable functorrent
+  main-is:             Main.hs
+  other-extensions:    OverloadedStrings
   hs-source-dirs:      src
   ghc-options:         -Wall -fwarn-incomplete-patterns
   default-language:    Haskell2010
+  build-depends:       base,
+                       HTTP,
+                       base16-bytestring,
+                       binary,
+                       bytestring,
+                       containers,
+                       cryptohash,
+                       doctest,
+                       network-uri,
+                       parsec,
+                       time
diff --git a/src/FuncTorrent.hs b/src/FuncTorrent.hs
new file mode 100644
index 0000000..acd679e
--- /dev/null
+++ b/src/FuncTorrent.hs
@@ -0,0 +1,32 @@
+module FuncTorrent
+    (BVal(..),
+     Info,
+     InfoDict,
+     Metainfo,
+     Peer,
+     PeerResp(..),
+     announce,
+     connect,
+     decode,
+     encode,
+     getPeerResponse,
+     getPeers,
+     handShakeMsg,
+     info,
+     infoHash,
+     initLogger,
+     lengthInBytes,
+     logMessage,
+     logStop,
+     mkInfo,
+     mkMetaInfo,
+     name,
+     prepareRequest,
+     urlEncodeHash
+    ) where
+
+import FuncTorrent.Bencode
+import FuncTorrent.Logger
+import FuncTorrent.Metainfo
+import FuncTorrent.Peer
+import FuncTorrent.Tracker
diff --git a/src/Bencode.hs b/src/FuncTorrent/Bencode.hs
similarity index 97%
rename from src/Bencode.hs
rename to src/FuncTorrent/Bencode.hs
index 246fffc..89446ea 100644
--- a/src/Bencode.hs
+++ b/src/FuncTorrent/Bencode.hs
@@ -1,4 +1,9 @@
-module Bencode where
+module FuncTorrent.Bencode
+    (BVal(..),
+     InfoDict,
+     encode,
+     decode
+    ) where
 
 import Control.Applicative ((<*))
 import Data.ByteString.Char8 (ByteString, pack, unpack)
diff --git a/src/Logger.hs b/src/FuncTorrent/Logger.hs
similarity index 98%
rename from src/Logger.hs
rename to src/FuncTorrent/Logger.hs
index c1a5894..255809b 100644
--- a/src/Logger.hs
+++ b/src/FuncTorrent/Logger.hs
@@ -1,4 +1,4 @@
-module Logger (
+module FuncTorrent.Logger (
       initLogger
     , logMessage
     , logStop
@@ -13,7 +13,7 @@ import Control.Concurrent
 -- Here the (MVar LogCommand) is used for actual thread communication
 -- So if multiple threads try to log, then the logger will be thread-safe
 -- Also the 'loop' in logger will wait for the message to come.
--- 
+--
 -- The MVar in stop is just to ensure the logger thread executes completely
 -- Before exiting the main application.
 --
diff --git a/src/Metainfo.hs b/src/FuncTorrent/Metainfo.hs
similarity index 94%
rename from src/Metainfo.hs
rename to src/FuncTorrent/Metainfo.hs
index c77b127..92b7b96 100644
--- a/src/Metainfo.hs
+++ b/src/FuncTorrent/Metainfo.hs
@@ -1,10 +1,20 @@
-module Metainfo where
+module FuncTorrent.Metainfo
+    (Info,
+     Metainfo,
+     mkMetaInfo,
+     mkInfo,
+     announce,
+     lengthInBytes,
+     info,
+     name
+    ) where
 
 import Prelude hiding (lookup)
-import Bencode (BVal(..))
 import Data.ByteString.Char8 (ByteString, pack, unpack)
 import Data.Map as M ((!), lookup)
 
+import FuncTorrent.Bencode (BVal(..))
+
 -- only single file mode supported for the time being.
 data Info = Info { pieceLength :: !Integer
                  , pieces :: !ByteString
diff --git a/src/Peer.hs b/src/FuncTorrent/Peer.hs
similarity index 91%
rename from src/Peer.hs
rename to src/FuncTorrent/Peer.hs
index b07b79d..b9334ba 100644
--- a/src/Peer.hs
+++ b/src/FuncTorrent/Peer.hs
@@ -1,18 +1,24 @@
-module Peer where
+module FuncTorrent.Peer
+    (Peer,
+     PeerResp(..),
+     getPeers,
+     getPeerResponse,
+     handShakeMsg
+    ) where
 
 import Prelude hiding (lookup, concat, replicate, splitAt)
-
-import Bencode (BVal(..), InfoDict, decode)
 import Data.ByteString.Char8 (ByteString, pack, unpack, concat, replicate, splitAt)
 import Data.ByteString.Lazy (toChunks)
 import Data.Int (Int8)
 import Data.List (intercalate)
 import Data.Map as M ((!), lookup)
-import Tracker (infoHash)
-import Utils (splitN)
 import qualified Data.Binary as Bin (encode)
 import qualified Data.ByteString.Base16 as B16 (encode)
 
+import FuncTorrent.Bencode (BVal(..), InfoDict, decode)
+import FuncTorrent.Tracker (infoHash)
+import FuncTorrent.Utils (splitN)
+
 
 type Address = String
 type Port = Integer
diff --git a/src/Tracker.hs b/src/FuncTorrent/Tracker.hs
similarity index 89%
rename from src/Tracker.hs
rename to src/FuncTorrent/Tracker.hs
index 6c558e5..178aa97 100644
--- a/src/Tracker.hs
+++ b/src/FuncTorrent/Tracker.hs
@@ -1,8 +1,11 @@
-module Tracker where
+module FuncTorrent.Tracker
+    (connect,
+     infoHash,
+     prepareRequest,
+     urlEncodeHash
+    ) where
 
 import Prelude hiding (lookup)
-
-import Bencode (BVal(..), InfoDict, encode)
 import Crypto.Hash.SHA1 (hash)
 import Data.ByteString.Char8 (ByteString, pack, unpack)
 import Data.Char (chr)
@@ -12,9 +15,11 @@ import Data.Map as M (Map, (!))
 import Network.HTTP (simpleHTTP, defaultGETRequest_, getResponseBody)
 import Network.HTTP.Base (urlEncode)
 import Network.URI (parseURI)
-import Utils (splitN)
 import qualified Data.ByteString.Base16 as B16 (encode)
 
+import FuncTorrent.Bencode (BVal(..), InfoDict, encode)
+import FuncTorrent.Utils (splitN)
+
 type Url = String
 
 -- | urlEncodeHash
diff --git a/src/Utils.hs b/src/FuncTorrent/Utils.hs
similarity index 86%
rename from src/Utils.hs
rename to src/FuncTorrent/Utils.hs
index 019b06b..e5a4a55 100644
--- a/src/Utils.hs
+++ b/src/FuncTorrent/Utils.hs
@@ -1,4 +1,4 @@
-module Utils where
+module FuncTorrent.Utils where
 
 import qualified Data.ByteString.Char8 as BC
 
diff --git a/src/Main.hs b/src/Main.hs
index bc4b8d3..c23b97e 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -7,11 +7,11 @@ import System.Environment (getArgs)
 import System.Exit (exitSuccess)
 import Text.ParserCombinators.Parsec (ParseError)
 
-import Bencode (decode, BVal(..))
-import Logger (initLogger, logMessage, logStop)
-import Metainfo (announce, lengthInBytes, mkMetaInfo, info, name)
-import Peer (getPeers, getPeerResponse, handShakeMsg)
-import Tracker (connect, prepareRequest)
+import FuncTorrent.Bencode (decode, BVal(..))
+import FuncTorrent.Logger (initLogger, logMessage, logStop)
+import FuncTorrent.Metainfo (announce, lengthInBytes, mkMetaInfo, info, name)
+import FuncTorrent.Peer (getPeers, getPeerResponse, handShakeMsg)
+import FuncTorrent.Tracker (connect, prepareRequest)
 
 logError :: ParseError -> (String -> IO ()) -> IO ()
 logError e logMsg = logMsg $ "parse error: \n" ++ show e
-- 
2.45.2