Permalink
Browse files

Merge search task into mainlein. (har har)

  • Loading branch information...
technomancy committed May 5, 2011
1 parent 1938e64 commit e3c1847245ea1a234cbb90caf648e654ee6de263
Showing with 96 additions and 3 deletions.
  1. +1 −0 project.clj
  2. +1 −3 src/leiningen/repl.clj
  3. +75 −0 src/leiningen/search.clj
  4. +19 −0 test/leiningen/test/search.clj
  5. BIN test/sample-index.zip
View
@@ -8,6 +8,7 @@
:license {:name "Eclipse Public License"}
:dependencies [[org.clojure/clojure "1.2.1"]
[org.clojure/clojure-contrib "1.2.0"]
+ [clucy "0.2.0"]
[lancet "1.0.0"]
[jline "0.9.94"]
[robert/hooke "1.1.0"]
View
@@ -53,9 +53,7 @@
(let [server# (ServerSocket. ~port 0 (InetAddress/getByName ~host))
acc# (fn [s#]
(let [ins# (.getInputStream s#)
- outs# (.getOutputStream s#)
- skip-whitespace# @(ns-resolve '~'clojure.main
- '~'skip-whitespace)]
+ outs# (.getOutputStream s#)]
(doto (Thread.
#(binding [*in* (-> ins# InputStreamReader.
LineNumberingPushbackReader.)
View
@@ -0,0 +1,75 @@
+(ns leiningen.search
+ (:use [leiningen.core :only [home-dir repositories-for user-settings]]
+ [leiningen.util.file :only [delete-file-recursively]])
+ (:require [clojure.java.io :as io]
+ [clojure.string :as string]
+ [clucy.core :as clucy])
+ (:import (java.util.zip ZipFile)
+ (java.net URL)))
+
+(defn- unzip [source target-dir]
+ (let [zip (ZipFile. source)
+ entries (enumeration-seq (.entries zip))
+ target-file #(io/file target-dir (.getName %))]
+ (doseq [entry entries :when (not (.isDirectory entry))
+ :let [f (target-file entry)]]
+ (.mkdirs (.getParentFile f))
+ (io/copy (.getInputStream zip entry) f))))
+
+(defn index-location [url]
+ (io/file (home-dir) "indices" (string/replace url #"[:/]" "_")))
+
+(defn remote-index-location [url]
+ (format "%s/.index/nexus-maven-repository-index.zip" url))
+
+(defn- download-index [[id {url :url}]]
+ (with-open [stream (.openStream (URL. (remote-index-location url)))]
+ (println "Downloading index from" id "-" url)
+ (let [tmp (java.io.File/createTempFile "lein" "index")]
+ (try (io/copy stream tmp)
+ (unzip tmp (index-location url))
+ (finally (.delete tmp))))))
+
+(defn- download-needed? [[id {:keys [url]}]]
+ (not (.exists (index-location url))))
+
+(defn ensure-fresh-index [repository]
+ (try (when (download-needed? repository)
+ (download-index repository))
+ true
+ (catch java.io.FileNotFoundException _
+ false)))
+
+(defn search-repository [[id {:keys [url]} :as repo] query]
+ (if (ensure-fresh-index repo)
+ (clucy/search (clucy/disk-index (.getAbsolutePath (index-location url)))
+ query (:search-page-size (user-settings) 25) :a)
+ (binding [*out* *err*]
+ (println "Warning: couldn't download index for" url))))
+
+(defn parse-result [{:keys [u d]}]
+ (let [[group artifact version classifier] (.split u "\\|")
+ group (if (not= group artifact) group)
+ identifier [(symbol group artifact) version]]
+ (if d
+ [identifier d]
+ [identifier])))
+
+(defn- print-results [results]
+ (doseq [result (sort-by ffirst (map parse-result results))]
+ (apply println result)))
+
+(defn search
+ "Search remote repository contents.
+
+The first run will download a set of indices, which will take a
+while. Pass in --update as the query to force a fresh download of all
+indices."
+ [project query]
+ ;; you know what would be just super? pattern matching.
+ (if (= "--update" query)
+ (doseq [[_ {url :url} :as repo] (repositories-for project)]
+ (delete-file-recursively (index-location url) :silently)
+ (ensure-fresh-index repo))
+ (doseq [repo (repositories-for project)]
+ (print-results (search-repository repo query)))))
@@ -0,0 +1,19 @@
+(ns leiningen.test.search
+ (:require [clojure.java.io :as io])
+ (:use [clojure.test]
+ [leiningen.search]))
+
+(deftest test-download
+ (is (= ["segments.gen" "_0.cfx" "timestamp" "_0.cfs" "segments_2"]
+ (vec (.list (index-location "http://example.com/repo"))))))
+
+(deftest test-searchy
+ (binding [remote-index-location (constantly "file://test/sample-index.zip")]
+ (ensure-fresh-index ["test" {:url "http://example.com/repo"}])
+ (let [results (search-repository ["test" {:url "http://example.com/repo"}]
+ "hooke")]
+ (is (= '#{[[robert/hooke "1.0.0"] "Hooke your functions!"]
+ [[robert/hooke "1.0.1"] "Hooke your functions!"]
+ [[robert/hooke "1.0.2"] "Hooke your functions!"]
+ [[robert/hooke "1.1.0"] "Hooke your functions!"]}
+ (set (map parse-result results)))))))
View
Binary file not shown.

0 comments on commit e3c1847

Please sign in to comment.