local/share/common-lisp/source/ambrevar/shell: Add finder and make-directory.

master
Pierre Neidhardt 2020-11-07 17:07:04 +01:00
parent 4ba21f0b75
commit f1ed246c39
1 changed files with 53 additions and 5 deletions

View File

@ -2,13 +2,61 @@
(:documentation "Shell-like utilities.")
(:nicknames #:$)
(:use :common-lisp)
(:import-from #:serapeum #:export-always)
(:import-from #:trivial-package-local-nicknames))
(:import-from #:serapeum #:export-always))
(in-package #:ambrevar/shell)
(eval-when (:compile-toplevel :load-toplevel :execute)
(trivial-package-local-nicknames:add-package-local-nickname :alex :alexandria)
(trivial-package-local-nicknames:add-package-local-nickname :sera :serapeum))
(serapeum:export-always 'foo)
(defun foo ()
17)
(defun assert-program (program &rest more-programs) ; TODO: Is this useful for a REPL?
(sera:and-let* ((missing-programs
(delete-if #'sera:resolve-executable (cons program more-programs))))
(error "Missing programs: ~{~a~,^, ~}" missing-programs)))
(export-always 'file-extension)
(defun file-extension (file)
"Return the file extension.
If none, return the empty string unlike `pathname-type'."
(or (pathname-type file)
""))
(export-always 'file-basename)
(defun file-basename (file)
"Return the file basename (including the extension)."
(apply #'str:concat (pathname-name file)
(sera:and-let* ((ext (file-extension file)))
`("." ,ext))))
(export-always 'match-extensions)
(defun match-extensions (extension &rest more-extensions)
"Return a predicate for files that match on of the provided extensions.
Useful for `finder'."
(lambda (file)
(some (lambda (ext)
(string= ext (pathname-type file)))
(cons extension more-extensions))))
(export-always 'finder)
(defun finder (root &rest predicates)
"List files in directory that satisfy all PREDICATES.
Without PREDICATES, list all files."
(let ((result '()))
(uiop:collect-sub*directories
(uiop:ensure-directory-pathname root)
(constantly t) (constantly t)
(lambda (subdirectory)
(setf result (nconc result
(let ((subfiles (uiop:directory-files subdirectory)))
(if predicates
(delete-if (lambda (file)
(notany (lambda (pred) (funcall pred file))
predicates))
subfiles)
subfiles))))))
result))
(export-always 'make-directory)
(defun make-directory (path)
"Including parents."
(uiop:ensure-all-directories-exist (list (uiop:ensure-directory-pathname path)))
path)