簡介
KCL 團隊很高興地宣布KCL v0.4.5 版本現在已經可用!本次發布主要為KCL 語言編寫便利性和穩定性提升,錯誤信息改進以及更多平台包括windows 版本支持以及更多下載方式支持。在KCL v0.4.5 版本中,用戶可以通過編寫更少的KCL 程式碼消除更多的配置模版;在新版本中提供了初步的KCL Playground 支持可用於在線免安裝編寫並運行KCL 程式碼;此外此次更新還包含多項編譯器報錯信息優化和錯誤修復。
您可以在 KCL v0.4.5 發布頁面 或者 KCL 官方網站 獲得KCL 二進制下載鏈接和更多詳細發布信息。
KCL 是一個開源的基於約束的記錄及函數語言,期望通過成熟的編程語言技術和實踐來改進對大量繁雜配置和策略的編寫,致力於構建圍繞配置的更好的模塊化、擴展性和穩定性,更簡單的邏輯編寫,以及更快的自動化集成和良好的生態延展性。
本文將會介紹KCL v0.4.5 版本的更新內容以及KCL 社區的近期動態。
語言更新
KCL 語言編寫便利性改進
支持Schema 非空屬性惰性校驗
在之前的KCL 版本中,我們已經支持了schema 屬性互相引用(包含繼承)以及check 校驗表達式的惰性求值與校驗能力,在此次版本更新中,我們支持了更多的schema 惰性求值能力: Schema 屬性非空惰性校驗。比如對於下述的KCL 的程式碼:
schema Spec:
id: int
value: str
schema Config:
name?: str
spec: Spec = Spec {
id = 1
} # 在 KCL v0.4.5 版本之前,这个语句会报属性非空错误,v0.4.5 版本之后,支持 Schema 非空属性惰性校验能力
config = Config {
spec.value = "value"
}
在v0.4.5 之前的KCL 版本中,直接執行上述程式碼會在 schema Config
語句塊的 spec: Spec = Spec {
處拋出一個 spec
的 value
屬性不能為空的錯誤,因為在該處只對 spec
的 id
屬性賦值為 1
,而沒有對 spec
的 value
屬性賦值。
在KCL 的v0.4.5 版本更新後,我們支持了schema 屬性的惰性非空校驗能力之後會避免這個錯誤的拋出,即當在 config
屬性的 spec.value = "value"
與 spec.id = 1
合併之後才會遞歸地對 config
的所有屬性進行非空檢查,此時 spec
屬性的所有值是被完整賦值的 (spec
的 id
字段的值為 1
, value
字段為 "value"
,),不會拋出必選屬性字段為空錯誤。
因此在v0.4.5 版本之後,執行上述KCL 程式碼,我們會得到如下所示的完整YAML 輸出:
config:
spec:
id: 1
value: value
支持配置塊屬性互相引用以消除更多的配置模版
在v0.4.5 之前的版本中,KCL 尚未支持配置塊內部的屬性互相引用,導致在某些場景中會需要定義額外的配置變量或者模版來進行引用,會產生較多的配置模版和重複程式碼,比如對於如下所示的KCL 程式碼:
name = "app-name"
data = {
name = name
metadata.name = name # `metadata.name` 不能直接引用 `data` 内部的 `name` 属性
}
data
配置塊的 metadata.name
屬性不能直接引用 data
內部的 name
屬性,需要額外定義一個全局變量 name
進行引用。
而在KCL 的v0.4.5 版本更新後,我們支持了配置塊屬性互相引用的特性,可以用於消除更多的配置模版,比如如下所示的KCL 程式碼:
data = {
name = "app-name"
metadata.name = name # 直接引用 `data` 配置的 name 属性
}
data
配置塊的 metadata.name
屬性可以直接引用 data
內部的 name
屬性而無需定義額外的全局變量。
執行上述KCL 程式碼可以獲得如下YAML 輸出:
data:
name: app-name
metadata:
name: app-name
下面是一個更複雜的例子
name = "global-name"
metadata = {
name = "metadata-name"
labels = {
"app.kubernetes.io/name" = name # 直接引用 `metadata.name`
"app.kubernetes.io/instance" = name # 直接引用 `metadata.name`
}
}
data = {
name = name # 引用全局的 `name` 变量
metadata = metadata # 引用全局的 `metadata` 变量
spec.template.metadata.name = metadata.name # 引用 `data` 内部的 `metadata` 变量
}
執行上述程式碼可以獲得如下YAML 輸出:
name: global-name
metadata:
name: metadata-name
labels:
app.kubernetes.io/name: metadata-name
app.kubernetes.io/instance: metadata-name
data:
name: global-name
metadata:
name: metadata-name
labels:
app.kubernetes.io/name: metadata-name
app.kubernetes.io/instance: metadata-name
spec:
template:
metadata:
name: metadata-name
注意:當前KCL 版本尚未支持配置塊內部屬性後向引用以及跳過內部作用域直接引用全局變量,需要將被引用的屬性書寫在配置引用處的前方
KCL 語言新增功能
字符串format 成員函數支持索引格式化
在KCL v0.4.5 版本更新後,KCL 支持了類似Python 字符串format 成員函數在 {}
格式化塊中使用 <format_ele_index>[<index_or_key>]
索引標記樣式對列表和字典類型的KCL 變量進行格式化。其中
<format_ele_index>
表示需要需要序列化列表和字典類型元素的索引<index_or_key>
表示對應列表和字典類型元素的列表子元素索引或者字典子元素鍵值
比如對於如下的KCL 程式碼
# 0[0] 表示取 ["Hello", "World"] 的第 0 个元素:"Hello"
# 0[1] 表示取 ["Hello", "World"] 的第 1 个元素:"World"
listIndexFormat = "{0[0]}{0[1]}".format(["Hello", "World"])
# 0[0] 表示取 ["0", "1"] 的第 0 个元素:"1"
# 1[Hello] 表示取 {"Hello": "World"} 键值为 Hello 的字典元素:"World"
dictIndexFormat = "0{0[0]}, 1{0[1]}, Hello{1[Hello]}".format(["0", "1"], {"Hello": "World"})
執行上述程式碼可以獲得如下YAML 輸出:
listIndexFormat: HelloWorld
dictIndexFormat: "00, 11, HelloWorld"
KCL 語言Playground 更新
在此次更新中,我們更新了KCL Playground 的版本並支持KCL 程式碼自動編譯和格式化兩項能力,您可以通過訪問 KCL 官網 並點擊Playground 按鈕進行體驗。
在後續KCL 版本中,我們會持續更新KCL Playground 更多能力支持如KCL 版本選擇與程式碼分享等功能。
KCL 更多平台和更多下載方式支持
Windows 版本支持
KCL Windows 二進製版本可以從 Github 手動下載並安裝,下載完成後將 {install-location}\kclvm\bin
添加到環境變量 PATH
中。
$env:PATH += ";{install-location}\kclvm\bin;"
此外,還可以通過如下所示的Powershell 腳本進行安裝:
powershell -Command "iwr -useb https://kcl-lang.io/script/install.ps1 | iex"
我們後續會支持更多的Windows 包管理下載方式,如 Scoop
等。
更多下載方式支持
在此次版本更新中,我們支持了更多的KCL 下載方式,包括腳本, Python, Go, Homebrew 和Docker 一鍵安裝,更多詳細內容請參考 KCL 下載與安裝,後續我們會支持更多KCL 安裝方式。
⚠️ 注意:對於上述所有操作系統和安裝方式,如果要使用 KCL Python 插件 能力,需要確保已經安裝了Python 3.7+ 版本並將python3 命令添加到您的PATH 環境變量中。
錯誤修復
當存在非配置表達式的右值時配置合併順序錯誤
schema Resource:
cpu: int
memory: str
schema Config:
resource: Resource
r = Resource {
cpu = 4
memory = "8Gi"
}
config: Config {
resource: Resource {
cpu = 2
memory = "4Gi"
}
}
config: Config {
resource: r
}
在KCL v0.4.5 版本之前,執行上述程式碼(main.k) 會得到非預期的配置值,是因為KCL 編譯器錯誤地優化瞭如下形式等效合併配置塊
config: Config {
resource: r
resource: Resource {
cpu = 2
memory = "4Gi"
}
}
KCL v0.4.5 版本更新後,修正了不正確配置合併順序,可以執行main.k 並獲得預期的YAML 輸出:
r:
cpu: 4
memory: 8Gi
config:
resource:
cpu: 4
memory: 8Gi
更多詳情請參考 KCL Issue #422
配置if 表達式類型不匹配錯誤優化
config: {"A"|"B": int} = {
if True:
A = "2"
}
在KCL v0.4.5 版本之前,對於配置if 表達式,執行上述程式碼會得到預期的配置值導致Type Unsoundness 問題,是因為KCL 編譯器錯誤地沒有檢查出A 屬性的值 "2"
與聲明的類型 int
不匹配,KCL v0.4.5 版本更新後,修正了此類問題,可以執行上述程式碼可以獲得預期的類型不匹配錯誤:
KCL Compile Error[E2G22] : The type got is inconsistent with the type expected
---> File main.k:1:1
1 |config: {"A"|"B": int} = {
1 ^ -> got {str(A):str(2)}
expect {str(A)|str(B):int}, got {str(A):str(2)}
更多詳情請參考 KCL Issue #389
Rule 語句校驗不生效問題
在之前的KCL 版本中,在使用如下rule 規則程式碼時(main.k),ServiceCheckRule
的約束程式碼會不生效。
protocol KubeResourceProtocol:
svc: Service
schema Service:
name: str
rule ServiceCheckRule for KubeResourceProtocol:
svc.name != "name"
svc = Service {
name = "name"
}
ServiceCheckRule {
svc = svc
}
進行改進後,我們執行上述程式碼,會得到一個準確的校驗不通過錯誤:
KCL Runtime Error[E3B17] : Schema check is failed to check condition
---> File main.k:14
14 |ServiceCheckRule { -> Instance check failed
---> File main.k:8
8 | svc.name != "name" -> Check failed on the condition
Check failed on check conditions
配置塊屬性類型推導優化
schema Id:
id?: int = 1
schema Config:
data?: {"A"|"B": Id}
c = Config {
data = {
A = Id() # v0.4.5 版本之前,此处会得到一个类型不匹配错误
B = Id()
}
}
在KCL v0.4.5 版本之前,執行上述程式碼會得到一個非預期的類型不匹配,是因為KCL 編譯器錯誤地將 c.data.A
屬性的類型推導為 str
類型,導致與 "A"|"B"
字面值聯合類型不匹配錯誤,KCL v0.4.5 版本更新後,修正了此類問題,可以執行上述程式碼可以獲得預期的YAML 輸出:
c:
data:
A:
id: 1
B:
id: 1
賦值語句使用schema 類型註解錯誤優化
schema Foo:
foo: int
schema Bar:
bar: int
foo: Foo = Bar { # v0.4.5 版本之前,此处会得到一个运行时类型不匹配错误
bar: 1
}
在KCL v0.4.5 版本之前,執行上述程式碼會得到一個運行時類型不匹配錯誤,版本更新後,會將此類類型不匹配錯誤優化到編譯時,將錯誤左移,更早地發現此類錯誤。
KCL 模塊類型使用?. 運算符類型錯誤修復
import math
data = math?.log(10) # v0.4.5 版本之前,此处会得到一个非预期的 `math is not defined` 错误
在KCL v0.4.5 版本之前,執行上述程式碼會得到一個非預期的變量未定義錯誤,是因為KCL 編譯器沒有正確地處理 math
module 類型和 ?.
運算符結合使用的情況,版本更新後,此類問題得到修復。
其他更新與錯誤修復
更多更新與錯誤修復 詳見
文檔更新
KCL 網站 新增KCL v0.4.5 文檔內容並支持版本化語義選項,目前支持v0.4.3, v0.4.4 和v0.4.5 版本選擇。
社區動態
- KCL 社區新增兩名外部貢獻者@thinkrapido, @Rishav1707, 感謝他們熱情並積極地參與貢獻。
- 感謝@Rishav1707 基於KCL 建立了Rust 語言版本的 kcl-loader-rs 子項目,當前版本支持根據KCL 档案中的Schema 和配置定義自動生成Rust 結構體並支持KCL 值到Rust 結構體值的反序列化函數。
下一步計劃
預計2023 年4 月中旬,我們將發布 KCL v0.4.6 版本,預期重點演進包括:
- KCL 語言進一步編寫便利性改進,用戶界面持續優化與體驗提升,用戶支持和痛點解決
- 全新版本的KCL Language Server 和 VSCode 語言插件,性能預計提升20 倍,並預期支持程式碼警告和錯誤波浪線提示,跳轉,引用查找等核心基礎能力
- 針對Kubernetes Manifests 配置管理場景痛點持續進行語言能力提升:如設計提供 Helm KCL Schema 插件以及為 kpt 工具提供KCL SDK 等
- KCL 包管理工具KPM 發布,預期支持Git 倉庫程式碼依賴配置與更新,程式碼下載等基礎能力
- KCL Playground 支持程式碼分享能力和KCL 版本選擇能力
- KCL Go SDK 更多能力支持:如支持KCL Schema 和Go 結構體的雙向轉換等
- KCL Python SDK 更多能力支持
更多詳情請參考 KCL v0.4.6 Milestone
常見問題及解答
詳見 KCL 常見問題
其他資源
感謝所有KCL 用戶在此次版本更新過程中提出的寶貴的反饋與建議。更多其他資源請參考:
歡迎加入我們的社區進行交流👏👏👏:https://github.com/KusionStack/community
You may also like
相关贴文:
- KCL v0.4.4 發布! 自定義YAML Manifests 輸出以及Python SDK! – 科技資訊
- 鍛煉反應小遊戲Looptap
- 谷歌Chrome 將於2023 年2 月停止支持Windows 7/8.1
- Kstry首頁、文檔和下載- 流程編排框架&並發框架&微服務業務整合框架- 科技資訊
- Chrome 109 發布,最後一個支持Windows 7/8 的版本- 科技資訊
- cozo: 使用Datalog 作為查詢語言的高性能·關係型·可嵌入式·圖數據庫,還可進行歷史穿梭查詢
- Dentaku —— 數學和邏輯公式解析器
- Dante Cloud 2.7.8.0 發布,Spring Boot 版本升級至2.7.8 – 科技資訊
近期文章
- Shopify 主題開發人員是 2023 年可行的職涯路徑嗎?
- 我的第一個獲獎 Shopify Dropshipping 產品#shorts
- 如何將 Shopify 商店連接到 Facebook 和 Instagram 商店 (2024)
- Shopify 與 Squarespace:2024 年最佳電子商務平台?
- 我第四季目前最暢銷的 5 個產品(Shopify Dropshipping)
- 英國的 Shopify Shipping:Royal Mail、Parcelforce 和 UPS – 我們推薦的承運商和運輸應用程式!
- 每月收入 4,300,000 美元的輝煌 Shopify 利基商店
- Shopify Dropshipping – 如何找到在 Shopify 上銷售的獲獎產品! (初學者指南)
- 哪個網站平台最適合銷售您的產品?比較 WIX、Shopify 和 GODADDY 2022
發佈留言