From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mark H Weaver Subject: [PATCH] union: Ensure that the output is always a directory Date: Thu, 03 Apr 2014 18:04:51 -0400 Message-ID: <87mwg2gjcs.fsf_-_@yeeloong.lan> References: <871txfk26u.fsf@yeeloong.lan> <87ha6anp8g.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:47155) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WVplt-00080R-Ej for guix-devel@gnu.org; Thu, 03 Apr 2014 18:06:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WVplo-0003qX-35 for guix-devel@gnu.org; Thu, 03 Apr 2014 18:06:05 -0400 In-Reply-To: <87ha6anp8g.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Thu, 03 Apr 2014 22:15:59 +0200") List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: Ludovic =?utf-8?Q?Court=C3=A8s?= Cc: guix-devel@gnu.org --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable ludo@gnu.org (Ludovic Court=C3=A8s) writes: > I stumbled upon this bug: building a profile with a single package > fails, because the new union.scm makes the profile directory a symlink > to that package, which then prevents the creation of the =E2=80=98manifes= t=E2=80=99 > file: Indeed! Here's a patch that fixes that problem. Thanks, Mark --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: inline; filename=0001-union-Ensure-that-the-output-is-always-a-directory.patch Content-Transfer-Encoding: quoted-printable Content-Description: [PATCH] union: Ensure that the output is always a directory >From 6c8582bc41c8935b8e9d63146595e87d9b92fa95 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Thu, 3 Apr 2014 17:49:20 -0400 Subject: [PATCH] union: Ensure that the output is always a directory. MIME-Version: 1.0 Content-Type: text/plain; charset=3DUTF-8 Content-Transfer-Encoding: 8bit Fixes the creation of single-package profiles, reported by Ludovic Court=C3= =A8s. * guix/build/union.scm (union-build): Add new internal procedure 'union-of-directories' that always creates a directory, containing the co= de previously used only to merge multiple directories. Call it from the multiple-directory case in 'union' and from the top-level 'union-build'. --- guix/build/union.scm | 53 +++++++++++++++++++++++++++---------------------= ---- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/guix/build/union.scm b/guix/build/union.scm index c65bea4..ccd2d5c 100644 --- a/guix/build/union.scm +++ b/guix/build/union.scm @@ -108,30 +108,8 @@ the INPUTS." (call-with-values (lambda () (partition file-is-directory? inputs)) (match-lambda* ((dirs ()) - ;; All inputs are directories. Create a new directory - ;; where we will merge the input directories. - (mkdir output) - - ;; Build a hash table mapping each file to a list of input - ;; directories containing that file. - (let ((table (make-hash-table))) - - (define (add-to-table! file dir) - (hash-set! table file (cons dir (hash-ref table file '()))= )) - - ;; Populate the table. - (for-each (lambda (dir) - (for-each (cut add-to-table! <> dir) - (files-in-directory dir))) - dirs) - - ;; Now iterate over the table and recursively - ;; perform a union for each entry. - (hash-for-each (lambda (file dirs-with-file) - (union (string-append output "/" file) - (map (cut string-append <> "/" file) - (reverse dirs-with-file)))) - table))) + ;; All inputs are directories. + (union-of-directories output dirs)) =20 ((() (file (? (cut file=3D? <> file)) ...)) ;; There are no directories, and all files have the same conte= nts, @@ -141,11 +119,36 @@ the INPUTS." ((dirs files) (resolve-collisions output dirs files))))))) =20 + (define (union-of-directories output dirs) + ;; Create a new directory where we will merge the input directories. + (mkdir output) + + ;; Build a hash table mapping each file to a list of input + ;; directories containing that file. + (let ((table (make-hash-table))) + + (define (add-to-table! file dir) + (hash-set! table file (cons dir (hash-ref table file '())))) + + ;; Populate the table. + (for-each (lambda (dir) + (for-each (cut add-to-table! <> dir) + (files-in-directory dir))) + dirs) + + ;; Now iterate over the table and recursively + ;; perform a union for each entry. + (hash-for-each (lambda (file dirs-with-file) + (union (string-append output "/" file) + (map (cut string-append <> "/" file) + (reverse dirs-with-file)))) + table))) + (setvbuf (current-output-port) _IOLBF) (setvbuf (current-error-port) _IOLBF) (when (file-port? log-port) (setvbuf log-port _IOLBF)) =20 - (union output (delete-duplicates inputs))) + (union-of-directories output (delete-duplicates inputs))) =20 ;;; union.scm ends here --=20 1.8.4 --=-=-=--