turtle icon indicating copy to clipboard operation
turtle copied to clipboard

Feature proposal: gfind

Open cfhammill opened this issue 6 years ago • 2 comments

I think having a more full featured find utility would be great.

I figured I'd post a plan to get ideas before I start trying to write it. In my head it's gfind because it's going to implement more of the features of gnu find.

Desired Features (a start at)

  • Non-recursive use
  • Depth limitation like -maxdepth and -mindepth
  • File status limitation like -cmin and -amin
  • File type limitation like -type

Implementation concerns

A feature rich find would have a huge number of parameters most of which wouldn't be necessary for every use. So optional arguments are almost definitely necessary. I think an approach inspired by: http://neilmitchell.blogspot.ca/2008/04/optional-parameters-in-haskell.html could be useful.

To avoid namespacing issues we could use vinyl records, an example might look like:

gfind path (chars) ((MinDepth ==: 1) :& (MaxDepth == : 1))

A global set of defaults can be defined by the package and the users options can be integrated with the defaults via rreplace

Any thoughts and suggestions would be appreciated.

cfhammill avatar Mar 24 '18 23:03 cfhammill

My intution is that if we design this correctly we won't need to have many parameters. Some of these desired features could be split out into orthogonal utilities. In the spirit of the Unix philosophy we want each utility to do one thing and do it well!

Specifically, I think you could split it up like this:

  • Create a lsdepth utility that is like lstree except with a minimum and maximum depth

    lsdepth :: Int -> Int -> FilePath -> Shell FilePath
    
  • Structure the generalized find to take a Shell FilePath as an input instead of a FilePath

    findtree :: Pattern a -> Shell FilePath -> Shell FilePath
    

    This way users can customize what files to traverse by supplying ls, lstree, lsdepth, or their own hand-written directory traversal:

    findtree (suffix ".exe") (ls ".") -- Only search the current directory
    
    findtree (suffix ".exe") (lsdepth 0 3 ".") -- Only search three levels down
    
  • For file status filter, provide simple predicate functions, like:

    cmin, cmax :: UTCTime -> FilePath -> Bool
    

    Then filtering the returned files just becomes Control.Monad.mfilter

    mfilter (cmin someTime) (findtree (suffix ".exe") (ls ".")) -- Find files created after `someTime`
    

Gabriella439 avatar Mar 25 '18 02:03 Gabriella439

That seems like a better way to structure this, I'll give writing it a shot and report back.

cfhammill avatar Mar 25 '18 22:03 cfhammill