Permalink
Browse files

More preparation for Cabal, name change

Ignore-this: e6bc8fae96ff29b5abf5e89591ed1e9a
-Changed module name to Tree, so that it will reside in System.Directory.Tree
-finished .cabal file
-other adjustments to DirectoryTree interface/exports

darcs-hash:20090508212743-a5925-b08d39e13d59b220953c689d9acd71785dbd6e54
  • Loading branch information...
1 parent 03ee7c2 commit 4cd66525a9c7eb72cef8e83c17f3db0dbb5592f1 @jberryman committed May 8, 2009
Showing with 153 additions and 64 deletions.
  1. +26 −0 LICENSE
  2. +2 −0 Setup.hs
  3. +69 −64 DirectoryTree.hs → System/Directory/Tree.hs
  4. +56 −0 directory-tree.cabal
View
26 LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2009 Brandon Simmons
+
+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 AUTHORS ``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 AUTHORS 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.
View
2 Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
View
133 DirectoryTree.hs → System/Directory/Tree.hs
@@ -1,6 +1,6 @@
--------------------------------------------------------------------
-- |
--- Module : System.Directory.DirectoryTree
+-- Module : System.Directory.Tree
-- Copyright : (c) Brandon Simmons
-- License : BSD3
--
@@ -20,47 +20,46 @@
--
-- The AnchoredDirTree type is a simple wrapper for DirTree to keep track
-- of a base directory context for the DirTree.
+--
+-- Please send me any requests, bugs, or other feedback on this module!
--------------------------------------------------------------------
-module DirectoryTree (-- high level:
- readDirectory, readDirectoryWith,
- writeDirectory, writeDirectoryWith,
-
- -- lower level:
- zipPaths, build, openDirectory, writeJustDirs,
-
- -- utilities:
- anyFailed, failures, failedMap, free,
-
- -- Types:
- DirTree (..), AnchoredDirTree (..), FileName)
- where
+module Tree (
+
+ -- * Data types for representing directory trees
+ DirTree (..)
+ , AnchoredDirTree (..)
+ , FileName
+
+ -- * High level IO functions
+ , readDirectory
+ , readDirectoryWith
+ , writeDirectory
+ , writeDirectoryWith
+
+ -- * Lower level functions
+ , zipPaths
+ , build
+ , openDirectory
+ , writeJustDirs
+
+ -- * Utility functions
+ -- ** Handling failure
+ , successful
+ , anyFailed
+ , failures
+ , failedMap
+ -- ** Misc.
+ , free
+
+ ) where
{-
-NOTES:
- a simple interface to directories. DirTree's free variable can hold
- file paths, strings to be written to files in a directory tree,
- file-handles, byte-strings read with 'readFile',etc.
-
- the AnchoredDirTree type is simply a wrapper that allows us to store,
- and return the base file path of the directory.
-
- we don't provide many special functions for only working within the
- current directory. it should be easy enough to create a DirTree
- "Anchored" at the current directory like so:
- anchorAtCurrent dTree = "." :/ dTree
-
-IDEAS:
- an informal comonad instance might might make sense: for example, cobind
- to convert Failed constructors to Files or Dirs, or cojoin to allow us to
- use the traversable/foldable functions over an entire File/Failed
- constructor.
- define a 'cojoin' function if you want.
-
TODO:
+ - add some tests
- tree combining functions
- tree searching based on file names
- look into comonad abstraction
@@ -84,10 +83,11 @@ import qualified Data.Foldable as F
--- the String in Dir is always the directory name, never a full path. We
--- provide functions to convert a DirTree String (where String is a filename)
--- to a DirTree FilePath, where the File constructor holds a full path to a
--- file (relative or absolute) rather than a bare file name.
+-- | the String in the "name" field is always a file name, never a full path.
+-- The free type variable is used in the File constructor and can hold Handles,
+-- Strings representing a file's contents or anything else you can think of.
+-- We catch any IO errors in the Failed constructor. an Exception can be
+-- converted to a String with 'show'.
data DirTree a = Dir { name :: FileName,
contents :: [DirTree a] } --files + directories
| File { name :: FileName,
@@ -101,14 +101,14 @@ instance (Ord a)=> Ord (DirTree a) where
compare = compare `on` name
--- a simple wrapper to hold a base directory name, which can be either
+-- | a simple wrapper to hold a base directory name, which can be either
-- an absolute or relative path. This lets us give the DirTree a context,
-- while still letting us store only directory and file NAMES (not full paths)
--- in the DirTree.
+-- in the DirTree. (uses an infix constructor; don't be scared)
data AnchoredDirTree a = FilePath :/ DirTree a
deriving (Show, Ord, Eq)
--- an element in a FilePath:
+-- | an element in a FilePath:
type FileName = String
@@ -132,27 +132,27 @@ instance T.Traversable DirTree where
----------------------------
--- build an AnchoredDirTree, given the path to a directory, opening the files
+-- | build an AnchoredDirTree, given the path to a directory, opening the files
-- using readFile.
readDirectory :: FilePath -> IO (AnchoredDirTree String)
readDirectory = readDirectoryWith readFile
--- same as readDirectory but allows us to, for example, use ByteString.readFile
--- to return a tree of ByteStrings.
+-- | same as readDirectory but allows us to, for example, use
+-- ByteString.readFile to return a tree of ByteStrings.
readDirectoryWith :: (FilePath -> IO a) -> FilePath -> IO (AnchoredDirTree a)
readDirectoryWith f p = do (b:/t) <- build p
t' <- T.mapM f t
return $ b:/t'
--- write a DirTree of strings to disk. clobbers files of the same name. doesn't
--- affect files in the directories (if any already exist) with different names:
+-- | write a DirTree of strings to disk. clobbers files of the same name.
+-- doesn't affect files in the directories (if any already exist) with
+-- different names:
writeDirectory :: AnchoredDirTree String -> IO ()
writeDirectory = writeDirectoryWith writeFile
--- writes the directory structure to disc, then uses the provided function to
--- write the contents of Files to disc. For example, we can provide 'readfile'
--- for ByteStrings on a DirTree of ByteStrings.
+-- | writes the directory structure to disc, then uses the provided function to
+-- write the contents of Files to disc.
writeDirectoryWith :: (FilePath -> a -> IO ()) -> AnchoredDirTree a -> IO ()
writeDirectoryWith f t = do writeJustDirs t
F.mapM_ (uncurry f) (zipPaths t)
@@ -166,14 +166,14 @@ writeDirectoryWith f t = do writeJustDirs t
-----------------------------
--- a simple application of readDirectoryWith openFile:
+-- | a simple application of readDirectoryWith openFile:
openDirectory :: FilePath -> IOMode -> IO (AnchoredDirTree Handle)
openDirectory p m = readDirectoryWith (flip openFile m) p
--- builds a DirTree from the contents of the directory passed to it, saving the
--- base directory in the Anchored* wrapper. Errors are caught in the tree in
+-- | builds a DirTree from the contents of the directory passed to it, saving
+-- the base directory in the Anchored* wrapper. Errors are caught in the tree in
-- the Failed constructor. The 'file' fields initially are populated with full
-- paths to the files they are abstracting.
build :: FilePath -> IO (AnchoredDirTree FilePath)
@@ -198,43 +198,48 @@ build' p =
-
-
-----------------
--[ UTILITIES ]--
-----------------
--- strips away base directory wrapper:
-free :: AnchoredDirTree a -> DirTree a
-free (_:/t) = t
-
---- HANDLING FAILURES ----
+-- | True if any Failed constructors in the tree
anyFailed :: DirTree a -> Bool
-anyFailed = not . null . failures
+anyFailed = not . successful
+-- | True if there are no Failed constructors in the tree
+successful :: DirTree a -> Bool
+successful = null . failures
--- MAKE THIS COMONADIC???
--- returns a list of 'Failed' constructors only:
+
+-- | returns a list of 'Failed' constructors only:
failures :: DirTree a -> [DirTree a]
failures (Dir _ cs) = concatMap failures cs
failures (File _ _) = []
failures f = [f]
--- maps a function to convert Failed DirTrees to Files or Dirs
+-- | maps a function to convert Failed DirTrees to Files or Dirs
failedMap :: (FileName -> Exception -> DirTree a) -> DirTree a -> DirTree a
failedMap f (Dir n cs) = Dir n $map (failedMap f) cs
failedMap f (Failed n e) = f n e
failedMap _ fle = fle
+---- OTHER ----
+
+-- | strips away base directory wrapper:
+free :: AnchoredDirTree a -> DirTree a
+free (_:/t) = t
+
+
---------------
--[ HELPERS ]--
@@ -245,7 +250,7 @@ failedMap _ fle = fle
--- tuple up the complete filename with the File contents, by building up the
+-- | tuple up the complete filename with the File contents, by building up the
-- path, trie-style, from the root. The filepath will be relative to the current
-- directory.
-- This allows us to, for example, mapM_ 'uncurry writeFile' over a DirTree of
@@ -267,7 +272,7 @@ baseDir = joinPath . init . splitDirectories
---- IO HELPERS: ----
--- writes the directory structure (not files) of a DirTree to the anchored
+-- | writes the directory structure (not files) of a DirTree to the anchored
-- directory. can be preparation for writing files:
writeJustDirs :: AnchoredDirTree a -> IO ()
writeJustDirs (b:/t) = write' b t
View
56 directory-tree.cabal
@@ -0,0 +1,56 @@
+name: directory-tree
+version: 0.1
+homepage: http://code.haskell.org/~bsimmons/code/directory-tree
+synopsis: A simple directory-like tree datatype, with useful IO functions and Foldable/Traversable instance
+description: A simple directory-like tree datatype, with useful IO functions and Foldable/Traversable instance
+ .
+ Provides a simple data structure mirroring a directory tree on the
+ filesystem, as well as useful functions for reading and writing
+ file/directory structures in the IO monad.
+ .
+ Importing the library and optional (useful) Foldable and Traverable libraries:
+ .
+ > import System.Directory.Tree
+ > import qualified Data.Foldable as F
+ > import qualified Data.Traversable as T
+ .
+ Write a hand-made directory tree of textfiles (strings) to the disk.
+ Simulates creating a new user Tux's home directory on a unix machine:
+ .
+ > writeDirectory$ "/home" :/ Dir "Tux" [File "README" "Welcome!"]
+ .
+ "read" a directory by opening all the files at a filepath with readFile,
+ returning an 'AnchoredDirTree String' (d2). Then check for any IO failures:
+ .
+ > do (base :/ d2) <- readDirectory "../parent_dir/dir2/"
+ > let failed = anyFailed d2
+ > if failed then ...
+ .
+ Use Foldable instance function to concat a directory 'dir' of text files into a
+ single file under the same directory:
+ .
+ > do (b :/ dt) <- readDirectory dir
+ > let f = F.concat dt
+ > return$ b :/ File "ALL_TEXT" f
+ .
+ Open all the files in the current directory as lazy bytestrings, ignoring
+ the base path in Anchored wrapper:
+ .
+ > import qualified Data.ByteString.Lazy as B
+ > (_ :/ dTree) <- readDirectoryWith B.readFile "./" {- "" works too -}
+ .
+category: Data, System
+license: BSD3
+license-file: LICENSE
+copyright: (c) 2009, Brandon Simmons <brandon.m.simmons@gmail.com>
+author: Brandon Simmons
+maintainer: Brandon Simmons <brandon.m.simmons@gmail.com>
+cabal-version: >= 1.2.0
+build-type: Simple
+tested-with: GHC ==6.8.2
+extra-source-files: examples.hs
+
+
+library
+ exposed-modules: System.Directory.Tree
+ build-depends: base

0 comments on commit 4cd6652

Please sign in to comment.