8个版本 (破坏性)

0.8.0 2024年6月11日
0.7.0 2024年4月25日
0.6.0 2024年3月12日
0.5.0 2024年1月25日
0.1.0 2023年7月10日

878配置

Download history 67/week @ 2024-05-01 30/week @ 2024-05-08 57/week @ 2024-05-15 72/week @ 2024-05-22 50/week @ 2024-05-29 148/week @ 2024-06-05 118/week @ 2024-06-12 52/week @ 2024-06-19 21/week @ 2024-06-26 22/week @ 2024-07-03 21/week @ 2024-07-10 30/week @ 2024-07-17 24/week @ 2024-07-24 39/week @ 2024-07-31 45/week @ 2024-08-07 27/week @ 2024-08-14

每月下载 141
4 crates 中使用

MITLGPL-3.0-only

1.5MB
29K SLoC

Continuous integration Website Discord

镍是一种经济的配置语言。

它的目的是自动化生成静态配置文件 - 想想JSON、YAML、XML或您喜欢的任何数据表示语言 - 然后将其馈送到另一个系统。它设计有简单、易于理解的核心:本质上它是带有函数的JSON。

镍的显著特征包括

  • 轻量级:镍易于嵌入。解释器应该易于实现。参考解释器可以从许多编程语言中调用。
  • 可组合代码:计算的基本构建块是函数。它们是一等公民,可以传递、调用和组合。
  • 可组合数据:数据的基本构建块是记录(在JSON中称为“对象”)。在镍中,可以随意合并记录,包括关联的元数据(文档、默认值、类型合同等)。
  • 类型化,但仅在需要时:静态类型可以提高代码质量,作为文档,并在早期消除错误。但是,特定于应用程序的独立代码始终评估为相同的值,因此类型错误最终仍将在运行时出现。有些JSON很难类型化。在那里,类型只是负担。而可重用代码 - 即函数 - 在可能无限多的不同输入上评估,并且无法完全测试。在那里,类型是宝贵的。镍有类型,但你可以选择何时需要它,并且它安全地处理类型化和非类型化世界之间的交互。
  • 按合同设计:与类型系统相辅相成,合同是一种检查断言的原则方法。解释器会自动在类型化和非类型化代码的边界处插入断言。镍允许用户添加任意的断言,并轻松理解断言失败的原因。

指导镍设计的格言是

良好的默认值,为扩展性而设计

应该有一条标准、清晰的路径用于常见的事情。不应该有任意限制,这些限制在您需要超越的一天会限制您所能做的事情。

用例

镍适用于任何需要生成复杂配置的情况,无论是单个应用程序、机器、整个基础设施还是构建系统。

特别激励的使用案例包括

  • Nix软件包管理器:Nix是一个声明式软件包管理器,它使用自己的语言来指定软件包。镍是Nix语言的进化,同时试图克服其一些局限性。
  • 基础设施即代码:随着基础设施变得越来越复杂,需要严格的部署、修改和配置方法。这正是声明式方法大放异彩的地方,正如TerraformNixOpsKubernetes所采用的,所有这些都需要可能复杂的配置生成。
  • 构建系统:构建系统(如Bazel)需要指定依赖图。

上述大多数项目都有自己的定制配置语言。见比较。一般来说,应用特定的语言可能会出现功能膨胀、缺乏抽象或感觉过于随意的问题。镍以更少的成本为您提供更多的功能。

镍生态系统

属于镍生态系统的相关项目

入门指南

请参阅nickel-lang网站上的镍用户入门指南。以下说明要么是为了使本文档独立,要么是因为它们旨在针对镍解释器本身进行黑客攻击(例如,构建nickel-lang-core crate文档)。

运行

  1. 获取镍二进制文件

    • 使用启用flake的Nix,可以直接使用nix run github:tweag/nickel运行镍。您可以使用我们的二进制缓存来防止重建大量软件包。使用额外的--将参数传递给镍,例如nix run github:tweag/nickel-- repl
    • 再次使用flake-enabled Nix,您可以使用nix profile install github:tweag/nickel将镍安装到您的配置文件中。然后nickel命令就在您的$PATH中,并且在任何地方都可以使用。
    • 如果您正在运行macOS,可以使用Homebrew通过brew install nickel安装Nickel的二进制文件。
    • 没有Nix,您可以在构建后使用 cargo run --bin nickel 运行程序,并通过额外的 -- 传递参数,例如 cargo run --bin nickel -- eval program.ncl
  2. 运行您的第一个程序

    $ nickel eval <<< '["hello", "world"] |> std.string.join ", "'
    "hello, world"
    

    或从文件加载它

    $ echo 'let s = "world" in "hello, %{s}"' > program.ncl
    $ nickel eval program.ncl
    "hello, world"
    
  3. 启动REPL

    $ nickel repl
    nickel> {"hello" = true, "world" = true, "universe" = false}
      |> std.record.to_array
      |> std.array.filter (fun {field, value} => value)
      |> std.array.map (fun {field, value} => field)
      |> std.string.join ", "
    
    "hello, world"
    

    使用 :help 查看可用的命令列表。

  4. 将配置导出到JSON、YAML或TOML

