首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态leiningen :轮廓

动态leiningen :轮廓
EN

Stack Overflow用户
提问于 2017-02-09 23:42:36
回答 2查看 1.6K关注 0票数 2

我试图使用一个函数作为:profiles键在defproject表单中的值。从一个新项目(lein new app test)开始,这很好:

代码语言:javascript
复制
:profiles {}

(正如你所希望的那样!)但如果我把它改为:

代码语言:javascript
复制
:profiles (merge {})

然后,当我运行lein repl时,它会爆炸:

代码语言:javascript
复制
Caused by: java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to java.util.Map$Entry

我对此感到困惑,因为如果我将:profiles设置为空映射并询问repl,这些内容是相等的:

代码语言:javascript
复制
test.core=> (= {} (merge {}))
true

我的误会在哪里?我错过了一些基本的东西吗?这是defproject宏的一个不幸的工件吗?还有别的吗?

(clojure 1.8.0,leiningen 2.7.1,java 1.8.0_102)

用Scott的答案编辑工作解决方案:

代码语言:javascript
复制
(def project-name 'myproj)
(def mains ["foo" "bar"])
...
(defn- lein-alias [main]
  { main ["with-profile" main] })

(defn- lein-profile [main]
  (let [jar      (str main ".jar")
        entry    `~(str project-name "." main)]
    {(keyword main) {:main          entry 
                     :bin           {:name main}
                     :jar-name      jar
                     :uberjar-name  jar}}))

(defproject project-name "0.1.0"
...
  :profiles ~(apply merge (concat (map lein-profile mains) {:uberjar {:aot :all}}))
  :aliases ~(apply merge (map lein-alias mains))
  ...

因此,现在我可以lein foo binlein bar bin的心满意足。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-10 15:01:38

如果您的表单unquote,您的表单Leiningen将在评估项目映射之前执行该表单。

所以~(merge {})应该能工作。

在Leiningen unquote-project中有一个名为src/leiningen/core/project.clj#L 176的函数。

不引用(~)允许任意的评估。

它看起来像是unquote中的项目,以允许它们被执行。根据评论,这在3.0中可能会消失,并建议use read-eval syntax

注意:如果您只是试图合并不同配置文件的值,则应该查看关于合并复合剖面配置文件文档。

复合剖面 有时,将概要文件定义为其他配置文件的组合是有用的。要做到这一点,只需使用向量而不是映射作为概要文件的值。这可以用来避免重复:

代码语言:javascript
复制
{:shared {:port 9229, :protocol "https"}
 :qa [:shared {:servers ["qa.mycorp.com"]}]
 :stage [:shared {:servers ["stage.mycorp.com"]}]
 :production [:shared {:servers ["prod1.mycorp.com", "prod1.mycorp.com"]}]}
票数 3
EN

Stack Overflow用户

发布于 2017-02-10 00:55:00

您不能手动合并配置文件。它们由lein自动(正常情况)或当您使用with-profile关键字时(手动控制)合并在一起。

例如,考虑一下这个project.clj

代码语言:javascript
复制
(defproject xyz "0.1.0-SNAPSHOT"

  :dependencies [ [org.clojure/clojure "1.8.0"] 
                  [tupelo "0.9.19"] ]

  :profiles {:dev     {:dependencies [ [org.clojure/test.check "0.9.0"]
                                       [criterium "0.4.4"] ] }
             :sample  {:dependencies [medley "0.8.2"] }
  ...
)

这个project.clj说项目总是需要org.clojure/clojuretupelo。在开发过程中,:dev的映射将合并到根级,因此:dependencies将被更新为包含test.checkcriterium。但是,在创建uberjar时不包含:dev配置文件值,因此这些库不会包含在交付给用户的代码中。

由于:sample不是默认配置文件之一,所以只有在使用以下命令时才会包含它:

代码语言:javascript
复制
> lein with-profile sample test

注意,前面的冒号不包含在命令行中,尽管我们在:sample文件中使用关键字project.clj和冒号。

详细信息如下:https://github.com/technomancy/leiningen/blob/master/doc/PROFILES.md#default-profiles

在这里:https://github.com/technomancy/leiningen/blob/master/sample.project.clj

说了这些之后,我通常不需要使用:profiles。除非您有比通常更复杂的东西,否则通常应该将所有的依赖项放在根级(即在:dependencies提供的项目中的(defproject xyz ...)下的第一级的lein new app xyz关键字)。

另一个建议:在lein项目中的许多地方都使用了test这个词(目录名、文件名后缀等等),所以将项目本身命名为test可能会非常混乱!如果您选择一个独特的名称,如xyzjoe或其他任何东西,您将为自己(和其他任何读者)省去一些痛苦。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42149021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档