diff --git a/src/rules_clojure/gen_build.clj b/src/rules_clojure/gen_build.clj index 3ff8a46..da163ff 100644 --- a/src/rules_clojure/gen_build.clj +++ b/src/rules_clojure/gen_build.clj @@ -660,60 +660,71 @@ "given a source directory, write a BUILD.bazel for all .clj files in the directory. non-recursive" [{:keys [deps-edn-dir] :as args} dir] (assert (map? (:src-ns->label args))) - (let [paths (->> (fs/ls dir) + (let [entries (fs/ls dir) + paths (->> entries (filter (fn [p] (or (clj*-path? p) (js-path? p)))) (sort-by str)) - subdirs (->> dir - fs/ls + build-file (-> dir (fs/->path "BUILD.bazel") fs/path->file) + build-mtime (when (.exists build-file) (.lastModified build-file)) + subdirs (->> entries (filter (fn [^Path p] (-> p .toFile fs/directory?))) (sort-by str)) - clj-subdirs (->> - subdirs - (filter (fn [p] - (some clj*-path? (seq (fs/ls-r p)))))) - [has-binary? rules] (reduce (fn [[hb? acc] rule] - [(or hb? (= :clojure_binary (:type rule))) - (conj acc (emit-rule rule))]) - [false []] - (->> paths - (group-by fs/basename) - (mapcat (fn [[_base paths]] - (ns-rules args paths))))) - - content (str "#autogenerated, do not edit\n" - (emit-bazel (list 'package (kwargs {:default_visibility ["//visibility:public"]}))) - "\n" - (emit-bazel (apply list 'load "@rules_clojure//:rules.bzl" - (cond-> ["clojure_library" "clojure_test"] - has-binary? (conj "clojure_binary")))) - "\n" - "\n" - (str/join "\n\n" rules) - "\n" - "\n" - (when (or (seq paths) (seq clj-subdirs)) - (str - (emit-bazel (list 'clojure_library (kwargs {:name "__clj_lib" - :deps (vec - (concat - (dedupe (map (fn [p] (str ":" (fs/basename p))) paths)) - (map (fn [p] - (str "//" (fs/path-relative-to deps-edn-dir p) ":__clj_lib")) clj-subdirs)))}))) - "\n" - "\n" - (emit-bazel (list 'filegroup (kwargs (merge - {:name "__clj_files" - :srcs (mapv fs/filename paths) - :data (mapv (fn [p] - (str "//" (fs/path-relative-to deps-edn-dir p) ":__clj_files")) clj-subdirs)})))))))] - (let [build-file (-> dir (fs/->path "BUILD.bazel") fs/path->file) - changed? (not= content (when (.exists build-file) (slurp build-file :encoding "UTF-8")))] - (when changed? - (spit build-file content :encoding "UTF-8")) - {:files (count paths) :wrote (if changed? 1 0)}))) + skip? (and build-mtime + (every? (fn [^Path p] + (<= (.lastModified (.toFile p)) ^long build-mtime)) + paths) + (every? (fn [^Path p] + (let [child-build (-> p (fs/->path "BUILD.bazel") fs/path->file)] + (or (not (.exists child-build)) + (<= (.lastModified child-build) ^long build-mtime)))) + subdirs))] + (if skip? + {:files (count paths) :wrote 0} + (let [clj-subdirs (->> + subdirs + (filter (fn [p] + (some clj*-path? (seq (fs/ls-r p)))))) + [has-binary? rules] (reduce (fn [[hb? acc] rule] + [(or hb? (= :clojure_binary (:type rule))) + (conj acc (emit-rule rule))]) + [false []] + (->> paths + (group-by fs/basename) + (mapcat (fn [[_base paths]] + (ns-rules args paths))))) + content (str "#autogenerated, do not edit\n" + (emit-bazel (list 'package (kwargs {:default_visibility ["//visibility:public"]}))) + "\n" + (emit-bazel (apply list 'load "@rules_clojure//:rules.bzl" + (cond-> ["clojure_library" "clojure_test"] + has-binary? (conj "clojure_binary")))) + "\n" + "\n" + (str/join "\n\n" rules) + "\n" + "\n" + (when (or (seq paths) (seq clj-subdirs)) + (str + (emit-bazel (list 'clojure_library (kwargs {:name "__clj_lib" + :deps (vec + (concat + (dedupe (map (fn [p] (str ":" (fs/basename p))) paths)) + (map (fn [p] + (str "//" (fs/path-relative-to deps-edn-dir p) ":__clj_lib")) clj-subdirs)))}))) + "\n" + "\n" + (emit-bazel (list 'filegroup (kwargs (merge + {:name "__clj_files" + :srcs (mapv fs/filename paths) + :data (mapv (fn [p] + (str "//" (fs/path-relative-to deps-edn-dir p) ":__clj_files")) clj-subdirs)}))))))) + changed? (not= content (when build-mtime (slurp build-file :encoding "UTF-8")))] + (when changed? + (spit build-file content :encoding "UTF-8")) + {:files (count paths) :wrote (if changed? 1 0)})))) (s/fdef gen-source-paths- :args (s/cat :a (s/keys :req-un [::deps-edn-dir ::src-ns->label ::dep-ns->label ::jar->lib ::deps-repo-tag ::deps-bazel]) :paths (s/coll-of fs/path?))) (defn gen-source-paths-