* [bug#30708] [PATCH] utils: Add helper method to list subdirectories.
@ 2018-03-05 4:15 Maxim Cournoyer
2018-03-05 17:12 ` Ludovic Courtès
0 siblings, 1 reply; 4+ messages in thread
From: Maxim Cournoyer @ 2018-03-05 4:15 UTC (permalink / raw)
To: 30708
[-- Attachment #1: Type: text/plain, Size: 167 bytes --]
Hello Guix!
This adds a method useful to list subdirectories, which I am using to
list bundled copies of libraries (and delete them), for example.
Thank you,
Maxim
[-- Attachment #2: 0001-utils-Add-helper-method-to-list-subdirectories.patch --]
[-- Type: text/x-patch, Size: 4106 bytes --]
From b4b607800d770c4cf77f92c247276c368357e94f Mon Sep 17 00:00:00 2001
From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Date: Sun, 25 Feb 2018 17:49:06 -0500
Subject: [PATCH] utils: Add helper method to list subdirectories.
* guix/build/utils.scm (find-subdirectories): New procedure.
* tests/build-utils.scm: Rename module so that it can be used with Geiser.
(%test-dir-hierarchy): New variable.
(make-test-dir-hierarchy): New test procedure.
("find-subdirectories"): New test.
---
guix/build/utils.scm | 16 ++++++++++++++++
tests/build-utils.scm | 37 +++++++++++++++++++++++++++++++++++--
2 files changed, 51 insertions(+), 2 deletions(-)
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index 7391307c8..9a321bf3e 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
;;; Copyright © 2013 Nikita Karetnikov <nikita@karetnikov.org>
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2018 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -60,6 +61,7 @@
delete-file-recursively
file-name-predicate
find-files
+ find-subdirectories
search-path-as-list
set-path-environment-variable
@@ -395,6 +397,20 @@ also be included. If FAIL-ON-ERROR? is true, raise an exception upon error."
stat)
string<?)))
+(define* (find-subdirectories dir #:key fail-on-error?)
+ "Return the list of the immediate subdirectories of DIR."
+ ;; Strip the trailing '/' DIR is '/'.
+ (let ((dir (if (and (> 1 (string-length dir))
+ (eq? (string-take-right dir 1) #\/))
+ (string-drop-right dir 1)
+ dir)))
+ (define (pred filename stat)
+ (and (eq? (stat:type stat) 'directory)
+ (string-match (string-append dir "/[^/]*$") filename)))
+ (find-files dir pred
+ #:directories? #t
+ #:fail-on-error? fail-on-error?)))
+
\f
;;;
;;; Search paths.
diff --git a/tests/build-utils.scm b/tests/build-utils.scm
index 7d49446f6..6a3d43784 100644
--- a/tests/build-utils.scm
+++ b/tests/build-utils.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2018 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -17,7 +18,7 @@
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
-(define-module (test-build-utils)
+(define-module (tests build-utils)
#:use-module (guix tests)
#:use-module (guix build utils)
#:use-module ((guix utils)
@@ -27,7 +28,8 @@
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-64)
#:use-module (rnrs io ports)
- #:use-module (ice-9 popen))
+ #:use-module (ice-9 popen)
+ #:use-module (ice-9 match))
\f
(test-begin "build-utils")
@@ -122,4 +124,35 @@
(and (zero? (close-pipe pipe))
str))))))
+(define %test-dir-hierarchy
+ ;; The first element of a list is a file if the only element, otherwise
+ ;; a directory.
+ '("top"
+ ("subdir1"
+ ("subsubdir1"
+ "a-file.txt"
+ "another-file.c"))
+ ("subdir2"
+ "yet-another-one.h")
+ ("file.txt")))
+
+(define* (make-test-dir-hierarchy hierarchy #:optional (top (getcwd)))
+ (mkdir-p top)
+ (match hierarchy
+ ((dir . rest)
+ (for-each
+ (lambda (item)
+ (make-test-dir-hierarchy item (string-append top "/" dir)))
+ rest))
+ (file
+ (system (string-append "echo \"\" > " "\"" top "/" file "\"")))))
+
+(test-equal "find-subdirectories"
+ '("top/subdir1" "top/subdir2")
+ (call-with-temporary-directory
+ (lambda (directory)
+ (make-test-dir-hierarchy %test-dir-hierarchy directory)
+ (chdir directory)
+ (find-subdirectories "top"))))
+
(test-end)
--
2.16.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [bug#30708] [PATCH] utils: Add helper method to list subdirectories.
2018-03-05 4:15 [bug#30708] [PATCH] utils: Add helper method to list subdirectories Maxim Cournoyer
@ 2018-03-05 17:12 ` Ludovic Courtès
2018-03-06 2:18 ` Maxim Cournoyer
0 siblings, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2018-03-05 17:12 UTC (permalink / raw)
To: Maxim Cournoyer; +Cc: 30708
Hi Maxim,
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
> From b4b607800d770c4cf77f92c247276c368357e94f Mon Sep 17 00:00:00 2001
> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
> Date: Sun, 25 Feb 2018 17:49:06 -0500
> Subject: [PATCH] utils: Add helper method to list subdirectories.
>
> * guix/build/utils.scm (find-subdirectories): New procedure.
> * tests/build-utils.scm: Rename module so that it can be used with Geiser.
> (%test-dir-hierarchy): New variable.
> (make-test-dir-hierarchy): New test procedure.
> ("find-subdirectories"): New test.
[...]
> +(define* (find-subdirectories dir #:key fail-on-error?)
> + "Return the list of the immediate subdirectories of DIR."
> + ;; Strip the trailing '/' DIR is '/'.
> + (let ((dir (if (and (> 1 (string-length dir))
> + (eq? (string-take-right dir 1) #\/))
> + (string-drop-right dir 1)
> + dir)))
> + (define (pred filename stat)
> + (and (eq? (stat:type stat) 'directory)
> + (string-match (string-append dir "/[^/]*$") filename)))
> + (find-files dir pred
> + #:directories? #t
> + #:fail-on-error? fail-on-error?)))
‘find-files’ recurses in subdirectories, so the above implementation is
not as efficient as it could be.
I would instead suggest using ‘scandir’ (or ‘file-system-fold’) from
Guile’s (ice-9 ftw) module.
That said… is this a common enough operation?
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
* [bug#30708] [PATCH] utils: Add helper method to list subdirectories.
2018-03-05 17:12 ` Ludovic Courtès
@ 2018-03-06 2:18 ` Maxim Cournoyer
2018-03-06 10:33 ` bug#30708: " Ludovic Courtès
0 siblings, 1 reply; 4+ messages in thread
From: Maxim Cournoyer @ 2018-03-06 2:18 UTC (permalink / raw)
To: Ludovic Courtès; +Cc: 30708
Hi Ludovic,
ludo@gnu.org (Ludovic Courtès) writes:
> Hi Maxim,
>
> Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
>
>> From b4b607800d770c4cf77f92c247276c368357e94f Mon Sep 17 00:00:00 2001
>> From: Maxim Cournoyer <maxim.cournoyer@gmail.com>
>> Date: Sun, 25 Feb 2018 17:49:06 -0500
>> Subject: [PATCH] utils: Add helper method to list subdirectories.
>>
>> * guix/build/utils.scm (find-subdirectories): New procedure.
>> * tests/build-utils.scm: Rename module so that it can be used with Geiser.
>> (%test-dir-hierarchy): New variable.
>> (make-test-dir-hierarchy): New test procedure.
>> ("find-subdirectories"): New test.
>
> [...]
>
>> +(define* (find-subdirectories dir #:key fail-on-error?)
>> + "Return the list of the immediate subdirectories of DIR."
>> + ;; Strip the trailing '/' DIR is '/'.
>> + (let ((dir (if (and (> 1 (string-length dir))
>> + (eq? (string-take-right dir 1) #\/))
>> + (string-drop-right dir 1)
>> + dir)))
>> + (define (pred filename stat)
>> + (and (eq? (stat:type stat) 'directory)
>> + (string-match (string-append dir "/[^/]*$") filename)))
>> + (find-files dir pred
>> + #:directories? #t
>> + #:fail-on-error? fail-on-error?)))
>
> ‘find-files’ recurses in subdirectories, so the above implementation is
> not as efficient as it could be.
>
> I would instead suggest using ‘scandir’ (or ‘file-system-fold’) from
> Guile’s (ice-9 ftw) module.
Thanks! See the new patched attached. The test still passes.
> That said… is this a common enough operation?
I'm using it in a forthcoming new Guix package (SuperCollider) where it
allows me to explicitly list the bundled dependencies that are to be
*kept* rather than the ones to be removed, as is more commonly done. Without a
list of the subdirectories the contrib/vendor/whatever bundled
libraries directory I would not be able to do the following:
--8<---------------cut here---------------start------------->8---
+ ;; The build system doesn't allow us to unbundle the
+ ;; following libraries.
+ (let* ((all-dirs (find-subdirectories "./external_libraries"))
+ (keep-dirs '("nova-simd" "nova-tt" "hidapi" "TLSF-2.4.6"
+ "oscpack_1_1_0"))
+ (remove-dirs
+ (remove (lambda (x)
+ (member (basename x) keep-dirs))
+ all-dirs)))
+ (format #t "Removing bundled libraries: ~s\n" remove-dirs)
+ (for-each delete-file-recursively remove-dirs)))))))
--8<---------------cut here---------------end--------------->8---
Although now that you've made me see the light (scandir), I could
rewrite the whole thing using:
--8<---------------cut here---------------start------------->8---
(lambda _
;; The build system doesn't allow us to unbundle the following
;; libraries.
(let ((keep-dirs '("nova-simd" "nova-tt" "hidapi" "TLSF-2.4.6"
"oscpack_1_1_0" "." "..")))
(with-directory-excursion "./external_libraries"
(for-each
delete-file-recursively
(scandir "."
(lambda (x)
(and (eq? (stat:type (stat x)) 'directory)
(not (member (basename x) keep-dirs))))))))
--8<---------------cut here---------------end--------------->8---
So, this patch can go to the recycle bin. Thanks! :)
Maxim
^ permalink raw reply [flat|nested] 4+ messages in thread
* bug#30708: [PATCH] utils: Add helper method to list subdirectories.
2018-03-06 2:18 ` Maxim Cournoyer
@ 2018-03-06 10:33 ` Ludovic Courtès
0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2018-03-06 10:33 UTC (permalink / raw)
To: Maxim Cournoyer; +Cc: 30708-done
Hi Maxim,
Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:
> Although now that you've made me see the light (scandir), I could
> rewrite the whole thing using:
>
> (lambda _
> ;; The build system doesn't allow us to unbundle the following
> ;; libraries.
> (let ((keep-dirs '("nova-simd" "nova-tt" "hidapi" "TLSF-2.4.6"
> "oscpack_1_1_0" "." "..")))
> (with-directory-excursion "./external_libraries"
> (for-each
> delete-file-recursively
> (scandir "."
> (lambda (x)
> (and (eq? (stat:type (stat x)) 'directory)
> (not (member (basename x) keep-dirs))))))))
>
> So, this patch can go to the recycle bin. Thanks! :)
Well, I’m glad that it works for you. :-)
Thanks,
Ludo’.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-03-06 10:34 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-05 4:15 [bug#30708] [PATCH] utils: Add helper method to list subdirectories Maxim Cournoyer
2018-03-05 17:12 ` Ludovic Courtès
2018-03-06 2:18 ` Maxim Cournoyer
2018-03-06 10:33 ` bug#30708: " Ludovic Courtès
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).