Skip to content

Commit

Permalink
Merge pull request #145 from zong-zhe/add-mod-docs
Browse files Browse the repository at this point in the history
feat: add the docs for 'kcl.mod'.
  • Loading branch information
Peefy authored Aug 15, 2023
2 parents 5a53906 + 580db96 commit f755f2d
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 37 deletions.
1 change: 1 addition & 0 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,4 @@ A: `go install` 默认会将二进制文件安装到 `$GOPATH/bin` 目录下,
- [OCI registry 支持](./docs/kpm_oci-zh.md).
- [如何使用 kpm 与他人分享您的 kcl 包](./docs/publish_your_kcl_packages-zh.md)
- [kpm 命令参考](./docs/command-reference-zh/index.md)
- [kcl.mod: KCL 包清单文件](./docs/kcl_mod-zh.md)
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,4 @@ For more information about [OCI registry support](./docs/kpm_oci.md).
- [OCI registry support](./docs/kpm_oci-zh.md).
- [How to share your kcl package with others using kpm](./docs/publish_your_kcl_packages-zh.md).
- [kpm command reference](./docs/command-reference/index.md)
- [kcl.mod: The KCL package Manifest File](./docs/kcl_mod.md)
162 changes: 162 additions & 0 deletions docs/kcl_mod-zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# kcl.mod: KCL 包清单文件

## 1. KCL 包清单

每个模块的 `kcl.mod` 文件都被称为其清单。它采用 TOML 格式编写,包含编译模块所需的元数据。

目前 `kcl.mod` 中支持如下内容:

