From ec5f8f13824c8fda646756ef0119e052a4e9a83f Mon Sep 17 00:00:00 2001
From: Cam Saul <1455846+camsaul@users.noreply.github.com>
Date: Thu, 30 Apr 2020 15:11:16 -0700
Subject: [PATCH] Fix include-drivers lein middleware (#12436)

* Fix include-plugins middleware when we use multiple lein with-profiles

* Bump core project dep version
---
 lein-plugins/include-drivers/project.clj      |  2 +-
 .../src/leiningen/include_drivers.clj         | 35 ++++++++++---------
 project.clj                                   |  2 +-
 src/metabase/plugins/classloader.clj          |  8 +++--
 4 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/lein-plugins/include-drivers/project.clj b/lein-plugins/include-drivers/project.clj
index a806ea64b78..149577d8aac 100644
--- a/lein-plugins/include-drivers/project.clj
+++ b/lein-plugins/include-drivers/project.clj
@@ -1,4 +1,4 @@
-(defproject metabase/lein-include-drivers "1.0.8"
+(defproject metabase/lein-include-drivers "1.0.9"
   :min-lein-version "2.5.0"
   :eval-in-leiningen true
   :deploy-repositories [["clojars" {:sign-releases false}]]
diff --git a/lein-plugins/include-drivers/src/leiningen/include_drivers.clj b/lein-plugins/include-drivers/src/leiningen/include_drivers.clj
index 4d7eefe8516..94160c08261 100644
--- a/lein-plugins/include-drivers/src/leiningen/include_drivers.clj
+++ b/lein-plugins/include-drivers/src/leiningen/include_drivers.clj
@@ -1,8 +1,13 @@
 (ns leiningen.include-drivers
-  (:require [clojure.string :as str]
-            [colorize.core :as colorize]
-            [leiningen.core.project :as p])
-  (:import java.io.File))
+     (:require [clojure.string :as str]
+               [colorize.core :as colorize]
+               [leiningen.core.project :as p])
+     (:import java.io.File))
+
+(defonce ^:private ^{:arglists '([s]), :doc "Log a message `s` the first time we see it. This middleware might run
+  multiple times, and we only really need to log a message the first time we see it."}
+  log-once
+  (comp (memoize println) str))
 
 (defn- file-exists? [^String filename]
   (.exists (File. filename)))
@@ -35,12 +40,12 @@
   {:pre [(string? driver) (seq driver)]}
   (if-let [{:keys [include-drivers-dependencies]} (driver->project driver)]
     (or (every? plugins-file-exists? include-drivers-dependencies)
-        (println
+        (log-once
          (colorize/color
           :red
           (format "[include-drivers middleware] Not including %s because not all dependencies matching %s found in /plugins"
                   driver (set include-drivers-dependencies)))))
-    (println
+    (log-once
      (colorize/color
       :red
       (format "[include-drivers middleware] Not including %s because we could not its project.clj" driver)))))
@@ -59,7 +64,7 @@
           :else
           (some-> (System/getenv "DRIVERS") (str/split #",") set (disj "h2" "postgres" "mysql")))
 
-        _ (println
+        _ (log-once
            (colorize/color
             :magenta
             (format "[include-drivers middleware] Attempting to include these drivers: %s" (set drivers))))
@@ -120,7 +125,7 @@
 (defn- test-drivers-profile [project]
   (let [test-drivers  (test-drivers project)
         test-projects (test-drivers-projects test-drivers)]
-    (println
+    (log-once
      (colorize/color
       :magenta
       (format "[include-drivers middleware] including these drivers: %s" (set test-drivers))))
@@ -130,17 +135,13 @@
      :source-paths (test-drivers-source-paths test-drivers)
      :test-paths   (test-drivers-test-paths   test-drivers)}))
 
-;; When we merge a new profile into the project Leiningen will reload the project, which will cause our middleware to
-;; run a second time. Make sure we don't add the profile a second time or we'll be stuck in an infinite loop of adding
-;; a new profile and reloading.
-(defonce ^:private has-added-test-drivers-profile? (atom false))
-
 (defn middleware
   "Add dependencies, source paths, and test paths for to Metabase drivers that are packaged as separate projects and
   specified by the `DRIVERS` env var."
   [project]
-  (if @has-added-test-drivers-profile?
+  ;; When we merge a new profile into the project Leiningen will reload the project, which will cause our middleware
+  ;; to run a second time. Make sure we don't add the profile a second time or we'll be stuck in an infinite loop of
+  ;; adding a new profile and reloading.
+  (if (::has-driver-profiles? project)
     project
-    (do
-      (reset! has-added-test-drivers-profile? true)
-      (p/merge-profiles project [(test-drivers-profile project)]))))
+    (p/merge-profiles project [(test-drivers-profile project) {::has-driver-profiles? true}])))
diff --git a/project.clj b/project.clj
index 9b4d67ecccc..9b772a2d7f0 100644
--- a/project.clj
+++ b/project.clj
@@ -251,7 +251,7 @@
 
    :with-include-drivers-middleware
    {:plugins
-    [[metabase/lein-include-drivers "1.0.8"]]
+    [[metabase/lein-include-drivers "1.0.9"]]
 
     :middleware
     [leiningen.include-drivers/middleware]}
diff --git a/src/metabase/plugins/classloader.clj b/src/metabase/plugins/classloader.clj
index 07c05fba4a8..1e17626d0f3 100644
--- a/src/metabase/plugins/classloader.clj
+++ b/src/metabase/plugins/classloader.clj
@@ -12,7 +12,8 @@
 
   <3 Cam"
   (:refer-clojure :exclude [require])
-  (:require [clojure.tools.logging :as log]
+  (:require [clojure.string :as str]
+            [clojure.tools.logging :as log]
             [dynapath.util :as dynapath]
             [metabase.util.i18n :refer [deferred-trs]])
   (:import [clojure.lang DynamicClassLoader RT]
@@ -126,8 +127,9 @@
         (apply clojure.core/require args)))
     (catch Throwable e
       (throw (ex-info (.getMessage e)
-                      {:classloader    (the-classloader)
-                       :classpath-urls (map str (dynapath/all-classpath-urls (the-classloader)))}
+                      {:classloader      (the-classloader)
+                       :classpath-urls   (map str (dynapath/all-classpath-urls (the-classloader)))
+                       :system-classpath (sort (str/split (System/getProperty "java.class.path") #"[:;]"))}
                       e)))))
 
 (defonce ^:private already-added (atom #{}))
-- 
GitLab