packages feed

fishfood 0.0.1.0 → 0.0.1.3

raw patch · 13 files changed

+93/−54 lines, 13 filessetup-changed

Files

Setup.hs view
@@ -1,5 +1,5 @@ #!/usr/bin/env runhaskell -import qualified	Distribution.Simple+import qualified Distribution.Simple -main	= Distribution.Simple.defaultMain+main = Distribution.Simple.defaultMain
changelog view
@@ -8,3 +8,13 @@ 	* Migrated all but the I/O, from "Main" to a new module "FishFood.Profiler". 	* Added module "FishFood.Test", containing "Test.QuickCheck"-implementation. 	* Added Command-line options; '--deriveProbabilityMassFunction', '--binSizeRatio', '--runQuickChecks'.+0.0.1.1+	* Added files to build .deb to 'fishfood.cabal'.+0.0.1.2+	* Added '--runQuickChecks' to 'man/man1/fishfood.1' & corrected typo.+	* Improved the syntax of 'verbosity' in the usage-message.+	* Tested with 'haskell-platform-2013.2.0.0'.+0.0.1.3+	* In module "FishFood.Data.File", replaced 'Control.Exception.throw' with 'Control.Exception.throwIO'.+	* Either replaced instances of '(<$>)' with 'fmap' to avoid ambiguity between "Control.Applicative" & "Prelude" which (from 'base-4.8') also exports this symbol, or hid the symbol when importing the "Prelude"..+	* In module "Main", redirected version-message to stderr.
+ debian/DEBIAN/control view
@@ -0,0 +1,13 @@+Package:	fishfood+Version:	0.0.1.3-1+Section:	utils+Priority:	optional+#Architecture:	i386+Architecture:	amd64+Depends:	libc6+Installed-size:	2252+Maintainer:	Dr. Alistair Ward <fishfood at functionalley dot eu>+Provides:+Homepage:	http://functionalley.eu+Description:	Counts the number of files in a set of bins, each of which holds only those files which fall within a specific size-interval.+
fishfood.cabal view
@@ -1,8 +1,8 @@---Package-properties+-- Package-properties Name:			fishfood-Version:		0.0.1.0+Version:		0.0.1.3 Cabal-Version:		>= 1.6-Copyright:		(C) 2013 Dr. Alistair Ward+Copyright:		(C) 2013-2015 Dr. Alistair Ward License:		GPL License-file:		LICENSE Author:			Dr. Alistair Ward@@ -11,13 +11,14 @@ Build-Type:		Simple Description:		Counts the number of files in a set of bins, each of which holds only those files which fall within a specific size-interval. Category:		Utils-Tested-With:		GHC == 7.4+Tested-With:		GHC == 7.4, GHC == 7.6, GHC == 7.10 Homepage:		http://functionalley.eu Maintainer:		fishfood <at> functionalley <dot> eu Bug-reports:		fishfood <at> functionalley <dot> eu Data-files:-Extra-Source-Files:	changelog copyright makefile man/man1/fishfood.1 fishfood.spec+Extra-Source-Files:	changelog copyright debian/DEBIAN/control makefile man/man1/fishfood.1 fishfood.spec +-- Turn on using: 'runhaskell ./Setup.hs configure -f llvm'. flag llvm     Description:	Whether the 'llvm' compiler-backend has been installed and is required for code-generation.     manual:		True@@ -46,7 +47,7 @@         toolshed >= 0.13,         unix -    GHC-options:	-Wall+    GHC-options:	-Wall -fno-warn-tabs      if impl(ghc >= 7.4.1)         GHC-prof-options:	-prof -fprof-auto -fprof-cafs
fishfood.spec view
@@ -1,4 +1,4 @@-# Copyright (C) 2013 Dr. Alistair Ward+# Copyright (C) 2013-2014 Dr. Alistair Ward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by@@ -22,7 +22,7 @@  Summary:	Calculates file-size frequency-distribution. Name:		fishfood-Version:	0.0.1.0+Version:	0.0.1.3 Release:	1 License:	GPLv3 #From '/usr/share/doc/packages/rpm/GROUPS'.
makefile view
@@ -1,4 +1,4 @@-# Copyright (C) 2010 Dr. Alistair Ward+# Copyright (C) 2013-2014 Dr. Alistair Ward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by@@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program.  If not, see <http://www.gnu.org/licenses/>. -.PHONY: all build check clean clobber configure copy haddock help hlint install prof rpm sdist+.PHONY: all build check clean clobber configure copy deb haddock help hlint install prof rpm sdist  PACKAGE_NAME=fishfood @@ -42,10 +42,10 @@ 	PATH=~/.cabal/bin:$$PATH runhaskell Setup $@ --hyperlink-source --executables	#Amend path to find 'HsColour', as required for 'hyperlink-source'.  hlint:-	@$@ src/+	@$@ src/ +RTS -N  sdist:-	runhaskell Setup $@+	TAR_OPTIONS='--format=ustar' runhaskell Setup $@  check: sdist 	cabal upload --check --verbose=3 dist/*.tar.gz;@@ -53,6 +53,13 @@ rpm: $(PACKAGE_NAME).spec 	rpmbuild -bb --nodeps -- $^ 	mv -- `find ~/rpmbuild -type f -name '$(PACKAGE_NAME)*.rpm' -mtime 0 -print` ./++deb: build+	mkdir -p debian/usr/bin/ && strip --strip-all 'dist/build/$(PACKAGE_NAME)/$(PACKAGE_NAME)' && mv 'dist/build/$(PACKAGE_NAME)/$(PACKAGE_NAME)' debian/usr/bin/+	mkdir -p 'debian/usr/share/doc/$(PACKAGE_NAME)/' && cp changelog changelog.Debian copyright LICENSE 'debian/usr/share/doc/$(PACKAGE_NAME)/' && cd 'debian/usr/share/doc/$(PACKAGE_NAME)/' && gzip --best -f changelog changelog.Debian LICENSE+	mkdir -p debian/usr/share/ && cp -R man/ debian/usr/share/ && gzip --best -f debian/usr/share/man/man1/*.1+	cd debian/ && md5sum `find usr -type f -print` >'DEBIAN/md5sums'+	fakeroot dpkg-deb --build debian .  clean: 	runhaskell Setup $@
man/man1/fishfood.1 view
@@ -23,7 +23,7 @@ \fB-d\fR \fIInt\fR, \fB--nDecimalDigits=\fR\fIInt\fR The precision to which fractional auxiliary data is displayed. .TP-\fB--verbosity=\fR\fBSilent\fR|\fBNormal\fR|\fBVerbose\fR|\fBDeafening\fR+\fB--verbosity=\fR(\fBSilent\fR|\fBNormal\fR|\fBVerbose\fR|\fBDeafening\fR) Produces additional output where appropriate; i.e. file-names, file-size statistics, & column-headers. .SS "Generic Program-information" .TP@@ -32,8 +32,12 @@ .TP \fB-?\fR, \fB--help\fR Displays help & then exits.-.SS "File-paths"+.SS Test .TP+\fB-q\fR, \fB--runQuickChecks\fR+Tests the implementation, by validating some invariant properties using arbitrary data; & then exits.+.SS File-paths+.TP If \fIFile-path\fR is a single hyphen-minus (\fB-\fR), then the list of file-paths will be read from standard-input. Only plain files are acceptable; no directories, symlinks, sockets, ... .SH EXIT-STATUS \fB0\fR on success, & >\fB0\fR if an error occurs.@@ -103,7 +107,7 @@    1000000         1 .fi .PP-From this data one can conclude that there are 4 files whose size lies in the semi-closed interval [0, 1) bytes, 3 files in [1, 10), 100 files in [10, 100), ...+From this data one can conclude that there are 4 files whose size is zero, 2 files in the semi-closed interval [1, 10), 100 files in [10, 100), ... .IP .B find $HOME -name '*.png' -o -name '*.gif' -o -name '*.jp*g' | fishfood --verbosity=Verbose -r 2 -p - .nf@@ -161,6 +165,6 @@ .IP \(bu .B http://en.wikipedia.org/wiki/Probability_mass_function .IP \(bu-Source-documentation is generated by \fBHaddock\fR, & is available in the distribution.+Source-documentation is generated by "\fBHaddock\fR", & is available in the distribution. .IP \(bu .B http://www.haskell.org/haddock/
src/FishFood/Data/CommandOptions.hs view
@@ -65,7 +65,7 @@  instance ToolShed.Defaultable.Defaultable (CommandOptions ratio)	where 	defaultValue	= MkCommandOptions {-		getBinSizeDelta				= Left Nothing,	--Interpreted as one standard-deviation.+		getBinSizeDelta				= Left Nothing,	-- Interpreted as one standard-deviation. 		getDeriveProbabilityMassFunction	= False, 		getNDecimalDigits			= 3, 		getVerbosity				= Distribution.Verbosity.normal@@ -87,7 +87,7 @@ 		let 			maxNDecimalDigits	= floor $ fromIntegral ( 				floatDigits (-					undefined :: Double	--CAVEAT: the actual type could be merely 'Float', but that's currently unknown.+					undefined :: Double	-- CAVEAT: the actual type could be merely 'Float', but that's currently unknown. 				) 			 ) * (logBase 10 2 :: Double) 		in (
src/FishFood/Data/File.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2013 Dr. Alistair Ward+	Copyright (C) 2013-2014 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -36,16 +36,16 @@ import qualified	System.Posix.Files  -- | A type-synonym specifically to hold file-sizes (in bytes).-type FileSize	= Integer	--Matches the return-type of 'IO.hFileSize'.+type FileSize	= Integer	-- Matches the return-type of 'IO.hFileSize'.  -- | Get the size of the specified file. findSize :: System.IO.FilePath -> IO FileSize findSize f	= do-	stat	<- System.Posix.Files.getFileStatus f	--CAVEAT: throws if the user is unauthorised, or the file is non-existent.+	stat	<- System.Posix.Files.getFileStatus f	-- CAVEAT: throws if the user is unauthorised, or the file is non-existent.  	if System.Posix.Files.isRegularFile stat 		then System.IO.withFile f System.IO.ReadMode System.IO.hFileSize-		else {-non-directory-} Control.Exception.throw $ System.IO.Error.mkIOError System.IO.Error.illegalOperationErrorType ("file=" ++ show f ++ " has unexpected type") Nothing (Just f)+		else {-non-directory-} Control.Exception.throwIO $ System.IO.Error.mkIOError System.IO.Error.illegalOperationErrorType ("file=" ++ show f ++ " has unexpected type") Nothing (Just f)  -- | Acquire statistics related to a list of file-sizes. getFileSizeStatistics
src/FishFood/Profiler.hs view
@@ -76,24 +76,24 @@  	return {-to Writer-monad-} $ if standardDeviation == 0 		then return {-to List-monad-} . (,) (head fileSizes) $ if deriveProbabilityMassFunction-			then Right 1		--i.e. certainty.-			else Left nFiles	--i.e. all.+			then Right 1		-- i.e. certainty.+			else Left nFiles	-- i.e. all. 		else let 			getDefaultedBinSizeIncrement :: Maybe Data.File.FileSize -> Data.File.FileSize-			getDefaultedBinSizeIncrement	= Data.Maybe.fromMaybe $ round standardDeviation `max` 1 {-minimum increment-} 	--CAVEAT: guard against subsequent division by zero or infinite iteration.+			getDefaultedBinSizeIncrement	= Data.Maybe.fromMaybe $ round standardDeviation `max` 1 {-minimum increment-}	-- CAVEAT: guard against subsequent division by zero or infinite iteration.  			calculatedBinSizes :: [Data.File.FileSize] 			calculatedBinSizes	= map ( 				\fileSize	-> either (-					div {-round down-} fileSize . getDefaultedBinSizeIncrement {-non-zero-} +					div {-round down-} fileSize . getDefaultedBinSizeIncrement {-non-zero-} 				) (-					floor {-round down-} . (`logBase` fromIntegral fileSize)	--CAVEAT: converts file-size 0, to bin-size -infinity.+					floor {-round down-} . (`logBase` fromIntegral fileSize)	-- CAVEAT: converts file-size 0, to bin-size -infinity. 				) binSizeDelta-			 ) fileSizes	--Each bin spans the semi-closed integral interval [size, succ size), so round down fractional values to match the lower bin.+			 ) fileSizes	-- Each bin spans the semi-closed integral interval [size, succ size), so round down fractional values to match the lower bin.  			initialFrequencyDistribution :: Data.Map.Map Data.File.FileSize Int 			initialFrequencyDistribution	= Data.Map.fromAscList . (-				`zip` repeat 0	--The initial file-count.+				`zip` repeat 0	-- The initial file-count. 			 ) . takeWhile ( 				<= maximum calculatedBinSizes 			 ) . dropWhile (@@ -101,21 +101,21 @@ 			 ) $ either ( 				\maybeBinSizeIncrement	-> iterate (+ getDefaultedBinSizeIncrement {-non-zero-} maybeBinSizeIncrement) 0 			 ) (-				\binRatio		-> map round {-file-sizes are integral-} $ iterate (* binRatio) 1	--The sequence could be started at fractional values in the open unit-interval, but the only value less than 1 which may be required is 0 (which isn't a sequence-member), which will be created later on demand.+				\binRatio		-> map round {-file-sizes are integral-} $ iterate (* binRatio) 1	-- The sequence could be started at fractional values in the open unit-interval, but the only value less than 1 which may be required is 0 (which isn't a sequence-member), which will be created later on demand. 			 ) binSizeDelta  			mapBinSizeToFileSize :: Data.Map.Map Data.File.FileSize value -> Data.Map.Map Data.File.FileSize value 			mapBinSizeToFileSize	= Data.Map.mapKeys $ \binSize -> either ( 				(* binSize) . getDefaultedBinSizeIncrement 			 ) (-				ceiling {-round up-} . (^^ binSize)	--Converts binSize -infinity, back to file-size 0.-			 ) binSizeDelta	--Represent each bin by the minimum file-size it can accept.+				ceiling {-round up-} . (^^ binSize)	-- Converts binSize -infinity, back to file-size 0.+			 ) binSizeDelta	-- Represent each bin by the minimum file-size it can accept. 		in Data.Map.toList . ( 			if deriveProbabilityMassFunction 				then Data.Map.map Right . mapBinSizeToFileSize . Data.Map.map ((/ fromIntegral nFiles {-non-zero-}) . fromIntegral) 				else Data.Map.map Left . mapBinSizeToFileSize 		) $ foldr (-			Data.Map.insertWith (+) `flip` 1	--Count the files allocated to each bin.+			Data.Map.insertWith (+) `flip` 1	-- Count the files allocated to each bin. 		) initialFrequencyDistribution calculatedBinSizes  -- | Formats a file-size distribution.@@ -128,10 +128,10 @@ 			[ 				( 					($ (fileSizeWidth, fileSizeHeader)) &&& ($ (valueWidth, valueHeader))-				) . uncurry $ Text.Printf.printf "%*s",	--Column-headers.-				(`replicate` '=') *** (`replicate` '=') $ columnWidths	--Separator-bar.+				) . uncurry $ Text.Printf.printf "%*s",	-- Column-headers.+				(`replicate` '=') *** (`replicate` '=') $ columnWidths	-- Separator-bar. 			] ++-		) --Section.+		) -- Section. 		else id  ) . map ( 	Text.Printf.printf "%*d" fileSizeWidth *** either (@@ -144,5 +144,5 @@ 	headers@(fileSizeHeader, valueHeader)	= (,) "Bin-size" $ if Data.CommandOptions.getDeriveProbabilityMassFunction commandOptions then "Probability" else "Frequency"  	fileSizeWidth, valueWidth :: Int-	columnWidths@(fileSizeWidth, valueWidth)	= (`max` 10) . length *** length $ headers	--CAVEAT: the data-length may exceed the header-length, so define a minimum.+	columnWidths@(fileSizeWidth, valueWidth)	= (`max` 10) . length *** length $ headers	-- CAVEAT: the data-length may exceed the header-length, so define a minimum. 
src/FishFood/Test/Data/CommandOptions.hs view
@@ -1,6 +1,6 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} {--	Copyright (C) 2013 Dr. Alistair Ward+	Copyright (C) 2013-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -27,7 +27,8 @@ 	CommandOptions ) where -import			Control.Applicative((<$>), (<*>)) +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol.+import			Control.Applicative((<$>), (<*>)) import qualified	Test.QuickCheck import qualified	FishFood.Data.CommandOptions	as Data.CommandOptions import			FishFood.Test.Data.Verbosity()
src/FishFood/Test/Profiler.hs view
@@ -49,7 +49,7 @@ 	prop_attendance commandOptions fileSizes	= not (null fileSizes') && ToolShed.SelfValidate.isValid commandOptions' ==> Test.QuickCheck.label "prop_attendance" . ( 		== Data.Set.fromList fileSizes' 	 ) . Data.Set.fromList . map Profiler.getFileSize . filter (-		(/= 0) . either fromIntegral id . Profiler.getValue	--Remove file-sizes which match zero actual files.+		(/= 0) . either fromIntegral id . Profiler.getValue	-- Remove file-sizes which match zero actual files. 	 ) . fst {-distribution-} . Control.Monad.Writer.runWriter $ Profiler.calculateFileSizeDistribution commandOptions' fileSizes'	where 		fileSizes'	= map abs fileSizes 
src/Main.hs view
@@ -1,5 +1,5 @@ {--	Copyright (C) 2013 Dr. Alistair Ward+	Copyright (C) 2013-2015 Dr. Alistair Ward  	This program is free software: you can redistribute it and/or modify 	it under the terms of the GNU General Public License as published by@@ -28,6 +28,7 @@  module Main(main) where +import Prelude hiding ((<$>), (<*>))	-- The "Prelude" from 'base-4.8' exports this symbol. import			Control.Applicative((<$>),(<*>)) import qualified	Control.Monad import qualified	Control.Monad.Writer@@ -42,13 +43,13 @@ import qualified	FishFood.Data.Verbosity		as Data.Verbosity import qualified	FishFood.Profiler		as Profiler import qualified	FishFood.Test.QuickChecks	as Test.QuickChecks-import qualified	Paths_fishfood			as Paths	--Either local stub, or package-instance autogenerated by 'Setup.hs build'.+import qualified	Paths_fishfood			as Paths	-- Either local stub, or package-instance autogenerated by 'Setup.hs build'. import qualified	System.Console.GetOpt		as G import qualified	System.Environment import qualified	System.Exit import qualified	System.IO import qualified	System.IO.Error-import qualified	Text.Printf+import qualified	ToolShed.Data.List import qualified	ToolShed.Defaultable import qualified	ToolShed.SelfValidate @@ -56,7 +57,7 @@ type CommandOptions	= Data.CommandOptions.CommandOptions Double  -- | Used to thread user-defined command-line options, though the list of functions which implement them.-type CommandLineAction	= CommandOptions -> IO CommandOptions	--Supplied as the type-argument to 'G.OptDescr'.+type CommandLineAction	= CommandOptions -> IO CommandOptions	-- Supplied as the type-argument to 'G.OptDescr'.  -- | On failure to parse the specified string, returns an explanatory error. read' :: Read a => String -> String -> a@@ -97,7 +98,8 @@ --				 String	[String]				(G.ArgDescr CommandLineAction)				String 			G.Option "?"	["help"]				(G.NoArg $ const printUsage)				"Display this help, & then exit.", 			G.Option ""	["verbosity"]				(-				setVerbosity `G.ReqArg` show Data.Verbosity.range+				setVerbosity `G.ReqArg` ToolShed.Data.List.showListWith listDelimiters Data.Verbosity.range ""+ 			)														("Define the log-level; default '" ++ show (Data.CommandOptions.getVerbosity defaultCommandOptions) ++ "'." 			), 			G.Option "v"	["version"]				(G.NoArg $ const printVersion)				"Print version-information, & then exit.",@@ -105,8 +107,10 @@ 			G.Option "r"	["binSizeRatio"]			(setBinSizeRatio `G.ReqArg` "<Float>")			"The constant size-ratio in the geometric sequence of bins into which the byte-sizes of files are categorised; an alternative to 'binSizeIncrement'.", 			G.Option "p"	["deriveProbabilityMassFunction"]	(setDeriveProbabilityMassFunction `G.OptArg` "<Bool>")	("Whether to derive the \"Probability mass function\" rather than the \"Frequency-distribution\"; default '" ++ show (Data.CommandOptions.getDeriveProbabilityMassFunction defaultCommandOptions) ++ "'."), 			G.Option "d"	["nDecimalDigits"]			(setNDecimalDigits `G.ReqArg` "<Int>")			("The precision to which fractional auxiliary data is displayed; default " ++ show (Data.CommandOptions.getNDecimalDigits defaultCommandOptions) ++ "."),-			G.Option "q"	["runQuickChecks"]			(G.NoArg runQuickChecks)				"Run Quick-checks using arbitrary data, & then exit."+			G.Option "q"	["runQuickChecks"]			(G.NoArg runQuickChecks)				"Test the implementation, by validating some invariant properties using arbitrary data; & then exit." 		 ] where+			listDelimiters	= ('(', '|', ')')+ 			setBinSizeIncrement, setBinSizeRatio, setNDecimalDigits, setVerbosity :: String -> CommandLineAction 			setBinSizeIncrement arg			= return {-to IO-monad-} . Data.CommandOptions.setBinSizeIncrement (readCommandArg arg) 			setBinSizeRatio arg			= return {-to IO-monad-} . Data.CommandOptions.setBinSizeRatio (readCommandArg arg)@@ -117,16 +121,15 @@ 			setDeriveProbabilityMassFunction arg commandOptions	= return {-to IO-monad-} commandOptions { Data.CommandOptions.getDeriveProbabilityMassFunction = Data.Maybe.maybe True readCommandArg arg }  			printVersion, printUsage :: IO CommandOptions-			printVersion	= Text.Printf.printf "%s\n\n%s %s.\n%s.\n%s.\n%s %s.\n" packageName "Copyright (C) 2013" author "This program comes with ABSOLUTELY NO WARRANTY" "This is free software, & you are welcome to redistribute it under certain conditions" "Written by" author >> System.Exit.exitWith System.Exit.ExitSuccess	where+			printVersion	= System.IO.hPutStrLn System.IO.stderr (Distribution.Text.display packageIdentifier ++ "\n\nCopyright (C) 2013-2015 " ++ author ++ ".\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain conditions.\n\nWritten by " ++ author ++ ".")	>> System.Exit.exitWith System.Exit.ExitSuccess	where 				packageIdentifier :: Distribution.Package.PackageIdentifier 				packageIdentifier	= Distribution.Package.PackageIdentifier {-					Distribution.Package.pkgName	= Distribution.Package.PackageName progName,	--CAVEAT: coincidentally.+					Distribution.Package.pkgName	= Distribution.Package.PackageName progName,	-- CAVEAT: coincidentally. 					Distribution.Package.pkgVersion	= Distribution.Version.Version (Data.Version.versionBranch Paths.version) [] 				} -				packageName, author :: String-				packageName	= Distribution.Text.display packageIdentifier-				author		= "Dr. Alistair Ward"+				author :: String+				author	= "Dr. Alistair Ward"  			printUsage	= System.IO.hPutStrLn System.IO.stderr ("Usage:\t" ++ G.usageInfo progName optDescrList ++ "  [<File-path> ...]") >> System.Exit.exitWith System.Exit.ExitSuccess @@ -163,7 +166,7 @@ 									else return filePaths 							else {-real fileNames-} return {-to IO-monad-} nonOptions -						Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions == maxBound) $ System.IO.hPrint System.IO.stderr filePaths	--CAVEAT: potentially very long.+						Control.Monad.when (Data.CommandOptions.getVerbosity commandOptions == maxBound) $ System.IO.hPrint System.IO.stderr filePaths	-- CAVEAT: potentially very long.  						(fileSizeDistribution, statistics)	<- Control.Monad.Writer.runWriter . Profiler.calculateFileSizeDistribution commandOptions <$> mapM Data.File.findSize (Data.List.nub filePaths)