【问题标题】:Read project name and version from Leiningen project.clj file从 Leiningen project.clj 文件中读取项目名称和版本
【发布时间】:2021-04-27 08:17:03
【问题描述】:

如何在不修改项目文件的情况下仅使用 lein 和简单的命令行实用程序从 Leiningen project.clj 文件中查询项目组、名称和版本?

我在 lein help 中找不到任何有用的东西,比如从命令行参数执行代码。

我正在考虑编写一个sed 表达式,但我想知道是否有更简单的方法使用 Leiningen。

【问题讨论】:

    标签: clojure leiningen


    【解决方案1】:

    这在某种程度上得到了 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。它添加了一个换行符。
    【解决方案2】:

    我不认为 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
    

    【讨论】:

      【解决方案3】:

      我只想写一个 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

      请随意进一步修饰!

      【讨论】:

        【解决方案4】:

        project.clj 的内容是一个 clojure 数据结构,因此您可以 read 它例如

        (let [[_ ga version] (read-string (slurp "project.clj"))]
           [(namespace ga) (name ga) version])
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-06-22
          • 2013-11-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-30
          • 2016-11-02
          • 2016-09-02
          相关资源
          最近更新 更多