From d06fcb46f34636a662467289f39fa28423f7b682 Mon Sep 17 00:00:00 2001
From: Robert Vollmert <rob@vllmrt.net>
Date: Fri, 24 May 2019 16:00:25 +0200
Subject: [PATCH 13/13] guix import hackage: Add flag to allow bypassing
 existing packages.

This adds a command line flag `-i` which causes recursive import
to reimport packages that are already part of guix, allowing a way
to easily define updated versions of stale packages.

* guix/import/utils.scm (recursive-import): Add keyword argument `#:ignore-existing?`.
* guix/import/hackage.scm (hackage-recursive-import): Add keyword argument `#:ignore-existing?`.
* guix/scripts/import/hackage.scm: Add flag -i/--ignore.
* doc/guix.tex (import hackage): Document flag -i/--ignore.
---
 doc/guix.texi                   |  4 ++++
 guix/import/hackage.scm         |  8 +++++---
 guix/import/utils.scm           |  5 +++--
 guix/scripts/import/hackage.scm | 11 ++++++++++-
 4 files changed, 22 insertions(+), 6 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index ae9ad0739e..45f2f14fd8 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8692,6 +8692,10 @@ associated with the keys @code{os}, @code{arch} and @code{impl} is
 Traverse the dependency graph of the given upstream package recursively
 and generate package expressions for all those packages that are not yet
 in Guix.
+@item --ignore
+@itemx -i
+When importing recursively, generate package expressions also for
+dependencies that are already in Guix.
 @end table
 
 The command below imports metadata for the latest version of the
diff --git a/guix/import/hackage.scm b/guix/import/hackage.scm
index 405294d186..d6f5448cfc 100644
--- a/guix/import/hackage.scm
+++ b/guix/import/hackage.scm
@@ -308,7 +308,8 @@ the hash of the Cabal file."
   (lambda* (package-name #:key
                          (include-test-dependencies? #t)
                          (port #f)
-                         (cabal-environment '()))
+                         (cabal-environment '())
+                         #:allow-other-keys)
    "Fetch the Cabal file for PACKAGE-NAME from hackage.haskell.org, or, if the
 called with keyword parameter PORT, from PORT.  Return the `package'
 S-expression corresponding to that package, or #f on failure.
@@ -337,11 +338,12 @@ respectively."
 (define hackage->guix-package
   (memoize hackage->guix-package-impl))
 
-(define* (hackage-recursive-import package-name . args)
+(define* (hackage-recursive-import package-name #:key ignore-existing? #:allow-other-keys #:rest args)
   (recursive-import package-name #f
                     #:repo->guix-package (lambda (name repo)
                                            (apply hackage->guix-package (cons name args)))
-                    #:guix-name hackage-name->package-name))
+                    #:guix-name hackage-name->package-name
+                    #:ignore-existing? ignore-existing?))
 
 (define (hackage-package? package)
   "Return #t if PACKAGE is a Haskell package from Hackage."
diff --git a/guix/import/utils.scm b/guix/import/utils.scm
index ff548b809a..3ae31e497c 100644
--- a/guix/import/utils.scm
+++ b/guix/import/utils.scm
@@ -374,12 +374,13 @@ separated by PRED."
                                     name)))
 
 (define* (recursive-import package-name repo
-                           #:key repo->guix-package guix-name
+                           #:key repo->guix-package guix-name ignore-existing?
                            #:allow-other-keys)
   "Generate a stream of package expressions for PACKAGE-NAME and all its
 dependencies."
   (define (exists? dependency)
-    (not (null? (find-packages-by-name (guix-name dependency)))))
+    (and (not ignore-existing?)
+         (not (null? (find-packages-by-name (guix-name dependency))))))
   (define initial-state (list #f (list package-name) (list)))
   (define (step state)
     (match state
diff --git a/guix/scripts/import/hackage.scm b/guix/scripts/import/hackage.scm
index f4aac61078..6574adf010 100644
--- a/guix/scripts/import/hackage.scm
+++ b/guix/scripts/import/hackage.scm
@@ -59,6 +59,8 @@ version.\n"))
   (display (G_ "
   -h, --help                   display this help and exit"))
   (display (G_ "
+  -i, --ignore                 ignore existing packages on recursive import"))
+  (display (G_ "
   -r, --recursive              import packages recursively"))
   (display (G_ "
   -s, --stdin                  read from standard input"))
@@ -96,6 +98,11 @@ version.\n"))
          (option '(#\r "recursive") #f #f
                  (lambda (opt name arg result)
                    (alist-cons 'recursive #t result)))
+
+         (option '(#\i "ignore") #f #f
+                 (lambda (opt name arg result)
+                   (alist-cons 'ignore-existing? #t result)))
+
          %standard-import-options))
 
 
@@ -122,7 +129,9 @@ version.\n"))
                                   (current-input-port)
                                   #f)
                        #:cabal-environment
-                       (assoc-ref opts 'cabal-environment)))
+                       (assoc-ref opts 'cabal-environment)
+                       #:ignore-existing?
+                       (assoc-ref opts 'ignore-existing?)))
            (sexp (if (assoc-ref opts 'recursive)
                      ;; Recursive import
                      (map (match-lambda
-- 
2.21.0

