|
119 | 119 | %)]
|
120 | 120 | (map flag frames)))
|
121 | 121 |
|
122 |
| -(def directory-namespaces |
123 |
| - "This looks for all namespaces inside of directories on the class |
124 |
| - path, ignoring jars." |
| 122 | +(defn directory-namespaces |
| 123 | + "Looks for all namespaces inside of directories on the class |
| 124 | + path, ignoring jars. |
| 125 | +
|
| 126 | + It's a defn because this set is always subject to change. |
| 127 | +
|
| 128 | + NOTE: depending on the use case, you might want to filter out |
| 129 | + namespaces such as `user` which while belong to the project, |
| 130 | + don't share a common naming scheme with the other namespaces." |
| 131 | + [] |
125 | 132 | (into #{} (namespace/project-namespaces)))
|
126 | 133 |
|
127 |
| -(def ns-common-prefix |
128 |
| - "In order to match more namespaces, we look for a common namespace |
129 |
| - prefix across the ones we have identified." |
| 134 | +(defn ns-common-prefix* [namespaces] |
130 | 135 | (let [common
|
131 |
| - (try (reduce |
132 |
| - (fn [common ns] |
133 |
| - (let [ns (str/lower-case ns) |
134 |
| - matched (map vector common ns) |
135 |
| - coincident (take-while (fn [[a b]] (= a b)) matched)] |
136 |
| - (apply str (map first coincident)))) |
137 |
| - (str/lower-case (first directory-namespaces)) |
138 |
| - directory-namespaces) |
139 |
| - (catch Throwable _e :error))] |
| 136 | + (try |
| 137 | + (->> namespaces |
| 138 | + (pmap (fn [ns-sym] |
| 139 | + (let [segments (-> ns-sym |
| 140 | + str |
| 141 | + (str/split #"\."))] |
| 142 | + ;; remove single-segment namespaces |
| 143 | + ;; (such as `dev`, `test`, `test-runner`) |
| 144 | + ;; that would break the commonality: |
| 145 | + (when (-> segments count (> 1)) |
| 146 | + segments)))) |
| 147 | + (filter identity) |
| 148 | + (reduce (fn [prev curr] |
| 149 | + (if (= ::placeholder prev) |
| 150 | + curr |
| 151 | + (let [found-commonality |
| 152 | + (reduce-kv (fn [result k v] |
| 153 | + (if (= (get prev k) |
| 154 | + (get curr k)) |
| 155 | + (conj result v) |
| 156 | + (reduced result))) |
| 157 | + [] |
| 158 | + prev)] |
| 159 | + (if (seq found-commonality) |
| 160 | + found-commonality |
| 161 | + (reduced :missing))))) |
| 162 | + ::placeholder)) |
| 163 | + (catch Throwable _e :error))] |
140 | 164 | (condp = common
|
141 |
| - "" |
| 165 | + ::placeholder |
| 166 | + {:valid false :common :missing} |
| 167 | + |
| 168 | + :missing |
142 | 169 | {:valid false :common :missing}
|
143 | 170 |
|
144 | 171 | :error
|
145 | 172 | {:valid false :common :error}
|
146 | 173 |
|
147 |
| - ;;default |
148 |
| - {:valid true :common common}))) |
| 174 | + {:valid true :common (str/join "." common)}))) |
| 175 | + |
| 176 | +(def ns-common-prefix |
| 177 | + "In order to match more namespaces, we look for a common namespace |
| 178 | + prefix across the ones we have identified." |
| 179 | + (delay |
| 180 | + (ns-common-prefix* (directory-namespaces)))) |
149 | 181 |
|
150 | 182 | (defn flag-project
|
151 | 183 | "Flag the frame if it is from the users project. From a users
|
152 | 184 | project means that the namespace is one we have identified or it
|
153 | 185 | begins with the identified common prefix."
|
154 | 186 | [{:keys [ns] :as frame}]
|
155 |
| - (if (and directory-namespaces ns |
156 |
| - (or (contains? directory-namespaces (symbol ns)) |
157 |
| - (when (:valid ns-common-prefix) |
158 |
| - (.startsWith ^String ns (:common ns-common-prefix))))) |
| 187 | + (if (and ns |
| 188 | + (or (contains? (directory-namespaces) (symbol ns)) |
| 189 | + (when (:valid @ns-common-prefix) |
| 190 | + (.startsWith ^String ns (:common @ns-common-prefix))))) |
159 | 191 | (flag-frame frame :project)
|
160 | 192 | frame))
|
161 | 193 |
|
|
0 commit comments