- 包元数据:
- [package](#package) - 定义一个包。
- [name](#package) — 包的名称。
- [version](#package) — 包的版本。
- [edition](#package) — KCL 编译器版本。
- 依赖表:
- [dependencies](#dependencies) - 包库依赖项。
- 编译器设置:
- [profile](#entries) - 编译器设置。
- [entries](#entries) - 编译包的入口点。

## 2. package
`kcl.mod` 中的第一个部分是 `[package]`。主要包含 `name`, `version``edition` 三个字段。

### 2.1. name
`name` 是包的名称,它是一个字符串, 这是一个必要的字段, 注意,包的名称中不可以包含`"."`

例如: 一个包名为 my_pkg 的 kcl 程序包。
```
[package]
name = "my_pkg"
```

### 2.2. version
`version` 是包的版本,它是一个字符串, 这是一个必要的字段。注意,目前 KCL 程序包的版本号仅支持语义化版本号。

例如: `my_pkg` 程序包的版本号为 `0.1.0`
```
[package]
name = "my_pkg"
version = "0.1.0"
```

### 2.3. edition
`edition` 是 KCL 编译器版本,它是一个字符串, 这是一个必要的字段。注意,目前 KCL 编译器版本号仅支持语义化版本号。

例如: `my_pkg` 程序包的版本号为 `0.1.0`, 并且与 0.5.1 的 KCL 编译器兼容。
```
[package]
name = "my_pkg"
version = "0.1.0"
edition = "0.5.0"
```

## 3. dependencies

你的 kcl 包可以依赖于来自 OCI 仓库、Git 存储库或本地文件系统子目录的其他库。

### 3.1. oci dependency

kpm 默认将包保存在 oci registry 上,默认使用的 oci registry 是 `ghcr.io/kcl-lang`
更多内容关于 oci registry 请参考 [kpm 支持 OCI registry](./docs/kpm_oci-zh.md)

你可以按照以下方式指定依赖项:

```toml
[dependencies]
<package name> = <package_version>
```

这将会从 oci registry 中拉取名称为 `<package name>` 的包,版本为 `<package_version>`

如果您希望拉取 `k8s` 包的 `1.27` 版本:

```toml
[dependencies]
k8s = "1.27"
```

### 3.2. git dependency

从 Git 存储库指定依赖项:
```
[dependencies]
<package name> = { git = "<git repo url>", tag = "<git repo tag>" }
```

这将会从 Git 存储库`<git repo url>`中拉取名称为 `<package name>` 的包,`tag``<git repo tag>`

## 4. entries

你可以在编译时指定包的入口点。

`entries``[profile]` 部分的子部分。entries 是一个字符串数组,包含编译器的入口点。这是一个可选的字段,如果没有指定,则默认为包根目录下的所有 `*.k` 文件。

```toml
[profile]
entries = [
...
]
```

entries 中可以定义绝对路径和相对路径,如果定义的是相对路径,那么就会以当前包的

`entries` 是 kcl 包根路径的相对路径,`kcl.mod` 文件路径是包的根路径。支持两种文件路径格式,即 `normal paths``mod relative paths`

- normal path:相对于当前包的根路径。
- mod relative path:相对于 kcl.mod 中 [dependencies](#dependencies) 部分中的三方包的根路径。

例如:
1. 如果 `kcl.mod` 位于 `/usr/my_pkg/kcl.mod`,则 `kpm run` 将把 `/usr/my_pkg/entry1.k``/usr/my_pkg/subdir/entry2.k` 作为 `kcl` 编译器的入口点。

```
entries = [
"entry1.k",
"subdir/entry2.k",
]
```

2. 如果 `kcl.mod` 位于 `/usr/my_pkg/kcl.mod`,并且当前 `kcl` 包依赖于 `kcl``k8s`。你可以使用 `mod relative paths` 将来自包 `k8s` 中的 `kcl` 文件作为 `kcl` 编译器的入口点。

```
entries = [
"entry1.k",
"subdir/entry2.k",
"{k8s:KCL_MOD}/core/api/v1/deployment.k"
]
```

`mod relative paths` 必须包含前缀 `{k8s:KCL_MOD}`,其中 `k8s` 是包名,`{k8s:KCL_MOD}` 表示包 k8s 的包根路径。因此,如果 `k8s` 的包根路径是 `/.kcl/kpm/k8s`,则上面的 `entries` 将把 `/usr/my_pkg/entry1.k``/usr/my_pkg/subdir/entry2.k``/.kcl/kpm/k8s/core/api/v1/deployment.k` 作为 `kcl` 编译器的入口点。

### 注意
你可以使用 `normal path` 指定当前包路径中的编译入口点,使用 `mod relative path` 指定三方包中的入口点。

因此,使用 `normal path` 制定的文件路径必须来自于同一个包,即从 `normal path` 开始寻找的 `kcl.mod` 路径必须只能找到一个 `kcl.mod` 文件,不然编译器将输出错误。

例如:

在路径 `/usr/kcl1`
```
/usr/kcl1
|--- kcl.mod
|--- entry1.k
```

在路径 `/usr/kcl2`
```
/usr/kcl2
|--- kcl.mod
|--- entry2.k
```

如果你在路径`/usr/kcl1`下使用这样的 kcl.mod 编译:
```
entries = [
"entry1.k", # 对应的 kcl.mod 文件是 /usr/kcl1/kcl.mod
"/usr/kcl2/entry2.k", # 对应的 kcl.mod 文件是 /usr/kcl2/kcl.mod
]
```

将会得到错误:
```
error[E3M38]: conflict kcl.mod file paths
```
120 changes: 83 additions & 37 deletions docs/kcl_mod.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,128 @@
# kcl.mod
# kcl.mod: The KCL package Manifest File

## The Manifest

The `kcl.mod` file for each module is called its manifest. It is written in the TOML format. It contains metadata that is needed to compile the module.

In the MVP version, the sections we plan to support are as follows:

- [package](#package) - Defines a package.
- [name](#package) — The name of the package.
- [version](#package) — The version of the package.
- [edition](#package) — The KCLVM edition.
- Package metadata:
- [package](#package) - Defines a package.
- [name](#package) — The name of the package.
- [version](#package) — The version of the package.
- [edition](#package) — The KCL compiler edition.
- Dependency tables:
- [dependencies](#dependencies) - Package library dependencies.
- Compiler settings:
- [profile] - The compiler settings.
- [entries](#entries) - The entry points of the package when compiling.

## package

The first section in a kcl.mod is [package].
The first section in a `kcl.mod` is [package].

```
[package]
name = "hello_world" # the name of the package
version = "0.1.0" # the current version, obeying semver
edition = "0.1.1-alpha.1" # the kclvm version
edition = "0.5.0" # the KCL compiler version
```

The only fields required by kpm are `name` and `version`. `edition` is an optional field that describes the version of kclvm being used. If not specified, the latest version will be selected by default.

## dependencies

Your kcl package can depend on other libraries from registries, git repositories, or subdirectories on your local file system.
Your kcl package can depend on other libraries from OCI registries, git repositories, or subdirectories on your local file system.

From registries:
You can specify a dependency by following:

```toml
[dependencies]
xxx = "0.0.1"
<package name> = <package_version>
```

From Git:
You can specify a dependency from git repository.

```toml
[dependencies]
# git release
xxxx = {git = "<github url>", version = "0.4.5"}
# git commit
xxxx = {git = "<github url>", commit = "h87h8f78"}
# git branch
xxxx = {git = "<github url>", branch = "main"}
<package name> = { git = "<git repo url>", tag = "<git repo tag>" }
```

From local file system
You can specify a dependency from local file path.

```toml
# Find the kcl.mod under "./xxx/xxx".
[dependencies]
xxxx = {path = "./xxx/xxx",version = "0.4.5"}
<package name> = {path = "<package local path>"}
```

## kcl.mod.lock
## entries
You can specify the entry points of the package when compiling.

A read-only file generated from kcl.mod to fix the dependencies version.
`entries` is a sub section of `profile` section.

```toml
# This file is automatically @generated by kpm.
# It is not intended for manual editing.
[profile]
entries = [
...
]
```

`entries` is the relative path of kcl package root path, the `kcl.mod` file path is the package root path. There are two types of file paths formats supported, `normal paths` and `mod relative paths`.

- normal path: The path is relative to the current package root path.
- mod relative path: The path is relative to the vendor package root path that can be found by the section [dependencies](#dependencies) in `kcl.mod` file.

### For example:

1. If the `kcl.mod` is localed in `/usr/my_pkg/kcl.mod`, `kpm run` will take `/usr/my_pkg/entry1.k` and `/usr/my_pkg/subdir/entry2.k` as the entry point of the kcl compiler.

[[package]]
name = "xxx"
version = "0.0.1"
source = "git+https://github.com/xxxxx"
checksum = "d468802bab17cbc0cc575e9b0"
```toml
entries = [
"entry1.k",
"subdir/entry2.k",
]
```

2. If the `kcl.mod` is localed in `/usr/my_pkg/kcl.mod`, and the current kcl package depends on the kcl package `k8s`. You can use the `mod relative paths` the take the kcl file in the package `k8s` as the entry point of the kcl compiler.

```toml
entries = [
"entry1.k",
"subdir/entry2.k",
"{k8s:KCL_MOD}/core/api/v1/deployment.k"
]
```

- name — The name of the package.
- version — The version of the package.
- source — registry, git or path.
- checksum - To verify the integrity of the package.
The `mod relative paths` must contains the preffix `{k8s:KCL_MOD}`, `k8s` is the package name, `{k8s:KCL_MOD}` means the package root path of the package `k8s`. Therefore, if the package root path of `k8s` is `/.kcl/kpm/k8s`, the `entries` show above will take `/usr/my_pkg/entry1.k`, `/usr/my_pkg/subdir/entry2.k` and `/.kcl/kpm/k8s/core/api/v1/deployment.k` as the entry point of the kcl compiler.

### Note
You can use `normal path` to specify the compilation entry point in the current package path, and use `mod relative path` to specify the entry point in a third-party package.

## kcl.mod.proto
Therefore, the file path specified by `normal path` must come from the same package, that is, the `kcl.mod` path found from the normal path must only find one `kcl.mod` file, otherwise the compiler will output an error.

We provide [kcl.mod.proto](./kcl.mod.proto) to define the specification of kcl.mod.
For example:

In the path `/usr/kcl1`:
```
/usr/kcl1
|--- kcl.mod
|--- entry1.k
```

In the path `/usr/kcl2`:
```
/usr/kcl2
|--- kcl.mod
|--- entry2.k
```

If you compile with this `kcl.mod` in the path `/usr/kcl1`:
```
entries = [
"entry1.k", # The corresponding kcl.mod file is /usr/kcl1/kcl.mod
"/usr/kcl2/entry2.k", # The corresponding kcl.mod file is /usr/kcl2/kcl.mod
]
```

You will get an error:
```
error[E3M38]: conflict kcl.mod file paths
```

0 comments on commit f755f2d

Please sign in to comment.