packages feed

lsfrom 0.1.1.1 → 1.0

raw patch · 7 files changed

+147/−45 lines, 7 filesdep +safedep ~simple-cmddep ~simple-cmd-argssetup-changed

Dependencies added: safe

Dependency ranges changed: simple-cmd, simple-cmd-args

Files

ChangeLog.md view
@@ -1,5 +1,13 @@ # Release history for lsfrom +## 1.0 (2024-01-07)+- add --after: start with the next file after the specified one+- add --until: include files only up to the specified file+- add --before: changes the behaviour of --until+- add --strict: error if the specified files do not exist+- the short option for --all is now -A+-+ ## 0.1.1.1 (2022-04-24) - add missing test files - fix testsuite for lts 12 and earlier
LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2018, Jens Petersen+Copyright (c) 2018 and 2021-2024, Jens Petersen  All rights reserved. 
Main.hs view
@@ -1,27 +1,83 @@ module Main (main) where +import Data.List (dropWhileEnd) import SimpleCmd import SimpleCmdArgs+import Safe (tailSafe) import System.FilePath  import Paths_lsfrom (version)  main :: IO () main =-  simpleCmdArgs (Just version) "List files from pattern"-  "lsfrom lists the files in a directory that follow from the given pattern" $-  lsfrom <$> switchWith 'a' "all" "include hidden (dot) files" <*> strArg "FILEPAT"+  simpleCmdArgs (Just version) "List directories files starting from file"+  "lsfrom lists the files in a directory that follow from the given file" $+  lsfrom+  <$> switchWith 's' "strict" "fail if specified file(s) do not exist"+  <*> switchWith 'A' "all" "include hidden (dot) files"+  <*> switchWith 'a' "after" "files after STARTFILE [default: from STARTFILE]"+  <*> optional (removeTrailing <$> strOptionWith 'u' "until" "LASTFILE" "files until FILE")+  <*> switchWith 'b' "before" "files before LASTFILE (only affects --until)"+  <*> (removeTrailing <$> strArg "STARTFILE")+  where+    removeTrailing "" = ""+    removeTrailing "/" = "/"+    removeTrailing f =+      if last f == '/'+      then removeTrailing $ init f+      else f -lsfrom :: Bool -> FilePath -> IO ()-lsfrom hidden file = do-  let isdir = last file == pathSeparator-      file' = if isdir then takeDirectory file else file-      (dir,pat) = splitFileName file'-      pat' = pat ++ if isdir then [pathSeparator] else ""-  sorted <- do-    files <- cmd "ls" $ ["-A" | hidden || head pat == '.'] ++ [dir]-    lines <$> cmdStdIn "sort" [] (pat' ++ "\n" ++ files)-  let result = tail $ dropWhile (pat' /=) sorted-  mapM_ (putStrLn . (renderDir dir </>)) result+lsfrom :: Bool -> Bool -> Bool -> Maybe FilePath -> Bool -> FilePath -> IO ()+lsfrom strict hidden after muntil before file =+  case reverse (splitDirectories file) of+    [] -> error' "empty filename!"+    ("":_) -> error' "empty filename!"+    (entry@(e:_):revdir) -> do+      let dir = joinPath $ reverse revdir+      lsout <- cmd "ls" $+                 ["-A" | hidden || e == '.'] ++ [dir | not (null dir)]+      let lsEntries = lines lsout+          entryExists = entry `elem` lsEntries+          muntilExists =+            case muntil of+              Nothing -> Nothing+              Just until' ->+                Just (until', until' `elem` lsEntries)+      listingWith <-+        lines <$>+        if strict+        then return lsout+        else if entryExists+             then case muntilExists of+                    Just (until',False) ->+                      sortLs $ prepend until' lsout+                    _ -> return lsout+             else case muntilExists of+                    Just (until',False) ->+                      sortLs $+                      if entry == until'+                      then prepend entry lsout+                      else prepend entry $ prepend until' lsout+                    _ -> sortLs $ prepend entry lsout+      let result =+            takeUntil muntilExists $+            (if after || not entryExists then tailSafe else id) $+            dropWhile (entry /=) listingWith+      mapM_ (putStrLn . (renderDir dir </>)) result   where     renderDir dir = if dir == "./" then "" else dir++    sortLs :: String -> IO String+    sortLs = cmdStdIn "sort" []++    prepend :: String -> String -> String+    prepend miss ls = miss ++ '\n' : ls++    takeUntil :: Maybe (String,Bool) -> [String] -> [String]+    takeUntil Nothing es = es+    takeUntil (Just _) [] = []+    takeUntil (Just (until',exists)) es =+      case dropWhileEnd (until' /=) es of+        [] -> []+        es' ->+          (if before || not exists then init else id) es'
README.md view
@@ -1,38 +1,64 @@ # lsfrom -`lsfrom` lists the files and dirs in a directory starting from the first one-that matches the given filename prefix or the first filename after that-if there is no match, using the current locale collation order.+`lsfrom` lists the files and dirs in a directory starting from+the given filename or the first file after that+if the file does not exist, using the current locale collation order. -```+```shellsession $ ls A a B C-$ lsfrom a-a-B-C+$ echo $(lsfrom a)+a B C $ lsfrom a/+a B C $ lsfrom /sy /sys-/sysroot /tmp /usr /var ``` -This may be useful for continuing a script on the content of a directory+It can be useful for continuing a script on the entries of a directory after a failure, etc:  ```shellsession $ myscript.sh $(lsfrom next) ``` +or only running a command on a subrange of files in a directory.++## Usage++`$ lsfrom --version`+```+1.0+```+`$ lsfrom -h`+```+List directories files starting from file++Usage: lsfrom [--version] [-s|--strict] [-A|--all] [-a|--after]+              [-u|--until LASTFILE] [-b|--before] STARTFILE++  lsfrom lists the files in a directory that follow from the given file++Available options:+  -h,--help                Show this help text+  --version                Show version+  -s,--strict              fail if specified file(s) do not exist+  -A,--all                 include hidden (dot) files+  -a,--after               files after STARTFILE [default: from STARTFILE]+  -u,--until LASTFILE      files until FILE+  -b,--before              files before LASTFILE (only affects --until)+```+ ## Requirements -It uses system `ls` order to preserve locale collation-and requires ls with the `-A` option to exclude `.` and `..` (eg coreutils).+It uses `ls` to list files with locale sorting+and requires the `-A` option to exclude `.` and `..` (ie coreutils).+It also uses `sort` when injecting missing marker files. It has been tested on Linux.  ## Installation
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
lsfrom.cabal view
@@ -1,10 +1,11 @@+cabal-version:       2.0 name:                lsfrom-version:             0.1.1.1+version:             1.0 synopsis:            List directory files starting from a specific name description:-            `lsfrom` lists the contents of a directory starting from-            a particular prefix and those files after it-            with respect to locale collation.+            `lsfrom` lists the entries of a directory starting from+            a particular file and then the files after it+            with respect to locale collation ordering.              This can be useful for example for continuing a command or script             in a directory after a failure.@@ -12,12 +13,11 @@ license-file:        LICENSE author:              Jens Petersen <petersen@redhat.com> maintainer:          Jens Petersen <petersen@redhat.com>-copyright:           2018,2021-2022  Jens Petersen+copyright:           2018,2021-2024  Jens Petersen category:            Utility homepage:            https://github.com/juhp/lsfrom bug-reports:         https://github.com/juhp/lsfrom/issues build-type:          Simple-cabal-version:       1.18 extra-doc-files:     ChangeLog.md                      README.md extra-source-files:  test/files/A@@ -31,10 +31,12 @@ executable lsfrom   main-is:             Main.hs   other-modules:       Paths_lsfrom+  autogen-modules:     Paths_lsfrom   build-depends:       base < 5,                        filepath,-                       simple-cmd,-                       simple-cmd-args >= 0.1.1+                       safe,+                       simple-cmd >= 0.1.4,+                       simple-cmd-args >= 0.1.2   default-language:    Haskell2010   ghc-options:        -fwarn-missing-signatures -Wall   if impl(ghc >= 8.0)@@ -63,4 +65,4 @@                , directory >= 1.2.3.0                , filepath                , simple-cmd >= 0.1.1-  build-tools:   lsfrom+  build-tool-depends:   lsfrom:lsfrom
test/tests.hs view
@@ -4,20 +4,32 @@ import SimpleCmd import System.Directory -lsfrom :: (FilePath, String, [String]) -> IO ()-lsfrom (dir, arg, expect) = do+type Test = (FilePath, [String], [String])++lsfrom :: Test -> IO ()+lsfrom (dir, args, expect) = do   out <- withCurrentDirectory dir $-         cmdLines "lsfrom" [arg]+         cmdLines "lsfrom" args   unless (out == expect) $ do-    cmdN "lsfrom" [arg]+    cmdN "lsfrom" args     putStrLn $ "returned> " ++ show out     putStrLn $ "expected> " ++ show expect     error' "failed" -tests :: [(FilePath, String,[String])]+tests :: [Test] tests =-  [ ("test/files", "B", ["B","C"])-  , ("test", "files/B/", ["files/C"])+  [ ("test/files", ["B"], ["B","C"])+  , ("test/files", ["-a", "B"], ["C"])+  , ("test", ["files/C/"], ["files/C"])+  , ("test/files", ["Bb"], ["C"])+  , ("test/files", ["-u", "B", "A"], ["A", "B"])+  , ("test/files", ["-u", "C", "-b", "A"], ["A", "B"])+  , ("test/files", ["-u", "C", "-b", "-a", "A"], ["B"])+  , ("test/files", ["-u", "A", "-b", "-a", "C"], [])+  , ("test/files", ["-u", "B", "-b", "B"], [])+  , ("test/files", ["-u", "B", "-a", "B"], [])+  , ("test/files", ["-u", "B", "-a", "-b", "B"], [])+  , ("test/files", ["-s", "-u", "B", "A"], ["A", "B"])   ]  main :: IO ()