【发布时间】:2021-04-27 08:17:03
【问题描述】:
如何在不修改项目文件的情况下仅使用 lein 和简单的命令行实用程序从 Leiningen project.clj 文件中查询项目组、名称和版本?
我在 lein help 中找不到任何有用的东西,比如从命令行参数执行代码。
我正在考虑编写一个sed 表达式,但我想知道是否有更简单的方法使用 Leiningen。
【问题讨论】:
如何在不修改项目文件的情况下仅使用 lein 和简单的命令行实用程序从 Leiningen project.clj 文件中查询项目组、名称和版本?
我在 lein help 中找不到任何有用的东西,比如从命令行参数执行代码。
我正在考虑编写一个sed 表达式,但我想知道是否有更简单的方法使用 Leiningen。
【问题讨论】:
这在某种程度上得到了 Leiningen 的完全(?)支持。简而言之:
$ (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 描述了just-a-colon 功能。)
除了update-in,Leiningen 还需要一个实际的命令。因为pr 返回 nil,我想更新会损坏项目图并使其不适合实际工作。上面的演示通过使用version 命令打印Leiningen 自己的版本来回避这个问题。
奇怪的是,印刷版本或名称出现了不止一次;因此cut 命令仅采用每行中第一个引用的字符串。我们假设您没有在项目名称或版本中使用引号!
您可以在一个命令行上堆叠update-in,但这样做会使名称和版本更难从输出中解析出来。
【讨论】:
prn而不是pr。它添加了一个换行符。
我不认为 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
【讨论】:
我只想写一个 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'"]
我们首先将双引号转换为单引号以简化正则表达式和输出。我们使用一个自定义模式类,它不仅包括字母数字字符,还包括连字符。 Clojure slurp 很方便,因为它将文件作为单个大字符串返回,如果感兴趣的所有内容都不在第一行,则忽略单独的行,这对 Unix grep 来说是个问题。
以上内容基于a simple template project。
请随意进一步修饰!
【讨论】:
project.clj 的内容是一个 clojure 数据结构,因此您可以 read 它例如
(let [[_ ga version] (read-string (slurp "project.clj"))]
[(namespace ga) (name ga) version])
【讨论】: