From fa92ed35a21eba6e806bea3334575f2342944d6f Mon Sep 17 00:00:00 2001 From: Max Miorim Date: Wed, 3 Jan 2024 16:42:42 -0300 Subject: [PATCH 1/4] Accept compiler options when building app --- README.md | 14 ++++++++++++++ src/vessel/builder.clj | 18 ++++++++++++------ src/vessel/program.clj | 15 ++++++++++++++- test/unit/vessel/builder_test.clj | 19 +++++++++++++++++++ 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6585094..800da0f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,19 @@ A containerization tool for Clojure applications. It uses [Google Jib](https://g ## Usage +> `build`: + +Build a Clojure application + +| Option | Default | Description | +| -- | -- | -- | +| `-c` `--classpath PATHS` | `--` | Directories and zip/jar files on the classpath in the same format expected by the java command | +| `-s` `--source-path PATH` | `--` | Directories containing source files. This option can be repeated many times | +| `-m` `--main-class NAMESPACE` | `--` | Namespace that contains the application's entrypoint, with a :gen-class directive and a -main function | +| `-r` `--resource-path PATH` | `--` | Directories containing resource files. This option can be repeated many times | +| `-o` `--output PATH` | `--` | Directory where the application's files will be written to | +| `-C` `--compiler-options OPTIONS` | No | Options provided to the Clojure compiler, see `clojure.core/*compiler-options*` | + > `containerize`: Containerize a Clojure application @@ -24,6 +37,7 @@ Containerize a Clojure application | `-s` `--source-path PATH` | `--` | Directories containing source files. This option can be repeated many times | | `-r` `--resource-path PATH` | `--` | Directories containing resource files. This option can be repeated many times | | `-u` `--user USER` | `root` | Define the default user for the image | +| `-C` `--compiler-options OPTIONS` | `nil` | Options provided to the Clojure compiler, see `clojure.core/*compiler-options*` | > `image`: diff --git a/src/vessel/builder.clj b/src/vessel/builder.clj index 00158da..6087620 100644 --- a/src/vessel/builder.clj +++ b/src/vessel/builder.clj @@ -59,9 +59,10 @@ "Compiles the main-ns by writing compiled .class files to target-dir. Displays a spin animation during the process." - [^Symbol main-ns ^Sequential classpath source-paths ^File target-dir] + [^Symbol main-ns ^Sequential classpath source-paths ^File target-dir compiler-options] (let [forms `(try - (binding [*compile-path* ~(str target-dir)] + (binding [*compile-path* ~(str target-dir) + *compiler-options* (merge *compiler-options* ~compiler-options)] (clojure.core/compile (symbol ~(name main-ns)))) (catch Throwable err# (println) @@ -103,11 +104,11 @@ Returns a map of compiled class files (as instances of java.io.File) to their sources (instances of java.io.File as well representing directories or jar files on the classpath)." - [classpath-files ^Symbol main-class source-paths ^File target-dir] + [classpath-files ^Symbol main-class source-paths ^File target-dir compiler-options] (let [namespaces (find-namespaces-on-classpath classpath-files) classes-dir (misc/make-dir target-dir "classes") classpath (cons classes-dir classpath-files) - _ (do-compile main-class classpath source-paths classes-dir)] + _ (do-compile main-class classpath source-paths classes-dir compiler-options)] (reduce (fn [result ^File class-file] (let [source-file (or (get-class-file-source namespaces (misc/relativize class-file classes-dir)) ;; Defaults to the first element of source-paths if the class file doesn't match any known source. @@ -230,16 +231,21 @@ * :target-dir (java.io.File) an existing directory where the application's files will be written to. + And it accepts the following optional keys: + + * :compiler-options (map) options for the Clojure compiler, refer + to `clojure.core/*compiler-options*` for the supported keys. + Returns a map containing the following namespaced keys: * :app/classes - a map from target files (compiled class files and resources) to their source classpath root (either directories or jar files present on the classpath); * :app/lib - a sequence of java.io.File objects containing libraries that the application depends on." - [{:keys [classpath-files ^Symbol main-class resource-paths source-paths ^File target-dir]}] + [{:keys [classpath-files ^Symbol main-class resource-paths source-paths ^File target-dir compiler-options]}] {:pre [classpath-files main-class source-paths target-dir]} (let [web-inf (misc/make-dir target-dir "WEB-INF") - classes (compile classpath-files main-class source-paths web-inf) + classes (compile classpath-files main-class source-paths web-inf compiler-options) dirs+jar-files (set/union resource-paths (set (vals classes))) libs (misc/filter-files (set/difference (set classpath-files) dirs+jar-files)) resource-files (copy-files dirs+jar-files web-inf)] diff --git a/src/vessel/program.clj b/src/vessel/program.clj index 7a96b6b..de24816 100644 --- a/src/vessel/program.clj +++ b/src/vessel/program.clj @@ -1,6 +1,7 @@ (ns vessel.program (:gen-class) - (:require [clojure.java.io :as io] + (:require [clojure.edn :as edn] + [clojure.java.io :as io] [clojure.string :as string] [vessel.api :as api] [vessel.cli :as cli] @@ -50,6 +51,12 @@ :desc "Directory where the application's files will be written to" :parse-fn io/file :validate cli/file-or-dir-must-exist] + ["-C" "--compiler-options OPTIONS" + :id :compiler-options + :desc "Options provided to the Clojure compiler, see clojure.core/*compiler-options*" + :default nil + :parse-fn edn/read-string + :validate [#(or (nil? %) (map? %)) "Compiler options must be a valid Clojure map"]] verbose]} "containerize" @@ -115,6 +122,12 @@ :id :user :desc "Define the default user for the image" :default "root"] + ["-C" "--compiler-options OPTIONS" + :id :compiler-options + :desc "Options provided to the Clojure compiler, see clojure.core/*compiler-options*" + :default nil + :parse-fn edn/read-string + :validate [#(or (nil? %) (map? %)) "Compiler options must be a valid Clojure map"]] verbose]} "image" diff --git a/test/unit/vessel/builder_test.clj b/test/unit/vessel/builder_test.clj index 142e007..e6f3dc0 100644 --- a/test/unit/vessel/builder_test.clj +++ b/test/unit/vessel/builder_test.clj @@ -6,6 +6,7 @@ [matcher-combinators.test :refer [match?]] [vessel.builder :as builder] [vessel.misc :as misc] + [vessel.sh :as sh] [vessel.test-helpers :refer [classpath ensure-clean-test-dir]]) (:import java.io.File)) @@ -130,3 +131,21 @@ (is (thrown-match? clojure.lang.ExceptionInfo #:vessel.error{:category :vessel/compilation-error} (builder/build-app (assoc options :main-class 'my-app.compilation-error))))))) + +(deftest use-provided-compiler-options-when-building-app-test + (let [project-dir (io/file "test/resources/my-app") + target (io/file "target/tests/builder-test/build-app-test") + classpath-files (map io/file (string/split (classpath project-dir) #":")) + options {:classpath-files classpath-files + :resource-paths #{(io/file project-dir "src")} + :source-paths #{(io/file project-dir "resources")} + :target-dir target + :main-class 'my-app.server + :compiler-options {:direct-linking true + :testing? true}} + sh-args (atom [])] + (with-redefs [sh/javac (constantly nil) + sh/clojure #(reset! sh-args [%1 %2 %3])] + (builder/build-app options)) + + (is (re-matches #".*clojure\.core/\*compiler-options\* \(clojure\.core/merge clojure\.core/\*compiler-options\* \{:direct-linking true, :testing\? true\}\).*" (last @sh-args))))) From 8d97da11d90e5c9dda528dbc57a9baf4ff6be825 Mon Sep 17 00:00:00 2001 From: Max Miorim Date: Wed, 31 Jan 2024 17:01:28 -0300 Subject: [PATCH 2/4] Extract compiler-options validator for reuse --- src/vessel/cli.clj | 3 +++ src/vessel/program.clj | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/vessel/cli.clj b/src/vessel/cli.clj index 1b1b898..d85034c 100644 --- a/src/vessel/cli.clj +++ b/src/vessel/cli.clj @@ -193,3 +193,6 @@ Please, specify extra paths in the form source:target or source:target@churn.") (defn repeat-option [m k v] (update-in m [k] (fnil conj #{}) v)) + +(def compiler-options-must-be-nil-or-map + [#(or (nil? %) (map? %)) "Compiler options must be a valid Clojure map"]) diff --git a/src/vessel/program.clj b/src/vessel/program.clj index de24816..997564c 100644 --- a/src/vessel/program.clj +++ b/src/vessel/program.clj @@ -56,7 +56,7 @@ :desc "Options provided to the Clojure compiler, see clojure.core/*compiler-options*" :default nil :parse-fn edn/read-string - :validate [#(or (nil? %) (map? %)) "Compiler options must be a valid Clojure map"]] + :validate cli/compiler-options-must-be-nil-or-map] verbose]} "containerize" @@ -127,7 +127,7 @@ :desc "Options provided to the Clojure compiler, see clojure.core/*compiler-options*" :default nil :parse-fn edn/read-string - :validate [#(or (nil? %) (map? %)) "Compiler options must be a valid Clojure map"]] + :validate cli/compiler-options-must-be-nil-or-map] verbose]} "image" From 968a1ec8615ae18c5baeae0b4134da3bb5000c28 Mon Sep 17 00:00:00 2001 From: Max Miorim Date: Wed, 31 Jan 2024 17:09:14 -0300 Subject: [PATCH 3/4] Prepare for version 0.2.149 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a25cb0..4597c56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.2.149] - 2024-01-31 + +### Added + +- Add option to define options for the Clojure compiler when building and containerizing an application: [#32](https://github.com/nubank/vessel/pull/32). + See the [Clojure documentation](https://clojure.org/reference/compilation#_compiler_options) for more details. + ## [0.2.148] - 2023-09-04 ### Changed From 52ce86f5ce337342377530f1d6ef4acf3af6fe90 Mon Sep 17 00:00:00 2001 From: Max Miorim Date: Thu, 1 Feb 2024 14:29:57 -0300 Subject: [PATCH 4/4] Remove unreleased version from changelog --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4597c56..8199197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,6 @@ All notable changes to this project will be documented in this file. ## [Unreleased] -## [0.2.149] - 2024-01-31 - ### Added - Add option to define options for the Clojure compiler when building and containerizing an application: [#32](https://github.com/nubank/vessel/pull/32).