从 Leiningen project.clj 文件中读取项目名称和版本
Read project name and version from Leiningen project.clj file
如何在不修改项目文件的情况下仅使用 lein
和简单的命令行实用程序从 Leiningen project.clj
文件中查询项目组、名称和版本?
我在 lein help
中找不到任何有用的东西,比如从命令行参数执行代码。
我正在考虑编写一个 sed
表达式,但我想知道是否有使用 Leiningen 的更简单的方法。
我只想写一个 Clojure 函数。 Java regular expressions 相当强大(超过 unix grep
)。
像这样的事情会让你开始:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require [tupelo.string :as str]))
(dotest
(let [txt (str/quotes->single (slurp "project.clj"))
result (re-find
#"(?ix) # turn on case-insensitive (i) and freespace (x) modes
defproject\s+ # anchor the regex, followed by 1+ spaces
([-a-z0-9]+)\/ # maven group name, followed by a slash
([-a-z0-9]+)\s+ # maven artifact name, followed by 1+ spaces
(\S+) # version string
"
txt)]
(spyx-pretty result)))
结果:
--------------------------------------
Clojure 1.10.2-alpha1 Java 15
--------------------------------------
Testing tst.demo.core
result =>
["defproject demo-grp/demo-art '0.1.0-SNAPSHOT'"
"demo-grp"
"demo-art"
"'0.1.0-SNAPSHOT'"]
我们首先将双引号转换为单引号以简化正则表达式和输出。我们使用自定义模式 class,它不仅包括字母数字字符,还包括连字符。 Clojure slurp
很方便,因为它 returns 文件作为单个大字符串,忽略单独的行,如果所有感兴趣的内容都不在第一行,这对 Unix grep
来说是个问题。
以上是根据a simple template project.
欢迎进一步修饰!
project.clj
的内容是一个 clojure 数据结构,因此您可以 read
它,例如
(let [[_ ga version] (read-string (slurp "project.clj"))]
[(namespace ga) (name ga) version])
我不认为 Leiningen 可以让您在命令行上评估事物,但它确实可以让您启动一个 REPL,您可以将一些 Clojure 代码传输到该 REPL:
$ echo "(-> '$(cat project.clj) (nth 1) namespace)" | lein repl | tail -n2 | head -n1
"mygroup"
$ echo "(-> '$(cat project.clj) (nth 1) name)" | lein repl | tail -n2 | head -n1
"myproject"
$ echo "(-> '$(cat project.clj) (nth 2))" | lein repl | tail -n2 | head -n1
"0.1.0-SNAPSHOT"
但是,如果您想要不那么笨重的东西,可以选择安装 Babashka 吗?
$ bb -i "(-> '$(cat project.clj) (nth 1) namespace)"
"mygroup"
$ bb -i "(-> '$(cat project.clj) (nth 1) name)"
"myproject"
$ bb -i "(-> '$(cat project.clj) (nth 2))"
"0.1.0-SNAPSHOT"
添加一个 println
以省略引号:
$ bb -i "(-> '$(cat project.clj) (nth 2) println)"
0.1.0-SNAPSHOT
莱宁根在某种程度上完全(?)支持这一点。简而言之:
$ (lein update-in :version pr -- version ; lein update-in :name pr -- version) | cut -d '"' -f 2
这通过滥用 update-in
命令将 clojure.core/pr
应用于 :version
或 :name
项目密钥来实现。 (您可以通过仅使用冒号作为 pr 的成员来查看所有项目密钥。lein help update-in
描述了仅冒号功能。)
除了 update-in
之外,Leiningen 也需要一个实际的命令。因为 pr
returns 零,我想更新会损坏项目地图并使其不适合实际工作。上面的演示通过使用 version
命令打印 Leiningen 自己的版本来回避问题。
奇怪的是,打印版本或名称出现了不止一次;因此 cut
命令只接受每行中第一个引用的字符串。我们假设您没有在项目名称或版本中使用引号!
您可以在一个命令行上堆叠 update-in
,但这样做会使名称和版本更难从输出中解析。
我为此创建了一个模块。它将读取默认值 project.clj 或路径。
如何在不修改项目文件的情况下仅使用 lein
和简单的命令行实用程序从 Leiningen project.clj
文件中查询项目组、名称和版本?
我在 lein help
中找不到任何有用的东西,比如从命令行参数执行代码。
我正在考虑编写一个 sed
表达式,但我想知道是否有使用 Leiningen 的更简单的方法。
我只想写一个 Clojure 函数。 Java regular expressions 相当强大(超过 unix grep
)。
像这样的事情会让你开始:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require [tupelo.string :as str]))
(dotest
(let [txt (str/quotes->single (slurp "project.clj"))
result (re-find
#"(?ix) # turn on case-insensitive (i) and freespace (x) modes
defproject\s+ # anchor the regex, followed by 1+ spaces
([-a-z0-9]+)\/ # maven group name, followed by a slash
([-a-z0-9]+)\s+ # maven artifact name, followed by 1+ spaces
(\S+) # version string
"
txt)]
(spyx-pretty result)))
结果:
--------------------------------------
Clojure 1.10.2-alpha1 Java 15
--------------------------------------
Testing tst.demo.core
result =>
["defproject demo-grp/demo-art '0.1.0-SNAPSHOT'"
"demo-grp"
"demo-art"
"'0.1.0-SNAPSHOT'"]
我们首先将双引号转换为单引号以简化正则表达式和输出。我们使用自定义模式 class,它不仅包括字母数字字符,还包括连字符。 Clojure slurp
很方便,因为它 returns 文件作为单个大字符串,忽略单独的行,如果所有感兴趣的内容都不在第一行,这对 Unix grep
来说是个问题。
以上是根据a simple template project.
欢迎进一步修饰!
project.clj
的内容是一个 clojure 数据结构,因此您可以 read
它,例如
(let [[_ ga version] (read-string (slurp "project.clj"))]
[(namespace ga) (name ga) version])
我不认为 Leiningen 可以让您在命令行上评估事物,但它确实可以让您启动一个 REPL,您可以将一些 Clojure 代码传输到该 REPL:
$ echo "(-> '$(cat project.clj) (nth 1) namespace)" | lein repl | tail -n2 | head -n1
"mygroup"
$ echo "(-> '$(cat project.clj) (nth 1) name)" | lein repl | tail -n2 | head -n1
"myproject"
$ echo "(-> '$(cat project.clj) (nth 2))" | lein repl | tail -n2 | head -n1
"0.1.0-SNAPSHOT"
但是,如果您想要不那么笨重的东西,可以选择安装 Babashka 吗?
$ bb -i "(-> '$(cat project.clj) (nth 1) namespace)"
"mygroup"
$ bb -i "(-> '$(cat project.clj) (nth 1) name)"
"myproject"
$ bb -i "(-> '$(cat project.clj) (nth 2))"
"0.1.0-SNAPSHOT"
添加一个 println
以省略引号:
$ bb -i "(-> '$(cat project.clj) (nth 2) println)"
0.1.0-SNAPSHOT
莱宁根在某种程度上完全(?)支持这一点。简而言之:
$ (lein update-in :version pr -- version ; lein update-in :name pr -- version) | cut -d '"' -f 2
这通过滥用 update-in
命令将 clojure.core/pr
应用于 :version
或 :name
项目密钥来实现。 (您可以通过仅使用冒号作为 pr 的成员来查看所有项目密钥。lein help update-in
描述了仅冒号功能。)
除了 update-in
之外,Leiningen 也需要一个实际的命令。因为 pr
returns 零,我想更新会损坏项目地图并使其不适合实际工作。上面的演示通过使用 version
命令打印 Leiningen 自己的版本来回避问题。
奇怪的是,打印版本或名称出现了不止一次;因此 cut
命令只接受每行中第一个引用的字符串。我们假设您没有在项目名称或版本中使用引号!
您可以在一个命令行上堆叠 update-in
,但这样做会使名称和版本更难从输出中解析。
我为此创建了一个模块。它将读取默认值 project.clj 或路径。