$ nickel export --format json <<< '{content = "hello, world"}'
{
  "content": "hello, world"
}

使用 nickel help 查看子命令列表,并使用 nickel help <子命令> 查看特定子命令的帮助。

要取得联系,您可以加入我们的 Discord 服务器。

编辑器设置

Nickel为Vim/Neovim和VSCode提供了语法高亮插件。Nickel语言服务器提供编辑器诊断、类型提示和自动完成。请遵循 LSP指南 来设置语法高亮和NLS。

格式化

要格式化一个或多个Nickel源文件,请使用 nickel format

nickel format network.ncl container.ncl api.ncl

Nickel在底层使用 Topiary 来格式化Nickel代码。

请遵循 LSP文档 中的格式化功能部分,了解如何将Nickel LSP和Topiary连接起来,以在代码编辑器中启用格式化。

构建

  1. 下载构建依赖项

    • 使用Nix:如果您已安装 Nix

      nix-shell # if you don't use Nix flakes
      nix develop # if you use Nix flakes
      

      您将进入一个shell,准备构建。您可以使用 我们的二进制缓存 来防止大量包的重构建。

    • 不使用Nix:否则,请按照 此指南 安装Rust和Cargo。

  2. 构建Nickel

    cargo build -p nickel-lang-cli --release
    

    瞧!生成的文件位于 target/release

    您可以直接使用 cargo run 构建 Nickle 二进制文件,并在 -- 后传递参数。

    cargo run --bin nickel -- eval foo.ncl
    

测试

使用以下命令运行测试

cargo test

文档

用户手册可在 nickel-lang.org 网站上 获取,以及在此存储库中作为位于 doc/manual 的Markdown文件集合。

要获取 nickel-lang 代码库本身的文档

  1. 构建文档

    cargo doc --no-deps
    
  2. 在您的浏览器中打开文件 target/doc/nickel/index.html

示例

您可以在 ./examples 目录中找到示例。

当前状态和路线图

自2023年5月发布的1.0版本以来,语言的内核设计已稳定,Nickel可用于实际应用。我们计划下一步工作的步骤是

我们计划下一步工作的步骤是

  • 镍集成:能够无缝使用镍来编写包和外壳(Organist
  • 自定义合并函数(覆盖提议的第二部分 overriding proposal
  • 增量评估:设计一个增量评估模型和缓存机制,以便在配置发生微小变化时快速重新评估。
  • 性能改进

比较

  • CUE 是一种关注数据验证的配置语言。它引入了一个由坚实理论支持的全新约束系统,确保了代码的强保障。它允许进行非常优雅的架构规范。然而,需要付出的代价是放弃函数和 图灵完备性。镍的合并系统受到了 CUE 的启发,尽管镍具有通用函数并且是图灵完备的,但它们必然是不同的。
  • Nix:Nix 语言,或 Nix 表达式,是镍的主要灵感之一。它是一种简单而强大的惰性函数式语言。我们努力保持这种简单性,同时添加类型能力、模块化和将语言从 Nix 软件包管理器中分离出来。
  • Dhall 是一种静态类型配置语言。它也受到了 Nix 的启发,并添加了一个强大的静态类型系统。然而,这迫使程序员必须对所有代码进行类型注解。
  • Jsonnet 是另一种可以被称为“具有函数的 JSON”(以及其它事物)的语言。它是一种具有面向对象功能的惰性函数式语言,其中继承类似于镍的合并系统。与镍的一个重大不同之处在于缺乏类型。
  • KCL 是一种逐步类型配置语言,其验证基于可以通过继承扩展的对象模式。与上述语言不同,其评估是严格的。
  • Pulumi 不是一个语言本身,而是一个云工具(类似于 Terraform),您可以使用您喜欢的语言来描述您的基础设施。这是一种不同的解决问题的方式,具有不同的权衡。
  • StarlarkBazel 的语言,它是 Python 的方言。它没有类型,递归是被禁止的,这使得它不是图灵完备的。

请参阅 RATIONALE.md 了解设计原理以及与这些语言的更详细比较。

与其他配置语言的比较

语言 类型 递归 评估 副作用
逐步(动态 + 静态) 惰性 是(受约束的,计划中的)
Starlark 动态 严格
Nix 动态 惰性 预定义且专用于包管理
Dhall 静态(需要注解) 受限 惰性
CUE 静态(一切都是类型) 惰性 否,但在分离的脚本层允许
Jsonnet 动态 惰性
KCL 逐步(动态 + 静态) 严格
JSON 严格
YAML 不适用
TOML 不适用

依赖关系

~26–44MB
~652K SLoC