minirotate 0.1.1.2 → 0.1.2.0
raw patch · 5 files changed
+61/−28 lines, 5 filesdep +template-haskell
Dependencies added: template-haskell
Files
- README +36/−1
- minirotate.cabal +3/−2
- src/Main.hs +12/−9
- src/Options.hs +4/−0
- src/Pattern.hs +6/−16
README view
@@ -1,1 +1,36 @@-See miniorotate.cabal for details.+$ minirotate --help++Usage: minirotate [OPTIONS] SOURCE [SOURCE..] DESTINATION+ -h, -? --help show help+ -V --version show version+ --show-defaults show program defaults+ -p PATTERN --pattern=PATTERN pattern for final files+ -m --move set copy mode to 'move'+ -c --copy set copy mode to 'copy'+ --min-files=NUM minimum number of files to keep+ --max-files=NUM maximum number of files to keep+ --max-age=NUMSEC maximum age of files to keep++$ minirotate --show-defaults+Defaults:+ EnvOptions {showHelp_ = False, showVers_ = False, showDefs_ = False, continue_ = True, logger_ = "", verbose_ = False}+ RunOptions {filePattern_ = "{basename}-{modtime %d-%m-%Y-%H_%M_%S}{ext}", copyMode_ = Copy, minimumFiles_ = 3, maximumFiles_ = 20, maximumAge_ = 7776000}++Supported file patterns:+{file} = takeFileName fp+{basename} = takeBaseName fp+{ext} = takeExtension fp -- this includes leading dot '.'+{modtime time-format}+++TODO:++-- logging+-- verbose mode+-- write docs+-- write examples++++See miniorotate.cabal for some more details.+
minirotate.cabal view
@@ -1,5 +1,5 @@ name: minirotate-version: 0.1.1.2+version: 0.1.2.0 synopsis: Minimalistic file rotation utility description: minirotate is minimalistic file rotation utility designed for calling from cron or similar tool.@@ -8,7 +8,7 @@ license-file: LICENSE author: Krzysztof Skrzetnicki <krzysztof.skrzetnicki+hackage@gmail.com> maintainer: Krzysztof Skrzetnicki <krzysztof.skrzetnicki+hackage@gmail.com>-homepage: http://github.com/Tener/haskell-minirotate+homepage: http://tener.github.com/haskell-minirotate/ stability: Beta build-type: Simple cabal-version: >= 1.6@@ -25,6 +25,7 @@ build-depends: filepath >= 1.1.0 && < 1.2.0, base >= 4 && < 5, directory >= 1,+ template-haskell >= 2.4, data-accessor-template == 0.2.1.3, data-accessor == 0.2.1.2, old-time >= 1,
src/Main.hs view
@@ -29,7 +29,7 @@ data FileOrDir = File | Dir deriving (Show,Ord,Eq) -- | auxilary function. to be replaced by proper logging.-logErr str = hPutStrLn stderr ("ERR: " ++ str)+logErr str = hPutStrLn stderr str main :: IO () main = do@@ -46,12 +46,15 @@ -copyOp :: CopyMode -> (FilePath -> FilePath -> IO ())--- copyOp Copy = \from to -> logErr (printf "COPY: %s -> %s" from to)--- copyOp Move = \from to -> logErr (printf "MOVE: %s -> %s" from to)-copyOp Copy = copyFile-copyOp Move = renameFile+copyOpDry :: Bool -> CopyMode -> (FilePath -> FilePath -> IO ())+copyOpDry True Copy = \from to -> logErr (printf "COPY: %s -> %s" from to)+copyOpDry True Move = \from to -> logErr (printf "MOVE: %s -> %s" from to)+copyOpDry False Copy = copyFile+copyOpDry False Move = renameFile +removeFileDry True fn = logErr (printf "REMOVE: %s" fn)+removeFileDry False fn = removeFile fn+ runRotate :: RunOptions -> [FilePath] -> IO () runRotate opts locs | length locs < 2 = logErr "Need at least one source location and destination\n" >> exitFailure | otherwise = do@@ -68,7 +71,7 @@ -- | oneLocation firstLevel? (element type, element name) oneLocation _ (File,fp) = do modTime <- getModificationTime fp- (copyOp (get copyMode $ opts)) fp (locTo </> (runPattern modTime fp))+ (copyOpDry (get dryRun $ opts) (get copyMode $ opts)) fp (locTo </> (runPattern modTime fp)) oneLocation True (Dir,fp) = do logErr (printf "Directory %s is a subdirectory at source site. Recursive operation is not supported. Skipping." (show fp))@@ -85,7 +88,7 @@ -- for each location decide if it's file or directory. -- then copy file to destination or report error.- mapM fileOrDir locFrom >>= mapM_ (either logErr (oneLocation False))+ (sort <$> mapM fileOrDir locFrom) >>= mapM_ (either logErr (oneLocation False)) -- rotate files in final directory rotateFiles opts locTo@@ -138,7 +141,7 @@ print (getKeptFiles partitionedFiles) -} - mapM_ removeFile (getDeletedFiles partitionedFiles)+ mapM_ (removeFileDry (get dryRun $ opts)) (getDeletedFiles partitionedFiles) return ()
src/Options.hs view
@@ -19,6 +19,7 @@ , minimumFiles_ :: Int -- ^ minimum # of files , maximumFiles_ :: Int -- ^ maximum # of files , maximumAge_ :: Int -- ^ oldest age allowed (in seconds)+ , dryRun_ :: Bool -- ^ should we really commit our operations? } deriving (Read,Show,Eq,Ord) @@ -44,6 +45,7 @@ , maximumFiles_ = 20 -- set maximum age to 3 months , maximumAge_ = 3600 {- hour -} * 24 {- day -} * 30 {- month -} * 3+ , dryRun_ = False } instance Default EnvOptions where@@ -94,6 +96,8 @@ (readErr "--max-age: bad format")) "NUMSEC") "maximum age of files to keep"+ , Option [] ["dry-run"] (NoArg (second .> dryRun ^= True))+ "don't remove or copy any files" -- TODO: logger, verbose ]
src/Pattern.hs view
@@ -25,15 +25,14 @@ , modtime_ :: ClockTime } -- $( deriveAccessors ''PatternEnv ) -makeEnv mt fp = PatternEnv { file_ = takeFileName fp- , basename_ = takeBaseName fp- , ext_ = takeExtension fp- , modtime_ = mt- }+makeEnv mt fp =+ PatternEnv { file_ = takeFileName fp+ , basename_ = takeBaseName fp+ , ext_ = takeExtension fp+ , modtime_ = mt+ } -- | compile file pattern and produce function that maps clock time and file name into resulting file name compilePattern :: String -> Either ErrString (ClockTime -> String -> String)@@ -71,12 +70,3 @@ formatCalendarTime defaultTimeLocale format ct) getFunction xx yy = Left (printf "Unknown function: '%s', args: %s" xx (show yy))----{--functions = ["file"- ,"basename"- ,"ext"- ,"modtime"]--}